wjx hace 1 mes
padre
commit
201c1f6828
Se han modificado 100 ficheros con 4722 adiciones y 0 borrados
  1. 1 0
      .commitlintrc.js
  2. 16 0
      .editorconfig
  3. 40 0
      .gitignore
  4. 1 0
      .husky/commit-msg
  5. 1 0
      .husky/pre-commit
  6. 5 0
      .lintstagedrc
  7. 1 0
      .npmrc
  8. 48 0
      biome.json
  9. 185 0
      config/config.ts
  10. 28 0
      config/defaultSettings.ts
  11. 593 0
      config/oneapi.json
  12. 46 0
      config/proxy.ts
  13. 41 0
      config/routes.ts
  14. 21 0
      jest.config.ts
  15. 187 0
      mock/listTableList.ts
  16. 14 0
      mock/monitor.mock.ts
  17. 117 0
      mock/notices.ts
  18. 345 0
      mock/requestRecord.mock.js
  19. 5 0
      mock/route.ts
  20. 205 0
      mock/user.ts
  21. 80 0
      package.json
  22. 1 0
      public/CNAME
  23. BIN
      public/favicon.ico
  24. BIN
      public/icons/icon-128x128.png
  25. BIN
      public/icons/icon-192x192.png
  26. BIN
      public/icons/icon-512x512.png
  27. 0 0
      public/logo.svg
  28. 5 0
      public/pro_icon.svg
  29. 202 0
      public/scripts/loading.js
  30. 11 0
      src/access.ts
  31. 230 0
      src/app.tsx
  32. 1 0
      src/assets/icons/book.svg
  33. 0 0
      src/assets/icons/corpChat.svg
  34. 1 0
      src/assets/icons/game.svg
  35. 0 0
      src/assets/icons/gameSystem.svg
  36. 1 0
      src/assets/icons/image.svg
  37. 0 0
      src/assets/icons/tencentAd.svg
  38. 1 0
      src/assets/icons/weChatData.svg
  39. BIN
      src/assets/image/qucheng.png
  40. 15 0
      src/components/Footer/index.tsx
  41. 41 0
      src/components/HeaderDropdown/index.tsx
  42. 156 0
      src/components/RightContent/AvatarDropdown.tsx
  43. 32 0
      src/components/RightContent/index.tsx
  44. 85 0
      src/components/SystemCard/index.tsx
  45. 12 0
      src/components/index.ts
  46. 94 0
      src/global.less
  47. 42 0
      src/global.style.ts
  48. 93 0
      src/global.tsx
  49. 7 0
      src/loading.tsx
  50. 25 0
      src/locales/bn-BD.ts
  51. 5 0
      src/locales/bn-BD/component.ts
  52. 17 0
      src/locales/bn-BD/globalHeader.ts
  53. 52 0
      src/locales/bn-BD/menu.ts
  54. 73 0
      src/locales/bn-BD/pages.ts
  55. 7 0
      src/locales/bn-BD/pwa.ts
  56. 32 0
      src/locales/bn-BD/settingDrawer.ts
  57. 60 0
      src/locales/bn-BD/settings.ts
  58. 25 0
      src/locales/en-US.ts
  59. 5 0
      src/locales/en-US/component.ts
  60. 18 0
      src/locales/en-US/globalHeader.ts
  61. 52 0
      src/locales/en-US/menu.ts
  62. 76 0
      src/locales/en-US/pages.ts
  63. 7 0
      src/locales/en-US/pwa.ts
  64. 32 0
      src/locales/en-US/settingDrawer.ts
  65. 61 0
      src/locales/en-US/settings.ts
  66. 25 0
      src/locales/fa-IR.ts
  67. 5 0
      src/locales/fa-IR/component.ts
  68. 18 0
      src/locales/fa-IR/globalHeader.ts
  69. 52 0
      src/locales/fa-IR/menu.ts
  70. 75 0
      src/locales/fa-IR/pages.ts
  71. 7 0
      src/locales/fa-IR/pwa.ts
  72. 32 0
      src/locales/fa-IR/settingDrawer.ts
  73. 64 0
      src/locales/fa-IR/settings.ts
  74. 25 0
      src/locales/id-ID.ts
  75. 5 0
      src/locales/id-ID/component.ts
  76. 18 0
      src/locales/id-ID/globalHeader.ts
  77. 53 0
      src/locales/id-ID/menu.ts
  78. 75 0
      src/locales/id-ID/pages.ts
  79. 7 0
      src/locales/id-ID/pwa.ts
  80. 33 0
      src/locales/id-ID/settingDrawer.ts
  81. 64 0
      src/locales/id-ID/settings.ts
  82. 25 0
      src/locales/ja-JP.ts
  83. 5 0
      src/locales/ja-JP/component.ts
  84. 17 0
      src/locales/ja-JP/globalHeader.ts
  85. 52 0
      src/locales/ja-JP/menu.ts
  86. 77 0
      src/locales/ja-JP/pages.ts
  87. 7 0
      src/locales/ja-JP/pwa.ts
  88. 33 0
      src/locales/ja-JP/settingDrawer.ts
  89. 63 0
      src/locales/ja-JP/settings.ts
  90. 22 0
      src/locales/pt-BR.ts
  91. 5 0
      src/locales/pt-BR/component.ts
  92. 18 0
      src/locales/pt-BR/globalHeader.ts
  93. 54 0
      src/locales/pt-BR/menu.ts
  94. 77 0
      src/locales/pt-BR/pages.ts
  95. 7 0
      src/locales/pt-BR/pwa.ts
  96. 33 0
      src/locales/pt-BR/settingDrawer.ts
  97. 66 0
      src/locales/pt-BR/settings.ts
  98. 24 0
      src/locales/zh-CN.ts
  99. 5 0
      src/locales/zh-CN/component.ts
  100. 17 0
      src/locales/zh-CN/globalHeader.ts

+ 1 - 0
.commitlintrc.js

@@ -0,0 +1 @@
+module.exports = { extends: ['@commitlint/config-conventional'] };

+ 16 - 0
.editorconfig

@@ -0,0 +1,16 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab

+ 40 - 0
.gitignore

@@ -0,0 +1,40 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+**/node_modules
+# roadhog-api-doc ignore
+/src/utils/request-temp.js
+_roadhog-api-doc
+
+# production
+/dist
+
+# misc
+.DS_Store
+npm-debug.log*
+yarn-error.log
+
+/coverage
+.idea
+yarn.lock
+package-lock.json
+*bak
+.vscode
+
+
+# visual studio code
+.history
+*.log
+functions/*
+.temp/**
+
+# umi
+.umi
+.umi-production
+.umi-test
+
+# screenshot
+screenshot
+.firebase
+
+build

+ 1 - 0
.husky/commit-msg

@@ -0,0 +1 @@
+npx --no -- commitlint --edit $1

+ 1 - 0
.husky/pre-commit

@@ -0,0 +1 @@
+lint-staged

+ 5 - 0
.lintstagedrc

@@ -0,0 +1,5 @@
+{
+  "**/*.{js,jsx,tsx,ts,md,css,less,json}": [
+    "npx @biomejs/biome check --write"
+  ]
+}

+ 1 - 0
.npmrc

@@ -0,0 +1 @@
+legacy-peer-deps=true

+ 48 - 0
biome.json

@@ -0,0 +1,48 @@
+{
+  "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
+  "files": {
+    "ignoreUnknown": true,
+    "includes": [
+      "**/*",
+      "!**/.umi/**",
+      "!**/.umi-production/**",
+      "!**/.umi-test/**",
+      "!**/.umi-test-production/**",
+      "!**/src/services/**",
+      "!**/mock/**",
+      "!**/dist/**",
+      "!**/server/**",
+      "!**/public/**",
+      "!**/coverage/**",
+      "!**/node_modules/**",
+      "!biome.json"
+    ]
+  },
+  "formatter": {
+    "enabled": true,
+    "indentStyle": "space"
+  },
+  "linter": {
+    "enabled": true,
+    "rules": {
+      "recommended": true,
+      "suspicious": {
+        "noExplicitAny": "off"
+      },
+      "correctness": {
+        "useExhaustiveDependencies": "off"
+      },
+      "a11y": {
+        "noStaticElementInteractions": "off",
+        "useValidAnchor": "off",
+        "useKeyWithClickEvents": "off"
+      }
+    }
+  },
+  "javascript": {
+    "jsxRuntime": "reactClassic",
+    "formatter": {
+      "quoteStyle": "single"
+    }
+  }
+}

+ 185 - 0
config/config.ts

@@ -0,0 +1,185 @@
+// https://umijs.org/config/
+
+import { join } from 'node:path';
+import { defineConfig } from '@umijs/max';
+import defaultSettings from './defaultSettings';
+import proxy from './proxy';
+
+import routes from './routes';
+
+const { REACT_APP_ENV = 'dev' } = process.env;
+
+/**
+ * @name 使用公共路径
+ * @description 部署时的路径,如果部署在非根目录下,需要配置这个变量
+ * @doc https://umijs.org/docs/api/config#publicpath
+ */
+const PUBLIC_PATH: string = '/';
+
+export default defineConfig({
+  history: {
+    type: 'hash',
+  },
+  links: [
+    {
+      rel: 'stylesheet',
+      href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css',
+      crossorigin: 'anonymous'
+    }
+  ],
+  /**
+   * @name 开启 hash 模式
+   * @description 让 build 之后的产物包含 hash 后缀。通常用于增量发布和避免浏览器加载缓存。
+   * @doc https://umijs.org/docs/api/config#hash
+   */
+  hash: true,
+
+  publicPath: PUBLIC_PATH,
+
+  /**
+   * @name 兼容性设置
+   * @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖
+   * @doc https://umijs.org/docs/api/config#targets
+   */
+  // targets: {
+  //   ie: 11,
+  // },
+  /**
+   * @name 路由的配置,不在路由中引入的文件不会编译
+   * @description 只支持 path,component,routes,redirect,wrappers,title 的配置
+   * @doc https://umijs.org/docs/guides/routes
+   */
+  // umi routes: https://umijs.org/docs/routing
+  routes,
+  /**
+   * @name 主题的配置
+   * @description 虽然叫主题,但是其实只是 less 的变量设置
+   * @doc antd的主题设置 https://ant.design/docs/react/customize-theme-cn
+   * @doc umi 的 theme 配置 https://umijs.org/docs/api/config#theme
+   */
+  // theme: { '@primary-color': '#1DA57A' }
+  /**
+   * @name moment 的国际化配置
+   * @description 如果对国际化没有要求,打开之后能减少js的包大小
+   * @doc https://umijs.org/docs/api/config#ignoremomentlocale
+   */
+  ignoreMomentLocale: true,
+  /**
+   * @name 代理配置
+   * @description 可以让你的本地服务器代理到你的服务器上,这样你就可以访问服务器的数据了
+   * @see 要注意以下 代理只能在本地开发时使用,build 之后就无法使用了。
+   * @doc 代理介绍 https://umijs.org/docs/guides/proxy
+   * @doc 代理配置 https://umijs.org/docs/api/config#proxy
+   */
+  proxy: proxy[REACT_APP_ENV as keyof typeof proxy],
+  /**
+   * @name 快速热更新配置
+   * @description 一个不错的热更新组件,更新时可以保留 state
+   */
+  fastRefresh: true,
+  //============== 以下都是max的插件配置 ===============
+  /**
+   * @name 数据流插件
+   * @@doc https://umijs.org/docs/max/data-flow
+   */
+  model: {},
+  /**
+   * 一个全局的初始数据流,可以用它在插件之间共享数据
+   * @description 可以用来存放一些全局的数据,比如用户信息,或者一些全局的状态,全局初始状态在整个 Umi 项目的最开始创建。
+   * @doc https://umijs.org/docs/max/data-flow#%E5%85%A8%E5%B1%80%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81
+   */
+  initialState: {},
+  /**
+   * @name layout 插件
+   * @doc https://umijs.org/docs/max/layout-menu
+   */
+  title: '趣程系统中控台',
+  layout: {
+    locale: true,
+    ...defaultSettings,
+  },
+  /**
+   * @name moment2dayjs 插件
+   * @description 将项目中的 moment 替换为 dayjs
+   * @doc https://umijs.org/docs/max/moment2dayjs
+   */
+  moment2dayjs: {
+    preset: 'antd',
+    plugins: ['duration'],
+  },
+  /**
+   * @name 国际化插件
+   * @doc https://umijs.org/docs/max/i18n
+   */
+  locale: false,
+  /**
+   * @name antd 插件
+   * @description 内置了 babel import 插件
+   * @doc https://umijs.org/docs/max/antd#antd
+   */
+  antd: {
+    appConfig: {},
+    configProvider: {
+      theme: {
+        cssVar: true,
+        token: {
+          fontFamily: 'AlibabaSans, sans-serif',
+        },
+      },
+    },
+  },
+  /**
+   * @name 网络请求配置
+   * @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
+   * @doc https://umijs.org/docs/max/request
+   */
+  request: {},
+  /**
+   * @name 权限插件
+   * @description 基于 initialState 的权限插件,必须先打开 initialState
+   * @doc https://umijs.org/docs/max/access
+   */
+  access: {},
+  /**
+   * @name <head> 中额外的 script
+   * @description 配置 <head> 中额外的 script
+   */
+  headScripts: [
+    // 解决首次加载时白屏的问题
+    { src: join(PUBLIC_PATH, 'scripts/loading.js'), async: true },
+  ],
+  //================ pro 插件配置 =================
+  presets: ['umi-presets-pro'],
+  /**
+   * @name openAPI 插件的配置
+   * @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码
+   * @doc https://pro.ant.design/zh-cn/docs/openapi/
+   */
+  openAPI: [
+    {
+      requestLibPath: "import { request } from '@umijs/max'",
+      // 或者使用在线的版本
+      // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
+      schemaPath: join(__dirname, 'oneapi.json'),
+      mock: false,
+    },
+    {
+      requestLibPath: "import { request } from '@umijs/max'",
+      schemaPath:
+        'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
+      projectName: 'swagger',
+    },
+  ],
+  mock: {
+    include: ['mock/**/*', 'src/pages/**/_mock.ts'],
+  },
+  /**
+   * @name 是否开启 mako
+   * @description 使用 mako 极速研发
+   * @doc https://umijs.org/docs/api/config#mako
+   */
+  mako: {},
+  esbuildMinifyIIFE: true,
+  requestRecord: {},
+  exportStatic: {},
+});

+ 28 - 0
config/defaultSettings.ts

@@ -0,0 +1,28 @@
+import type { ProLayoutProps } from '@ant-design/pro-components';
+
+/**
+ * @name
+ */
+const Settings: ProLayoutProps & {
+  pwa?: boolean;
+  logo?: string;
+} = {
+  navTheme: 'light',
+  // 拂晓蓝
+  colorPrimary: '#1890ff',
+  layout: 'mix',
+  contentWidth: 'Fluid',
+  fixedHeader: true,
+  fixSiderbar: true,
+  colorWeak: false,
+  title: '趣程系统中控台',
+  pwa: true,
+  logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
+  iconfontUrl: '',
+  token: {
+    // 参见ts声明,demo 见文档,通过token 修改样式
+    //https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
+  },
+};
+
+export default Settings;

+ 593 - 0
config/oneapi.json

@@ -0,0 +1,593 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "Ant Design Pro",
+    "version": "1.0.0"
+  },
+  "servers": [
+    {
+      "url": "http://localhost:8000/"
+    },
+    {
+      "url": "https://localhost:8000/"
+    }
+  ],
+  "paths": {
+    "/api/currentUser": {
+      "get": {
+        "tags": ["api"],
+        "description": "获取当前的用户",
+        "operationId": "currentUser",
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/CurrentUser"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "x-swagger-router-controller": "api"
+    },
+    "/api/login/captcha": {
+      "post": {
+        "description": "发送验证码",
+        "operationId": "getFakeCaptcha",
+        "tags": ["login"],
+        "parameters": [
+          {
+            "name": "phone",
+            "in": "query",
+            "description": "手机号",
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/FakeCaptcha"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/login/outLogin": {
+      "post": {
+        "description": "登录接口",
+        "operationId": "outLogin",
+        "tags": ["login"],
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "x-swagger-router-controller": "api"
+    },
+    "/api/login/account": {
+      "post": {
+        "tags": ["login"],
+        "description": "登录接口",
+        "operationId": "login",
+        "requestBody": {
+          "description": "登录系统",
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/LoginParams"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LoginResult"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        },
+        "x-codegen-request-body-name": "body"
+      },
+      "x-swagger-router-controller": "api"
+    },
+    "/api/notices": {
+      "summary": "getNotices",
+      "description": "NoticeIconItem",
+      "get": {
+        "tags": ["api"],
+        "operationId": "getNotices",
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/NoticeIconList"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/rule": {
+      "get": {
+        "tags": ["rule"],
+        "description": "获取规则列表",
+        "operationId": "rule",
+        "parameters": [
+          {
+            "name": "current",
+            "in": "query",
+            "description": "当前的页码",
+            "schema": {
+              "type": "number"
+            }
+          },
+          {
+            "name": "pageSize",
+            "in": "query",
+            "description": "页面的容量",
+            "schema": {
+              "type": "number"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/RuleList"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "post": {
+        "tags": ["rule"],
+        "description": "新建规则",
+        "operationId": "addRule",
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/RuleListItem"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "put": {
+        "tags": ["rule"],
+        "description": "新建规则",
+        "operationId": "updateRule",
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/RuleListItem"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "delete": {
+        "tags": ["rule"],
+        "description": "删除规则",
+        "operationId": "removeRule",
+        "responses": {
+          "200": {
+            "description": "Success",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ErrorResponse"
+                }
+              }
+            }
+          }
+        }
+      },
+      "x-swagger-router-controller": "api"
+    },
+    "/swagger": {
+      "x-swagger-pipe": "swagger_raw"
+    }
+  },
+  "components": {
+    "schemas": {
+      "CurrentUser": {
+        "type": "object",
+        "properties": {
+          "name": {
+            "type": "string"
+          },
+          "avatar": {
+            "type": "string"
+          },
+          "userid": {
+            "type": "string"
+          },
+          "email": {
+            "type": "string"
+          },
+          "signature": {
+            "type": "string"
+          },
+          "title": {
+            "type": "string"
+          },
+          "group": {
+            "type": "string"
+          },
+          "tags": {
+            "type": "array",
+            "items": {
+              "type": "object",
+              "properties": {
+                "key": {
+                  "type": "string"
+                },
+                "label": {
+                  "type": "string"
+                }
+              }
+            }
+          },
+          "notifyCount": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "unreadCount": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "country": {
+            "type": "string"
+          },
+          "access": {
+            "type": "string"
+          },
+          "geographic": {
+            "type": "object",
+            "properties": {
+              "province": {
+                "type": "object",
+                "properties": {
+                  "label": {
+                    "type": "string"
+                  },
+                  "key": {
+                    "type": "string"
+                  }
+                }
+              },
+              "city": {
+                "type": "object",
+                "properties": {
+                  "label": {
+                    "type": "string"
+                  },
+                  "key": {
+                    "type": "string"
+                  }
+                }
+              }
+            }
+          },
+          "address": {
+            "type": "string"
+          },
+          "phone": {
+            "type": "string"
+          }
+        }
+      },
+      "LoginResult": {
+        "type": "object",
+        "properties": {
+          "status": {
+            "type": "string"
+          },
+          "type": {
+            "type": "string"
+          },
+          "currentAuthority": {
+            "type": "string"
+          }
+        }
+      },
+      "PageParams": {
+        "type": "object",
+        "properties": {
+          "current": {
+            "type": "number"
+          },
+          "pageSize": {
+            "type": "number"
+          }
+        }
+      },
+      "RuleListItem": {
+        "type": "object",
+        "properties": {
+          "key": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "disabled": {
+            "type": "boolean"
+          },
+          "href": {
+            "type": "string"
+          },
+          "avatar": {
+            "type": "string"
+          },
+          "name": {
+            "type": "string"
+          },
+          "owner": {
+            "type": "string"
+          },
+          "desc": {
+            "type": "string"
+          },
+          "callNo": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "status": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "updatedAt": {
+            "type": "string",
+            "format": "datetime"
+          },
+          "createdAt": {
+            "type": "string",
+            "format": "datetime"
+          },
+          "progress": {
+            "type": "integer",
+            "format": "int32"
+          }
+        }
+      },
+      "RuleList": {
+        "type": "object",
+        "properties": {
+          "data": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/RuleListItem"
+            }
+          },
+          "total": {
+            "type": "integer",
+            "description": "列表的内容总数",
+            "format": "int32"
+          },
+          "success": {
+            "type": "boolean"
+          }
+        }
+      },
+      "FakeCaptcha": {
+        "type": "object",
+        "properties": {
+          "code": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "status": {
+            "type": "string"
+          }
+        }
+      },
+      "LoginParams": {
+        "type": "object",
+        "properties": {
+          "username": {
+            "type": "string"
+          },
+          "password": {
+            "type": "string"
+          },
+          "autoLogin": {
+            "type": "boolean"
+          },
+          "type": {
+            "type": "string"
+          }
+        }
+      },
+      "ErrorResponse": {
+        "required": ["errorCode"],
+        "type": "object",
+        "properties": {
+          "errorCode": {
+            "type": "string",
+            "description": "业务约定的错误码"
+          },
+          "errorMessage": {
+            "type": "string",
+            "description": "业务上的错误信息"
+          },
+          "success": {
+            "type": "boolean",
+            "description": "业务上的请求是否成功"
+          }
+        }
+      },
+      "NoticeIconList": {
+        "type": "object",
+        "properties": {
+          "data": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/NoticeIconItem"
+            }
+          },
+          "total": {
+            "type": "integer",
+            "description": "列表的内容总数",
+            "format": "int32"
+          },
+          "success": {
+            "type": "boolean"
+          }
+        }
+      },
+      "NoticeIconItemType": {
+        "title": "NoticeIconItemType",
+        "description": "已读未读列表的枚举",
+        "type": "string",
+        "properties": {},
+        "enum": ["notification", "message", "event"]
+      },
+      "NoticeIconItem": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string"
+          },
+          "extra": {
+            "type": "string",
+            "format": "any"
+          },
+          "key": { "type": "string" },
+          "read": {
+            "type": "boolean"
+          },
+          "avatar": {
+            "type": "string"
+          },
+          "title": {
+            "type": "string"
+          },
+          "status": {
+            "type": "string"
+          },
+          "datetime": {
+            "type": "string",
+            "format": "date"
+          },
+          "description": {
+            "type": "string"
+          },
+          "type": {
+            "extensions": {
+              "x-is-enum": true
+            },
+            "$ref": "#/components/schemas/NoticeIconItemType"
+          }
+        }
+      }
+    }
+  }
+}

+ 46 - 0
config/proxy.ts

