diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..7e3649a
--- /dev/null
+++ b/.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
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..8336e93
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,8 @@
+/lambda/
+/scripts
+/config
+.history
+public
+dist
+.umi
+mock
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..b882c20
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,8 @@
+module.exports = {
+ extends: [require.resolve('@umijs/fabric/dist/eslint')],
+ globals: {
+ ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
+ page: true,
+ REACT_APP_ENV: true,
+ },
+};
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..21ab9fb
--- /dev/null
+++ b/.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
+pnpm-lock.yaml
+*bak
+
+
+# visual studio code
+.history
+*.log
+functions/*
+.temp/**
+
+# umi
+.umi
+.umi-production
+
+# screenshot
+screenshot
+.firebase
+.eslintcache
+
+build
diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 0000000..31354ec
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/commit-msg b/.husky/commit-msg
new file mode 100644
index 0000000..d50cdcf
--- /dev/null
+++ b/.husky/commit-msg
@@ -0,0 +1,7 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+# Export Git hook params
+export GIT_PARAMS=$*
+
+npx --no-install fabric verify-commit
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..d37daa0
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx --no-install lint-staged
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..d17efb4
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,23 @@
+**/*.svg
+package.json
+.umi
+.umi-production
+/dist
+.dockerignore
+.DS_Store
+.eslintignore
+*.png
+*.toml
+docker
+.editorconfig
+Dockerfile*
+.gitignore
+.prettierignore
+LICENSE
+.eslintcache
+*.lock
+yarn-error.log
+.history
+CNAME
+/build
+/public
\ No newline at end of file
diff --git a/.prettierrc.js b/.prettierrc.js
new file mode 100644
index 0000000..7b597d7
--- /dev/null
+++ b/.prettierrc.js
@@ -0,0 +1,5 @@
+const fabric = require('@umijs/fabric');
+
+module.exports = {
+ ...fabric.prettier,
+};
diff --git a/.stylelintrc.js b/.stylelintrc.js
new file mode 100644
index 0000000..a1184de
--- /dev/null
+++ b/.stylelintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: [require.resolve('@umijs/fabric/dist/stylelint')],
+};
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..33f300d
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "esbenp.prettier-vscode",
+ "dbaeumer.vscode-eslint",
+ "stylelint.vscode-stylelint",
+ "wangzy.sneak-mark"
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..a5d9d03
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "editor.formatOnSave": true,
+ "prettier.requireConfig": true,
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+}
diff --git a/config/config.dev.js b/config/config.dev.js
new file mode 100644
index 0000000..8e33701
--- /dev/null
+++ b/config/config.dev.js
@@ -0,0 +1,14 @@
+// https://umijs.org/config/
+import { defineConfig } from 'umi';
+export default defineConfig({
+ plugins: [
+ // https://github.com/zthxxx/react-dev-inspector
+ 'react-dev-inspector/plugins/umi/react-inspector',
+ ],
+ // https://github.com/zthxxx/react-dev-inspector#inspector-loader-props
+ inspectorConfig: {
+ exclude: [],
+ babelPlugins: [],
+ babelOptions: {},
+ },
+});
diff --git a/config/config.js b/config/config.js
new file mode 100644
index 0000000..7110b42
--- /dev/null
+++ b/config/config.js
@@ -0,0 +1,75 @@
+// https://umijs.org/config/
+import { defineConfig } from 'umi';
+import { join } from 'path';
+import defaultSettings from './defaultSettings';
+import proxy from './proxy';
+import routes from './routes';
+const { REACT_APP_ENV } = process.env;
+export default defineConfig({
+ hash: true,
+ antd: {},
+ dva: {
+ hmr: true,
+ },
+ layout: {
+ // https://umijs.org/zh-CN/plugins/plugin-layout
+ locale: true,
+ siderWidth: 208,
+ ...defaultSettings,
+ },
+ // https://umijs.org/zh-CN/plugins/plugin-locale
+ locale: {
+ // default zh-CN
+ default: 'zh-CN',
+ antd: true,
+ // default true, when it is true, will use `navigator.language` overwrite default
+ baseNavigator: true,
+ },
+ dynamicImport: {
+ loading: '@ant-design/pro-layout/es/PageLoading',
+ },
+ targets: {
+ ie: 11,
+ },
+ // umi routes: https://umijs.org/docs/routing
+ routes,
+ access: {},
+ // Theme for antd: https://ant.design/docs/react/customize-theme-cn
+ theme: {
+ // 如果不想要 configProvide 动态设置主题需要把这个设置为 default
+ // 只有设置为 variable, 才能使用 configProvide 动态设置主色调
+ // https://ant.design/docs/react/customize-theme-variable-cn
+ 'root-entry-name': 'variable',
+ },
+ // esbuild is father build tools
+ // https://umijs.org/plugins/plugin-esbuild
+ esbuild: {},
+ title: false,
+ ignoreMomentLocale: true,
+ proxy: proxy[REACT_APP_ENV || 'dev'],
+ manifest: {
+ basePath: '/',
+ },
+ // Fast Refresh 热更新
+ fastRefresh: {},
+ openAPI: [
+ {
+ requestLibPath: "import { request } from 'umi'",
+ // 或者使用在线的版本
+ // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
+ schemaPath: join(__dirname, 'oneapi.json'),
+ mock: false,
+ },
+ {
+ requestLibPath: "import { request } from 'umi'",
+ schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
+ projectName: 'swagger',
+ },
+ ],
+ nodeModulesTransform: {
+ type: 'none',
+ },
+ mfsu: {},
+ webpack5: {},
+ exportStatic: {},
+});
diff --git a/config/defaultSettings.js b/config/defaultSettings.js
new file mode 100644
index 0000000..be689e1
--- /dev/null
+++ b/config/defaultSettings.js
@@ -0,0 +1,15 @@
+const Settings = {
+ navTheme: 'light',
+ // 拂晓蓝
+ primaryColor: '#1890ff',
+ layout: 'mix',
+ contentWidth: 'Fluid',
+ fixedHeader: false,
+ fixSiderbar: true,
+ colorWeak: false,
+ title: 'Ant Design Pro',
+ pwa: false,
+ logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
+ iconfontUrl: '',
+};
+export default Settings;
diff --git a/config/oneapi.json b/config/oneapi.json
new file mode 100644
index 0000000..c77d988
--- /dev/null
+++ b/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"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/config/proxy.js b/config/proxy.js
new file mode 100644
index 0000000..49a4625
--- /dev/null
+++ b/config/proxy.js
@@ -0,0 +1,38 @@
+/**
+ * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
+ * -------------------------------
+ * 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
+ */
+export default {
+ dev: {
+ // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
+ '/api/': {
+ // 要代理的地址
+ target: 'https://preview.pro.ant.design',
+ // 配置了这个可以从 http 代理到 https
+ // 依赖 origin 的功能可能需要这个,比如 cookie
+ changeOrigin: true,
+ },
+ },
+ test: {
+ '/api/': {
+ target: 'https://proapi.azurewebsites.net',
+ changeOrigin: true,
+ pathRewrite: {
+ '^': '',
+ },
+ },
+ },
+ pre: {
+ '/api/': {
+ target: 'your pre url',
+ changeOrigin: true,
+ pathRewrite: {
+ '^': '',
+ },
+ },
+ },
+};
diff --git a/config/routes.js b/config/routes.js
new file mode 100644
index 0000000..39803fb
--- /dev/null
+++ b/config/routes.js
@@ -0,0 +1,53 @@
+export default [
+ {
+ path: '/user',
+ layout: false,
+ routes: [
+ {
+ name: 'login',
+ path: '/user/login',
+ component: './user/Login',
+ },
+ {
+ component: './404',
+ },
+ ],
+ },
+ {
+ path: '/welcome',
+ name: 'welcome',
+ icon: 'smile',
+ component: './Welcome',
+ },
+ {
+ path: '/admin',
+ name: 'admin',
+ icon: 'crown',
+ access: 'canAdmin',
+ component: './Admin',
+ routes: [
+ {
+ path: '/admin/sub-page',
+ name: 'sub-page',
+ icon: 'smile',
+ component: './Welcome',
+ },
+ {
+ component: './404',
+ },
+ ],
+ },
+ {
+ name: 'list.table-list',
+ icon: 'table',
+ path: '/list',
+ component: './TableList',
+ },
+ {
+ path: '/',
+ redirect: '/welcome',
+ },
+ {
+ component: './404',
+ },
+];
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..4729573
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ testURL: 'http://localhost:8000',
+ verbose: false,
+ extraSetupFiles: ['./tests/setupTests.js'],
+ globals: {
+ ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
+ localStorage: null,
+ },
+};
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..197bee5
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/mock/listTableList.js b/mock/listTableList.js
new file mode 100644
index 0000000..b02c454
--- /dev/null
+++ b/mock/listTableList.js
@@ -0,0 +1,177 @@
+import moment from 'moment';
+import { parse } from 'url'; // mock tableListDataSource
+
+const genList = (current, pageSize) => {
+ const tableListDataSource = [];
+
+ 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: moment().format('YYYY-MM-DD'),
+ createdAt: moment().format('YYYY-MM-DD'),
+ progress: Math.ceil(Math.random() * 100),
+ });
+ }
+
+ tableListDataSource.reverse();
+ return tableListDataSource;
+};
+
+let tableListDataSource = genList(1, 100);
+
+function getRule(req, res, u) {
+ 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;
+ let dataSource = [...tableListDataSource].slice((current - 1) * pageSize, current * pageSize);
+
+ if (params.sorter) {
+ const sorter = JSON.parse(params.sorter);
+ dataSource = dataSource.sort((prev, next) => {
+ let sortNumber = 0;
+ Object.keys(sorter).forEach((key) => {
+ if (sorter[key] === 'descend') {
+ if (prev[key] - next[key] > 0) {
+ sortNumber += -1;
+ } else {
+ sortNumber += 1;
+ }
+
+ return;
+ }
+
+ if (prev[key] - next[key] > 0) {
+ sortNumber += 1;
+ } else {
+ sortNumber += -1;
+ }
+ });
+ return sortNumber;
+ });
+ }
+
+ if (params.filter) {
+ const filter = JSON.parse(params.filter);
+
+ if (Object.keys(filter).length > 0) {
+ dataSource = dataSource.filter((item) => {
+ return Object.keys(filter).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, res, u, b) {
+ let realUrl = u;
+
+ if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
+ realUrl = req.url;
+ }
+
+ const body = (b && b.body) || req.body;
+ const { method, name, desc, key } = body;
+
+ switch (method) {
+ /* eslint no-case-declarations:0 */
+ case 'delete':
+ tableListDataSource = tableListDataSource.filter((item) => key.indexOf(item.key) === -1);
+ break;
+
+ case 'post':
+ (() => {
+ const i = Math.ceil(Math.random() * 10000);
+ const newRule = {
+ 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: moment().format('YYYY-MM-DD'),
+ createdAt: moment().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,
+};
diff --git a/mock/notices.js b/mock/notices.js
new file mode 100644
index 0000000..7efbf77
--- /dev/null
+++ b/mock/notices.js
@@ -0,0 +1,105 @@
+const getNotices = (req, res) => {
+ res.json({
+ data: [
+ {
+ id: '000000001',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
+ title: '你收到了 14 份新周报',
+ datetime: '2017-08-09',
+ type: 'notification',
+ },
+ {
+ id: '000000002',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
+ title: '你推荐的 曲妮妮 已通过第三轮面试',
+ datetime: '2017-08-08',
+ type: 'notification',
+ },
+ {
+ id: '000000003',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
+ title: '这种模板可以区分多种通知类型',
+ datetime: '2017-08-07',
+ read: true,
+ type: 'notification',
+ },
+ {
+ id: '000000004',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
+ title: '左侧图标用于区分不同的类型',
+ datetime: '2017-08-07',
+ type: 'notification',
+ },
+ {
+ id: '000000005',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
+ title: '内容不要超过两行字,超出时自动截断',
+ datetime: '2017-08-07',
+ type: 'notification',
+ },
+ {
+ id: '000000006',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
+ title: '曲丽丽 评论了你',
+ description: '描述信息描述信息描述信息',
+ datetime: '2017-08-07',
+ type: 'message',
+ clickClose: true,
+ },
+ {
+ id: '000000007',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
+ title: '朱偏右 回复了你',
+ description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
+ datetime: '2017-08-07',
+ type: 'message',
+ clickClose: true,
+ },
+ {
+ id: '000000008',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
+ 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,
+};
diff --git a/mock/route.js b/mock/route.js
new file mode 100644
index 0000000..a6deca8
--- /dev/null
+++ b/mock/route.js
@@ -0,0 +1,7 @@
+export default {
+ '/api/auth_routes': {
+ '/form/advanced-form': {
+ authority: ['admin', 'user'],
+ },
+ },
+};
diff --git a/mock/user.js b/mock/user.js
new file mode 100644
index 0000000..fa8c1b4
--- /dev/null
+++ b/mock/user.js
@@ -0,0 +1,210 @@
+const waitTime = (time = 100) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(true);
+ }, time);
+ });
+};
+
+async function getFakeCaptcha(req, res) {
+ 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, res) => {
+ 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, res) => {
+ 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, res) => {
+ access = '';
+ res.send({
+ data: {},
+ success: true,
+ });
+ },
+ 'POST /api/register': (req, res) => {
+ res.send({
+ status: 'ok',
+ currentAuthority: 'user',
+ success: true,
+ });
+ },
+ 'GET /api/500': (req, res) => {
+ res.status(500).send({
+ timestamp: 1513932555104,
+ status: 500,
+ error: 'error',
+ message: 'error',
+ path: '/base/category/list',
+ });
+ },
+ 'GET /api/404': (req, res) => {
+ res.status(404).send({
+ timestamp: 1513932643431,
+ status: 404,
+ error: 'Not Found',
+ message: 'No message available',
+ path: '/base/category/list/2121212',
+ });
+ },
+ 'GET /api/403': (req, res) => {
+ res.status(403).send({
+ timestamp: 1513932555104,
+ status: 403,
+ error: 'Forbidden',
+ message: 'Forbidden',
+ path: '/base/category/list',
+ });
+ },
+ 'GET /api/401': (req, res) => {
+ res.status(401).send({
+ timestamp: 1513932555104,
+ status: 401,
+ error: 'Unauthorized',
+ message: 'Unauthorized',
+ path: '/base/category/list',
+ });
+ },
+ 'GET /api/login/captcha': getFakeCaptcha,
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6b55e52
--- /dev/null
+++ b/package.json
@@ -0,0 +1,98 @@
+{
+ "name": "ant-design-pro",
+ "version": "5.2.0",
+ "private": true,
+ "description": "An out-of-box UI solution for enterprise applications",
+ "scripts": {
+ "analyze": "cross-env ANALYZE=1 umi build",
+ "build": "umi 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": "umi g tmp",
+ "lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier && npm run tsc",
+ "lint-staged": "lint-staged",
+ "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
+ "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style",
+ "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
+ "lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto",
+ "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
+ "openapi": "umi openapi",
+ "playwright": "playwright install && playwright test",
+ "prepare": "husky install",
+ "prettier": "prettier -c --write \"src/**/*\"",
+ "serve": "umi-serve",
+ "start": "cross-env UMI_ENV=dev umi dev",
+ "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
+ "start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev",
+ "start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev",
+ "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev",
+ "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev umi dev",
+ "test": "umi test",
+ "test:component": "umi test ./src/components",
+ "test:e2e": "node ./tests/run-tests.js",
+ "tsc": "tsc --noEmit"
+ },
+ "lint-staged": {
+ "**/*.less": "stylelint --syntax less",
+ "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
+ "**/*.{js,jsx,tsx,ts,less,md,json}": ["prettier --write"]
+ },
+ "browserslist": ["> 1%", "last 2 versions", "not ie <= 10"],
+ "dependencies": {
+ "@ant-design/icons": "^4.7.0",
+ "@ant-design/pro-card": "^1.19.0",
+ "@ant-design/pro-descriptions": "^1.10.0",
+ "@ant-design/pro-form": "^1.64.0",
+ "@ant-design/pro-layout": "^6.35.0",
+ "@ant-design/pro-table": "^2.71.0",
+ "@umijs/route-utils": "^2.0.0",
+ "antd": "^4.19.0",
+ "classnames": "^2.3.0",
+ "lodash": "^4.17.0",
+ "moment": "^2.29.0",
+ "omit.js": "^2.0.2",
+ "rc-menu": "^9.1.0",
+ "rc-util": "^5.16.0",
+ "react": "^17.0.0",
+ "react-dev-inspector": "^1.7.0",
+ "react-dom": "^17.0.0",
+ "react-helmet-async": "^1.2.0",
+ "umi": "^3.5.0"
+ },
+ "devDependencies": {
+ "@ant-design/pro-cli": "^2.1.0",
+ "@playwright/test": "^1.17.0",
+ "@types/express": "^4.17.0",
+ "@types/history": "^4.7.0",
+ "@types/jest": "^26.0.0",
+ "@types/lodash": "^4.14.0",
+ "@types/react": "^17.0.0",
+ "@types/react-dom": "^17.0.0",
+ "@types/react-helmet": "^6.1.0",
+ "@umijs/fabric": "^2.8.0",
+ "@umijs/openapi": "^1.3.0",
+ "@umijs/plugin-blocks": "^2.2.0",
+ "@umijs/plugin-esbuild": "^1.4.0",
+ "@umijs/plugin-openapi": "^1.3.0",
+ "@umijs/preset-ant-design-pro": "^1.3.0",
+ "@umijs/preset-dumi": "^1.1.0",
+ "@umijs/preset-react": "^2.1.0",
+ "cross-env": "^7.0.0",
+ "cross-port-killer": "^1.3.0",
+ "detect-installer": "^1.0.0",
+ "eslint": "^7.32.0",
+ "gh-pages": "^3.2.0",
+ "husky": "^7.0.4",
+ "jsdom-global": "^3.0.0",
+ "lint-staged": "^10.0.0",
+ "mockjs": "^1.1.0",
+ "prettier": "^2.5.0",
+ "stylelint": "^13.0.0",
+ "swagger-ui-react": "^3.52.0",
+ "typescript": "^4.5.0",
+ "umi-serve": "^1.9.10"
+ },
+ "engines": { "node": ">=12.0.0" }
+}
diff --git a/playwright.config.js b/playwright.config.js
new file mode 100644
index 0000000..9b554d0
--- /dev/null
+++ b/playwright.config.js
@@ -0,0 +1,20 @@
+// playwright.config.ts
+import { devices } from '@playwright/test';
+const config = {
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 2 : 0,
+ use: {
+ trace: 'on-first-retry',
+ },
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ {
+ name: 'firefox',
+ use: { ...devices['Desktop Firefox'] },
+ },
+ ],
+};
+export default config;
diff --git a/public/CNAME b/public/CNAME
new file mode 100644
index 0000000..30c2d4d
--- /dev/null
+++ b/public/CNAME
@@ -0,0 +1 @@
+preview.pro.ant.design
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e2e9325
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png
new file mode 100644
index 0000000..48d0e23
Binary files /dev/null and b/public/icons/icon-128x128.png differ
diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png
new file mode 100644
index 0000000..938e9b5
Binary files /dev/null and b/public/icons/icon-192x192.png differ
diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png
new file mode 100644
index 0000000..21fc108
Binary files /dev/null and b/public/icons/icon-512x512.png differ
diff --git a/public/logo.svg b/public/logo.svg
new file mode 100644
index 0000000..239bf69
--- /dev/null
+++ b/public/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/pro_icon.svg b/public/pro_icon.svg
new file mode 100644
index 0000000..e075b78
--- /dev/null
+++ b/public/pro_icon.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/src/access.js b/src/access.js
new file mode 100644
index 0000000..209b095
--- /dev/null
+++ b/src/access.js
@@ -0,0 +1,9 @@
+/**
+ * @see https://umijs.org/zh-CN/plugins/plugin-access
+ * */
+export default function access(initialState) {
+ const { currentUser } = initialState ?? {};
+ return {
+ canAdmin: currentUser && currentUser.access === 'admin',
+ };
+}
diff --git a/src/app.jsx b/src/app.jsx
new file mode 100644
index 0000000..2b722a4
--- /dev/null
+++ b/src/app.jsx
@@ -0,0 +1,98 @@
+import { SettingDrawer } from '@ant-design/pro-layout';
+import { PageLoading } from '@ant-design/pro-layout';
+import { history, Link } from 'umi';
+import RightContent from '@/components/RightContent';
+import Footer from '@/components/Footer';
+import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
+import { BookOutlined, LinkOutlined } from '@ant-design/icons';
+import defaultSettings from '../config/defaultSettings';
+const isDev = process.env.NODE_ENV === 'development';
+const loginPath = '/user/login';
+/** 获取用户信息比较慢的时候会展示一个 loading */
+
+export const initialStateConfig = {
+ loading: ,
+};
+/**
+ * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
+ * */
+
+export async function getInitialState() {
+ const fetchUserInfo = async () => {
+ try {
+ const msg = await queryCurrentUser();
+ return msg.data;
+ } catch (error) {
+ history.push(loginPath);
+ }
+
+ return undefined;
+ }; // 如果不是登录页面,执行
+
+ if (history.location.pathname !== loginPath) {
+ const currentUser = await fetchUserInfo();
+ return {
+ fetchUserInfo,
+ currentUser,
+ settings: defaultSettings,
+ };
+ }
+
+ return {
+ fetchUserInfo,
+ settings: defaultSettings,
+ };
+} // ProLayout 支持的api https://procomponents.ant.design/components/layout
+
+export const layout = ({ initialState, setInitialState }) => {
+ return {
+ rightContentRender: () => ,
+ disableContentMargin: false,
+ waterMarkProps: {
+ content: initialState?.currentUser?.name,
+ },
+ footerRender: () => ,
+ onPageChange: () => {
+ const { location } = history; // 如果没有登录,重定向到 login
+
+ if (!initialState?.currentUser && location.pathname !== loginPath) {
+ history.push(loginPath);
+ }
+ },
+ links: isDev
+ ? [
+
+
+ OpenAPI 文档
+ ,
+
+
+ 业务组件文档
+ ,
+ ]
+ : [],
+ menuHeaderRender: undefined,
+ // 自定义 403 页面
+ // unAccessible:
unAccessible
,
+ // 增加一个 loading 的状态
+ childrenRender: (children, props) => {
+ // if (initialState?.loading) return ;
+ return (
+ <>
+ {children}
+ {!props.location?.pathname?.includes('/login') && (
+ {
+ setInitialState((preInitialState) => ({ ...preInitialState, settings }));
+ }}
+ />
+ )}
+ >
+ );
+ },
+ ...initialState?.settings,
+ };
+};
diff --git a/src/components/Footer/index.jsx b/src/components/Footer/index.jsx
new file mode 100644
index 0000000..a91f0d3
--- /dev/null
+++ b/src/components/Footer/index.jsx
@@ -0,0 +1,39 @@
+import { useIntl } from 'umi';
+import { GithubOutlined } from '@ant-design/icons';
+import { DefaultFooter } from '@ant-design/pro-layout';
+
+const Footer = () => {
+ const intl = useIntl();
+ const defaultMessage = intl.formatMessage({
+ id: 'app.copyright.produced',
+ defaultMessage: '蚂蚁集团体验技术部出品',
+ });
+ const currentYear = new Date().getFullYear();
+ return (
+ ,
+ href: 'https://github.com/ant-design/ant-design-pro',
+ blankTarget: true,
+ },
+ {
+ key: 'Ant Design',
+ title: 'Ant Design',
+ href: 'https://ant.design',
+ blankTarget: true,
+ },
+ ]}
+ />
+ );
+};
+
+export default Footer;
diff --git a/src/components/HeaderDropdown/index.jsx b/src/components/HeaderDropdown/index.jsx
new file mode 100644
index 0000000..c857c0d
--- /dev/null
+++ b/src/components/HeaderDropdown/index.jsx
@@ -0,0 +1,10 @@
+import { Dropdown } from 'antd';
+import React from 'react';
+import classNames from 'classnames';
+import styles from './index.less';
+
+const HeaderDropdown = ({ overlayClassName: cls, ...restProps }) => (
+
+);
+
+export default HeaderDropdown;
diff --git a/src/components/HeaderDropdown/index.less b/src/components/HeaderDropdown/index.less
new file mode 100644
index 0000000..f583513
--- /dev/null
+++ b/src/components/HeaderDropdown/index.less
@@ -0,0 +1,16 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.container > * {
+ background-color: @popover-bg;
+ border-radius: 4px;
+ box-shadow: @shadow-1-down;
+}
+
+@media screen and (max-width: @screen-xs) {
+ .container {
+ width: 100% !important;
+ }
+ .container > * {
+ border-radius: 0 !important;
+ }
+}
diff --git a/src/components/HeaderSearch/index.jsx b/src/components/HeaderSearch/index.jsx
new file mode 100644
index 0000000..6f735c5
--- /dev/null
+++ b/src/components/HeaderSearch/index.jsx
@@ -0,0 +1,83 @@
+import { SearchOutlined } from '@ant-design/icons';
+import { AutoComplete, Input } from 'antd';
+import useMergedState from 'rc-util/es/hooks/useMergedState';
+import React, { useRef } from 'react';
+import classNames from 'classnames';
+import styles from './index.less';
+
+const HeaderSearch = (props) => {
+ const {
+ className,
+ defaultValue,
+ onVisibleChange,
+ placeholder,
+ visible,
+ defaultVisible,
+ ...restProps
+ } = props;
+ const inputRef = useRef(null);
+ const [value, setValue] = useMergedState(defaultValue, {
+ value: props.value,
+ onChange: props.onChange,
+ });
+ const [searchMode, setSearchMode] = useMergedState(defaultVisible ?? false, {
+ value: props.visible,
+ onChange: onVisibleChange,
+ });
+ const inputClass = classNames(styles.input, {
+ [styles.show]: searchMode,
+ });
+ return (
+ {
+ setSearchMode(true);
+
+ if (searchMode && inputRef.current) {
+ inputRef.current.focus();
+ }
+ }}
+ onTransitionEnd={({ propertyName }) => {
+ if (propertyName === 'width' && !searchMode) {
+ if (onVisibleChange) {
+ onVisibleChange(searchMode);
+ }
+ }
+ }}
+ >
+
+
setValue(completeValue)}
+ >
+ {
+ if (e.key === 'Enter') {
+ if (restProps.onSearch) {
+ restProps.onSearch(value);
+ }
+ }
+ }}
+ onBlur={() => {
+ setSearchMode(false);
+ }}
+ />
+
+
+ );
+};
+
+export default HeaderSearch;
diff --git a/src/components/HeaderSearch/index.less b/src/components/HeaderSearch/index.less
new file mode 100644
index 0000000..7dc3eaa
--- /dev/null
+++ b/src/components/HeaderSearch/index.less
@@ -0,0 +1,25 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.headerSearch {
+ display: inline-flex;
+ align-items: center;
+ .input {
+ width: 0;
+ min-width: 0;
+ overflow: hidden;
+ background: transparent;
+ border-radius: 0;
+ transition: width 0.3s, margin-left 0.3s;
+ :global(.ant-select-selection) {
+ background: transparent;
+ }
+ input {
+ box-shadow: none !important;
+ }
+
+ &.show {
+ width: 210px;
+ margin-left: 8px;
+ }
+ }
+}
diff --git a/src/components/NoticeIcon/NoticeIcon.jsx b/src/components/NoticeIcon/NoticeIcon.jsx
new file mode 100644
index 0000000..e20fad9
--- /dev/null
+++ b/src/components/NoticeIcon/NoticeIcon.jsx
@@ -0,0 +1,114 @@
+import { BellOutlined } from '@ant-design/icons';
+import { Badge, Spin, Tabs } from 'antd';
+import useMergedState from 'rc-util/es/hooks/useMergedState';
+import React from 'react';
+import classNames from 'classnames';
+import NoticeList from './NoticeList';
+import HeaderDropdown from '../HeaderDropdown';
+import styles from './index.less';
+const { TabPane } = Tabs;
+
+const NoticeIcon = (props) => {
+ const getNotificationBox = () => {
+ const {
+ children,
+ loading,
+ onClear,
+ onTabChange,
+ onItemClick,
+ onViewMore,
+ clearText,
+ viewMoreText,
+ } = props;
+
+ if (!children) {
+ return null;
+ }
+
+ const panes = [];
+ React.Children.forEach(children, (child) => {
+ if (!child) {
+ return;
+ }
+
+ const { list, title, count, tabKey, showClear, showViewMore } = child.props;
+ const len = list && list.length ? list.length : 0;
+ const msgCount = count || count === 0 ? count : len;
+ const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title;
+ panes.push(
+
+ onClear && onClear(title, tabKey)}
+ onClick={(item) => onItemClick && onItemClick(item, child.props)}
+ onViewMore={(event) => onViewMore && onViewMore(child.props, event)}
+ showClear={showClear}
+ showViewMore={showViewMore}
+ title={title}
+ />
+ ,
+ );
+ });
+ return (
+ <>
+
+
+ {panes}
+
+
+ >
+ );
+ };
+
+ const { className, count, bell } = props;
+ const [visible, setVisible] = useMergedState(false, {
+ value: props.popupVisible,
+ onChange: props.onPopupVisibleChange,
+ });
+ const noticeButtonClass = classNames(className, styles.noticeButton);
+ const notificationBox = getNotificationBox();
+ const NoticeBellIcon = bell || ;
+ const trigger = (
+
+
+ {NoticeBellIcon}
+
+
+ );
+
+ if (!notificationBox) {
+ return trigger;
+ }
+
+ return (
+
+ {trigger}
+
+ );
+};
+
+NoticeIcon.defaultProps = {
+ emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
+};
+NoticeIcon.Tab = NoticeList;
+export default NoticeIcon;
diff --git a/src/components/NoticeIcon/NoticeList.jsx b/src/components/NoticeIcon/NoticeList.jsx
new file mode 100644
index 0000000..cc645c5
--- /dev/null
+++ b/src/components/NoticeIcon/NoticeList.jsx
@@ -0,0 +1,97 @@
+import { Avatar, List } from 'antd';
+import React from 'react';
+import classNames from 'classnames';
+import styles from './NoticeList.less';
+
+const NoticeList = ({
+ list = [],
+ onClick,
+ onClear,
+ title,
+ onViewMore,
+ emptyText,
+ showClear = true,
+ clearText,
+ viewMoreText,
+ showViewMore = false,
+}) => {
+ if (!list || list.length === 0) {
+ return (
+
+

+
{emptyText}
+
+ );
+ }
+
+ return (
+
+
{
+ const itemCls = classNames(styles.item, {
+ [styles.read]: item.read,
+ }); // eslint-disable-next-line no-nested-ternary
+
+ const leftIcon = item.avatar ? (
+ typeof item.avatar === 'string' ? (
+
+ ) : (
+ {item.avatar}
+ )
+ ) : null;
+ return (
+ {
+ onClick?.(item);
+ }}
+ >
+
+ {item.title}
+ {item.extra}
+
+ }
+ description={
+
+
{item.description}
+
{item.datetime}
+
+ }
+ />
+
+ );
+ }}
+ />
+
+ {showClear ? (
+
+ {clearText} {title}
+
+ ) : null}
+ {showViewMore ? (
+
{
+ if (onViewMore) {
+ onViewMore(e);
+ }
+ }}
+ >
+ {viewMoreText}
+
+ ) : null}
+
+
+ );
+};
+
+export default NoticeList;
diff --git a/src/components/NoticeIcon/NoticeList.less b/src/components/NoticeIcon/NoticeList.less
new file mode 100644
index 0000000..c87fece
--- /dev/null
+++ b/src/components/NoticeIcon/NoticeList.less
@@ -0,0 +1,103 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.list {
+ max-height: 400px;
+ overflow: auto;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ .item {
+ padding-right: 24px;
+ padding-left: 24px;
+ overflow: hidden;
+ cursor: pointer;
+ transition: all 0.3s;
+
+ .meta {
+ width: 100%;
+ }
+
+ .avatar {
+ margin-top: 4px;
+ background: @component-background;
+ }
+ .iconElement {
+ font-size: 32px;
+ }
+
+ &.read {
+ opacity: 0.4;
+ }
+ &:last-child {
+ border-bottom: 0;
+ }
+ &:hover {
+ background: @primary-1;
+ }
+ .title {
+ margin-bottom: 8px;
+ font-weight: normal;
+ }
+ .description {
+ font-size: 12px;
+ line-height: @line-height-base;
+ }
+ .datetime {
+ margin-top: 4px;
+ font-size: 12px;
+ line-height: @line-height-base;
+ }
+ .extra {
+ float: right;
+ margin-top: -1.5px;
+ margin-right: 0;
+ color: @text-color-secondary;
+ font-weight: normal;
+ }
+ }
+ .loadMore {
+ padding: 8px 0;
+ color: @primary-6;
+ text-align: center;
+ cursor: pointer;
+ &.loadedAll {
+ color: rgba(0, 0, 0, 0.25);
+ cursor: unset;
+ }
+ }
+}
+
+.notFound {
+ padding: 73px 0 88px;
+ color: @text-color-secondary;
+ text-align: center;
+ img {
+ display: inline-block;
+ height: 76px;
+ margin-bottom: 16px;
+ }
+}
+
+.bottomBar {
+ height: 46px;
+ color: @text-color;
+ line-height: 46px;
+ text-align: center;
+ border-top: 1px solid @border-color-split;
+ border-radius: 0 0 @border-radius-base @border-radius-base;
+ transition: all 0.3s;
+ div {
+ display: inline-block;
+ width: 50%;
+ cursor: pointer;
+ transition: all 0.3s;
+ user-select: none;
+
+ &:only-child {
+ width: 100%;
+ }
+ &:not(:only-child):last-child {
+ border-left: 1px solid @border-color-split;
+ }
+ }
+}
diff --git a/src/components/NoticeIcon/index.jsx b/src/components/NoticeIcon/index.jsx
new file mode 100644
index 0000000..9491362
--- /dev/null
+++ b/src/components/NoticeIcon/index.jsx
@@ -0,0 +1,148 @@
+import { useEffect, useState } from 'react';
+import { Tag, message } from 'antd';
+import { groupBy } from 'lodash';
+import moment from 'moment';
+import { useModel, useRequest } from 'umi';
+import { getNotices } from '@/services/ant-design-pro/api';
+import NoticeIcon from './NoticeIcon';
+import styles from './index.less';
+
+const getNoticeData = (notices) => {
+ if (!notices || notices.length === 0 || !Array.isArray(notices)) {
+ return {};
+ }
+
+ const newNotices = notices.map((notice) => {
+ const newNotice = { ...notice };
+
+ if (newNotice.datetime) {
+ newNotice.datetime = moment(notice.datetime).fromNow();
+ }
+
+ if (newNotice.id) {
+ newNotice.key = newNotice.id;
+ }
+
+ if (newNotice.extra && newNotice.status) {
+ const color = {
+ todo: '',
+ processing: 'blue',
+ urgent: 'red',
+ doing: 'gold',
+ }[newNotice.status];
+ newNotice.extra = (
+
+ {newNotice.extra}
+
+ );
+ }
+
+ return newNotice;
+ });
+ return groupBy(newNotices, 'type');
+};
+
+const getUnreadData = (noticeData) => {
+ const unreadMsg = {};
+ Object.keys(noticeData).forEach((key) => {
+ const value = noticeData[key];
+
+ if (!unreadMsg[key]) {
+ unreadMsg[key] = 0;
+ }
+
+ if (Array.isArray(value)) {
+ unreadMsg[key] = value.filter((item) => !item.read).length;
+ }
+ });
+ return unreadMsg;
+};
+
+const NoticeIconView = () => {
+ const { initialState } = useModel('@@initialState');
+ const { currentUser } = initialState || {};
+ const [notices, setNotices] = useState([]);
+ const { data } = useRequest(getNotices);
+ useEffect(() => {
+ setNotices(data || []);
+ }, [data]);
+ const noticeData = getNoticeData(notices);
+ const unreadMsg = getUnreadData(noticeData || {});
+
+ const changeReadState = (id) => {
+ setNotices(
+ notices.map((item) => {
+ const notice = { ...item };
+
+ if (notice.id === id) {
+ notice.read = true;
+ }
+
+ return notice;
+ }),
+ );
+ };
+
+ const clearReadState = (title, key) => {
+ setNotices(
+ notices.map((item) => {
+ const notice = { ...item };
+
+ if (notice.type === key) {
+ notice.read = true;
+ }
+
+ return notice;
+ }),
+ );
+ message.success(`${'清空了'} ${title}`);
+ };
+
+ return (
+ {
+ changeReadState(item.id);
+ }}
+ onClear={(title, key) => clearReadState(title, key)}
+ loading={false}
+ clearText="清空"
+ viewMoreText="查看更多"
+ onViewMore={() => message.info('Click on view more')}
+ clearClose
+ >
+
+
+
+
+ );
+};
+
+export default NoticeIconView;
diff --git a/src/components/NoticeIcon/index.less b/src/components/NoticeIcon/index.less
new file mode 100644
index 0000000..a2e44f1
--- /dev/null
+++ b/src/components/NoticeIcon/index.less
@@ -0,0 +1,35 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.popover {
+ position: relative;
+ width: 336px;
+}
+
+.noticeButton {
+ display: inline-block;
+ cursor: pointer;
+ transition: all 0.3s;
+}
+.icon {
+ padding: 4px;
+ vertical-align: middle;
+}
+
+.badge {
+ font-size: 16px;
+}
+
+.tabs {
+ :global {
+ .ant-tabs-nav-list {
+ margin: auto;
+ }
+
+ .ant-tabs-nav-scroll {
+ text-align: center;
+ }
+ .ant-tabs-nav {
+ margin-bottom: 0;
+ }
+ }
+}
diff --git a/src/components/RightContent/AvatarDropdown.jsx b/src/components/RightContent/AvatarDropdown.jsx
new file mode 100644
index 0000000..61248e4
--- /dev/null
+++ b/src/components/RightContent/AvatarDropdown.jsx
@@ -0,0 +1,98 @@
+import React, { useCallback } from 'react';
+import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
+import { Avatar, Menu, Spin } from 'antd';
+import { history, useModel } from 'umi';
+import { stringify } from 'querystring';
+import HeaderDropdown from '../HeaderDropdown';
+import styles from './index.less';
+import { outLogin } from '@/services/ant-design-pro/api';
+
+/**
+ * 退出登录,并且将当前的 url 保存
+ */
+const loginOut = async () => {
+ await outLogin();
+ const { query = {}, search, pathname } = history.location;
+ const { redirect } = query; // 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 AvatarDropdown = ({ menu }) => {
+ const { initialState, setInitialState } = useModel('@@initialState');
+ const onMenuClick = useCallback(
+ (event) => {
+ const { key } = event;
+
+ if (key === 'logout') {
+ setInitialState((s) => ({ ...s, currentUser: undefined }));
+ loginOut();
+ return;
+ }
+
+ history.push(`/account/${key}`);
+ },
+ [setInitialState],
+ );
+ const loading = (
+
+
+
+ );
+
+ if (!initialState) {
+ return loading;
+ }
+
+ const { currentUser } = initialState;
+
+ if (!currentUser || !currentUser.name) {
+ return loading;
+ }
+
+ const menuHeaderDropdown = (
+
+ );
+ return (
+
+
+
+ {currentUser.name}
+
+
+ );
+};
+
+export default AvatarDropdown;
diff --git a/src/components/RightContent/index.jsx b/src/components/RightContent/index.jsx
new file mode 100644
index 0000000..4660693
--- /dev/null
+++ b/src/components/RightContent/index.jsx
@@ -0,0 +1,64 @@
+import { Space } from 'antd';
+import { QuestionCircleOutlined } from '@ant-design/icons';
+import React from 'react';
+import { useModel, SelectLang } from 'umi';
+import Avatar from './AvatarDropdown';
+import HeaderSearch from '../HeaderSearch';
+import styles from './index.less';
+
+const GlobalHeaderRight = () => {
+ const { initialState } = useModel('@@initialState');
+
+ if (!initialState || !initialState.settings) {
+ return null;
+ }
+
+ const { navTheme, layout } = initialState.settings;
+ let className = styles.right;
+
+ if ((navTheme === 'dark' && layout === 'top') || layout === 'mix') {
+ className = `${styles.right} ${styles.dark}`;
+ }
+
+ return (
+
+ umi ui,
+ value: 'umi ui',
+ },
+ {
+ label: Ant Design,
+ value: 'Ant Design',
+ },
+ {
+ label: Pro Table,
+ value: 'Pro Table',
+ },
+ {
+ label: Pro Layout,
+ value: 'Pro Layout',
+ },
+ ]} // onSearch={value => {
+ // console.log('input', value);
+ // }}
+ />
+ {
+ window.open('https://pro.ant.design/docs/getting-started');
+ }}
+ >
+
+
+
+
+
+ );
+};
+
+export default GlobalHeaderRight;
diff --git a/src/components/RightContent/index.less b/src/components/RightContent/index.less
new file mode 100644
index 0000000..6d6f198
--- /dev/null
+++ b/src/components/RightContent/index.less
@@ -0,0 +1,84 @@
+@import (reference) '~antd/es/style/themes/index';
+
+@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
+
+.menu {
+ :global(.anticon) {
+ margin-right: 8px;
+ }
+ :global(.ant-dropdown-menu-item) {
+ min-width: 160px;
+ }
+}
+
+.right {
+ display: flex;
+ float: right;
+ height: 48px;
+ margin-left: auto;
+ overflow: hidden;
+ .action {
+ display: flex;
+ align-items: center;
+ height: 48px;
+ padding: 0 12px;
+ cursor: pointer;
+ transition: all 0.3s;
+ > span {
+ vertical-align: middle;
+ }
+ &:hover {
+ background: @pro-header-hover-bg;
+ }
+ &:global(.opened) {
+ background: @pro-header-hover-bg;
+ }
+ }
+ .search {
+ padding: 0 12px;
+ &:hover {
+ background: transparent;
+ }
+ }
+ .account {
+ .avatar {
+ margin-right: 8px;
+ color: @primary-color;
+ vertical-align: top;
+ background: rgba(255, 255, 255, 0.85);
+ }
+ }
+}
+
+.dark {
+ .action {
+ &:hover {
+ background: #252a3d;
+ }
+ &:global(.opened) {
+ background: #252a3d;
+ }
+ }
+}
+
+@media only screen and (max-width: @screen-md) {
+ :global(.ant-divider-vertical) {
+ vertical-align: unset;
+ }
+ .name {
+ display: none;
+ }
+ .right {
+ position: absolute;
+ top: 0;
+ right: 12px;
+ .account {
+ .avatar {
+ margin-right: 0;
+ }
+ }
+ .search {
+ display: none;
+ }
+ }
+}
diff --git a/src/components/index.md b/src/components/index.md
new file mode 100644
index 0000000..408da93
--- /dev/null
+++ b/src/components/index.md
@@ -0,0 +1,272 @@
+---
+title: 业务组件
+sidemenu: false
+---
+
+> 此功能由[dumi](https://d.umijs.org/zh-CN/guide/advanced#umi-%E9%A1%B9%E7%9B%AE%E9%9B%86%E6%88%90%E6%A8%A1%E5%BC%8F)提供,dumi 是一个 📖 为组件开发场景而生的文档工具,用过的都说好。
+
+# 业务组件
+
+这里列举了 Pro 中所有用到的组件,这些组件不适合作为组件库,但是在业务中却真实需要。所以我们准备了这个文档,来指导大家是否需要使用这个组件。
+
+## Footer 页脚组件
+
+这个组件自带了一些 Pro 的配置,你一般都需要改掉它的信息。
+
+```tsx
+/**
+ * background: '#f0f2f5'
+ */
+import React from 'react';
+import Footer from '@/components/Footer';
+
+export default () => ;
+```
+
+## HeaderDropdown 头部下拉列表
+
+HeaderDropdown 是 antd Dropdown 的封装,但是增加了移动端的特殊处理,用法也是相同的。
+
+```tsx
+/**
+ * background: '#f0f2f5'
+ */
+import { Button, Menu } from 'antd';
+import React from 'react';
+import HeaderDropdown from '@/components/HeaderDropdown';
+
+export default () => {
+ const menuHeaderDropdown = (
+
+ );
+ return (
+
+
+
+ );
+};
+```
+
+## HeaderSearch 头部搜索框
+
+一个带补全数据的输入框,支持收起和展开 Input
+
+```tsx
+/**
+ * background: '#f0f2f5'
+ */
+import { Button, Menu } from 'antd';
+import React from 'react';
+import HeaderSearch from '@/components/HeaderSearch';
+
+export default () => {
+ return (
+ {
+ console.log('input', value);
+ }}
+ />
+ );
+};
+```
+
+### API
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --------------- | ---------------------------------- | ---------------------------- | ------ |
+| value | 输入框的值 | `string` | - |
+| onChange | 值修改后触发 | `(value?: string) => void` | - |
+| onSearch | 查询后触发 | `(value?: string) => void` | - |
+| options | 选项菜单的的列表 | `{label,value}[]` | - |
+| defaultVisible | 输入框默认是否显示,只有第一次生效 | `boolean` | - |
+| visible | 输入框是否显示 | `boolean` | - |
+| onVisibleChange | 输入框显示隐藏的回调函数 | `(visible: boolean) => void` | - |
+
+## NoticeIcon 通知工具
+
+通知工具提供一个展示多种通知信息的界面。
+
+```tsx
+/**
+ * background: '#f0f2f5'
+ */
+import { message } from 'antd';
+import React from 'react';
+import NoticeIcon from '@/components/NoticeIcon/NoticeIcon';
+
+export default () => {
+ const list = [
+ {
+ id: '000000001',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
+ title: '你收到了 14 份新周报',
+ datetime: '2017-08-09',
+ type: 'notification',
+ },
+ {
+ id: '000000002',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
+ title: '你推荐的 曲妮妮 已通过第三轮面试',
+ datetime: '2017-08-08',
+ type: 'notification',
+ },
+ ];
+ return (
+ {
+ message.info(`${item.title} 被点击了`);
+ }}
+ onClear={(title: string, key: string) => message.info('点击了清空更多')}
+ loading={false}
+ clearText="清空"
+ viewMoreText="查看更多"
+ onViewMore={() => message.info('点击了查看更多')}
+ clearClose
+ >
+
+
+
+
+ );
+};
+```
+
+### NoticeIcon API
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| count | 有多少未读通知 | `number` | - |
+| bell | 铃铛的图表 | `ReactNode` | - |
+| onClear | 点击清空数据按钮 | `(tabName: string, tabKey: string) => void` | - |
+| onItemClick | 未读消息列被点击 | `(item: API.NoticeIconData, tabProps: NoticeIconTabProps) => void` | - |
+| onViewMore | 查看更多的按钮点击 | `(tabProps: NoticeIconTabProps, e: MouseEvent) => void` | - |
+| onTabChange | 通知 Tab 的切换 | `(tabTile: string) => void;` | - |
+| popupVisible | 通知显示是否展示 | `boolean` | - |
+| onPopupVisibleChange | 通知信息显示隐藏的回调函数 | `(visible: boolean) => void` | - |
+| clearText | 清空按钮的文字 | `string` | - |
+| viewMoreText | 查看更多的按钮文字 | `string` | - |
+| clearClose | 展示清空按钮 | `boolean` | - |
+| emptyImage | 列表为空时的兜底展示 | `ReactNode` | - |
+
+### NoticeIcon.Tab API
+
+| 参数 | 说明 | 类型 | 默认值 |
+| ------------ | ------------------ | ------------------------------------ | ------ |
+| count | 有多少未读通知 | `number` | - |
+| title | 通知 Tab 的标题 | `ReactNode` | - |
+| showClear | 展示清除按钮 | `boolean` | `true` |
+| showViewMore | 展示加载更 | `boolean` | `true` |
+| tabKey | Tab 的唯一 key | `string` | - |
+| onClick | 子项的单击事件 | `(item: API.NoticeIconData) => void` | - |
+| onClear | 清楚按钮的点击 | `()=>void` | - |
+| emptyText | 为空的时候测试 | `()=>void` | - |
+| viewMoreText | 查看更多的按钮文字 | `string` | - |
+| onViewMore | 查看更多的按钮点击 | `( e: MouseEvent) => void` | - |
+| list | 通知信息的列表 | `API.NoticeIconData` | - |
+
+### NoticeIconData
+
+```tsx | pure
+export interface NoticeIconData {
+ id: string;
+ key: string;
+ avatar: string;
+ title: string;
+ datetime: string;
+ type: string;
+ read?: boolean;
+ description: string;
+ clickClose?: boolean;
+ extra: any;
+ status: string;
+}
+```
+
+## RightContent
+
+RightContent 是以上几个组件的组合,同时新增了 plugins 的 `SelectLang` 插件。
+
+```tsx | pure
+
+ umi ui, value: 'umi ui' },
+ {
+ label: Ant Design,
+ value: 'Ant Design',
+ },
+ {
+ label: Pro Table,
+ value: 'Pro Table',
+ },
+ {
+ label: Pro Layout,
+ value: 'Pro Layout',
+ },
+ ]}
+ />
+
+ {
+ window.location.href = 'https://pro.ant.design/docs/getting-started';
+ }}
+ >
+
+
+
+
+ {REACT_APP_ENV && (
+
+ {REACT_APP_ENV}
+
+ )}
+
+
+```
diff --git a/src/e2e/baseLayout.e2e.spec.js b/src/e2e/baseLayout.e2e.spec.js
new file mode 100644
index 0000000..78f8060
--- /dev/null
+++ b/src/e2e/baseLayout.e2e.spec.js
@@ -0,0 +1,47 @@
+import { test, expect } from '@playwright/test';
+
+const { uniq } = require('lodash');
+
+const RouterConfig = require('../../config/routes').default;
+
+const BASE_URL = `http://localhost:${process.env.PORT || 8001}`;
+
+function formatter(routes, parentPath = '') {
+ const fixedParentPath = parentPath.replace(/\/{1,}/g, '/');
+ let result = [];
+ routes.forEach((item) => {
+ if (item.path && !item.path.startsWith('/')) {
+ result.push(`${fixedParentPath}/${item.path}`.replace(/\/{1,}/g, '/'));
+ }
+
+ if (item.path && item.path.startsWith('/')) {
+ result.push(`${item.path}`.replace(/\/{1,}/g, '/'));
+ }
+
+ if (item.routes) {
+ result = result.concat(
+ formatter(item.routes, item.path ? `${fixedParentPath}/${item.path}` : parentPath),
+ );
+ }
+ });
+ return uniq(result.filter((item) => !!item));
+}
+
+const testPage = (path, page) => async () => {
+ await page.evaluate(() => {
+ localStorage.setItem('antd-pro-authority', '["admin"]');
+ });
+ await page.goto(`${BASE_URL}${path}`);
+ await page.waitForSelector('footer', {
+ timeout: 2000,
+ });
+ const haveFooter = await page.evaluate(() => document.getElementsByTagName('footer').length > 0);
+ expect(haveFooter).toBeTruthy();
+};
+
+const routers = formatter(RouterConfig);
+routers.forEach((route) => {
+ test(`test route page ${route}`, async ({ page }) => {
+ await testPage(route, page);
+ });
+});
diff --git a/src/global.jsx b/src/global.jsx
new file mode 100644
index 0000000..d980905
--- /dev/null
+++ b/src/global.jsx
@@ -0,0 +1,108 @@
+import { Button, message, notification } from 'antd';
+import { useIntl } from 'umi';
+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) => {
+ const e = event;
+
+ 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 && 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 = (
+
+ );
+ 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();
+}
diff --git a/src/global.less b/src/global.less
new file mode 100644
index 0000000..0d6158c
--- /dev/null
+++ b/src/global.less
@@ -0,0 +1,57 @@
+@import '~antd/es/style/variable.less';
+
+html,
+body,
+#root {
+ height: 100%;
+}
+
+.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: @screen-xs) {
+ .ant-table {
+ width: 100%;
+ overflow-x: auto;
+ &-thead > tr,
+ &-tbody > tr {
+ > th,
+ > td {
+ white-space: pre;
+ > span {
+ display: block;
+ }
+ }
+ }
+ }
+}
+
+// Compatible with IE11
+@media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) {
+ body .ant-design-pro > .ant-layout {
+ min-height: 100vh;
+ }
+}
diff --git a/src/locales/bn-BD.js b/src/locales/bn-BD.js
new file mode 100644
index 0000000..39c02f8
--- /dev/null
+++ b/src/locales/bn-BD.js
@@ -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.copyright.produced': 'প্রযোজনা করেছেন অ্যান্ট ফিনান্সিয়াল এক্সপেরিয়েন্স ডিপার্টমেন্ট',
+ 'app.preview.down.block': 'আপনার স্থানীয় প্রকল্পে এই পৃষ্ঠাটি ডাউনলোড করুন',
+ 'app.welcome.link.fetch-blocks': 'সমস্ত ব্লক পান',
+ 'app.welcome.link.block-list':
+ '`block` ডেভেলপমেন্ট এর উপর ভিত্তি করে দ্রুত স্ট্যান্ডার্ড, পৃষ্ঠাসমূহ তৈরি করুন।',
+ ...globalHeader,
+ ...menu,
+ ...settingDrawer,
+ ...settings,
+ ...pwa,
+ ...component,
+ ...pages,
+};
diff --git a/src/locales/bn-BD/component.js b/src/locales/bn-BD/component.js
new file mode 100644
index 0000000..a546e75
--- /dev/null
+++ b/src/locales/bn-BD/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'বিস্তৃত',
+ 'component.tagSelect.collapse': 'সঙ্কুচিত',
+ 'component.tagSelect.all': 'সব',
+};
diff --git a/src/locales/bn-BD/globalHeader.js b/src/locales/bn-BD/globalHeader.js
new file mode 100644
index 0000000..2679be4
--- /dev/null
+++ b/src/locales/bn-BD/globalHeader.js
@@ -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': 'আরো দেখুন',
+};
diff --git a/src/locales/bn-BD/menu.js b/src/locales/bn-BD/menu.js
new file mode 100644
index 0000000..ae511a0
--- /dev/null
+++ b/src/locales/bn-BD/menu.js
@@ -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': 'কোনি সম্পাদক',
+};
diff --git a/src/locales/bn-BD/pages.js b/src/locales/bn-BD/pages.js
new file mode 100644
index 0000000..726bd20
--- /dev/null
+++ b/src/locales/bn-BD/pages.js
@@ -0,0 +1,70 @@
+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.advancedComponent': 'অ্যাডভান্সড কম্পোনেন্ট',
+ 'pages.welcome.link': 'স্বাগতম',
+ 'pages.welcome.advancedLayout': 'অ্যাডভান্সড লেআউট',
+ 'pages.welcome.alertMessage': 'দ্রুত এবং শক্তিশালী ভারী শুল্ক উপাদান প্রকাশ করা হয়েছে।',
+ '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': 'একসাখে অনুমোদন',
+};
diff --git a/src/locales/bn-BD/pwa.js b/src/locales/bn-BD/pwa.js
new file mode 100644
index 0000000..233fb30
--- /dev/null
+++ b/src/locales/bn-BD/pwa.js
@@ -0,0 +1,7 @@
+export default {
+ 'app.pwa.offline': 'আপনি এখন অফলাইন',
+ 'app.pwa.serviceworker.updated': 'নতুন সামগ্রী উপলব্ধ',
+ 'app.pwa.serviceworker.updated.hint':
+ 'বর্তমান পৃষ্ঠাটি পুনরায় লোড করতে দয়া করে "রিফ্রেশ" বোতাম টিপুন',
+ 'app.pwa.serviceworker.updated.ok': 'রিফ্রেশ',
+};
diff --git a/src/locales/bn-BD/settingDrawer.js b/src/locales/bn-BD/settingDrawer.js
new file mode 100644
index 0000000..2bd1d04
--- /dev/null
+++ b/src/locales/bn-BD/settingDrawer.js
@@ -0,0 +1,31 @@
+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':
+ 'কেবল বিকাশের পরিবেশে প্যানেল শো সেট করা হচ্ছে, দয়া করে ম্যানুয়ালি সংশোধন করুন',
+};
diff --git a/src/locales/bn-BD/settings.js b/src/locales/bn-BD/settings.js
new file mode 100644
index 0000000..93cf904
--- /dev/null
+++ b/src/locales/bn-BD/settings.js
@@ -0,0 +1,59 @@
+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': 'বন্ধ',
+};
diff --git a/src/locales/en-US.js b/src/locales/en-US.js
new file mode 100644
index 0000000..5e39ad3
--- /dev/null
+++ b/src/locales/en-US.js
@@ -0,0 +1,24 @@
+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.copyright.produced': 'Produced by Ant Financial Experience Department',
+ '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,
+};
diff --git a/src/locales/en-US/component.js b/src/locales/en-US/component.js
new file mode 100644
index 0000000..3ba7eed
--- /dev/null
+++ b/src/locales/en-US/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'Expand',
+ 'component.tagSelect.collapse': 'Collapse',
+ 'component.tagSelect.all': 'All',
+};
diff --git a/src/locales/en-US/globalHeader.js b/src/locales/en-US/globalHeader.js
new file mode 100644
index 0000000..60b6d4e
--- /dev/null
+++ b/src/locales/en-US/globalHeader.js
@@ -0,0 +1,17 @@
+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',
+};
diff --git a/src/locales/en-US/menu.js b/src/locales/en-US/menu.js
new file mode 100644
index 0000000..eae3e53
--- /dev/null
+++ b/src/locales/en-US/menu.js
@@ -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',
+};
diff --git a/src/locales/en-US/pages.js b/src/locales/en-US/pages.js
new file mode 100644
index 0000000..3d61742
--- /dev/null
+++ b/src/locales/en-US/pages.js
@@ -0,0 +1,70 @@
+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.advancedComponent': 'Advanced Component',
+ 'pages.welcome.link': 'Welcome',
+ 'pages.welcome.advancedLayout': 'Advanced Layout',
+ 'pages.welcome.alertMessage': 'Faster and stronger heavy-duty components have been released.',
+ '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': 'bacth deletion',
+ 'pages.searchTable.batchApproval': 'batch approval',
+};
diff --git a/src/locales/en-US/pwa.js b/src/locales/en-US/pwa.js
new file mode 100644
index 0000000..ed8d199
--- /dev/null
+++ b/src/locales/en-US/pwa.js
@@ -0,0 +1,6 @@
+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',
+};
diff --git a/src/locales/en-US/settingDrawer.js b/src/locales/en-US/settingDrawer.js
new file mode 100644
index 0000000..a644905
--- /dev/null
+++ b/src/locales/en-US/settingDrawer.js
@@ -0,0 +1,31 @@
+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': 'Weak 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',
+};
diff --git a/src/locales/en-US/settings.js b/src/locales/en-US/settings.js
new file mode 100644
index 0000000..822dd00
--- /dev/null
+++ b/src/locales/en-US/settings.js
@@ -0,0 +1,60 @@
+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',
+};
diff --git a/src/locales/fa-IR.js b/src/locales/fa-IR.js
new file mode 100644
index 0000000..840a2f1
--- /dev/null
+++ b/src/locales/fa-IR.js
@@ -0,0 +1,23 @@
+import component from './fa-IR/component';
+import globalHeader from './fa-IR/globalHeader';
+import menu from './fa-IR/menu';
+import pwa from './fa-IR/pwa';
+import settingDrawer from './fa-IR/settingDrawer';
+import settings from './fa-IR/settings';
+import pages from './fa-IR/pages';
+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,
+};
diff --git a/src/locales/fa-IR/component.js b/src/locales/fa-IR/component.js
new file mode 100644
index 0000000..91e7a05
--- /dev/null
+++ b/src/locales/fa-IR/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'باز',
+ 'component.tagSelect.collapse': 'بسته ',
+ 'component.tagSelect.all': 'همه',
+};
diff --git a/src/locales/fa-IR/globalHeader.js b/src/locales/fa-IR/globalHeader.js
new file mode 100644
index 0000000..1a92fbb
--- /dev/null
+++ b/src/locales/fa-IR/globalHeader.js
@@ -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': 'نمایش بیشتر',
+};
diff --git a/src/locales/fa-IR/menu.js b/src/locales/fa-IR/menu.js
new file mode 100644
index 0000000..c67e003
--- /dev/null
+++ b/src/locales/fa-IR/menu.js
@@ -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',
+};
diff --git a/src/locales/fa-IR/pages.js b/src/locales/fa-IR/pages.js
new file mode 100644
index 0000000..d2782d3
--- /dev/null
+++ b/src/locales/fa-IR/pages.js
@@ -0,0 +1,67 @@
+export default {
+ 'pages.layouts.userLayout.title': 'طراحی مورچه تأثیرگذارترین مشخصات طراحی وب در منطقه Xihu است',
+ 'pages.login.accountLogin.tab': 'ورود به حساب کاربری',
+ 'pages.login.accountLogin.errorMessage': 'نام کاربری / رمزعبور نادرست (مدیر / ant.design)',
+ '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.advancedComponent': 'مولفه پیشرفته',
+ 'pages.welcome.link': 'خوش آمدید',
+ 'pages.welcome.advancedLayout': 'چیدمان پیشرفته',
+ 'pages.welcome.alertMessage': 'اجزای سنگین تر سریعتر و قوی تر آزاد شده اند.',
+ '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': 'تصویب دسته ای',
+};
diff --git a/src/locales/fa-IR/pwa.js b/src/locales/fa-IR/pwa.js
new file mode 100644
index 0000000..54831b4
--- /dev/null
+++ b/src/locales/fa-IR/pwa.js
@@ -0,0 +1,7 @@
+export default {
+ 'app.pwa.offline': 'شما اکنون آفلاین هستید',
+ 'app.pwa.serviceworker.updated': 'مطالب جدید در دسترس است',
+ 'app.pwa.serviceworker.updated.hint':
+ 'لطفاً برای بارگیری مجدد صفحه فعلی ، دکمه "تازه سازی" را فشار دهید',
+ 'app.pwa.serviceworker.updated.ok': 'تازه سازی',
+};
diff --git a/src/locales/fa-IR/settingDrawer.js b/src/locales/fa-IR/settingDrawer.js
new file mode 100644
index 0000000..cb223d5
--- /dev/null
+++ b/src/locales/fa-IR/settingDrawer.js
@@ -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':
+ 'صفحه تنظیم فقط در محیط توسعه نمایش داده می شود ، لطفاً دستی تغییر دهید',
+};
diff --git a/src/locales/fa-IR/settings.js b/src/locales/fa-IR/settings.js
new file mode 100644
index 0000000..040bc31
--- /dev/null
+++ b/src/locales/fa-IR/settings.js
@@ -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':
+ 'دستگاه 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': 'بستن',
+};
diff --git a/src/locales/id-ID.js b/src/locales/id-ID.js
new file mode 100644
index 0000000..af6ee8e
--- /dev/null
+++ b/src/locales/id-ID.js
@@ -0,0 +1,24 @@
+import component from './id-ID/component';
+import globalHeader from './id-ID/globalHeader';
+import menu from './id-ID/menu';
+import pwa from './id-ID/pwa';
+import settingDrawer from './id-ID/settingDrawer';
+import settings from './id-ID/settings';
+import pages from './id-ID/pages';
+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,
+};
diff --git a/src/locales/id-ID/component.js b/src/locales/id-ID/component.js
new file mode 100644
index 0000000..fe583af
--- /dev/null
+++ b/src/locales/id-ID/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'Perluas',
+ 'component.tagSelect.collapse': 'Lipat',
+ 'component.tagSelect.all': 'Semua',
+};
diff --git a/src/locales/id-ID/globalHeader.js b/src/locales/id-ID/globalHeader.js
new file mode 100644
index 0000000..e6283ea
--- /dev/null
+++ b/src/locales/id-ID/globalHeader.js
@@ -0,0 +1,17 @@
+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',
+};
diff --git a/src/locales/id-ID/menu.js b/src/locales/id-ID/menu.js
new file mode 100644
index 0000000..254ff44
--- /dev/null
+++ b/src/locales/id-ID/menu.js
@@ -0,0 +1,52 @@
+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',
+};
diff --git a/src/locales/id-ID/pages.js b/src/locales/id-ID/pages.js
new file mode 100644
index 0000000..ebae874
--- /dev/null
+++ b/src/locales/id-ID/pages.js
@@ -0,0 +1,70 @@
+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.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.advancedComponent': 'Formulir Lanjutan',
+ 'pages.welcome.link': 'Selamat datang',
+ 'pages.welcome.advancedLayout': 'Tata letak Lanjutan',
+ 'pages.welcome.alertMessage':
+ 'Komponen heavy-duty yang lebih cepat dan lebih kuat telah dirilis.',
+ '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',
+};
diff --git a/src/locales/id-ID/pwa.js b/src/locales/id-ID/pwa.js
new file mode 100644
index 0000000..b2cb8a1
--- /dev/null
+++ b/src/locales/id-ID/pwa.js
@@ -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',
+};
diff --git a/src/locales/id-ID/settingDrawer.js b/src/locales/id-ID/settingDrawer.js
new file mode 100644
index 0000000..f2d3e40
--- /dev/null
+++ b/src/locales/id-ID/settingDrawer.js
@@ -0,0 +1,32 @@
+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',
+};
diff --git a/src/locales/id-ID/settings.js b/src/locales/id-ID/settings.js
new file mode 100644
index 0000000..04b7d12
--- /dev/null
+++ b/src/locales/id-ID/settings.js
@@ -0,0 +1,60 @@
+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',
+};
diff --git a/src/locales/ja-JP.js b/src/locales/ja-JP.js
new file mode 100644
index 0000000..d8742c9
--- /dev/null
+++ b/src/locales/ja-JP.js
@@ -0,0 +1,23 @@
+import globalHeader from './ja-JP/globalHeader';
+import menu from './ja-JP/menu';
+import settingDrawer from './ja-JP/settingDrawer';
+import settings from './ja-JP/settings';
+import pwa from './ja-JP/pwa';
+import component from './ja-JP/component';
+import pages from './ja-JP/pages';
+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,
+};
diff --git a/src/locales/ja-JP/component.js b/src/locales/ja-JP/component.js
new file mode 100644
index 0000000..40f238c
--- /dev/null
+++ b/src/locales/ja-JP/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': '展開',
+ 'component.tagSelect.collapse': '折りたたむ',
+ 'component.tagSelect.all': 'すべて',
+};
diff --git a/src/locales/ja-JP/globalHeader.js b/src/locales/ja-JP/globalHeader.js
new file mode 100644
index 0000000..1642938
--- /dev/null
+++ b/src/locales/ja-JP/globalHeader.js
@@ -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': 'もっと見る',
+};
diff --git a/src/locales/ja-JP/menu.js b/src/locales/ja-JP/menu.js
new file mode 100644
index 0000000..af6ed0e
--- /dev/null
+++ b/src/locales/ja-JP/menu.js
@@ -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': 'コニエディター',
+};
diff --git a/src/locales/ja-JP/pages.js b/src/locales/ja-JP/pages.js
new file mode 100644
index 0000000..f438dbe
--- /dev/null
+++ b/src/locales/ja-JP/pages.js
@@ -0,0 +1,67 @@
+export default {
+ 'pages.layouts.userLayout.title': 'Ant Designは、西湖区で最も影響力のあるWebデザイン仕様です。',
+ 'pages.login.accountLogin.tab': 'アカウントログイン',
+ 'pages.login.accountLogin.errorMessage':
+ 'ユーザー名/パスワードが正しくありません(admin/ant.design)',
+ '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.advancedComponent': '高度なコンポーネント',
+ 'pages.welcome.link': 'ようこそ',
+ 'pages.welcome.advancedLayout': '高度なレイアウト',
+ 'pages.welcome.alertMessage': 'より高速で強力な頑丈なコンポーネントがリリースされました。',
+ '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': 'バッチ承認',
+};
diff --git a/src/locales/ja-JP/pwa.js b/src/locales/ja-JP/pwa.js
new file mode 100644
index 0000000..ace23ae
--- /dev/null
+++ b/src/locales/ja-JP/pwa.js
@@ -0,0 +1,7 @@
+export default {
+ 'app.pwa.offline': 'あなたは今オフラインです',
+ 'app.pwa.serviceworker.updated': '新しいコンテンツが利用可能です',
+ 'app.pwa.serviceworker.updated.hint':
+ '現在のページをリロードするには、「更新」ボタンを押してください',
+ 'app.pwa.serviceworker.updated.ok': 'リフレッシュ',
+};
diff --git a/src/locales/ja-JP/settingDrawer.js b/src/locales/ja-JP/settingDrawer.js
new file mode 100644
index 0000000..67a22df
--- /dev/null
+++ b/src/locales/ja-JP/settingDrawer.js
@@ -0,0 +1,31 @@
+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': '設定パネルは開発環境でのみ表示されます。手動で変更してください',
+};
diff --git a/src/locales/ja-JP/settings.js b/src/locales/ja-JP/settings.js
new file mode 100644
index 0000000..de52481
--- /dev/null
+++ b/src/locales/ja-JP/settings.js
@@ -0,0 +1,59 @@
+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': '閉じる',
+};
diff --git a/src/locales/pt-BR.js b/src/locales/pt-BR.js
new file mode 100644
index 0000000..8fbe172
--- /dev/null
+++ b/src/locales/pt-BR.js
@@ -0,0 +1,21 @@
+import component from './pt-BR/component';
+import globalHeader from './pt-BR/globalHeader';
+import menu from './pt-BR/menu';
+import pwa from './pt-BR/pwa';
+import settingDrawer from './pt-BR/settingDrawer';
+import settings from './pt-BR/settings';
+import pages from './pt-BR/pages';
+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,
+};
diff --git a/src/locales/pt-BR/component.js b/src/locales/pt-BR/component.js
new file mode 100644
index 0000000..7cf9999
--- /dev/null
+++ b/src/locales/pt-BR/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'Expandir',
+ 'component.tagSelect.collapse': 'Diminuir',
+ 'component.tagSelect.all': 'Todas',
+};
diff --git a/src/locales/pt-BR/globalHeader.js b/src/locales/pt-BR/globalHeader.js
new file mode 100644
index 0000000..c927399
--- /dev/null
+++ b/src/locales/pt-BR/globalHeader.js
@@ -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.loaded': 'Carregado',
+ 'component.noticeIcon.view-more': 'Veja mais',
+};
diff --git a/src/locales/pt-BR/menu.js b/src/locales/pt-BR/menu.js
new file mode 100644
index 0000000..99d4d72
--- /dev/null
+++ b/src/locales/pt-BR/menu.js
@@ -0,0 +1,52 @@
+export default {
+ 'menu.welcome': 'Welcome',
+ 'menu.more-blocks': 'More Blocks',
+ 'menu.home': 'Início',
+ 'menu.login': 'Login',
+ 'menu.admin': 'Admin',
+ 'menu.admin.sub-page': 'Sub-Page',
+ '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',
+};
diff --git a/src/locales/pt-BR/pages.js b/src/locales/pt-BR/pages.js
new file mode 100644
index 0000000..14f8a8d
--- /dev/null
+++ b/src/locales/pt-BR/pages.js
@@ -0,0 +1,70 @@
+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.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.advancedComponent': 'Componente Avançado',
+ 'pages.welcome.link': 'Bem-vindo',
+ 'pages.welcome.advancedLayout': 'Layout Avançado',
+ 'pages.welcome.alertMessage': 'Componentes pesados mais rápidos e mais fortes foram lançados.',
+ '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',
+};
diff --git a/src/locales/pt-BR/pwa.js b/src/locales/pt-BR/pwa.js
new file mode 100644
index 0000000..05cc797
--- /dev/null
+++ b/src/locales/pt-BR/pwa.js
@@ -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',
+};
diff --git a/src/locales/pt-BR/settingDrawer.js b/src/locales/pt-BR/settingDrawer.js
new file mode 100644
index 0000000..8a10b57
--- /dev/null
+++ b/src/locales/pt-BR/settingDrawer.js
@@ -0,0 +1,32 @@
+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',
+};
diff --git a/src/locales/pt-BR/settings.js b/src/locales/pt-BR/settings.js
new file mode 100644
index 0000000..aad2e38
--- /dev/null
+++ b/src/locales/pt-BR/settings.js
@@ -0,0 +1,60 @@
+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',
+};
diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js
new file mode 100644
index 0000000..47fc9e7
--- /dev/null
+++ b/src/locales/zh-CN.js
@@ -0,0 +1,24 @@
+import component from './zh-CN/component';
+import globalHeader from './zh-CN/globalHeader';
+import menu from './zh-CN/menu';
+import pwa from './zh-CN/pwa';
+import settingDrawer from './zh-CN/settingDrawer';
+import settings from './zh-CN/settings';
+import pages from './zh-CN/pages';
+export default {
+ 'navBar.lang': '语言',
+ 'layout.user.link.help': '帮助',
+ 'layout.user.link.privacy': '隐私',
+ 'layout.user.link.terms': '条款',
+ 'app.copyright.produced': '蚂蚁集团体验技术部出品',
+ 'app.preview.down.block': '下载此页面到本地项目',
+ 'app.welcome.link.fetch-blocks': '获取全部区块',
+ 'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
+ ...pages,
+ ...globalHeader,
+ ...menu,
+ ...settingDrawer,
+ ...settings,
+ ...pwa,
+ ...component,
+};
diff --git a/src/locales/zh-CN/component.js b/src/locales/zh-CN/component.js
new file mode 100644
index 0000000..1f1fead
--- /dev/null
+++ b/src/locales/zh-CN/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': '展开',
+ 'component.tagSelect.collapse': '收起',
+ 'component.tagSelect.all': '全部',
+};
diff --git a/src/locales/zh-CN/globalHeader.js b/src/locales/zh-CN/globalHeader.js
new file mode 100644
index 0000000..9fd66a5
--- /dev/null
+++ b/src/locales/zh-CN/globalHeader.js
@@ -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': '查看更多',
+};
diff --git a/src/locales/zh-CN/menu.js b/src/locales/zh-CN/menu.js
new file mode 100644
index 0000000..fecb70a
--- /dev/null
+++ b/src/locales/zh-CN/menu.js
@@ -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': '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': '拓扑编辑器',
+};
diff --git a/src/locales/zh-CN/pages.js b/src/locales/zh-CN/pages.js
new file mode 100644
index 0000000..adb36f4
--- /dev/null
+++ b/src/locales/zh-CN/pages.js
@@ -0,0 +1,67 @@
+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 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.advancedComponent': '高级表格',
+ 'pages.welcome.link': '欢迎使用',
+ 'pages.welcome.advancedLayout': '高级布局',
+ 'pages.welcome.alertMessage': '更快更强的重型组件,已经发布。',
+ 'pages.admin.subPage.title': ' 这个页面只有 admin 权限才能查看',
+ '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': '万',
+ 'pages.searchTable.batchDeletion': '批量删除',
+ 'pages.searchTable.batchApproval': '批量审批',
+};
diff --git a/src/locales/zh-CN/pwa.js b/src/locales/zh-CN/pwa.js
new file mode 100644
index 0000000..e950484
--- /dev/null
+++ b/src/locales/zh-CN/pwa.js
@@ -0,0 +1,6 @@
+export default {
+ 'app.pwa.offline': '当前处于离线状态',
+ 'app.pwa.serviceworker.updated': '有新内容',
+ 'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
+ 'app.pwa.serviceworker.updated.ok': '刷新',
+};
diff --git a/src/locales/zh-CN/settingDrawer.js b/src/locales/zh-CN/settingDrawer.js
new file mode 100644
index 0000000..3f44958
--- /dev/null
+++ b/src/locales/zh-CN/settingDrawer.js
@@ -0,0 +1,31 @@
+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': '固定 Header',
+ 'app.setting.fixedsidebar': '固定侧边菜单',
+ 'app.setting.fixedsidebar.hint': '侧边菜单布局时可配置',
+ 'app.setting.hideheader': '下滑时隐藏 Header',
+ 'app.setting.hideheader.hint': '固定 Header 时可配置',
+ 'app.setting.othersettings': '其他设置',
+ 'app.setting.weakmode': '色弱模式',
+ 'app.setting.copy': '拷贝设置',
+ 'app.setting.copyinfo': '拷贝成功,请到 config/defaultSettings.js 中替换默认配置',
+ 'app.setting.production.hint':
+ '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件',
+};
diff --git a/src/locales/zh-CN/settings.js b/src/locales/zh-CN/settings.js
new file mode 100644
index 0000000..df8af43
--- /dev/null
+++ b/src/locales/zh-CN/settings.js
@@ -0,0 +1,55 @@
+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': '绑定淘宝',
+ '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': '关',
+};
diff --git a/src/locales/zh-TW.js b/src/locales/zh-TW.js
new file mode 100644
index 0000000..c55a881
--- /dev/null
+++ b/src/locales/zh-TW.js
@@ -0,0 +1,19 @@
+import component from './zh-TW/component';
+import globalHeader from './zh-TW/globalHeader';
+import menu from './zh-TW/menu';
+import pwa from './zh-TW/pwa';
+import settingDrawer from './zh-TW/settingDrawer';
+import settings from './zh-TW/settings';
+export default {
+ 'navBar.lang': '語言',
+ 'layout.user.link.help': '幫助',
+ 'layout.user.link.privacy': '隱私',
+ 'layout.user.link.terms': '條款',
+ 'app.preview.down.block': '下載此頁面到本地項目',
+ ...globalHeader,
+ ...menu,
+ ...settingDrawer,
+ ...settings,
+ ...pwa,
+ ...component,
+};
diff --git a/src/locales/zh-TW/component.js b/src/locales/zh-TW/component.js
new file mode 100644
index 0000000..ba48e29
--- /dev/null
+++ b/src/locales/zh-TW/component.js
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': '展開',
+ 'component.tagSelect.collapse': '收起',
+ 'component.tagSelect.all': '全部',
+};
diff --git a/src/locales/zh-TW/globalHeader.js b/src/locales/zh-TW/globalHeader.js
new file mode 100644
index 0000000..ed58451
--- /dev/null
+++ b/src/locales/zh-TW/globalHeader.js
@@ -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': '查看更多',
+};
diff --git a/src/locales/zh-TW/menu.js b/src/locales/zh-TW/menu.js
new file mode 100644
index 0000000..6969ccc
--- /dev/null
+++ b/src/locales/zh-TW/menu.js
@@ -0,0 +1,52 @@
+export default {
+ 'menu.welcome': '歡迎',
+ 'menu.more-blocks': '更多區塊',
+ 'menu.home': '首頁',
+ 'menu.login': '登錄',
+ 'menu.admin': '权限',
+ 'menu.admin.sub-page': '二级管理页',
+ 'menu.exception.403': '403',
+ 'menu.exception.404': '404',
+ 'menu.exception.500': '500',
+ 'menu.register': '註冊',
+ 'menu.register-result': '註冊結果',
+ 'menu.dashboard': 'Dashboard',
+ 'menu.dashboard.analysis': '分析頁',
+ 'menu.dashboard.monitor': '監控頁',
+ 'menu.dashboard.workplace': '工作臺',
+ '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.account': '個人頁',
+ 'menu.account.center': '個人中心',
+ 'menu.account.settings': '個人設置',
+ 'menu.account.trigger': '觸發報錯',
+ 'menu.account.logout': '退出登錄',
+ 'menu.exception': '异常页',
+ 'menu.exception.not-permission': '403',
+ 'menu.exception.not-find': '404',
+ 'menu.exception.server-error': '500',
+ 'menu.exception.trigger': '触发错误',
+ 'menu.editor': '圖形編輯器',
+ 'menu.editor.flow': '流程編輯器',
+ 'menu.editor.mind': '腦圖編輯器',
+ 'menu.editor.koni': '拓撲編輯器',
+};
diff --git a/src/locales/zh-TW/pwa.js b/src/locales/zh-TW/pwa.js
new file mode 100644
index 0000000..108a6e4
--- /dev/null
+++ b/src/locales/zh-TW/pwa.js
@@ -0,0 +1,6 @@
+export default {
+ 'app.pwa.offline': '當前處於離線狀態',
+ 'app.pwa.serviceworker.updated': '有新內容',
+ 'app.pwa.serviceworker.updated.hint': '請點擊“刷新”按鈕或者手動刷新頁面',
+ 'app.pwa.serviceworker.updated.ok': '刷新',
+};
diff --git a/src/locales/zh-TW/settingDrawer.js b/src/locales/zh-TW/settingDrawer.js
new file mode 100644
index 0000000..454da28
--- /dev/null
+++ b/src/locales/zh-TW/settingDrawer.js
@@ -0,0 +1,31 @@
+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': '固定 Header',
+ 'app.setting.fixedsidebar': '固定側邊菜單',
+ 'app.setting.fixedsidebar.hint': '側邊菜單布局時可配置',
+ 'app.setting.hideheader': '下滑時隱藏 Header',
+ 'app.setting.hideheader.hint': '固定 Header 時可配置',
+ 'app.setting.othersettings': '其他設置',
+ 'app.setting.weakmode': '色弱模式',
+ 'app.setting.copy': '拷貝設置',
+ 'app.setting.copyinfo': '拷貝成功,請到 config/defaultSettings.js 中替換默認配置',
+ 'app.setting.production.hint':
+ '配置欄只在開發環境用於預覽,生產環境不會展現,請拷貝後手動修改配置文件',
+};
diff --git a/src/locales/zh-TW/settings.js b/src/locales/zh-TW/settings.js
new file mode 100644
index 0000000..dd45151
--- /dev/null
+++ b/src/locales/zh-TW/settings.js
@@ -0,0 +1,55 @@
+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': '綁定淘寶',
+ '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': '關',
+};
diff --git a/src/manifest.json b/src/manifest.json
new file mode 100644
index 0000000..839bc5b
--- /dev/null
+++ b/src/manifest.json
@@ -0,0 +1,22 @@
+{
+ "name": "Ant Design Pro",
+ "short_name": "Ant Design Pro",
+ "display": "standalone",
+ "start_url": "./?utm_source=homescreen",
+ "theme_color": "#002140",
+ "background_color": "#001529",
+ "icons": [
+ {
+ "src": "icons/icon-192x192.png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "icons/icon-128x128.png",
+ "sizes": "128x128"
+ },
+ {
+ "src": "icons/icon-512x512.png",
+ "sizes": "512x512"
+ }
+ ]
+}
diff --git a/src/pages/404.jsx b/src/pages/404.jsx
new file mode 100644
index 0000000..99dd95a
--- /dev/null
+++ b/src/pages/404.jsx
@@ -0,0 +1,18 @@
+import { Button, Result } from 'antd';
+import React from 'react';
+import { history } from 'umi';
+
+const NoFoundPage = () => (
+ history.push('/')}>
+ Back Home
+
+ }
+ />
+);
+
+export default NoFoundPage;
diff --git a/src/pages/Admin.jsx b/src/pages/Admin.jsx
new file mode 100644
index 0000000..1dd53c0
--- /dev/null
+++ b/src/pages/Admin.jsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import { HeartTwoTone, SmileTwoTone } from '@ant-design/icons';
+import { Card, Typography, Alert } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import { useIntl } from 'umi';
+
+const Admin = () => {
+ const intl = useIntl();
+ return (
+
+
+
+
+ Ant Design Pro You
+
+
+
+ Want to add more pages? Please refer to{' '}
+
+ use block
+
+ 。
+
+
+ );
+};
+
+export default Admin;
diff --git a/src/pages/TableList/components/UpdateForm.jsx b/src/pages/TableList/components/UpdateForm.jsx
new file mode 100644
index 0000000..9e8c4f0
--- /dev/null
+++ b/src/pages/TableList/components/UpdateForm.jsx
@@ -0,0 +1,196 @@
+import React from 'react';
+import { Modal } from 'antd';
+import {
+ ProFormSelect,
+ ProFormText,
+ ProFormTextArea,
+ StepsForm,
+ ProFormRadio,
+ ProFormDateTimePicker,
+} from '@ant-design/pro-form';
+import { useIntl, FormattedMessage } from 'umi';
+
+const UpdateForm = (props) => {
+ const intl = useIntl();
+ return (
+ {
+ return (
+ {
+ props.onCancel();
+ }}
+ >
+ {dom}
+
+ );
+ }}
+ onFinish={props.onSubmit}
+ >
+
+
+ ),
+ },
+ ]}
+ />
+
+ ),
+ min: 5,
+ },
+ ]}
+ />
+
+
+
+
+
+
+
+
+ ),
+ },
+ ]}
+ />
+
+
+
+ );
+};
+
+export default UpdateForm;
diff --git a/src/pages/TableList/index.jsx b/src/pages/TableList/index.jsx
new file mode 100644
index 0000000..86cb33a
--- /dev/null
+++ b/src/pages/TableList/index.jsx
@@ -0,0 +1,403 @@
+import { PlusOutlined } from '@ant-design/icons';
+import { Button, message, Input, Drawer } from 'antd';
+import React, { useState, useRef } from 'react';
+import { useIntl, FormattedMessage } from 'umi';
+import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
+import ProTable from '@ant-design/pro-table';
+import { ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
+import ProDescriptions from '@ant-design/pro-descriptions';
+import UpdateForm from './components/UpdateForm';
+import { rule, addRule, updateRule, removeRule } from '@/services/ant-design-pro/api';
+/**
+ * @en-US Add node
+ * @zh-CN 添加节点
+ * @param fields
+ */
+
+const handleAdd = async (fields) => {
+ const hide = message.loading('正在添加');
+
+ try {
+ await addRule({ ...fields });
+ hide();
+ message.success('Added successfully');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Adding failed, please try again!');
+ return false;
+ }
+};
+/**
+ * @en-US Update node
+ * @zh-CN 更新节点
+ *
+ * @param fields
+ */
+
+const handleUpdate = async (fields) => {
+ const hide = message.loading('Configuring');
+
+ try {
+ await updateRule({
+ name: fields.name,
+ desc: fields.desc,
+ key: fields.key,
+ });
+ hide();
+ message.success('Configuration is successful');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Configuration failed, please try again!');
+ return false;
+ }
+};
+/**
+ * Delete node
+ * @zh-CN 删除节点
+ *
+ * @param selectedRows
+ */
+
+const handleRemove = async (selectedRows) => {
+ const hide = message.loading('正在删除');
+ if (!selectedRows) return true;
+
+ try {
+ await removeRule({
+ key: selectedRows.map((row) => row.key),
+ });
+ hide();
+ message.success('Deleted successfully and will refresh soon');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Delete failed, please try again');
+ return false;
+ }
+};
+
+const TableList = () => {
+ /**
+ * @en-US Pop-up window of new window
+ * @zh-CN 新建窗口的弹窗
+ * */
+ const [createModalVisible, handleModalVisible] = useState(false);
+ /**
+ * @en-US The pop-up window of the distribution update window
+ * @zh-CN 分布更新窗口的弹窗
+ * */
+
+ const [updateModalVisible, handleUpdateModalVisible] = useState(false);
+ const [showDetail, setShowDetail] = useState(false);
+ const actionRef = useRef();
+ const [currentRow, setCurrentRow] = useState();
+ const [selectedRowsState, setSelectedRows] = useState([]);
+ /**
+ * @en-US International configuration
+ * @zh-CN 国际化配置
+ * */
+
+ const intl = useIntl();
+ const columns = [
+ {
+ title: (
+
+ ),
+ dataIndex: 'name',
+ tip: 'The rule name is the unique key',
+ render: (dom, entity) => {
+ return (
+ {
+ setCurrentRow(entity);
+ setShowDetail(true);
+ }}
+ >
+ {dom}
+
+ );
+ },
+ },
+ {
+ title: ,
+ dataIndex: 'desc',
+ valueType: 'textarea',
+ },
+ {
+ title: (
+
+ ),
+ dataIndex: 'callNo',
+ sorter: true,
+ hideInForm: true,
+ renderText: (val) =>
+ `${val}${intl.formatMessage({
+ id: 'pages.searchTable.tenThousand',
+ defaultMessage: ' 万 ',
+ })}`,
+ },
+ {
+ title: ,
+ dataIndex: 'status',
+ hideInForm: true,
+ valueEnum: {
+ 0: {
+ text: (
+
+ ),
+ status: 'Default',
+ },
+ 1: {
+ text: (
+
+ ),
+ status: 'Processing',
+ },
+ 2: {
+ text: (
+
+ ),
+ status: 'Success',
+ },
+ 3: {
+ text: (
+
+ ),
+ status: 'Error',
+ },
+ },
+ },
+ {
+ title: (
+
+ ),
+ sorter: true,
+ dataIndex: 'updatedAt',
+ valueType: 'dateTime',
+ renderFormItem: (item, { defaultRender, ...rest }, form) => {
+ const status = form.getFieldValue('status');
+
+ if (`${status}` === '0') {
+ return false;
+ }
+
+ if (`${status}` === '3') {
+ return (
+
+ );
+ }
+
+ return defaultRender(item);
+ },
+ },
+ {
+ title: ,
+ dataIndex: 'option',
+ valueType: 'option',
+ render: (_, record) => [
+ {
+ handleUpdateModalVisible(true);
+ setCurrentRow(record);
+ }}
+ >
+
+ ,
+
+
+ ,
+ ],
+ },
+ ];
+ return (
+
+ [
+ ,
+ ]}
+ request={rule}
+ columns={columns}
+ rowSelection={{
+ onChange: (_, selectedRows) => {
+ setSelectedRows(selectedRows);
+ },
+ }}
+ />
+ {selectedRowsState?.length > 0 && (
+
+ {' '}
+
+ {selectedRowsState.length}
+ {' '}
+
+
+
+ {' '}
+ {selectedRowsState.reduce((pre, item) => pre + item.callNo, 0)}{' '}
+
+
+
+ }
+ >
+
+
+
+ )}
+ {
+ const success = await handleAdd(value);
+
+ if (success) {
+ handleModalVisible(false);
+
+ if (actionRef.current) {
+ actionRef.current.reload();
+ }
+ }
+ }}
+ >
+
+ ),
+ },
+ ]}
+ width="md"
+ name="name"
+ />
+
+
+ {
+ const success = await handleUpdate(value);
+
+ if (success) {
+ handleUpdateModalVisible(false);
+ setCurrentRow(undefined);
+
+ if (actionRef.current) {
+ actionRef.current.reload();
+ }
+ }
+ }}
+ onCancel={() => {
+ handleUpdateModalVisible(false);
+
+ if (!showDetail) {
+ setCurrentRow(undefined);
+ }
+ }}
+ updateModalVisible={updateModalVisible}
+ values={currentRow || {}}
+ />
+
+ {
+ setCurrentRow(undefined);
+ setShowDetail(false);
+ }}
+ closable={false}
+ >
+ {currentRow?.name && (
+ ({
+ data: currentRow || {},
+ })}
+ params={{
+ id: currentRow?.name,
+ }}
+ columns={columns}
+ />
+ )}
+
+
+ );
+};
+
+export default TableList;
diff --git a/src/pages/Welcome.jsx b/src/pages/Welcome.jsx
new file mode 100644
index 0000000..33a7486
--- /dev/null
+++ b/src/pages/Welcome.jsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { PageContainer } from '@ant-design/pro-layout';
+import { Card, Alert, Typography } from 'antd';
+import { useIntl, FormattedMessage } from 'umi';
+import styles from './Welcome.less';
+
+const CodePreview = ({ children }) => (
+
+
+ {children}
+
+
+);
+
+const Welcome = () => {
+ const intl = useIntl();
+ return (
+
+
+
+
+ {' '}
+
+
+
+
+ yarn add @ant-design/pro-table
+
+ {' '}
+
+
+
+
+ yarn add @ant-design/pro-layout
+
+
+ );
+};
+
+export default Welcome;
diff --git a/src/pages/Welcome.less b/src/pages/Welcome.less
new file mode 100644
index 0000000..224a793
--- /dev/null
+++ b/src/pages/Welcome.less
@@ -0,0 +1,8 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.pre {
+ margin: 12px 0;
+ padding: 12px 20px;
+ background: @input-bg;
+ box-shadow: @card-shadow;
+}
diff --git a/src/pages/document.ejs b/src/pages/document.ejs
new file mode 100644
index 0000000..6db8355
--- /dev/null
+++ b/src/pages/document.ejs
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+ Ant Design Pro
+
+
+
+
+
+
+
+

