框架资源概览
12003本文提供了江湖框架内置资源的全面概览,涵盖了内置表、页面、静态资源、接口、中间件和配置等关键部分。
内置表 (Table)
内置表/View
- 用户:
_user
,_user_session
,_view01_user
- 页面&接口:
_page
,_resource
- 用户权限:
_group
,_user_group_role
,_user_group_role_page
,_user_group_role_resource
- 工具表:
constant_ui
,constant
,_record_history
,_file
,_cache
- 用户:
说明:提供框架的基础功能,包括登陆、鉴权、数据管理等等。
内置页面资源 (Page)
- 位置:/node_modules/@jianghujs/jianghu/app/view/
- 说明:包含页面、组件和模板,用于构建用户界面。
资源 | 说明 | 使用 |
---|---|---|
/template/ | ||
└── jhTemplateV4.html | 页面模版 | {% extends 'template/jhTemplateV4.html'%} |
/page/ | ||
├── helpV4.html | 页面.帮助 | http://127.0.0.1:${port}/${appId}/page/help |
├── loginV4.html | 页面.登陆 | http://127.0.0.1:${port}/${appId}/page/login |
└── manual.html | 页面.操作手册 | http://127.0.0.1:${port}/${appId}/page/manual |
/component/jianghuJs/ | ||
├── jhConfirmDialogV4.html | 组件.Dialog | <jh-confirm-dialog /> await window.confirmDialog({title: "新增", content: "确定新增吗?"}) |
├── jhMaskV4.html | 组件.遮罩层 | <jh-mask /> window.jhMask.show(); window.jhMask.hide(); |
├── jhMenuV4.html | 组件.导航菜单 | <jh-menu /> |
├── jhSideMenuV4.html | 组件.导航菜单 | <jh-menu-side /> |
├── jhSceneV4.html | 组件.场景搜索 | {% include 'component/jianghuJs/jhSceneV4.html' %} 👉场景搜索👈 |
└── jhToastV4.html | 组件.消息提示 | <jh-toast /> window.vtoast.success("成功"); window.vtoast.fail("失败"); window.vtoast.show({ message: '=_=', icon: 'mdi-help-circle' }) |
/common/jianghuJs/ | ||
├── fixedTableColV4.html | 样式.固定table单元格宽度 | 自动识别所有table |
├── fixedTableHeightV4.html | 样式.固定table高度 | {% include 'common/jianghuJs/fixedTableHeightV4.html' %} class="jh-fixed-table-height" |
├── globalCSSFontV4.html | 样式.字体样式 | |
├── globalCSSJHV4.html | 样式.江湖自定义 | |
├── globalCSSMediaV4.html | 样式.响应式 | |
├── globalCSSVuetifyV4.html | 样式.Vuetify样式 | |
└── tableRowClickHighlight.html | 样式.table行高亮样式 | class="jh-fixed-table-height" |
/utility/jianghuJs/ | ||
├── htmlErrorCollectionV4.html | 工具.html异常收集 | 异常日志会记录到 /logs/${appId}.html.log |
├── jianghuAxiosV4.html | 工具.axios请求 | window.jianghuAxios({...}) |
├── jianghuDisplayTextV4.html | 工具.常量数据值转换文字 | {{ getDisplayText({displayObj: constantObj.level, displayValue: item.level}) }} |
├── pagePasscodeValidation.html | 工具.页面二次认证 | {% include 'utility/jianghuJs/pagePasscodeValidation.html' %} <page-passcode-validation validation-duration-hour="1"></page-passcode-validation> |
├── prepareAppInfoV4.html | 工具.应用信息 | window.appInfo |
├── prepareDeviceIdV4.html | 工具.设备Id生成 | {% include 'utility/jianghuJs/prepareDeviceIdV4.html' %} window.deviceId |
├── prepareUserInfoV4.html | 工具.用户信息 | window.userInfo |
└── uiActionV4.1.html | 工具.多组件vueData共享 | window.registerData({}) 👉更多registerData信息👈 |
内置后端工具 (common)
工具 | 说明 | 使用 |
---|---|---|
commonUtil.js | ---- | ---- |
diffUtil.js | ---- | ---- |
fileUtil.js | ---- | ---- |
hyperDiff.js | ---- | ---- |
idGenerateUtil.js | ---- | ---- |
jianghuKnexUtil.js | ---- | ---- |
validateUtil.js | ---- | ---- |
内置静态资源 (Static)
- 位置:/node_modules/@jianghujs/jianghu/app/public/
- 说明:CSS、JS、字体和图片等静态文件。
资源 说明 使用 /public/ ==待补充==
内置接口 (Resource)
- 示例:登录 (
login
), 登出 (logout
), 用户信息查询 (userInfo
) 等。 - 说明:框架基础的接口, 登陆、用户、文件相关。
desc | pageId | actionId | resourceType | resourceData |
---|---|---|---|---|
登陆 | login | passwordLogin | service | {"service": "user", "serviceFunction": "passwordLogin"} |
登出 | allPage | logout | service | {"service": "user", "serviceFunction": "logout"} |
获取用户信息 | allPage | userInfo | service | {"service": "user", "serviceFunction": "userInfo"} |
修改用户密码 | resetUserPassword | resetPassword | service | {"service": "user", "serviceFunction": "resetPassword"} |
查询常量 | allPage | getConstantUiList | sql | { "table": "_constant_ui", "operation": "select" } |
文件分片下载-获取分片信息 | allPage | getChunkInfo | service | {"service": "file", "serviceFunction": "getChunkInfo"} |
文件分片上传-所有分片上传完毕 | allPage | uploadFileDone | service | {"service": "file", "serviceFunction": "uploadFileDone"} |
文件分片上传-http文件流 | allPage | uploadFileChunkByStream | service | {"service": "file", "serviceFunction": "uploadFileChunkByStream"} |
文件分片上传-http base64 | allPage | uploadFileChunkByBase64 | service | {"service": "file", "serviceFunction": "uploadFileChunkByBase64"} |
文件分片下载-http base64 | allPage | downloadFileChunkByBase64 | service | {"service": "file", "serviceFunction": "downloadFileChunkByBase64"} |
内置中间件 (Middleware)
- 位置:/node_modules/@jianghujs/jianghu/app/middleware/
- 说明:处理资源(页面/接口/文件)请求和响应的鉴限逻辑。
路由 中间件 补充说明 /${appId}/page/*
pagePackage.js, pageUserInfo.js, pageAuthorization.js, pageHook.js /${appId}/resource/*
httpPackage.js, httpUserInfo.js, httpAuthorization.js, httpResourceHook.js /${appId}/upload/*
downloadUserInfo.js
内置配置 (Config)
位置:/node_modules/@jianghujs/jianghu/config/config.default.js
说明:包括基础配置、页面路径、数据库连接、安全配置、跨域策略、性能优化和日志管理。
基础配置
appId
: 应用ID。authTokenKey
: authToken存储的前缀keys
: cookie-session的安全密钥。appTitle
: 应用的名称。appLogo
: 应用的logo路径。appType
: 应用模式,single: 单应用; multiApp: 多应用。
const appId = 'jianghujs-basic';
const config = {
appId: appId,
authTokenKey: appId,
keys: `${appId}_1638108566009`,
appTitle: '第一个应用',
appLogo: `${appId}/public/img/logo.svg`,
appType: 'single', // single: 单应用; multiApp: 多应用
}
页面配置
indexPage
: 首页路径, 默认值/${appId}/page/manual
。loginPage
: 登陆页路径, 默认值/${appId}/page/loginPage
。helpPage
: 帮助页路径, 默认值/${appId}/page/helpPage
。appDirectoryLink
: 目录页路径。默认是跟路径'/'。primaryColor
: 主题色,默认值#1867c0
。nunjucks
: njk模板引擎,用于渲染视图。cache
: 模板缓存,默认不开启 。tags
: njk模板变量取值符号,默认为<$
和$>
,用于包裹变量。(为了避免和vue的{{
和}}
起冲突)
const appId = 'jianghujs-basic';
const config = {
indexPage: `/${appId}/page/manual`,
loginPage: `/${appId}/page/login`,
helpPage: `/${appId}/page/help`,
appDirectoryLink: '/',
primaryColor: '#1867c0',
// nunjucks页面模版 @ref: https://github.com/eggjs/egg-view-nunjucks
nunjucks: {
cache: false,
tags: {
variableStart: '<$',
variableEnd: '$>',
},
},
}
数据库配置
knex
: Mysql客户端。knex文档。jhIdConfig
: 应用数据隔离(多个应用共用一个数据时)。
const config = {
// 数据库配置,使用knex插件 @ref: https://github.com/sunfuze/egg-knex
knex: {
client: {
dialect: 'mysql', // 数据库类型
connection: { // 连接设置
host: '127.0.0.1', // 主机地址
port: '3306', // 端口
user: 'jianghu', // 用户名
password: '123456', // 密码
database: 'jianghu', // 数据库名
},
pool: { min: 0, max: 10 }, // 连接池大小
acquireConnectionTimeout: 30000, // 连接超时时间(毫秒)
},
app: true, // 挂载到app
},
jianghuConfig: {
jhIdConfig: { // 应用数据隔离
enable: false, // 是否启用
jhId: 'default', // 数据隔离时的Id
careTableViewList: [ // 要隔离的表
'_cache', '_constant', '_file', '_group',
'_page', '_record_history', '_resource', '_resource_request_log',
'_role', '_test_case', '_ui', '_user',
'_user_group_role', '_user_group_role_page', '_user_group_role_resource',
'_user_session', '_view01_user'
],
},
},
}
安全配置
cors
: 跨域配置。egg-cors文档。- jianghuConfig
enableUploadStaticFileAuthorization
: 上传文件鉴权。enableRateLimiter
: 限流是否开启。默认关闭rateLimiterDuration
: 限流持续时间(毫秒)。rateLimiterMax
: 限流最大请求数。rateLimiterIgnorePathPrefix
: 限流忽略的路径前缀列表。rateLimiterWhitelist
: 限流白名单。enableIpBlock
: IP黑名单是否开启。默认关闭ipBlocklist
: IP黑名单列表。ipBlocklistFilePath
: 黑名单文件路径。
const appId = 'jianghujs-basic';
const config = {
// 跨域支持, @ref: https://github.com/eggjs/egg-cors
cors: {
origin: '*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
},
jianghuConfig: {
// 上传文件鉴权 @ref: /middleware/downloadUserInfo.js
enableUploadStaticFileAuthorization: true,
// WAF: 限流
enableRateLimiter: false,
rateLimiterDuration: 60000,
rateLimiterMax: 100,
rateLimiterIgnorePathPrefix: [ '/${appId}/resource', '/${appId}/page', '/${appId}/public', '${appId}/upload' ],
rateLimiterWhitelist: [],
// WAF: IP 黑名单
enableIpBlock: false,
ipBlocklist: [],
ipBlocklistFilePath: '',
},
}
性能与资源
enableUserInfoCache
: 用户信息缓存开启,默认关闭enableUploadStaticFileAuthorization
: 下载Upload文件鉴权开启,默认关闭enableUploadStaticFileCache
: Upload文件缓存开启,默认关闭uploadFileMaxAge
: upload文件缓存时间multipart
: 文件上传的配置,包括模式和文件大小限制。multipart文档。bodyParser
bodyParser文档。formLimit
: 表单数据的最大大小限制。jsonLimit
: JSON 数据的最大大小限制。textLimit
: 文本数据的最大大小限制。
const appId = 'jianghujs-basic';
const config = {
jianghuConfig: {
// 开启用户信息缓存, @ref: /schedule/syncDataToCache.js
enableUserInfoCache: false,
userInfoCacheRefreshInterval: '10s',
// 上传文件鉴权 @ref: /middleware/downloadUserInfo.js
enableUploadStaticFileAuthorization: false,
// 缓存配置
enableUploadStaticFileCache: true,
uploadFileMaxAge: 30 * 24 * 60 * 60 * 1000, // 30d
},
// 文件上传限制 @ref: https://eggjs.org/zh-cn/plugins/multipart.html
multipart: {
mode: 'file',
fileSize: '100mb',
allowArrayField: false,
// 允许所有格式的文件上传
whitelist: () => true,
tmpdir: path.join(appInfo.baseDir, 'multipartTmp'),
cleanSchedule: {
// run tmpdir clean job on every day 04:30 am
// cron style see https://github.com/eggjs/egg-schedule#cron-style-scheduling
cron: '0 30 4 * * *',
disable: false,
},
},
// 表单限制 @ref: https://github.com/eggjs/egg/blob/master/app/middleware/body_parser.js
bodyParser: {
formLimit: '100mb',
jsonLimit: '100mb',
textLimit: '100mb',
},
}
异常处理
onerror
: 异常处理。const config = {
onerror: {
async json(err, ctx) {
ctx.status = 200;
const { packageId } = ctx.request.body;
// TODO: 如何将系统异常 & 数据库异常 & Biz异常 优雅的返回
const errorCode =
err.errorCode || err.code || errorInfoEnum.server_error.errorCode;
const errorReason =
err.errorReason ||
err.sqlMessage ||
err.message ||
errorInfoEnum.server_error.errorReason;
// 清除cookie;
if (
errorCode === 'request_token_invalid' ||
errorCode === 'request_user_not_exist' ||
errorCode === 'request_token_expired' ||
errorCode === 'request_app_forbidden' ||
errorCode === 'user_banned'
) {
ctx.cookies.set(`${ctx.app.config.authTokenKey}_authToken`, null);
}
const errorReasonSupplement = err.errorReasonSupplement || null;
ctx.body = httpResponse.fail({
packageId,
appData: { errorCode, errorReason, errorReasonSupplement },
});
},
}
}
日志配置
enableHtmlErrorLogRecord
: 页面错误日志记录,默认关闭enableResourceLogRecord
: 接口日志记录,默认关闭autoClearOldLogFile
: 自动清理日志,默认关闭logger
: 日志输出配置。logrotator
: 日志切割配置。customLogger
: 定制分类日志记录。
const appId = 'jianghujs-basic';
const config = {
jianghuConfig: {
// 页面日志收集
enableHtmlErrorLogRecord: false,
htmlErrorLogRecordInterval: 60000,
// resource 日志收集
enableResourceLogRecord: true,
ignoreListOfResourceLogRecord: [ 'user.passwordLogin', 'allPage.getConstantList', 'allPage.httpUploadByStream', 'allPage.httpUploadByBase64', 'allPage.httpDownloadByBase64' ],
// 自动清理旧日志文件,保留 N 天内的日志
autoClearOldLogFile: false,
autoClearOldLogBeforeDays: 7,
autoClearOldLogFilePrefixList: [
'common-error', 'egg-web', 'egg-schedule', 'egg-knex', 'egg-agent', '_resource_request_log',
`${appId}.html`, `${appId}.resource`, `${appId}-web`, `${appId}.html`,
],
},
// 日志配置
logger: {
outputJSON: true,
level: 'INFO',
dir: path.join(appInfo.baseDir, 'logs'),
contextFormatter(meta) {
return `[${meta.date}] [${meta.level}] [${meta.ctx.method} ${meta.ctx.url}] ${meta.message}`;
},
},
// 日志切割
logrotator: {
filesRotateBySize: [
path.join(appInfo.baseDir, `logs/${appId}.page.log`),
path.join(appInfo.baseDir, `logs/${appId}.page.json.log`),
path.join(appInfo.baseDir, `logs/${appId}.html.log`),
path.join(appInfo.baseDir, `logs/${appId}.html.json.log`),
],
maxFileSize: 10 * 1024 * 1024, // 10M
maxFiles: 20, // 最大文件个数
maxDays: 20, // 最大天数
},
// 定制的分类日志
customLogger: {
knex: { consoleLevel: 'WARN' },
// https://www.eggjs.org/zh-CN/core/logger
htmlLogger: {
file: path.join(appInfo.baseDir, `logs/${appId}.html.log`),
contextFormatter(meta) {
return `[${meta.date}] [${meta.level}] [${meta.ctx.method} ${meta.ctx.url}] ${meta.message}`;
},
},
resourceLogger: {
file: path.join(appInfo.baseDir, `logs/${appId}.resource.log`),
contextFormatter(meta) {
return `[${meta.date}] [${meta.level}] [${meta.ctx.method} ${meta.ctx.url}] ${meta.message}`;
},
},
pageLogger: {
file: path.join(appInfo.baseDir, `logs/${appId}.page.log`),
contextFormatter(meta) {
return `[${meta.date}] [${meta.level}] [${meta.ctx.method} ${meta.ctx.url}] ${meta.message}`;
},
},
},
}