@@ -0,0 +1,46 @@
+/**
+ * @name 代理的配置
+ * @see 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
+ * -------------------------------
+ * The agent cannot take effect in the production environment
+ * so there is no configuration of the production environment
+ * For details, please see
+ * https://pro.ant.design/docs/deploy
+ *
+ * @doc https://umijs.org/docs/guides/proxy
+ */
+export default {
+  // 如果需要自定义本地开发服务器  请取消注释按需调整
+  dev: {
+    '/api/': {
+      target: 'https://api.zanxiangwl.com',
+      changeOrigin: true,
+      pathRewrite: { '/api': '' },
+    },
+    '/gameApi/': {
+      target: 'https://game.84game.cn',//服务器
+      changeOrigin: true,
+      pathRewrite: { '^/gameApi/': '' },
+    },
+  },
+
+  /**
+   * @name 详细的代理配置
+   * @doc https://github.com/chimurai/http-proxy-middleware
+   */
+  test: {
+    // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
+    '/api/': {
+      target: 'https://game.84game.cn',
+      changeOrigin: true,
+      pathRewrite: { '^': '' },
+    },
+  },
+  pre: {
+    '/api/': {
+      target: 'your pre url',
+      changeOrigin: true,
+      pathRewrite: { '^': '' },
+    },
+  },
+};

+ 41 - 0
config/routes.ts

@@ -0,0 +1,41 @@
+/**
+ * @name umi 的路由配置
+ * @description 只支持 path,component,routes,redirect,wrappers,name,icon 的配置
+ * @param path  path 只支持两种占位符配置,第一种是动态参数 :id 的形式,第二种是 * 通配符,通配符只能出现路由字符串的最后。
+ * @param component 配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。
+ * @param routes 配置子路由,通常在需要为多个路径增加 layout 组件时使用。
+ * @param redirect 配置路由跳转
+ * @param wrappers 配置路由组件的包装组件,通过包装组件可以为当前的路由组件组合进更多的功能。 比如,可以用于路由级别的权限校验
+ * @param name 配置路由的标题,默认读取国际化文件 menu.ts 中 menu.xxxx 的值,如配置 name 为 login,则读取 menu.ts 中 menu.login 的取值作为标题
+ * @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 <StepBackwardOutlined /> 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 <UserOutlined /> 则取值应为 user 或者 User
+ * @doc https://umijs.org/docs/guides/routes
+ */
+export default [
+  {
+    path: '/user',
+    layout: false,
+    routes: [
+      {
+        name: 'login',
+        path: '/user/login',
+        component: './user/login',
+      },
+    ],
+  },
+  {
+    path: '/welcome',
+    name: 'welcome',
+    icon: 'smile',
+    layout: false,
+    component: './Welcome',
+  },
+  {
+    path: '/',
+    redirect: '/welcome',
+  },
+  {
+    path: '*',
+    layout: false,
+    component: './404',
+  },
+];

+ 21 - 0
jest.config.ts

@@ -0,0 +1,21 @@
+import { configUmiAlias, createConfig } from '@umijs/max/test';
+
+export default async (): Promise<any> => {
+  const config = await configUmiAlias({
+    ...createConfig({
+      target: 'browser',
+    }),
+  });
+  return {
+    ...config,
+    testEnvironmentOptions: {
+      ...(config?.testEnvironmentOptions || {}),
+      url: 'http://localhost:8000',
+    },
+    setupFiles: [...(config.setupFiles || []), './tests/setupTests.jsx'],
+    globals: {
+      ...config.globals,
+      localStorage: null,
+    },
+  };
+};

+ 187 - 0
mock/listTableList.ts

@@ -0,0 +1,187 @@
+import { parse } from 'node:url';
+import dayjs from 'dayjs';
+import type { Request, Response } from 'express';
+
+// mock tableListDataSource
+const genList = (current: number, pageSize: number) => {
+  const tableListDataSource: API.RuleListItem[] = [];
+
+  for (let i = 0; i < pageSize; i += 1) {
+    const index = (current - 1) * 10 + i;
+    tableListDataSource.push({
+      key: index,
+      disabled: i % 6 === 0,
+      href: 'https://ant.design',
+      avatar: [
+        'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+      ][i % 2],
+      name: `TradeCode ${index}`,
+      owner: '曲丽丽',
+      desc: '这是一段描述',
+      callNo: Math.floor(Math.random() * 1000),
+      status: Math.floor(Math.random() * 10) % 4,
+      updatedAt: dayjs().format('YYYY-MM-DD'),
+      createdAt: dayjs().format('YYYY-MM-DD'),
+      progress: Math.ceil(Math.random() * 100),
+    });
+  }
+  tableListDataSource.reverse();
+  return tableListDataSource;
+};
+
+let tableListDataSource = genList(1, 100);
+
+function getRule(req: Request, res: Response, u: string) {
+  let realUrl = u;
+  if (
+    !realUrl ||
+    Object.prototype.toString.call(realUrl) !== '[object String]'
+  ) {
+    realUrl = req.url;
+  }
+  const { current = 1, pageSize = 10 } = req.query;
+  const params = parse(realUrl, true).query as unknown as API.PageParams &
+    API.RuleListItem & {
+      sorter: any;
+      filter: any;
+    };
+
+  let dataSource = [...tableListDataSource].slice(
+    ((current as number) - 1) * (pageSize as number),
+    (current as number) * (pageSize as number),
+  );
+  if (params.sorter) {
+    const sorter = JSON.parse(params.sorter);
+    dataSource = dataSource.sort((prev, next) => {
+      let sortNumber = 0;
+      (Object.keys(sorter) as Array<keyof API.RuleListItem>).forEach((key) => {
+        const nextSort = next?.[key] as number;
+        const preSort = prev?.[key] as number;
+        if (sorter[key] === 'descend') {
+          if (preSort - nextSort > 0) {
+            sortNumber += -1;
+          } else {
+            sortNumber += 1;
+          }
+          return;
+        }
+        if (preSort - nextSort > 0) {
+          sortNumber += 1;
+        } else {
+          sortNumber += -1;
+        }
+      });
+      return sortNumber;
+    });
+  }
+  if (params.filter) {
+    const filter = JSON.parse(params.filter as any) as {
+      [key: string]: string[];
+    };
+    if (Object.keys(filter).length > 0) {
+      dataSource = dataSource.filter((item) => {
+        return (Object.keys(filter) as Array<keyof API.RuleListItem>).some(
+          (key) => {
+            if (!filter[key]) {
+              return true;
+            }
+            if (filter[key].includes(`${item[key]}`)) {
+              return true;
+            }
+            return false;
+          },
+        );
+      });
+    }
+  }
+
+  if (params.name) {
+    dataSource = dataSource.filter((data) =>
+      data?.name?.includes(params.name || ''),
+    );
+  }
+  const result = {
+    data: dataSource,
+    total: tableListDataSource.length,
+    success: true,
+    pageSize,
+    current: parseInt(`${params.current}`, 10) || 1,
+  };
+
+  return res.json(result);
+}
+
+function postRule(req: Request, res: Response, u: string, b: Request) {
+  let realUrl = u;
+  if (
+    !realUrl ||
+    Object.prototype.toString.call(realUrl) !== '[object String]'
+  ) {
+    realUrl = req.url;
+  }
+
+  const body = b?.body || req.body;
+  const { method, name, desc, key } = body;
+
+  switch (method) {
+    case 'delete':
+      tableListDataSource = tableListDataSource.filter(
+        (item) => key.indexOf(item.key) === -1,
+      );
+      break;
+    case 'post':
+      (() => {
+        const i = Math.ceil(Math.random() * 10000);
+        const newRule: API.RuleListItem = {
+          key: tableListDataSource.length,
+          href: 'https://ant.design',
+          avatar: [
+            'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+            'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+          ][i % 2],
+          name,
+          owner: '曲丽丽',
+          desc,
+          callNo: Math.floor(Math.random() * 1000),
+          status: Math.floor(Math.random() * 10) % 2,
+          updatedAt: dayjs().format('YYYY-MM-DD'),
+          createdAt: dayjs().format('YYYY-MM-DD'),
+          progress: Math.ceil(Math.random() * 100),
+        };
+        tableListDataSource.unshift(newRule);
+        return res.json(newRule);
+      })();
+      return;
+
+    case 'update':
+      (() => {
+        let newRule = {};
+        tableListDataSource = tableListDataSource.map((item) => {
+          if (item.key === key) {
+            newRule = { ...item, desc, name };
+            return { ...item, desc, name };
+          }
+          return item;
+        });
+        return res.json(newRule);
+      })();
+      return;
+    default:
+      break;
+  }
+
+  const result = {
+    list: tableListDataSource,
+    pagination: {
+      total: tableListDataSource.length,
+    },
+  };
+
+  res.json(result);
+}
+
+export default {
+  'GET /api/rule': getRule,
+  'POST /api/rule': postRule,
+};

+ 14 - 0
mock/monitor.mock.ts

@@ -0,0 +1,14 @@
+import type { Request, Response } from 'express';
+import mockjs from 'mockjs';
+
+const getTags = (_: Request, res: Response) => {
+  return res.json({
+    data: mockjs.mock({
+      'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }],
+    }),
+  });
+};
+
+export default {
+  'GET  /api/tags': getTags,
+};

+ 117 - 0
mock/notices.ts

@@ -0,0 +1,117 @@
+import type { Request, Response } from 'express';
+
+const getNotices = (_req: Request, res: Response) => {
+  res.json({
+    data: [
+      {
+        id: '000000001',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/MSbDR4FR2MUAAAAAAAAAAAAAFl94AQBr',
+        title: '你收到了 14 份新周报',
+        datetime: '2017-08-09',
+        type: 'notification',
+      },
+      {
+        id: '000000002',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/hX-PTavYIq4AAAAAAAAAAAAAFl94AQBr',
+        title: '你推荐的 曲妮妮 已通过第三轮面试',
+        datetime: '2017-08-08',
+        type: 'notification',
+      },
+      {
+        id: '000000003',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/jHX5R5l3QjQAAAAAAAAAAAAAFl94AQBr',
+        title: '这种模板可以区分多种通知类型',
+        datetime: '2017-08-07',
+        read: true,
+        type: 'notification',
+      },
+      {
+        id: '000000004',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/Wr4mQqx6jfwAAAAAAAAAAAAAFl94AQBr',
+        title: '左侧图标用于区分不同的类型',
+        datetime: '2017-08-07',
+        type: 'notification',
+      },
+      {
+        id: '000000005',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/Mzj_TbcWUj4AAAAAAAAAAAAAFl94AQBr',
+        title: '内容不要超过两行字,超出时自动截断',
+        datetime: '2017-08-07',
+        type: 'notification',
+      },
+      {
+        id: '000000006',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/eXLzRbPqQE4AAAAAAAAAAAAAFl94AQBr',
+        title: '曲丽丽 评论了你',
+        description: '描述信息描述信息描述信息',
+        datetime: '2017-08-07',
+        type: 'message',
+        clickClose: true,
+      },
+      {
+        id: '000000007',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/w5mRQY2AmEEAAAAAAAAAAAAAFl94AQBr',
+        title: '朱偏右 回复了你',
+        description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
+        datetime: '2017-08-07',
+        type: 'message',
+        clickClose: true,
+      },
+      {
+        id: '000000008',
+        avatar:
+          'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/wPadR5M9918AAAAAAAAAAAAAFl94AQBr',
+        title: '标题',
+        description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
+        datetime: '2017-08-07',
+        type: 'message',
+        clickClose: true,
+      },
+      {
+        id: '000000009',
+        title: '任务名称',
+        description: '任务需要在 2017-01-12 20:00 前启动',
+        extra: '未开始',
+        status: 'todo',
+        type: 'event',
+      },
+      {
+        id: '000000010',
+        title: '第三方紧急代码变更',
+        description:
+          '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
+        extra: '马上到期',
+        status: 'urgent',
+        type: 'event',
+      },
+      {
+        id: '000000011',
+        title: '信息安全考试',
+        description: '指派竹尔于 2017-01-09 前完成更新并发布',
+        extra: '已耗时 8 天',
+        status: 'doing',
+        type: 'event',
+      },
+      {
+        id: '000000012',
+        title: 'ABCD 版本发布',
+        description:
+          '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
+        extra: '进行中',
+        status: 'processing',
+        type: 'event',
+      },
+    ],
+  });
+};
+
+export default {
+  'GET /api/notices': getNotices,
+};

+ 345 - 0
mock/requestRecord.mock.js

@@ -0,0 +1,345 @@
+module.exports = {
+  'GET /api/currentUser': {
+    data: {
+      name: 'Serati Ma',
+      avatar:
+        'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
+      userid: '00000001',
+      email: 'antdesign@alipay.com',
+      signature: '海纳百川,有容乃大',
+      title: '交互专家',
+      group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED',
+      tags: [
+        { key: '0', label: '很有想法的' },
+        { key: '1', label: '专注设计' },
+        { key: '2', label: '辣~' },
+        { key: '3', label: '大长腿' },
+        { key: '4', label: '川妹子' },
+        { key: '5', label: '海纳百川' },
+      ],
+      notifyCount: 12,
+      unreadCount: 11,
+      country: 'China',
+      geographic: {
+        province: { label: '浙江省', key: '330000' },
+        city: { label: '杭州市', key: '330100' },
+      },
+      address: '西湖区工专路 77 号',
+      phone: '0752-268888888',
+    },
+  },
+  'GET /api/rule': {
+    data: [
+      {
+        key: 99,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 99',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 503,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 81,
+      },
+      {
+        key: 98,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 98',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 164,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 12,
+      },
+      {
+        key: 97,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 97',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 174,
+        status: '1',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 81,
+      },
+      {
+        key: 96,
+        disabled: true,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 96',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 914,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 7,
+      },
+      {
+        key: 95,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 95',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 698,
+        status: '2',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 82,
+      },
+      {
+        key: 94,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 94',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 488,
+        status: '1',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 14,
+      },
+      {
+        key: 93,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 93',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 580,
+        status: '2',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 77,
+      },
+      {
+        key: 92,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 92',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 244,
+        status: '3',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 58,
+      },
+      {
+        key: 91,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 91',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 959,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 66,
+      },
+      {
+        key: 90,
+        disabled: true,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 90',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 958,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 72,
+      },
+      {
+        key: 89,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 89',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 301,
+        status: '2',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 2,
+      },
+      {
+        key: 88,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 88',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 277,
+        status: '1',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 12,
+      },
+      {
+        key: 87,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 87',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 810,
+        status: '1',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 82,
+      },
+      {
+        key: 86,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 86',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 780,
+        status: '3',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 22,
+      },
+      {
+        key: 85,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 85',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 705,
+        status: '3',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 12,
+      },
+      {
+        key: 84,
+        disabled: true,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 84',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 203,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 79,
+      },
+      {
+        key: 83,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 83',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 491,
+        status: '2',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 59,
+      },
+      {
+        key: 82,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 82',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 73,
+        status: '0',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 100,
+      },
+      {
+        key: 81,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+        name: 'TradeCode 81',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 406,
+        status: '3',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 61,
+      },
+      {
+        key: 80,
+        disabled: false,
+        href: 'https://ant.design',
+        avatar:
+          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+        name: 'TradeCode 80',
+        owner: '曲丽丽',
+        desc: '这是一段描述',
+        callNo: 112,
+        status: '2',
+        updatedAt: '2022-12-06T05:00:57.040Z',
+        createdAt: '2022-12-06T05:00:57.040Z',
+        progress: 20,
+      },
+    ],
+    total: 100,
+    success: true,
+    pageSize: 20,
+    current: 1,
+  },
+  'POST /api/login/outLogin': { data: {}, success: true },
+  'POST /api/login/account': {
+    status: 'ok',
+    type: 'account',
+    currentAuthority: 'admin',
+  },
+};

+ 5 - 0
mock/route.ts

@@ -0,0 +1,5 @@
+export default {
+  '/api/auth_routes': {
+    '/form/advanced-form': { authority: ['admin', 'user'] },
+  },
+};

+ 205 - 0
mock/user.ts

@@ -0,0 +1,205 @@
+import type { Request, Response } from 'express';
+
+const waitTime = (time: number = 100) => {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      resolve(true);
+    }, time);
+  });
+};
+
+async function getFakeCaptcha(_req: Request, res: Response) {
+  await waitTime(2000);
+  return res.json('captcha-xxx');
+}
+
+const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env;
+
+/**
+ * 当前用户的权限,如果为空代表没登录
+ * current user access, if is '', user need login
+ * 如果是 pro 的预览,默认是有权限的
+ */
+let access =
+  ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' ? 'admin' : '';
+
+const getAccess = () => {
+  return access;
+};
+
+// 代码中会兼容本地 service mock 以及部署站点的静态数据
+export default {
+  // 支持值为 Object 和 Array
+  'GET /api/currentUser': (_req: Request, res: Response) => {
+    if (!getAccess()) {
+      res.status(401).send({
+        data: {
+          isLogin: false,
+        },
+        errorCode: '401',
+        errorMessage: '请先登录!',
+        success: true,
+      });
+      return;
+    }
+    res.send({
+      success: true,
+      data: {
+        name: 'Serati Ma',
+        avatar:
+          'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png',
+        userid: '00000001',
+        email: 'antdesign@alipay.com',
+        signature: '海纳百川,有容乃大',
+        title: '交互专家',
+        group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED',
+        tags: [
+          {
+            key: '0',
+            label: '很有想法的',
+          },
+          {
+            key: '1',
+            label: '专注设计',
+          },
+          {
+            key: '2',
+            label: '辣~',
+          },
+          {
+            key: '3',
+            label: '大长腿',
+          },
+          {
+            key: '4',
+            label: '川妹子',
+          },
+          {
+            key: '5',
+            label: '海纳百川',
+          },
+        ],
+        notifyCount: 12,
+        unreadCount: 11,
+        country: 'China',
+        access: getAccess(),
+        geographic: {
+          province: {
+            label: '浙江省',
+            key: '330000',
+          },
+          city: {
+            label: '杭州市',
+            key: '330100',
+          },
+        },
+        address: '西湖区工专路 77 号',
+        phone: '0752-268888888',
+      },
+    });
+  },
+  // GET POST 可省略
+  'GET /api/users': [
+    {
+      key: '1',
+      name: 'John Brown',
+      age: 32,
+      address: 'New York No. 1 Lake Park',
+    },
+    {
+      key: '2',
+      name: 'Jim Green',
+      age: 42,
+      address: 'London No. 1 Lake Park',
+    },
+    {
+      key: '3',
+      name: 'Joe Black',
+      age: 32,
+      address: 'Sidney No. 1 Lake Park',
+    },
+  ],
+  'POST /api/login/account': async (req: Request, res: Response) => {
+    const { password, username, type } = req.body;
+    await waitTime(2000);
+    if (password === 'ant.design' && username === 'admin') {
+      res.send({
+        status: 'ok',
+        type,
+        currentAuthority: 'admin',
+      });
+      access = 'admin';
+      return;
+    }
+    if (password === 'ant.design' && username === 'user') {
+      res.send({
+        status: 'ok',
+        type,
+        currentAuthority: 'user',
+      });
+      access = 'user';
+      return;
+    }
+    if (type === 'mobile') {
+      res.send({
+        status: 'ok',
+        type,
+        currentAuthority: 'admin',
+      });
+      access = 'admin';
+      return;
+    }
+
+    res.send({
+      status: 'error',
+      type,
+      currentAuthority: 'guest',
+    });
+    access = 'guest';
+  },
+  'POST /api/login/outLogin': (_req: Request, res: Response) => {
+    access = '';
+    res.send({ data: {}, success: true });
+  },
+  'POST /api/register': (_req: Request, res: Response) => {
+    res.send({ status: 'ok', currentAuthority: 'user', success: true });
+  },
+  'GET /api/500': (_req: Request, res: Response) => {
+    res.status(500).send({
+      timestamp: 1513932555104,
+      status: 500,
+      error: 'error',
+      message: 'error',
+      path: '/base/category/list',
+    });
+  },
+  'GET /api/404': (_req: Request, res: Response) => {
+    res.status(404).send({
+      timestamp: 1513932643431,
+      status: 404,
+      error: 'Not Found',
+      message: 'No message available',
+      path: '/base/category/list/2121212',
+    });
+  },
+  'GET /api/403': (_req: Request, res: Response) => {
+    res.status(403).send({
+      timestamp: 1513932555104,
+      status: 403,
+      error: 'Forbidden',
+      message: 'Forbidden',
+      path: '/base/category/list',
+    });
+  },
+  'GET /api/401': (_req: Request, res: Response) => {
+    res.status(401).send({
+      timestamp: 1513932555104,
+      status: 401,
+      error: 'Unauthorized',
+      message: 'Unauthorized',
+      path: '/base/category/list',
+    });
+  },
+
+  'GET  /api/login/captcha': getFakeCaptcha,
+};

+ 80 - 0
package.json

@@ -0,0 +1,80 @@
+{
+  "name": "ant-design-pro",
+  "version": "6.0.0",
+  "private": true,
+  "description": "An out-of-box UI solution for enterprise applications",
+  "repository": "git@github.com:ant-design/ant-design-pro.git",
+  "scripts": {
+    "analyze": "cross-env ANALYZE=1 max build",
+    "biome:lint": "npx @biomejs/biome lint",
+    "build": "max build",
+    "deploy": "npm run build && npm run gh-pages",
+    "dev": "npm run start:dev",
+    "gh-pages": "gh-pages -d dist",
+    "i18n-remove": "pro i18n-remove --locale=zh-CN --write",
+    "postinstall": "max setup",
+    "jest": "jest",
+    "lint": "npm run biome:lint && npm run tsc",
+    "lint-staged": "lint-staged",
+    "openapi": "max openapi",
+    "prepare": "husky",
+    "preview": "npm run build && max preview --port 8000",
+    "record": "cross-env NODE_ENV=development REACT_APP_ENV=test max record --scene=login",
+    "serve": "umi-serve",
+    "start": "cross-env UMI_ENV=dev max dev",
+    "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev max dev",
+    "start:no-mock": "cross-env MOCK=none UMI_ENV=dev max dev",
+    "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev max dev",
+    "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev max dev",
+    "test": "jest",
+    "test:coverage": "npm run jest -- --coverage",
+    "test:update": "npm run jest -- -u",
+    "tsc": "tsc --noEmit"
+  },
+  "browserslist": [
+    "defaults"
+  ],
+  "dependencies": {
+    "@ant-design/icons": "^5.6.1",
+    "@ant-design/pro-components": "^2.7.19",
+    "@ant-design/v5-patch-for-react-19": "^1.0.3",
+    "antd": "^5.25.4",
+    "antd-style": "^3.7.0",
+    "classnames": "^2.5.1",
+    "dayjs": "^1.11.13",
+    "framer-motion": "^12.23.12",
+    "react": "^19.1.0",
+    "react-dom": "^19.1.0"
+  },
+  "devDependencies": {
+    "@ant-design/pro-cli": "^3.3.0",
+    "@biomejs/biome": "^2.0.6",
+    "@commitlint/cli": "^19.5.0",
+    "@commitlint/config-conventional": "^19.5.0",
+    "@testing-library/dom": "^10.4.0",
+    "@testing-library/react": "^16.0.1",
+    "@types/express": "^5.0.3",
+    "@types/jest": "^30.0.0",
+    "@types/lodash": "^4.17.10",
+    "@types/node": "^24.0.10",
+    "@types/react": "^19.1.5",
+    "@types/react-dom": "^19.1.5",
+    "@types/react-helmet": "^6.1.11",
+    "@umijs/max": "^4.3.24",
+    "cross-env": "^7.0.3",
+    "express": "^4.21.1",
+    "gh-pages": "^6.1.1",
+    "husky": "^9.1.7",
+    "jest": "^30.0.4",
+    "jest-environment-jsdom": "^29.7.0",
+    "lint-staged": "^16.1.2",
+    "mockjs": "^1.1.0",
+    "ts-node": "^10.9.2",
+    "typescript": "^5.6.3",
+    "umi-presets-pro": "^2.0.3",
+    "umi-serve": "^1.9.11"
+  },
+  "engines": {
+    "node": ">=20.0.0"
+  }
+}