+
+
+

+ Ant Design
+
+
+
+
+
diff --git a/src/pages/user/Login/index.jsx b/src/pages/user/Login/index.jsx
new file mode 100644
index 0000000..5791c30
--- /dev/null
+++ b/src/pages/user/Login/index.jsx
@@ -0,0 +1,288 @@
+import {
+ AlipayCircleOutlined,
+ LockOutlined,
+ MobileOutlined,
+ TaobaoCircleOutlined,
+ UserOutlined,
+ WeiboCircleOutlined,
+} from '@ant-design/icons';
+import { Alert, message, Tabs } from 'antd';
+import React, { useState } from 'react';
+import { ProFormCaptcha, ProFormCheckbox, ProFormText, LoginForm } from '@ant-design/pro-form';
+import { useIntl, history, FormattedMessage, SelectLang, useModel } from 'umi';
+import Footer from '@/components/Footer';
+import { login } from '@/services/ant-design-pro/api';
+import { getFakeCaptcha } from '@/services/ant-design-pro/login';
+import styles from './index.less';
+
+const LoginMessage = ({ content }) => (
+
+);
+
+const Login = () => {
+ const [userLoginState, setUserLoginState] = useState({});
+ const [type, setType] = useState('account');
+ const { initialState, setInitialState } = useModel('@@initialState');
+ const intl = useIntl();
+
+ const fetchUserInfo = async () => {
+ const userInfo = await initialState?.fetchUserInfo?.();
+
+ if (userInfo) {
+ await setInitialState((s) => ({ ...s, currentUser: userInfo }));
+ }
+ };
+
+ const handleSubmit = async (values) => {
+ try {
+ // 登录
+ const msg = await login({ ...values, type });
+
+ if (msg.status === 'ok') {
+ const defaultLoginSuccessMessage = intl.formatMessage({
+ id: 'pages.login.success',
+ defaultMessage: '登录成功!',
+ });
+ message.success(defaultLoginSuccessMessage);
+ await fetchUserInfo();
+ /** 此方法会跳转到 redirect 参数所在的位置 */
+
+ if (!history) return;
+ const { query } = history.location;
+ const { redirect } = query;
+ history.push(redirect || '/');
+ return;
+ }
+
+ console.log(msg); // 如果失败去设置用户错误信息
+
+ setUserLoginState(msg);
+ } catch (error) {
+ const defaultLoginFailureMessage = intl.formatMessage({
+ id: 'pages.login.failure',
+ defaultMessage: '登录失败,请重试!',
+ });
+ message.error(defaultLoginFailureMessage);
+ }
+ };
+
+ const { status, type: loginType } = userLoginState;
+ return (
+
+
+ {SelectLang && }
+
+
+
}
+ title="Ant Design"
+ subTitle={intl.formatMessage({
+ id: 'pages.layouts.userLayout.title',
+ })}
+ initialValues={{
+ autoLogin: true,
+ }}
+ actions={[
+
,
+
,
+
,
+
,
+ ]}
+ onFinish={async (values) => {
+ await handleSubmit(values);
+ }}
+ >
+
+
+
+
+
+ {status === 'error' && loginType === 'account' && (
+
+ )}
+ {type === 'account' && (
+ <>
+
,
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.username.placeholder',
+ defaultMessage: '用户名: admin or user',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
,
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.password.placeholder',
+ defaultMessage: '密码: ant.design',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+ >
+ )}
+
+ {status === 'error' && loginType === 'mobile' &&
}
+ {type === 'mobile' && (
+ <>
+
,
+ }}
+ name="mobile"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.phoneNumber.placeholder',
+ defaultMessage: '手机号',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ {
+ pattern: /^1\d{10}$/,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
,
+ }}
+ captchaProps={{
+ size: 'large',
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.captcha.placeholder',
+ defaultMessage: '请输入验证码',
+ })}
+ captchaTextRender={(timing, count) => {
+ if (timing) {
+ return `${count} ${intl.formatMessage({
+ id: 'pages.getCaptchaSecondText',
+ defaultMessage: '获取验证码',
+ })}`;
+ }
+
+ return intl.formatMessage({
+ id: 'pages.login.phoneLogin.getVerificationCode',
+ defaultMessage: '获取验证码',
+ });
+ }}
+ name="captcha"
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ onGetCaptcha={async (phone) => {
+ const result = await getFakeCaptcha({
+ phone,
+ });
+
+ if (result === false) {
+ return;
+ }
+
+ message.success('获取验证码成功!验证码为:1234');
+ }}
+ />
+ >
+ )}
+
+
+
+
+
+ );
+};
+
+export default Login;
diff --git a/src/pages/user/Login/index.less b/src/pages/user/Login/index.less
new file mode 100644
index 0000000..f6ecf00
--- /dev/null
+++ b/src/pages/user/Login/index.less
@@ -0,0 +1,50 @@
+@import (reference) '~antd/es/style/themes/index';
+
+.container {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ overflow: auto;
+ background: @layout-body-background;
+}
+
+.lang {
+ width: 100%;
+ height: 40px;
+ line-height: 44px;
+ text-align: right;
+ :global(.ant-dropdown-trigger) {
+ margin-right: 24px;
+ }
+}
+
+.content {
+ flex: 1;
+ padding: 32px 0;
+}
+
+@media (min-width: @screen-md-min) {
+ .container {
+ background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
+ background-repeat: no-repeat;
+ background-position: center 110px;
+ background-size: 100%;
+ }
+
+ .content {
+ padding: 32px 0 24px;
+ }
+}
+
+.icon {
+ margin-left: 8px;
+ color: rgba(0, 0, 0, 0.2);
+ font-size: 24px;
+ vertical-align: middle;
+ cursor: pointer;
+ transition: color 0.3s;
+
+ &:hover {
+ color: @primary-color;
+ }
+}
diff --git a/src/service-worker.js b/src/service-worker.js
new file mode 100644
index 0000000..b86726c
--- /dev/null
+++ b/src/service-worker.js
@@ -0,0 +1,65 @@
+/* eslint-disable no-restricted-globals */
+/* eslint-disable no-underscore-dangle */
+/* globals workbox */
+workbox.core.setCacheNameDetails({
+ prefix: 'antd-pro',
+ suffix: 'v5',
+});
+// Control all opened tabs ASAP
+workbox.clientsClaim();
+
+/**
+ * Use precaching list generated by workbox in build process.
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching
+ */
+workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
+
+/**
+ * Register a navigation route.
+ * https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
+ */
+workbox.routing.registerNavigationRoute('/index.html');
+
+/**
+ * Use runtime cache:
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute
+ *
+ * Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc.
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies
+ */
+
+/** Handle API requests */
+workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst());
+
+/** Handle third party requests */
+workbox.routing.registerRoute(
+ /^https:\/\/gw\.alipayobjects\.com\//,
+ workbox.strategies.networkFirst(),
+);
+workbox.routing.registerRoute(
+ /^https:\/\/cdnjs\.cloudflare\.com\//,
+ workbox.strategies.networkFirst(),
+);
+workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst());
+
+/** Response to client after skipping waiting with MessageChannel */
+addEventListener('message', (event) => {
+ const replyPort = event.ports[0];
+ const message = event.data;
+ if (replyPort && message && message.type === 'skip-waiting') {
+ event.waitUntil(
+ self.skipWaiting().then(
+ () => {
+ replyPort.postMessage({
+ error: null,
+ });
+ },
+ (error) => {
+ replyPort.postMessage({
+ error,
+ });
+ },
+ ),
+ );
+ }
+});
diff --git a/src/services/ant-design-pro/api.js b/src/services/ant-design-pro/api.js
new file mode 100644
index 0000000..a024540
--- /dev/null
+++ b/src/services/ant-design-pro/api.js
@@ -0,0 +1,73 @@
+// @ts-ignore
+
+/* eslint-disable */
+import { request } from 'umi';
+/** 获取当前的用户 GET /api/currentUser */
+
+export async function currentUser(options) {
+ return request('/api/currentUser', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+/** 退出登录接口 POST /api/login/outLogin */
+
+export async function outLogin(options) {
+ return request('/api/login/outLogin', {
+ method: 'POST',
+ ...(options || {}),
+ });
+}
+/** 登录接口 POST /api/login/account */
+
+export async function login(body, options) {
+ return request('/api/login/account', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+/** 此处后端没有提供注释 GET /api/notices */
+
+export async function getNotices(options) {
+ return request('/api/notices', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+/** 获取规则列表 GET /api/rule */
+
+export async function rule(params, options) {
+ return request('/api/rule', {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** 新建规则 PUT /api/rule */
+
+export async function updateRule(options) {
+ return request('/api/rule', {
+ method: 'PUT',
+ ...(options || {}),
+ });
+}
+/** 新建规则 POST /api/rule */
+
+export async function addRule(options) {
+ return request('/api/rule', {
+ method: 'POST',
+ ...(options || {}),
+ });
+}
+/** 删除规则 DELETE /api/rule */
+
+export async function removeRule(options) {
+ return request('/api/rule', {
+ method: 'DELETE',
+ ...(options || {}),
+ });
+}
diff --git a/src/services/ant-design-pro/index.js b/src/services/ant-design-pro/index.js
new file mode 100644
index 0000000..73b0072
--- /dev/null
+++ b/src/services/ant-design-pro/index.js
@@ -0,0 +1,11 @@
+// @ts-ignore
+
+/* eslint-disable */
+// API 更新时间:
+// API 唯一标识:
+import * as api from './api';
+import * as login from './login';
+export default {
+ api,
+ login,
+};
diff --git a/src/services/ant-design-pro/login.js b/src/services/ant-design-pro/login.js
new file mode 100644
index 0000000..153e80b
--- /dev/null
+++ b/src/services/ant-design-pro/login.js
@@ -0,0 +1,13 @@
+// @ts-ignore
+
+/* eslint-disable */
+import { request } from 'umi';
+/** 发送验证码 POST /api/login/captcha */
+
+export async function getFakeCaptcha(params, options) {
+ return request('/api/login/captcha', {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
diff --git a/src/services/swagger/index.js b/src/services/swagger/index.js
new file mode 100644
index 0000000..007bd01
--- /dev/null
+++ b/src/services/swagger/index.js
@@ -0,0 +1,13 @@
+// @ts-ignore
+
+/* eslint-disable */
+// API 更新时间:
+// API 唯一标识:
+import * as pet from './pet';
+import * as store from './store';
+import * as user from './user';
+export default {
+ pet,
+ store,
+ user,
+};
diff --git a/src/services/swagger/pet.js b/src/services/swagger/pet.js
new file mode 100644
index 0000000..aa0668a
--- /dev/null
+++ b/src/services/swagger/pet.js
@@ -0,0 +1,110 @@
+// @ts-ignore
+
+/* eslint-disable */
+import { request } from 'umi';
+/** Update an existing pet PUT /pet */
+
+export async function updatePet(body, options) {
+ return request('/pet', {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Add a new pet to the store POST /pet */
+
+export async function addPet(body, options) {
+ return request('/pet', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Finds Pets by status Multiple status values can be provided with comma separated strings GET /pet/findByStatus */
+
+export async function findPetsByStatus(params, options) {
+ return request('/pet/findByStatus', {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Finds Pets by tags Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. GET /pet/findByTags */
+
+export async function findPetsByTags(params, options) {
+ return request('/pet/findByTags', {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Find pet by ID Returns a single pet GET /pet/${param0} */
+
+export async function getPetById(params, options) {
+ const { petId: param0 } = params;
+ return request(`/pet/${param0}`, {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Updates a pet in the store with form data POST /pet/${param0} */
+
+export async function updatePetWithForm(params, body, options) {
+ const { petId: param0 } = params;
+ const formData = new FormData();
+ Object.keys(body).forEach((ele) => {
+ const item = body[ele];
+
+ if (item !== undefined && item !== null) {
+ formData.append(ele, typeof item === 'object' ? JSON.stringify(item) : item);
+ }
+ });
+ return request(`/pet/${param0}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ params: { ...params },
+ data: formData,
+ ...(options || {}),
+ });
+}
+/** Deletes a pet DELETE /pet/${param0} */
+
+export async function deletePet(params, options) {
+ const { petId: param0 } = params;
+ return request(`/pet/${param0}`, {
+ method: 'DELETE',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** uploads an image POST /pet/${param0}/uploadImage */
+
+export async function uploadFile(params, body, options) {
+ const { petId: param0 } = params;
+ const formData = new FormData();
+ Object.keys(body).forEach((ele) => {
+ const item = body[ele];
+
+ if (item !== undefined && item !== null) {
+ formData.append(ele, typeof item === 'object' ? JSON.stringify(item) : item);
+ }
+ });
+ return request(`/pet/${param0}/uploadImage`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ params: { ...params },
+ data: formData,
+ ...(options || {}),
+ });
+}
diff --git a/src/services/swagger/store.js b/src/services/swagger/store.js
new file mode 100644
index 0000000..c0853c1
--- /dev/null
+++ b/src/services/swagger/store.js
@@ -0,0 +1,41 @@
+// @ts-ignore
+
+/* eslint-disable */
+import { request } from 'umi';
+/** Returns pet inventories by status Returns a map of status codes to quantities GET /store/inventory */
+
+export async function getInventory(options) {
+ return request('/store/inventory', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+/** Place an order for a pet POST /store/order */
+
+export async function placeOrder(body, options) {
+ return request('/store/order', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Find purchase order by ID For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions GET /store/order/${param0} */
+
+export async function getOrderById(params, options) {
+ const { orderId: param0 } = params;
+ return request(`/store/order/${param0}`, {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Delete purchase order by ID For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors DELETE /store/order/${param0} */
+
+export async function deleteOrder(params, options) {
+ const { orderId: param0 } = params;
+ return request(`/store/order/${param0}`, {
+ method: 'DELETE',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
diff --git a/src/services/swagger/user.js b/src/services/swagger/user.js
new file mode 100644
index 0000000..f330d1a
--- /dev/null
+++ b/src/services/swagger/user.js
@@ -0,0 +1,79 @@
+// @ts-ignore
+
+/* eslint-disable */
+import { request } from 'umi';
+/** Create user This can only be done by the logged in user. POST /user */
+
+export async function createUser(body, options) {
+ return request('/user', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Creates list of users with given input array POST /user/createWithArray */
+
+export async function createUsersWithArrayInput(body, options) {
+ return request('/user/createWithArray', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Creates list of users with given input array POST /user/createWithList */
+
+export async function createUsersWithListInput(body, options) {
+ return request('/user/createWithList', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Logs user into the system GET /user/login */
+
+export async function loginUser(params, options) {
+ return request('/user/login', {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Logs out current logged in user session GET /user/logout */
+
+export async function logoutUser(options) {
+ return request('/user/logout', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+/** Get user by user name GET /user/${param0} */
+
+export async function getUserByName(params, options) {
+ const { username: param0 } = params;
+ return request(`/user/${param0}`, {
+ method: 'GET',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
+/** Updated user This can only be done by the logged in user. PUT /user/${param0} */
+
+export async function updateUser(params, body, options) {
+ const { username: param0 } = params;
+ return request(`/user/${param0}`, {
+ method: 'PUT',
+ params: { ...params },
+ data: body,
+ ...(options || {}),
+ });
+}
+/** Delete user This can only be done by the logged in user. DELETE /user/${param0} */
+
+export async function deleteUser(params, options) {
+ const { username: param0 } = params;
+ return request(`/user/${param0}`, {
+ method: 'DELETE',
+ params: { ...params },
+ ...(options || {}),
+ });
+}
diff --git a/tests/run-tests.js b/tests/run-tests.js
new file mode 100644
index 0000000..d4e0fc8
--- /dev/null
+++ b/tests/run-tests.js
@@ -0,0 +1,47 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const { spawn } = require('child_process');
+const { kill } = require('cross-port-killer');
+
+const env = Object.create(process.env);
+env.BROWSER = 'none';
+env.TEST = true;
+env.UMI_UI = 'none';
+env.PROGRESS = 'none';
+// flag to prevent multiple test
+let once = false;
+
+const startServer = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['run', 'serve'], {
+ env,
+});
+
+startServer.stderr.on('data', (data) => {
+ // eslint-disable-next-line
+ console.log(data.toString());
+});
+
+startServer.on('exit', () => {
+ kill(process.env.PORT || 8000);
+});
+
+console.log('Starting development server for e2e tests...');
+startServer.stdout.on('data', (data) => {
+ console.log(data.toString());
+ // hack code , wait umi
+ if (!once && data.toString().indexOf('Serving your umi project!') >= 0) {
+ // eslint-disable-next-line
+ once = true;
+ console.log('Development server is started, ready to run tests.');
+ const testCmd = spawn(
+ /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
+ ['run', 'playwright'],
+ {
+ stdio: 'inherit',
+ },
+ );
+ testCmd.on('exit', (code) => {
+ console.log('服务已经退出,退出码:', code);
+ startServer.kill();
+ process.exit(code);
+ });
+ }
+});
diff --git a/tests/setupTests.js b/tests/setupTests.js
new file mode 100644
index 0000000..78b5068
--- /dev/null
+++ b/tests/setupTests.js
@@ -0,0 +1,10 @@
+// do some test init
+
+const localStorageMock = {
+ getItem: jest.fn(),
+ setItem: jest.fn(),
+ removeItem: jest.fn(),
+ clear: jest.fn(),
+};
+
+global.localStorage = localStorageMock;