Framework Resources Overview

12003

This 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
  • Purpose: Provides foundational framework features including authentication, authorization, data management, and more.

Built-in Page Resources (Page)

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)

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)

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)

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, single for single app or multiApp for 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.
  • bodyParser bodyParser 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}`;
        },
      },
    },
};