+ 1 - 0
public/CNAME

@@ -0,0 +1 @@
+preview.pro.ant.design

BIN
public/favicon.ico


BIN
public/icons/icon-128x128.png


BIN
public/icons/icon-192x192.png


BIN
public/icons/icon-512x512.png


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
public/logo.svg


+ 5 - 0
public/pro_icon.svg

@@ -0,0 +1,5 @@
+<svg width="42" height="42" xmlns="http://www.w3.org/2000/svg">
+ <g>
+  <path fill="#070707" d="m6.717392,13.773912l5.6,0c2.8,0 4.7,1.9 4.7,4.7c0,2.8 -2,4.7 -4.9,4.7l-2.5,0l0,4.3l-2.9,0l0,-13.7zm2.9,2.2l0,4.9l1.9,0c1.6,0 2.6,-0.9 2.6,-2.4c0,-1.6 -0.9,-2.4 -2.6,-2.4l-1.9,0l0,-0.1zm8.9,11.5l2.7,0l0,-5.7c0,-1.4 0.8,-2.3 2.2,-2.3c0.4,0 0.8,0.1 1,0.2l0,-2.4c-0.2,-0.1 -0.5,-0.1 -0.8,-0.1c-1.2,0 -2.1,0.7 -2.4,2l-0.1,0l0,-1.9l-2.7,0l0,10.2l0.1,0zm11.7,0.1c-3.1,0 -5,-2 -5,-5.3c0,-3.3 2,-5.3 5,-5.3s5,2 5,5.3c0,3.4 -1.9,5.3 -5,5.3zm0,-2.1c1.4,0 2.2,-1.1 2.2,-3.2c0,-2 -0.8,-3.2 -2.2,-3.2c-1.4,0 -2.2,1.2 -2.2,3.2c0,2.1 0.8,3.2 2.2,3.2z" class="st0" id="Ant-Design-Pro"/>
+ </g>
+</svg>

+ 202 - 0
public/scripts/loading.js

@@ -0,0 +1,202 @@
+/**
+ * loading 占位
+ * 解决首次加载时白屏的问题
+ */
+(function () {
+  const _root = document.querySelector('#root');
+  if (_root && _root.innerHTML === '') {
+    _root.innerHTML = `
+      <style>
+        html,
+        body,
+        #root {
+          height: 100%;
+          margin: 0;
+          padding: 0;
+        }
+        #root {
+          background-repeat: no-repeat;
+          background-size: 100% auto;
+        }
+
+        .loading-title {
+          font-size: 1.1rem;
+        }
+
+        .loading-sub-title {
+          margin-top: 20px;
+          font-size: 1rem;
+          color: #888;
+        }
+
+        .page-loading-warp {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          padding: 26px;
+        }
+        .ant-spin {
+          position: absolute;
+          display: none;
+          -webkit-box-sizing: border-box;
+          box-sizing: border-box;
+          margin: 0;
+          padding: 0;
+          color: rgba(0, 0, 0, 0.65);
+          color: #1890ff;
+          font-size: 14px;
+          font-variant: tabular-nums;
+          line-height: 1.5;
+          text-align: center;
+          list-style: none;
+          opacity: 0;
+          -webkit-transition: -webkit-transform 0.3s
+            cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: -webkit-transform 0.3s
+            cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86),
+            -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          -webkit-font-feature-settings: "tnum";
+          font-feature-settings: "tnum";
+        }
+
+        .ant-spin-spinning {
+          position: static;
+          display: inline-block;
+          opacity: 1;
+        }
+
+        .ant-spin-dot {
+          position: relative;
+          display: inline-block;
+          width: 20px;
+          height: 20px;
+          font-size: 20px;
+        }
+
+        .ant-spin-dot-item {
+          position: absolute;
+          display: block;
+          width: 9px;
+          height: 9px;
+          background-color: #1890ff;
+          border-radius: 100%;
+          -webkit-transform: scale(0.75);
+          -ms-transform: scale(0.75);
+          transform: scale(0.75);
+          -webkit-transform-origin: 50% 50%;
+          -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+          opacity: 0.3;
+          -webkit-animation: antspinmove 1s infinite linear alternate;
+          animation: antSpinMove 1s infinite linear alternate;
+        }
+
+        .ant-spin-dot-item:nth-child(1) {
+          top: 0;
+          left: 0;
+        }
+
+        .ant-spin-dot-item:nth-child(2) {
+          top: 0;
+          right: 0;
+          -webkit-animation-delay: 0.4s;
+          animation-delay: 0.4s;
+        }
+
+        .ant-spin-dot-item:nth-child(3) {
+          right: 0;
+          bottom: 0;
+          -webkit-animation-delay: 0.8s;
+          animation-delay: 0.8s;
+        }
+
+        .ant-spin-dot-item:nth-child(4) {
+          bottom: 0;
+          left: 0;
+          -webkit-animation-delay: 1.2s;
+          animation-delay: 1.2s;
+        }
+
+        .ant-spin-dot-spin {
+          -webkit-transform: rotate(45deg);
+          -ms-transform: rotate(45deg);
+          transform: rotate(45deg);
+          -webkit-animation: antrotate 1.2s infinite linear;
+          animation: antRotate 1.2s infinite linear;
+        }
+
+        .ant-spin-lg .ant-spin-dot {
+          width: 32px;
+          height: 32px;
+          font-size: 32px;
+        }
+
+        .ant-spin-lg .ant-spin-dot i {
+          width: 14px;
+          height: 14px;
+        }
+
+        @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
+          .ant-spin-blur {
+            background: #fff;
+            opacity: 0.5;
+          }
+        }
+
+        @-webkit-keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+
+        @keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+
+        @-webkit-keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+
+        @keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+      </style>
+
+      <div style="
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        height: 100%;
+        min-height: 362px;
+      ">
+        <div class="page-loading-warp">
+          <div class="ant-spin ant-spin-lg ant-spin-spinning">
+            <span class="ant-spin-dot ant-spin-dot-spin">
+              <i class="ant-spin-dot-item"></i>
+              <i class="ant-spin-dot-item"></i>
+              <i class="ant-spin-dot-item"></i>
+              <i class="ant-spin-dot-item"></i>
+            </span>
+          </div>
+        </div>
+        <div class="loading-title">
+          正在加载资源
+        </div>
+        <div class="loading-sub-title">
+          初次加载资源可能需要较多时间 请耐心等待
+        </div>
+      </div>
+    `;
+  }
+})();

+ 11 - 0
src/access.ts

@@ -0,0 +1,11 @@
+/**
+ * @see https://umijs.org/docs/max/access#access
+ * */
+export default function access(
+  initialState: { currentUser?: API.CurrentUser } | undefined,
+) {
+  const { currentUser } = initialState ?? {};
+  return {
+    canAdmin: currentUser && currentUser.access === 'admin',
+  };
+}

+ 230 - 0
src/app.tsx

@@ -0,0 +1,230 @@
+import { DesktopOutlined, MessageOutlined, SendOutlined, TeamOutlined } from '@ant-design/icons';
+import type { Settings as LayoutSettings } from '@ant-design/pro-components';
+import { PageLoading, SettingDrawer } from '@ant-design/pro-components';
+import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
+import { history } from '@umijs/max';
+import {
+  AvatarDropdown,
+  AvatarName,
+  Footer,
+} from '@/components';
+import { currentUser as queryCurrentUser } from '@/services/user/api';
+import defaultSettings from '../config/defaultSettings';
+import { errorConfig } from './requestErrorConfig';
+import '@ant-design/v5-patch-for-react-19';
+import { ConfigProvider, Watermark } from 'antd';
+
+const isDev = process.env.NODE_ENV === 'development';
+const loginPath = '/user/login';
+
+/**
+ * @see https://umijs.org/docs/api/runtime-config#getinitialstate
+ * */
+export async function getInitialState(): Promise<{
+  settings?: Partial<LayoutSettings>;
+  currentUser?: API.CurrentUser;
+  loading?: boolean;
+  menu?: any,
+  collapsed?: string,
+  onCollapse?: (onCollapse: boolean) => void
+  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
+}> {
+  const fetchUserInfo = async () => {
+    try {
+      const msg = await queryCurrentUser();
+      return msg.data;
+    } catch (error) {
+      history.push(loginPath);
+    }
+    return undefined;
+  };
+  if (localStorage.getItem('Admin-Token')) {
+    try {
+      sessionStorage.removeItem('IS_MES')
+      const currentUser = await fetchUserInfo();
+      console.log('currentUser', currentUser)
+      if (currentUser) {
+        const { companyRelationInfo, userInfo: { powerLevel, nickname, userId, phone, sex }, onlineCompanyId } = currentUser
+        const companyInfo = companyRelationInfo?.filter((item: { companyId: number }) => item.companyId !== 4 && item.companyId !== 3)
+        localStorage.setItem('sex', sex)
+        localStorage.setItem('userId', userId)
+        localStorage.setItem('name', nickname)
+        const navTheme: any = localStorage.getItem('NAVTHEME')
+        const isNoDark = localStorage.getItem('ISNODARK')
+        return {
+          fetchUserInfo,
+          currentUser: { access: 'admin', powerLevel, name: nickname || '', userId, phone, companyList: companyInfo, onlineCompanyId: onlineCompanyId },
+          settings: { ...defaultSettings as Partial<LayoutSettings>, navTheme: navTheme || defaultSettings.navTheme, isNoDark: JSON.parse(isNoDark || 'false') } as any,
+          loading: false,
+          collapsed: '0',
+          onCollapse: (collapsed: boolean) => {
+            const v = collapsed ? '1' : '0'
+            localStorage.setItem('collapsed', v)
+          }
+        };
+      }
+    } catch (error) {
+      history.push(loginPath);
+    }
+  } else {
+    history.push(loginPath);
+  }
+  return {
+    fetchUserInfo,
+    settings: defaultSettings as Partial<LayoutSettings>,
+  };
+}
+
+
+const IconMap = {
+  desktop: <DesktopOutlined />,
+  message: <MessageOutlined />,
+  send: <SendOutlined />,
+  team: <TeamOutlined />
+};
+
+/** 处理远程路由 */
+const handleMenuData = (menuData: any[]) => {
+  return menuData.map(item => {
+    const data: { [x: string]: any } = {
+      name: item.title,
+      path: item.path,
+      icon: item.icon && IconMap[item.icon as keyof typeof IconMap]
+    }
+    if (item?.component) {
+      data.component = item.component
+    }
+    if (item?.children?.length) {
+      data.routes = handleMenuData(item.children)
+    }
+    return data
+  })
+}
+
+// ProLayout 支持的api https://procomponents.ant.design/components/layout
+export const layout: RunTimeLayoutConfig = ({
+  initialState,
+  setInitialState,
+}) => {
+  
+  return {
+    splitMenus: true,//切割菜单
+    className: initialState?.settings?.navTheme === 'realDark' ? 'css-realDark' : (initialState?.settings as any)?.isNoDark ? 'css-light' : 'css-dark',
+    avatarProps: {
+      src: initialState?.currentUser?.avatar || 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
+      title: <AvatarName />,
+      render: (_, avatarChildren) => {
+        return <AvatarDropdown>{avatarChildren}</AvatarDropdown>;
+      },
+    },
+    footerRender: () => <Footer />,
+    onPageChange: (location) => {
+      // 如果没有登录,重定向到 login
+      if (location?.pathname !== loginPath && !localStorage.getItem('Admin-Token')) {
+        history.push(loginPath);
+      }
+      if (initialState?.currentUser && location?.pathname !== loginPath) {
+        let menu = []
+        if (initialState?.menu) {
+          menu = Object.values(initialState?.menu).map((item: unknown) => {
+            if (Array.isArray(item)) {
+              return item[0];
+            }
+            return null; // 或者根据业务逻辑返回默认值
+          }).filter(Boolean) as any[]
+        }
+        if (menu?.length) {
+          switch (location?.pathname) {
+            case '/':
+              history.push(menu?.[0]?.children?.[0]?.path)
+              break;
+          }
+        }
+      }
+    },
+    bgLayoutImgList: [
+      {
+        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
+        left: 85,
+        bottom: 100,
+        height: '303px',
+      },
+      {
+        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
+        bottom: -68,
+        right: -45,
+        height: '303px',
+      },
+      {
+        src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
+        bottom: 0,
+        left: 0,
+        width: '331px',
+      }
+    ],
+    menuHeaderRender: undefined,
+    // 自定义 403 页面
+    // unAccessible: <div>unAccessible</div>,
+    // 增加一个 loading 的状态
+    childrenRender: (children) => {
+      if (initialState?.loading) return <PageLoading />;
+      return (<ConfigProvider
+        componentSize='middle'
+        theme={initialState?.settings?.navTheme === 'realDark' ? undefined : {
+          components: {
+            Table: {
+              colorBorderSecondary: '#e0e0e0',
+              headerBg: '#F5F5F5'
+            },
+            Menu: {
+              fontSizeSM: 20,
+              fontSizeXL: 20,
+              fontSize: 20,
+              fontSizeLG: 20
+            }
+          }
+        }}
+      >
+        <Watermark
+          content={initialState?.currentUser?.name}
+          font={{
+            color: 'rgba(255, 0, 0, 0.06)',
+            fontSize: 20,
+            fontWeight: 600,
+          }}
+          gap={[50, 100]}
+        >
+          {children}
+          {isDev && (
+            <SettingDrawer
+              disableUrlParams
+              enableDarkTheme
+              settings={initialState?.settings}
+              onSettingChange={(settings) => {
+                setInitialState((preInitialState) => ({
+                  ...preInitialState,
+                  settings,
+                }));
+              }}
+            />
+          )}
+        </Watermark>
+      </ConfigProvider>);
+    },
+    ...initialState?.settings
+  };
+};
+
+/**
+ * @name request 配置,可以配置错误处理
+ * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
+ * @doc https://umijs.org/docs/max/request#配置
+ */
+export const request: RequestConfig = {
+  ...errorConfig,
+  timeout: 300000,
+  headers: {
+    ['Authorization']: 'Bearer ' + localStorage.getItem('Admin-Token'),
+    ['debug']: sessionStorage.getItem('debug') || ''
+  }
+};

+ 1 - 0
src/assets/icons/book.svg

@@ -0,0 +1 @@
+<svg viewBox="64 64 896 896" focusable="false" data-icon="fund-view" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M813.25000001 64L461.25 64l-192 0L237.25000001 64C166.658 64 109.25 121.408 109.25 192l0 640c0 70.592 57.408 128 128.00000001 128l576 0c70.592 0 128-57.408 128-128L941.25000001 192C941.25000001 121.408 883.842 64 813.25000001 64zM429.25 128l0 296.256L381.37800001 396.352C376.386 393.408 370.818 392 365.25 392S354.114 393.408 349.122 396.352L301.25000001 424.256 301.25000001 128 429.25 128zM877.25000001 832c0 35.328-28.672 64-64 64L237.25000001 896c-35.264 0-64-28.672-64.00000001-64L173.25 192c0-35.264 28.736-64 64.00000001-64l0 352c0 11.456 6.144 22.016 16.06399999 27.776 9.92 5.76 22.208 5.632 32.064-0.064L365.25 461.056l79.872 46.656C450.114 510.528 455.68200001 512 461.25 512c5.504 0 11.008-1.408 15.936-4.224C487.106 502.016 493.25 491.456 493.25 480L493.25 128l320.00000001 0c35.328 0 64 28.736 64 64L877.25000001 832z" fill="currentColor" p-id="18287"></path></svg>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icons/corpChat.svg


+ 1 - 0
src/assets/icons/game.svg

@@ -0,0 +1 @@
+<svg viewBox="64 64 896 896" focusable="false" data-icon="fund-view" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M470.7 641.2m-104.3 0a104.3 104.3 0 1 0 208.6 0 104.3 104.3 0 1 0-208.6 0Z" fill="#A5E8D0" p-id="26792"></path><path d="M710.5 710m-47.4 0a47.4 47.4 0 1 0 94.8 0 47.4 47.4 0 1 0-94.8 0Z" fill="currentColor" p-id="26793"></path><path d="M783.4 615.3m-33.5 0a33.5 33.5 0 1 0 67 0 33.5 33.5 0 1 0-67 0Z" fill="currentColor" p-id="26794"></path><path d="M664.8 375.4H507.6c7-33.9 23.4-78.4 61.6-78.7 80.8-0.7 114.7-64.1 125.5-118 4.3-21.5-12.1-41.5-34-41.3-16.2 0.1-30.4 11.5-33.4 27.4-5 26.5-19 62.7-58.8 63-85.8 0.8-121.1 81.6-131.4 147.6h-58.3C232.2 375.4 113 494.6 113 641.2 113 787.8 232.2 907 378.8 907h285.9c146.6 0 265.8-119.2 265.8-265.8 0.1-146.6-119.1-265.8-265.7-265.8z m0 462.7H378.9c-108.6 0-196.9-88.3-196.9-196.9 0-108.6 88.3-196.9 196.9-196.9h285.9c108.6 0 196.9 88.3 196.9 196.9 0 108.6-88.3 196.9-196.9 196.9z" fill="currentColor" p-id="26795"></path><path d="M358.2 537.5c-57.2 0-103.7 46.5-103.7 103.7S301 744.9 358.2 744.9s103.7-46.5 103.7-103.7-46.5-103.7-103.7-103.7z m0 137.2c-18.5 0-33.5-15-33.5-33.5s15-33.5 33.5-33.5 33.5 15 33.5 33.5-15 33.5-33.5 33.5z" fill="currentColor" p-id="26796"></path></svg>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icons/gameSystem.svg


+ 1 - 0
src/assets/icons/image.svg

@@ -0,0 +1 @@
+<svg viewBox="64 64 896 896" focusable="false" data-icon="fund-view" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M254.976 448.512q27.648 0 47.104 19.456t19.456 47.104q0 26.624-19.456 46.592t-47.104 19.968-47.104-19.968-19.456-46.592q0-27.648 19.456-47.104t47.104-19.456zM771.072 66.56q45.056 0 79.872 15.872t58.88 40.96 36.864 56.832 12.8 62.464l0 523.264q0 23.552-10.752 46.08t-28.672 40.96-40.96 29.696-47.616 11.264l0-572.416q0-26.624-10.24-49.664t-27.648-40.448-40.448-27.648-49.664-10.24l-575.488 0q0-22.528 10.24-45.056t27.648-40.96 40.96-29.696 50.176-11.264l514.048 0zM681.984 258.048q46.08 0 65.536 25.088t19.456 67.072l0 603.136q0 25.6-21.504 48.128t-54.272 22.528l-620.544 0q-27.648 0-49.152-22.528t-21.504-54.272l0-614.4q0-32.768 17.92-53.76t47.616-20.992l616.448 0zM640 413.696q0-11.264-7.168-18.432t-18.432-7.168l-461.824 0q-11.264 0-18.432 7.168t-7.168 18.432l0 228.352q9.216 11.264 16.896 25.088t18.944 26.112 29.696 20.992 51.2 8.704q48.128 0 78.336-15.36t53.248-38.912 43.008-50.688 47.616-51.2 68.608-40.96 105.472-18.944l0-93.184z" p-id="28038"></path></svg>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
src/assets/icons/tencentAd.svg


+ 1 - 0
src/assets/icons/weChatData.svg

@@ -0,0 +1 @@
+<svg viewBox="64 64 896 896" focusable="false" data-icon="fund-view" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M995.837 449.01L900 353.173V217.686c0-50.237-40.725-90.958-90.962-90.958H673.552l-95.838-95.836c-35.407-35.413-93.08-35.413-128.704 0l-95.837 95.836H217.687a90.958 90.958 0 0 0-90.958 90.957v135.488L30.893 449.01c-35.414 35.409-35.414 93.08 0 128.703l95.836 95.838v135.487a90.952 90.952 0 0 0 26.64 64.316 90.954 90.954 0 0 0 64.318 26.644h135.486l95.837 95.838c35.409 35.409 93.08 35.409 128.704 0l95.838-95.838h135.486a90.95 90.95 0 0 0 64.317-26.644A90.948 90.948 0 0 0 900 809.038V673.551l95.837-95.838a90.852 90.852 0 0 0 0-128.703z m-248.286-26.078L452.192 672.916c-8.271 6.993-18.661 10.81-29.469 10.81-1.274 0-2.549 0-4.031-0.21-12.088-1.059-23.321-6.785-30.958-16.113L274.088 531.065c-16.112-19.294-13.57-47.915 5.724-64.034 19.296-16.115 47.917-13.356 64.029 5.73l84.39 101.137 260.584-220.512c19.296-16.113 47.921-13.785 64.035 5.301 16.324 19.294 13.991 48.132-5.299 64.245z m0 0" fill="currentColor" p-id="9123"></path></svg>

BIN
src/assets/image/qucheng.png


+ 15 - 0
src/components/Footer/index.tsx

@@ -0,0 +1,15 @@
+import { DefaultFooter } from '@ant-design/pro-components';
+import React from 'react';
+
+const Footer: React.FC = () => {
+  return (
+    <DefaultFooter
+      copyright="2025 Copyright 趣程"
+      style={{
+        background: 'none',
+      }}
+    />
+  );
+};
+
+export default Footer;

+ 41 - 0
src/components/HeaderDropdown/index.tsx

@@ -0,0 +1,41 @@
+import { Dropdown } from 'antd';
+import type { DropDownProps } from 'antd/es/dropdown';
+import { createStyles } from 'antd-style';
+import classNames from 'classnames';
+import React from 'react';
+
+const useStyles = createStyles(({ token }) => {
+  return {
+    dropdown: {
+      [`@media screen and (max-width: ${token.screenXS}px)`]: {
+        width: '100%',
+      },
+    },
+  };
+});
+
+export type HeaderDropdownProps = {
+  overlayClassName?: string;
+  placement?:
+    | 'bottomLeft'
+    | 'bottomRight'
+    | 'topLeft'
+    | 'topCenter'
+    | 'topRight'
+    | 'bottomCenter';
+} & Omit<DropDownProps, 'overlay'>;
+
+const HeaderDropdown: React.FC<HeaderDropdownProps> = ({
+  overlayClassName: cls,
+  ...restProps
+}) => {
+  const { styles } = useStyles();
+  return (
+    <Dropdown
+      overlayClassName={classNames(styles.dropdown, cls)}
+      {...restProps}
+    />
+  );
+};
+
+export default HeaderDropdown;

+ 156 - 0
src/components/RightContent/AvatarDropdown.tsx

