框架资源概览
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-nunjucksnunjucks: {cache: false,tags: {variableStart: '<$',variableEnd: '$>',},},}
数据库配置
knex: Mysql客户端。knex文档。jhIdConfig: 应用数据隔离(多个应用共用一个数据时)。
const config = {// 数据库配置,使用knex插件 @ref: https://github.com/sunfuze/egg-knexknex: {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', // 数据隔离时的IdcareTableViewList: [ // 要隔离的表'_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-corscors: {origin: '*',allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',},jianghuConfig: {// 上传文件鉴权 @ref: /middleware/downloadUserInfo.jsenableUploadStaticFileAuthorization: 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文档。bodyParserbodyParser文档。formLimit: 表单数据的最大大小限制。jsonLimit: JSON 数据的最大大小限制。textLimit: 文本数据的最大大小限制。
const appId = 'jianghujs-basic';const config = {jianghuConfig: {// 开启用户信息缓存, @ref: /schedule/syncDataToCache.jsenableUserInfoCache: false,userInfoCacheRefreshInterval: '10s',// 上传文件鉴权 @ref: /middleware/downloadUserInfo.jsenableUploadStaticFileAuthorization: false,// 缓存配置enableUploadStaticFileCache: true,uploadFileMaxAge: 30 * 24 * 60 * 60 * 1000, // 30d},// 文件上传限制 @ref: https://eggjs.org/zh-cn/plugins/multipart.htmlmultipart: {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-schedulingcron: '0 30 4 * * *',disable: false,},},// 表单限制 @ref: https://github.com/eggjs/egg/blob/master/app/middleware/body_parser.jsbodyParser: {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, // 10MmaxFiles: 20, // 最大文件个数maxDays: 20, // 最大天数},// 定制的分类日志customLogger: {knex: { consoleLevel: 'WARN' },// https://www.eggjs.org/zh-CN/core/loggerhtmlLogger: {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}`;},},},}