Compare commits
No commits in common. 'master' and 'gh-pages' have entirely different histories.
@ -1,16 +0,0 @@ |
|||
# 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 |
@ -1,9 +0,0 @@ |
|||
/lambda/ |
|||
/scripts |
|||
/config |
|||
.history |
|||
public |
|||
src |
|||
dist |
|||
.umi |
|||
mock |
@ -1,7 +0,0 @@ |
|||
module.exports = { |
|||
extends: [require.resolve('@umijs/lint/dist/config/eslint')], |
|||
globals: { |
|||
page: true, |
|||
REACT_APP_ENV: true, |
|||
}, |
|||
}; |
@ -1,41 +0,0 @@ |
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. |
|||
|
|||
# dependencies |
|||
**/node_modules |
|||
# roadhog-api-doc ignore |
|||
/src/utils/request-temp.js |
|||
_roadhog-api-doc |
|||
|
|||
# # production |
|||
# /dist |
|||
|
|||
# misc |
|||
.DS_Store |
|||
npm-debug.log* |
|||
yarn-error.log |
|||
|
|||
/coverage |
|||
.idea |
|||
yarn.lock |
|||
package-lock.json |
|||
*bak |
|||
.vscode |
|||
|
|||
|
|||
# visual studio code |
|||
.history |
|||
*.log |
|||
functions/* |
|||
.temp/** |
|||
|
|||
# umi |
|||
.umi |
|||
.umi-production |
|||
.umi-test |
|||
|
|||
# screenshot |
|||
screenshot |
|||
.firebase |
|||
.eslintcache |
|||
|
|||
build |
@ -1,7 +0,0 @@ |
|||
#!/bin/sh |
|||
. "$(dirname "$0")/_/husky.sh" |
|||
|
|||
# Export Git hook params |
|||
export GIT_PARAMS=$* |
|||
|
|||
npx --no-install fabric verify-commit |
@ -1,4 +0,0 @@ |
|||
#!/bin/sh |
|||
. "$(dirname "$0")/_/husky.sh" |
|||
|
|||
npx --no-install lint-staged |
@ -1,22 +0,0 @@ |
|||
**/*.svg |
|||
.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 |
@ -1,21 +0,0 @@ |
|||
module.exports = { |
|||
singleQuote: true, |
|||
trailingComma: 'all', |
|||
printWidth: 100, |
|||
proseWrap: 'never', |
|||
endOfLine: 'lf', |
|||
overrides: [ |
|||
{ |
|||
files: '.prettierrc', |
|||
options: { |
|||
parser: 'json', |
|||
}, |
|||
}, |
|||
{ |
|||
files: 'document.ejs', |
|||
options: { |
|||
parser: 'html', |
|||
}, |
|||
}, |
|||
], |
|||
}; |
@ -1,57 +0,0 @@ |
|||
# Ant Design Pro |
|||
|
|||
This project is initialized with [Ant Design Pro](https://pro.ant.design). Follow is the quick guide for how to use. |
|||
|
|||
## Environment Prepare |
|||
|
|||
Install `node_modules`: |
|||
|
|||
```bash |
|||
npm install |
|||
``` |
|||
|
|||
or |
|||
|
|||
```bash |
|||
yarn |
|||
``` |
|||
|
|||
## Provided Scripts |
|||
|
|||
Ant Design Pro provides some useful script to help you quick start and build with web project, code style check and test. |
|||
|
|||
Scripts provided in `package.json`. It's safe to modify or add additional script: |
|||
|
|||
### Start project |
|||
|
|||
```bash |
|||
npm start |
|||
``` |
|||
|
|||
### Build project |
|||
|
|||
```bash |
|||
npm run build |
|||
``` |
|||
|
|||
### Check code style |
|||
|
|||
```bash |
|||
npm run lint |
|||
``` |
|||
|
|||
You can also use script to auto fix some lint error: |
|||
|
|||
```bash |
|||
npm run lint:fix |
|||
``` |
|||
|
|||
### Test code |
|||
|
|||
```bash |
|||
npm test |
|||
``` |
|||
|
|||
## More |
|||
|
|||
You can view full document on our [official website](https://pro.ant.design). And welcome any feedback in our [github](https://github.com/ant-design/ant-design-pro). |
@ -0,0 +1 @@ |
|||
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["15.a664eb81.async.js",15],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["p__MoneyManagement.4138f9c6.async.js",190],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.4594a64b.async.js",301],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.c61abcd9.async.js",371],["390.41467286.async.js",390],["393.38316f72.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.dec1a716.async.js",455],["p__Proxy__ProxyUserManagement.3e781dae.async.js",526],["531.35af34f5.async.js",531],["539.290aefb9.async.js",539],["p__AdvRecordListV2.93e34297.async.js",542],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.20e45f05.async.js",635],["p__App__AppManagement.6464403a.async.js",731],["761.f7bbde11.async.js",761],["p__AdminManagement.22b52ba3.async.js",816],["841.614ef4c0.async.js",841],["p__AdvRecordList.fc092f59.async.js",857],["p__UserManagement.0ef1f876.async.js",903],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930],["931.c2d40e0b.async.js",931],["p__Proxy__ProxyAdvRecordListV2.20a0f4c8.async.js",990]],"r":{"/*":[19,27],"/":[1,5,6,18,20,27],"/welcome":[1,2,3,10,18,28,5,6,20,27],"/super":[0,1,2,12,14,15,27,28,29,5,6,18,20],"/adminList":[0,1,2,14,15,22,23,27,5,6,18,20],"/bind":[1,2,10,11,17,18,28,5,6,20,27],"/appList":[1,2,11,14,15,21,27,28,29,5,6,18,20],"/advList/:code":[1,2,14,15,18,24,25,27,28,5,6,20],"/advListV2/:code":[0,1,2,14,15,16,18,24,27,28,5,6,20],"/user/:code":[0,1,2,14,15,26,27,28,5,6,18,20],"/money/:code":[0,1,2,4,14,15,27,28,5,6,18,20],"/app/:code":[1,2,8,14,15,18,24,27,28,5,6,20],"/user/login":[1,2,7,14],"/proxy/advListV2/:code":[0,1,2,14,15,18,24,27,28,30,5,6,20],"/proxy/user/:code":[0,1,2,13,14,15,27,28,5,6,18,20]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}(); |
@ -1,156 +0,0 @@ |
|||
// https://umijs.org/config/
|
|||
import { defineConfig } from '@umijs/max'; |
|||
import { join } from 'path'; |
|||
import defaultSettings from './defaultSettings'; |
|||
import proxy from './proxy'; |
|||
import routes from './routes'; |
|||
|
|||
const { REACT_APP_ENV = 'dev' } = process.env; |
|||
|
|||
export default defineConfig({ |
|||
/** |
|||
* @name 开启 hash 模式 |
|||
* @description 让 build 之后的产物包含 hash 后缀。通常用于增量发布和避免浏览器加载缓存。 |
|||
* @doc https://umijs.org/docs/api/config#hash
|
|||
*/ |
|||
hash: true, |
|||
|
|||
/** |
|||
* @name 兼容性设置 |
|||
* @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖 |
|||
* @doc https://umijs.org/docs/api/config#targets
|
|||
*/ |
|||
// targets: {
|
|||
// ie: 11,
|
|||
// },
|
|||
/** |
|||
* @name 路由的配置,不在路由中引入的文件不会编译 |
|||
* @description 只支持 path,component,routes,redirect,wrappers,title 的配置 |
|||
* @doc https://umijs.org/docs/guides/routes
|
|||
*/ |
|||
// umi routes: https://umijs.org/docs/routing
|
|||
routes, |
|||
/** |
|||
* @name 主题的配置 |
|||
* @description 虽然叫主题,但是其实只是 less 的变量设置 |
|||
* @doc antd的主题设置 https://ant.design/docs/react/customize-theme-cn
|
|||
* @doc umi 的theme 配置 https://umijs.org/docs/api/config#theme
|
|||
*/ |
|||
theme: { |
|||
// 如果不想要 configProvide 动态设置主题需要把这个设置为 default
|
|||
// 只有设置为 variable, 才能使用 configProvide 动态设置主色调
|
|||
'root-entry-name': 'variable', |
|||
}, |
|||
/** |
|||
* @name moment 的国际化配置 |
|||
* @description 如果对国际化没有要求,打开之后能减少js的包大小 |
|||
* @doc https://umijs.org/docs/api/config#ignoremomentlocale
|
|||
*/ |
|||
ignoreMomentLocale: true, |
|||
/** |
|||
* @name 代理配置 |
|||
* @description 可以让你的本地服务器代理到你的服务器上,这样你就可以访问服务器的数据了 |
|||
* @see 要注意以下 代理只能在本地开发时使用,build 之后就无法使用了。 |
|||
* @doc 代理介绍 https://umijs.org/docs/guides/proxy
|
|||
* @doc 代理配置 https://umijs.org/docs/api/config#proxy
|
|||
*/ |
|||
proxy: proxy[REACT_APP_ENV as keyof typeof proxy], |
|||
/** |
|||
* @name 快速热更新配置 |
|||
* @description 一个不错的热更新组件,更新时可以保留 state |
|||
*/ |
|||
fastRefresh: true, |
|||
//============== 以下都是max的插件配置 ===============
|
|||
/** |
|||
* @name 数据流插件 |
|||
* @@doc https://umijs.org/docs/max/data-flow
|
|||
*/ |
|||
model: {}, |
|||
/** |
|||
* 一个全局的初始数据流,可以用它在插件之间共享数据 |
|||
* @description 可以用来存放一些全局的数据,比如用户信息,或者一些全局的状态,全局初始状态在整个 Umi 项目的最开始创建。 |
|||
* @doc https://umijs.org/docs/max/data-flow#%E5%85%A8%E5%B1%80%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81
|
|||
*/ |
|||
initialState: {}, |
|||
/** |
|||
* @name layout 插件 |
|||
* @doc https://umijs.org/docs/max/layout-menu
|
|||
*/ |
|||
title: 'Ant Design Pro', |
|||
layout: { |
|||
locale: true, |
|||
...defaultSettings, |
|||
}, |
|||
/** |
|||
* @name moment2dayjs 插件 |
|||
* @description 将项目中的 moment 替换为 dayjs |
|||
* @doc https://umijs.org/docs/max/moment2dayjs
|
|||
*/ |
|||
moment2dayjs: { |
|||
preset: 'antd', |
|||
plugins: ['duration'], |
|||
}, |
|||
/** |
|||
* @name 国际化插件 |
|||
* @doc https://umijs.org/docs/max/i18n
|
|||
*/ |
|||
locale: { |
|||
// default zh-CN
|
|||
default: 'zh-CN', |
|||
antd: true, |
|||
// default true, when it is true, will use `navigator.language` overwrite default
|
|||
baseNavigator: true, |
|||
}, |
|||
/** |
|||
* @name antd 插件 |
|||
* @description 内置了 babel import 插件 |
|||
* @doc https://umijs.org/docs/max/antd#antd
|
|||
*/ |
|||
antd: {}, |
|||
/** |
|||
* @name 网络请求配置 |
|||
* @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。 |
|||
* @doc https://umijs.org/docs/max/request
|
|||
*/ |
|||
request: {}, |
|||
/** |
|||
* @name 权限插件 |
|||
* @description 基于 initialState 的权限插件,必须先打开 initialState |
|||
* @doc https://umijs.org/docs/max/access
|
|||
*/ |
|||
access: {}, |
|||
/** |
|||
* @name <head> 中额外的 script |
|||
* @description 配置 <head> 中额外的 script |
|||
*/ |
|||
headScripts: [ |
|||
// 解决首次加载时白屏的问题
|
|||
{ src: '/scripts/loading.js', async: true }, |
|||
], |
|||
//================ pro 插件配置 =================
|
|||
presets: ['umi-presets-pro'], |
|||
/** |
|||
* @name openAPI 插件的配置 |
|||
* @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码 |
|||
* @doc https://pro.ant.design/zh-cn/docs/openapi/
|
|||
*/ |
|||
openAPI: [ |
|||
// {
|
|||
// requestLibPath: "import { request } from '@umijs/max'",
|
|||
// // 或者使用在线的版本
|
|||
// // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
|
|||
// schemaPath: join(__dirname, 'oneapi.json'),
|
|||
// mock: false,
|
|||
// },
|
|||
{ |
|||
requestLibPath: "import { request } from '@umijs/max'", |
|||
schemaPath: 'http://localhost:9001/api/v3/api-docs', |
|||
projectName: 'matrix', |
|||
}, |
|||
], |
|||
mfsu: { |
|||
strategy: 'normal', |
|||
}, |
|||
esbuildMinifyIIFE: true, |
|||
requestRecord: {}, |
|||
}); |
@ -1,28 +0,0 @@ |
|||
import { ProLayoutProps } from '@ant-design/pro-components'; |
|||
|
|||
/** |
|||
* @name |
|||
*/ |
|||
const Settings: ProLayoutProps & { |
|||
pwa?: boolean; |
|||
logo?: string; |
|||
} = { |
|||
navTheme: 'light', |
|||
// 拂晓蓝
|
|||
colorPrimary: '#1890ff', |
|||
layout: 'mix', |
|||
contentWidth: 'Fluid', |
|||
fixedHeader: false, |
|||
fixSiderbar: true, |
|||
colorWeak: false, |
|||
title: 'Matrix', |
|||
pwa: true, |
|||
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg', |
|||
iconfontUrl: '', |
|||
token: { |
|||
// 参见ts声明,demo 见文档,通过token 修改样式
|
|||
//https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
|
|||
}, |
|||
}; |
|||
|
|||
export default Settings; |
@ -1,593 +0,0 @@ |
|||
{ |
|||
"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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,44 +0,0 @@ |
|||
/** |
|||
* @name 代理的配置 |
|||
* @see 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 |
|||
* ------------------------------- |
|||
* The agent cannot take effect in the production environment |
|||
* so there is no configuration of the production environment |
|||
* For details, please see |
|||
* https://pro.ant.design/docs/deploy
|
|||
* |
|||
* @doc https://umijs.org/docs/guides/proxy
|
|||
*/ |
|||
export default { |
|||
// 如果需要自定义本地开发服务器 请取消注释按需调整
|
|||
dev: { |
|||
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
|
|||
'/api/': { |
|||
// 要代理的地址
|
|||
target: 'http://localhost:9001', |
|||
// 配置了这个可以从 http 代理到 https
|
|||
// 依赖 origin 的功能可能需要这个,比如 cookie
|
|||
changeOrigin: true, |
|||
}, |
|||
}, |
|||
|
|||
/** |
|||
* @name 详细的代理配置 |
|||
* @doc https://github.com/chimurai/http-proxy-middleware
|
|||
*/ |
|||
test: { |
|||
// localhost:8000/api/** -> https://preview.pro.ant.design/api/**
|
|||
'/api/': { |
|||
target: 'https://proapi.azurewebsites.net', |
|||
changeOrigin: true, |
|||
pathRewrite: { '^': '' }, |
|||
}, |
|||
}, |
|||
pre: { |
|||
'/api/': { |
|||
target: 'your pre url', |
|||
changeOrigin: true, |
|||
pathRewrite: { '^': '' }, |
|||
}, |
|||
}, |
|||
}; |
@ -1,80 +0,0 @@ |
|||
|
|||
/** |
|||
* @name umi 的路由配置 |
|||
* @description 只支持 path,component,routes,redirect,wrappers,name,icon 的配置 |
|||
* @param path path 只支持两种占位符配置,第一种是动态参数 :id 的形式,第二种是 * 通配符,通配符只能出现路由字符串的最后。 |
|||
* @param component 配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。 |
|||
* @param routes 配置子路由,通常在需要为多个路径增加 layout 组件时使用。 |
|||
* @param redirect 配置路由跳转 |
|||
* @param wrappers 配置路由组件的包装组件,通过包装组件可以为当前的路由组件组合进更多的功能。 比如,可以用于路由级别的权限校验 |
|||
* @param name 配置路由的标题,默认读取国际化文件 menu.ts 中 menu.xxxx 的值,如配置 name 为 login,则读取 menu.ts 中 menu.login 的取值作为标题 |
|||
* @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 <StepBackwardOutlined /> 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 <UserOutlined /> 则取值应为 user 或者 User
|
|||
* @doc https://umijs.org/docs/guides/routes
|
|||
*/ |
|||
export default [ |
|||
{ |
|||
path: '/user', |
|||
layout: false, |
|||
routes: [ |
|||
{ |
|||
name: 'login', |
|||
path: '/user/login', |
|||
component: './User/Login', |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
path: '/welcome', |
|||
name: '欢迎', |
|||
icon: 'smile', |
|||
component: './Welcome', |
|||
}, |
|||
{ |
|||
path: '/super', |
|||
name: '魔法之地', |
|||
icon: 'smile', |
|||
access: 'superAdmin', |
|||
component: './SuperAdmin', |
|||
}, |
|||
{ |
|||
path: '/advList/:code', |
|||
name: '广告列表', |
|||
icon: 'smile', |
|||
access: 'canAdmin', |
|||
component: './AdvRecordList', |
|||
}, |
|||
{ |
|||
path: '/app/:code', |
|||
name: '应用列表', |
|||
icon: 'smile', |
|||
access: 'canDeviceOwner', |
|||
component: './DeviceOwnerApp', |
|||
}, |
|||
{ |
|||
path: '/adminList', |
|||
name: '人员管理', |
|||
access: 'canAdmin', |
|||
component: './AdminManagement' |
|||
}, |
|||
{ |
|||
path: '/bind', |
|||
name: '绑定设备', |
|||
access: 'canDeviceOwner', |
|||
component: './Bind' |
|||
}, |
|||
{ |
|||
path: '/appList', |
|||
name: '应用管理', |
|||
access: 'canAdmin', |
|||
component: './AppManagement' |
|||
}, |
|||
{ |
|||
path: '/', |
|||
redirect: '/welcome', |
|||
}, |
|||
{ |
|||
path: '*', |
|||
layout: false, |
|||
component: './404', |
|||
}, |
|||
]; |
@ -1,16 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
<title>Ant Design Pro</title> |
|||
<link rel="stylesheet" href="/umi.1ca9308c.css"> |
|||
<script async src="/scripts/loading.js"></script> |
|||
<script>!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["p__AppManagement.7cb3b3e5.async.js",39],["51.e174e29e.async.js",51],["63.d3cf24e7.async.js",63],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["235.f7c67994.async.js",235],["247.3fe8fb10.async.js",247],["258.d191bbdb.async.js",258],["287.b21721be.async.js",287],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.afe80231.async.js",301],["335.e3ecf74a.async.js",335],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.0a01face.async.js",371],["390.41467286.async.js",390],["393.b64a7324.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.d2274a04.async.js",455],["531.47eea593.async.js",531],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.84db70b9.async.js",635],["p__AdminManagement.a0dd8c31.async.js",816],["p__AdvRecordList.4131e6d9.async.js",857],["905.6e225d1b.async.js",905],["930.42e2019f.async.js",930]],"r":{"/*":[22,26],"/":[3,10,11,21,23,26],"/welcome":[3,4,5,16,21,27,10,11,23,26],"/super":[1,2,3,4,6,7,18,27,10,11,21,23,26],"/adminList":[1,4,6,9,24,3,10,11,21,23,26],"/bind":[3,4,16,17,20,21,27,10,11,23,26],"/appList":[0,1,2,3,4,6,9,12,17,19,26,27,10,11,21,23],"/advList/:code":[1,2,3,4,6,8,9,12,19,21,25,26,27,10,11,23],"/app/:code":[1,2,3,4,6,8,9,12,14,19,21,26,27,10,11,23],"/user/login":[2,3,4,6,9,13,19]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}();</script> |
|||
</head> |
|||
<body> |
|||
<div id="root"></div> |
|||
<script src="/umi.18c8c913.js"></script> |
|||
</body> |
|||
</html> |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
@ -0,0 +1,16 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
<title>Ant Design Pro</title> |
|||
<link rel="stylesheet" href="/umi.1ca9308c.css"> |
|||
<script async src="/scripts/loading.js"></script> |
|||
<script src="/_umi_route_preload_helper.18cd284f.js"></script> |
|||
</head> |
|||
<body> |
|||
<div id="root"></div> |
|||
<script src="/umi.bb5c7069.js"></script> |
|||
</body> |
|||
</html> |
@ -1,23 +0,0 @@ |
|||
import { configUmiAlias, createConfig } from '@umijs/max/test'; |
|||
|
|||
export default async () => { |
|||
const config = await configUmiAlias({ |
|||
...createConfig({ |
|||
target: 'browser', |
|||
}), |
|||
}); |
|||
console.log(JSON.stringify(config)); |
|||
|
|||
return { |
|||
...config, |
|||
testEnvironmentOptions: { |
|||
...(config?.testEnvironmentOptions || {}), |
|||
url: 'http://localhost:8000', |
|||
}, |
|||
setupFiles: [...(config.setupFiles || []), './tests/setupTests.jsx'], |
|||
globals: { |
|||
...config.globals, |
|||
localStorage: null, |
|||
}, |
|||
}; |
|||
}; |
@ -1,11 +0,0 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"jsx": "react-jsx", |
|||
"emitDecoratorMetadata": true, |
|||
"experimentalDecorators": true, |
|||
"baseUrl": ".", |
|||
"paths": { |
|||
"@/*": ["./src/*"] |
|||
} |
|||
} |
|||
} |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
@ -1,176 +0,0 @@ |
|||
import { Request, Response } from 'express'; |
|||
import moment from 'moment'; |
|||
import { parse } from 'url'; |
|||
|
|||
// mock tableListDataSource
|
|||
const genList = (current: number, pageSize: number) => { |
|||
const tableListDataSource: API.RuleListItem[] = []; |
|||
|
|||
for (let i = 0; i < pageSize; i += 1) { |
|||
const index = (current - 1) * 10 + i; |
|||
tableListDataSource.push({ |
|||
key: index, |
|||
disabled: i % 6 === 0, |
|||
href: 'https://ant.design', |
|||
avatar: [ |
|||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
][i % 2], |
|||
name: `TradeCode ${index}`, |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: Math.floor(Math.random() * 1000), |
|||
status: Math.floor(Math.random() * 10) % 4, |
|||
updatedAt: 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: Request, res: Response, u: string) { |
|||
let realUrl = u; |
|||
if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { |
|||
realUrl = req.url; |
|||
} |
|||
const { current = 1, pageSize = 10 } = req.query; |
|||
const params = parse(realUrl, true).query as unknown as API.PageParams & |
|||
API.RuleListItem & { |
|||
sorter: any; |
|||
filter: any; |
|||
}; |
|||
|
|||
let dataSource = [...tableListDataSource].slice( |
|||
((current as number) - 1) * (pageSize as number), |
|||
(current as number) * (pageSize as number), |
|||
); |
|||
if (params.sorter) { |
|||
const sorter = JSON.parse(params.sorter); |
|||
dataSource = dataSource.sort((prev, next) => { |
|||
let sortNumber = 0; |
|||
(Object.keys(sorter) as Array<keyof API.RuleListItem>).forEach((key) => { |
|||
let nextSort = next?.[key] as number; |
|||
let preSort = prev?.[key] as number; |
|||
if (sorter[key] === 'descend') { |
|||
if (preSort - nextSort > 0) { |
|||
sortNumber += -1; |
|||
} else { |
|||
sortNumber += 1; |
|||
} |
|||
return; |
|||
} |
|||
if (preSort - nextSort > 0) { |
|||
sortNumber += 1; |
|||
} else { |
|||
sortNumber += -1; |
|||
} |
|||
}); |
|||
return sortNumber; |
|||
}); |
|||
} |
|||
if (params.filter) { |
|||
const filter = JSON.parse(params.filter as any) as { |
|||
[key: string]: string[]; |
|||
}; |
|||
if (Object.keys(filter).length > 0) { |
|||
dataSource = dataSource.filter((item) => { |
|||
return (Object.keys(filter) as Array<keyof API.RuleListItem>).some((key) => { |
|||
if (!filter[key]) { |
|||
return true; |
|||
} |
|||
if (filter[key].includes(`${item[key]}`)) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
if (params.name) { |
|||
dataSource = dataSource.filter((data) => data?.name?.includes(params.name || '')); |
|||
} |
|||
const result = { |
|||
data: dataSource, |
|||
total: tableListDataSource.length, |
|||
success: true, |
|||
pageSize, |
|||
current: parseInt(`${params.current}`, 10) || 1, |
|||
}; |
|||
|
|||
return res.json(result); |
|||
} |
|||
|
|||
function postRule(req: Request, res: Response, u: string, b: Request) { |
|||
let realUrl = u; |
|||
if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') { |
|||
realUrl = req.url; |
|||
} |
|||
|
|||
const body = (b && 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: API.RuleListItem = { |
|||
key: tableListDataSource.length, |
|||
href: 'https://ant.design', |
|||
avatar: [ |
|||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
][i % 2], |
|||
name, |
|||
owner: '曲丽丽', |
|||
desc, |
|||
callNo: Math.floor(Math.random() * 1000), |
|||
status: Math.floor(Math.random() * 10) % 2, |
|||
updatedAt: 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, |
|||
}; |
@ -1,115 +0,0 @@ |
|||
import { Request, Response } from 'express'; |
|||
|
|||
const getNotices = (req: Request, res: Response) => { |
|||
res.json({ |
|||
data: [ |
|||
{ |
|||
id: '000000001', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/MSbDR4FR2MUAAAAAAAAAAAAAFl94AQBr', |
|||
title: '你收到了 14 份新周报', |
|||
datetime: '2017-08-09', |
|||
type: 'notification', |
|||
}, |
|||
{ |
|||
id: '000000002', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/hX-PTavYIq4AAAAAAAAAAAAAFl94AQBr', |
|||
title: '你推荐的 曲妮妮 已通过第三轮面试', |
|||
datetime: '2017-08-08', |
|||
type: 'notification', |
|||
}, |
|||
{ |
|||
id: '000000003', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/jHX5R5l3QjQAAAAAAAAAAAAAFl94AQBr', |
|||
title: '这种模板可以区分多种通知类型', |
|||
datetime: '2017-08-07', |
|||
read: true, |
|||
type: 'notification', |
|||
}, |
|||
{ |
|||
id: '000000004', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/Wr4mQqx6jfwAAAAAAAAAAAAAFl94AQBr', |
|||
title: '左侧图标用于区分不同的类型', |
|||
datetime: '2017-08-07', |
|||
type: 'notification', |
|||
}, |
|||
{ |
|||
id: '000000005', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/Mzj_TbcWUj4AAAAAAAAAAAAAFl94AQBr', |
|||
title: '内容不要超过两行字,超出时自动截断', |
|||
datetime: '2017-08-07', |
|||
type: 'notification', |
|||
}, |
|||
{ |
|||
id: '000000006', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/eXLzRbPqQE4AAAAAAAAAAAAAFl94AQBr', |
|||
title: '曲丽丽 评论了你', |
|||
description: '描述信息描述信息描述信息', |
|||
datetime: '2017-08-07', |
|||
type: 'message', |
|||
clickClose: true, |
|||
}, |
|||
{ |
|||
id: '000000007', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/w5mRQY2AmEEAAAAAAAAAAAAAFl94AQBr', |
|||
title: '朱偏右 回复了你', |
|||
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', |
|||
datetime: '2017-08-07', |
|||
type: 'message', |
|||
clickClose: true, |
|||
}, |
|||
{ |
|||
id: '000000008', |
|||
avatar: |
|||
'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/wPadR5M9918AAAAAAAAAAAAAFl94AQBr', |
|||
title: '标题', |
|||
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', |
|||
datetime: '2017-08-07', |
|||
type: 'message', |
|||
clickClose: true, |
|||
}, |
|||
{ |
|||
id: '000000009', |
|||
title: '任务名称', |
|||
description: '任务需要在 2017-01-12 20:00 前启动', |
|||
extra: '未开始', |
|||
status: 'todo', |
|||
type: 'event', |
|||
}, |
|||
{ |
|||
id: '000000010', |
|||
title: '第三方紧急代码变更', |
|||
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', |
|||
extra: '马上到期', |
|||
status: 'urgent', |
|||
type: 'event', |
|||
}, |
|||
{ |
|||
id: '000000011', |
|||
title: '信息安全考试', |
|||
description: '指派竹尔于 2017-01-09 前完成更新并发布', |
|||
extra: '已耗时 8 天', |
|||
status: 'doing', |
|||
type: 'event', |
|||
}, |
|||
{ |
|||
id: '000000012', |
|||
title: 'ABCD 版本发布', |
|||
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', |
|||
extra: '进行中', |
|||
status: 'processing', |
|||
type: 'event', |
|||
}, |
|||
], |
|||
}); |
|||
}; |
|||
|
|||
export default { |
|||
'GET /api/notices': getNotices, |
|||
}; |
@ -1,324 +0,0 @@ |
|||
module.exports = { |
|||
'GET /api/currentUser': { |
|||
data: { |
|||
name: 'Serati Ma', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', |
|||
userid: '00000001', |
|||
email: 'antdesign@alipay.com', |
|||
signature: '海纳百川,有容乃大', |
|||
title: '交互专家', |
|||
group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', |
|||
tags: [ |
|||
{ key: '0', label: '很有想法的' }, |
|||
{ key: '1', label: '专注设计' }, |
|||
{ key: '2', label: '辣~' }, |
|||
{ key: '3', label: '大长腿' }, |
|||
{ key: '4', label: '川妹子' }, |
|||
{ key: '5', label: '海纳百川' }, |
|||
], |
|||
notifyCount: 12, |
|||
unreadCount: 11, |
|||
country: 'China', |
|||
geographic: { |
|||
province: { label: '浙江省', key: '330000' }, |
|||
city: { label: '杭州市', key: '330100' }, |
|||
}, |
|||
address: '西湖区工专路 77 号', |
|||
phone: '0752-268888888', |
|||
}, |
|||
}, |
|||
'GET /api/rule': { |
|||
data: [ |
|||
{ |
|||
key: 99, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 99', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 503, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 81, |
|||
}, |
|||
{ |
|||
key: 98, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 98', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 164, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 12, |
|||
}, |
|||
{ |
|||
key: 97, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 97', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 174, |
|||
status: '1', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 81, |
|||
}, |
|||
{ |
|||
key: 96, |
|||
disabled: true, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 96', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 914, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 7, |
|||
}, |
|||
{ |
|||
key: 95, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 95', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 698, |
|||
status: '2', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 82, |
|||
}, |
|||
{ |
|||
key: 94, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 94', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 488, |
|||
status: '1', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 14, |
|||
}, |
|||
{ |
|||
key: 93, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 93', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 580, |
|||
status: '2', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 77, |
|||
}, |
|||
{ |
|||
key: 92, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 92', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 244, |
|||
status: '3', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 58, |
|||
}, |
|||
{ |
|||
key: 91, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 91', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 959, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 66, |
|||
}, |
|||
{ |
|||
key: 90, |
|||
disabled: true, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 90', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 958, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 72, |
|||
}, |
|||
{ |
|||
key: 89, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 89', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 301, |
|||
status: '2', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 2, |
|||
}, |
|||
{ |
|||
key: 88, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 88', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 277, |
|||
status: '1', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 12, |
|||
}, |
|||
{ |
|||
key: 87, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 87', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 810, |
|||
status: '1', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 82, |
|||
}, |
|||
{ |
|||
key: 86, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 86', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 780, |
|||
status: '3', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 22, |
|||
}, |
|||
{ |
|||
key: 85, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 85', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 705, |
|||
status: '3', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 12, |
|||
}, |
|||
{ |
|||
key: 84, |
|||
disabled: true, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 84', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 203, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 79, |
|||
}, |
|||
{ |
|||
key: 83, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 83', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 491, |
|||
status: '2', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 59, |
|||
}, |
|||
{ |
|||
key: 82, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 82', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 73, |
|||
status: '0', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 100, |
|||
}, |
|||
{ |
|||
key: 81, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png', |
|||
name: 'TradeCode 81', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 406, |
|||
status: '3', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 61, |
|||
}, |
|||
{ |
|||
key: 80, |
|||
disabled: false, |
|||
href: 'https://ant.design', |
|||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', |
|||
name: 'TradeCode 80', |
|||
owner: '曲丽丽', |
|||
desc: '这是一段描述', |
|||
callNo: 112, |
|||
status: '2', |
|||
updatedAt: '2022-12-06T05:00:57.040Z', |
|||
createdAt: '2022-12-06T05:00:57.040Z', |
|||
progress: 20, |
|||
}, |
|||
], |
|||
total: 100, |
|||
success: true, |
|||
pageSize: 20, |
|||
current: 1, |
|||
}, |
|||
'POST /api/login/outLogin': { data: {}, success: true }, |
|||
'POST /api/login/account': { |
|||
status: 'ok', |
|||
type: 'account', |
|||
currentAuthority: 'admin', |
|||
}, |
|||
}; |
@ -1,5 +0,0 @@ |
|||
export default { |
|||
'/api/auth_routes': { |
|||
'/form/advanced-form': { authority: ['admin', 'user'] }, |
|||
}, |
|||
}; |
@ -1,203 +0,0 @@ |
|||
import { Request, Response } from 'express'; |
|||
|
|||
const waitTime = (time: number = 100) => { |
|||
return new Promise((resolve) => { |
|||
setTimeout(() => { |
|||
resolve(true); |
|||
}, time); |
|||
}); |
|||
}; |
|||
|
|||
async function getFakeCaptcha(req: Request, res: Response) { |
|||
await waitTime(2000); |
|||
return res.json('captcha-xxx'); |
|||
} |
|||
|
|||
const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env; |
|||
|
|||
/** |
|||
* 当前用户的权限,如果为空代表没登录 |
|||
* current user access, if is '', user need login |
|||
* 如果是 pro 的预览,默认是有权限的 |
|||
*/ |
|||
let access = ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' ? 'admin' : ''; |
|||
|
|||
const getAccess = () => { |
|||
return access; |
|||
}; |
|||
|
|||
// 代码中会兼容本地 service mock 以及部署站点的静态数据
|
|||
export default { |
|||
// 支持值为 Object 和 Array
|
|||
'GET /api/currentUser': (req: Request, res: Response) => { |
|||
if (!getAccess()) { |
|||
res.status(401).send({ |
|||
data: { |
|||
isLogin: false, |
|||
}, |
|||
errorCode: '401', |
|||
errorMessage: '请先登录!', |
|||
success: true, |
|||
}); |
|||
return; |
|||
} |
|||
res.send({ |
|||
success: true, |
|||
data: { |
|||
name: 'Serati Ma', |
|||
avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png', |
|||
userid: '00000001', |
|||
email: 'antdesign@alipay.com', |
|||
signature: '海纳百川,有容乃大', |
|||
title: '交互专家', |
|||
group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', |
|||
tags: [ |
|||
{ |
|||
key: '0', |
|||
label: '很有想法的', |
|||
}, |
|||
{ |
|||
key: '1', |
|||
label: '专注设计', |
|||
}, |
|||
{ |
|||
key: '2', |
|||
label: '辣~', |
|||
}, |
|||
{ |
|||
key: '3', |
|||
label: '大长腿', |
|||
}, |
|||
{ |
|||
key: '4', |
|||
label: '川妹子', |
|||
}, |
|||
{ |
|||
key: '5', |
|||
label: '海纳百川', |
|||
}, |
|||
], |
|||
notifyCount: 12, |
|||
unreadCount: 11, |
|||
country: 'China', |
|||
access: getAccess(), |
|||
geographic: { |
|||
province: { |
|||
label: '浙江省', |
|||
key: '330000', |
|||
}, |
|||
city: { |
|||
label: '杭州市', |
|||
key: '330100', |
|||
}, |
|||
}, |
|||
address: '西湖区工专路 77 号', |
|||
phone: '0752-268888888', |
|||
}, |
|||
}); |
|||
}, |
|||
// GET POST 可省略
|
|||
'GET /api/users': [ |
|||
{ |
|||
key: '1', |
|||
name: 'John Brown', |
|||
age: 32, |
|||
address: 'New York No. 1 Lake Park', |
|||
}, |
|||
{ |
|||
key: '2', |
|||
name: 'Jim Green', |
|||
age: 42, |
|||
address: 'London No. 1 Lake Park', |
|||
}, |
|||
{ |
|||
key: '3', |
|||
name: 'Joe Black', |
|||
age: 32, |
|||
address: 'Sidney No. 1 Lake Park', |
|||
}, |
|||
], |
|||
'POST /api/login/account': async (req: Request, res: Response) => { |
|||
const { password, username, type } = req.body; |
|||
await waitTime(2000); |
|||
if (password === 'ant.design' && username === 'admin') { |
|||
res.send({ |
|||
status: 'ok', |
|||
type, |
|||
currentAuthority: 'admin', |
|||
}); |
|||
access = 'admin'; |
|||
return; |
|||
} |
|||
if (password === 'ant.design' && username === 'user') { |
|||
res.send({ |
|||
status: 'ok', |
|||
type, |
|||
currentAuthority: 'user', |
|||
}); |
|||
access = 'user'; |
|||
return; |
|||
} |
|||
if (type === 'mobile') { |
|||
res.send({ |
|||
status: 'ok', |
|||
type, |
|||
currentAuthority: 'admin', |
|||
}); |
|||
access = 'admin'; |
|||
return; |
|||
} |
|||
|
|||
res.send({ |
|||
status: 'error', |
|||
type, |
|||
currentAuthority: 'guest', |
|||
}); |
|||
access = 'guest'; |
|||
}, |
|||
'POST /api/login/outLogin': (req: Request, res: Response) => { |
|||
access = ''; |
|||
res.send({ data: {}, success: true }); |
|||
}, |
|||
'POST /api/register': (req: Request, res: Response) => { |
|||
res.send({ status: 'ok', currentAuthority: 'user', success: true }); |
|||
}, |
|||
'GET /api/500': (req: Request, res: Response) => { |
|||
res.status(500).send({ |
|||
timestamp: 1513932555104, |
|||
status: 500, |
|||
error: 'error', |
|||
message: 'error', |
|||
path: '/base/category/list', |
|||
}); |
|||
}, |
|||
'GET /api/404': (req: Request, res: Response) => { |
|||
res.status(404).send({ |
|||
timestamp: 1513932643431, |
|||
status: 404, |
|||
error: 'Not Found', |
|||
message: 'No message available', |
|||
path: '/base/category/list/2121212', |
|||
}); |
|||
}, |
|||
'GET /api/403': (req: Request, res: Response) => { |
|||
res.status(403).send({ |
|||
timestamp: 1513932555104, |
|||
status: 403, |
|||
error: 'Forbidden', |
|||
message: 'Forbidden', |
|||
path: '/base/category/list', |
|||
}); |
|||
}, |
|||
'GET /api/401': (req: Request, res: Response) => { |
|||
res.status(401).send({ |
|||
timestamp: 1513932555104, |
|||
status: 401, |
|||
error: 'Unauthorized', |
|||
message: 'Unauthorized', |
|||
path: '/base/category/list', |
|||
}); |
|||
}, |
|||
|
|||
'GET /api/login/captcha': getFakeCaptcha, |
|||
}; |
@ -1,103 +0,0 @@ |
|||
{ |
|||
"name": "ant-design-pro", |
|||
"version": "6.0.0", |
|||
"private": true, |
|||
"description": "An out-of-box UI solution for enterprise applications", |
|||
"scripts": { |
|||
"analyze": "cross-env ANALYZE=1 max build", |
|||
"build": "max build", |
|||
"deploy": "npm run build && npm run gh-pages", |
|||
"dev": "npm run start:dev", |
|||
"gh-pages": "gh-pages -d dist", |
|||
"i18n-remove": "pro i18n-remove --locale=zh-CN --write", |
|||
"postinstall": "max setup", |
|||
"jest": "jest", |
|||
"lint": "npm run lint:js && 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 ", |
|||
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src", |
|||
"lint:prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\" --end-of-line auto", |
|||
"openapi": "max openapi", |
|||
"prepare": "husky install", |
|||
"prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"", |
|||
"preview": "npm run build && max preview --port 8000", |
|||
"record": "cross-env NODE_ENV=development REACT_APP_ENV=test max record --scene=login", |
|||
"serve": "umi-serve", |
|||
"start": "cross-env UMI_ENV=dev max dev", |
|||
"start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev max dev", |
|||
"start:no-mock": "cross-env MOCK=none UMI_ENV=dev max dev", |
|||
"start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev max dev", |
|||
"start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev max dev", |
|||
"test": "jest", |
|||
"test:coverage": "npm run jest -- --coverage", |
|||
"test:update": "npm run jest -- -u", |
|||
"tsc": "tsc --noEmit" |
|||
}, |
|||
"lint-staged": { |
|||
"**/*.{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/charts": "^2.0.3", |
|||
"@ant-design/icons": "^4.8.1", |
|||
"@ant-design/pro-components": "^2.6.48", |
|||
"@umijs/route-utils": "^2.2.2", |
|||
"ali-oss": "^6.20.0", |
|||
"antd": "^5.13.2", |
|||
"antd-style": "^3.6.1", |
|||
"classnames": "^2.5.1", |
|||
"lodash": "^4.17.21", |
|||
"moment": "^2.30.1", |
|||
"omit.js": "^2.0.2", |
|||
"querystring": "^0.2.1", |
|||
"rc-menu": "^9.12.4", |
|||
"rc-util": "^5.38.1", |
|||
"react": "^18.2.0", |
|||
"react-dom": "^18.2.0", |
|||
"react-helmet-async": "^1.3.0", |
|||
"spark-md5": "^3.0.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@ant-design/pro-cli": "^3.3.0", |
|||
"@testing-library/react": "^13.4.0", |
|||
"@types/ali-oss": "^6.16.11", |
|||
"@types/classnames": "^2.3.1", |
|||
"@types/express": "^4.17.21", |
|||
"@types/history": "^4.7.11", |
|||
"@types/jest": "^29.5.11", |
|||
"@types/lodash": "^4.14.202", |
|||
"@types/react": "^18.2.48", |
|||
"@types/react-dom": "^18.2.18", |
|||
"@types/react-helmet": "^6.1.11", |
|||
"@types/spark-md5": "^3.0.4", "@umijs/fabric": "^2.14.1", |
|||
"@umijs/lint": "^4.1.1", |
|||
"@umijs/max": "^4.1.1", |
|||
"cross-env": "^7.0.3", |
|||
"eslint": "^8.56.0", |
|||
"express": "^4.18.2", |
|||
"gh-pages": "^3.2.3", |
|||
"husky": "^7.0.4", |
|||
"jest": "^29.7.0", |
|||
"jest-environment-jsdom": "^29.7.0", |
|||
"lint-staged": "^10.5.4", |
|||
"mockjs": "^1.1.0", |
|||
"prettier": "^2.8.8", |
|||
"react-dev-inspector": "^1.9.0", |
|||
"swagger-ui-dist": "^4.19.1", |
|||
"ts-node": "^10.9.2", |
|||
"typescript": "^5.3.3", |
|||
"umi-presets-pro": "^2.0.3", |
|||
"umi-serve": "^1.9.11" |
|||
}, |
|||
"engines": { |
|||
"node": ">=12.0.0" |
|||
} |
|||
} |
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 677 B |
@ -1 +0,0 @@ |
|||
preview.pro.ant.design |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 677 B |
@ -1,202 +0,0 @@ |
|||
/** |
|||
* loading 占位 |
|||
* 解决首次加载时白屏的问题 |
|||
*/ |
|||
(function () { |
|||
const _root = document.querySelector('#root'); |
|||
if (_root && _root.innerHTML === '') { |
|||
_root.innerHTML = ` |
|||
<style> |
|||
html, |
|||
body, |
|||
#root { |
|||
height: 100%; |
|||
margin: 0; |
|||
padding: 0; |
|||
} |
|||
#root { |
|||
background-repeat: no-repeat; |
|||
background-size: 100% auto; |
|||
} |
|||
|
|||
.loading-title { |
|||
font-size: 1.1rem; |
|||
} |
|||
|
|||
.loading-sub-title { |
|||
margin-top: 20px; |
|||
font-size: 1rem; |
|||
color: #888; |
|||
} |
|||
|
|||
.page-loading-warp { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 26px; |
|||
} |
|||
.ant-spin { |
|||
position: absolute; |
|||
display: none; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
padding: 0; |
|||
color: rgba(0, 0, 0, 0.65); |
|||
color: #1890ff; |
|||
font-size: 14px; |
|||
font-variant: tabular-nums; |
|||
line-height: 1.5; |
|||
text-align: center; |
|||
list-style: none; |
|||
opacity: 0; |
|||
-webkit-transition: -webkit-transform 0.3s |
|||
cubic-bezier(0.78, 0.14, 0.15, 0.86); |
|||
transition: -webkit-transform 0.3s |
|||
cubic-bezier(0.78, 0.14, 0.15, 0.86); |
|||
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86); |
|||
transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), |
|||
-webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86); |
|||
-webkit-font-feature-settings: "tnum"; |
|||
font-feature-settings: "tnum"; |
|||
} |
|||
|
|||
.ant-spin-spinning { |
|||
position: static; |
|||
display: inline-block; |
|||
opacity: 1; |
|||
} |
|||
|
|||
.ant-spin-dot { |
|||
position: relative; |
|||
display: inline-block; |
|||
width: 20px; |
|||
height: 20px; |
|||
font-size: 20px; |
|||
} |
|||
|
|||
.ant-spin-dot-item { |
|||
position: absolute; |
|||
display: block; |
|||
width: 9px; |
|||
height: 9px; |
|||
background-color: #1890ff; |
|||
border-radius: 100%; |
|||
-webkit-transform: scale(0.75); |
|||
-ms-transform: scale(0.75); |
|||
transform: scale(0.75); |
|||
-webkit-transform-origin: 50% 50%; |
|||
-ms-transform-origin: 50% 50%; |
|||
transform-origin: 50% 50%; |
|||
opacity: 0.3; |
|||
-webkit-animation: antspinmove 1s infinite linear alternate; |
|||
animation: antSpinMove 1s infinite linear alternate; |
|||
} |
|||
|
|||
.ant-spin-dot-item:nth-child(1) { |
|||
top: 0; |
|||
left: 0; |
|||
} |
|||
|
|||
.ant-spin-dot-item:nth-child(2) { |
|||
top: 0; |
|||
right: 0; |
|||
-webkit-animation-delay: 0.4s; |
|||
animation-delay: 0.4s; |
|||
} |
|||
|
|||
.ant-spin-dot-item:nth-child(3) { |
|||
right: 0; |
|||
bottom: 0; |
|||
-webkit-animation-delay: 0.8s; |
|||
animation-delay: 0.8s; |
|||
} |
|||
|
|||
.ant-spin-dot-item:nth-child(4) { |
|||
bottom: 0; |
|||
left: 0; |
|||
-webkit-animation-delay: 1.2s; |
|||
animation-delay: 1.2s; |
|||
} |
|||
|
|||
.ant-spin-dot-spin { |
|||
-webkit-transform: rotate(45deg); |
|||
-ms-transform: rotate(45deg); |
|||
transform: rotate(45deg); |
|||
-webkit-animation: antrotate 1.2s infinite linear; |
|||
animation: antRotate 1.2s infinite linear; |
|||
} |
|||
|
|||
.ant-spin-lg .ant-spin-dot { |
|||
width: 32px; |
|||
height: 32px; |
|||
font-size: 32px; |
|||
} |
|||
|
|||
.ant-spin-lg .ant-spin-dot i { |
|||
width: 14px; |
|||
height: 14px; |
|||
} |
|||
|
|||
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { |
|||
.ant-spin-blur { |
|||
background: #fff; |
|||
opacity: 0.5; |
|||
} |
|||
} |
|||
|
|||
@-webkit-keyframes antSpinMove { |
|||
to { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@keyframes antSpinMove { |
|||
to { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
|
|||
@-webkit-keyframes antRotate { |
|||
to { |
|||
-webkit-transform: rotate(405deg); |
|||
transform: rotate(405deg); |
|||
} |
|||
} |
|||
|
|||
@keyframes antRotate { |
|||
to { |
|||
-webkit-transform: rotate(405deg); |
|||
transform: rotate(405deg); |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
<div style=" |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
height: 100%; |
|||
min-height: 362px; |
|||
"> |
|||
<div class="page-loading-warp"> |
|||
<div class="ant-spin ant-spin-lg ant-spin-spinning"> |
|||
<span class="ant-spin-dot ant-spin-dot-spin"> |
|||
<i class="ant-spin-dot-item"></i> |
|||
<i class="ant-spin-dot-item"></i> |
|||
<i class="ant-spin-dot-item"></i> |
|||
<i class="ant-spin-dot-item"></i> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div class="loading-title"> |
|||
正在加载资源 |
|||
</div> |
|||
<div class="loading-sub-title"> |
|||
初次加载资源可能需要较多时间 请耐心等待 |
|||
</div> |
|||
</div> |
|||
`;
|
|||
} |
|||
})(); |
@ -1,12 +0,0 @@ |
|||
/** |
|||
* @see https://umijs.org/docs/max/access#access
|
|||
* */ |
|||
export default function access(initialState: { currentUser?: API.MatrixAdmin } | undefined) { |
|||
const { currentUser } = initialState ?? {}; |
|||
let data = { |
|||
canAdmin: currentUser && currentUser.role && currentUser.role <= 3, |
|||
superAdmin: currentUser && currentUser.role && currentUser.role === 1, |
|||
canDeviceOwner: currentUser && currentUser.role && currentUser.role > 3, |
|||
}; |
|||
return data; |
|||
} |
@ -1,212 +0,0 @@ |
|||
import { AvatarDropdown, AvatarName, Question, SelectLang } from '@/components'; |
|||
import { current } from '@/services/matrix/admin'; |
|||
import { LinkOutlined } from '@ant-design/icons'; |
|||
import { MenuDataItem, SettingDrawer } from '@ant-design/pro-components'; |
|||
import { Link, history } from '@umijs/max'; |
|||
|
|||
import { appList } from '@/services/matrix/admin'; |
|||
import type { Settings as LayoutSettings } from '@ant-design/pro-components'; |
|||
import type { RunTimeLayoutConfig } from '@umijs/max'; |
|||
import defaultSettings from '../config/defaultSettings'; |
|||
import access from './access'; |
|||
import { errorConfig } from './requestErrorConfig'; |
|||
const isDev = process.env.NODE_ENV === 'development'; |
|||
const loginPath = '/user/login'; |
|||
|
|||
/** |
|||
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
|
|||
* */ |
|||
export async function getInitialState(): Promise<{ |
|||
settings?: Partial<LayoutSettings>; |
|||
currentUser?: API.MatrixAdmin; |
|||
loading?: boolean; |
|||
fetchUserInfo?: () => Promise<API.MatrixAdmin | undefined>; |
|||
}> { |
|||
const fetchUserInfo = async () => { |
|||
try { |
|||
const msg = await current({ |
|||
skipErrorHandler: true, |
|||
}); |
|||
return msg.data; |
|||
} catch (error) { |
|||
history.push(loginPath); |
|||
} |
|||
return undefined; |
|||
}; |
|||
// 如果不是登录页面,执行
|
|||
const { location } = history; |
|||
if (location.pathname !== loginPath) { |
|||
const currentUser = await fetchUserInfo(); |
|||
return { |
|||
fetchUserInfo, |
|||
currentUser, |
|||
settings: defaultSettings as Partial<LayoutSettings>, |
|||
}; |
|||
} |
|||
return { |
|||
fetchUserInfo, |
|||
settings: defaultSettings as Partial<LayoutSettings>, |
|||
}; |
|||
} |
|||
|
|||
// ProLayout 支持的api https://procomponents.ant.design/components/layout
|
|||
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => { |
|||
return { |
|||
menu: { |
|||
// 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
|
|||
params: { |
|||
userId: initialState?.currentUser?.id, |
|||
}, |
|||
request: async () => { |
|||
const apps = await appList(); |
|||
const menuData: MenuDataItem[] = []; |
|||
const role = initialState?.currentUser?.role || 100; |
|||
apps.data?.forEach((x: any) => { |
|||
if (x.hide === 1 && role <= 2) { |
|||
} else { |
|||
menuData.push({ |
|||
path: '/advList/' + x.code, |
|||
name: x.name, |
|||
access: 'canAdmin', |
|||
component: './AdvRecordList', |
|||
}); |
|||
} |
|||
if (role === 4) { |
|||
menuData.push({ |
|||
path: '/app/' + x.code, |
|||
name: x.name, |
|||
access: 'canDeviceOwner', |
|||
component: './DeviceOwnerApp', |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
menuData.push({ |
|||
path: '/adminList', |
|||
name: '人员管理', |
|||
access: 'canAdmin', |
|||
}); |
|||
|
|||
menuData.push({ |
|||
path: '/bind', |
|||
name: '绑定设备', |
|||
access: 'canDeviceOwner', |
|||
}); |
|||
|
|||
menuData.push({ |
|||
path: '/appList', |
|||
name: '应用列表', |
|||
access: 'canAdmin', |
|||
}); |
|||
|
|||
menuData.push({ |
|||
path: '/super', |
|||
name: '魔法之地', |
|||
access: 'superAdmin', |
|||
}); |
|||
|
|||
return menuData; |
|||
}, |
|||
}, |
|||
// 添加权限校验逻辑
|
|||
menuDataRender: (menuData) => |
|||
menuData.map((item) => { |
|||
const val = item.access; |
|||
if (!val) { |
|||
return item; |
|||
} |
|||
|
|||
const accessData: { [key: string]: boolean | 0 | undefined } = access(initialState); |
|||
if (!accessData[val]) { |
|||
return { |
|||
...item, |
|||
hideInMenu: true, |
|||
}; |
|||
} |
|||
|
|||
return item; |
|||
}), |
|||
actionsRender: () => [<Question key="doc" />, <SelectLang key="SelectLang" />], |
|||
avatarProps: { |
|||
// src: initialState?.currentUser?.avatar,
|
|||
title: <AvatarName />, |
|||
render: (_, avatarChildren) => { |
|||
return <AvatarDropdown>{avatarChildren}</AvatarDropdown>; |
|||
}, |
|||
}, |
|||
// waterMarkProps: {
|
|||
// content: initialState?.currentUser?.name,
|
|||
// },
|
|||
// footerRender: () => <Footer />,
|
|||
onPageChange: () => { |
|||
const { location } = history; |
|||
// 如果没有登录,重定向到 login
|
|||
if (!initialState?.currentUser && location.pathname !== loginPath) { |
|||
history.push(loginPath); |
|||
} |
|||
}, |
|||
bgLayoutImgList: [ |
|||
{ |
|||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr', |
|||
left: 85, |
|||
bottom: 100, |
|||
height: '303px', |
|||
}, |
|||
{ |
|||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr', |
|||
bottom: -68, |
|||
right: -45, |
|||
height: '303px', |
|||
}, |
|||
{ |
|||
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr', |
|||
bottom: 0, |
|||
left: 0, |
|||
width: '331px', |
|||
}, |
|||
], |
|||
links: isDev |
|||
? [ |
|||
<Link key="openapi" to="/umi/plugin/openapi" target="_blank"> |
|||
<LinkOutlined onPointerEnterCapture={undefined} onPointerLeaveCapture={undefined} /> |
|||
<span>OpenAPI 文档</span> |
|||
</Link>, |
|||
] |
|||
: [], |
|||
menuHeaderRender: undefined, |
|||
// 自定义 403 页面
|
|||
// unAccessible: <div>unAccessible</div>,
|
|||
// 增加一个 loading 的状态
|
|||
childrenRender: (children) => { |
|||
// if (initialState?.loading) return <PageLoading />;
|
|||
return ( |
|||
<> |
|||
{children} |
|||
{isDev && ( |
|||
<SettingDrawer |
|||
disableUrlParams |
|||
enableDarkTheme |
|||
settings={initialState?.settings} |
|||
onSettingChange={(settings) => { |
|||
setInitialState((preInitialState) => ({ |
|||
...preInitialState, |
|||
settings, |
|||
})); |
|||
}} |
|||
/> |
|||
)} |
|||
</> |
|||
); |
|||
}, |
|||
...initialState?.settings, |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* @name request 配置,可以配置错误处理 |
|||
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。 |
|||
* @doc https://umijs.org/docs/max/request#配置
|
|||
*/ |
|||
export const request = { |
|||
...errorConfig, |
|||
}; |
@ -1,35 +0,0 @@ |
|||
import { GithubOutlined } from '@ant-design/icons'; |
|||
import { DefaultFooter } from '@ant-design/pro-components'; |
|||
import React from 'react'; |
|||
|
|||
const Footer: React.FC = () => { |
|||
return ( |
|||
<DefaultFooter |
|||
style={{ |
|||
background: 'none', |
|||
}} |
|||
links={[ |
|||
{ |
|||
key: 'Ant Design Pro', |
|||
title: 'Ant Design Pro', |
|||
href: 'https://pro.ant.design', |
|||
blankTarget: true, |
|||
}, |
|||
{ |
|||
key: 'github', |
|||
title: <GithubOutlined />, |
|||
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; |
@ -1,27 +0,0 @@ |
|||
import { Dropdown } from 'antd'; |
|||
import { createStyles } from 'antd-style'; |
|||
import type { DropDownProps } from 'antd/es/dropdown'; |
|||
import classNames from 'classnames'; |
|||
import React from 'react'; |
|||
|
|||
const useStyles = createStyles(({ token }) => { |
|||
return { |
|||
dropdown: { |
|||
[`@media screen and (max-width: ${token.screenXS}px)`]: { |
|||
width: '100%', |
|||
}, |
|||
}, |
|||
}; |
|||
}); |
|||
|
|||
export type HeaderDropdownProps = { |
|||
overlayClassName?: string; |
|||
placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight' | 'bottomCenter'; |
|||
} & Omit<DropDownProps, 'overlay'>; |
|||
|
|||
const HeaderDropdown: React.FC<HeaderDropdownProps> = ({ overlayClassName: cls, ...restProps }) => { |
|||
const { styles } = useStyles(); |
|||
return <Dropdown overlayClassName={classNames(styles.dropdown, cls)} {...restProps} />; |
|||
}; |
|||
|
|||
export default HeaderDropdown; |
@ -1,137 +0,0 @@ |
|||
import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; |
|||
import { history, useModel } from '@umijs/max'; |
|||
import { Spin } from 'antd'; |
|||
import { createStyles } from 'antd-style'; |
|||
import { stringify } from 'querystring'; |
|||
import React, { useCallback } from 'react'; |
|||
import { flushSync } from 'react-dom'; |
|||
|
|||
import HeaderDropdown from '../HeaderDropdown'; |
|||
|
|||
import type { MenuInfo } from 'rc-menu/lib/interface'; |
|||
export type GlobalHeaderRightProps = { |
|||
menu?: boolean; |
|||
children?: React.ReactNode; |
|||
}; |
|||
|
|||
export const AvatarName = () => { |
|||
const { initialState } = useModel('@@initialState'); |
|||
const { currentUser } = initialState || {}; |
|||
return <span className="anticon">{currentUser?.name}</span>; |
|||
}; |
|||
|
|||
const useStyles = createStyles(({ token }) => { |
|||
return { |
|||
action: { |
|||
display: 'flex', |
|||
height: '48px', |
|||
marginLeft: 'auto', |
|||
overflow: 'hidden', |
|||
alignItems: 'center', |
|||
padding: '0 8px', |
|||
cursor: 'pointer', |
|||
borderRadius: token.borderRadius, |
|||
'&:hover': { |
|||
backgroundColor: token.colorBgTextHover, |
|||
}, |
|||
}, |
|||
}; |
|||
}); |
|||
|
|||
export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu, children }) => { |
|||
/** |
|||
* 退出登录,并且将当前的 url 保存 |
|||
*/ |
|||
const loginOut = async () => { |
|||
const { search, pathname } = window.location; |
|||
const urlParams = new URL(window.location.href).searchParams; |
|||
/** 此方法会跳转到 redirect 参数所在的位置 */ |
|||
const redirect = urlParams.get('redirect'); |
|||
// Note: There may be security issues, please note
|
|||
if (window.location.pathname !== '/user/login' && !redirect) { |
|||
history.replace({ |
|||
pathname: '/user/login', |
|||
search: stringify({ |
|||
redirect: pathname + search, |
|||
}), |
|||
}); |
|||
} |
|||
}; |
|||
const { styles } = useStyles(); |
|||
|
|||
const { initialState, setInitialState } = useModel('@@initialState'); |
|||
|
|||
const onMenuClick = useCallback( |
|||
(event: MenuInfo) => { |
|||
const { key } = event; |
|||
if (key === 'logout') { |
|||
flushSync(() => { |
|||
setInitialState((s) => ({ ...s, currentUser: undefined })); |
|||
}); |
|||
loginOut(); |
|||
return; |
|||
} |
|||
history.push(`/account/${key}`); |
|||
}, |
|||
[setInitialState], |
|||
); |
|||
|
|||
const loading = ( |
|||
<span className={styles.action}> |
|||
<Spin |
|||
size="small" |
|||
style={{ |
|||
marginLeft: 8, |
|||
marginRight: 8, |
|||
}} |
|||
/> |
|||
</span> |
|||
); |
|||
|
|||
if (!initialState) { |
|||
return loading; |
|||
} |
|||
|
|||
const { currentUser } = initialState; |
|||
|
|||
if (!currentUser || !currentUser.name) { |
|||
return loading; |
|||
} |
|||
|
|||
const menuItems = [ |
|||
...(menu |
|||
? [ |
|||
{ |
|||
key: 'center', |
|||
icon: <UserOutlined />, |
|||
label: '个人中心', |
|||
}, |
|||
{ |
|||
key: 'settings', |
|||
icon: <SettingOutlined />, |
|||
label: '个人设置', |
|||
}, |
|||
{ |
|||
type: 'divider' as const, |
|||
}, |
|||
] |
|||
: []), |
|||
{ |
|||
key: 'logout', |
|||
icon: <LogoutOutlined />, |
|||
label: '退出登录', |
|||
}, |
|||
]; |
|||
|
|||
return ( |
|||
<HeaderDropdown |
|||
menu={{ |
|||
selectedKeys: [], |
|||
onClick: onMenuClick, |
|||
items: menuItems, |
|||
}} |
|||
> |
|||
{children} |
|||
</HeaderDropdown> |
|||
); |
|||
}; |
@ -1,30 +0,0 @@ |
|||
import { QuestionCircleOutlined } from '@ant-design/icons'; |
|||
import { SelectLang as UmiSelectLang } from '@umijs/max'; |
|||
|
|||
export type SiderTheme = 'light' | 'dark'; |
|||
|
|||
export const SelectLang = () => { |
|||
return ( |
|||
<UmiSelectLang |
|||
style={{ |
|||
padding: 4, |
|||
}} |
|||
/> |
|||
); |
|||
}; |
|||
|
|||
export const Question = () => { |
|||
return ( |
|||
<div |
|||
style={{ |
|||
display: 'flex', |
|||
height: 26, |
|||
}} |
|||
onClick={() => { |
|||
window.open('https://pro.ant.design/docs/getting-started'); |
|||
}} |
|||
> |
|||
<QuestionCircleOutlined /> |
|||
</div> |
|||
); |
|||
}; |
@ -1,12 +0,0 @@ |
|||
/** |
|||
* 这个文件作为组件的目录 |
|||
* 目的是统一管理对外输出的组件,方便分类 |
|||
*/ |
|||
/** |
|||
* 布局组件 |
|||
*/ |
|||
import Footer from './Footer'; |
|||
import { Question, SelectLang } from './RightContent'; |
|||
import { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown'; |
|||
|
|||
export { Footer, Question, SelectLang, AvatarDropdown, AvatarName }; |
@ -1,53 +0,0 @@ |
|||
html, |
|||
body, |
|||
#root { |
|||
height: 100%; |
|||
margin: 0; |
|||
padding: 0; |
|||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, |
|||
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', |
|||
'Noto Color Emoji'; |
|||
} |
|||
|
|||
.colorWeak { |
|||
filter: invert(80%); |
|||
} |
|||
|
|||
.ant-layout { |
|||
min-height: 100vh; |
|||
} |
|||
.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed { |
|||
left: unset; |
|||
} |
|||
|
|||
canvas { |
|||
display: block; |
|||
} |
|||
|
|||
body { |
|||
text-rendering: optimizeLegibility; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
ul, |
|||
ol { |
|||
list-style: none; |
|||
} |
|||
|
|||
@media (max-width: 768px) { |
|||
.ant-table { |
|||
width: 100%; |
|||
overflow-x: auto; |
|||
&-thead > tr, |
|||
&-tbody > tr { |
|||
> th, |
|||
> td { |
|||
white-space: pre; |
|||
> span { |
|||
display: block; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,91 +0,0 @@ |
|||
import { useIntl } from '@umijs/max'; |
|||
import { Button, message, notification } from 'antd'; |
|||
import defaultSettings from '../config/defaultSettings'; |
|||
|
|||
const { pwa } = defaultSettings; |
|||
const isHttps = document.location.protocol === 'https:'; |
|||
|
|||
const clearCache = () => { |
|||
// remove all caches
|
|||
if (window.caches) { |
|||
caches |
|||
.keys() |
|||
.then((keys) => { |
|||
keys.forEach((key) => { |
|||
caches.delete(key); |
|||
}); |
|||
}) |
|||
.catch((e) => console.log(e)); |
|||
} |
|||
}; |
|||
|
|||
// if pwa is true
|
|||
if (pwa) { |
|||
// Notify user if offline now
|
|||
window.addEventListener('sw.offline', () => { |
|||
message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' })); |
|||
}); |
|||
|
|||
// Pop up a prompt on the page asking the user if they want to use the latest version
|
|||
window.addEventListener('sw.updated', (event: Event) => { |
|||
const e = event as CustomEvent; |
|||
const reloadSW = async () => { |
|||
// Check if there is sw whose state is waiting in ServiceWorkerRegistration
|
|||
// https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
|
|||
const worker = e.detail && e.detail.waiting; |
|||
if (!worker) { |
|||
return true; |
|||
} |
|||
// Send skip-waiting event to waiting SW with MessageChannel
|
|||
await new Promise((resolve, reject) => { |
|||
const channel = new MessageChannel(); |
|||
channel.port1.onmessage = (msgEvent) => { |
|||
if (msgEvent.data.error) { |
|||
reject(msgEvent.data.error); |
|||
} else { |
|||
resolve(msgEvent.data); |
|||
} |
|||
}; |
|||
worker.postMessage({ type: 'skip-waiting' }, [channel.port2]); |
|||
}); |
|||
|
|||
clearCache(); |
|||
window.location.reload(); |
|||
return true; |
|||
}; |
|||
const key = `open${Date.now()}`; |
|||
const btn = ( |
|||
<Button |
|||
type="primary" |
|||
onClick={() => { |
|||
notification.destroy(key); |
|||
reloadSW(); |
|||
}} |
|||
> |
|||
{useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })} |
|||
</Button> |
|||
); |
|||
notification.open({ |
|||
message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }), |
|||
description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }), |
|||
btn, |
|||
key, |
|||
onClose: async () => null, |
|||
}); |
|||
}); |
|||
} else if ('serviceWorker' in navigator && isHttps) { |
|||
// unregister service worker
|
|||
const { serviceWorker } = navigator; |
|||
if (serviceWorker.getRegistrations) { |
|||
serviceWorker.getRegistrations().then((sws) => { |
|||
sws.forEach((sw) => { |
|||
sw.unregister(); |
|||
}); |
|||
}); |
|||
} |
|||
serviceWorker.getRegistration().then((sw) => { |
|||
if (sw) sw.unregister(); |
|||
}); |
|||
|
|||
clearCache(); |
|||
} |
@ -1,25 +0,0 @@ |
|||
import component from './bn-BD/component'; |
|||
import globalHeader from './bn-BD/globalHeader'; |
|||
import menu from './bn-BD/menu'; |
|||
import pages from './bn-BD/pages'; |
|||
import pwa from './bn-BD/pwa'; |
|||
import settingDrawer from './bn-BD/settingDrawer'; |
|||
import settings from './bn-BD/settings'; |
|||
|
|||
export default { |
|||
'navBar.lang': 'ভাষা', |
|||
'layout.user.link.help': 'সহায়তা', |
|||
'layout.user.link.privacy': 'গোপনীয়তা', |
|||
'layout.user.link.terms': 'শর্তাদি', |
|||
'app.preview.down.block': 'আপনার স্থানীয় প্রকল্পে এই পৃষ্ঠাটি ডাউনলোড করুন', |
|||
'app.welcome.link.fetch-blocks': 'সমস্ত ব্লক পান', |
|||
'app.welcome.link.block-list': |
|||
'`block` ডেভেলপমেন্ট এর উপর ভিত্তি করে দ্রুত স্ট্যান্ডার্ড, পৃষ্ঠাসমূহ তৈরি করুন।', |
|||
...globalHeader, |
|||
...menu, |
|||
...settingDrawer, |
|||
...settings, |
|||
...pwa, |
|||
...component, |
|||
...pages, |
|||
}; |
@ -1,5 +0,0 @@ |
|||
export default { |
|||
'component.tagSelect.expand': 'বিস্তৃত', |
|||
'component.tagSelect.collapse': 'সঙ্কুচিত', |
|||
'component.tagSelect.all': 'সব', |
|||
}; |
@ -1,17 +0,0 @@ |
|||
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': 'আরো দেখুন', |
|||
}; |
@ -1,52 +0,0 @@ |
|||
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': 'কোনি সম্পাদক', |
|||
}; |
@ -1,70 +0,0 @@ |
|||
export default { |
|||
'pages.layouts.userLayout.title': |
|||
'পিঁপড়া ডিজাইন হচ্ছে সিহু জেলার সবচেয়ে প্রভাবশালী ওয়েব ডিজাইনের স্পেসিফিকেশন', |
|||
'pages.login.accountLogin.tab': 'অ্যাকাউন্টে লগইন', |
|||
'pages.login.accountLogin.errorMessage': 'ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড(admin/ant.design)', |
|||
'pages.login.failure': 'লগইন ব্যর্থ হয়েছে। আবার চেষ্টা করুন!', |
|||
'pages.login.success': 'সফল লগইন!', |
|||
'pages.login.username.placeholder': 'ব্যবহারকারীর নাম: admin or user', |
|||
'pages.login.username.required': 'আপনার ব্যবহারকারীর নাম ইনপুট করুন!', |
|||
'pages.login.password.placeholder': 'পাসওয়ার্ড: ant.design', |
|||
'pages.login.password.required': 'আপনার পাসওয়ার্ড ইনপুট করুন!', |
|||
'pages.login.phoneLogin.tab': 'ফোন লগইন', |
|||
'pages.login.phoneLogin.errorMessage': 'যাচাইকরণ কোড ত্রুটি', |
|||
'pages.login.phoneNumber.placeholder': 'ফোন নম্বর', |
|||
'pages.login.phoneNumber.required': 'আপনার ফোন নম্বর ইনপুট করুন!', |
|||
'pages.login.phoneNumber.invalid': 'ফোন নম্বরটি সঠিক নয়!', |
|||
'pages.login.captcha.placeholder': 'যাচাইকরণের কোড', |
|||
'pages.login.captcha.required': 'দয়া করে ভেরিফিকেশন কোডটি ইনপুট করুন!', |
|||
'pages.login.phoneLogin.getVerificationCode': 'কোড পান', |
|||
'pages.getCaptchaSecondText': 'সেকেন্ড', |
|||
'pages.login.rememberMe': 'আমাকে মনে রাখুন', |
|||
'pages.login.forgotPassword': 'পাসওয়ার্ড ভুলে গেছেন?', |
|||
'pages.login.submit': 'প্রবেশ করুন', |
|||
'pages.login.loginWith': 'লগইন করতে পারেন:', |
|||
'pages.login.registerAccount': 'অ্যাকাউন্ট নিবন্ধন করুন', |
|||
'pages.welcome.link': 'স্বাগতম', |
|||
'pages.welcome.alertMessage': 'দ্রুত এবং শক্তিশালী ভারী শুল্ক উপাদান প্রকাশ করা হয়েছে।', |
|||
'pages.404.subTitle': 'দুঃখিত, আপনি যে পৃষ্ঠাটি দেখতে চান তা বিদ্যমান নেই।', |
|||
'pages.404.buttonText': 'প্রধান পাতায় ফিরে যান', |
|||
'pages.admin.subPage.title': 'এই পৃষ্ঠাটি কেবল অ্যাডমিন দ্বারা দেখা যাবে', |
|||
'pages.admin.subPage.alertMessage': |
|||
'UMI UI এখন প্রকাশিত হয়েছে, অভিজ্ঞতা শুরু করতে npm run ui ব্যবহার করতে স্বাগতম।', |
|||
'pages.searchTable.createForm.newRule': 'নতুন বিধি', |
|||
'pages.searchTable.updateForm.ruleConfig': 'বিধি কনফিগারেশন', |
|||
'pages.searchTable.updateForm.basicConfig': 'মৌলিক তথ্য', |
|||
'pages.searchTable.updateForm.ruleName.nameLabel': 'বিধি নাম', |
|||
'pages.searchTable.updateForm.ruleName.nameRules': 'বিধির নাম লিখুন!', |
|||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'বিধির বিবরণ', |
|||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'কমপক্ষে পাঁচটি অক্ষর লিখুন', |
|||
'pages.searchTable.updateForm.ruleDesc.descRules': |
|||
'কমপক্ষে পাঁচটি অক্ষরের একটি বিধান বিবরণ লিখুন!', |
|||
'pages.searchTable.updateForm.ruleProps.title': 'বৈশিষ্ট্য কনফিগার করুন', |
|||
'pages.searchTable.updateForm.object': 'নিরীক্ষণ অবজেক্ট', |
|||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'বিধি টেম্পলেট', |
|||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'বিধি প্রকার', |
|||
'pages.searchTable.updateForm.schedulingPeriod.title': 'সময়সূচী নির্ধারণ করুন', |
|||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'শুরুর সময়', |
|||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'একটি শুরুর সময় চয়ন করুন!', |
|||
'pages.searchTable.titleDesc': 'বর্ণনা', |
|||
'pages.searchTable.ruleName': 'বিধি নাম প্রয়োজন', |
|||
'pages.searchTable.titleCallNo': 'পরিষেবা কল সংখ্যা', |
|||
'pages.searchTable.titleStatus': 'অবস্থা', |
|||
'pages.searchTable.nameStatus.default': 'ডিফল্ট', |
|||
'pages.searchTable.nameStatus.running': 'চলমান', |
|||
'pages.searchTable.nameStatus.online': 'অনলাইন', |
|||
'pages.searchTable.nameStatus.abnormal': 'অস্বাভাবিক', |
|||
'pages.searchTable.titleUpdatedAt': 'সর্বশেষ নির্ধারিত', |
|||
'pages.searchTable.exception': 'ব্যতিক্রম জন্য কারণ লিখুন!', |
|||
'pages.searchTable.titleOption': 'অপশন', |
|||
'pages.searchTable.config': 'কনফিগারেশন', |
|||
'pages.searchTable.subscribeAlert': 'সতর্কতা সাবস্ক্রাইব করুন', |
|||
'pages.searchTable.title': 'ইনকয়েরি ফরম', |
|||
'pages.searchTable.new': 'নতুন', |
|||
'pages.searchTable.chosen': 'নির্বাচিত', |
|||
'pages.searchTable.item': 'আইটেম', |
|||
'pages.searchTable.totalServiceCalls': 'পরিষেবা কলগুলির মোট সংখ্যা', |
|||
'pages.searchTable.tenThousand': '000', |
|||
'pages.searchTable.batchDeletion': 'একসাখে ডিলিট', |
|||
'pages.searchTable.batchApproval': 'একসাখে অনুমোদন', |
|||
}; |
@ -1,7 +0,0 @@ |
|||
export default { |
|||
'app.pwa.offline': 'আপনি এখন অফলাইন', |
|||
'app.pwa.serviceworker.updated': 'নতুন সামগ্রী উপলব্ধ', |
|||
'app.pwa.serviceworker.updated.hint': |
|||
'বর্তমান পৃষ্ঠাটি পুনরায় লোড করতে দয়া করে "রিফ্রেশ" বোতাম টিপুন', |
|||
'app.pwa.serviceworker.updated.ok': 'রিফ্রেশ', |
|||
}; |
@ -1,31 +0,0 @@ |
|||
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': |
|||
'কেবল বিকাশের পরিবেশে প্যানেল শো সেট করা হচ্ছে, দয়া করে ম্যানুয়ালি সংশোধন করুন', |
|||
}; |