@@ -0,0 +1,156 @@
+import { outLogin, selectCompanyApi } from '@/services/user/api';
+import { LogoutOutlined, SwapOutlined } from '@ant-design/icons';
+import { history, useModel, useRequest } from '@umijs/max';
+import { Spin } from 'antd';
+import { createStyles } from 'antd-style';
+import { stringify } from 'querystring';
+import type { MenuInfo } from 'rc-menu/lib/interface';
+import React, { useCallback, useState } from 'react';
+import { flushSync } from 'react-dom';
+import HeaderDropdown from '../HeaderDropdown';
+import SwitchCompany from '@/pages/user/login/switchCompany';
+
+export type GlobalHeaderRightProps = {
+  children?: React.ReactNode;
+};
+
+export const AvatarName = () => {
+  const { initialState } = useModel('@@initialState');
+  const { currentUser } = initialState || {};
+  return <span className="anticon">{currentUser?.name}</span>;
+};
+
+const useStyles = createStyles(({ token }) => {
+  return {
+    action: {
+      display: 'flex',
+      height: '48px',
+      marginLeft: 'auto',
+      overflow: 'hidden',
+      alignItems: 'center',
+      padding: '0 8px',
+      cursor: 'pointer',
+      borderRadius: token.borderRadius,
+      '&:hover': {
+        backgroundColor: token.colorBgTextHover,
+      },
+    },
+  };
+});
+
+export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ children }) => {
+
+  const [switchOpen, setSwitchOpen] = useState<boolean>(false)
+  const selectCompany = useRequest((params) => selectCompanyApi(params), { manual: true }) // 切换公司
+  /**
+   * 退出登录,并且将当前的 url 保存
+   */
+  const loginOut = async () => {
+    await outLogin();
+    localStorage.removeItem('Admin-Token')
+    const { search, pathname } = window.location;
+    const urlParams = new URL(window.location.href).searchParams;
+    /** 此方法会跳转到 redirect 参数所在的位置 */
+    const redirect = urlParams.get('redirect');
+    // Note: There may be security issues, please note
+    if (window.location.pathname !== '/user/login' && !redirect) {
+      history.replace({
+        pathname: '/user/login',
+        search: stringify({
+          redirect: pathname + search,
+        }),
+      });
+    }
+  };
+  const { styles } = useStyles();
+
+  const { initialState, setInitialState } = useModel('@@initialState');
+
+  const onMenuClick = useCallback(
+    (event: MenuInfo) => {
+      const { key } = event;
+      if (key === 'logout') {
+        flushSync(() => {
+          setInitialState((s) => ({ ...s, currentUser: undefined }));
+        });
+        loginOut();
+        return;
+      } else if (key === 'switch') {
+        setSwitchOpen(true)
+        return
+      } else if (key === 'dark' || key === 'solid') {
+        localStorage.setItem('ISNODARK', JSON.stringify(key === 'solid'))
+        setInitialState((s) => ({ ...s, settings: { ...s?.settings, isNoDark: key === 'solid' } }))
+        return
+      }
+      history.push(`/account/${key}`);
+    },
+    [setInitialState],
+  );
+
+  const loading = (
+    <span className={styles.action}>
+      <Spin
+        size="small"
+        style={{
+          marginLeft: 8,
+          marginRight: 8,
+        }}
+      />
+    </span>
+  );
+
+  if (!initialState) {
+    return loading;
+  }
+
+  const { currentUser } = initialState;
+
+  if (!currentUser || !currentUser.name) {
+    return loading;
+  }
+
+  const menuItems = [
+    {
+      key: 'switch',
+      icon: <SwapOutlined />,
+      label: '切换公司',
+    },
+    {
+      key: 'logout',
+      icon: <LogoutOutlined />,
+      label: '退出登录',
+    },
+  ];
+
+  // 切换公司
+  const setCompanyHandle = (companyId: number) => {
+    selectCompany.run(companyId).then((res: any) => {
+      setSwitchOpen(false)
+      sessionStorage.setItem('Admin-Token', res?.data?.token)
+      window.location.reload()
+    })
+  }
+  return (
+    <>
+      <HeaderDropdown
+        menu={{
+          selectedKeys: [],
+          onClick: onMenuClick,
+          items: menuItems,
+        }}
+      >
+        {children}
+      </HeaderDropdown>
+      {/* 切换公司弹窗 */}
+      {switchOpen && <SwitchCompany
+        onlineCompanyId={initialState.currentUser?.onlineCompanyId as number}
+        companyList={initialState.currentUser?.companyList as any[]}
+        setCompanyHandle={setCompanyHandle}
+        visible={switchOpen}
+        onClose={() => { setSwitchOpen(false) }}
+        loading={selectCompany.loading}
+      />}
+    </>
+  );
+};

+ 32 - 0
src/components/RightContent/index.tsx

@@ -0,0 +1,32 @@
+import { QuestionCircleOutlined } from '@ant-design/icons';
+import { SelectLang as UmiSelectLang } from '@umijs/max';
+
+export type SiderTheme = 'light' | 'dark';
+
+export const SelectLang: React.FC = () => {
+  return (
+    <UmiSelectLang
+      style={{
+        padding: 4,
+      }}
+    />
+  );
+};
+
+export const Question: React.FC = () => {
+  return (
+    <a
+      href="https://pro.ant.design/docs/getting-started"
+      target="_blank"
+      rel="noreferrer"
+      style={{
+        display: 'inline-flex',
+        padding: '4px',
+        fontSize: '18px',
+        color: 'inherit',
+      }}
+    >
+      <QuestionCircleOutlined />
+    </a>
+  );
+};

+ 85 - 0
src/components/SystemCard/index.tsx

@@ -0,0 +1,85 @@
+import { motion } from 'framer-motion';
+import { BusinessSystem } from '@/mocks/systemData';
+import { ReactComponent as WeChatDataSvg } from '@/assets/icons/weChatData.svg'
+import { ReactComponent as CorpWechatSvg } from '@/assets/icons/corpChat.svg'
+import { ReactComponent as TencentAdSvg } from '@/assets/icons/tencentAd.svg'
+import { ReactComponent as BookSvg } from '@/assets/icons/book.svg'
+import { ReactComponent as GameSystemSvg } from '@/assets/icons/gameSystem.svg'
+import { ReactComponent as GameSvg } from '@/assets/icons/game.svg'
+import { ReactComponent as ImageSvg } from '@/assets/icons/image.svg'
+import { JSX } from 'react';
+import { SettingOutlined } from '@ant-design/icons';
+
+interface SystemCardProps {
+    system: BusinessSystem;
+    onClick: (url: string) => void;
+}
+
+
+const IconMap: { [x: string]: JSX.Element } = {
+    weChatData: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 20 }}><WeChatDataSvg /></span>,
+    corpWeChat: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 24 }}><CorpWechatSvg /></span>,
+    tencentAd: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 24 }}><TencentAdSvg /></span>,
+    book: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 20 }}><BookSvg /></span>,
+    gameSystem: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 20 }}><GameSystemSvg /></span>,
+    game: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 26 }}><GameSvg /></span>,
+    image: <span role="img" aria-label="fund-view" className="anticon anticon-fund-view" style={{ fontSize: 20 }}><ImageSvg /></span>,
+    system: <SettingOutlined style={{ fontSize: 20 }} />
+};
+
+export default function SystemCard({ system, onClick }: SystemCardProps) {
+    return (
+        <motion.div
+            className="group bg-white dark:bg-gray-800 rounded-xl shadow-md hover:shadow-xl transition-all duration-300 overflow-hidden border border-gray-100 dark:border-gray-700"
+            whileHover={{ y: -5 }}
+            onClick={() => onClick(system.url)}
+        >
+            <div className="p-5">
+                <div className="flex justify-between items-start mb-4">
+                    <div className="w-12 h-12 rounded-lg bg-blue-100 dark:bg-blue-900 flex items-center justify-center text-blue-600 dark:text-blue-300" style={system?.iconBackColor ? { backgroundColor: system.iconBackColor, color: system?.iconColor || '#FFFF' } : { color: system?.iconColor || '#FFFF' }}>
+                        {IconMap?.[system?.icon] || <i className={`fa-solid ${system.icon} text-xl`} style={system?.iconColor ? { color: system?.iconColor } : {}}></i>}
+                    </div>
+                    <div className="flex gap-1">
+                        {system.isNew && (
+                            <span className="text-xs px-2 py-1 bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-300 rounded-full">
+                                新
+                            </span>
+                        )}
+                        {system.isPopular && (
+                            <span className="text-xs px-2 py-1 bg-amber-100 dark:bg-amber-900 text-amber-600 dark:text-amber-300 rounded-full">
+                                常用
+                            </span>
+                        )}
+                    </div>
+                </div>
+
+                <h3 className="text-lg font-semibold text-gray-800 dark:text-white mb-2 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
+                    {system.name}
+                </h3>
+
+                <p className="text-sm text-gray-500 dark:text-gray-400 mb-4 line-clamp-2">
+                    {system.description}
+                </p>
+
+                <div className="flex items-center justify-between">
+                    <div className="flex items-center gap-2">
+                        {system.category.map((item, index) => <span key={index} className="text-xs font-medium px-2 py-1 rounded-full bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300">
+                            {item}
+                        </span>)}
+                    </div>
+
+                    <button
+                        className="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 flex items-center gap-1 transition-colors"
+                        onClick={(e) => {
+                            e.stopPropagation();
+                            onClick(system.url);
+                        }}
+                    >
+                        访问
+                        <i className="fa-solid fa-arrow-right text-xs"></i>
+                    </button>
+                </div>
+            </div>
+        </motion.div>
+    );
+}

+ 12 - 0
src/components/index.ts

@@ -0,0 +1,12 @@
+/**
+ * 这个文件作为组件的目录
+ * 目的是统一管理对外输出的组件,方便分类
+ */
+/**
+ * 布局组件
+ */
+import Footer from './Footer';
+import { Question, SelectLang } from './RightContent';
+import { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown';
+
+export { AvatarDropdown, AvatarName, Footer, Question, SelectLang };

+ 94 - 0
src/global.less

@@ -0,0 +1,94 @@
+@font-face {
+  font-family: "AlibabaSans";
+  font-style: normal;
+  font-weight: 300;
+  font-display: swap;
+  src: url("//mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*1GSgSYDD_aIAAAAAQsAAAAgAegCCAQ/AlibabaSans-Light.woff2")
+    format("woff2");
+}
+@font-face {
+  font-family: "AlibabaSans";
+  font-style: normal;
+  font-weight: 400;
+  font-display: swap;
+  src: url("//mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*2zEUQqnPNesAAAAAQtAAAAgAegCCAQ/AlibabaSans-Regular.woff2")
+    format("woff2");
+}
+@font-face {
+  font-family: "AlibabaSans";
+  font-style: normal;
+  font-weight: 500;
+  font-display: swap;
+  src: url("//mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*E_cxRbMlZqUAAAAAQuAAAAgAegCCAQ/AlibabaSans-Medium.woff2")
+    format("woff2");
+}
+@font-face {
+  font-family: "AlibabaSans";
+  font-style: normal;
+  font-weight: 600;
+  font-display: swap;
+  src: url("//mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*E_cxRbMlZqUAAAAAQuAAAAgAegCCAQ/AlibabaSans-Bold.woff2")
+    format("woff2");
+}
+@font-face {
+  font-family: "AlibabaSans";
+  font-style: normal;
+  font-weight: 700;
+  font-display: swap;
+  src: url("//mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*E_cxRbMlZqUAAAAAQuAAAAgAegCCAQ/AlibabaSans-Heavy.woff2")
+    format("woff2");
+}
+
+html,
+body,
+#root {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  font-family:
+    AlibabaSans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans',
+    sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+}
+
+.colorWeak {
+  filter: invert(80%);
+}
+
+.ant-layout {
+  min-height: 100vh;
+}
+.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
+  left: unset;
+}
+
+canvas {
+  display: block;
+}
+
+body {
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+ul,
+ol {
+  list-style: none;
+}
+
+@media (max-width: 768px) {
+  .ant-table {
+    width: 100%;
+    overflow-x: auto;
+    &-thead > tr,
+    &-tbody > tr {
+      > th,
+      > td {
+        white-space: pre;
+        > span {
+          display: block;
+        }
+      }
+    }
+  }
+}

+ 42 - 0
src/global.style.ts

@@ -0,0 +1,42 @@
+import { createStyles } from 'antd-style';
+
+const useStyles = createStyles(() => {
+  return {
+    colorWeak: {
+      filter: 'invert(80%)',
+    },
+    'ant-layout': {
+      minHeight: '100vh',
+    },
+    'ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed': {
+      left: 'unset',
+    },
+    canvas: {
+      display: 'block',
+    },
+    body: {
+      textRendering: 'optimizeLegibility',
+      WebkitFontSmoothing: 'antialiased',
+      MozOsxFontSmoothing: 'grayscale',
+    },
+    'ul,ol': {
+      listStyle: 'none',
+    },
+    '@media(max-width: 768px)': {
+      'ant-table': {
+        width: '100%',
+        overflowX: 'auto',
+        '&-thead > tr,    &-tbody > tr': {
+          '> th,      > td': {
+            whiteSpace: 'pre',
+            '> span': {
+              display: 'block',
+            },
+          },
+        },
+      },
+    },
+  };
+});
+
+export default useStyles;

+ 93 - 0
src/global.tsx

@@ -0,0 +1,93 @@
+import { useIntl } from '@umijs/max';
+import { Button, message, notification } from 'antd';
+import defaultSettings from '../config/defaultSettings';
+
+const { pwa } = defaultSettings;
+const isHttps = document.location.protocol === 'https:';
+
+const clearCache = () => {
+  // remove all caches
+  if (window.caches) {
+    caches
+      .keys()
+      .then((keys) => {
+        keys.forEach((key) => {
+          caches.delete(key);
+        });
+      })
+      .catch((e) => console.log(e));
+  }
+};
+
+// if pwa is true
+if (pwa) {
+  // Notify user if offline now
+  window.addEventListener('sw.offline', () => {
+    message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }));
+  });
+
+  // Pop up a prompt on the page asking the user if they want to use the latest version
+  window.addEventListener('sw.updated', (event: Event) => {
+    const e = event as CustomEvent;
+    const reloadSW = async () => {
+      // Check if there is sw whose state is waiting in ServiceWorkerRegistration
+      // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
+      const worker = e.detail?.waiting;
+      if (!worker) {
+        return true;
+      }
+      // Send skip-waiting event to waiting SW with MessageChannel
+      await new Promise((resolve, reject) => {
+        const channel = new MessageChannel();
+        channel.port1.onmessage = (msgEvent) => {
+          if (msgEvent.data.error) {
+            reject(msgEvent.data.error);
+          } else {
+            resolve(msgEvent.data);
+          }
+        };
+        worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
+      });
+
+      clearCache();
+      window.location.reload();
+      return true;
+    };
+    const key = `open${Date.now()}`;
+    const btn = (
+      <Button
+        type="primary"
+        onClick={() => {
+          notification.destroy(key);
+          reloadSW();
+        }}
+      >
+        {useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })}
+      </Button>
+    );
+    notification.open({
+      message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }),
+      description: useIntl().formatMessage({
+        id: 'app.pwa.serviceworker.updated.hint',
+      }),
+      btn,
+      key,
+      onClose: async () => null,
+    });
+  });
+} else if ('serviceWorker' in navigator && isHttps) {
+  // unregister service worker
+  const { serviceWorker } = navigator;
+  if (serviceWorker.getRegistrations) {
+    serviceWorker.getRegistrations().then((sws) => {
+      sws.forEach((sw) => {
+        sw.unregister();
+      });
+    });
+  }
+  serviceWorker.getRegistration().then((sw) => {
+    if (sw) sw.unregister();
+  });
+
+  clearCache();
+}

+ 7 - 0
src/loading.tsx

@@ -0,0 +1,7 @@
+import { Skeleton } from 'antd';
+
+const Loading: React.FC = () => (
+  <Skeleton style={{ margin: '24px 40px', height: '60vh' }} active />
+);
+
+export default Loading;

+ 25 - 0
src/locales/bn-BD.ts

@@ -0,0 +1,25 @@
+import component from './bn-BD/component';
+import globalHeader from './bn-BD/globalHeader';
+import menu from './bn-BD/menu';
+import pages from './bn-BD/pages';
+import pwa from './bn-BD/pwa';
+import settingDrawer from './bn-BD/settingDrawer';
+import settings from './bn-BD/settings';
+
+export default {
+  'navBar.lang': 'ভাষা',
+  'layout.user.link.help': 'সহায়তা',
+  'layout.user.link.privacy': 'গোপনীয়তা',
+  'layout.user.link.terms': 'শর্তাদি',
+  'app.preview.down.block': 'আপনার স্থানীয় প্রকল্পে এই পৃষ্ঠাটি ডাউনলোড করুন',
+  'app.welcome.link.fetch-blocks': 'সমস্ত ব্লক পান',
+  'app.welcome.link.block-list':
+    '`block` ডেভেলপমেন্ট এর উপর ভিত্তি করে দ্রুত স্ট্যান্ডার্ড, পৃষ্ঠাসমূহ তৈরি করুন।',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/bn-BD/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': 'বিস্তৃত',
+  'component.tagSelect.collapse': 'সঙ্কুচিত',
+  'component.tagSelect.all': 'সব',
+};

+ 17 - 0
src/locales/bn-BD/globalHeader.ts

@@ -0,0 +1,17 @@
+export default {
+  'component.globalHeader.search': 'অনুসন্ধান করুন',
+  'component.globalHeader.search.example1': 'অনুসন্ধান উদাহরণ ১',
+  'component.globalHeader.search.example2': 'অনুসন্ধান উদাহরণ ২',
+  'component.globalHeader.search.example3': 'অনুসন্ধান উদাহরণ ৩',
+  'component.globalHeader.help': 'সহায়তা',
+  'component.globalHeader.notification': 'বিজ্ঞপ্তি',
+  'component.globalHeader.notification.empty': 'আপনি সমস্ত বিজ্ঞপ্তি দেখেছেন।',
+  'component.globalHeader.message': 'বার্তা',
+  'component.globalHeader.message.empty': 'আপনি সমস্ত বার্তা দেখেছেন।',
+  'component.globalHeader.event': 'ঘটনা',
+  'component.globalHeader.event.empty': 'আপনি সমস্ত ইভেন্ট দেখেছেন।',
+  'component.noticeIcon.clear': 'সাফ',
+  'component.noticeIcon.cleared': 'সাফ করা হয়েছে',
+  'component.noticeIcon.empty': 'বিজ্ঞপ্তি নেই',
+  'component.noticeIcon.view-more': 'আরো দেখুন',
+};

+ 52 - 0
src/locales/bn-BD/menu.ts

@@ -0,0 +1,52 @@
+export default {
+  'menu.welcome': 'স্বাগতম',
+  'menu.more-blocks': 'আরও ব্লক',
+  'menu.home': 'নীড়',
+  'menu.admin': 'অ্যাডমিন',
+  'menu.admin.sub-page': 'উপ-পৃষ্ঠা',
+  'menu.login': 'প্রবেশ',
+  'menu.register': 'নিবন্ধন',
+  'menu.register-result': 'নিবন্ধনে ফলাফল',
+  'menu.dashboard': 'ড্যাশবোর্ড',
+  'menu.dashboard.analysis': 'বিশ্লেষণ',
+  'menu.dashboard.monitor': 'নিরীক্ষণ',
+  'menu.dashboard.workplace': 'কর্মক্ষেত্র',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'ফর্ম',
+  'menu.form.basic-form': 'বেসিক ফর্ম',
+  'menu.form.step-form': 'পদক্ষেপ ফর্ম',
+  'menu.form.step-form.info': 'পদক্ষেপ ফর্ম (স্থানান্তর তথ্য লিখুন)',
+  'menu.form.step-form.confirm': 'পদক্ষেপ ফর্ম (স্থানান্তর তথ্য নিশ্চিত করুন)',
+  'menu.form.step-form.result': 'পদক্ষেপ ফর্ম (সমাপ্ত)',
+  'menu.form.advanced-form': 'উন্নত ফর্ম',
+  'menu.list': 'তালিকা',
+  'menu.list.table-list': 'অনুসন্ধানের টেবিল',
+  'menu.list.basic-list': 'বেসিক তালিকা',
+  'menu.list.card-list': 'কার্ডের তালিকা',
+  'menu.list.search-list': 'অনুসন্ধানের তালিকা',
+  'menu.list.search-list.articles': 'অনুসন্ধানের তালিকা (নিবন্ধসমূহ)',
+  'menu.list.search-list.projects': 'অনুসন্ধানের তালিকা (প্রকল্পগুলি)',
+  'menu.list.search-list.applications': 'অনুসন্ধানের তালিকা (অ্যাপ্লিকেশন)',
+  'menu.profile': 'প্রোফাইল',
+  'menu.profile.basic': 'বেসিক প্রোফাইল',
+  'menu.profile.advanced': 'উন্নত প্রোফাইল',
+  'menu.result': 'ফলাফল',
+  'menu.result.success': 'সাফল্য',
+  'menu.result.fail': 'ব্যর্থ',
+  'menu.exception': 'ব্যতিক্রম',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'ট্রিগার',
+  'menu.account': 'হিসাব',
+  'menu.account.center': 'অ্যাকাউন্ট কেন্দ্র',
+  'menu.account.settings': 'অ্যাকাউন্ট সেটিংস',
+  'menu.account.trigger': 'ট্রিগার ত্রুটি',
+  'menu.account.logout': 'প্রস্থান',
+  'menu.editor': 'গ্রাফিক সম্পাদক',
+  'menu.editor.flow': 'ফ্লো এডিটর',
+  'menu.editor.mind': 'মাইন্ড এডিটর',
+  'menu.editor.koni': 'কোনি সম্পাদক',
+};

+ 73 - 0
src/locales/bn-BD/pages.ts

