Framework Resources Overview
12003This document provides a comprehensive overview of the built-in resources in the Jianghu Framework, covering key components such as built-in tables, pages, static assets, APIs, middleware, and configurations.
Built-in Tables (Table)
Built-in Tables/Views
- User:
_user,_user_session,_view01_user - Page & API:
_page,_resource - User Permissions:
_group,_user_group_role,_user_group_role_page,_user_group_role_resource
- Utility Tables:
constant_ui,constant,_record_history,_file,_cache
- User:
Purpose: Provides foundational framework features including authentication, authorization, data management, and more.
Built-in Page Resources (Page)
- Location: /node_modules/@jianghujs/jianghu/app/view/
- Purpose: Contains pages, components, and templates used to build the user interface.
| Resource | Description | Usage |
|---|---|---|
| /template/ | ||
| └── jhTemplateV4.html | Page Template | {% extends 'template/jhTemplateV4.html' %} |
| /page/ | ||
| ├── helpV4.html | Page.Help | http://127.0.0.1:${port}/${appId}/page/help |
| ├── loginV4.html | Page.Login | http://127.0.0.1:${port}/${appId}/page/login |
| └── manual.html | Page.Manual | http://127.0.0.1:${port}/${appId}/page/manual |
| /component/jianghuJs/ | ||
| ├── jhConfirmDialogV4.html | Component.Dialog | <jh-confirm-dialog /> await window.confirmDialog({title: "Add", content: "Confirm to add?"}) |
| ├── jhMaskV4.html | Component.Overlay | <jh-mask /> window.jhMask.show(); window.jhMask.hide(); |
| ├── jhMenuV4.html | Component.Navigation Menu | <jh-menu /> |
| ├── jhSideMenuV4.html | Component.Navigation Menu | <jh-menu-side /> |
| ├── jhSceneV4.html | Component.Scene Search | {% include 'component/jianghuJs/jhSceneV4.html' %} 👉 Scene Search 👈 |
| └── jhToastV4.html | Component.Toast Notification | <jh-toast /> window.vtoast.success("Success"); window.vtoast.fail("Failed"); window.vtoast.show({ message: '=_=', icon: 'mdi-help-circle' }) |
| /common/jianghuJs/ | ||
| ├── fixedTableColV4.html | Styling.Fixed Table Column Width | Automatically applies to all table elements |
| ├── fixedTableHeightV4.html | Styling.Fixed Table Height | {% include 'common/jianghuJs/fixedTableHeightV4.html' %} and add class="jh-fixed-table-height" |
| ├── globalCSSFontV4.html | Styling.Font Styles | |
| ├── globalCSSJHV4.html | Styling.Jianghu Custom Styles | |
| ├── globalCSSMediaV4.html | Styling.Responsive Design | |
| ├── globalCSSVuetifyV4.html | Styling.Vuetify Styles | |
| └── tableRowClickHighlight.html | Styling.Table Row Highlight Style | Add class="jh-fixed-table-height" |
| /utility/jianghuJs/ | ||
| ├── htmlErrorCollectionV4.html | Utility.HTML Error Collection | Errors are logged to /logs/${appId}.html.log |
| ├── jianghuAxiosV4.html | Utility.Axios Requests | window.jianghuAxios({...}) |
| ├── jianghuDisplayTextV4.html | Utility.Constant-to-Text Mapping | {{ getDisplayText({displayObj: constantObj.level, displayValue: item.level}) }} |
| ├── pagePasscodeValidation.html | Utility.Page Re-Authentication | {% include 'utility/jianghuJs/pagePasscodeValidation.html' %} and <page-passcode-validation validation-duration-hour="1"></page-passcode-validation> |
| ├── prepareAppInfoV4.html | Utility.Application Info | window.appInfo |
| ├── prepareDeviceIdV4.html | Utility.Device ID Generation | {% include 'utility/jianghuJs/prepareDeviceIdV4.html' %} → window.deviceId |
| ├── prepareUserInfoV4.html | Utility.User Info | window.userInfo |
| └── uiActionV4.1.html | Utility.Multi-component Vue Data Sharing | window.registerData({}) 👉 More registerData info 👈 |
Built-in Backend Utilities (common)
| Utility | Description | Usage |
|---|---|---|
| commonUtil.js | ||
| diffUtil.js | ||
| fileUtil.js | ||
| hyperDiff.js | ||
| idGenerateUtil.js | ||
| jianghuKnexUtil.js | ||
| validateUtil.js |
Built-in Static Resources (Static)
- Location: /node_modules/@jianghujs/jianghu/app/public/
- Purpose: Static files such as CSS, JS, fonts, and images.
| Resource | Description | Usage |
|---|---|---|
| /public/ | ==To be added== |
Built-in APIs (Resource)
- Examples: Login (
login), Logout (logout), User Info Query (userInfo), etc. - Purpose: Framework-level APIs for authentication, user management, and file operations.
| Desc | pageId | actionId | resourceType | resourceData |
|---|---|---|---|---|
| Login | login | passwordLogin | service | {"service": "user", "serviceFunction": "passwordLogin"} |
| Logout | allPage | logout | service | {"service": "user", "serviceFunction": "logout"} |
| Get User Info | allPage | userInfo | service | {"service": "user", "serviceFunction": "userInfo"} |
| Reset User Password | resetUserPassword | resetPassword | service | {"service": "user", "serviceFunction": "resetPassword"} |
| Query Constants | allPage | getConstantUiList | sql | { "table": "_constant_ui", "operation": "select" } |
| Chunked File Download - Get Chunk Info | allPage | getChunkInfo | service | {"service": "file", "serviceFunction": "getChunkInfo"} |
| Chunked File Upload - Upload Complete | allPage | uploadFileDone | service | {"service": "file", "serviceFunction": "uploadFileDone"} |
| Chunked File Upload - HTTP Stream | allPage | uploadFileChunkByStream | service | {"service": "file", "serviceFunction": "uploadFileChunkByStream"} |
| Chunked File Upload - HTTP Base64 | allPage | uploadFileChunkByBase64 | service | {"service": "file", "serviceFunction": "uploadFileChunkByBase64"} |
| Chunked File Download - HTTP Base64 | allPage | downloadFileChunkByBase64 | service | {"service": "file", "serviceFunction": "downloadFileChunkByBase64"} |
Built-in Middleware (Middleware)
- Location: /node_modules/@jianghujs/jianghu/app/middleware/
- Purpose: Handles authentication and authorization logic for resource (page/API/file) requests and responses.
| Route | Middleware | Notes |
|---|---|---|
/${appId}/page/* |
pagePackage.js, pageUserInfo.js, pageAuthorization.js, pageHook.js | |
/${appId}/resource/* |
httpPackage.js, httpUserInfo.js, httpAuthorization.js, httpResourceHook.js | |
/${appId}/upload/* |
downloadUserInfo.js |
Built-in Configuration (Config)
- Location: /node_modules/@jianghujs/jianghu/config/config.default.js
- Purpose: Includes basic settings, page paths, database connections, security policies, CORS, performance tuning, and logging.
Basic Configuration
appId: Application ID.authTokenKey: Prefix for storing auth tokens.keys: Security key for cookie-session.appTitle: Application name.appLogo: Path to the application logo.appType: Application mode,singlefor single app ormultiAppfor multi-app.
const appId = 'jianghujs-basic';
const config = {
appId: appId,
authTokenKey: appId,
keys: `${appId}_1638108566009`,
appTitle: 'My First App',
appLogo: `${appId}/public/img/logo.svg`,
appType: 'single', // single: single app; multiApp: multi-app
};Page Configuration
indexPage: Home page path, defaults to/${appId}/page/manual.loginPage: Login page path, defaults to/${appId}/page/loginPage.helpPage: Help page path, defaults to/${appId}/page/helpPage.appDirectoryLink: Directory page path, defaults to root '/'.primaryColor: Theme color, defaults to#1867c0.nunjucks: Nunjucks template engine to render views.cache: Template caching, disabled by default.tags: Nunjucks variable delimiters, defaults to<$and$>to avoid conflicts with Vue's{{and}}.
const appId = 'jianghujs-basic';
const config = {
indexPage: `/${appId}/page/manual`,
loginPage: `/${appId}/page/login`,
helpPage: `/${appId}/page/help`,
appDirectoryLink: '/',
primaryColor: '#1867c0',
nunjucks: {
cache: false,
tags: {
variableStart: '<$',
variableEnd: '$>',
},
},
};Database Configuration
knex: MySQL client. Knex documentation.jianghuConfig: Application data isolation (when multiple apps share one database).
const config = {
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,
},
jianghuConfig: {
jhIdConfig: {
enable: false,
jhId: 'default',
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'
],
},
},
};Security Configuration
cors: CORS settings. egg-cors documentation.jianghuConfig:enableUploadStaticFileAuthorization: Upload file authorization.enableRateLimiter: Rate limiting, disabled by default.rateLimiterDuration: Duration for rate limiting (ms).rateLimiterMax: Maximum requests allowed.rateLimiterIgnorePathPrefix: Path prefixes to ignore in rate limiting.rateLimiterWhitelist: Rate limiting whitelist.enableIpBlock: IP blacklist, disabled by default.ipBlocklist: IP blacklist.ipBlocklistFilePath: Path to the blacklist file.
const appId = 'jianghujs-basic';
const config = {
cors: {
origin: '*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
},
jianghuConfig: {
enableUploadStaticFileAuthorization: true,
enableRateLimiter: false,
rateLimiterDuration: 60000,
rateLimiterMax: 100,
rateLimiterIgnorePathPrefix: [ '/${appId}/resource', '/${appId}/page', '/${appId}/public', '${appId}/upload' ],
rateLimiterWhitelist: [],
enableIpBlock: false,
ipBlocklist: [],
ipBlocklistFilePath: '',
},
};Performance & Resources
enableUserInfoCache: User info caching, disabled by default.enableUploadStaticFileAuthorization: Download Upload file authorization, disabled by default.enableUploadStaticFileCache: Upload file caching, disabled by default.uploadFileMaxAge: Cache duration for uploaded files.multipart: File upload settings including mode and size limit. multipart documentation.bodyParserbodyParser documentation.formLimit: Max size for form data.jsonLimit: Max size for JSON data.textLimit: Max size for text data.
const appId = 'jianghujs-basic';
const config = {
jianghuConfig: {
enableUserInfoCache: false,
userInfoCacheRefreshInterval: '10s',
enableUploadStaticFileAuthorization: false,
enableUploadStaticFileCache: true,
uploadFileMaxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
},
multipart: {
mode: 'file',
fileSize: '100mb',
allowArrayField: false,
whitelist: () => true,
tmpdir: path.join(appInfo.baseDir, 'multipartTmp'),
cleanSchedule: {
cron: '0 30 4 * * *',
disable: false,
},
},
bodyParser: {
formLimit: '100mb',
jsonLimit: '100mb',
textLimit: '100mb',
},
};Error Handling
onerror: Error handling.
const config = {
onerror: {
async json(err, ctx) {
ctx.status = 200;
const { packageId } = ctx.request.body;
const errorCode =
err.errorCode || err.code || errorInfoEnum.server_error.errorCode;
const errorReason =
err.errorReason ||
err.sqlMessage ||
err.message ||
errorInfoEnum.server_error.errorReason;
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 },
});
},
}
};Logging Configuration
enableHtmlErrorLogRecord: HTML error logging, disabled by default.enableResourceLogRecord: API logging, disabled by default.autoClearOldLogFile: Auto-cleanup of old log files, disabled by default.logger: Log output settings.logrotator: Log rotation settings.customLogger: Custom categorized logging.
const appId = 'jianghujs-basic';
const config = {
jianghuConfig: {
enableHtmlErrorLogRecord: false,
htmlErrorLogRecordInterval: 60000,
enableResourceLogRecord: true,
ignoreListOfResourceLogRecord: [ 'user.passwordLogin', 'allPage.getConstantList', 'allPage.httpUploadByStream', 'allPage.httpUploadByBase64', 'allPage.httpDownloadByBase64' ],
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, // 10MB
maxFiles: 20,
maxDays: 20,
},
customLogger: {
knex: { consoleLevel: 'WARN' },
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}`;
},
},
},
};