commit e77c77ef96d34c032a1a6b8e1b3f4d08da465426 Author: txb Date: Thu Apr 21 15:53:56 2022 +0800 初始化提交 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..dafff25 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +/lambda/ +/scripts +/config +.history +public +dist +.umi +mock +src \ 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/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9878537 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# 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 +/.vscode + +# misc +.DS_Store +npm-debug.log* +yarn-error.log + +/coverage +.idea +yarn.lock +package-lock.json +*bak +.vscode +.vs +.git +# visual studio code +.history +*.log +functions/* +.temp/** + +# umi +.umi +.umi-production + +# screenshot +screenshot +.firebase +.eslintcache + +build 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..c203078 --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,5 @@ +const fabric = require('@umijs/fabric'); + +module.exports = { + ...fabric.stylelint, +}; diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..2544773 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,139 @@ + +def getHost(){ + def remote = [:] + remote.name = 'eip' + remote.host = '10.6.1.50' + remote.user = 'root' + remote.port = 22 + remote.password = '120962839' + remote.allowAnyHosts = true + return remote +} + +pipeline{ + agent any + parameters { + choice( + description: 'EIP环境', + name: 'environment', + choices: ['dev1'] + ) + + choice( + description: '执行操作(发布|回滚)', + name: 'operation', + choices: ['develop', 'rollback'] + ) + + choice( + description: '分支名', + name: 'branchName', + choices: ['master'] + ) + + string( + name: 'tag', + defaultValue: '', + description: '版本tag' + ) + + } + + stages + { + + stage('Prepare') { + steps { + script{ + echo "1.Prepare Stage" + echo "当前环境${params.environment}" + if(params.operation=='develop') + { + checkout scm + script { + build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() + if (env.BRANCH_NAME != 'master') { + build_tag = "${env.BRANCH_NAME}-${build_tag}" + } + } + } + else{ + build_tag="${params.tag}" + } + } + } + } + stage('Test') { + steps { + script{ + echo "2.Test Stage" + } + } + + } + stage('Build') { + steps { + script{ + echo "3.Build Docker Image Stage" + if(params.operation=='develop') + { + nodejs("nodejs") { + + } + sh "npm install --unsafe-perm=true --allow-root" + sh "rm -rf ./dist/*" + sh "npm run build" + sh "docker build -t 10.2.1.24:10242/bpa/kitchenweb:${build_tag} ." + } + } + } + + } + + + + + + stage('Push') { + steps { + script{ + echo "4.Push Docker Image Stage" + withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harborPassword', usernameVariable: 'harborUser')]) { + sh "docker login -u ${harborUser} -p ${harborPassword} 10.2.1.24:10242" + if(params.operation=='develop') + { + sh "docker push 10.2.1.24:10242/bpa/kitchenweb:${build_tag}" + } + } + } + } + + + + + } + + + stage('Deploy') { + + steps { + script{ + echo "5. Deploy Stage" + // server = getHost() + // sshCommand remote: server, command: """ + // /root/eip/web/shell/linux-eipweb.install.sh eipweb ${build_tag} 80 + // """ + + sh "sed -i 's//${build_tag}/' k8s_kitchenweb.yaml" + sh "sed -i 's//${env.BRANCH_NAME}/' k8s_kitchenweb.yaml" + sh "sed -i 's//${params.environment}/' k8s_kitchenweb.yaml" + sh "kubectl apply -f k8s_kitchenweb.yaml --record" + } + + + + } + } + } + +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..27ea928 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# 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). 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..6db2c1f --- /dev/null +++ b/config/config.js @@ -0,0 +1,74 @@ +// 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, + }, + define: { + 'process.env.UMI_ENV': process.env.UMI_ENV || 'dev', + }, + layout: { + // https://umijs.org/zh-CN/plugins/plugin-layout + locale: false, + 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, + // Theme for antd: https://ant.design/docs/react/customize-theme-cn + theme: { + 'primary-color': defaultSettings.primaryColor, + }, + // 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..bcf6bec --- /dev/null +++ b/config/defaultSettings.js @@ -0,0 +1,16 @@ +const Settings = { + navTheme: 'dark', + // 拂晓蓝 + primaryColor: '#FA541C', //'#1890ff', + layout: 'side', + contentWidth: 'Fluid', + fixedHeader: false, + fixSiderbar: true, + colorWeak: false, + title: '加盟商管理系统', + pwa: false, + logo: '/logo.svg', + iconfontUrl: '', +}; + +export default Settings; diff --git a/config/oneapi.json b/config/oneapi.json new file mode 100644 index 0000000..78efb57 --- /dev/null +++ b/config/oneapi.json @@ -0,0 +1,619 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Ant Design Pro", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:44324/" + }, + { + "url": "https://localhost:44324/" + } + ], + "paths": { + "/kitchen/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" + }, + "/kitchen/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" + } + } + } + } + } + } + }, + "/kitchen/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" + }, + "/kitchen/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" + }, + "/kitchen/api/notices": { + "summary": "getNotices", + "description": "NoticeIconItem", + "get": { + "tags": [ + "api" + ], + "operationId": "getNotices", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeIconList" + } + } + } + } + } + } + }, + "/kitchen/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..6ed7f93 --- /dev/null +++ b/config/proxy.js @@ -0,0 +1,89 @@ +/** + * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 + * ------------------------------- + * 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: { + '/kitchen/api/': { + target: 'http://10.2.1.26:21527', + changeOrigin: true, + secure: false, //关闭证书验证 + pathRewrite: { + '^': '', + }, + }, + // Nginx发布的时候需要配置 + '/cos/':{ + target: 'https://hbl-test-1305371387.cos.ap-chengdu.myqcloud.com', + changeOrigin: true, + secure: false, //关闭证书验证 + pathRewrite: { + '/cos/': '/', + }, + } + }, + test: { + '/api/': { + target: 'http://localhost:7002', + changeOrigin: true, + secure: false, + pathRewrite: { + '^': '', + }, + }, + }, + pre: { + '/api/': { + target: 'http://localhost:7002', + changeOrigin: true, + secure: false, + pathRewrite: { + '^': '', + }, + }, + }, +}; +// /** +// * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 +// * ------------------------------- +// * 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: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, //关闭证书验证 +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// test: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// pre: { +// '/api/': { +// target: 'http://114.117.161.250:7002', +// changeOrigin: true, +// secure: false, +// pathRewrite: { +// '^': '', +// }, +// }, +// }, +// }; diff --git a/config/routes.js b/config/routes.js new file mode 100644 index 0000000..9ac961c --- /dev/null +++ b/config/routes.js @@ -0,0 +1,614 @@ +/** + * SYS 系统设置 + * admin 系统用户 + * erp 供应链管理 + * basic 基础信息管理 + * bill 单据管理 + * crm crm会员管理 + * franchisee 加盟商 + * srd 店铺管理 + **/ +export default [ + { + path: '/user', + layout: false, + routes: [ + { + name: '系统登录', + path: '/user/login', + component: './user/login', + access: 'k1', + }, + ], + }, + { + name: '系统管理', + icon: 'SettingOutlined', + path: '/sys', + routes: [ + { + name: '加盟商管理', + icon: 'smile', + path: '/sys/company', + component: './sys/company', + access: 'k2', + }, + { + name: '组织管理', + icon: 'smile', + path: '/sys/Org', + component: './sys/Org', + access: 'k2', + }, + { + name: '操作日志', + icon: 'smile', + path: '/sys/Log', + component: './sys/Log', + access: 'k3', + }, + { + name: '系统用户', + icon: 'smile', + path: '/sys/user', + component: './sys/user', + access: 'k4', + }, + { + name: '角色权限', + icon: 'smile', + path: '/sys/Roles', + component: './sys/Roles', + access: 'k5', + }, + { + name: '系统菜单', + icon: 'smile', + path: '/sys/Menus', + component: './sys/Menus', + access: 'k6', + }, + { + name: '字典信息', + icon: 'smile', + path: '/sys/dictionary/dictdata', + component: './sys/dictionary/dictdata', + access: 'k6', + }, + { + name: '字典类型', + icon: 'smile', + path: '/sys/dictionary/dicttype', + component: './sys/dictionary/dicttype', + access: 'k6', + }, + { + name: '系统配置', + icon: 'smile', + path: '/sys/sysSettings', + component: './sys/sysSettings', + access: 'k6', + }, + { + name: '设备管理', + icon: 'smile', + path: '/sys/storemanage', + component: './sys/storemanage', + access: 'k6', + }, + ], + }, + { + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/erp', + routes: [ + { + name: '物料信息', + icon: 'smile', + path: '/erp/basic/product', + component: './erp/basic/product', + access: 'k7', + }, + { + name: '物料单位', + icon: 'smile', + path: '/erp/basic/unit', + component: './erp/basic/unit', + access: 'k8', + }, + { + name: '物料分类', + icon: 'smile', + path: '/erp/basic/productType', + component: './erp/basic/productType', + access: 'k9', + }, + { + name: '验收入库', + icon: 'smile', + path: '/erp/Bill/ReceivingNote', + component: './erp/Bill/ReceivingNote', + access: 'k15', + }, + { + name: '采购管理', + icon: 'smile', + path: '/erp/Bill/purchaseOrder', + component: './erp/Bill/purchaseOrder', + }, + { + name: '物料库存', + icon: 'smile', + path: '/erp/stock', + component: './erp/stock', + access: 'k16', + }, + ], + }, + { + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/bom', + routes: [ + { + name: '配方管理', + icon: 'smile', + path: '/bom/manage', + component: './bom/manage', + access: 'k7', + }, + { + name: '配方下发', + icon: 'smile', + path: '/bom/push', + component: './bom/push', + access: 'k8', + }, + ], + }, + { + name: '商品管理', + icon: 'ProjectFilled', + path: '/goods', + routes: [ + { + name: '商品管理', + icon: 'smile', + path: '/goods/goods-manage', + component: './goods/goods-manage', + access: 'k10', + }, + { + name: '商品管理新', + icon: 'smile', + path: '/goods/newgoods', + component: './goods/newgoods', + access: 'k10', + }, + { + name: '商品口味', + icon: 'smile', + path: '/goods/goods-taste', + component: './goods/goods-taste', + access: 'k11', + }, + { + name: '商品小类', + icon: 'smile', + path: '/goods/goods-type-manage', + component: './goods/goods-type-manage', + access: 'k11', + }, + { + name: '商品大类', + icon: 'smile', + path: '/goods/goodsParentTypemanage', + component: './goods/goodsParentTypemanage', + access: 'k11', + }, + { + name: '商品单位', + icon: 'smile', + path: '/goods/unit', + component: './goods/unit', + access: 'k11', + }, + { + name: '商品详情', + icon: 'smile', + path: '/goods/goodsInfo', + component: './goods/goodsInfo', + access: 'k11', + }, + + + + ], + }, + + { + name: '店铺管理', + icon: 'BankFilled', + path: '/store', + routes: [ + { + name: '店铺类型', + icon: 'smile', + path: '/store/storeType', + component: './store/storeType', + access: 'k12', + }, + { + name: '店铺小票打印机', + icon: 'smile', + path: '/store/printer/Printer', + component: './store/printer/Printer', + access: 'k12', + }, + { + name: '打印机模板', + icon: 'smile', + path: '/store/printer/printerTemplate', + component: './store/printer/printerTemplate', + access: 'k12', + }, + + { + name: '店铺桌面码', + icon: 'smile', + path: '/store/storeDesktopNumber', + component: './store/storeDesktopNumber', + access: 'k12', + }, + { + name: '店铺等级', + icon: 'smile', + path: '/store/storeLevel', + component: './store/storeLevel', + access: 'k13', + }, + { + name: '店铺信息', + icon: 'smile', + path: '/store/storeInfo', + component: './store/storeInfo', + access: 'k14', + }, + { + name: '加购商品', + icon: 'smile', + path: '/store/storeAddGoodsInfo', + component: './store/storeAddGoodsInfo', + access: 'k14', + }, + { + name: '店铺商品', + icon: 'smile', + path: '/store/storeGoodsInfo', + component: './store/storeGoodsInfo', + access: 'k14', + }, + { + name: '店铺广告', + icon: 'smile', + path: '/store/storeAdvertisement', + component: './store/storeAdvertisement', + access: 'k39', + }, + ], + }, + { + name: '设备管理', + icon: 'BankFilled', + path: '/device', + routes: [ + { + name: '设备分类', + icon: 'smile', + path: '/device/deviceType', + component: './device/deviceType', + access: 'k12', + }, + { + name: '设备信息', + icon: 'smile', + path: '/device/deviceInfo', + component: './device/deviceInfo', + access: 'k14', + }, + { + name: '设备商品管理', + icon: 'smile', + path: '/device/deviceFood', + component: './device/deviceFood', + access: 'k14', + }, + { + name: '设备补货', + icon: 'smile', + path: '/device/deviceStock', + component: './device/deviceStock', + access: 'k14', + } + + + ], + }, + { + name: '积分管理', + icon: 'BankFilled', + path: '/integral', + routes: [ + { + name: '积分规则', + icon: 'smile', + path: '/integral/integralConfigure', + component: './integral/integralConfigure', + access: 'k12', + }, + ] + }, + { + name: '菜谱管理', + icon: 'BankFilled', + path: '/foodMenu', + routes: [ + { + name: '菜谱设置', + icon: 'smile', + path: '/foodMenu/foodMenuInfo', + component: './foodMenu/foodMenuInfo', + access: 'k12', + }, + { + name: '菜谱关联门店', + icon: 'smile', + path: '/foodMenu/storeFoodMenu', + component: './foodMenu/storeFoodMenu', + access: 'k14', + }, + { + name: '菜谱关联菜品', + icon: 'smile', + path: '/foodMenu/foodMenu', + component: './foodMenu/foodMenu', + access: 'k14', + } + ] + }, + { + name: '会员管理', + icon: 'UserSwitchOutlined', + path: '/member', + routes: [ + { + name: '会员信息', + icon: 'smile', + path: '/member/memberInfo', + component: './member/memberInfo', + access: 'k17', + }, + { + name: '会员标签信息', + icon: 'smile', + path: '/member/membertag', + component: './member/membertag', + access: 'k18', + }, + { + name: '会员数据分析', + icon: 'smile', + path: '/member/memberAnalysis', + component: './member/memberAnalysis', + access: 'k19', + }, + ], + }, + { + name: '活动管理', + icon: 'CarryOutOutlined', + path: '/activity', + routes: [ + { + name: '活动信息', + icon: 'smile', + path: '/activity/activityInfo', + component: './activity/activityInfo', + access: 'k20', + }, + { + name: '活动记录信息', + icon: 'smile', + path: '/activity/activityRecord', + component: './activity/activityRecord', + access: 'k21', + }, + ], + }, + { + name: '优惠券管理', + icon: 'WalletOutlined', + path: '/crm', + routes: [ + { + name: '优惠卷管理', + icon: 'smile', + path: '/crm/coupon/couponInfo', + component: './crm/coupon/couponInfo', + access: 'k22', + }, + { + name: '优惠卷批次信息', + icon: 'smile', + path: '/crm/coupon/coupon-Batch', + component: './crm/coupon/coupon-Batch', + access: 'k23', + }, + { + name: '优惠卷领取信息', + icon: 'smile', + path: '/crm/coupon/customerCoupon', + component: './crm/coupon/customerCoupon', + access: 'k24', + }, + ], + }, + { + name: '分账管理', + icon: 'RedEnvelopeOutlined', + path: '/split', + routes: [ + { + name: '分账账户管理', + icon: 'smile', + path: '/split/account', + component: './split/account', + access: 'k25', + }, + { + name: '加盟商分账方案', + icon: 'smile', + path: '/split/FranchiseePlan', + component: './split/FranchiseePlan', + access: 'k25', + }, + { + name: '分账方案管理', + icon: 'smile', + path: '/split/plan', + component: './split/plan', + access: 'k26', + }, + { + name: '分账订单管理', + icon: 'smile', + path: '/split/splitOrders', + component: './split/splitOrders', + access: 'k27', + }, + ], + }, + { + name: '退款操作', + icon: 'AccountBookOutlined', + path: '/refundment', + routes: [ + { + name: '售后申请', + icon: 'smile', + path: '/refundment/OrderAfterSales', + component: './refundment/OrderAfterSales', + access: 'k28', + }, + ], + }, + { + name: '报表统计', + icon: 'SmileOutlined', + path: '/order', + routes: [ + { + name: '订单汇总', + path: '/order/order-summary-manage', + component: './order/order-summary-manage', + access: 'k29', + }, + { + name: '订单流水', + path: '/order/order-flow-manage', + component: './order/order-flow-manage', + access: 'k30', + }, + { + name: '订单明细', + path: '/order/orderDetail', + component: './order/orderDetail', + access: 'k31', + }, + { + name: '营业日报', + path: '/order/ordersalescountbyday', + component: './order/ordersalescountbyday', + access: 'k32', + }, + { + name: '异常订单信息', + path: '/order/ExOrder', + component: './order/ExOrder', + access: 'k31', + }, + ], + }, + { + name: '库存管理', + icon: 'HddOutlined', + path: '/stockManager', + routes: [ + { + name: '其它物料入库', + path: '/stockManager/stockItem', + component: './stockManager/stockItem', + access: 'k36', + }, + { + name: '库存盘点', + path: '/stockManager/stockInventory', + component: './stockManager/stockInventory', + access: 'k37', + }, + { + name: '库存报表', + path: '/stockManager/stockReports', + component: './stockManager/stockReports', + access: 'k38', + }, + ], + }, + { + name: '财务报表', + icon: 'HddOutlined', + path: '/financereport', + routes: [ + { + name: '财务账单', + path: '/financereport/finance', + component: './financereport/finance', + access: 'k37', + }, + ], + }, + { + path: '/', + redirect: '/welcome', + }, + { + path: '/welcome', + name: 'welcome', + icon: 'smile', + component: './Welcome', + }, + { + name: 'test', + icon: 'HddOutlined', + path: '/test', + routes: [ + { + name: 'test', + path: '/test/update', + component: './test/update', + access: 'k37', + }, + { + name: 'test', + path: '/test', + component: './test', + access: 'k37', + }, + ], + }, + //什么都不要想404直接放最后 + { + component: './404', + }, +]; diff --git a/default.conf b/default.conf new file mode 100644 index 0000000..ad50602 --- /dev/null +++ b/default.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } +} + + + diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..b7f2e44 --- /dev/null +++ b/dockerfile @@ -0,0 +1,4 @@ +FROM nginx:latest +COPY ./dist /usr/share/nginx/html/ +COPY ./default.conf /etc/nginx/conf.d/ +EXPOSE 80 diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..6410cc0 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,10 @@ +module.exports = { + testURL: 'http://localhost:7002/', + testEnvironment: './tests/PuppeteerEnvironment', + 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..f2853d7 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": [ + "./src/*" + ] + } + } +} diff --git a/k8s_kitchenweb.yaml b/k8s_kitchenweb.yaml new file mode 100644 index 0000000..98fdfee --- /dev/null +++ b/k8s_kitchenweb.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kitchenweb + namespace: kube- +spec: + + selector: + matchLabels: + app: kitchenweb + replicas: 1 + template: + metadata: + labels: + app: kitchenweb + spec: + containers: + - image: 10.2.1.24:10242/bpa/kitchenweb: + imagePullPolicy: IfNotPresent + name: kitchenweb + env: + - name: branch + value: + ports: + - containerPort: 80 + protocol: TCP + volumeMounts: + - mountPath: "/etc/localtime" + name: timezone + resources: + requests: + cpu: "100m" + memory: "112Mi" + limits: + cpu: "500m" + memory: "512Mi" + volumes: + - name: timezone + hostPath: + path: /usr/share/zoneinfo/Asia/Shanghai +--- +kind: Service +apiVersion: v1 +metadata: + labels: + app: kitchenweb + name: kitchenweb + namespace: kube- +spec: + type: ClusterIP + ports: + - port: 80 + name: http + selector: + app: kitchenweb diff --git a/mock/listTableList.js b/mock/listTableList.js new file mode 100644 index 0000000..abd0748 --- /dev/null +++ b/mock/listTableList.js @@ -0,0 +1,178 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +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); + const sorter = JSON.parse(params.sorter || '{}'); + + if (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..851e8cd --- /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 /kitchen/api/notices': getNotices, +}; diff --git a/mock/route.js b/mock/route.js new file mode 100644 index 0000000..1944341 --- /dev/null +++ b/mock/route.js @@ -0,0 +1,7 @@ +export default { + '/kitchen/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..436f62d --- /dev/null +++ b/mock/user.js @@ -0,0 +1,207 @@ +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 /kitchen/api/currentUser': (req, res) => { + if (!getAccess()) { + res.status(401).send({ + data: { + isLogin: false, + }, + errorCode: '401', + errorMessage: '请先登录!', + success: true, + }); + return; + } + + res.send({ + 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 /kitchen/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 /kitchen/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 /kitchen/api/login/outLogin': (req, res) => { + access = ''; + res.send({ + data: {}, + success: true, + }); + }, + 'POST /kitchen/api/register': (req, res) => { + res.send({ + status: 'ok', + currentAuthority: 'user', + success: true, + }); + }, + 'GET /kitchen/api/500': (req, res) => { + res.status(500).send({ + timestamp: 1513932555104, + status: 500, + error: 'error', + message: 'error', + path: '/base/category/list', + }); + }, + 'GET /kitchen/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 /kitchen/api/403': (req, res) => { + res.status(403).send({ + timestamp: 1513932555104, + status: 403, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + 'GET /kitchen/api/401': (req, res) => { + res.status(401).send({ + timestamp: 1513932555104, + status: 401, + error: 'Unauthorized', + message: 'Unauthorized', + path: '/base/category/list', + }); + }, + 'GET /kitchen/api/login/captcha': getFakeCaptcha, +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..0e8815a --- /dev/null +++ b/package.json @@ -0,0 +1,120 @@ +{ + "name": "ant-design-pro", + "version": "5.0.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", + "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", + "precommit": "lint-staged", + "prettier": "prettier -c --write \"src/**/*\"", + "start": "cross-env UMI_ENV=dev umi dev", + "start:umi-ui": "HOST=0.0.0.0 UMI-UI=1 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", + "pretest": "node ./tests/beforeTest", + "test": "umi test", + "test:all": "node ./tests/run-tests.js", + "test:component": "umi test ./src/components", + "serve": "umi-serve", + "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/charts": "^1.2.14", + "@ant-design/icons": "^4.5.0", + "@ant-design/pro-card": "^1.18.0", + "@ant-design/pro-descriptions": "^1.10.0", + "@ant-design/pro-form": "^1.48.0", + "@ant-design/pro-layout": "^6.29.0", + "@ant-design/pro-list": "^1.21.37", + "@ant-design/pro-table": "^2.57.0", + "@ant-design/pro-utils": "^1.28.0", + "@umijs/route-utils": "^2.0.3", + "antd": "^4.17.0", + "axios": "^0.26.1", + "braft-editor": "^2.3.9", + "classnames": "^2.2.6", + "cos-js-sdk-v5": "^1.3.5", + "js-export-excel": "^1.1.4", + "linq": "^4.0.0", + "lodash": "^4.17.11", + "moment": "^2.25.3", + "omit.js": "^2.0.2", + "qrcode.react": "^1.0.1", + "react": "^17.0.0", + "react-dev-inspector": "^1.1.1", + "react-dom": "^17.0.0", + "react-helmet-async": "^1.0.4", + "umi": "^3.5.0", + "umi-serve": "^1.9.10" + }, + "devDependencies": { + "@ant-design/pro-cli": "^2.0.2", + "@types/express": "^4.17.0", + "@types/history": "^4.7.2", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.177", + "@types/react": "^17.0.35", + "@types/react-dom": "^17.0.0", + "@types/react-helmet": "^6.1.0", + "@umijs/fabric": "^2.6.2", + "@umijs/openapi": "^1.3.6", + "@umijs/plugin-blocks": "^2.0.5", + "@umijs/plugin-esbuild": "^1.0.1", + "@umijs/plugin-openapi": "^1.2.0", + "@umijs/preset-ant-design-pro": "^1.2.0", + "@umijs/preset-dumi": "^1.1.32", + "@umijs/preset-react": "^1.8.27", + "@umijs/preset-ui": "^2.2.9", + "@umijs/yorkie": "^2.0.3", + "carlo": "^0.9.46", + "cross-env": "^7.0.0", + "cross-port-killer": "^1.1.1", + "detect-installer": "^1.0.1", + "enzyme": "^3.11.0", + "eslint": "^8.2.0", + "express": "^4.17.1", + "gh-pages": "^3.0.0", + "jsdom-global": "^3.0.2", + "lint-staged": "^12.0.2", + "mockjs": "^1.0.1-beta3", + "prettier": "^2.3.2", + "puppeteer-core": "^11.0.0", + "stylelint": "^14.1.0", + "typescript": "^4.2.2" + }, + "engines": { + "node": ">=10.0.0" + }, + "gitHooks": { + "commit-msg": "fabric verify-commit" + } +} 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.png b/public/logo.png new file mode 100644 index 0000000..d0b98c5 Binary files /dev/null and b/public/logo.png differ diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..14d453c --- /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..530d028 --- /dev/null +++ b/src/access.js @@ -0,0 +1,50 @@ +/** + * 这里是把登录信息拿来做菜单权限控制 + * @see https://umijs.org/zh-CN/plugins/plugin-access + * */ +// permission 按钮权限标志 +// function checkPermission(currentUser:API.CurrentUser,permission:string) +// { +// return currentUser&& currentUser.data.roles.some( +// (roles)=>roles.permissions.map(permission=>permission.name).indexof(permission)>-1) +// } +export default function access(initialState) { + const { currentUser, menuData } = initialState || {}; + + return { + // k1:true, + // k2:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k2'): false, + // k3:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k3'): false, + // k4:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k4'): false, + // k5:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k5'): false, + // k6:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k6'): false, + // k7:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k7'): false, + // k8:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k8'): false, + // k9:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k9'): false, + // k10:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k10'): false, + // k11:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k11'): false, + // k12:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k12'): false, + // k13:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k13'): false, + // k14:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k14'): false, + // k15:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k15'): false, + // k16:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k16'): false, + // k17:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k17'): false, + // k18:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k18'): false, + // k19:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k19'): false, + // k20:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k20'): false, + // k21:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k21'): false, + // k22:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k22'): false, + // k23:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k23'): false, + // k24:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k24'): false, + // k25:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k25'): false, + // k26:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k26'): false, + // k27:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k27'): false, + // k28:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k28'): false, + // k29:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k29'): false, + // k30:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k30'): false, + // k31:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k31'): false, + // k32:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k32'): false, + // k33:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k33'): false, + // k34:dymicMenu!=undefined? dymicMenu.data.some(t=>t.access=='k34'): false, + }; +} diff --git a/src/app.jsx b/src/app.jsx new file mode 100644 index 0000000..97fe035 --- /dev/null +++ b/src/app.jsx @@ -0,0 +1,782 @@ +import React from 'react'; +import { PageLoading } from '@ant-design/pro-layout'; +import { notification } from 'antd'; +import { history, Link, RequestConfig } from 'umi'; +import RightContent from '@/components/RightContent'; +import Footer from '@/components/Footer'; +import * as Icon from '@ant-design/icons'; +import api from '@/services/api'; +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 currentUser = await api.queryCurrent(); + if (currentUser.data == null) { + history.push(loginPath); + } + return currentUser; + } catch (error) { + const { location } = history; // 如果没有登录,重定向到 login + console.log(location.pathname); + if (location.pathname != loginPath) { + history.push(loginPath); + } + } + + return undefined; + }; + const queryMenuData = async () => { + try { + const data = [ + + { + code:'device', + name: '设备管理', + icon: 'BankFilled', + path: '/device', + routes: [ + { + code:'deviceType', + name: '设备分类', + icon: 'smile', + path: '/device/deviceType', + component: './device/deviceType', + access: 'k12', + }, + { + code:'deviceInfo', + name: '设备信息', + icon: 'smile', + path: '/device/deviceInfo', + component: './device/deviceInfo', + access: 'k14', + }, + { + code:'deviceFood', + name: '设备商品管理', + icon: 'smile', + path: '/device/deviceFood', + component: './device/deviceFood', + access: 'k14', + } + ], + }, + { + code:'integral', + name: '积分管理', + icon: 'BankFilled', + path: '/integral', + routes: [ + { + code:'integralConfigure', + name: '积分规则', + icon: 'smile', + path: '/integral/integralConfigure', + component: './integral/integralConfigure', + access: 'k12', + },] + + }, + { + code:'foodMenu', + name: '菜谱管理', + icon: 'BankFilled', + path: '/foodMenu', + routes: [ + { + code:'foodMenuInfo', + name: '菜谱设置', + icon: 'smile', + path: '/foodMenu/foodMenuInfo', + component: './foodMenu/foodMenuInfo', + access: 'k12', + }, + { + code:'storeFoodMenu', + name: '菜谱关联门店', + icon: 'smile', + path: '/foodMenu/storeFoodMenu', + component: './foodMenu/storeFoodMenu', + access: 'k14', + }, + { + code:'foodMenu', + name: '菜谱关联菜品', + icon: 'smile', + path: '/foodMenu/foodMenu', + component: './foodMenu/foodMenu', + access: 'k14', + } + ] + }, + { + code:'sys', + name: '系统管理', + icon: 'SettingOutlined', + path: '/sys', + routes: [ + { + code:'company', + name: '加盟商管理', + icon: 'smile', + path: '/sys/company', + component: './sys/company', + access: 'k2', + }, + { + code:'Org', + name: '组织管理', + icon: 'smile', + path: '/sys/Org', + component: './sys/Org', + access: 'k2', + }, + { + code:'Log', + name: '操作日志', + icon: 'smile', + path: '/sys/Log', + component: './sys/Log', + access: 'k3', + }, + { + code:'User', + name: '系统用户', + icon: 'smile', + path: '/sys/User', + component: './sys/User', + access: 'k4', + }, + { + code:'Roles', + name: '角色权限', + icon: 'smile', + path: '/sys/Roles', + component: './sys/Roles', + access: 'k5', + }, + { + code:'Menus', + name: '系统菜单', + icon: 'smile', + path: '/sys/Menus', + component: './sys/Menus', + access: 'k6', + }, + { + code:'dictdata', + name: '字典信息', + icon: 'smile', + path: '/sys/dictionary/dictdata', + component: './sys/dictionary/dictdata', + access: 'k6', + }, + { + code:'dicttype', + name: '字典类型', + icon: 'smile', + path: '/sys/dictionary/dicttype', + component: './sys/dictionary/dicttype', + access: 'k6', + }, + { + code:'sysSettings', + name: '系统配置', + icon: 'smile', + path: '/sys/sysSettings', + component: './sys/sysSettings', + access: 'k6', + }, + ], + }, + { + code:'bom', + name: '配方管理', + icon: 'DropboxSquareFilled', + path: '/bom', + routes: [ + { + code:'bommanage', + name: '配方列表', + icon: 'smile', + path: '/bom/manage', + component: './bom/manage', + access: 'k7', + }, + ], + }, + { + code:'erp', + name: '物料管理', + icon: 'DropboxSquareFilled', + path: '/erp', + routes: [ + { + code:'product', + name: '物料信息', + icon: 'smile', + path: '/erp/basic/product', + component: './erp/basic/product', + access: 'k7', + }, + { + code:'unit', + name: '物料单位', + icon: 'smile', + path: '/erp/basic/unit', + component: './erp/basic/unit', + access: 'k8', + }, + { + code:'productType', + name: '物料分类', + icon: 'smile', + path: '/erp/basic/productType', + component: './erp/basic/productType', + access: 'k9', + }, + + ], + }, + { + code:'goods', + name: '商品管理', + icon: 'ProjectFilled', + path: '/goods', + routes: [ + { + code:'newgoods', + name: '商品管理', + icon: 'smile', + path: '/goods/newgoods', + component: './goods/newgoods', + access: 'k10', + }, + { + code:'goods-taste', + name: '商品口味', + icon: 'smile', + path: '/goods/goods-taste', + component: './goods/goods-taste', + access: 'k11', + }, + { + code:'goods-type', + name: '商品小类', + icon: 'smile', + path: '/goods/goods-type-manage', + component: './goods/goods-type-manage', + access: 'k11', + }, + { + code:'goodsbigtype', + name: '商品大类', + icon: 'smile', + path: '/goods/goodsParentTypemanage', + component: './goods/goodsParentTypemanage', + access: 'k11', + }, + { + code:'unit', + name: '商品单位', + icon: 'smile', + path: '/goods/unit', + component: './goods/unit', + access: 'k11', + }, + ], + }, + { + code:'store', + name: '店铺管理', + icon: 'BankFilled', + path: '/store', + routes: [ + { + code:'storeDesktopNumber', + name: '店铺桌面码', + icon: 'smile', + path: '/store/storeDesktopNumber', + component: './store/storeDesktopNumber', + access: 'k12', + }, + { + code:'Printer', + name: '店铺小票打印机', + icon: 'smile', + path: '/store/printer/Printer', + component: './store/printer/Printer', + access: 'k12', + }, + { + code:'printerTemplate', + name: '打印机模板', + icon: 'smile', + path: '/store/printer/printerTemplate', + component: './store/printer/printerTemplate', + access: 'k12', + }, + { + code:'storeGoodsInfo', + name: '店铺商品', + icon: 'smile', + path: '/store/storeGoodsInfo', + component: './store/storeGoodsInfo', + access: 'k14', + }, + { + code:'storeAdvertisement', + name: '店铺广告', + icon: 'smile', + path: '/store/storeAdvertisement', + component: './store/storeAdvertisement', + access: 'k39', + }, + ], + }, + { + code:'member', + name: '会员管理', + icon: 'UserSwitchOutlined', + path: '/member', + routes: [ + { + code:'memberInfo', + name: '会员信息', + icon: 'smile', + path: '/member/memberInfo', + component: './member/memberInfo', + access: 'k17', + }, + { + code:'membertag', + name: '会员标签信息', + icon: 'smile', + path: '/member/membertag', + component: './member/membertag', + access: 'k18', + }, + { + code:'memberAnalysis', + name: '会员数据分析', + icon: 'smile', + path: '/member/memberAnalysis', + component: './member/memberAnalysis', + access: 'k19', + }, + ], + }, + { + code:'activity', + name: '活动管理', + icon: 'CarryOutOutlined', + path: '/activity', + routes: [ + { + code:'activityInfo', + name: '活动信息', + icon: 'smile', + path: '/activity/activityInfo', + component: './crm/activity/activityInfo', + access: 'k20', + }, + { + code:'activityRecord', + name: '活动记录信息', + icon: 'smile', + path: '/activity/activityRecord', + component: './activity/activityRecord', + access: 'k21', + }, + ], + }, + { + code:'Coupon', + name: '优惠券管理', + icon: 'WalletOutlined', + path: '/crm', + routes: [ + { + code:'couponInfo', + name: '优惠卷管理', + icon: 'smile', + path: '/crm/Coupon/couponInfo', + component: './crm/Coupon/couponInfo', + access: 'k22', + }, + { + code:'coupon-Batch', + name: '优惠卷批次信息', + icon: 'smile', + path: '/crm/Coupon/coupon-Batch', + component: './crm/Coupon/coupon-Batch', + access: 'k23', + }, + { + code:'customerCoupon', + name: '优惠卷领取信息', + icon: 'smile', + path: '/crm/Coupon/customerCoupon', + component: './crm/Coupon/customerCoupon', + access: 'k24', + }, + ], + }, + { + code:'split', + name: '分账管理', + icon: 'RedEnvelopeOutlined', + path: '/split', + routes: [ + { + code:'account', + name: '分账账户管理', + icon: 'smile', + path: '/split/account', + component: './split/account', + access: 'k25', + }, + { + code:'FranchiseePlan', + name: '加盟商分账方案', + icon: 'smile', + path: '/split/FranchiseePlan', + component: './split/FranchiseePlan', + access: 'k25', + }, + { + code:'plan', + name: '分账方案管理', + icon: 'smile', + path: '/split/plan', + component: './split/plan', + access: 'k26', + }, + { + code:'splitOrders', + name: '分账订单管理', + icon: 'smile', + path: '/split/splitOrders', + component: './split/splitOrders', + access: 'k27', + }, + ], + }, + { + code:'refundment', + name: '退款操作', + icon: 'AccountBookOutlined', + path: '/refundment', + routes: [ + { + code:'OrderAfterSales', + name: '售后申请', + icon: 'smile', + path: '/refundment/OrderAfterSales', + component: './refundment/OrderAfterSales', + access: 'k28', + }, + ], + }, + { + code:'order', + name: '报表统计', + icon: 'SmileOutlined', + path: '/order', + routes: [ + { + code:'ordersummarymanage', + name: '订单汇总', + path: '/order/order-summary-manage', + component: './order/order-summary-manage', + access: 'k29', + }, + { + code:'orderflowmanage', + name: '订单流水', + path: '/order/order-flow-manage', + component: './order/order-flow-manage', + access: 'k30', + }, + { + code:'orderDetail', + name: '订单明细', + path: '/order/orderDetail', + component: './order/orderDetail', + access: 'k31', + }, + { + code:'ordersalescountbyday', + name: '营业日报', + path: '/order/ordersalescountbyday', + component: './order/ordersalescountbyday', + access: 'k32', + }, + { + code:'ExOrder', + name: '异常订单', + path: '/order/ExOrder', + component: './order/ExOrder', + access: 'k32', + }, + ], + }, + { + code:'stockManager', + name: '库存管理', + icon: 'HddOutlined', + path: '/stockManager', + routes: [ + { + code:'stockItem', + name: '其它物料入库', + path: '/stockManager/stockItem', + component: './stockManager/stockItem', + access: 'k36', + }, + { + code:'stockInventory', + name: '库存盘点', + path: '/stockManager/stockInventory', + component: './stockManager/stockInventory', + access: 'k37', + }, + { + code:'stockReports', + name: '库存报表', + path: '/stockManager/stockReports', + component: './stockManager/stockReports', + access: 'k38', + }, + ], + }, + { + code:'financereport', + name: '财务报表', + icon: 'HddOutlined', + path: '/financereport', + routes: [ + { + code:'finance', + name: '财务账单', + path: '/financereport/finance', + component: './financereport/finance', + access: 'k37', + }, + ], + }, + ]; + // api.queryMenus(); + return data; + } catch (error) { + history.push(loginPath); + } + return []; + }; + // 如果是登录页面,不执行 + + if (history.location.pathname !== loginPath) { + const currentUser = await fetchUserInfo(); + var tempMenu = await queryMenuData(); + //创建菜单 + // await syncMenus(tempMenu); + // if (!isDev) { + // var data = await dymicMenus(currentUser.data.id); + // tempMenu = data.data; + // } + + return { + fetchUserInfo, + currentUser, + menuData: tempMenu, + settings: {}, + }; + } + return { + fetchUserInfo, + settings: {}, + }; +} + +/** + * 同步菜单 + * @param {*} args + * @returns + */ +const syncMenus = async (args) => { + return await api.queryAndSyncMenu({ json: JSON.stringify(args) }); +}; + +/** + * 动态菜单 + * @param {*} userid + * @returns + */ + +const dymicMenus = async (userid) => { + return await api.DymicMenus(userid); +}; + +/** + * + * 动态路由 + * + */ +const loopMenuItem = (menus) => + menus?.map(({ icon, children, ...item }) => { + if (typeof icon != 'undefined' && Icon[icon] != undefined) { + return { + ...item, + icon: icon && React.createElement(Icon[icon]), + children: children && loopMenuItem(children), + }; + } else { + return { + ...item, + children: children && loopMenuItem(children), + }; + } + }); +/** + * 异常处理程序 + 200: '服务器成功返回请求的数据。', + 201: '新建或修改数据成功。', + 202: '一个请求已经进入后台排队(异步任务)。', + 204: '删除数据成功。', + 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', + 401: '用户没有权限(令牌、用户名、密码错误)。', + 403: '用户得到授权,但是访问是被禁止的。', + 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', + 405: '请求方法不被允许。', + 406: '请求的格式不可得。', + 410: '请求的资源被永久删除,且不会再得到的。', + 422: '当创建一个对象时,发生一个验证错误。', + 500: '服务器发生错误,请检查服务器。', + 502: '网关错误。', + 503: '服务不可用,服务器暂时过载或维护。', + 504: '网关超时。', + //-----English + 200: The server successfully returned the requested data. ', + 201: New or modified data is successful. ', + 202: A request has entered the background queue (asynchronous task). ', + 204: Data deleted successfully. ', + 400: 'There was an error in the request sent, and the server did not create or modify data. ', + 401: The user does not have permission (token, username, password error). ', + 403: The user is authorized, but access is forbidden. ', + 404: The request sent was for a record that did not exist. ', + 405: The request method is not allowed. ', + 406: The requested format is not available. ', + 410': + 'The requested resource is permanently deleted and will no longer be available. ', + 422: When creating an object, a validation error occurred. ', + 500: An error occurred on the server, please check the server. ', + 502: Gateway error. ', + 503: The service is unavailable. ', + 504: The gateway timed out. ', + * @see https://beta-pro.ant.design/docs/request-cn + */ +const codeMessage = { + 200: '服务器成功返回请求的数据。', + 201: '新建或修改数据成功。', + 202: '一个请求已经进入后台排队(异步任务)。', + 204: '删除数据成功。', + 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', + 401: '用户没有权限(令牌、用户名、密码错误)。', + 403: '用户得到授权,但是访问是被禁止的。', + 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', + 405: '请求方法不被允许。', + 406: '请求的格式不可得。', + 410: '请求的资源被永久删除,且不会再得到的。', + 422: '当创建一个对象时,发生一个验证错误。', + 500: '服务器发生错误,请检查服务器。', + 502: '网关错误。', + 503: '服务不可用,服务器暂时过载或维护。', + 504: '网关超时。', +}; + +export const request = { + errorHandler: (error) => { + const { response } = error; + if (response && response.status !== 200 && response.status !== 422) { + const errorText = codeMessage[response.status] || response.statusText; + const { status, url } = response; + if (response.status === 401 || response.status === 403) { + notification.error({ + description: '户没有权限(令牌、用户名、密码错误)。', + message: '网络异常', + }); + // history.push('/user/login'); + const { location } = history; // 如果没有登录,重定向到 login + if (!location.pathname.includes(loginPath)) { + history.push(loginPath); + } + } else { + notification.error({ + message: `请求错误 ${status}: ${url}`, + description: errorText, + }); + } + } + if (!response) { + notification.error({ + description: '您的网络发生异常,无法连接服务器', + message: '网络异常', + }); + } + + throw error; + }, + //prefix: `${DOMAIN}`, + requestInterceptors: [ + (url, options) => { + console.log(url); + console.log(options); + url = decodeURI(encodeURI(url).replace(/%E2%80%8B/g, '')); + const newOptions = { ...options }; + const auttoken = localStorage.getItem('token'); + const userid = localStorage.getItem('userid'); + newOptions.headers = { + ...newOptions.headers, + userid: userid, + Authorization: 'Bearer ' + auttoken, + LoginType: 1, + Accept: 'application/json', + 'Content-Type': 'application/json; charset=utf-8', + }; + return { url, options: newOptions }; + }, + ], +}; +// ProLayout 支持的api https://procomponents.ant.design/components/layout + +export const layout = ({ initialState }) => { + return { + rightContentRender: () => , + disableContentMargin: false, + waterMarkProps: { + content: '黑菠萝技术部', + }, + + footerRender: () =>