@@ -0,0 +1,73 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'পিঁপড়া ডিজাইন হচ্ছে সিহু জেলার সবচেয়ে প্রভাবশালী ওয়েব ডিজাইনের স্পেসিফিকেশন',
+  'pages.login.accountLogin.tab': 'অ্যাকাউন্টে লগইন',
+  'pages.login.accountLogin.errorMessage':
+    'ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড(admin/ant.design)',
+  'pages.login.failure': 'লগইন ব্যর্থ হয়েছে। আবার চেষ্টা করুন!',
+  'pages.login.success': 'সফল লগইন!',
+  'pages.login.username.placeholder': 'ব্যবহারকারীর নাম: admin or user',
+  'pages.login.username.required': 'আপনার ব্যবহারকারীর নাম ইনপুট করুন!',
+  'pages.login.password.placeholder': 'পাসওয়ার্ড: ant.design',
+  'pages.login.password.required': 'আপনার পাসওয়ার্ড ইনপুট করুন!',
+  'pages.login.phoneLogin.tab': 'ফোন লগইন',
+  'pages.login.phoneLogin.errorMessage': 'যাচাইকরণ কোড ত্রুটি',
+  'pages.login.phoneNumber.placeholder': 'ফোন নম্বর',
+  'pages.login.phoneNumber.required': 'আপনার ফোন নম্বর ইনপুট করুন!',
+  'pages.login.phoneNumber.invalid': 'ফোন নম্বরটি সঠিক নয়!',
+  'pages.login.captcha.placeholder': 'যাচাইকরণের কোড',
+  'pages.login.captcha.required': 'দয়া করে ভেরিফিকেশন কোডটি ইনপুট করুন!',
+  'pages.login.phoneLogin.getVerificationCode': 'কোড পান',
+  'pages.getCaptchaSecondText': 'সেকেন্ড',
+  'pages.login.rememberMe': 'আমাকে মনে রাখুন',
+  'pages.login.forgotPassword': 'পাসওয়ার্ড ভুলে গেছেন?',
+  'pages.login.submit': 'প্রবেশ করুন',
+  'pages.login.loginWith': 'লগইন করতে পারেন:',
+  'pages.login.registerAccount': 'অ্যাকাউন্ট নিবন্ধন করুন',
+  'pages.welcome.link': 'স্বাগতম',
+  'pages.welcome.alertMessage': 'দ্রুত এবং শক্তিশালী ভারী শুল্ক উপাদান প্রকাশ করা হয়েছে।',
+  'pages.404.subTitle': 'দুঃখিত, আপনি যে পৃষ্ঠাটি দেখতে চান তা বিদ্যমান নেই।',
+  'pages.404.buttonText': 'প্রধান পাতায় ফিরে যান',
+  'pages.admin.subPage.title': 'এই পৃষ্ঠাটি কেবল অ্যাডমিন দ্বারা দেখা যাবে',
+  'pages.admin.subPage.alertMessage':
+    'UMI UI এখন প্রকাশিত হয়েছে, অভিজ্ঞতা শুরু করতে npm run ui ব্যবহার করতে স্বাগতম।',
+  'pages.searchTable.createForm.newRule': 'নতুন বিধি',
+  'pages.searchTable.updateForm.ruleConfig': 'বিধি কনফিগারেশন',
+  'pages.searchTable.updateForm.basicConfig': 'মৌলিক তথ্য',
+  'pages.searchTable.updateForm.ruleName.nameLabel': 'বিধি নাম',
+  'pages.searchTable.updateForm.ruleName.nameRules': 'বিধির নাম লিখুন!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'বিধির বিবরণ',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    'কমপক্ষে পাঁচটি অক্ষর লিখুন',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    'কমপক্ষে পাঁচটি অক্ষরের একটি বিধান বিবরণ লিখুন!',
+  'pages.searchTable.updateForm.ruleProps.title': 'বৈশিষ্ট্য কনফিগার করুন',
+  'pages.searchTable.updateForm.object': 'নিরীক্ষণ অবজেক্ট',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'বিধি টেম্পলেট',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'বিধি প্রকার',
+  'pages.searchTable.updateForm.schedulingPeriod.title': 'সময়সূচী নির্ধারণ করুন',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'শুরুর সময়',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    'একটি শুরুর সময় চয়ন করুন!',
+  'pages.searchTable.titleDesc': 'বর্ণনা',
+  'pages.searchTable.ruleName': 'বিধি নাম প্রয়োজন',
+  'pages.searchTable.titleCallNo': 'পরিষেবা কল সংখ্যা',
+  'pages.searchTable.titleStatus': 'অবস্থা',
+  'pages.searchTable.nameStatus.default': 'ডিফল্ট',
+  'pages.searchTable.nameStatus.running': 'চলমান',
+  'pages.searchTable.nameStatus.online': 'অনলাইন',
+  'pages.searchTable.nameStatus.abnormal': 'অস্বাভাবিক',
+  'pages.searchTable.titleUpdatedAt': 'সর্বশেষ নির্ধারিত',
+  'pages.searchTable.exception': 'ব্যতিক্রম জন্য কারণ লিখুন!',
+  'pages.searchTable.titleOption': 'অপশন',
+  'pages.searchTable.config': 'কনফিগারেশন',
+  'pages.searchTable.subscribeAlert': 'সতর্কতা সাবস্ক্রাইব করুন',
+  'pages.searchTable.title': 'ইনকয়েরি ফরম',
+  'pages.searchTable.new': 'নতুন',
+  'pages.searchTable.chosen': 'নির্বাচিত',
+  'pages.searchTable.item': 'আইটেম',
+  'pages.searchTable.totalServiceCalls': 'পরিষেবা কলগুলির মোট সংখ্যা',
+  'pages.searchTable.tenThousand': '000',
+  'pages.searchTable.batchDeletion': 'একসাখে ডিলিট',
+  'pages.searchTable.batchApproval': 'একসাখে অনুমোদন',
+};

+ 7 - 0
src/locales/bn-BD/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'আপনি এখন অফলাইন',
+  'app.pwa.serviceworker.updated': 'নতুন সামগ্রী উপলব্ধ',
+  'app.pwa.serviceworker.updated.hint':
+    'বর্তমান পৃষ্ঠাটি পুনরায় লোড করতে দয়া করে "রিফ্রেশ" বোতাম টিপুন',
+  'app.pwa.serviceworker.updated.ok': 'রিফ্রেশ',
+};

+ 32 - 0
src/locales/bn-BD/settingDrawer.ts

@@ -0,0 +1,32 @@
+export default {
+  'app.setting.pagestyle': 'পৃষ্ঠা স্টাইল সেটিং',
+  'app.setting.pagestyle.dark': 'ডার্ক স্টাইল',
+  'app.setting.pagestyle.light': 'লাইট স্টাইল',
+  'app.setting.content-width': 'সামগ্রীর প্রস্থ',
+  'app.setting.content-width.fixed': 'স্থির',
+  'app.setting.content-width.fluid': 'প্রবাহী',
+  'app.setting.themecolor': 'থিম রঙ',
+  'app.setting.themecolor.dust': 'ডাস্ট রেড',
+  'app.setting.themecolor.volcano': 'আগ্নেয়গিরি',
+  'app.setting.themecolor.sunset': 'সানসেট কমলা',
+  'app.setting.themecolor.cyan': 'সবুজাভ নীল',
+  'app.setting.themecolor.green': 'পোলার সবুজ',
+  'app.setting.themecolor.daybreak': 'দিবস ব্রেক ব্লু (ডিফল্ট)',
+  'app.setting.themecolor.geekblue': 'গিক আঠালো',
+  'app.setting.themecolor.purple': 'গোল্ডেন বেগুনি',
+  'app.setting.navigationmode': 'নেভিগেশন মোড',
+  'app.setting.sidemenu': 'সাইড মেনু লেআউট',
+  'app.setting.topmenu': 'টপ মেনু লেআউট',
+  'app.setting.fixedheader': 'স্থির হেডার',
+  'app.setting.fixedsidebar': 'স্থির সাইডবার',
+  'app.setting.fixedsidebar.hint': 'সাইড মেনু বিন্যাসে কাজ করে',
+  'app.setting.hideheader': 'স্ক্রোল করার সময় হেডার লুকানো',
+  'app.setting.hideheader.hint': 'লুকানো হেডার সক্ষম থাকলে কাজ করে',
+  'app.setting.othersettings': 'অন্যান্য সেটিংস্',
+  'app.setting.weakmode': 'দুর্বল মোড',
+  'app.setting.copy': 'সেটিং কপি করুন',
+  'app.setting.copyinfo':
+    'সাফল্যের অনুলিপি করুন - প্রতিস্থাপন করুন: src/models/setting.js',
+  'app.setting.production.hint':
+    'কেবল বিকাশের পরিবেশে প্যানেল শো সেট করা হচ্ছে, দয়া করে ম্যানুয়ালি সংশোধন করুন',
+};

+ 60 - 0
src/locales/bn-BD/settings.ts

@@ -0,0 +1,60 @@
+export default {
+  'app.settings.menuMap.basic': 'মৌলিক বৈশিষ্ট্যসহ',
+  'app.settings.menuMap.security': 'নিরাপত্তা বিন্যাস',
+  'app.settings.menuMap.binding': 'অ্যাকাউন্ট বাঁধাই',
+  'app.settings.menuMap.notification': 'নতুন বার্তা বিজ্ঞপ্তি',
+  'app.settings.basic.avatar': 'অবতার',
+  'app.settings.basic.change-avatar': 'অবতার পরিবর্তন করুন',
+  'app.settings.basic.email': 'ইমেইল',
+  'app.settings.basic.email-message': 'আপনার ইমেইল ইনপুট করুন!',
+  'app.settings.basic.nickname': 'ডাক নাম',
+  'app.settings.basic.nickname-message': 'আপনার ডাকনামটি ইনপুট করুন!',
+  'app.settings.basic.profile': 'ব্যক্তিগত প্রোফাইল',
+  'app.settings.basic.profile-message': 'আপনার ব্যক্তিগত প্রোফাইল ইনপুট করুন!',
+  'app.settings.basic.profile-placeholder': 'নিজের সাথে সংক্ষিপ্ত পরিচয়',
+  'app.settings.basic.country': 'দেশ/অঞ্চল',
+  'app.settings.basic.country-message': 'আপনার দেশ ইনপুট করুন!',
+  'app.settings.basic.geographic': 'প্রদেশ বা শহর',
+  'app.settings.basic.geographic-message': 'আপনার ভৌগলিক তথ্য ইনপুট করুন!',
+  'app.settings.basic.address': 'রাস্তার ঠিকানা',
+  'app.settings.basic.address-message': 'দয়া করে আপনার ঠিকানা ইনপুট করুন!',
+  'app.settings.basic.phone': 'ফোন নম্বর',
+  'app.settings.basic.phone-message': 'আপনার ফোন ইনপুট করুন!',
+  'app.settings.basic.update': 'তথ্য হালনাগাদ',
+  'app.settings.security.strong': 'শক্তিশালী',
+  'app.settings.security.medium': 'মধ্যম',
+  'app.settings.security.weak': 'দুর্বল',
+  'app.settings.security.password': 'অ্যাকাউন্টের পাসওয়ার্ড',
+  'app.settings.security.password-description': 'বর্তমান পাসওয়ার্ড শক্তি',
+  'app.settings.security.phone': 'সুরক্ষা ফোন',
+  'app.settings.security.phone-description': 'আবদ্ধ ফোন',
+  'app.settings.security.question': 'নিরাপত্তা প্রশ্ন',
+  'app.settings.security.question-description':
+    'সুরক্ষা প্রশ্ন সেট করা নেই, এবং সুরক্ষা নীতি কার্যকরভাবে অ্যাকাউন্ট সুরক্ষা রক্ষা করতে পারে',
+  'app.settings.security.email': 'ব্যাকআপ ইমেইল',
+  'app.settings.security.email-description': 'বাউন্ড ইমেইল',
+  'app.settings.security.mfa': 'MFA ডিভাইস',
+  'app.settings.security.mfa-description':
+    "আনবাউন্ড এমএফএ ডিভাইস, বাঁধাইয়ের পরে, দু'বার নিশ্চিত করা যায়",
+  'app.settings.security.modify': 'পরিবর্তন করুন',
+  'app.settings.security.set': 'সেট',
+  'app.settings.security.bind': 'বাঁধাই',
+  'app.settings.binding.taobao': 'বাঁধাই তাওবাও',
+  'app.settings.binding.taobao-description': 'বর্তমানে আনবাউন্ড তাওবাও অ্যাকাউন্ট',
+  'app.settings.binding.alipay': 'বাইন্ডিং আলিপে',
+  'app.settings.binding.alipay-description': 'বর্তমানে আনবাউন্ড আলিপে অ্যাকাউন্ট',
+  'app.settings.binding.dingding': 'বাঁধাই ডিঙ্গটালক',
+  'app.settings.binding.dingding-description': 'বর্তমানে আনবাউন্ড ডিঙ্গটাল অ্যাকাউন্ট',
+  'app.settings.binding.bind': 'বাঁধাই',
+  'app.settings.notification.password': 'অ্যাকাউন্টের পাসওয়ার্ড',
+  'app.settings.notification.password-description':
+    'অন্যান্য ব্যবহারকারীর বার্তাগুলি স্টেশন চিঠি আকারে জানানো হবে',
+  'app.settings.notification.messages': 'সিস্টেম বার্তা',
+  'app.settings.notification.messages-description':
+    'সিস্টেম বার্তাগুলি স্টেশন চিঠির আকারে জানানো হবে',
+  'app.settings.notification.todo': 'করণীয় বিজ্ঞপ্তি',
+  'app.settings.notification.todo-description':
+    'করণীয় তালিকাটি স্টেশন থেকে চিঠি আকারে জানানো হবে',
+  'app.settings.open': 'খোলা',
+  'app.settings.close': 'বন্ধ',
+};

+ 25 - 0
src/locales/en-US.ts

@@ -0,0 +1,25 @@
+import component from './en-US/component';
+import globalHeader from './en-US/globalHeader';
+import menu from './en-US/menu';
+import pages from './en-US/pages';
+import pwa from './en-US/pwa';
+import settingDrawer from './en-US/settingDrawer';
+import settings from './en-US/settings';
+
+export default {
+  'navBar.lang': 'Languages',
+  'layout.user.link.help': 'Help',
+  'layout.user.link.privacy': 'Privacy',
+  'layout.user.link.terms': 'Terms',
+  'app.preview.down.block': 'Download this page to your local project',
+  'app.welcome.link.fetch-blocks': 'Get all block',
+  'app.welcome.link.block-list':
+    'Quickly build standard, pages based on `block` development',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/en-US/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': 'Expand',
+  'component.tagSelect.collapse': 'Collapse',
+  'component.tagSelect.all': 'All',
+};

+ 18 - 0
src/locales/en-US/globalHeader.ts

@@ -0,0 +1,18 @@
+export default {
+  'component.globalHeader.search': 'Search',
+  'component.globalHeader.search.example1': 'Search example 1',
+  'component.globalHeader.search.example2': 'Search example 2',
+  'component.globalHeader.search.example3': 'Search example 3',
+  'component.globalHeader.help': 'Help',
+  'component.globalHeader.notification': 'Notification',
+  'component.globalHeader.notification.empty':
+    'You have viewed all notifications.',
+  'component.globalHeader.message': 'Message',
+  'component.globalHeader.message.empty': 'You have viewed all messsages.',
+  'component.globalHeader.event': 'Event',
+  'component.globalHeader.event.empty': 'You have viewed all events.',
+  'component.noticeIcon.clear': 'Clear',
+  'component.noticeIcon.cleared': 'Cleared',
+  'component.noticeIcon.empty': 'No notifications',
+  'component.noticeIcon.view-more': 'View more',
+};

+ 52 - 0
src/locales/en-US/menu.ts

@@ -0,0 +1,52 @@
+export default {
+  'menu.welcome': 'Welcome',
+  'menu.more-blocks': 'More Blocks',
+  'menu.home': 'Home',
+  'menu.admin': 'Admin',
+  'menu.admin.sub-page': 'Sub-Page',
+  'menu.login': 'Login',
+  'menu.register': 'Register',
+  'menu.register-result': 'Register Result',
+  'menu.dashboard': 'Dashboard',
+  'menu.dashboard.analysis': 'Analysis',
+  'menu.dashboard.monitor': 'Monitor',
+  'menu.dashboard.workplace': 'Workplace',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'Form',
+  'menu.form.basic-form': 'Basic Form',
+  'menu.form.step-form': 'Step Form',
+  'menu.form.step-form.info': 'Step Form(write transfer information)',
+  'menu.form.step-form.confirm': 'Step Form(confirm transfer information)',
+  'menu.form.step-form.result': 'Step Form(finished)',
+  'menu.form.advanced-form': 'Advanced Form',
+  'menu.list': 'List',
+  'menu.list.table-list': 'Search Table',
+  'menu.list.basic-list': 'Basic List',
+  'menu.list.card-list': 'Card List',
+  'menu.list.search-list': 'Search List',
+  'menu.list.search-list.articles': 'Search List(articles)',
+  'menu.list.search-list.projects': 'Search List(projects)',
+  'menu.list.search-list.applications': 'Search List(applications)',
+  'menu.profile': 'Profile',
+  'menu.profile.basic': 'Basic Profile',
+  'menu.profile.advanced': 'Advanced Profile',
+  'menu.result': 'Result',
+  'menu.result.success': 'Success',
+  'menu.result.fail': 'Fail',
+  'menu.exception': 'Exception',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'Trigger',
+  'menu.account': 'Account',
+  'menu.account.center': 'Account Center',
+  'menu.account.settings': 'Account Settings',
+  'menu.account.trigger': 'Trigger Error',
+  'menu.account.logout': 'Logout',
+  'menu.editor': 'Graphic Editor',
+  'menu.editor.flow': 'Flow Editor',
+  'menu.editor.mind': 'Mind Editor',
+  'menu.editor.koni': 'Koni Editor',
+};

+ 76 - 0
src/locales/en-US/pages.ts

@@ -0,0 +1,76 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'Ant Design is the most influential web design specification in Xihu district',
+  'pages.login.accountLogin.tab': 'Account Login',
+  'pages.login.accountLogin.errorMessage':
+    'Incorrect username/password(admin/ant.design)',
+  'pages.login.failure': 'Login failed, please try again!',
+  'pages.login.success': 'Login successful!',
+  'pages.login.username.placeholder': 'Username: admin or user',
+  'pages.login.username.required': 'Please input your username!',
+  'pages.login.password.placeholder': 'Password: ant.design',
+  'pages.login.password.required': 'Please input your password!',
+  'pages.login.phoneLogin.tab': 'Phone Login',
+  'pages.login.phoneLogin.errorMessage': 'Verification Code Error',
+  'pages.login.phoneNumber.placeholder': 'Phone Number',
+  'pages.login.phoneNumber.required': 'Please input your phone number!',
+  'pages.login.phoneNumber.invalid': 'Phone number is invalid!',
+  'pages.login.captcha.placeholder': 'Verification Code',
+  'pages.login.captcha.required': 'Please input verification code!',
+  'pages.login.phoneLogin.getVerificationCode': 'Get Code',
+  'pages.getCaptchaSecondText': 'sec(s)',
+  'pages.login.rememberMe': 'Remember me',
+  'pages.login.forgotPassword': 'Forgot Password ?',
+  'pages.login.submit': 'Login',
+  'pages.login.loginWith': 'Login with :',
+  'pages.login.registerAccount': 'Register Account',
+  'pages.welcome.link': 'Welcome',
+  'pages.welcome.alertMessage':
+    'Faster and stronger heavy-duty components have been released.',
+  'pages.404.subTitle': 'Sorry, the page you visited does not exist.',
+  'pages.404.buttonText': 'Back Home',
+  'pages.admin.subPage.title': 'This page can only be viewed by Admin',
+  'pages.admin.subPage.alertMessage':
+    'Umi ui is now released, welcome to use npm run ui to start the experience.',
+  'pages.searchTable.createForm.newRule': 'New Rule',
+  'pages.searchTable.updateForm.ruleConfig': 'Rule configuration',
+  'pages.searchTable.updateForm.basicConfig': 'Basic Information',
+  'pages.searchTable.updateForm.ruleName.nameLabel': 'Rule Name',
+  'pages.searchTable.updateForm.ruleName.nameRules':
+    'Please enter the rule name!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'Rule Description',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    'Please enter at least five characters',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    'Please enter a rule description of at least five characters!',
+  'pages.searchTable.updateForm.ruleProps.title': 'Configure Properties',
+  'pages.searchTable.updateForm.object': 'Monitoring Object',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'Rule Template',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'Rule Type',
+  'pages.searchTable.updateForm.schedulingPeriod.title':
+    'Set Scheduling Period',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Starting Time',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    'Please choose a start time!',
+  'pages.searchTable.titleDesc': 'Description',
+  'pages.searchTable.ruleName': 'Rule name is required',
+  'pages.searchTable.titleCallNo': 'Number of Service Calls',
+  'pages.searchTable.titleStatus': 'Status',
+  'pages.searchTable.nameStatus.default': 'default',
+  'pages.searchTable.nameStatus.running': 'running',
+  'pages.searchTable.nameStatus.online': 'online',
+  'pages.searchTable.nameStatus.abnormal': 'abnormal',
+  'pages.searchTable.titleUpdatedAt': 'Last Scheduled at',
+  'pages.searchTable.exception': 'Please enter the reason for the exception!',
+  'pages.searchTable.titleOption': 'Option',
+  'pages.searchTable.config': 'Configuration',
+  'pages.searchTable.subscribeAlert': 'Subscribe to alerts',
+  'pages.searchTable.title': 'Enquiry Form',
+  'pages.searchTable.new': 'New',
+  'pages.searchTable.chosen': 'chosen',
+  'pages.searchTable.item': 'item',
+  'pages.searchTable.totalServiceCalls': 'Total Number of Service Calls',
+  'pages.searchTable.tenThousand': '0000',
+  'pages.searchTable.batchDeletion': 'batch deletion',
+  'pages.searchTable.batchApproval': 'batch approval',
+};

+ 7 - 0
src/locales/en-US/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'You are offline now',
+  'app.pwa.serviceworker.updated': 'New content is available',
+  'app.pwa.serviceworker.updated.hint':
+    'Please press the "Refresh" button to reload current page',
+  'app.pwa.serviceworker.updated.ok': 'Refresh',
+};

+ 32 - 0
src/locales/en-US/settingDrawer.ts

@@ -0,0 +1,32 @@
+export default {
+  'app.setting.pagestyle': 'Page style setting',
+  'app.setting.pagestyle.dark': 'Dark style',
+  'app.setting.pagestyle.light': 'Light style',
+  'app.setting.content-width': 'Content Width',
+  'app.setting.content-width.fixed': 'Fixed',
+  'app.setting.content-width.fluid': 'Fluid',
+  'app.setting.themecolor': 'Theme Color',
+  'app.setting.themecolor.dust': 'Dust Red',
+  'app.setting.themecolor.volcano': 'Volcano',
+  'app.setting.themecolor.sunset': 'Sunset Orange',
+  'app.setting.themecolor.cyan': 'Cyan',
+  'app.setting.themecolor.green': 'Polar Green',
+  'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
+  'app.setting.themecolor.geekblue': 'Geek Glue',
+  'app.setting.themecolor.purple': 'Golden Purple',
+  'app.setting.navigationmode': 'Navigation Mode',
+  'app.setting.sidemenu': 'Side Menu Layout',
+  'app.setting.topmenu': 'Top Menu Layout',
+  'app.setting.fixedheader': 'Fixed Header',
+  'app.setting.fixedsidebar': 'Fixed Sidebar',
+  'app.setting.fixedsidebar.hint': 'Works on Side Menu Layout',
+  'app.setting.hideheader': 'Hidden Header when scrolling',
+  'app.setting.hideheader.hint': 'Works when Hidden Header is enabled',
+  'app.setting.othersettings': 'Other Settings',
+  'app.setting.weakmode': 'Color Blind Friendly Mode',
+  'app.setting.copy': 'Copy Setting',
+  'app.setting.copyinfo':
+    'copy success, please replace defaultSettings in src/models/setting.js',
+  'app.setting.production.hint':
+    'Setting panel shows in development environment only, please manually modify',
+};

+ 61 - 0
src/locales/en-US/settings.ts

@@ -0,0 +1,61 @@
+export default {
+  'app.settings.menuMap.basic': 'Basic Settings',
+  'app.settings.menuMap.security': 'Security Settings',
+  'app.settings.menuMap.binding': 'Account Binding',
+  'app.settings.menuMap.notification': 'New Message Notification',
+  'app.settings.basic.avatar': 'Avatar',
+  'app.settings.basic.change-avatar': 'Change avatar',
+  'app.settings.basic.email': 'Email',
+  'app.settings.basic.email-message': 'Please input your email!',
+  'app.settings.basic.nickname': 'Nickname',
+  'app.settings.basic.nickname-message': 'Please input your Nickname!',
+  'app.settings.basic.profile': 'Personal profile',
+  'app.settings.basic.profile-message': 'Please input your personal profile!',
+  'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
+  'app.settings.basic.country': 'Country/Region',
+  'app.settings.basic.country-message': 'Please input your country!',
+  'app.settings.basic.geographic': 'Province or city',
+  'app.settings.basic.geographic-message': 'Please input your geographic info!',
+  'app.settings.basic.address': 'Street Address',
+  'app.settings.basic.address-message': 'Please input your address!',
+  'app.settings.basic.phone': 'Phone Number',
+  'app.settings.basic.phone-message': 'Please input your phone!',
+  'app.settings.basic.update': 'Update Information',
+  'app.settings.security.strong': 'Strong',
+  'app.settings.security.medium': 'Medium',
+  'app.settings.security.weak': 'Weak',
+  'app.settings.security.password': 'Account Password',
+  'app.settings.security.password-description': 'Current password strength',
+  'app.settings.security.phone': 'Security Phone',
+  'app.settings.security.phone-description': 'Bound phone',
+  'app.settings.security.question': 'Security Question',
+  'app.settings.security.question-description':
+    'The security question is not set, and the security policy can effectively protect the account security',
+  'app.settings.security.email': 'Backup Email',
+  'app.settings.security.email-description': 'Bound Email',
+  'app.settings.security.mfa': 'MFA Device',
+  'app.settings.security.mfa-description':
+    'Unbound MFA device, after binding, can be confirmed twice',
+  'app.settings.security.modify': 'Modify',
+  'app.settings.security.set': 'Set',
+  'app.settings.security.bind': 'Bind',
+  'app.settings.binding.taobao': 'Binding Taobao',
+  'app.settings.binding.taobao-description': 'Currently unbound Taobao account',
+  'app.settings.binding.alipay': 'Binding Alipay',
+  'app.settings.binding.alipay-description': 'Currently unbound Alipay account',
+  'app.settings.binding.dingding': 'Binding DingTalk',
+  'app.settings.binding.dingding-description':
+    'Currently unbound DingTalk account',
+  'app.settings.binding.bind': 'Bind',
+  'app.settings.notification.password': 'Account Password',
+  'app.settings.notification.password-description':
+    'Messages from other users will be notified in the form of a station letter',
+  'app.settings.notification.messages': 'System Messages',
+  'app.settings.notification.messages-description':
+    'System messages will be notified in the form of a station letter',
+  'app.settings.notification.todo': 'To-do Notification',
+  'app.settings.notification.todo-description':
+    'The to-do list will be notified in the form of a letter from the station',
+  'app.settings.open': 'Open',
+  'app.settings.close': 'Close',
+};

+ 25 - 0
src/locales/fa-IR.ts

@@ -0,0 +1,25 @@
+import component from './fa-IR/component';
+import globalHeader from './fa-IR/globalHeader';
+import menu from './fa-IR/menu';
+import pages from './fa-IR/pages';
+import pwa from './fa-IR/pwa';
+import settingDrawer from './fa-IR/settingDrawer';
+import settings from './fa-IR/settings';
+
+export default {
+  'navBar.lang': 'زبان ها  ',
+  'layout.user.link.help': 'کمک',
+  'layout.user.link.privacy': 'حریم خصوصی',
+  'layout.user.link.terms': 'مقررات',
+  'app.preview.down.block': 'این صفحه را در پروژه محلی خود بارگیری کنید',
+  'app.welcome.link.fetch-blocks': 'دریافت تمام بلوک',
+  'app.welcome.link.block-list':
+    'به سرعت صفحات استاندارد مبتنی بر توسعه "بلوک" را بسازید',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/fa-IR/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': 'باز',
+  'component.tagSelect.collapse': 'بسته ',
+  'component.tagSelect.all': 'همه',
+};

+ 18 - 0
src/locales/fa-IR/globalHeader.ts

@@ -0,0 +1,18 @@
+export default {
+  'component.globalHeader.search': 'جستجو ',
+  'component.globalHeader.search.example1': 'مثال 1 را جستجو کنید',
+  'component.globalHeader.search.example2': 'مثال 2 را جستجو کنید',
+  'component.globalHeader.search.example3': 'مثال 3 را جستجو کنید',
+  'component.globalHeader.help': 'کمک',
+  'component.globalHeader.notification': 'اعلان',
+  'component.globalHeader.notification.empty':
+    'شما همه اعلان ها را مشاهده کرده اید.',
+  'component.globalHeader.message': 'پیام',
+  'component.globalHeader.message.empty': 'شما همه پیام ها را مشاهده کرده اید.',
+  'component.globalHeader.event': 'رویداد',
+  'component.globalHeader.event.empty': 'شما همه رویدادها را مشاهده کرده اید.',
+  'component.noticeIcon.clear': 'پاک کردن',
+  'component.noticeIcon.cleared': 'پاک شد',
+  'component.noticeIcon.empty': 'بدون اعلان',
+  'component.noticeIcon.view-more': 'نمایش بیشتر',
+};

+ 52 - 0
src/locales/fa-IR/menu.ts

@@ -0,0 +1,52 @@
+export default {
+  'menu.welcome': 'خوش آمدید',
+  'menu.more-blocks': 'بلوک های بیشتر',
+  'menu.home': 'خانه',
+  'menu.admin': 'مدیر',
+  'menu.admin.sub-page': 'زیر صفحه',
+  'menu.login': 'ورود',
+  'menu.register': 'ثبت نام',
+  'menu.register-result': 'ثبت نام نتیجه',
+  'menu.dashboard': 'داشبورد',
+  'menu.dashboard.analysis': 'تحلیل و بررسی',
+  'menu.dashboard.monitor': 'نظارت',
+  'menu.dashboard.workplace': 'محل کار',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'فرم',
+  'menu.form.basic-form': 'فرم اساسی',
+  'menu.form.step-form': 'فرم مرحله',
+  'menu.form.step-form.info': 'فرم مرحله (نوشتن اطلاعات انتقال)',
+  'menu.form.step-form.confirm': 'فرم مرحله (تأیید اطلاعات انتقال)',
+  'menu.form.step-form.result': 'فرم مرحله (تمام شده)',
+  'menu.form.advanced-form': 'فرم پیشرفته',
+  'menu.list': 'لیست',
+  'menu.list.table-list': 'جدول جستجو',
+  'menu.list.basic-list': 'لیست اصلی',
+  'menu.list.card-list': 'لیست کارت',
+  'menu.list.search-list': 'لیست جستجو',
+  'menu.list.search-list.articles': 'لیست جستجو (مقالات)',
+  'menu.list.search-list.projects': 'لیست جستجو (پروژه ها)',
+  'menu.list.search-list.applications': 'لیست جستجو (برنامه ها)',
+  'menu.profile': 'مشخصات',
+  'menu.profile.basic': 'مشخصات عمومی',
+  'menu.profile.advanced': 'مشخصات پیشرفته',
+  'menu.result': 'نتیجه',
+  'menu.result.success': 'موفق',
+  'menu.result.fail': 'ناموفق',
+  'menu.exception': 'استثنا',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'راه اندازی',
+  'menu.account': 'حساب',
+  'menu.account.center': 'مرکز حساب',
+  'menu.account.settings': 'تنظیمات حساب',
+  'menu.account.trigger': 'خطای راه اندازی',
+  'menu.account.logout': 'خروج',
+  'menu.editor': 'ویرایشگر گرافیک',
+  'menu.editor.flow': 'ویرایشگر جریان',
+  'menu.editor.mind': 'ویرایشگر ذهن',
+  'menu.editor.koni': 'ویرایشگر Koni',
+};

+ 75 - 0
src/locales/fa-IR/pages.ts

@@ -0,0 +1,75 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'طراحی مورچه تأثیرگذارترین مشخصات طراحی وب در منطقه Xihu است',
+  'pages.login.accountLogin.tab': 'ورود به حساب کاربری',
+  'pages.login.accountLogin.errorMessage':
+    'نام کاربری / رمزعبور نادرست (مدیر / ant.design)',
+  'pages.login.failure':
+    'ورود به سیستم با شکست مواجه شد، لطفا دوباره سعی کنید!',
+  'pages.login.success': 'ورود موفق!',
+  'pages.login.username.placeholder': 'نام کاربری: مدیر یا کاربر',
+  'pages.login.username.required': 'لطفا نام کاربری خود را وارد کنید!',
+  'pages.login.password.placeholder': 'رمز عبور: ant.design',
+  'pages.login.password.required': 'لطفاً رمز ورود خود را وارد کنید!',
+  'pages.login.phoneLogin.tab': 'ورود به سیستم تلفن',
+  'pages.login.phoneLogin.errorMessage': 'خطای کد تأیید',
+  'pages.login.phoneNumber.placeholder': 'شماره تلفن',
+  'pages.login.phoneNumber.required': 'لطفاً شماره تلفن خود را وارد کنید!',
+  'pages.login.phoneNumber.invalid': 'شماره تلفن نامعتبر است!',
+  'pages.login.captcha.placeholder': 'کد تایید',
+  'pages.login.captcha.required': 'لطفا کد تأیید را وارد کنید!',
+  'pages.login.phoneLogin.getVerificationCode': 'دریافت کد',
+  'pages.getCaptchaSecondText': 'ثانیه',
+  'pages.login.rememberMe': 'مرا به خاطر بسپار',
+  'pages.login.forgotPassword': 'رمز عبور را فراموش کرده اید ?',
+  'pages.login.submit': 'ارسال',
+  'pages.login.loginWith': 'وارد شوید با :',
+  'pages.login.registerAccount': 'ثبت نام',
+  'pages.welcome.link': 'خوش آمدید',
+  'pages.welcome.alertMessage': 'اجزای سنگین تر سریعتر و قوی تر آزاد شده اند.',
+  'pages.404.subTitle': 'ببخشيد، صفحه اي که ديديد وجود نداره',
+  'pages.404.buttonText': 'بازگشت به صفحه اصلی',
+  'pages.admin.subPage.title': 'این صفحه فقط توسط مدیر قابل مشاهده است',
+  'pages.admin.subPage.alertMessage':
+    'رابط کاربری Umi اکنون منتشر شده است ، برای شروع تجربه استفاده از npm run ui خوش آمدید.',
+  'pages.searchTable.createForm.newRule': 'قانون جدید',
+  'pages.searchTable.updateForm.ruleConfig': 'پیکربندی قانون',
+  'pages.searchTable.updateForm.basicConfig': 'اطلاعات اولیه',
+  'pages.searchTable.updateForm.ruleName.nameLabel': ' نام قانون',
+  'pages.searchTable.updateForm.ruleName.nameRules':
+    'لطفاً نام قانون را وارد کنید!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'شرح قانون',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    'لطفاً حداقل پنج حرف وارد کنید',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    'لطفاً حداقل یک قانون حاوی پنج کاراکتر شرح دهید!',
+  'pages.searchTable.updateForm.ruleProps.title': 'پیکربندی خصوصیات',
+  'pages.searchTable.updateForm.object': 'نظارت بر شی',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'الگوی قانون',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'نوع قانون',
+  'pages.searchTable.updateForm.schedulingPeriod.title': 'تنظیم دوره زمان بندی',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'زمان شروع',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    'لطفاً زمان شروع را انتخاب کنید!',
+  'pages.searchTable.titleDesc': 'شرح',
+  'pages.searchTable.ruleName': 'نام قانون لازم است',
+  'pages.searchTable.titleCallNo': 'تعداد تماس های خدماتی',
+  'pages.searchTable.titleStatus': 'وضعیت',
+  'pages.searchTable.nameStatus.default': 'پیش فرض',
+  'pages.searchTable.nameStatus.running': 'در حال دویدن',
+  'pages.searchTable.nameStatus.online': 'برخط',
+  'pages.searchTable.nameStatus.abnormal': 'غیرطبیعی',
+  'pages.searchTable.titleUpdatedAt': 'آخرین برنامه ریزی در',
+  'pages.searchTable.exception': 'لطفا دلیل استثنا را وارد کنید!',
+  'pages.searchTable.titleOption': 'گزینه',
+  'pages.searchTable.config': 'پیکربندی',
+  'pages.searchTable.subscribeAlert': 'مشترک شدن در هشدارها',
+  'pages.searchTable.title': 'فرم درخواست',
+  'pages.searchTable.new': 'جدید',
+  'pages.searchTable.chosen': 'انتخاب شده',
+  'pages.searchTable.item': 'مورد',
+  'pages.searchTable.totalServiceCalls': 'تعداد کل تماس های خدماتی',
+  'pages.searchTable.tenThousand': '0000',
+  'pages.searchTable.batchDeletion': 'حذف دسته ای',
+  'pages.searchTable.batchApproval': 'تصویب دسته ای',
+};

+ 7 - 0
src/locales/fa-IR/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'شما اکنون آفلاین هستید',
+  'app.pwa.serviceworker.updated': 'مطالب جدید در دسترس است',
+  'app.pwa.serviceworker.updated.hint':
+    'لطفاً برای بارگیری مجدد صفحه فعلی ، دکمه "تازه سازی" را فشار دهید',
+  'app.pwa.serviceworker.updated.ok': 'تازه سازی',
+};

+ 32 - 0
src/locales/fa-IR/settingDrawer.ts

@@ -0,0 +1,32 @@
+export default {
+  'app.setting.pagestyle': 'تنظیم نوع صفحه',
+  'app.setting.pagestyle.dark': 'سبک تیره',
+  'app.setting.pagestyle.light': 'سبک سبک',
+  'app.setting.content-width': 'عرض محتوا',
+  'app.setting.content-width.fixed': 'ثابت',
+  'app.setting.content-width.fluid': 'شناور',
+  'app.setting.themecolor': 'رنگ تم',
+  'app.setting.themecolor.dust': 'گرد و غبار قرمز',
+  'app.setting.themecolor.volcano': 'آتشفشان',
+  'app.setting.themecolor.sunset': 'غروب نارنجی',
+  'app.setting.themecolor.cyan': 'فیروزه ای',
+  'app.setting.themecolor.green': 'سبز قطبی',
+  'app.setting.themecolor.daybreak': 'آبی روشن(پیشفرض)',
+  'app.setting.themecolor.geekblue': 'چسب گیک',
+  'app.setting.themecolor.purple': 'بنفش طلایی',
+  'app.setting.navigationmode': 'حالت پیمایش',
+  'app.setting.sidemenu': 'طرح منوی کناری',
+  'app.setting.topmenu': 'طرح منوی بالایی',
+  'app.setting.fixedheader': 'سرصفحه ثابت',
+  'app.setting.fixedsidebar': 'نوار کناری ثابت',
+  'app.setting.fixedsidebar.hint': 'کار بر روی منوی کناری',
+  'app.setting.hideheader': 'هدر پنهان هنگام پیمایش',
+  'app.setting.hideheader.hint': 'وقتی Hidden Header فعال باشد کار می کند',
+  'app.setting.othersettings': 'تنظیمات دیگر',
+  'app.setting.weakmode': 'حالت ضعیف',
+  'app.setting.copy': 'تنظیمات کپی',
+  'app.setting.copyinfo':
+    'موفقیت در کپی کردن , لطفا defaultSettings را در src / models / setting.js جایگزین کنید',
+  'app.setting.production.hint':
+    'صفحه تنظیم فقط در محیط توسعه نمایش داده می شود ، لطفاً دستی تغییر دهید',
+};

+ 64 - 0
src/locales/fa-IR/settings.ts

@@ -0,0 +1,64 @@
+export default {
+  'app.settings.menuMap.basic': 'تنظیمات پایه ',
+  'app.settings.menuMap.security': 'تنظیمات امنیتی',
+  'app.settings.menuMap.binding': 'صحافی حساب',
+  'app.settings.menuMap.notification': 'اعلان پیام جدید',
+  'app.settings.basic.avatar': 'آواتار',
+  'app.settings.basic.change-avatar': 'آواتار را تغییر دهید',
+  'app.settings.basic.email': 'ایمیل',
+  'app.settings.basic.email-message': 'لطفا ایمیل خود را وارد کنید!',
+  'app.settings.basic.nickname': 'نام مستعار',
+  'app.settings.basic.nickname-message': 'لطفاً نام مستعار خود را وارد کنید!',
+  'app.settings.basic.profile': 'پروفایل شخصی',
+  'app.settings.basic.profile-message': 'لطفاً مشخصات شخصی خود را وارد کنید!',
+  'app.settings.basic.profile-placeholder': 'معرفی مختصر خودتان',
+  'app.settings.basic.country': 'کشور / منطقه',
+  'app.settings.basic.country-message': 'لطفاً کشور خود را وارد کنید!',
+  'app.settings.basic.geographic': 'استان یا شهر',
+  'app.settings.basic.geographic-message':
+    'لطفاً اطلاعات جغرافیایی خود را وارد کنید!',
+  'app.settings.basic.address': 'آدرس خیابان',
+  'app.settings.basic.address-message': 'لطفا آدرس خود را وارد کنید!',
+  'app.settings.basic.phone': 'شماره تلفن',
+  'app.settings.basic.phone-message': 'لطفاً تلفن خود را وارد کنید!',
+  'app.settings.basic.update': 'به روز رسانی اطلاعات',
+  'app.settings.security.strong': 'قوی',
+  'app.settings.security.medium': 'متوسط',
+  'app.settings.security.weak': 'ضعیف',
+  'app.settings.security.password': 'رمز عبور حساب کاربری',
+  'app.settings.security.password-description': 'قدرت رمز عبور فعلی',
+  'app.settings.security.phone': 'تلفن امنیتی',
+  'app.settings.security.phone-description': 'تلفن مقید',
+  'app.settings.security.question': 'سوال امنیتی',
+  'app.settings.security.question-description':
+    'سوال امنیتی تنظیم نشده است و سیاست امنیتی می تواند به طور موثر از امنیت حساب محافظت کند',
+  'app.settings.security.email': 'ایمیل پشتیبان',
+  'app.settings.security.email-description': 'ایمیل مقید',
+  'app.settings.security.mfa': 'دستگاه MFA',
+  'app.settings.security.mfa-description':
+    'دستگاه MFA بسته نشده ، پس از اتصال ، می تواند دو بار تأیید شود',
+  'app.settings.security.modify': 'تغییر',
+  'app.settings.security.set': 'تنظیم',
+  'app.settings.security.bind': 'بستن',
+  'app.settings.binding.taobao': 'اتصال Taobao',
+  'app.settings.binding.taobao-description':
+    'حساب Taobao در حال حاضر بسته نشده است',
+  'app.settings.binding.alipay': 'اتصال Alipay',
+  'app.settings.binding.alipay-description':
+    'حساب Alipay در حال حاضر بسته نشده است',
+  'app.settings.binding.dingding': 'اتصال DingTalk',
+  'app.settings.binding.dingding-description':
+    'حساب DingTalk در حال حاضر محدود نشده است',
+  'app.settings.binding.bind': 'بستن',
+  'app.settings.notification.password': 'رمز عبور حساب کاربری',
+  'app.settings.notification.password-description':
+    'پیام های سایر کاربران در قالب یک نامه ایستگاهی اعلام خواهد شد',
+  'app.settings.notification.messages': 'پیام های سیستم',
+  'app.settings.notification.messages-description':
+    'پیام های سیستم به صورت نامه ایستگاه مطلع می شوند',
+  'app.settings.notification.todo': 'اعلان کارها',
+  'app.settings.notification.todo-description':
+    'لیست کارها به صورت نامه ای از ایستگاه اطلاع داده می شود',
+  'app.settings.open': 'باز کن',
+  'app.settings.close': 'بستن',
+};

+ 25 - 0
src/locales/id-ID.ts

@@ -0,0 +1,25 @@
+import component from './id-ID/component';
+import globalHeader from './id-ID/globalHeader';
+import menu from './id-ID/menu';
+import pages from './id-ID/pages';
+import pwa from './id-ID/pwa';
+import settingDrawer from './id-ID/settingDrawer';
+import settings from './id-ID/settings';
+
+export default {
+  'navbar.lang': 'Bahasa',
+  'layout.user.link.help': 'Bantuan',
+  'layout.user.link.privacy': 'Privasi',
+  'layout.user.link.terms': 'Ketentuan',
+  'app.preview.down.block': 'Unduh halaman ini dalam projek lokal anda',
+  'app.welcome.link.fetch-blocks': 'Dapatkan semua blok',
+  'app.welcome.link.block-list':
+    'Buat standar dengan cepat, halaman-halaman berdasarkan pengembangan `block`',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/id-ID/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': 'Perluas',
+  'component.tagSelect.collapse': 'Lipat',
+  'component.tagSelect.all': 'Semua',
+};

+ 18 - 0
src/locales/id-ID/globalHeader.ts

@@ -0,0 +1,18 @@
+export default {
+  'component.globalHeader.search': 'Pencarian',
+  'component.globalHeader.search.example1': 'Contoh 1 Pencarian',
+  'component.globalHeader.search.example2': 'Contoh 2 Pencarian',
+  'component.globalHeader.search.example3': 'Contoh 3 Pencarian',
+  'component.globalHeader.help': 'Bantuan',
+  'component.globalHeader.notification': 'Notifikasi',
+  'component.globalHeader.notification.empty':
+    'Anda telah membaca semua notifikasi',
+  'component.globalHeader.message': 'Pesan',
+  'component.globalHeader.message.empty': 'Anda telah membaca semua pesan.',
+  'component.globalHeader.event': 'Acara',
+  'component.globalHeader.event.empty': 'Anda telah melihat semua acara.',
+  'component.noticeIcon.clear': 'Kosongkan',
+  'component.noticeIcon.cleared': 'Berhasil dikosongkan',
+  'component.noticeIcon.empty': 'Tidak ada pemberitahuan',
+  'component.noticeIcon.view-more': 'Melihat lebih',
+};

+ 53 - 0
src/locales/id-ID/menu.ts

@@ -0,0 +1,53 @@
+export default {
+  'menu.welcome': 'Selamat Datang',
+  'menu.more-blocks': 'Blocks Lainnya',
+  'menu.home': 'Halaman Awal',
+  'menu.admin': 'Admin',
+  'menu.admin.sub-page': 'Sub-Halaman',
+  'menu.login': 'Masuk',
+  'menu.register': 'Pendaftaran',
+  'menu.register-result': 'Hasil Pendaftaran',
+  'menu.dashboard': 'Dasbor',
+  'menu.dashboard.analysis': 'Analisis',
+  'menu.dashboard.monitor': 'Monitor',
+  'menu.dashboard.workplace': 'Workplace',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'Form',
+  'menu.form.basic-form': 'Form Dasar',
+  'menu.form.step-form': 'Form Bertahap',
+  'menu.form.step-form.info': 'Form Bertahap(menulis informasi yang dibagikan)',
+  'menu.form.step-form.confirm':
+    'Form Bertahap(konfirmasi informasi yang dibagikan)',
+  'menu.form.step-form.result': 'Form Bertahap(selesai)',
+  'menu.form.advanced-form': 'Form Lanjutan',
+  'menu.list': 'Daftar',
+  'menu.list.table-list': 'Tabel Pencarian',
+  'menu.list.basic-list': 'Daftar Dasar',
+  'menu.list.card-list': 'Daftar Kartu',
+  'menu.list.search-list': 'Daftar Pencarian',
+  'menu.list.search-list.articles': 'Daftar Pencarian(artikel)',
+  'menu.list.search-list.projects': 'Daftar Pencarian(projek)',
+  'menu.list.search-list.applications': 'Daftar Pencarian(aplikasi)',
+  'menu.profile': 'Profil',
+  'menu.profile.basic': 'Profil Dasar',
+  'menu.profile.advanced': 'Profile Lanjutan',
+  'menu.result': 'Hasil',
+  'menu.result.success': 'Sukses',
+  'menu.result.fail': 'Gagal',
+  'menu.exception': 'Pengecualian',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'Jalankan',
+  'menu.account': 'Akun',
+  'menu.account.center': 'Detail Akun',
+  'menu.account.settings': 'Pengaturan Akun',
+  'menu.account.trigger': 'Mengaktivasi Error',
+  'menu.account.logout': 'Keluar',
+  'menu.editor': 'Penyusun Grafis',
+  'menu.editor.flow': 'Penyusun Alur',
+  'menu.editor.mind': 'Penyusun Mind',
+  'menu.editor.koni': 'Penyusun Koni',
+};

+ 75 - 0
src/locales/id-ID/pages.ts

@@ -0,0 +1,75 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'Ant Design adalah spesifikasi desain Web yang paling berpengaruh di Kabupaten Xihu',
+  'pages.login.accountLogin.tab': 'Login dengan akun',
+  'pages.login.accountLogin.errorMessage':
+    'Nama pengguna dan kata sandi salah(admin/ant.design)',
+  'pages.login.failure': 'Log masuk gagal, silakan coba lagi!',
+  'pages.login.success': 'Login berhasil!',
+  'pages.login.username.placeholder': 'nama pengguna: admin atau user',
+  'pages.login.username.required': 'Nama pengguna harus diisi!',
+  'pages.login.password.placeholder': 'kata sandi: ant.design',
+  'pages.login.password.required': 'Kata sandi harus diisi!',
+  'pages.login.phoneLogin.tab': 'Login dengan ponsel',
+  'pages.login.phoneLogin.errorMessage': 'Kesalahan kode verifikasi',
+  'pages.login.phoneNumber.placeholder': 'masukkan nomor telepon',
+  'pages.login.phoneNumber.required': 'Nomor ponsel harus diisi!',
+  'pages.login.phoneNumber.invalid': 'Nomor ponsel tidak valid!',
+  'pages.login.captcha.placeholder': 'kode verifikasi',
+  'pages.login.captcha.required': 'Kode verifikasi diperlukan!',
+  'pages.login.phoneLogin.getVerificationCode': 'Dapatkan kode',
+  'pages.getCaptchaSecondText': 'detik tersisa',
+  'pages.login.rememberMe': 'Ingat saya',
+  'pages.login.forgotPassword': 'Lupa Kata Sandi?',
+  'pages.login.submit': 'Masuk',
+  'pages.login.loginWith': 'Masuk dengan :',
+  'pages.login.registerAccount': 'Daftar Akun',
+  'pages.welcome.link': 'Selamat datang',
+  'pages.welcome.alertMessage':
+    'Komponen heavy-duty yang lebih cepat dan lebih kuat telah dirilis.',
+  'pages.404.subTitle': 'Maaf, halaman yang Anda kunjungi tidak ada. ',
+  'pages.404.buttonText': 'Kembali ke halaman utama',
+  'pages.admin.subPage.title': 'Halaman ini hanya dapat dilihat oleh admin',
+  'pages.admin.subPage.alertMessage':
+    'umi ui telah dirilis, silahkan gunakan npm run ui untuk memulai pengalaman.',
+  'pages.searchTable.createForm.newRule': 'Aturan baru',
+  'pages.searchTable.updateForm.ruleConfig': 'Konfigurasi aturan',
+  'pages.searchTable.updateForm.basicConfig': 'Informasi dasar',
+  'pages.searchTable.updateForm.ruleName.nameLabel': 'Nama aturan',
+  'pages.searchTable.updateForm.ruleName.nameRules':
+    'Harap masukkan nama aturan!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'Deskripsi aturan',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    'Harap masukkan setidaknya lima karakter',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    'Harap masukkan deskripsi aturan setidaknya lima karakter!',
+  'pages.searchTable.updateForm.ruleProps.title': 'Properti aturan',
+  'pages.searchTable.updateForm.object': 'Objek pemantauan',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'Template aturan',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'Jenis aturan',
+  'pages.searchTable.updateForm.schedulingPeriod.title': 'Periode penjadwalan',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Waktu mulai',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    'Pilih waktu mulai!',
+  'pages.searchTable.titleDesc': 'deskripsi',
+  'pages.searchTable.ruleName': 'Nama aturan wajib diisi',
+  'pages.searchTable.titleCallNo': 'Jumlah panggilan',
+  'pages.searchTable.titleStatus': 'Status',
+  'pages.searchTable.nameStatus.default': 'default',
+  'pages.searchTable.nameStatus.running': 'menyala',
+  'pages.searchTable.nameStatus.online': 'online',
+  'pages.searchTable.nameStatus.abnormal': 'abnormal',
+  'pages.searchTable.titleUpdatedAt': 'Waktu terjadwal',
+  'pages.searchTable.exception': 'Harap masukkan alasan pengecualian!',
+  'pages.searchTable.titleOption': 'Pengoperasian',
+  'pages.searchTable.config': 'Konfigurasi',
+  'pages.searchTable.subscribeAlert': 'Berlangganan notifikasi',
+  'pages.searchTable.title': 'Formulir pertanyaan',
+  'pages.searchTable.new': 'Baru',
+  'pages.searchTable.chosen': 'Terpilih',
+  'pages.searchTable.item': 'item',
+  'pages.searchTable.totalServiceCalls': 'Jumlah total panggilan layanan',
+  'pages.searchTable.tenThousand': '0000',
+  'pages.searchTable.batchDeletion': 'Penghapusan batch',
+  'pages.searchTable.batchApproval': 'Persetujuan batch',
+};

+ 7 - 0
src/locales/id-ID/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'Koneksi anda terputus',
+  'app.pwa.serviceworker.updated': 'Konten baru sudah tersedia',
+  'app.pwa.serviceworker.updated.hint':
+    'Silahkan klik tombol "Refresh" untuk memuat ulang halaman ini',
+  'app.pwa.serviceworker.updated.ok': 'Memuat ulang',
+};

+ 33 - 0
src/locales/id-ID/settingDrawer.ts

@@ -0,0 +1,33 @@
+export default {
+  'app.setting.pagestyle': 'Pengaturan style Halaman',
+  'app.setting.pagestyle.dark': 'Style Gelap',
+  'app.setting.pagestyle.light': 'Style Cerah',
+  'app.setting.content-width': 'Lebar Konten',
+  'app.setting.content-width.fixed': 'Tetap',
+  'app.setting.content-width.fluid': 'Fluid',
+  'app.setting.themecolor': 'Theme Color',
+  'app.setting.themecolor.dust': 'Dust Red',
+  'app.setting.themecolor.volcano': 'Volcano',
+  'app.setting.themecolor.sunset': 'Sunset Orange',
+  'app.setting.themecolor.cyan': 'Cyan',
+  'app.setting.themecolor.green': 'Polar Green',
+  'app.setting.themecolor.daybreak': 'Daybreak Blue (bawaan)',
+  'app.setting.themecolor.geekblue': 'Geek Glue',
+  'app.setting.themecolor.purple': 'Golden Purple',
+  'app.setting.navigationmode': 'Mode Navigasi',
+  'app.setting.sidemenu': 'Susunan Menu Samping',
+  'app.setting.topmenu': 'Susunan Menu Atas',
+  'app.setting.fixedheader': 'Header Tetap',
+  'app.setting.fixedsidebar': 'Sidebar Tetap',
+  'app.setting.fixedsidebar.hint': 'Berjalan pada Susunan Menu Samping',
+  'app.setting.hideheader': 'Sembunyikan Header ketika gulir ke bawah',
+  'app.setting.hideheader.hint':
+    'Bekerja ketika Header tersembunyi dimunculkan',
+  'app.setting.othersettings': 'Pengaturan Lainnya',
+  'app.setting.weakmode': 'Mode Lemah',
+  'app.setting.copy': 'Salin Pengaturan',
+  'app.setting.copyinfo':
+    'Berhasil disalin, tolong ubah defaultSettings pada src/models/setting.js',
+  'app.setting.production.hint':
+    'Panel pengaturan hanya muncul pada lingkungan pengembangan, silahkan modifikasi secara menual',
+};

+ 64 - 0
src/locales/id-ID/settings.ts

@@ -0,0 +1,64 @@
+export default {
+  'app.settings.menuMap.basic': 'Pengaturan Dasar',
+  'app.settings.menuMap.security': 'Pengaturan Keamanan',
+  'app.settings.menuMap.binding': 'Pengikatan Akun',
+  'app.settings.menuMap.notification': 'Notifikasi Pesan Baru',
+  'app.settings.basic.avatar': 'Avatar',
+  'app.settings.basic.change-avatar': 'Ubah avatar',
+  'app.settings.basic.email': 'Email',
+  'app.settings.basic.email-message': 'Tolong masukkan email!',
+  'app.settings.basic.nickname': 'Nickname',
+  'app.settings.basic.nickname-message': 'Tolong masukkan Nickname!',
+  'app.settings.basic.profile': 'Profil Personal',
+  'app.settings.basic.profile-message': 'Tolong masukkan profil personal!',
+  'app.settings.basic.profile-placeholder':
+    'Perkenalan Singkat tentang Diri Anda',
+  'app.settings.basic.country': 'Negara/Wilayah',
+  'app.settings.basic.country-message': 'Tolong masukkan negara anda!',
+  'app.settings.basic.geographic': 'Provinsi atau kota',
+  'app.settings.basic.geographic-message':
+    'Tolong masukkan info geografis anda!',
+  'app.settings.basic.address': 'Alamat Jalan',
+  'app.settings.basic.address-message': 'Tolong masukkan Alamat Jalan anda!',
+  'app.settings.basic.phone': 'Nomor Ponsel',
+  'app.settings.basic.phone-message': 'Tolong masukkan Nomor Ponsel anda!',
+  'app.settings.basic.update': 'Perbarui Informasi',
+  'app.settings.security.strong': 'Kuat',
+  'app.settings.security.medium': 'Sedang',
+  'app.settings.security.weak': 'Lemah',
+  'app.settings.security.password': 'Kata Sandi Akun',
+  'app.settings.security.password-description': 'Kekuatan Kata Sandi saat ini',
+  'app.settings.security.phone': 'Keamanan Ponsel',
+  'app.settings.security.phone-description': 'Mengikat Ponsel',
+  'app.settings.security.question': 'Pertanyaan Keamanan',
+  'app.settings.security.question-description':
+    'Pertanyaan Keamanan belum diatur, dan kebijakan keamanan dapat melindungi akun secara efektif',
+  'app.settings.security.email': 'Email Cadangan',
+  'app.settings.security.email-description': 'Mengikat Email',
+  'app.settings.security.mfa': 'Perangka MFA',
+  'app.settings.security.mfa-description':
+    'Tidak mengikat Perangkat MFA, setelah diikat, dapat dikonfirmasi dua kali',
+  'app.settings.security.modify': 'Modifikasi',
+  'app.settings.security.set': 'Setel',
+  'app.settings.security.bind': 'Ikat',
+  'app.settings.binding.taobao': 'Mengikat Taobao',
+  'app.settings.binding.taobao-description':
+    'Tidak mengikat akun Taobao saat ini',
+  'app.settings.binding.alipay': 'Mengikat Alipay',
+  'app.settings.binding.alipay-description':
+    'Tidak mengikat akun Alipay saat ini',
+  'app.settings.binding.dingding': 'Mengikat DingTalk',
+  'app.settings.binding.dingding-description': 'Tidak mengikat akun DingTalk',
+  'app.settings.binding.bind': 'Ikat',
+  'app.settings.notification.password': 'Kata Sandi Akun',
+  'app.settings.notification.password-description':
+    'Pesan dari pengguna lain akan diberitahu dalam bentuk surat',
+  'app.settings.notification.messages': 'Pesan Sistem',
+  'app.settings.notification.messages-description':
+    'Pesan sistem akan diberitahu dalam bentuk surat',
+  'app.settings.notification.todo': 'Notifikasi daftar To-do',
+  'app.settings.notification.todo-description':
+    'Daftar to-do akan diberitahukan dalam bentuk surat dari stasiun',
+  'app.settings.open': 'Buka',
+  'app.settings.close': 'Tutup',
+};

+ 25 - 0
src/locales/ja-JP.ts

@@ -0,0 +1,25 @@
+import component from './ja-JP/component';
+import globalHeader from './ja-JP/globalHeader';
+import menu from './ja-JP/menu';
+import pages from './ja-JP/pages';
+import pwa from './ja-JP/pwa';
+import settingDrawer from './ja-JP/settingDrawer';
+import settings from './ja-JP/settings';
+
+export default {
+  'navBar.lang': '言語',
+  'layout.user.link.help': 'ヘルプ',
+  'layout.user.link.privacy': 'プライバシー',
+  'layout.user.link.terms': '利用規約',
+  'app.preview.down.block':
+    'このページをローカルプロジェクトにダウンロードしてください',
+  'app.welcome.link.fetch-blocks': '',
+  'app.welcome.link.block-list': '',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/ja-JP/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': '展開',
+  'component.tagSelect.collapse': '折りたたむ',
+  'component.tagSelect.all': 'すべて',
+};

+ 17 - 0
src/locales/ja-JP/globalHeader.ts

@@ -0,0 +1,17 @@
+export default {
+  'component.globalHeader.search': '検索',
+  'component.globalHeader.search.example1': '検索例1',
+  'component.globalHeader.search.example2': '検索例2',
+  'component.globalHeader.search.example3': '検索例3',
+  'component.globalHeader.help': 'ヘルプ',
+  'component.globalHeader.notification': '通知',
+  'component.globalHeader.notification.empty': 'すべての通知を表示しました。',
+  'component.globalHeader.message': 'メッセージ',
+  'component.globalHeader.message.empty': 'すべてのメッセージを表示しました。',
+  'component.globalHeader.event': 'イベント',
+  'component.globalHeader.event.empty': 'すべてのイベントを表示しました。',
+  'component.noticeIcon.clear': 'クリア',
+  'component.noticeIcon.cleared': 'クリア済み',
+  'component.noticeIcon.empty': '通知なし',
+  'component.noticeIcon.view-more': 'もっと見る',
+};

+ 52 - 0
src/locales/ja-JP/menu.ts

@@ -0,0 +1,52 @@
+export default {
+  'menu.welcome': 'ようこそ',
+  'menu.more-blocks': 'その他のブロック',
+  'menu.home': 'ホーム',
+  'menu.admin': '管理者',
+  'menu.admin.sub-page': 'サブページ',
+  'menu.login': 'ログイン',
+  'menu.register': '登録',
+  'menu.register-result': '登録結果',
+  'menu.dashboard': 'ダッシュボード',
+  'menu.dashboard.analysis': '分析',
+  'menu.dashboard.monitor': 'モニター',
+  'menu.dashboard.workplace': '職場',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'フォーム',
+  'menu.form.basic-form': '基本フォーム',
+  'menu.form.step-form': 'ステップフォーム',
+  'menu.form.step-form.info': 'ステップフォーム(転送情報の書き込み)',
+  'menu.form.step-form.confirm': 'ステップフォーム(転送情報の確認)',
+  'menu.form.step-form.result': 'ステップフォーム(完成)',
+  'menu.form.advanced-form': '高度なフォーム',
+  'menu.list': 'リスト',
+  'menu.list.table-list': '検索テーブル',
+  'menu.list.basic-list': '基本リスト',
+  'menu.list.card-list': 'カードリスト',
+  'menu.list.search-list': '検索リスト',
+  'menu.list.search-list.articles': '検索リスト(記事)',
+  'menu.list.search-list.projects': '検索リスト(プロジェクト)',
+  'menu.list.search-list.applications': '検索リスト(アプリ)',
+  'menu.profile': 'プロフィール',
+  'menu.profile.basic': '基本プロフィール',
+  'menu.profile.advanced': '高度なプロフィール',
+  'menu.result': '結果',
+  'menu.result.success': '成功',
+  'menu.result.fail': '失敗',
+  'menu.exception': '例外',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'トリガー',
+  'menu.account': 'アカウント',
+  'menu.account.center': 'アカウントセンター',
+  'menu.account.settings': 'アカウント設定',
+  'menu.account.trigger': 'トリガーエラー',
+  'menu.account.logout': 'ログアウト',
+  'menu.editor': 'グラフィックエディタ',
+  'menu.editor.flow': 'フローエディタ',
+  'menu.editor.mind': 'マインドエディター',
+  'menu.editor.koni': 'コニエディター',
+};

+ 77 - 0
src/locales/ja-JP/pages.ts

@@ -0,0 +1,77 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'Ant Designは、西湖区で最も影響力のあるWebデザイン仕様です。',
+  'pages.login.accountLogin.tab': 'アカウントログイン',
+  'pages.login.accountLogin.errorMessage':
+    'ユーザー名/パスワードが正しくありません(admin/ant.design)',
+  'pages.login.failure': 'ログインに失敗したら、もう一度試してください!',
+  'pages.login.success': 'ログイン成功!',
+  'pages.login.username.placeholder': 'ユーザー名:adminまたはuser',
+  'pages.login.username.required': 'ユーザー名を入力してください!',
+  'pages.login.password.placeholder': 'パスワード:ant.design',
+  'pages.login.password.required': 'パスワードを入力してください!',
+  'pages.login.phoneLogin.tab': '電話ログイン',
+  'pages.login.phoneLogin.errorMessage': '検証コードエラー',
+  'pages.login.phoneNumber.placeholder': '電話番号',
+  'pages.login.phoneNumber.required': '電話番号を入力してください!',
+  'pages.login.phoneNumber.invalid': '電話番号が無効です!',
+  'pages.login.captcha.placeholder': '確認コード',
+  'pages.login.captcha.required': '確認コードを入力してください!',
+  'pages.login.phoneLogin.getVerificationCode': '確認コードを取得',
+  'pages.getCaptchaSecondText': '秒',
+  'pages.login.rememberMe': 'Remember me',
+  'pages.login.forgotPassword': 'パスワードをお忘れですか?',
+  'pages.login.submit': 'ログイン',
+  'pages.login.loginWith': 'その他のログイン方法:',
+  'pages.login.registerAccount': 'アカウント登録',
+  'pages.welcome.link': 'ようこそ',
+  'pages.welcome.alertMessage':
+    'より高速で強力な頑丈なコンポーネントがリリースされました。',
+  'pages.404.subTitle':
+    '申し訳ありませんが、アクセスしたページは存在しません。',
+  'pages.404.buttonText': 'ホームに戻る',
+  'pages.admin.subPage.title': 'このページは管理者のみが表示できます',
+  'pages.admin.subPage.alertMessage':
+    'Umi uiがリリースされました。npm run uiを使用して体験してください。',
+  'pages.searchTable.createForm.newRule': '新しいルール',
+  'pages.searchTable.updateForm.ruleConfig': 'ルール構成',
+  'pages.searchTable.updateForm.basicConfig': '基本情報',
+  'pages.searchTable.updateForm.ruleName.nameLabel': 'ルール名',
+  'pages.searchTable.updateForm.ruleName.nameRules':
+    'ルール名を入力してください!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'ルールの説明',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    '5文字以上入力してください',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    '5文字以上のルールの説明を入力してください!',
+  'pages.searchTable.updateForm.ruleProps.title': 'プロパティの構成',
+  'pages.searchTable.updateForm.object': '監視対象',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'ルールテンプレート',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'ルールタイプ',
+  'pages.searchTable.updateForm.schedulingPeriod.title':
+    'スケジュール期間の設定',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': '開始時間',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    '開始時間を選択してください!',
+  'pages.searchTable.titleDesc': '説明',
+  'pages.searchTable.ruleName': 'ルール名が必要です',
+  'pages.searchTable.titleCallNo': 'サービスコール数',
+  'pages.searchTable.titleStatus': 'ステータス',
+  'pages.searchTable.nameStatus.default': 'デフォルト',
+  'pages.searchTable.nameStatus.running': '起動中',
+  'pages.searchTable.nameStatus.online': 'オンライン',
+  'pages.searchTable.nameStatus.abnormal': '異常',
+  'pages.searchTable.titleUpdatedAt': '最終スケジュール',
+  'pages.searchTable.exception': '例外の理由を入力してください!',
+  'pages.searchTable.titleOption': 'オプション',
+  'pages.searchTable.config': '構成',
+  'pages.searchTable.subscribeAlert': 'アラートを購読する',
+  'pages.searchTable.title': 'お問い合わせフォーム',
+  'pages.searchTable.new': '新しい',
+  'pages.searchTable.chosen': '選んだ項目',
+  'pages.searchTable.item': '項目',
+  'pages.searchTable.totalServiceCalls': 'サービスコールの総数',
+  'pages.searchTable.tenThousand': '万',
+  'pages.searchTable.batchDeletion': 'バッチ削除',
+  'pages.searchTable.batchApproval': 'バッチ承認',
+};

+ 7 - 0
src/locales/ja-JP/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'あなたは今オフラインです',
+  'app.pwa.serviceworker.updated': '新しいコンテンツが利用可能です',
+  'app.pwa.serviceworker.updated.hint':
+    '現在のページをリロードするには、「更新」ボタンを押してください',
+  'app.pwa.serviceworker.updated.ok': 'リフレッシュ',
+};

+ 33 - 0
src/locales/ja-JP/settingDrawer.ts

@@ -0,0 +1,33 @@
+export default {
+  'app.setting.pagestyle': 'ページスタイル設定',
+  'app.setting.pagestyle.dark': 'ダークスタイル',
+  'app.setting.pagestyle.light': 'ライトスタイル',
+  'app.setting.content-width': 'コンテンツの幅',
+  'app.setting.content-width.fixed': '固定',
+  'app.setting.content-width.fluid': '流体',
+  'app.setting.themecolor': 'テーマカラー',
+  'app.setting.themecolor.dust': 'ダストレッド',
+  'app.setting.themecolor.volcano': 'ボルケ-ノ',
+  'app.setting.themecolor.sunset': 'サンセットオレンジ',
+  'app.setting.themecolor.cyan': 'シアン',
+  'app.setting.themecolor.green': 'ポーラーグリーン',
+  'app.setting.themecolor.daybreak': '夜明けの青(デフォルト)',
+  'app.setting.themecolor.geekblue': 'ギーク ブルー',
+  'app.setting.themecolor.purple': 'ゴールデンパープル',
+  'app.setting.navigationmode': 'ナビゲーションモード',
+  'app.setting.sidemenu': 'サイドメニューのレイアウト',
+  'app.setting.topmenu': 'トップメニューのレイアウト',
+  'app.setting.fixedheader': '固定ヘッダー',
+  'app.setting.fixedsidebar': '固定サイドバー',
+  'app.setting.fixedsidebar.hint': 'サイドメニューのレイアウトで動作します',
+  'app.setting.hideheader': 'スクロール時の非表示ヘッダー',
+  'app.setting.hideheader.hint':
+    '非表示ヘッダーが有効になっている場合に機能します',
+  'app.setting.othersettings': 'その他の設定',
+  'app.setting.weakmode': 'ウィークモード',
+  'app.setting.copy': 'コピー設定',
+  'app.setting.copyinfo':
+    'コピーが成功しました。src/models/setting.jsのdefaultSettingsを置き換えてください',
+  'app.setting.production.hint':
+    '設定パネルは開発環境でのみ表示されます。手動で変更してください',
+};

+ 63 - 0
src/locales/ja-JP/settings.ts

@@ -0,0 +1,63 @@
+export default {
+  'app.settings.menuMap.basic': '基本設定',
+  'app.settings.menuMap.security': 'セキュリティ設定',
+  'app.settings.menuMap.binding': 'アカウントのバインド',
+  'app.settings.menuMap.notification': '新しいメッセージの通知',
+  'app.settings.basic.avatar': 'アバター',
+  'app.settings.basic.change-avatar': 'アバターを変更する',
+  'app.settings.basic.email': 'メール',
+  'app.settings.basic.email-message': 'メールアドレスを入力してください!',
+  'app.settings.basic.nickname': 'ニックネーム',
+  'app.settings.basic.nickname-message': 'ニックネームを入力してください!',
+  'app.settings.basic.profile': '個人プロフィール',
+  'app.settings.basic.profile-message': '個人プロフィールを入力してください!',
+  'app.settings.basic.profile-placeholder': '自己紹介',
+  'app.settings.basic.country': '国/地域',
+  'app.settings.basic.country-message': 'あなたの国を入力してください!',
+  'app.settings.basic.geographic': '州または市',
+  'app.settings.basic.geographic-message': '地理情報を入力してください!',
+  'app.settings.basic.address': '住所',
+  'app.settings.basic.address-message': '住所を入力してください!',
+  'app.settings.basic.phone': '電話番号',
+  'app.settings.basic.phone-message': '電話番号を入力してください!',
+  'app.settings.basic.update': '更新情報',
+  'app.settings.security.strong': '強い',
+  'app.settings.security.medium': 'ミディアム',
+  'app.settings.security.weak': '弱い',
+  'app.settings.security.password': 'アカウントパスワード',
+  'app.settings.security.password-description': '現在のパスワードの強度',
+  'app.settings.security.phone': 'セキュリティ電話番号',
+  'app.settings.security.phone-description': 'バインドされた電話番号',
+  'app.settings.security.question': '秘密の質問',
+  'app.settings.security.question-description':
+    'セキュリティの質問が設定されてません。セキュリティポリシーはアカウントのセキュリティを効果的に保護できます',
+  'app.settings.security.email': 'バックアップメール',
+  'app.settings.security.email-description': 'バインドされたメール',
+  'app.settings.security.mfa': '多要素認証デバイス',
+  'app.settings.security.mfa-description':
+    'バインドされていない多要素認証デバイスは、バインド後、2回確認できます',
+  'app.settings.security.modify': '変更する',
+  'app.settings.security.set': 'セットする',
+  'app.settings.security.bind': 'バインド',
+  'app.settings.binding.taobao': 'タオバオをバインドする',
+  'app.settings.binding.taobao-description':
+    '現在バインドされていないタオバオアカウント',
+  'app.settings.binding.alipay': 'アリペイをバインドする',
+  'app.settings.binding.alipay-description':
+    '現在バインドされていないアリペイアカウント',
+  'app.settings.binding.dingding': 'ディントークをバインドする',
+  'app.settings.binding.dingding-description':
+    '現在バインドされていないディントークアカウント',
+  'app.settings.binding.bind': 'バインド',
+  'app.settings.notification.password': 'アカウントパスワード',
+  'app.settings.notification.password-description':
+    '他のユーザーからのメッセージは、ステーションレターの形式で通知されます',
+  'app.settings.notification.messages': 'システムメッセージ',
+  'app.settings.notification.messages-description':
+    'システムメッセージは、ステーションレターの形式で通知されます',
+  'app.settings.notification.todo': 'To Do(用事) 通知',
+  'app.settings.notification.todo-description':
+    'To Doタスクは、内部レターの形式で通知されます',
+  'app.settings.open': '開く',
+  'app.settings.close': '閉じる',
+};

+ 22 - 0
src/locales/pt-BR.ts

@@ -0,0 +1,22 @@
+import component from './pt-BR/component';
+import globalHeader from './pt-BR/globalHeader';
+import menu from './pt-BR/menu';
+import pages from './pt-BR/pages';
+import pwa from './pt-BR/pwa';
+import settingDrawer from './pt-BR/settingDrawer';
+import settings from './pt-BR/settings';
+
+export default {
+  'navBar.lang': 'Idiomas',
+  'layout.user.link.help': 'ajuda',
+  'layout.user.link.privacy': 'política de privacidade',
+  'layout.user.link.terms': 'termos de serviços',
+  'app.preview.down.block': 'Download this page to your local project',
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+  ...pages,
+};

+ 5 - 0
src/locales/pt-BR/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': 'Expandir',
+  'component.tagSelect.collapse': 'Diminuir',
+  'component.tagSelect.all': 'Todas',
+};

+ 18 - 0
src/locales/pt-BR/globalHeader.ts

@@ -0,0 +1,18 @@
+export default {
+  'component.globalHeader.search': 'Busca',
+  'component.globalHeader.search.example1': 'Exemplo de busca 1',
+  'component.globalHeader.search.example2': 'Exemplo de busca 2',
+  'component.globalHeader.search.example3': 'Exemplo de busca 3',
+  'component.globalHeader.help': 'Ajuda',
+  'component.globalHeader.notification': 'Notificação',
+  'component.globalHeader.notification.empty':
+    'Você visualizou todas as notificações.',
+  'component.globalHeader.message': 'Mensagem',
+  'component.globalHeader.message.empty': 'Você visualizou todas as mensagens.',
+  'component.globalHeader.event': 'Evento',
+  'component.globalHeader.event.empty': 'Você visualizou todos os eventos.',
+  'component.noticeIcon.clear': 'Limpar',
+  'component.noticeIcon.cleared': 'Limpo',
+  'component.noticeIcon.empty': 'Sem notificações',
+  'component.noticeIcon.view-more': 'Veja mais',
+};

+ 54 - 0
src/locales/pt-BR/menu.ts

@@ -0,0 +1,54 @@
+export default {
+  'menu.welcome': 'Welcome',
+  'menu.more-blocks': 'More Blocks',
+  'menu.home': 'Início',
+  'menu.admin': 'Admin',
+  'menu.admin.sub-page': 'Sub-Page',
+  'menu.login': 'Login',
+  'menu.register': 'Registro',
+  'menu.register-result': 'Resultado de registro',
+  'menu.dashboard': 'Dashboard',
+  'menu.dashboard.analysis': 'Análise',
+  'menu.dashboard.monitor': 'Monitor',
+  'menu.dashboard.workplace': 'Ambiente de Trabalho',
+  'menu.exception.403': '403',
+  'menu.exception.404': '404',
+  'menu.exception.500': '500',
+  'menu.form': 'Formulário',
+  'menu.form.basic-form': 'Formulário Básico',
+  'menu.form.step-form': 'Formulário Assistido',
+  'menu.form.step-form.info':
+    'Formulário Assistido(gravar informações de transferência)',
+  'menu.form.step-form.confirm':
+    'Formulário Assistido(confirmar informações de transferência)',
+  'menu.form.step-form.result': 'Formulário Assistido(finalizado)',
+  'menu.form.advanced-form': 'Formulário Avançado',
+  'menu.list': 'Lista',
+  'menu.list.table-list': 'Tabela de Busca',
+  'menu.list.basic-list': 'Lista Básica',
+  'menu.list.card-list': 'Lista de Card',
+  'menu.list.search-list': 'Lista de Busca',
+  'menu.list.search-list.articles': 'Lista de Busca(artigos)',
+  'menu.list.search-list.projects': 'Lista de Busca(projetos)',
+  'menu.list.search-list.applications': 'Lista de Busca(aplicações)',
+  'menu.profile': 'Perfil',
+  'menu.profile.basic': 'Perfil Básico',
+  'menu.profile.advanced': 'Perfil Avançado',
+  'menu.result': 'Resultado',
+  'menu.result.success': 'Sucesso',
+  'menu.result.fail': 'Falha',
+  'menu.exception': 'Exceção',
+  'menu.exception.not-permission': '403',
+  'menu.exception.not-find': '404',
+  'menu.exception.server-error': '500',
+  'menu.exception.trigger': 'Disparar',
+  'menu.account': 'Conta',
+  'menu.account.center': 'Central da Conta',
+  'menu.account.settings': 'Configurar Conta',
+  'menu.account.trigger': 'Disparar Erro',
+  'menu.account.logout': 'Sair',
+  'menu.editor': 'Graphic Editor',
+  'menu.editor.flow': 'Flow Editor',
+  'menu.editor.mind': 'Mind Editor',
+  'menu.editor.koni': 'Koni Editor',
+};

+ 77 - 0
src/locales/pt-BR/pages.ts

@@ -0,0 +1,77 @@
+export default {
+  'pages.layouts.userLayout.title':
+    'Ant Design é a especificação de web design mais influente no distrito de Xihu',
+  'pages.login.accountLogin.tab': 'Login da conta',
+  'pages.login.accountLogin.errorMessage':
+    'usuário/senha incorreto(admin/ant.design)',
+  'pages.login.failure': 'Login falhou, por favor tente novamente!',
+  'pages.login.success': 'Login efetuado com sucesso!',
+  'pages.login.username.placeholder': 'Usuário: admin or user',
+  'pages.login.username.required': 'Por favor insira seu usuário!',
+  'pages.login.password.placeholder': 'Senha: ant.design',
+  'pages.login.password.required': 'Por favor insira sua senha!',
+  'pages.login.phoneLogin.tab': 'Login com Telefone',
+  'pages.login.phoneLogin.errorMessage': 'Erro de Código de Verificação',
+  'pages.login.phoneNumber.placeholder': 'Telefone',
+  'pages.login.phoneNumber.required': 'Por favor entre com seu telefone!',
+  'pages.login.phoneNumber.invalid': 'Telefone é inválido!',
+  'pages.login.captcha.placeholder': 'Código de Verificação',
+  'pages.login.captcha.required':
+    'Por favor entre com o código de verificação!',
+  'pages.login.phoneLogin.getVerificationCode': 'Obter Código',
+  'pages.getCaptchaSecondText': 'seg(s)',
+  'pages.login.rememberMe': 'Lembre-me',
+  'pages.login.forgotPassword': 'Perdeu a Senha ?',
+  'pages.login.submit': 'Enviar',
+  'pages.login.loginWith': 'Login com :',
+  'pages.login.registerAccount': 'Registra Conta',
+  'pages.welcome.link': 'Bem-vindo',
+  'pages.welcome.alertMessage':
+    'Componentes pesados mais rápidos e mais fortes foram lançados.',
+  'pages.404.subTitle': 'Desculpe, a página que você visitou não existe. ',
+  'pages.404.buttonText': 'Voltar à página inicial',
+  'pages.admin.subPage.title': 'Esta página só pode ser vista pelo Admin',
+  'pages.admin.subPage.alertMessage':
+    'O Umi ui foi lançado, bem-vindo ao usar o npm run ui para iniciar a experiência.',
+  'pages.searchTable.createForm.newRule': 'Neva Regra',
+  'pages.searchTable.updateForm.ruleConfig': 'Configuração de Regra',
+  'pages.searchTable.updateForm.basicConfig': 'Informação básica',
+  'pages.searchTable.updateForm.ruleName.nameLabel': 'Nome da Regra',
+  'pages.searchTable.updateForm.ruleName.nameRules':
+    'Por favor entre com o nome da regra!',
+  'pages.searchTable.updateForm.ruleDesc.descLabel': 'Descrição da Regra',
+  'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
+    'Por favor insira ao menos cinco caracteres',
+  'pages.searchTable.updateForm.ruleDesc.descRules':
+    'Insira uma descrição de regra de pelo menos cinco caracteres!',
+  'pages.searchTable.updateForm.ruleProps.title': 'Configurar Propriedades',
+  'pages.searchTable.updateForm.object': 'Objeto de Monitoramento',
+  'pages.searchTable.updateForm.ruleProps.templateLabel': 'Modelo de Regra',
+  'pages.searchTable.updateForm.ruleProps.typeLabel': 'Tipo de Regra',
+  'pages.searchTable.updateForm.schedulingPeriod.title':
+    'Definir Período de Agendamento',
+  'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Hora de Início',
+  'pages.searchTable.updateForm.schedulingPeriod.timeRules':
+    'Por favor selecione um horáriod e início!',
+  'pages.searchTable.titleDesc': 'Descrição',
+  'pages.searchTable.ruleName': 'O nome da regra é obrigatório',
+  'pages.searchTable.titleCallNo': 'Número de chamadas de serviço',
+  'pages.searchTable.titleStatus': 'Status',
+  'pages.searchTable.nameStatus.default': 'padrão',
+  'pages.searchTable.nameStatus.running': 'executando',
+  'pages.searchTable.nameStatus.online': 'online',
+  'pages.searchTable.nameStatus.abnormal': 'anormal',
+  'pages.searchTable.titleUpdatedAt': 'Última programação em',
+  'pages.searchTable.exception': 'Por favor, indique o motivo da exceção!',
+  'pages.searchTable.titleOption': 'Opção',
+  'pages.searchTable.config': 'Configuração',
+  'pages.searchTable.subscribeAlert': 'Inscreva-se para receber alertas',
+  'pages.searchTable.title': 'Formulário de Consulta',
+  'pages.searchTable.new': 'Novo',
+  'pages.searchTable.chosen': 'selecionado',
+  'pages.searchTable.item': 'item',
+  'pages.searchTable.totalServiceCalls': 'Número total de chamadas de serviço',
+  'pages.searchTable.tenThousand': '0000',
+  'pages.searchTable.batchDeletion': 'deleção em lote',
+  'pages.searchTable.batchApproval': 'aprovação em lote',
+};

+ 7 - 0
src/locales/pt-BR/pwa.ts

@@ -0,0 +1,7 @@
+export default {
+  'app.pwa.offline': 'Você está offline agora',
+  'app.pwa.serviceworker.updated': 'Novo conteúdo está disponível',
+  'app.pwa.serviceworker.updated.hint':
+    'Por favor, pressione o botão "Atualizar" para recarregar a página atual',
+  'app.pwa.serviceworker.updated.ok': 'Atualizar',
+};

+ 33 - 0
src/locales/pt-BR/settingDrawer.ts

@@ -0,0 +1,33 @@
+export default {
+  'app.setting.pagestyle': 'Configuração de estilo da página',
+  'app.setting.pagestyle.dark': 'Dark style',
+  'app.setting.pagestyle.light': 'Light style',
+  'app.setting.content-width': 'Largura do conteúdo',
+  'app.setting.content-width.fixed': 'Fixo',
+  'app.setting.content-width.fluid': 'Fluido',
+  'app.setting.themecolor': 'Cor do Tema',
+  'app.setting.themecolor.dust': 'Dust Red',
+  'app.setting.themecolor.volcano': 'Volcano',
+  'app.setting.themecolor.sunset': 'Sunset Orange',
+  'app.setting.themecolor.cyan': 'Cyan',
+  'app.setting.themecolor.green': 'Polar Green',
+  'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
+  'app.setting.themecolor.geekblue': 'Geek Glue',
+  'app.setting.themecolor.purple': 'Golden Purple',
+  'app.setting.navigationmode': 'Modo de Navegação',
+  'app.setting.sidemenu': 'Layout do Menu Lateral',
+  'app.setting.topmenu': 'Layout do Menu Superior',
+  'app.setting.fixedheader': 'Cabeçalho fixo',
+  'app.setting.fixedsidebar': 'Barra lateral fixa',
+  'app.setting.fixedsidebar.hint': 'Funciona no layout do menu lateral',
+  'app.setting.hideheader': 'Esconder o cabeçalho quando rolar',
+  'app.setting.hideheader.hint':
+    'Funciona quando o esconder cabeçalho está abilitado',
+  'app.setting.othersettings': 'Outras configurações',
+  'app.setting.weakmode': 'Weak Mode',
+  'app.setting.copy': 'Copiar Configuração',
+  'app.setting.copyinfo':
+    'copiado com sucesso, por favor trocar o defaultSettings em src/models/setting.js',
+  'app.setting.production.hint':
+    'O painel de configuração apenas é exibido no ambiente de desenvolvimento, por favor modifique manualmente o',
+};

+ 66 - 0
src/locales/pt-BR/settings.ts

@@ -0,0 +1,66 @@
+export default {
+  'app.settings.menuMap.basic': 'Configurações Básicas',
+  'app.settings.menuMap.security': 'Configurações de Segurança',
+  'app.settings.menuMap.binding': 'Vinculação de Conta',
+  'app.settings.menuMap.notification': 'Mensagens de Notificação',
+  'app.settings.basic.avatar': 'Avatar',
+  'app.settings.basic.change-avatar': 'Alterar avatar',
+  'app.settings.basic.email': 'Email',
+  'app.settings.basic.email-message': 'Por favor insira seu email!',
+  'app.settings.basic.nickname': 'Nome de usuário',
+  'app.settings.basic.nickname-message':
+    'Por favor insira seu nome de usuário!',
+  'app.settings.basic.profile': 'Perfil pessoal',
+  'app.settings.basic.profile-message': 'Por favor insira seu perfil pessoal!',
+  'app.settings.basic.profile-placeholder': 'Breve introdução sua',
+  'app.settings.basic.country': 'País/Região',
+  'app.settings.basic.country-message': 'Por favor insira país!',
+  'app.settings.basic.geographic': 'Província, estado ou cidade',
+  'app.settings.basic.geographic-message':
+    'Por favor insira suas informações geográficas!',
+  'app.settings.basic.address': 'Endereço',
+  'app.settings.basic.address-message': 'Por favor insira seu endereço!',
+  'app.settings.basic.phone': 'Número de telefone',
+  'app.settings.basic.phone-message':
+    'Por favor insira seu número de telefone!',
+  'app.settings.basic.update': 'Atualizar Informações',
+  'app.settings.security.strong': 'Forte',
+  'app.settings.security.medium': 'Média',
+  'app.settings.security.weak': 'Fraca',
+  'app.settings.security.password': 'Senha da Conta',
+  'app.settings.security.password-description': 'Força da senha',
+  'app.settings.security.phone': 'Telefone de Seguraça',
+  'app.settings.security.phone-description': 'Telefone vinculado',
+  'app.settings.security.question': 'Pergunta de Segurança',
+  'app.settings.security.question-description':
+    'A pergunta de segurança não está definida e a política de segurança pode proteger efetivamente a segurança da conta',
+  'app.settings.security.email': 'Email de Backup',
+  'app.settings.security.email-description': 'Email vinculado',
+  'app.settings.security.mfa': 'Dispositivo MFA',
+  'app.settings.security.mfa-description':
+    'O dispositivo MFA não vinculado, após a vinculação, pode ser confirmado duas vezes',
+  'app.settings.security.modify': 'Modificar',
+  'app.settings.security.set': 'Atribuir',
+  'app.settings.security.bind': 'Vincular',
+  'app.settings.binding.taobao': 'Vincular Taobao',
+  'app.settings.binding.taobao-description':
+    'Atualmente não vinculado à conta Taobao',
+  'app.settings.binding.alipay': 'Vincular Alipay',
+  'app.settings.binding.alipay-description':
+    'Atualmente não vinculado à conta Alipay',
+  'app.settings.binding.dingding': 'Vincular DingTalk',
+  'app.settings.binding.dingding-description':
+    'Atualmente não vinculado à conta DingTalk',
+  'app.settings.binding.bind': 'Vincular',
+  'app.settings.notification.password': 'Senha da Conta',
+  'app.settings.notification.password-description':
+    'Mensagens de outros usuários serão notificadas na forma de uma estação de letra',
+  'app.settings.notification.messages': 'Mensagens de Sistema',
+  'app.settings.notification.messages-description':
+    'Mensagens de sistema serão notificadas na forma de uma estação de letra',
+  'app.settings.notification.todo': 'Notificação de To-do',
+  'app.settings.notification.todo-description':
+    'A lista de to-do será notificada na forma de uma estação de letra',
+  'app.settings.open': 'Aberto',
+  'app.settings.close': 'Fechado',
+};

+ 24 - 0
src/locales/zh-CN.ts

@@ -0,0 +1,24 @@
+import component from './zh-CN/component';
+import globalHeader from './zh-CN/globalHeader';
+import menu from './zh-CN/menu';
+import pages from './zh-CN/pages';
+import pwa from './zh-CN/pwa';
+import settingDrawer from './zh-CN/settingDrawer';
+import settings from './zh-CN/settings';
+
+export default {
+  'navBar.lang': '语言',
+  'layout.user.link.help': '帮助',
+  'layout.user.link.privacy': '隐私',
+  'layout.user.link.terms': '条款',
+  'app.preview.down.block': '下载此页面到本地项目',
+  'app.welcome.link.fetch-blocks': '获取全部区块',
+  'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
+  ...pages,
+  ...globalHeader,
+  ...menu,
+  ...settingDrawer,
+  ...settings,
+  ...pwa,
+  ...component,
+};

+ 5 - 0
src/locales/zh-CN/component.ts

@@ -0,0 +1,5 @@
+export default {
+  'component.tagSelect.expand': '展开',
+  'component.tagSelect.collapse': '收起',
+  'component.tagSelect.all': '全部',
+};

+ 17 - 0
src/locales/zh-CN/globalHeader.ts

@@ -0,0 +1,17 @@
+export default {
+  'component.globalHeader.search': '站内搜索',
+  'component.globalHeader.search.example1': '搜索提示一',
+  'component.globalHeader.search.example2': '搜索提示二',
+  'component.globalHeader.search.example3': '搜索提示三',
+  'component.globalHeader.help': '使用文档',
+  'component.globalHeader.notification': '通知',
+  'component.globalHeader.notification.empty': '你已查看所有通知',
+  'component.globalHeader.message': '消息',
+  'component.globalHeader.message.empty': '您已读完所有消息',
+  'component.globalHeader.event': '待办',
+  'component.globalHeader.event.empty': '你已完成所有待办',
+  'component.noticeIcon.clear': '清空',
+  'component.noticeIcon.cleared': '清空了',
+  'component.noticeIcon.empty': '暂无数据',
+  'component.noticeIcon.view-more': '查看更多',
+};

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio