Explorar o código

新增多租户版本

ahjung %!s(int64=3) %!d(string=hai) anos
achega
16ca935eef
Modificáronse 100 ficheiros con 12500 adicións e 0 borrados
  1. 19 0
      .editorconfig
  2. 11 0
      .env
  3. 31 0
      .env.development
  4. 31 0
      .env.production
  5. 31 0
      .env.test
  6. 16 0
      .eslintignore
  7. 74 0
      .eslintrc.js
  8. 26 0
      .gitignore
  9. 9 0
      .prettierignore
  10. 3 0
      .stylelintignore
  11. 123 0
      CHANGELOG.md
  12. 79 0
      README.md
  13. 6 0
      auto-imports.d.ts
  14. 6 0
      build/constant.ts
  15. 9 0
      build/getConfigFileName.ts
  16. 44 0
      build/script/buildConf.ts
  17. 23 0
      build/script/postBuild.ts
  18. 71 0
      build/utils.ts
  19. 35 0
      build/vite/plugin/compress.ts
  20. 40 0
      build/vite/plugin/html.ts
  21. 58 0
      build/vite/plugin/index.ts
  22. 19 0
      build/vite/plugin/mock.ts
  23. 15 0
      build/vite/plugin/visualizer.ts
  24. 34 0
      build/vite/proxy.ts
  25. 57 0
      commitlint.config.js
  26. 121 0
      index.html
  27. 18 0
      mock/_createProductionServer.ts
  28. 73 0
      mock/_util.ts
  29. 96 0
      mock/comtemp/article.ts
  30. 34 0
      mock/comtemp/category.ts
  31. 52 0
      mock/comtemp/make.ts
  32. 104 0
      mock/comtemp/video.ts
  33. 44 0
      mock/dashboard/console.ts
  34. 153 0
      mock/region/region.ts
  35. 31 0
      mock/select/select.ts
  36. 149 0
      mock/system/dictionary.ts
  37. 89 0
      mock/system/menu.ts
  38. 35 0
      mock/system/region.ts
  39. 46 0
      mock/system/role.ts
  40. 43 0
      mock/table/list.ts
  41. 269 0
      mock/table/select.ts
  42. 116 0
      mock/user/menus.ts
  43. 115 0
      mock/user/user.ts
  44. 145 0
      package.json
  45. 6600 0
      pnpm-lock.yaml
  46. 6 0
      postcss.config.js
  47. 10 0
      prettier.config.js
  48. BIN=BIN
      public/favicon.ico
  49. 64 0
      src/App.vue
  50. 84 0
      src/api/article/index.ts
  51. 67 0
      src/api/auth/dept.ts
  52. 56 0
      src/api/auth/post.ts
  53. 41 0
      src/api/common/index.ts
  54. 10 0
      src/api/comtemp/article.ts
  55. 10 0
      src/api/comtemp/category.ts
  56. 10 0
      src/api/comtemp/make.ts
  57. 10 0
      src/api/comtemp/video.ts
  58. 9 0
      src/api/dashboard/console.ts
  59. 67 0
      src/api/notice/notice.ts
  60. 18 0
      src/api/region/region.ts
  61. 10 0
      src/api/select/select.ts
  62. 56 0
      src/api/system/config.ts
  63. 114 0
      src/api/system/dictionary.ts
  64. 12 0
      src/api/system/logs.ts
  65. 71 0
      src/api/system/menu.ts
  66. 96 0
      src/api/system/region.ts
  67. 77 0
      src/api/system/role.ts
  68. 56 0
      src/api/system/tasks.ts
  69. 128 0
      src/api/system/user.ts
  70. 19 0
      src/api/table/list.ts
  71. 127 0
      src/assets/icons/login.svg
  72. 60 0
      src/assets/icons/logo.svg
  73. 474 0
      src/assets/images/Business.svg
  74. 255 0
      src/assets/images/Error.svg
  75. BIN=BIN
      src/assets/images/account-logo.png
  76. 156 0
      src/assets/images/analysis.svg
  77. 100 0
      src/assets/images/exception/403.svg
  78. 115 0
      src/assets/images/exception/404.svg
  79. 111 0
      src/assets/images/exception/500.svg
  80. 133 0
      src/assets/images/exception/developing.svg
  81. 178 0
      src/assets/images/exception/load-error.svg
  82. 106 0
      src/assets/images/exception/nodata.svg
  83. 49 0
      src/assets/images/header-theme-dark.svg
  84. 10 0
      src/assets/images/login-bg.svg
  85. BIN=BIN
      src/assets/images/login-pic.png
  86. 127 0
      src/assets/images/login.svg
  87. BIN=BIN
      src/assets/images/logo.png
  88. 15 0
      src/assets/images/nav-horizontal-mix.svg
  89. 26 0
      src/assets/images/nav-horizontal.svg
  90. 49 0
      src/assets/images/nav-theme-dark.svg
  91. 49 0
      src/assets/images/nav-theme-light.svg
  92. 1 0
      src/assets/images/order_count.svg
  93. 1 0
      src/assets/images/sale.svg
  94. 43 0
      src/assets/images/sales-dashboard.svg
  95. BIN=BIN
      src/assets/images/schoolboy.png
  96. BIN=BIN
      src/assets/images/tool.png
  97. 1 0
      src/assets/images/visits.svg
  98. 1 0
      src/assets/images/volume.svg
  99. 9 0
      src/components/Application/Application.vue
  100. 0 0
      src/components/Application/index.ts

+ 19 - 0
.editorconfig

@@ -0,0 +1,19 @@
+root = true
+
+[*]
+charset=utf-8
+end_of_line=lf
+insert_final_newline=true
+indent_style=space
+indent_size=2
+max_line_length = 100
+
+[*.{yml,yaml,json}]
+indent_style = space
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab

+ 11 - 0
.env

@@ -0,0 +1,11 @@
+# port
+VITE_PORT = 8001
+
+# spa-title
+VITE_GLOB_APP_TITLE = NaiveAdminElementFull
+
+# spa shortname
+VITE_GLOB_APP_SHORT_NAME = NaiveAdminElementFull
+
+# 生产环境 开启mock
+VITE_GLOB_PROD_MOCK = true

+ 31 - 0
.env.development

@@ -0,0 +1,31 @@
+# 只在开发模式中被载入
+VITE_PORT = 8083
+
+# 网站根目录
+VITE_PUBLIC_PATH = /
+
+# 是否开启mock
+VITE_USE_MOCK = true
+
+# 网站前缀
+VITE_BASE_URL = /
+
+# 是否删除console
+VITE_DROP_CONSOLE = true
+
+# 跨域代理,可以配置多个,请注意不要换行
+#VITE_PROXY = [["/appApi","http://localhost:8001"],["/upload","http://localhost:8001/upload"]]
+# VITE_PROXY=[["/api","https://naive-ui-admin"]]
+
+# API 接口地址
+VITE_GLOB_API_URL = https://vapi.naiveadmin.com
+# VITE_GLOB_API_URL = http://192.168.3.199:8086
+
+# 图片上传地址
+VITE_GLOB_UPLOAD_URL= https://vapi.naiveadmin.com
+
+# 图片前缀地址
+VITE_GLOB_IMG_URL= https://vapi.naiveadmin.com
+
+# 接口前缀
+VITE_GLOB_API_URL_PREFIX = /api

+ 31 - 0
.env.production

@@ -0,0 +1,31 @@
+# 是否开启mock
+VITE_USE_MOCK = true
+
+# 网站根目录
+VITE_PUBLIC_PATH = /
+
+# 网站前缀
+VITE_BASE_URL = /
+
+# 是否删除console
+VITE_DROP_CONSOLE = true
+
+# API
+VITE_GLOB_API_URL = https://vapi.naiveadmin.com
+
+# 图片上传地址
+VITE_GLOB_UPLOAD_URL= https://vapi.naiveadmin.com
+
+# 图片前缀地址
+VITE_GLOB_IMG_URL= https://vapi.naiveadmin.com
+
+# 接口前缀
+VITE_GLOB_API_URL_PREFIX = /api
+
+# 是否启用gzip压缩或brotli压缩
+# 可选: gzip | brotli | none
+# 如果你需要多种形式,你可以用','来分隔
+VITE_BUILD_COMPRESS = 'none'
+
+# 使用压缩时是否删除原始文件,默认为false
+VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

+ 31 - 0
.env.test

@@ -0,0 +1,31 @@
+# 是否开启mock
+VITE_USE_MOCK = true
+
+# 网站根目录
+VITE_PUBLIC_PATH = /
+
+# 网站前缀
+VITE_BASE_URL = /
+
+# 是否删除console
+VITE_DROP_CONSOLE = true
+
+# API
+VITE_GLOB_API_URL =
+
+# 图片上传地址
+VITE_GLOB_UPLOAD_URL =
+
+# 图片前缀地址
+VITE_GLOB_IMG_URL =
+
+# 接口前缀
+VITE_GLOB_API_URL_PREFIX = /api
+
+# 是否启用gzip压缩或brotli压缩
+# 可选: gzip | brotli | none
+# 如果你需要多种形式,你可以用','来分隔
+VITE_BUILD_COMPRESS = 'none'
+
+# 使用压缩时是否删除原始文件,默认为false
+VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false

+ 16 - 0
.eslintignore

@@ -0,0 +1,16 @@
+
+*.sh
+node_modules
+*.md
+*.woff
+*.ttf
+.vscode
+.idea
+dist
+/public
+/docs
+.husky
+.local
+/bin
+Dockerfile
+components.d.ts

+ 74 - 0
.eslintrc.js

@@ -0,0 +1,74 @@
+module.exports = {
+  root: true,
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  parser: 'vue-eslint-parser',
+  parserOptions: {
+    parser: '@typescript-eslint/parser',
+    ecmaVersion: 2020,
+    sourceType: 'module',
+    jsxPragma: 'React',
+    ecmaFeatures: {
+      jsx: true,
+    },
+  },
+  extends: [
+    'plugin:vue/vue3-recommended',
+    'plugin:@typescript-eslint/recommended',
+    'plugin:prettier/recommended',
+  ],
+  rules: {
+    'vue/script-setup-uses-vars': 'error',
+    '@typescript-eslint/ban-ts-ignore': 'off',
+    '@typescript-eslint/explicit-function-return-type': 'off',
+    '@typescript-eslint/no-explicit-any': 'off',
+    '@typescript-eslint/no-var-requires': 'off',
+    '@typescript-eslint/no-empty-function': 'off',
+    'vue/custom-event-name-casing': 'off',
+    'no-use-before-define': 'off',
+    '@typescript-eslint/no-use-before-define': 'off',
+    '@typescript-eslint/ban-ts-comment': 'off',
+    '@typescript-eslint/ban-types': 'off',
+    '@typescript-eslint/no-non-null-assertion': 'off',
+    '@typescript-eslint/explicit-module-boundary-types': 'off',
+    '@typescript-eslint/no-unused-vars': [
+      'error',
+      {
+        argsIgnorePattern: '^_',
+        varsIgnorePattern: '^_',
+      },
+    ],
+    'no-unused-vars': [
+      'error',
+      {
+        argsIgnorePattern: '^_',
+        varsIgnorePattern: '^_',
+      },
+    ],
+    'space-before-function-paren': 'off',
+    'vue/multi-word-component-names': 'off',
+    'vue/attributes-order': 'off',
+    'vue/one-component-per-file': 'off',
+    'vue/html-closing-bracket-newline': 'off',
+    'vue/max-attributes-per-line': 'off',
+    'vue/multiline-html-element-content-newline': 'off',
+    'vue/singleline-html-element-content-newline': 'off',
+    'vue/attribute-hyphenation': 'off',
+    'vue/require-default-prop': 'off',
+    'vue/html-self-closing': [
+      'error',
+      {
+        html: {
+          void: 'always',
+          normal: 'never',
+          component: 'always',
+        },
+        svg: 'always',
+        math: 'always',
+      },
+    ],
+  },
+};

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+.DS_Store
+node_modules
+/screenshots
+/dist
+dist.zip
+dist_electron
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+/components.d.ts

+ 9 - 0
.prettierignore

@@ -0,0 +1,9 @@
+/dist/*
+.local
+.output.js
+/node_modules/**
+
+**/*.svg
+**/*.sh
+
+/public/*

+ 3 - 0
.stylelintignore

@@ -0,0 +1,3 @@
+/dist/*
+/public/*
+public/*

+ 123 - 0
CHANGELOG.md

@@ -0,0 +1,123 @@
+# CHANGELOG
+
+## Pending
+
+## 1.3.4 (2022-12-12)
+
+- 🌟 新增 `env.test` 环境打包配置
+- 🌟 新增 `rollup-plugin-visualizer` 打包分析插件支持
+- 🌟 增强 `menuSetting` 配置灵活性
+- 💎 移除 `lodash` 统一使用 `lodash-es` 版本
+- 🐞 修复 `TableSelect` 组件,分页查询参数丢失
+- 🌟 新增 `TableSelect` 导出 `getFormValues` 方法
+- 🌟 新增 `TableSelect` 支持 `form-values-change` BasicForm 变动回调
+- `依赖升级`
+
+## 1.3.3 (2022-11-16)
+
+- 💎 优化 `使用官方黑暗模式` 样式
+- 💎 优化 `BasicForm` 样式
+- 🌟 新增 `BasicForm` 支持 `field` 参数支持 `a.b.c` 语法
+- 🌟 增强 `TableSelect` 组件,支持分页多选
+- 🐞 修复 `多页签` 设置未完成状态,不显示
+- 🐞 修复 `修复ts类型` 错误
+- `依赖升级`
+
+## 1.3.2 (2022-09-13)
+
+- 🌟 升级 `vite` 支持 `3.x`
+- `依赖升级`
+
+## 1.3.1
+
+- 🌟 增强 `FormSchema` 配置,支持更多属性
+- 🐞 修复 `BasicTable` 可编辑状态显示异常
+- 🐞 修复 `修复ts类型` 错误
+- `依赖升级`
+
+## 1.3.0 
+
+- ✨ 同步 `Naive admin Pro` 版本功能
+- 🌟 新增 `meta.documentTitle` 网页标题 优先 title 字段
+- 🌟 新增 `meta.title` 支持定制 `Render` `多页签` `面包屑` 同步渲染
+- 🌟 新增 `meta.breadcrumbView` 配置,是否显示在面包屑中
+- 🌟 新增 `meta.tagView` 配置,是否显示在多页签中
+- 🌟 新增 `meta.authEvery` 是否验证每一个权限都包含
+- 🌟 新增 `BasicTable` 表格列支持 `draggable` 配置是可拖拽
+- 🌟 新增 `BasicTable` 拖拽列 `columns-change` 方法
+- 🌟 新增 `TableSetting` 支持 `宽度配置` 且支持最大高度滚动
+- 🌟 新增 `basicModal` 支持 `prefixFooter` `centerFooter` `suffixFooter` 插槽,用于定制其他元素
+- 🌟 新增 `basicModal` 导出 `handleSubmit` 方法
+- 🌟 新增 `Authority` 权限控制组件
+- 🐞 修复 `修复ts类型` 错误
+
+## 1.2.2
+
+- 🌟 新增 `tableSelect` 组件支持 `v-model`
+- 🌟 新增 `Region` 支持配置 `labelField` 和 `valueField` 属性
+- 🐞 修复 `activeMenu` 路由配置,刷新浏览器之后失效
+- `依赖升级`
+
+## 1.2.1 
+
+### ✨ 新增功能
+- 新增 `Password` 组件支持 `v-model`
+- `依赖升级`
+
+### 🐛 Bug Fixes
+- 修复 `permission` 指令 `disabled` 类名错误
+- 修复 `actionColumn` 配置更多 `下拉菜单` 打包后不展示问题
+- 修复 `BasicTable` 当没有分页 `自动计算` 最大高度错误
+
+## 1.2.0 (2022-06-02)
+
+### ✨ 优化
+- 升级 `element-plus` 至 `2.2.2`
+- 升级 `vite-plugin-html` 插件
+- 升级 `xlsx` 插件
+- `其他依赖升级`
+
+### 🐛 Bug Fixes
+- 修复 `BasicForm` 隐藏表单,存在占位问题
+- 修复 `BasicModal` 组件`api`变动问题
+
+## 1.1.0 (2022-04-29)
+### ✨ 新增功能
+- 新增 `表格选择器` 组件(beta)
+- 新增 `BasicForm` 支持 `BasicSelect` 组件,示例在:组件-表单-基础使用 
+- 新增 `BasicTable` 导出 `getTableRef` 方法,用于调用组件原生事件
+
+### 🐛 Bug Fixes
+- 修复 `开发环境` 运行控制台错误提示
+
+### 💻  新增页面
+- 新增 `表格选择器` 示例
+- `依赖升级`
+
+## 1.0.1 (2022-03-24)
+
+### ✨ 新增功能
+- 新增 `顶部加载进度条` 可跟随主题变化
+- 新增 `按需加载示例` 可根据自身情况使用
+
+💎 代码优化
+- 删除 `废弃文件夹和代码`
+
+🐛 问题修复
+- 修正 `Axios` 中 `message` 调用
+
+## 1.0.0 (2022-03-22)
+
+## 💄 发布 Element Plus. 2.x 版本
+### ✨ 新增功能
+- 🔥🔥🔥 `支持黑暗主题` 一键切换
+- 🔥🔥🔥 `任意主题色` 随意切换
+- 🔥🔥🔥 `全新重构` script setup 语法,源码更加易读,性能更优 `ts` 类型更加全面
+
+### ✨ 新增页面
+
+- 新增 `三个常用模板` 页面
+
+### 💻 页面 | 🏷️ 功能 | 📦 组件
+- 和 `NaiveAdmin` 版本一致
+- ✍️ 持续更新迭代中

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 79 - 0
README.md


+ 6 - 0
auto-imports.d.ts

@@ -0,0 +1,6 @@
+// Generated by 'unplugin-auto-import'
+// We suggest you to commit this file into source control
+declare global {
+
+}
+export {}

+ 6 - 0
build/constant.ts

@@ -0,0 +1,6 @@
+/**
+ * The name of the configuration file entered in the production environment
+ */
+export const GLOB_CONFIG_FILE_NAME = 'app.config.js';
+
+export const OUTPUT_DIR = 'dist';

+ 9 - 0
build/getConfigFileName.ts

@@ -0,0 +1,9 @@
+/**
+ * Get the configuration file variable name
+ * @param env
+ */
+export const getConfigFileName = (env: Record<string, any>) => {
+  return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
+    .toUpperCase()
+    .replace(/\s/g, '');
+};

+ 44 - 0
build/script/buildConf.ts

@@ -0,0 +1,44 @@
+/**
+ * Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
+ */
+import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant';
+import fs, { writeFileSync } from 'fs-extra';
+import chalk from 'chalk';
+
+import { getRootPath, getEnvConfig } from '../utils';
+import { getConfigFileName } from '../getConfigFileName';
+
+import pkg from '../../package.json';
+
+function createConfig(
+  {
+    configName,
+    config,
+    configFileName = GLOB_CONFIG_FILE_NAME,
+  }: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} }
+) {
+  try {
+    const windowConf = `window.${configName}`;
+    // Ensure that the variable will not be modified
+    const configStr = `${windowConf}=${JSON.stringify(config)};
+      Object.freeze(${windowConf});
+      Object.defineProperty(window, "${configName}", {
+        configurable: false,
+        writable: false,
+      });
+    `.replace(/\s/g, '');
+    fs.mkdirp(getRootPath(OUTPUT_DIR));
+    writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr);
+
+    console.log(chalk.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`);
+    console.log(chalk.gray(OUTPUT_DIR + '/' + chalk.green(configFileName)) + '\n');
+  } catch (error) {
+    console.log(chalk.red('configuration file configuration file failed to package:\n' + error));
+  }
+}
+
+export function runBuildConfig() {
+  const config = getEnvConfig();
+  const configFileName = getConfigFileName(config);
+  createConfig({ config, configName: configFileName });
+}

+ 23 - 0
build/script/postBuild.ts

@@ -0,0 +1,23 @@
+// #!/usr/bin/env node
+
+import { runBuildConfig } from './buildConf';
+import chalk from 'chalk';
+
+import pkg from '../../package.json';
+
+export const runBuild = async () => {
+  try {
+    const argvList = process.argv.splice(2);
+
+    // Generate configuration file
+    if (!argvList.includes('disabled-config')) {
+      await runBuildConfig();
+    }
+
+    console.log(`✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
+  } catch (error) {
+    console.log(chalk.red('vite build error:\n' + error));
+    process.exit(1);
+  }
+};
+runBuild();

+ 71 - 0
build/utils.ts

@@ -0,0 +1,71 @@
+import fs from 'fs';
+import path from 'path';
+import dotenv from 'dotenv';
+
+export function isDevFn(mode: string): boolean {
+  return mode === 'development';
+}
+
+export function isProdFn(mode: string): boolean {
+  return mode === 'production';
+}
+
+/**
+ * Whether to generate package preview
+ */
+export function isReportMode(): boolean {
+  return process.env.REPORT === 'true';
+}
+
+// Read all environment variable configuration files to process.env
+export function wrapperEnv(envConf: Recordable): ViteEnv {
+  const ret: any = {};
+
+  for (const envName of Object.keys(envConf)) {
+    let realName = envConf[envName].replace(/\\n/g, '\n');
+    realName = realName === 'true' ? true : realName === 'false' ? false : realName;
+
+    if (envName === 'VITE_PORT') {
+      realName = Number(realName);
+    }
+    if (envName === 'VITE_PROXY') {
+      try {
+        realName = JSON.parse(realName);
+      } catch (error) {}
+    }
+    ret[envName] = realName;
+    process.env[envName] = realName;
+  }
+  return ret;
+}
+
+/**
+ * Get the environment variables starting with the specified prefix
+ * @param match prefix
+ * @param confFiles ext
+ */
+export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.production']) {
+  let envConfig = {};
+  confFiles.forEach((item) => {
+    try {
+      const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
+      envConfig = { ...envConfig, ...env };
+    } catch (error) {}
+  });
+
+  Object.keys(envConfig).forEach((key) => {
+    const reg = new RegExp(`^(${match})`);
+    if (!reg.test(key)) {
+      Reflect.deleteProperty(envConfig, key);
+    }
+  });
+  return envConfig;
+}
+
+/**
+ * Get user root directory
+ * @param dir file path
+ */
+export function getRootPath(...dir: string[]) {
+  return path.resolve(process.cwd(), ...dir);
+}

+ 35 - 0
build/vite/plugin/compress.ts

@@ -0,0 +1,35 @@
+/**
+ * Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
+ * https://github.com/anncwb/vite-plugin-compression
+ */
+import type { Plugin } from 'vite';
+
+import compressPlugin from 'vite-plugin-compression';
+
+export function configCompressPlugin(
+  compress: 'gzip' | 'brotli' | 'none',
+  deleteOriginFile = false
+): Plugin | Plugin[] {
+  const compressList = compress.split(',');
+
+  const plugins: Plugin[] = [];
+
+  if (compressList.includes('gzip')) {
+    plugins.push(
+      compressPlugin({
+        ext: '.gz',
+        deleteOriginFile,
+      })
+    );
+  }
+  if (compressList.includes('brotli')) {
+    plugins.push(
+      compressPlugin({
+        ext: '.br',
+        algorithm: 'brotliCompress',
+        deleteOriginFile,
+      })
+    );
+  }
+  return plugins;
+}

+ 40 - 0
build/vite/plugin/html.ts

@@ -0,0 +1,40 @@
+/**
+ * Plugin to minimize and use ejs template syntax in index.html.
+ * https://github.com/anncwb/vite-plugin-html
+ */
+ import type { PluginOption } from 'vite';
+ import { createHtmlPlugin } from 'vite-plugin-html';
+ import pkg from '../../../package.json';
+ import { GLOB_CONFIG_FILE_NAME } from '../../constant';
+ 
+ export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
+   const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env;
+ 
+   const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`;
+ 
+   const getAppConfigSrc = () => {
+     return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`;
+   };
+ 
+   const htmlPlugin: PluginOption[] = createHtmlPlugin({
+     minify: isBuild,
+     inject: {
+       // Inject data into ejs template
+       data: {
+         title: VITE_GLOB_APP_TITLE,
+       },
+       // Embed the generated app.config.js file
+       tags: isBuild
+         ? [
+             {
+               tag: 'script',
+               attrs: {
+                 src: getAppConfigSrc(),
+               },
+             },
+           ]
+         : [],
+     },
+   });
+   return htmlPlugin;
+ }

+ 58 - 0
build/vite/plugin/index.ts

@@ -0,0 +1,58 @@
+import type { PluginOption } from 'vite';
+
+import vue from '@vitejs/plugin-vue';
+import vueJsx from '@vitejs/plugin-vue-jsx';
+import VueSetupExtend from 'vite-plugin-vue-setup-extend';
+// 自动按需导入,根据自身情况选择
+// import AutoImport from 'unplugin-auto-import/vite';
+// import Components from 'unplugin-vue-components/vite';
+// import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
+// import Components from 'unplugin-vue-components/vite';
+// import ElementPlus from 'unplugin-element-plus/vite';
+
+import { configHtmlPlugin } from './html';
+import { configMockPlugin } from './mock';
+import { configCompressPlugin } from './compress';
+import { configVisualizerPlugin } from './visualizer';
+
+export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, prodMock) {
+  const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;
+
+  const vitePlugins: (PluginOption | PluginOption[])[] = [
+    // have to
+    vue(),
+    // have to
+    vueJsx(),
+    VueSetupExtend(),
+    // ElementPlus({
+    //   // 引入的样式的类型,可以是css、sass、less等,
+    //   importStyle: 'sass',
+    //   useSource: true,
+    // }),
+    // 按需引入element且自动创建组件声明
+    // AutoImport({
+    //   resolvers: [ElementPlusResolver()],
+    // }),
+    // Components({
+    //   resolvers: [ElementPlusResolver()],
+    // }),
+  ];
+
+  // vite-plugin-html
+  vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));
+
+  // vite-plugin-mock
+  VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild, prodMock));
+
+  // rollup-plugin-visualizer
+  vitePlugins.push(configVisualizerPlugin());
+
+  if (isBuild) {
+    // rollup-plugin-gzip
+    vitePlugins.push(
+      configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
+    );
+  }
+
+  return vitePlugins;
+}

+ 19 - 0
build/vite/plugin/mock.ts

@@ -0,0 +1,19 @@
+/**
+ * Mock plugin for development and production.
+ * https://github.com/anncwb/vite-plugin-mock
+ */
+import { viteMockServe } from 'vite-plugin-mock';
+
+export function configMockPlugin(isBuild: boolean, prodMock: boolean) {
+  return viteMockServe({
+    ignore: /^\_/,
+    mockPath: 'mock',
+    localEnabled: !isBuild,
+    prodEnabled: isBuild && prodMock,
+    injectCode: `
+       import { setupProdMockServer } from '../mock/_createProductionServer';
+ 
+       setupProdMockServer();
+       `,
+  });
+}

+ 15 - 0
build/vite/plugin/visualizer.ts

@@ -0,0 +1,15 @@
+import { PluginOption } from 'vite';
+import visualizer from 'rollup-plugin-visualizer';
+import { isReportMode } from '../../utils';
+
+export function configVisualizerPlugin() {
+  if (isReportMode()) {
+    return visualizer({
+      filename: './node_modules/.cache/visualizer/stats.html',
+      open: true,
+      gzipSize: true,
+      brotliSize: true,
+    }) as PluginOption;
+  }
+  return [];
+}

+ 34 - 0
build/vite/proxy.ts

@@ -0,0 +1,34 @@
+/**
+ * Used to parse the .env.development proxy configuration
+ */
+import type { ProxyOptions } from 'vite';
+
+type ProxyItem = [string, string];
+
+type ProxyList = ProxyItem[];
+
+type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>;
+
+const httpsRE = /^https:\/\//;
+
+/**
+ * Generate proxy
+ * @param list
+ */
+export function createProxy(list: ProxyList = []) {
+  const ret: ProxyTargetList = {};
+  for (const [prefix, target] of list) {
+    const isHttps = httpsRE.test(target);
+
+    // https://github.com/http-party/node-http-proxy#options
+    ret[prefix] = {
+      target: target,
+      changeOrigin: true,
+      ws: true,
+      rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
+      // https is require secure=false
+      ...(isHttps ? { secure: false } : {}),
+    };
+  }
+  return ret;
+}

+ 57 - 0
commitlint.config.js

@@ -0,0 +1,57 @@
+module.exports = {
+  ignores: [(commit) => commit.includes('init')],
+  extends: ['@commitlint/config-conventional'],
+  parserPreset: {
+    parserOpts: {
+      headerPattern: /^(\w*|[\u4e00-\u9fa5]*)(?:[\(\(](.*)[\)\)])?[\:\:] (.*)/,
+      headerCorrespondence: ['type', 'scope', 'subject'],
+      referenceActions: [
+        'close',
+        'closes',
+        'closed',
+        'fix',
+        'fixes',
+        'fixed',
+        'resolve',
+        'resolves',
+        'resolved'
+      ],
+      issuePrefixes: ['#'],
+      noteKeywords: ['BREAKING CHANGE'],
+      fieldPattern: /^-(.*?)-$/,
+      revertPattern: /^Revert\s"([\s\S]*)"\s*This reverts commit (\w*)\./,
+      revertCorrespondence: ['header', 'hash'],
+      warn() {},
+      mergePattern: null,
+      mergeCorrespondence: null
+    }
+  },
+  rules: {
+    'body-leading-blank': [2, 'always'],
+    'footer-leading-blank': [1, 'always'],
+    'header-max-length': [2, 'always', 108],
+    'subject-empty': [2, 'never'],
+    'type-empty': [2, 'never'],
+    'type-enum': [
+      2,
+      'always',
+      [
+        'feat',
+        'fix',
+        'perf',
+        'style',
+        'docs',
+        'test',
+        'refactor',
+        'build',
+        'ci',
+        'chore',
+        'revert',
+        'wip',
+        'workflow',
+        'types',
+        'release'
+      ]
+    ]
+  }
+}

+ 121 - 0
index.html

@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html lang="zh-cmn-Hans" id="htmlRoot" data-theme="light">
+<head>
+  <meta charset="UTF-8">
+  <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
+  <meta content="webkit" name="renderer"/>
+  <meta
+    content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
+    name="viewport"
+  />
+  <link href="/favicon.ico" rel="icon"/>
+  <title><%= title %></title>
+</head>
+<body>
+<div id="app">
+  <style>
+  .first-loading-wrap {
+    display: flex;
+    width: 100%;
+    height: 100vh;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+  }
+
+  .first-loading-wrap > h1 {
+    font-size: 128px
+  }
+
+  .first-loading-wrap .loading-wrap {
+    padding: 98px;
+    display: flex;
+    justify-content: center;
+    align-items: center
+  }
+
+  .dot {
+    animation: antRotate 1.2s infinite linear;
+    transform: rotate(45deg);
+    position: relative;
+    display: inline-block;
+    font-size: 32px;
+    width: 32px;
+    height: 32px;
+    box-sizing: border-box
+  }
+
+  .dot i {
+    width: 14px;
+    height: 14px;
+    position: absolute;
+    display: block;
+    background-color: #1890ff;
+    border-radius: 100%;
+    transform: scale(.75);
+    transform-origin: 50% 50%;
+    opacity: .3;
+    animation: antSpinMove 1s infinite linear alternate
+  }
+
+  .dot i:nth-child(1) {
+    top: 0;
+    left: 0
+  }
+
+  .dot i:nth-child(2) {
+    top: 0;
+    right: 0;
+    -webkit-animation-delay: .4s;
+    animation-delay: .4s
+  }
+
+  .dot i:nth-child(3) {
+    right: 0;
+    bottom: 0;
+    -webkit-animation-delay: .8s;
+    animation-delay: .8s
+  }
+
+  .dot i:nth-child(4) {
+    bottom: 0;
+    left: 0;
+    -webkit-animation-delay: 1.2s;
+    animation-delay: 1.2s
+  }
+
+  @keyframes antRotate {
+    to {
+      -webkit-transform: rotate(405deg);
+      transform: rotate(405deg)
+    }
+  }
+
+  @-webkit-keyframes antRotate {
+    to {
+      -webkit-transform: rotate(405deg);
+      transform: rotate(405deg)
+    }
+  }
+
+  @keyframes antSpinMove {
+    to {
+      opacity: 1
+    }
+  }
+
+  @-webkit-keyframes antSpinMove {
+    to {
+      opacity: 1
+    }
+  }</style>
+  <div class="first-loading-wrap">
+    <div class="loading-wrap">
+      <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
+    </div>
+  </div>
+</div>
+<script>var globalThis = window;</script> 
+<script src="/src/main.ts" type="module"></script>
+</body>
+</html>

+ 18 - 0
mock/_createProductionServer.ts

@@ -0,0 +1,18 @@
+import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
+
+const modules: any = import.meta.glob('./**/*.ts', { eager: true });
+
+const mockModules: any[] = [];
+Object.keys(modules).forEach((key) => {
+  if (key.includes('/_')) {
+    return;
+  }
+  mockModules.push(...modules[key].default);
+});
+
+/**
+ * Used in a production environment. Need to manually import all modules
+ */
+export function setupProdMockServer() {
+  createProdMockServer(mockModules);
+}

+ 73 - 0
mock/_util.ts

@@ -0,0 +1,73 @@
+import Mock from 'mockjs';
+
+export function resultSuccess(result, { message = 'ok' } = {}) {
+  return Mock.mock({
+    code: 200,
+    result,
+    message,
+    type: 'success',
+  });
+}
+
+export function resultPageSuccess<T = any>(
+  page: number,
+  pageSize: number,
+  list: T[],
+  { message = 'ok' } = {},
+) {
+  const pageData = pagination(page, pageSize, list);
+
+  return {
+    ...resultSuccess({
+      page,
+      pageSize,
+      pageCount: list.length,
+      list: pageData,
+    }),
+    message,
+  };
+}
+
+export function resultError(message = 'Request failed', { code = -1, result = null } = {}) {
+  return {
+    code,
+    result,
+    message,
+    type: 'error',
+  };
+}
+
+export function pagination<T = any>(pageNo: number, pageSize: number, array: T[]): T[] {
+  const offset = (pageNo - 1) * Number(pageSize);
+  const ret =
+    offset + Number(pageSize) >= array.length
+      ? array.slice(offset, array.length)
+      : array.slice(offset, offset + Number(pageSize));
+  return ret;
+}
+
+/**
+ * @param {Number} times 回调函数需要执行的次数
+ * @param {Function} callback 回调函数
+ */
+export function doCustomTimes(times: number, callback: any) {
+  let i = -1;
+  while (++i < times) {
+    callback(i);
+  }
+}
+
+export interface requestParams {
+  method: string;
+  body: any;
+  headers?: { token?: string };
+  query: any;
+}
+
+/**
+ * @description 本函数用于从request数据中获取token,请根据项目的实际情况修改
+ *
+ */
+export function getRequestToken({ headers }: requestParams): string | undefined {
+  return headers?.token;
+}

+ 96 - 0
mock/comtemp/article.ts

@@ -0,0 +1,96 @@
+import { Random } from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const avatarList = [
+  'https://img.naiveadmin.com/assets/avatar/avatar-1.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-2.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-3.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-4.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-5.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-6.jpg',
+];
+
+const coverList = [
+  'https://img.naiveadmin.com/assets/article/1.jpeg',
+  'https://img.naiveadmin.com/assets/article/2.jpeg',
+  'https://img.naiveadmin.com/assets/article/3.jpeg',
+  'https://img.naiveadmin.com/assets/article/4.jpg',
+  'https://img.naiveadmin.com/assets/article/5.jpeg',
+  'https://img.naiveadmin.com/assets/article/6.jpeg',
+  'https://img.naiveadmin.com/assets/article/7.jpeg',
+  'https://img.naiveadmin.com/assets/article/8.jpeg',
+  'https://img.naiveadmin.com/assets/article/9.jpeg',
+  'https://img.naiveadmin.com/assets/article/10.jpeg',
+];
+
+const articleList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      title: Random.csentence(),
+      tags: getRandomArrayElements(
+        [
+          '有限理性',
+          '智商',
+          '情绪智力',
+          '心理理论',
+          '多动症',
+          '抑郁症',
+          '梦的解析',
+          '催眠',
+          '投射测验',
+          '习惯化范式',
+        ],
+        2,
+        4,
+      ),
+      summary: Random.cparagraph(),
+      avatar: Random.pick(avatarList),
+      cover: Random.pick(coverList),
+      author: '@cname()',
+      collection: Random.natural(10, 999),
+      like: Random.natural(10, 999),
+      comment: Random.natural(10, 999),
+      date: `@date('yyyy-MM-dd')`,
+      'no|100000-10000000': 100000,
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/article/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 1 } = query;
+      const list = articleList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 60,
+        itemCount: 60 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];
+
+//从数组中取出指定个数的元素
+function getRandomArrayElements(arr, start, end) {
+  const count = Math.floor(Math.random() * (end - start) + start);
+  const shuffled = arr.slice(0);
+  let i = arr.length;
+  const min = i - count;
+  let temp: any;
+  let index: number;
+  while (i-- > min) {
+    index = Math.floor((i + 1) * Math.random());
+    temp = shuffled[index];
+    shuffled[index] = shuffled[i];
+    shuffled[i] = temp;
+  }
+  return shuffled.slice(min);
+}

+ 34 - 0
mock/comtemp/category.ts

@@ -0,0 +1,34 @@
+import { Random } from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const categoryList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      'no|100000-10000000': 100000,
+      name: `分类${Random.cword('零一二三四五六七八九十')}`,
+    });
+  });
+  return result;
+};
+
+export default [
+  //分类列表
+  {
+    url: '/api/category/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 30 } = query;
+      const list = categoryList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 60,
+        itemCount: 60 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 52 - 0
mock/comtemp/make.ts

@@ -0,0 +1,52 @@
+import { Random } from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const avatarList = [
+  'https://img.naiveadmin.com/assets/avatar/avatar-1.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-2.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-3.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-4.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-5.jpg',
+  'https://img.naiveadmin.com/assets/avatar/avatar-6.jpg',
+];
+
+const makeList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      doctor: '@cname()',
+      avatar: Random.pick(avatarList),
+      subject: Random.pick([
+        '中医内科',
+        '中医外科',
+        '中医儿科',
+        '中医妇科',
+        '中医针灸科',
+        '中医五官科',
+        '中医骨伤科',
+      ]),
+      date: Random.datetime(),
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/make/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 1 } = query;
+      const list = makeList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 60,
+        itemCount: 60 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 104 - 0
mock/comtemp/video.ts

@@ -0,0 +1,104 @@
+import { Random } from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const avatargroupList = [
+  {
+    name: '张三',
+    src: 'https://img.naiveadmin.com/assets/avatar/avatar-1.jpg',
+  },
+  {
+    name: '李四',
+    src: 'https://img.naiveadmin.com/assets/avatar/avatar-2.jpg',
+  },
+  {
+    name: '王五',
+    src: 'https://img.naiveadmin.com/assets/avatar/avatar-3.jpg',
+  },
+  {
+    name: '赵六',
+    src: 'https://img.naiveadmin.com/assets/avatar/avatar-4.jpg',
+  },
+  {
+    name: '七仔',
+    src: 'https://img.naiveadmin.com/assets/avatar/avatar-5.jpg',
+  },
+];
+
+const coverList = [
+  'https://img.naiveadmin.com/assets/article/1.jpeg',
+  'https://img.naiveadmin.com/assets/article/2.jpeg',
+  'https://img.naiveadmin.com/assets/article/3.jpeg',
+  'https://img.naiveadmin.com/assets/article/4.jpg',
+  'https://img.naiveadmin.com/assets/article/5.jpeg',
+  'https://img.naiveadmin.com/assets/article/6.jpeg',
+  'https://img.naiveadmin.com/assets/article/7.jpeg',
+  'https://img.naiveadmin.com/assets/article/8.jpeg',
+  'https://img.naiveadmin.com/assets/article/9.jpeg',
+  'https://img.naiveadmin.com/assets/article/10.jpeg',
+];
+
+const videoList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      title: Random.pick([
+        'TTT培训-企业内训师(TTT)',
+        '卓越管理-打造高效执行力',
+        '卓越领导力-目标管理与计划执行',
+        '九型人格与管理应用',
+        '深刻理解激励辅导下属的内涵及价值,并积极有效的改变辅导的观念与...',
+        '裂变-创新时代卓越领导艺术与实践',
+      ]),
+      summary: Random.pick([
+        '帮助企业内部培训师充分认识自己的角色和任务,树立培训师的职业形...',
+        '向复杂的大型机构客户销售产品和方案的销售方法论',
+        '分析众多真实、鲜活的挑战性的销售案例,结合客户购买的6个心理周期...',
+        '了解大客户销售中客户的决策方式,购买特点,行为心理,有针对性地...',
+        '没有搞不定的订单,只有不会成交的销售。本课程将教给您:用头脑做...',
+        '精准销售模式是以企业现有销售团队为基础,通过高层推动,重新梳理...',
+      ]),
+      avatargroup: getRandomArrayElements(avatargroupList, 2, 5),
+      cover: Random.pick(coverList),
+      viewingtimes: Random.natural(10, 999),
+      date: `@date('yyyy-MM-dd')`,
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/video/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 1 } = query;
+      const list = videoList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 60,
+        itemCount: 60 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];
+
+//从数组中取出指定个数的元素
+function getRandomArrayElements(arr, start, end) {
+  const count = Math.floor(Math.random() * (end - start) + start);
+  const shuffled = arr.slice(0);
+  let i = arr.length;
+  const min = i - count;
+  let temp: any;
+  let index: number;
+  while (i-- > min) {
+    index = Math.floor((i + 1) * Math.random());
+    temp = shuffled[index];
+    shuffled[index] = shuffled[i];
+    shuffled[i] = temp;
+  }
+  return shuffled.slice(min);
+}

+ 44 - 0
mock/dashboard/console.ts

@@ -0,0 +1,44 @@
+import { Random } from 'mockjs';
+import { resultSuccess } from '../_util';
+
+const consoleInfo = {
+  //访问量
+  visits: {
+    dayVisits: Random.float(10000, 99999, 2, 2),
+    rise: Random.float(10, 99),
+    decline: Random.float(10, 99),
+    amount: Random.float(99999, 999999, 3, 5),
+  },
+  //销售额
+  saleroom: {
+    weekSaleroom: Random.float(10000, 99999, 2, 2),
+    amount: Random.float(99999, 999999, 2, 2),
+    degree: Random.float(10, 99),
+  },
+  //订单量
+  orderLarge: {
+    weekLarge: Random.float(10000, 99999, 2, 2),
+    rise: Random.float(10, 99),
+    decline: Random.float(10, 99),
+    amount: Random.float(99999, 999999, 2, 2),
+  },
+  //成交额度
+  volume: {
+    weekLarge: Random.float(10000, 99999, 2, 2),
+    rise: Random.float(10, 99),
+    decline: Random.float(10, 99),
+    amount: Random.float(99999, 999999, 2, 2),
+  },
+};
+
+export default [
+  //主控台 卡片数据
+  {
+    url: '/api/dashboard/console',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(consoleInfo);
+    },
+  },
+];

+ 153 - 0
mock/region/region.ts

@@ -0,0 +1,153 @@
+import { resultSuccess } from '../_util';
+
+const regionList = [
+  {
+    id: 1,
+    name: '广东省',
+    parentId: null,
+    depth: 1,
+  },
+  {
+    id: 2,
+    name: '江西省',
+    parentId: null,
+    depth: 1,
+  },
+  {
+    id: 3,
+    name: '浙江省',
+    parentId: null,
+    depth: 1,
+  },
+];
+
+const subRegionList = [
+  {
+    id: 11,
+    name: '深圳市',
+    parentId: 1,
+    depth: 2,
+  },
+  {
+    id: 111,
+    name: '宝安区',
+    parentId: 11,
+    depth: 3,
+  },
+  {
+    id: 112,
+    name: '南山区',
+    parentId: 11,
+    depth: 3,
+  },
+  {
+    id: 22,
+    name: '广州市',
+    parentId: 1,
+    depth: 2,
+  },
+  {
+    id: 221,
+    name: '花都区',
+    parentId: 22,
+    depth: 3,
+  },
+  {
+    id: 222,
+    name: '白云区',
+    parentId: 22,
+    depth: 3,
+  },
+  {
+    id: 33,
+    name: '萍乡市',
+    parentId: 2,
+    depth: 2,
+  },
+  {
+    id: 331,
+    name: '上栗县',
+    parentId: 33,
+    depth: 3,
+  },
+  {
+    id: 332,
+    name: '安源区',
+    parentId: 33,
+    depth: 3,
+  },
+  {
+    id: 44,
+    name: '宜春市',
+    parentId: 2,
+    depth: 2,
+  },
+  {
+    id: 441,
+    name: '袁州区',
+    parentId: 44,
+    depth: 3,
+  },
+  {
+    id: 442,
+    name: '上高县',
+    parentId: 44,
+    depth: 3,
+  },
+  {
+    id: 55,
+    name: '杭州市',
+    parentId: 3,
+    depth: 2,
+  },
+  {
+    id: 551,
+    name: '上城区',
+    parentId: 55,
+    depth: 3,
+  },
+  {
+    id: 552,
+    name: '下城区',
+    parentId: 55,
+    depth: 3,
+  },
+  {
+    id: 66,
+    name: '温州市',
+    parentId: 3,
+    depth: 2,
+  },
+  {
+    id: 661,
+    name: '龙湾区',
+    parentId: 66,
+    depth: 3,
+  },
+  {
+    id: 662,
+    name: '平阳县',
+    parentId: 66,
+    depth: 3,
+  },
+];
+
+export default [
+  {
+    url: '/api/area/getParent',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(regionList);
+    },
+  },
+  {
+    url: '/api/area/findByParentId',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { parentId } = query;
+      return resultSuccess(subRegionList.filter((item) => item.parentId === parseInt(parentId)));
+    },
+  },
+];

+ 31 - 0
mock/select/select.ts

@@ -0,0 +1,31 @@
+import { resultSuccess } from '../_util';
+
+const classifyList = [
+  {
+    label: '新品',
+    value: 'new',
+  },
+  {
+    label: '爆款',
+    value: 'hot',
+  },
+  {
+    label: '推荐',
+    value: 'rec',
+  },
+  {
+    label: '促销',
+    value: 'promotion',
+  },
+];
+
+export default [
+  {
+    url: '/api/classifyList',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(classifyList);
+    },
+  },
+];

+ 149 - 0
mock/system/dictionary.ts

@@ -0,0 +1,149 @@
+import { resultSuccess } from '../_util';
+
+const dictionaryList = [
+  {
+    id: '@integer(10,9999)',
+    label: '预约事项',
+    key: 'makeMatter',
+    children: [
+      {
+        id: '@integer(10,9999)',
+        label: '初次预约',
+        key: 'theMake',
+      },
+      {
+        id: '@integer(10,9999)',
+        label: '多次预约',
+        key: 'towMake',
+      },
+    ],
+  },
+  {
+    id: '@integer(10,9999)',
+    label: '注册来源',
+    key: 'registeredSource',
+  },
+];
+
+const dictionaryItems = () => {
+  return [
+    {
+      key: 'registeredSource',
+      values: [
+        {
+          id: '@integer(10,9999)',
+          value: 'baidu',
+          label: '百度',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+        {
+          id: '@integer(10,9999)',
+          value: 'weibo',
+          label: '微博',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+        {
+          id: '@integer(10,9999)',
+          value: 'weixin',
+          label: '微信',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+      ],
+    },
+    {
+      key: 'theMake',
+      parentKey: 'makeMatter',
+      values: [
+        {
+          id: '@integer(10,9999)',
+          value: 'examine',
+          label: '检查',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+        {
+          id: '@integer(10,9999)',
+          value: 'tooth',
+          label: '拔牙',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+      ],
+    },
+    {
+      key: 'towMake',
+      parentKey: 'makeMatter',
+      values: [
+        {
+          id: '@integer(10,9999)',
+          value: 'take',
+          label: '拆线',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+        {
+          id: '@integer(10,9999)',
+          value: 'periodontal',
+          label: '牙周',
+          'order|1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+          create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+        },
+      ],
+    },
+  ];
+};
+
+const dictionaryInfo = (_, key: string) => {
+  const list: any[] = [];
+  dictionaryItems().forEach((item: any) => {
+    if (item.key === key || item.parentKey === key) {
+      list.push(item as any);
+    }
+  });
+  const valuesList: any[] = [];
+  list.forEach((item: any) => {
+    item.values.map((values) => {
+      valuesList.push(values);
+    });
+  });
+  return valuesList;
+};
+
+export default [
+  //字典列表
+  {
+    url: '/api/dictionary/list',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(dictionaryList);
+    },
+  },
+  //字典详情
+  {
+    url: '/api/dictionary/info',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 10, key, keywords } = query;
+      let list = dictionaryInfo(Number(pageSize), key);
+      //实现搜索筛选
+      if (keywords) {
+        list = list.filter((item) => {
+          return item.label.indexOf(keywords) != -1;
+        });
+      }
+      const count = list.length > Number(pageSize) ? Math.ceil(list.length / Number(pageSize)) : 0;
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: count,
+        itemCount: count * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 89 - 0
mock/system/menu.ts

@@ -0,0 +1,89 @@
+import { resultSuccess } from '../_util';
+
+const menuList = () => {
+  const result: any[] = [
+    {
+      label: 'Dashboard',
+      key: 'dashboard',
+      type: 1,
+      subtitle: 'dashboard',
+      openType: 1,
+      auth: 'dashboard',
+      path: '/dashboard',
+      children: [
+        {
+          label: '主控台',
+          key: 'console',
+          type: 1,
+          subtitle: 'console',
+          openType: 1,
+          auth: 'console',
+          path: '/dashboard/console',
+        },
+        {
+          label: '工作台',
+          key: 'workplace',
+          type: 1,
+          subtitle: 'workplace',
+          openType: 1,
+          auth: 'workplace',
+          path: '/dashboard/workplace',
+        },
+      ],
+    },
+    {
+      label: '表单管理',
+      key: 'form',
+      type: 1,
+      subtitle: 'form',
+      openType: 1,
+      auth: 'form',
+      path: '/form',
+      children: [
+        {
+          label: '基础表单',
+          key: 'basic-form',
+          type: 1,
+          subtitle: 'basic-form',
+          openType: 1,
+          auth: 'basic-form',
+          path: '/form/basic-form',
+        },
+        {
+          label: '分步表单',
+          key: 'step-form',
+          type: 1,
+          subtitle: 'step-form',
+          openType: 1,
+          auth: 'step-form',
+          path: '/form/step-form',
+        },
+        {
+          label: '表单详情',
+          key: 'detail',
+          type: 1,
+          subtitle: 'detail',
+          openType: 1,
+          auth: 'detail',
+          path: '/form/detail',
+        },
+      ],
+    },
+  ];
+
+  return result;
+};
+
+export default [
+  {
+    url: '/api/menu/list',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      const list = menuList();
+      return resultSuccess({
+        list,
+      });
+    },
+  },
+];

+ 35 - 0
mock/system/region.ts

@@ -0,0 +1,35 @@
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const regionList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      name: '@province()',
+      'type|1': [1],
+      createTime: `@date('yyyy-MM-dd')`,
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/region/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 10, name } = query;
+      const list = regionList(Number(pageSize));
+      //并非真实,只是为了模拟搜索结果
+      const count = name ? 30 : 60;
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        totalPage: count,
+        totalCount: count * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 46 - 0
mock/system/role.ts

@@ -0,0 +1,46 @@
+import { resultSuccess, doCustomTimes } from '../_util';
+
+function getMenuKeys() {
+  const keys = ['dashboard', 'console', 'workplace', 'basic-form', 'step-form', 'detail'];
+  const newKeys: string[] = [];
+  doCustomTimes(parseInt(Math.random() * 6), () => {
+    const key: string = keys[Math.floor(Math.random() * keys.length)];
+    newKeys.push(key);
+  });
+  return Array.from(new Set(newKeys));
+}
+
+const roleList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,100)',
+      name: '@cname()',
+      explain: '@cname()',
+      isDefault: '@boolean()',
+      menu_keys: getMenuKeys(),
+      create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+      'status|1': ['normal', 'enable', 'disable'],
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/role/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 10 } = query;
+      const list = roleList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 30,
+        itemCount: 30 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 43 - 0
mock/table/list.ts

@@ -0,0 +1,43 @@
+import { Random } from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const tableList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,999999)',
+      'no|100000-10000000': 100000,
+      name: '@cname()',
+      avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()),
+      address: '@city()',
+      beginTime: '@datetime',
+      endTime: '@datetime',
+      'status|1': [true, false],
+      date: `@date('yyyy-MM-dd')`,
+      time: `@time('HH:mm')`,
+    });
+  });
+  return result;
+};
+
+export default [
+  //表格数据列表
+  {
+    url: '/api/table/list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 10, name } = query;
+      const list = tableList(Number(pageSize));
+      //并非真实,只是为了模拟搜索结果
+      const count = name ? 30 : 60;
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: count,
+        itemCount: count * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 269 - 0
mock/table/select.ts

@@ -0,0 +1,269 @@
+import { resultSuccess } from '../_util';
+
+const tableList = (page) => {
+  return page === 1
+    ? [
+        {
+          id: 659962,
+          no: 6965078,
+          name: '文洋',
+          avatar: 'http://dummyimage.com/400x400/79f29b/f27979&text=Joseph',
+          address: '台北市',
+          beginTime: '1982-08-20 04:10:02',
+          endTime: '1975-01-12 02:09:40',
+          status: false,
+          date: '1984-11-08',
+          time: '21:40',
+        },
+        {
+          id: 818440,
+          no: 2032345,
+          name: '冯涛',
+          avatar: 'http://dummyimage.com/400x400/799df2/c0f279&text=Donna',
+          address: '九龙',
+          beginTime: '1991-12-29 20:44:54',
+          endTime: '2002-05-27 12:09:35',
+          status: false,
+          date: '1993-11-04',
+          time: '18:56',
+        },
+        {
+          id: 212788,
+          no: 9668086,
+          name: '卢桂英',
+          avatar: 'http://dummyimage.com/400x400/f279e3/79f2dd&text=Sarah',
+          address: '毕节市',
+          beginTime: '2006-02-04 17:37:27',
+          endTime: '2007-03-13 12:15:59',
+          status: false,
+          date: '1984-05-07',
+          time: '13:47',
+        },
+        {
+          id: 23986,
+          no: 6841254,
+          name: '董秀英',
+          avatar: 'http://dummyimage.com/400x400/f2ba79/9679f2&text=Deborah',
+          address: '香港岛',
+          beginTime: '2016-03-28 12:39:23',
+          endTime: '1990-08-19 05:20:46',
+          status: true,
+          date: '1997-04-20',
+          time: '05:26',
+        },
+        {
+          id: 318041,
+          no: 1476802,
+          name: '周秀兰',
+          avatar: 'http://dummyimage.com/400x400/7ef279/f279a2&text=Laura',
+          address: '阿里地区',
+          beginTime: '2016-08-04 23:48:29',
+          endTime: '2005-05-02 09:28:46',
+          status: true,
+          date: '1997-11-14',
+          time: '13:42',
+        },
+        {
+          id: 228323,
+          no: 8883045,
+          name: '吕超',
+          avatar: 'http://dummyimage.com/400x400/79c5f2/e8f279&text=Linda',
+          address: '内江市',
+          beginTime: '1989-02-22 14:08:54',
+          endTime: '2009-10-30 23:04:49',
+          status: true,
+          date: '2016-07-19',
+          time: '05:51',
+        },
+        {
+          id: 5347,
+          no: 7551218,
+          name: '黎丽',
+          avatar: 'http://dummyimage.com/400x400/d879f2/79f2b4&text=William',
+          address: '辽源市',
+          beginTime: '1974-07-29 13:43:47',
+          endTime: '2012-08-27 23:27:05',
+          status: true,
+          date: '1976-07-14',
+          time: '22:50',
+        },
+        {
+          id: 287642,
+          no: 4410781,
+          name: '孙秀兰',
+          avatar: 'http://dummyimage.com/400x400/f29179/7984f2&text=Gary',
+          address: '汉中市',
+          beginTime: '1979-12-06 09:22:28',
+          endTime: '1972-06-20 02:53:21',
+          status: false,
+          date: '1988-01-01',
+          time: '00:01',
+        },
+        {
+          id: 352276,
+          no: 1342992,
+          name: '谢涛',
+          avatar: 'http://dummyimage.com/400x400/a7f279/f279ca&text=Daniel',
+          address: '苏州市',
+          beginTime: '2019-10-29 20:53:32',
+          endTime: '1977-09-17 01:41:39',
+          status: true,
+          date: '1970-06-09',
+          time: '22:39',
+        },
+        {
+          id: 509832,
+          no: 8171697,
+          name: '邵杰',
+          avatar: 'http://dummyimage.com/400x400/79eef2/f2d379&text=Paul',
+          address: '巢湖市',
+          beginTime: '1994-04-07 06:46:03',
+          endTime: '1974-03-16 01:28:24',
+          status: false,
+          date: '1988-11-11',
+          time: '19:10',
+        },
+      ]
+    : [
+        {
+          id: 601173,
+          no: 9911085,
+          name: '乔涛',
+          avatar: 'http://dummyimage.com/400x400/79e3f2/f2dd79&text=Jennifer',
+          address: '阳泉市',
+          beginTime: '1997-03-14 06:52:04',
+          endTime: '1989-05-23 13:14:14',
+          status: false,
+          date: '1988-12-15',
+          time: '04:42',
+        },
+        {
+          id: 328638,
+          no: 720053,
+          name: '郝明',
+          avatar: 'http://dummyimage.com/400x400/ba79f2/79f296&text=Anthony',
+          address: '吴忠市',
+          beginTime: '1991-09-19 21:15:47',
+          endTime: '1977-04-04 06:45:09',
+          status: false,
+          date: '2014-08-30',
+          time: '14:41',
+        },
+        {
+          id: 274363,
+          no: 3776909,
+          name: '贾洋',
+          avatar: 'http://dummyimage.com/400x400/f2797e/79a2f2&text=Sandra',
+          address: '吉安市',
+          beginTime: '2011-06-06 01:50:26',
+          endTime: '2000-03-29 13:02:10',
+          status: true,
+          date: '1985-11-10',
+          time: '01:11',
+        },
+        {
+          id: 627841,
+          no: 4226993,
+          name: '尹磊',
+          avatar: 'http://dummyimage.com/400x400/c5f279/f279e8&text=Ruth',
+          address: '新界',
+          beginTime: '1972-01-22 02:49:21',
+          endTime: '1994-12-10 14:33:11',
+          status: true,
+          date: '2017-05-29',
+          time: '18:28',
+        },
+        {
+          id: 853120,
+          no: 8772153,
+          name: '尹静',
+          avatar: 'http://dummyimage.com/400x400/79f2d8/f2b579&text=Lisa',
+          address: '抚顺市',
+          beginTime: '2018-10-31 07:40:52',
+          endTime: '2011-08-24 18:50:10',
+          status: true,
+          date: '1984-10-09',
+          time: '06:00',
+        },
+        {
+          id: 973847,
+          no: 8594801,
+          name: '毛涛',
+          avatar: 'http://dummyimage.com/400x400/9179f2/83f279&text=Maria',
+          address: '钦州市',
+          beginTime: '1970-05-10 20:00:00',
+          endTime: '1986-12-10 12:23:18',
+          status: true,
+          date: '1981-01-31',
+          time: '09:39',
+        },
+        {
+          id: 366765,
+          no: 9291682,
+          name: '方秀英',
+          avatar: 'http://dummyimage.com/400x400/f279a7/79caf2&text=Laura',
+          address: '昌都地区',
+          beginTime: '1980-05-12 22:54:51',
+          endTime: '1998-11-13 16:11:40',
+          status: true,
+          date: '1996-02-23',
+          time: '00:33',
+        },
+        {
+          id: 145082,
+          no: 4062636,
+          name: '范艳',
+          avatar: 'http://dummyimage.com/400x400/edf279/d379f2&text=Angela',
+          address: '连江县',
+          beginTime: '2001-03-19 23:58:41',
+          endTime: '2003-02-02 07:36:33',
+          status: false,
+          date: '2018-03-01',
+          time: '11:44',
+        },
+        {
+          id: 175542,
+          no: 9194674,
+          name: '刘秀英',
+          avatar: 'http://dummyimage.com/400x400/79f2af/f28c79&text=Maria',
+          address: '唐山市',
+          beginTime: '2018-05-07 16:06:35',
+          endTime: '2000-04-26 12:54:37',
+          status: false,
+          date: '1999-07-16',
+          time: '15:37',
+        },
+        {
+          id: 647222,
+          no: 3466012,
+          name: '尹艳',
+          avatar: 'http://dummyimage.com/400x400/7989f2/acf279&text=Brenda',
+          address: '离岛',
+          beginTime: '1994-12-25 10:58:49',
+          endTime: '1978-05-31 23:23:37',
+          status: false,
+          date: '2018-10-16',
+          time: '19:58',
+        },
+      ];
+};
+
+export default [
+  //表格数据列表
+  {
+    url: '/api/table/select',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 3 } = query;
+      const list = tableList(Number(page));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 2,
+        itemCount: 20,
+        list,
+      });
+    },
+  },
+];

+ 116 - 0
mock/user/menus.ts

@@ -0,0 +1,116 @@
+import { resultSuccess } from '../_util';
+
+//超级管理员
+const adminMenusList = [
+  {
+    path: '/dashboard',
+    name: 'Dashboard',
+    component: 'LAYOUT',
+    redirect: '/dashboard/console',
+    meta: {
+      icon: 'DashboardOutlined',
+      title: 'Dashboard',
+    },
+    children: [
+      {
+        path: 'console',
+        name: 'dashboard_console',
+        component: '/dashboard/console/console',
+        meta: {
+          title: '主控台',
+        },
+      },
+      {
+        path: 'monitor',
+        name: 'dashboard_monitor',
+        component: '/dashboard/monitor/monitor',
+        meta: {
+          title: '监控页',
+        },
+      },
+      {
+        path: 'workplace',
+        name: 'dashboard_workplace',
+        component: '/dashboard/workplace/workplace',
+        meta: {
+          hidden: true,
+          title: '工作台',
+        },
+      },
+    ],
+  },
+  {
+    path: '/list',
+    name: 'List',
+    component: 'LAYOUT',
+    redirect: '/list/basic-list',
+    meta: {
+      icon: 'TableOutlined',
+      title: '列表页面',
+    },
+    children: [
+      {
+        path: 'basic-list',
+        name: 'basic-list',
+        component: '/list/basicList/index',
+        meta: {
+          title: '基础列表',
+        },
+      },
+    ],
+  },
+];
+
+//普通管理员
+const ordinaryMenusList = [
+  {
+    path: '/dashboard',
+    name: 'Dashboard',
+    component: 'LAYOUT',
+    redirect: '/dashboard/console',
+    meta: {
+      icon: 'DashboardOutlined',
+      title: 'Dashboard',
+    },
+    children: [
+      {
+        path: 'console',
+        name: 'dashboard_console',
+        component: '/dashboard/console/console',
+        meta: {
+          title: '主控台',
+        },
+      },
+      {
+        path: 'monitor',
+        name: 'dashboard_monitor',
+        component: '/dashboard/monitor/monitor',
+        meta: {
+          title: '监控页',
+        },
+      },
+      {
+        path: 'workplace',
+        name: 'dashboard_workplace',
+        component: '/dashboard/workplace/workplace',
+        meta: {
+          hidden: true,
+          title: '工作台',
+        },
+      },
+    ],
+  },
+];
+
+export default [
+  {
+    url: '/api/menus',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      //此处随机了,为了模拟不同角色权限
+      const randomNum = Math.floor(Math.random() * 2 + 1);
+      return randomNum === 1 ? resultSuccess(adminMenusList) : resultSuccess(ordinaryMenusList);
+    },
+  },
+];

+ 115 - 0
mock/user/user.ts

@@ -0,0 +1,115 @@
+import Mock from 'mockjs';
+import { resultSuccess, doCustomTimes } from '../_util';
+
+const Random = Mock.Random;
+
+const token = Random.string('upper', 32, 32);
+
+//超级管理员
+const adminPermissions = [
+  {
+    label: '主控台',
+    value: 'dashboard_console',
+  },
+  {
+    label: '监控页',
+    value: 'dashboard_monitor',
+  },
+  {
+    label: '工作台',
+    value: 'dashboard_workplace',
+  },
+  {
+    label: '基础列表',
+    value: 'basic_list',
+  },
+];
+
+//普通管理员
+const ordinaryPermissions = [
+  {
+    label: '主控台',
+    value: 'dashboard_console',
+  },
+  {
+    label: '监控页',
+    value: 'dashboard_monitor',
+  },
+  {
+    label: '工作台',
+    value: 'dashboard_workplace',
+  },
+];
+
+const adminInfo = {
+  userId: '1',
+  username: 'admin',
+  realName: 'Admin',
+  avatar: Random.image(),
+  desc: 'manager',
+  password: Random.string('upper', 4, 16),
+  token,
+  role_type: 1, // 1 超级管理员 2 普通管理员
+  permissions: [], // 权限集合
+};
+
+const userList = (pageSize) => {
+  const result: any[] = [];
+  doCustomTimes(pageSize, () => {
+    result.push({
+      id: '@integer(10,9999)',
+      username: '@cname()',
+      avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()),
+      account: 'M086611',
+      mobile: `188@integer(1000,9999)9999`,
+      email: '735@integer(1000,9999)02@qq.com',
+      'gender|1': [1, 2],
+      'status|1': ['normal', 'disable'],
+      'role|1': ['普通用户', '推广管理员', '发货管理员', '财务管理员'],
+      create_date: `@date('yyyy-MM-dd hh:mm:ss')`,
+    });
+  });
+  return result;
+};
+
+export default [
+  {
+    url: '/api/login',
+    timeout: 1000,
+    method: 'post',
+    response: () => {
+      return resultSuccess({ token });
+    },
+  },
+  {
+    url: '/api/admin_info',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      // const token = getRequestToken(request);
+      // if (!token) return resultError('Invalid token');
+      //此处随机了,为了模拟不同角色权限
+      //const randomNum = Math.floor(Math.random() * 2 + 1);
+      const randomNum = 1;
+      adminInfo.permissions = (randomNum === 1 ? adminPermissions : ordinaryPermissions) as never[];
+      adminInfo.role_type = randomNum;
+      return resultSuccess(adminInfo);
+    },
+  },
+  {
+    url: '/api/user_list',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 10 } = query;
+      const list = userList(Number(pageSize));
+      return resultSuccess({
+        page: Number(page),
+        pageSize: Number(pageSize),
+        pageCount: 60,
+        itemCount: 60 * Number(pageSize),
+        list,
+      });
+    },
+  },
+];

+ 145 - 0
package.json

@@ -0,0 +1,145 @@
+{
+  "name": "naive-admin-element-tenant",
+  "version": "1.0.0",
+  "author": {
+    "name": "Ahjung",
+    "email": "735878602@qq.com",
+    "url": "https://github.com/jekip"
+  },
+  "private": true,
+  "scripts": {
+    "bootstrap": "pnpm install",
+    "serve": "pnpm run dev",
+    "dev": "vite",
+    "build": "cross-env NODE_ENV=production vite build && esno ./build/script/postBuild.ts",
+    "build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
+    "build:no-cache": "pnpm clean:cache && pnpm run build",
+    "report": "cross-env REPORT=true pnpm run build",
+    "type:check": "vue-tsc --noEmit --skipLibCheck",
+    "preview": "pnpm run build && vite preview",
+    "preview:dist": "vite preview",
+    "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
+    "clean:lib": "rimraf node_modules",
+    "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
+    "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
+    "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
+    "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
+    "lint:pretty": "pretty-quick --staged",
+    "test prod gzip": "http-server dist --cors --gzip -c-1",
+    "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && pnpm run bootstrap",
+    "build typecheck": "vuedx-typecheck . && vite build",
+    "deploy": "gh-pages -d dist"
+  },
+  "dependencies": {
+    "@element-plus/icons-vue": "^2.0.9",
+    "@vicons/antd": "^0.12.0",
+    "@vicons/ionicons5": "^0.12.0",
+    "@vueup/vue-quill": "1.0.0-beta.8",
+    "@vueuse/core": "^8.9.4",
+    "@wangeditor/editor": "^5.1.23",
+    "@wangeditor/editor-for-vue": "^5.1.12",
+    "axios": "^0.27.2",
+    "blueimp-md5": "^2.19.0",
+    "cropperjs": "^1.5.12",
+    "dayjs": "^1.11.4",
+    "echarts": "^5.3.3",
+    "element-plus": "^2.2.26",
+    "element-resize-detector": "^1.2.4",
+    "lodash": "^4.17.21",
+    "lodash-es": "^4.17.21",
+    "mockjs": "^1.1.0",
+    "nprogress": "^0.2.0",
+    "perfect-scrollbar": "^1.5.5",
+    "pinia": "^2.0.16",
+    "print-js": "^1.6.0",
+    "qrcode": "^1.5.1",
+    "qs": "^6.11.0",
+    "vue": "^3.2.45",
+    "vue-router": "^4.1.2",
+    "vue-types": "^4.1.1",
+    "vuedraggable": "^4.1.0",
+    "xlsx": "^0.18.5"
+  },
+  "devDependencies": {
+    "@commitlint/cli": "^17.0.3",
+    "@commitlint/config-conventional": "^17.0.3",
+    "@types/element-resize-detector": "^1.1.3",
+    "@types/intro.js": "^3.0.2",
+    "@types/lodash": "^4.14.182",
+    "@types/node": "^17.0.45",
+    "@types/qrcode": "^1.4.2",
+    "@typescript-eslint/eslint-plugin": "^5.30.7",
+    "@typescript-eslint/parser": "^5.30.7",
+    "@vitejs/plugin-vue": "^2.3.3",
+    "@vitejs/plugin-vue-jsx": "^1.3.10",
+    "@vue/compiler-sfc": "^3.2.45",
+    "autoprefixer": "^10.4.7",
+    "colors": "^1.4.0",
+    "commitizen": "^4.2.5",
+    "core-js": "^3.23.5",
+    "cross-env": "^7.0.3",
+    "dotenv": "^16.0.1",
+    "eslint": "^8.20.0",
+    "eslint-config-prettier": "^8.5.0",
+    "eslint-define-config": "^1.5.1",
+    "eslint-plugin-prettier": "^4.2.1",
+    "eslint-plugin-vue": "^8.7.1",
+    "esno": "^0.16.3",
+    "fs-extra": "^10.1.0",
+    "gh-pages": "^4.0.0",
+    "husky": "^8.0.1",
+    "lint-staged": "^13.0.3",
+    "picocolors": "^1.0.0",
+    "postcss": "^8.4.14",
+    "prettier": "^2.7.1",
+    "pretty-quick": "^3.1.3",
+    "rimraf": "^3.0.2",
+    "rollup-plugin-visualizer": "^5.8.3",
+    "sass": "^1.53.0",
+    "stylelint": "^14.9.1",
+    "stylelint-config-prettier": "^9.0.3",
+    "stylelint-config-standard": "^25.0.0",
+    "stylelint-order": "^5.0.0",
+    "stylelint-scss": "^4.3.0",
+    "tailwindcss": "^3.1.6",
+    "ts-node": "^10.9.1",
+    "typescript": "^4.7.4",
+    "vite": "^3.2.5",
+    "vite-plugin-compression": "^0.5.1",
+    "vite-plugin-html": "^3.2.0",
+    "vite-plugin-mock": "^2.9.6",
+    "vite-plugin-style-import": "^2.0.0",
+    "vite-plugin-vue-setup-extend": "^0.4.0",
+    "vue-eslint-parser": "^9.0.3",
+    "vue-tsc": "^0.35.2"
+  },
+  "lint-staged": {
+    "*.{vue,js,ts,tsx}": "eslint --fix"
+  },
+  "config": {
+    "commitizen": {
+      "path": "./node_modules/cz-customizable"
+    }
+  },
+  "keywords": [
+    "vue",
+    "naive-ui",
+    "naive-ui-admin",
+    "vue3",
+    "ts",
+    "tsx",
+    "admin",
+    "typescript"
+  ],
+  "engines": {
+    "node": "^12 || >=14"
+  },
+  "pnpm": {
+    "peerDependencyRules": {
+      "ignoreMissing": [
+        "rollup",
+        "webpack"
+      ]
+    }
+  }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6600 - 0
pnpm-lock.yaml


+ 6 - 0
postcss.config.js

@@ -0,0 +1,6 @@
+module.exports = {
+  plugins: {
+    tailwindcss: {},
+    autoprefixer: {},
+  },
+};

+ 10 - 0
prettier.config.js

@@ -0,0 +1,10 @@
+module.exports = {
+  printWidth: 100,
+  semi: true,
+  vueIndentScriptAndStyle: true,
+  singleQuote: true,
+  trailingComma: 'all',
+  proseWrap: 'never',
+  htmlWhitespaceSensitivity: 'strict',
+  endOfLine: 'auto',
+};

BIN=BIN
public/favicon.ico


+ 64 - 0
src/App.vue

@@ -0,0 +1,64 @@
+<template>
+  <el-config-provider size="default" :zIndex="zIndex">
+    <AppProvider>
+      <RouterView v-if="!isLock" />
+      <transition v-if="isLock && $route.name !== LoginName" name="slide-up">
+        <LockScreen />
+      </transition>
+    </AppProvider>
+  </el-config-provider>
+</template>
+
+<script lang="ts" setup>
+  import { computed, onMounted, onUnmounted, ref } from 'vue';
+  import { ElConfigProvider } from 'element-plus';
+  import { LockScreen } from '@/components/Lockscreen';
+  import { AppProvider } from '@/components/Application';
+  import { useLockscreenStore } from '@/store/modules/lockscreen';
+  import { useRoute } from 'vue-router';
+  import { PageEnum } from '@/enums/pageEnum';
+
+  const route = useRoute();
+  const useLockscreen = useLockscreenStore();
+
+  const isLock = computed(() => useLockscreen.isLock);
+  const lockTime = computed(() => useLockscreen.lockTime);
+
+  const zIndex = ref(3000);
+
+  const LoginName = PageEnum.BASE_LOGIN_NAME;
+
+  let timer;
+
+  const timekeeping = () => {
+    clearInterval(timer);
+    if (route.name === LoginName || isLock.value) return;
+    // 设置不锁屏
+    useLockscreen.setLock(false);
+    // 重置锁屏时间
+    useLockscreen.setLockTime();
+    timer = setInterval(() => {
+      // 锁屏倒计时递减
+      useLockscreen.setLockTime(lockTime.value - 1);
+      if (lockTime.value <= 0) {
+        // 设置锁屏
+        useLockscreen.setLock(true);
+        return clearInterval(timer);
+      }
+    }, 1000);
+  };
+
+  onMounted(() => {
+    document.addEventListener('mousedown', timekeeping);
+  });
+
+  onUnmounted(() => {
+    document.removeEventListener('mousedown', timekeeping);
+  });
+</script>
+
+<style lang="scss">
+  #nprogress .bar {
+    background: var(--el-color-primary);
+  }
+</style>

+ 84 - 0
src/api/article/index.ts

@@ -0,0 +1,84 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 文章列表
+ */
+export function articleList(params) {
+  return http.request({
+    url: '/article/list',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 添加文章
+ */
+export function addArticle(params) {
+  return http.request({
+    url: '/article/add',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 修改文章
+ */
+export function editArticle(params) {
+  return http.request({
+    url: '/article/update ',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 文章信息
+ */
+export function articleInfo(params) {
+  return http.request({
+    url: '/article/info',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 删除文章
+ */
+export function deleteArticle(data) {
+  return http.request({
+    url: '/article/delete ',
+    method: 'post',
+    data,
+  });
+}
+
+/**
+ * @description: 导出文章
+ */
+export function exportArticle(data?) {
+  return http.request(
+    {
+      url: '/article/export',
+      method: 'post',
+      data,
+      responseType: 'blob', // 二进制流
+    },
+    {
+      isReturnNativeResponse: true,
+    },
+  );
+}
+
+/**
+ * @description: 导入文章
+ */
+export function importArticle(data) {
+  return http.request({
+    url: '/article/import',
+    method: 'post',
+    data,
+  });
+}

+ 67 - 0
src/api/auth/dept.ts

@@ -0,0 +1,67 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 部门列表
+ */
+export function deptList(params) {
+  return http.request({
+    url: '/dept/list',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 部门树形列表
+ */
+export function deptTreeList(params?) {
+  return http.request({
+    url: '/dept/queryRegionTree',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 添加部门
+ */
+export function addDept(params) {
+  return http.request({
+    url: '/dept/add',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑部门
+ */
+export function editDept(params) {
+  return http.request({
+    url: '/dept/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 部门详情
+ */
+export function deptInfo(params) {
+  return http.request({
+    url: '/dept/view',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 删除部门
+ */
+export function deleteDept(params) {
+  return http.request({
+    url: '/dept/delete',
+    method: 'post',
+    params,
+  });
+}

+ 56 - 0
src/api/auth/post.ts

@@ -0,0 +1,56 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 岗位列表
+ */
+export function postList(params) {
+  return http.request({
+    url: '/post/list',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 添加岗位
+ */
+export function addPost(params) {
+  return http.request({
+    url: '/post/add',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑岗位
+ */
+export function editPost(params) {
+  return http.request({
+    url: '/post/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 岗位详情
+ */
+export function postInfo(params) {
+  return http.request({
+    url: '/post/view',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 删除岗位
+ */
+export function deletePost(params) {
+  return http.request({
+    url: '/post/delete',
+    method: 'post',
+    params,
+  });
+}

+ 41 - 0
src/api/common/index.ts

@@ -0,0 +1,41 @@
+import { http } from '@/utils/http/axios';
+
+//图片上传
+export function upload(data) {
+  return http.request({
+    url: '/upload',
+    method: 'post',
+    data,
+  });
+}
+
+//初始化配置数据
+export function initData(data?) {
+  return http.request({
+    url: '/common/initData',
+    method: 'get',
+    data,
+  });
+}
+
+/**
+ * @description: 验证码 Base64
+ */
+export function captchaBase64(params) {
+  return http.request({
+    url: '/common/captchaBase64',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 岗位列表 不分页
+ */
+export function postList(params?) {
+  return http.request({
+    url: '/common/queryPostList',
+    method: 'GET',
+    params,
+  });
+}

+ 10 - 0
src/api/comtemp/article.ts

@@ -0,0 +1,10 @@
+import { http } from '@/utils/http/axios';
+
+//获取文章
+export function articleList(params?) {
+  return http.request({
+    url: '/article/list',
+    method: 'get',
+    params,
+  });
+}

+ 10 - 0
src/api/comtemp/category.ts

@@ -0,0 +1,10 @@
+import { http } from '@/utils/http/axios';
+
+//获取分类
+export function categoryList(params?) {
+  return http.request({
+    url: '/category/list',
+    method: 'get',
+    params,
+  });
+}

+ 10 - 0
src/api/comtemp/make.ts

@@ -0,0 +1,10 @@
+import { http } from '@/utils/http/axios';
+
+//获取文章
+export function makeList(params?) {
+  return http.request({
+    url: '/make/list',
+    method: 'get',
+    params,
+  });
+}

+ 10 - 0
src/api/comtemp/video.ts

@@ -0,0 +1,10 @@
+import { http } from '@/utils/http/axios';
+
+//获取文章
+export function videoList(params?) {
+  return http.request({
+    url: '/video/list',
+    method: 'get',
+    params,
+  });
+}

+ 9 - 0
src/api/dashboard/console.ts

@@ -0,0 +1,9 @@
+import { http } from '@/utils/http/axios';
+
+//获取主控台信息
+export function getConsoleInfo() {
+  return http.request({
+    url: '/dashboard/console',
+    method: 'get',
+  });
+}

+ 67 - 0
src/api/notice/notice.ts

@@ -0,0 +1,67 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 通知列表
+ */
+export function noticeList(params) {
+  return http.request({
+    url: '/notice/list',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 添加通知
+ */
+export function addNotice(params) {
+  return http.request({
+    url: '/notice/add',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑通知
+ */
+export function editNotice(params) {
+  return http.request({
+    url: '/notice/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 通知详情
+ */
+export function noticeInfo(params) {
+  return http.request({
+    url: '/notice/view',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 删除通知
+ */
+export function deleteNotice(params) {
+  return http.request({
+    url: '/notice/delete',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 我的通知
+ */
+export function myNotice(params) {
+  return http.request({
+    url: '/notice/myNotice',
+    method: 'get',
+    params,
+  });
+}

+ 18 - 0
src/api/region/region.ts

@@ -0,0 +1,18 @@
+import { http } from '@/utils/http/axios';
+
+//获取
+export function allProvinces(params?) {
+  return http.request({
+    url: '/area/getParent',
+    method: 'get',
+    params,
+  });
+}
+
+export function regionParent(params) {
+  return http.request({
+    url: '/area/findByParentId',
+    method: 'get',
+    params,
+  });
+}

+ 10 - 0
src/api/select/select.ts

@@ -0,0 +1,10 @@
+import { http } from '@/utils/http/axios';
+
+//获取分类
+export function getClassifyList(params?) {
+  return http.request({
+    url: '/classifyList',
+    method: 'get',
+    params,
+  });
+}

+ 56 - 0
src/api/system/config.ts

@@ -0,0 +1,56 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 添加配置
+ */
+export function addConfig(params) {
+  return http.request({
+    url: '/sysconfig/add',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 删除配置
+ */
+export function deleteConfig(params) {
+  return http.request({
+    url: '/sysconfig/delete',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑配置
+ */
+export function editConfig(params) {
+  return http.request({
+    url: '/sysconfig/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 配置列表
+ */
+export function configList(params) {
+  return http.request({
+    url: '/sysconfig/list',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 配置详情
+ */
+export function configInfo(params) {
+  return http.request({
+    url: '/sysconfig/view',
+    method: 'get',
+    params,
+  });
+}

+ 114 - 0
src/api/system/dictionary.ts

@@ -0,0 +1,114 @@
+import { http } from '@/utils/http/axios';
+
+/** ======================字典===================== */
+/**
+ * @description: 添加字典
+ */
+export function addDictData(params) {
+  return http.request({
+    url: '/dict/addDictData',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑字典
+ */
+export function editDictData(params) {
+  return http.request({
+    url: '/dict/updateDictData',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 删除字典
+ */
+export function delDictData(params) {
+  return http.request({
+    url: '/dict/delDictData',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 查询数据类型下数据字典列表(不分页)
+ */
+export function dictList(params) {
+  return http.request({
+    url: '/dict/dictList',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 获取字典类型对应列表
+ */
+export function dictInfo(params) {
+  return http.request({
+    url: '/dict/listDictData',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 查询数据字典类型(不分页)
+ */
+export function dictTypeInfo(params) {
+  return http.request({
+    url: '/dict/listDictType',
+    method: 'get',
+    params,
+  });
+}
+
+/** ======================字典类型===================== */
+
+/**
+ * @description: 添加字典类型
+ */
+export function addDictType(params) {
+  return http.request({
+    url: '/dict/addDictType',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑字典类型
+ */
+export function editDictType(params) {
+  return http.request({
+    url: '/dict/updateDictType',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 删除字典类型
+ */
+export function delDictType(params) {
+  return http.request({
+    url: '/dict/delDictType',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 字典类型列表
+ */
+export function dictTypeList(params) {
+  return http.request({
+    url: '/dict/typePagelist',
+    method: 'get',
+    params,
+  });
+}

+ 12 - 0
src/api/system/logs.ts

@@ -0,0 +1,12 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 日志列表
+ */
+export function logsList(params) {
+  return http.request({
+    url: '/log/list',
+    method: 'get',
+    params,
+  });
+}

+ 71 - 0
src/api/system/menu.ts

@@ -0,0 +1,71 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 获取动态菜单
+ */
+export function adminMenus() {
+  return http.request({
+    url: '/login/getRouters',
+    method: 'GET',
+  });
+}
+
+/**
+ * 获取tree菜单列表
+ * @param params
+ */
+export function getMenuList(params?) {
+  return http.request({
+    url: '/menu/menuList',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * 添加菜单
+ * @param params
+ */
+export function addMenu(params?) {
+  return http.request({
+    url: '/menu/add',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * 编辑菜单
+ * @param params
+ */
+export function editMenu(params?) {
+  return http.request({
+    url: '/menu/update',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * 菜单信息
+ * @param params
+ */
+export function menuInfo(params?) {
+  return http.request({
+    url: '/menu/info',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * 删除菜单
+ * @param params
+ */
+export function deleteMenu(params) {
+  return http.request({
+    url: '/menu/delete',
+    method: 'POST',
+    params,
+  });
+}

+ 96 - 0
src/api/system/region.ts

@@ -0,0 +1,96 @@
+import { http } from '@/utils/http/axios';
+
+import { useGlobSetting } from '@/hooks/setting';
+
+const globSetting = useGlobSetting();
+const urlPrefix = globSetting.urlPrefix || '';
+
+const hsot = location.origin + urlPrefix;
+
+/**
+ * @description: 地区列表
+ */
+export function regionList(params) {
+  return http.request({
+    url: `${hsot}/region/list`,
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 获取省份/直辖市
+ */
+export function provinceList(params) {
+  return http.request({
+    url: '/region/queryProvinceList',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 获取下一级行政区域列表
+ */
+export function parentList(params) {
+  return http.request({
+    url: '/region/queryParentList',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 获取行政区域树形列表
+ */
+export function regionTreeList(params?) {
+  return http.request({
+    url: '/region/queryRegionTree',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 获取单个行政区域
+ */
+export function regionInfo(params) {
+  return http.request({
+    url: '/region/view',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 删除行政区域
+ */
+export function deleteRegion(params) {
+  return http.request({
+    url: '/region/delete',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 新增行政区域
+ */
+export function addRegion(params) {
+  return http.request({
+    url: '/region/add',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑行政区域
+ */
+export function editRegion(params) {
+  return http.request({
+    url: '/region/update',
+    method: 'POST',
+    params,
+  });
+}

+ 77 - 0
src/api/system/role.ts

@@ -0,0 +1,77 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 添加角色
+ */
+export function addRole(params) {
+  return http.request({
+    url: '/role/add',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 查询角色信息
+ */
+export function roleInfo(params) {
+  return http.request({
+    url: '/role/info',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑角色
+ */
+export function editRole(params) {
+  return http.request({
+    url: '/role/update',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 删除角色
+ */
+export function delRole(params) {
+  return http.request({
+    url: '/role/delete',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 角色列表
+ */
+export function roleList(params?) {
+  return http.request({
+    url: '/role/pageList',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 所有角色列表
+ */
+export function roleAllList(params?) {
+  return http.request({
+    url: '/role/getAllRoles',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 获取所有权限
+ */
+export function permissionList() {
+  return http.request({
+    url: '/role/listAllPermission',
+    method: 'GET',
+  });
+}

+ 56 - 0
src/api/system/tasks.ts

@@ -0,0 +1,56 @@
+import { http } from '@/utils/http/axios';
+
+/**
+ * @description: 添加定时任务
+ */
+export function addTasks(params) {
+  return http.request({
+    url: '/job/save',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 删除定时任务
+ */
+export function deleteTasks(params) {
+  return http.request({
+    url: '/job/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑定时任务
+ */
+export function editTasks(params) {
+  return http.request({
+    url: '/job/update',
+    method: 'post',
+    params,
+  });
+}
+
+/**
+ * @description: 任务列表
+ */
+export function tasksList(params) {
+  return http.request({
+    url: '/job/pageList',
+    method: 'get',
+    params,
+  });
+}
+
+/**
+ * @description: 定时任务详情
+ */
+export function tasksInfo(params) {
+  return http.request({
+    url: '/job/view',
+    method: 'get',
+    params,
+  });
+}

+ 128 - 0
src/api/system/user.ts

@@ -0,0 +1,128 @@
+import { http } from '@/utils/http/axios';
+
+export interface BasicResponseModel<T = any> {
+  code: number;
+  msg: string;
+  data: T;
+}
+
+export interface BasicPageParams {
+  pageNumber: number;
+  pageSize: number;
+  total: number;
+}
+
+/**
+ * @description: 获取用户信息
+ */
+export function getUserInfo(params?) {
+  return http.request({
+    url: '/login/info',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 添加/编辑用户
+ */
+export function addUsur(params) {
+  return http.request({
+    url: '/user/add',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 编辑用户
+ */
+export function editUsur(params) {
+  return http.request({
+    url: '/user/update',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 用户信息
+ */
+export function userInfo(params) {
+  return http.request({
+    url: '/user/info',
+    method: 'GET',
+    params,
+  });
+}
+
+/**
+ * @description: 删除用户
+ */
+export function delUser(params) {
+  return http.request({
+    url: '/user/delete',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 用户登录
+ */
+export function login(params) {
+  return http.request<BasicResponseModel>(
+    {
+      url: '/login/auth',
+      method: 'POST',
+      params,
+    },
+    {
+      isTransformResponse: false,
+    },
+  );
+}
+
+/**
+ * @description: 用户修改密码
+ */
+export function changePassword(params) {
+  return http.request({
+    url: '/login/updatePwd',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 修改用户信息
+ */
+export function editUserInfo(params) {
+  return http.request({
+    url: '/login/updateUser',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 用户登出
+ */
+export function logout(params) {
+  return http.request({
+    url: '/user/doLogout',
+    method: 'POST',
+    params,
+  });
+}
+
+/**
+ * @description: 获取用户列表
+ */
+export function getUserList(params) {
+  return http.request({
+    url: '/user/list',
+    method: 'GET',
+    params,
+  });
+}

+ 19 - 0
src/api/table/list.ts

@@ -0,0 +1,19 @@
+import { http } from '@/utils/http/axios';
+
+//获取table
+export function getTableList(params) {
+  return http.request({
+    url: '/table/list',
+    method: 'get',
+    params,
+  });
+}
+
+//获取table select
+export function getTableSelectList(params) {
+  return http.request({
+    url: '/table/select',
+    method: 'get',
+    params,
+  });
+}

+ 127 - 0
src/assets/icons/login.svg

@@ -0,0 +1,127 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1361px"
+     height="609px" viewBox="0 0 1361 609" version="1.1">
+    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 21</title>
+    <desc>Created with Sketch.</desc>
+    <defs/>
+    <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
+            <g id="Group-21" transform="translate(77.000000, 73.000000)">
+                <g id="Group-18" opacity="0.8"
+                   transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
+                    <ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367"
+                             rx="21.7830479" ry="21.766008"/>
+                    <ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601"
+                             rx="5.2173913" ry="5.21330997"/>
+                    <path
+                            d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z"
+                            id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"/>
+                    <path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6"
+                          stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"/>
+                    <path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7"
+                          stroke-width="0.702678964" opacity="0.7" stroke-linecap="round"
+                          stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"/>
+                    <path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9"
+                          stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round"
+                          stroke-dasharray="1.405357899873153,2.108036953469981"/>
+                    <g id="Group-17"
+                       transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)"
+                       fill="#CFDAE6">
+                        <ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653"
+                                 ry="9.12768076"/>
+                        <path
+                                d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z"
+                                id="Oval-4"
+                                transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "/>
+                    </g>
+                </g>
+                <g id="Group-14"
+                   transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439"
+                             rx="29.1176471" ry="29.1402439"/>
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439"
+                             rx="21.5686275" ry="21.5853659"/>
+                    <ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341"
+                             rx="23.7254902" ry="23.7439024"/>
+                    <ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439"
+                             rx="10.7843137" ry="10.7926829"/>
+                    <path
+                            d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z"
+                            id="Oval-2" fill="#BACAD9"/>
+                    <g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)"
+                       fill="#E6A1A6">
+                        <ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824"
+                                 ry="6.47560976"/>
+                        <path
+                                d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z"
+                                id="Oval-2-Copy-2"
+                                transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "/>
+                    </g>
+                    <ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706"
+                             ry="1.61890244"/>
+                    <ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098"
+                             rx="1.61764706" ry="1.61890244"/>
+                    <ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488"
+                             rx="2.15686275" ry="2.15853659"/>
+                    <path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6"
+                          opacity="0.8"/>
+                </g>
+                <g id="Group-10" opacity="0.799999952"
+                   transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
+                    <ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32"
+                             rx="11.1864407" ry="11.2941176"/>
+                    <g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
+                        <ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627"
+                                 ry="8.55614973"/>
+                        <path
+                                d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z"
+                                id="Oval-7"/>
+                    </g>
+                    <path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6"
+                          stroke-width="0.941176471"/>
+                    <ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186"
+                             cy="3.29411765" rx="3.26271186" ry="3.29411765"/>
+                    <ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017"
+                             ry="2.82352941"/>
+                    <path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6"
+                          stroke-width="0.941176471"/>
+                </g>
+                <g id="Group-19" opacity="0.33"
+                   transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
+                    <g id="Group-17"
+                       transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)"
+                       fill="#BACAD9">
+                        <circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"/>
+                        <path
+                                d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z"
+                                id="Oval-4"
+                                transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "/>
+                    </g>
+                    <circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"/>
+                    <path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667"
+                              points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"/>
+                    <path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7"
+                          stroke-width="1.16666667" opacity="0.6"/>
+                    <path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6"
+                          stroke-width="1.16666667"/>
+                    <circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"/>
+                    <circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"/>
+                    <circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25"
+                            r="8.75"/>
+                    <circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333"
+                            cy="30.3333333" r="5.83333333"/>
+                    <circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"/>
+                </g>
+            </g>
+        </g>
+    </g>
+    <div xmlns="" id="divScriptsUsed" style="display: none"/>
+    <script xmlns="" id="globalVarsDetection"
+            src="chrome-extension://cmkdbmfndkfgebldhnkbfhlneefdaaip/js/wrs_env.js"/>
+</svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 60 - 0
src/assets/icons/logo.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 474 - 0
src/assets/images/Business.svg


+ 255 - 0
src/assets/images/Error.svg

@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+     x="0px" y="0px"
+     viewBox="0 0 600 600" enable-background="new 0 0 600 600" xml:space="preserve">
+<g id="LEFT_ARM_1">
+	<g id="XMLID_46_">
+		<path id="XMLID_290_" fill="#FFB96C" d="M294.4,485.5c-1.2,0.3-2.4,0.4-3.6,0.4c-0.2,0-0.4,0-0.6,0c-8.4-0.3-16.2-6.9-21-15.7
+			c-21.3-39.2-27.1-63.4-34.8-89.9c-1.9-6.6-1.4-13.3,1.4-18.1c2.2-3.7,5.7-6.4,10.5-6.9c0.6-0.1,1.1-0.1,1.7-0.1
+			c8.5,0,17.4,6.8,20.9,15.6l36.5,89.4C310,471.5,305,483.1,294.4,485.5z"/>
+        <path id="XMLID_280_" fill="#FCAF63" d="M290.2,485.9c-8.4-0.3-16.2-6.9-21-15.7c-21.3-39.2-27.1-63.4-34.8-89.9
+			c-1.9-6.6-1.4-13.3,1.4-18.1c9.5,23,40.7,98.5,50.3,116.1C287.6,481.1,289,483.6,290.2,485.9z"/>
+	</g>
+</g>
+    <g id="LEFT_ARM_2">
+	<g id="XMLID_10_">
+		<g id="XMLID_42_">
+			<path id="XMLID_293_" fill="#FFB96C" d="M340.2,472c-0.9,2.3-2.1,4.1-3.3,5c-7.2,5.7-14.3,7-26.2,9.6c-11.9,2.6-24.2,2-29.9-3.4
+				c-1.9-1.8-3.3-3.8-4.1-5.9c-2.5-6-0.3-12.3,6.8-15c4.2-1.6,42.4-10.6,48.7-9.4C343.1,455,342.9,465.3,340.2,472z"/>
+            <path id="XMLID_279_" fill="#FCAF63" d="M340.2,472c-0.9,2.3-2.1,4.1-3.3,5c-7.2,5.7-14.3,7-26.2,9.6c-11.9,2.6-24.2,2-29.9-3.4
+				c-1.9-1.8-3.3-3.8-4.1-5.9c3.2,0.9,9.6,2.1,20.5,0.9C306.4,477.2,325.3,474.3,340.2,472z"/>
+		</g>
+        <g id="XMLID_41_">
+			<path id="XMLID_49_" fill="#FEA691" d="M330.2,453.6c-11.9,4-10.6,11.9-8.8,19.6c1.8,7.7,16.6,27.5,21.1,28.5s4.8-0.8,3.6-4.5
+				c-1.2-3.7-9.7-16.6-9.7-16.6s9.4,12.8,13.3,16.6c3.9,3.8,7.2,3.5,7.1-0.7c-0.2-4.2-9.5-18.3-9.5-18.3s8.2,10.8,11.6,14.5
+				s7.9,3.1,6.3-1.9c-1.5-5-8.3-15.9-8.3-15.9s6.6,11,11,12.1c4.4,1.1,1.7-5.5-3-13.9C360.3,464.5,345,448.6,330.2,453.6z"/>
+            <path id="XMLID_50_" fill="#FEA691" d="M320.2,464.6c0,0-2.5,9.8-0.9,18.4s4.3,10.3,6.1,10.7s2.4-1.9,1.5-5.6
+				c-0.9-3.7,1.5-11,1.5-11S325.8,462.4,320.2,464.6z"/>
+		</g>
+	</g>
+</g>
+    <g id="BODY">
+	<g id="XMLID_70_">
+		<path id="XMLID_45_" fill="#FEC272" d="M273.1,496H172.2c0,0-13.9-97.2-5.1-121.1c2.5-6.8,5.8-12.3,9.6-16.9
+			c9.5-11.6,21.7-16.9,30-19c10.9-2.8,20.4-2.9,28.6-0.9c21.8,5.2,33.9,25.1,37.8,46.8C278.5,414.8,273.1,496,273.1,496z"/>
+        <path id="XMLID_43_" fill="#F9B35F" d="M207.6,358.5c-13.2,3.4-25.3,3-31-0.5c9.5-11.6,21.7-16.9,30-19
+			c10.9-2.8,20.4-2.9,28.6-0.9C237,344.9,224.6,354.1,207.6,358.5z"/>
+	</g>
+</g>
+    <g id="RIGHT_ARM_1">
+	<g id="XMLID_16_">
+		<path id="XMLID_278_" fill="#FFCD92" d="M199,381.3c0,1.6-0.1,3.2-0.4,4.7c-4.1,26.6-27.7,90.6-27.7,90.6c-1.7,5.1-5.3,8.9-9.7,11
+			c-4.4,2-9.5,2.4-14.4,0.5c-7.6-3-11.2-10.2-11.2-18.1c0-1.7,0.2-3.4,0.5-5.1c6.9-37.3,19.2-68.2,29.3-90
+			c4.4-9.6,15.2-15.6,24.7-10.8c2.9,1.4,4.9,3.7,6.4,6.3C198.3,373.6,199,377.4,199,381.3z"/>
+        <path id="XMLID_273_" fill="#FCB765" d="M199,381.3c0,1.6-0.1,3.2-0.4,4.7c-4.1,26.6-27.7,90.6-27.7,90.6c-1.7,5.1-5.3,8.9-9.7,11
+			l35.2-117.3C198.3,373.6,199,377.4,199,381.3z"/>
+	</g>
+</g>
+    <g id="RIGHT_ARM_2">
+	<g id="XMLID_17_">
+		<g id="XMLID_20_">
+			<path id="XMLID_285_" fill="#FFCD92" d="M230.5,487.4c-2.2,5.4-9.4,5.6-9.4,5.6s-20.2,1.2-37.7,1.2c-17.5,0-34.7,0-41.7-7.9
+				c-1.4-1.6-2.5-3.4-3.1-5.3c-2.6-7.3,0.7-16,11.1-20.4c7.5-3.2,16.1-2.1,25.5-1.2c9.4,0.9,27.5,5.1,38,7.9
+				c10.6,2.7,16.9,5.4,17.8,15.4C231.3,484.6,231,486.1,230.5,487.4z"/>
+            <path id="XMLID_284_" fill="#FCB765" d="M230.5,487.4c-2.2,5.4-9.4,5.6-9.4,5.6s-20.2,1.2-37.7,1.2c-17.5,0-34.7,0-41.7-7.9
+				c-1.4-1.6-2.5-3.4-3.1-5.3c7.8,2.4,18.3,5.2,26.7,5.9C189,488.9,220.4,487.9,230.5,487.4z"/>
+		</g>
+        <g id="XMLID_2_">
+			<g id="XMLID_18_">
+				<path id="XMLID_47_" fill="#FEA691" d="M251.6,471.3c0,1.6-0.2,3.3-0.6,5.1c-2.1,8.6-13.2,15.2-30.1,16.1
+					c-7.5,0.4-12.6,0.4-16-0.4c-4.4-1.1-6.1-3.7-6.5-9.1c-0.5-6.9,4.7-13.2,8.6-15.9c11.7-7.9,22.6-8.5,32.1-7.6
+					C247.6,460.4,251.5,465.1,251.6,471.3z"/>
+                <path id="XMLID_44_" fill="#FC8172" d="M251.6,471.3c0,1.6-0.2,3.3-0.6,5.1c-2.1,8.6-13.2,15.2-30.1,16.1
+					c-7.5,0.4-12.6,0.4-16-0.4c-0.4-1-0.7-2.2-0.8-3.7c-0.5-5.9,4.4-11.4,8.2-13.7c11.1-6.8,21.5-7.4,30.5-6.5
+					C246.8,468.5,249.7,469.6,251.6,471.3z"/>
+			</g>
+            <g id="XMLID_19_">
+				<path id="XMLID_48_" fill="#C7DCF9" d="M264.7,488.7c0,1.1-0.2,2.1-0.5,3.2h-55c-0.3-1-0.5-2.1-0.5-3.2c0-9.6,12.5-17.4,28-17.4
+					C252.2,471.3,264.7,479.1,264.7,488.7z"/>
+                <path id="XMLID_254_" opacity="0.55" fill="#C7DCF9" d="M263.5,490.2c0,0.6-0.1,1.1-0.4,1.7h-50.3c-0.3-0.6-0.4-1.1-0.4-1.7
+					c0-5.1,11.4-9.3,25.5-9.3C252.1,480.9,263.5,485.1,263.5,490.2z"/>
+			</g>
+            <g id="XMLID_37_">
+				<path id="XMLID_28_" fill="#FEA691" d="M252.6,456.6c3.6,0.4,6.1,2.7,7.5,7.5c1.4,4.8,1.7,11.9,0.2,14.4
+					c-1.5,2.5-4.3,3.6-7.4,1.1c-3.1-2.5-4.8-9.5-5.8-13C245.9,462,244.5,455.8,252.6,456.6z"/>
+                <g id="XMLID_4_">
+					<path id="XMLID_38_" fill="#FEA691" d="M239.2,454.3c3.9,0.4,5.5,3.7,7,8.7c1.5,5,1.8,12.6,0.2,15.3c-1.6,2.6-4.6,3.8-7.9,1.2
+						c-3.3-2.6-5.2-10.1-6.2-13.8C231,460.8,230.4,453.5,239.2,454.3z"/>
+                    <path id="XMLID_79_" fill="#FF8D76" d="M243.1,480.8c-1.4,0.3-3,0-4.6-1.4c-3.3-2.6-5.1-10.1-6.2-13.8c-1.1-4-1.7-9.7,3-11.1
+						c-0.9,2.7-0.4,6.4,0.3,9.2c1,4.3,2.9,13,6.2,16C242.3,480.2,242.7,480.6,243.1,480.8z"/>
+				</g>
+                <path id="XMLID_39_" fill="#FEA691" d="M224.6,456.6c3.9,0.4,6.5,2.9,8,7.9s1.8,12.6,0.2,15.3c-1.6,2.6-4.6,3.8-7.9,1.2
+					c-3.3-2.6-5.2-10.1-6.2-13.8C217.4,462.3,215.9,455.7,224.6,456.6z"/>
+                <path id="XMLID_81_" fill="#FF8D76" d="M228.5,482.4c-1.1,0-2.3-0.5-3.5-1.5c-3.3-2.6-5.1-10.1-6.2-13.8
+					c-1-3.8-2.2-8.6,1.5-10.2c-0.3,2.5,0.4,5.7,1.1,8.3c1.2,4.5,3.3,13.7,7,17C228.4,482.4,228.4,482.4,228.5,482.4z"/>
+                <path id="XMLID_40_" fill="#FEA691" d="M211.5,459.4c3.4-1,6,2.7,7.3,7.3c1.3,4.6,1.7,11.6,0.2,14c-1.4,2.4-4.2,3.5-7.2,1.1
+					c-3-2.4-3.8-7-4.7-10.4C205.9,467,204.9,461.4,211.5,459.4z"/>
+                <path id="XMLID_82_" fill="#FF8D76" d="M215.2,483.2c-1.1,0-2.2-0.4-3.4-1.4c-3-2.4-3.8-7-4.7-10.4c-1.1-3.8-1.9-8.5,2.1-11
+					c-0.3,2.7,0.2,5.6,0.7,8.2c0.9,4.6,1.6,10.9,5,14.3C215,483,215.1,483.1,215.2,483.2z"/>
+                <path id="XMLID_78_" fill="#FF8D76" d="M256.8,480.9c-1.2,0.1-2.5-0.3-3.8-1.4c-3.1-2.5-4.8-9.5-5.8-13c-1-3.7-2.2-8.5,1.8-9.7
+					c0,2.2,0.5,4.7,1,6.9c1,4.5,2.9,13.5,6.1,16.7C256.4,480.6,256.6,480.8,256.8,480.9z"/>
+			</g>
+		</g>
+	</g>
+</g>
+    <g id="HEAD">
+	<g id="XMLID_89_">
+		<path id="XMLID_6_" fill="#FF8D76"
+              d="M208.8,235c0,0,9.3-3.8,15.6,8.8c6.3,12.7-0.5,20.8-0.5,20.8S217.7,246.3,208.8,235z"/>
+        <path id="XMLID_173_" fill="#FEA691" d="M215.2,350.9c-8.8,4.1-14.9-1.6-14.9-1.6l-5.5-11.9l-9.9-21.4c14.9-3.2,27.9-5.7,27.9-5.7
+			l2.3,9.5l4.3,17.7C219.2,337.6,224,346.9,215.2,350.9z"/>
+        <path id="XMLID_171_" fill="#FF8D76" d="M215,319.9c-1.3,1.9-2.7,3.9-4.4,5.8c-4.3,5.1-10.5,9-15.9,11.7l-9.9-21.4
+			c14.9-3.2,27.9-5.7,27.9-5.7L215,319.9z"/>
+
+        <ellipse id="XMLID_3_" transform="matrix(0.8545 -0.5194 0.5194 0.8545 -114.0092 131.008)"
+                 fill="#FEA691" cx="176.9" cy="269" rx="47.2" ry="57.7"/>
+        <path id="XMLID_12_" fill="#FF8D76" d="M217.4,308.8c-2.9,3.7-6.5,6.9-10.6,9.5c-22.3,13.5-53.7,2.4-70.3-24.8
+			c-16.4-26.9-12-59.6,9.7-73.4c-12.6,16.2-13.2,42.2,0.3,64.3c16.5,27.2,48,38.3,70.3,24.8C217,309.1,217.2,309,217.4,308.8z"/>
+        <path id="XMLID_5_" fill="#283575" d="M157.2,309.5c0,0-17-13.4-21.3-37.4s0.5-33.7,20.2-45.3c19.7-11.5,34.4-7.4,34.4-7.4
+			s-14-10.5-36.9-6.6c-22.9,3.8-46.2,25.6-41.4,58.4C117.2,306.2,138,316.5,157.2,309.5z"/>
+        <path id="XMLID_11_" fill="#F76F59" d="M177.8,246.8c-2.7,1.9,1.1,12,9.3,19.5c8.2,7.5,16.1,3.6,16.3-3.8
+			C203.6,254.9,187.1,240.2,177.8,246.8z"/>
+        <path id="XMLID_7_" fill="#FF8D76"
+              d="M137.5,291.4c0,0-16,15.7-1.6,29.4c13.8,13.1,31.2-4.5,31.2-4.5S142.7,303.2,137.5,291.4z"
+        />
+        <path id="XMLID_250_" fill="#F76F59"
+              d="M139.4,300.5c0,0-9,8.8-0.9,16.6c7.8,7.4,17.6-2.5,17.6-2.5S142.3,307.2,139.4,300.5z"/>
+	</g>
+</g>
+    <g id="HAIR">
+	<g id="XMLID_84_">
+		<path id="XMLID_8_" fill="#283575" d="M188.5,218.1c0,0,1.7-30.2-15.5-42.5c-19.4-13.8-30.3,6.1-23.9,22.4
+			c2.8,7.3,5.8,11.7,8.2,14.3c2.2,2.4,5.2,3.8,8.4,4L188.5,218.1z"/>
+        <path id="XMLID_9_" fill="#283575" d="M122.7,192.6c-15.3,12.2-2.1,29.7,4.2,34.4c2.7,2,5.6,3.6,8.1,4.8c3.4,1.6,7.4,1.4,10.6-0.6
+			l21.6-13.7C167.2,217.6,143,176.5,122.7,192.6z"/>
+        <path id="XMLID_51_" fill="#3C4E8E"
+              d="M159,172.3c-4.8,0.6,0.5,9.8,7.5,11S171.3,170.8,159,172.3z"/>
+        <path id="XMLID_61_" fill="#3C4E8E"
+              d="M128.7,192.8c-2.8,3.2,4.5,7.3,10.4,5.3C145.1,196.2,134.9,185.8,128.7,192.8z"/>
+	</g>
+</g>
+    <g id="MOUTH">
+	<g id="XMLID_83_">
+		<path id="XMLID_177_" fill="#F76F59" d="M217.7,285c-0.5,1-1.2,1.9-2.2,2.7c-3.7,2.9-6.5,7.1-8.5,11.5c-1.8,3.9-6.4,8.5-10.7,5.2
+			c-0.5-0.4-1-0.8-1.4-1.4c-4.5-5.7-2.8-20.4,4.2-26.9c5.4-5,12.1-3.7,15.5-0.9C217.9,277.7,219.3,281.7,217.7,285z"/>
+        <path id="XMLID_175_" fill="#FF6EA9" d="M217.7,285c-0.5,1-1.2,1.9-2.2,2.7c-3.7,2.9-6.5,7.1-8.5,11.5c-1.8,3.9-6.4,8.5-10.7,5.2
+			c0-6.3,2.3-13.7,6.7-17.7C208.1,282.1,214.1,282.7,217.7,285z"/>
+	</g>
+</g>
+    <g id="EYE_1">
+	<g id="XMLID_14_">
+		<path id="XMLID_86_" fill="#1C3177" d="M155.8,267.7c-3.2,0-5.7-1-5.9-1.1c-1.3-0.5-1.9-2-1.4-3.3c0.5-1.3,2-1.9,3.3-1.4
+			c0.1,0,5.6,2.2,8.6-1.1c3.9-4.1-0.2-9.4-0.3-9.6c-0.9-1.1-0.7-2.7,0.4-3.6c1.1-0.9,2.7-0.7,3.6,0.4c2.4,3.1,5.5,10.4,0,16.2
+			C161.6,266.9,158.5,267.7,155.8,267.7z"/>
+	</g>
+</g>
+    <g id="EYE_2">
+	<g id="XMLID_15_">
+		<path id="XMLID_85_" fill="#1C3177" d="M193,242.6c-5.1,0-9.4-3.8-9.7-4c-1.1-0.9-1.1-2.6-0.2-3.6c0.9-1,2.5-1.1,3.6-0.2
+			c0,0,4.6,3.9,8,2.4c1.5-0.7,0.4-3.8,0.3-3.9c-0.5-1.3,0.1-2.8,1.5-3.3c1.3-0.5,2.8,0.1,3.3,1.4c1.5,3.7,1.1,8.6-3,10.4
+			C195.5,242.4,194.2,242.6,193,242.6z"/>
+	</g>
+</g>
+    <g id="EYEBROW_1">
+	<g id="XMLID_1_">
+		<path id="XMLID_88_" fill="#1C3177" d="M142.4,261.7c-0.1,0-0.2,0-0.3,0c-1.4-0.2-2.4-1.4-2.3-2.8c0-0.3,0.7-6.3,4.9-12.4
+			c4.1-6.1,8.3-8.2,8.5-8.3c1.3-0.6,2.8-0.1,3.4,1.2c0.6,1.3,0.1,2.8-1.2,3.4c0,0-3.2,1.7-6.5,6.5c-3.4,5-4,10-4,10.1
+			C144.8,260.7,143.7,261.7,142.4,261.7z"/>
+	</g>
+</g>
+    <g id="EYEBROW_2">
+	<g id="XMLID_13_">
+		<path id="XMLID_87_" fill="#1C3177" d="M179,232.1c-0.7,0-1.5-0.3-2-0.9c-0.9-1.1-0.7-2.7,0.4-3.6c0.3-0.2,2.6-2.1,6.7-3.3
+			c4.1-1.2,7.5-1.1,7.6-1.1c1.4,0,2.5,1.2,2.5,2.6c0,1.4-1.3,2.5-2.6,2.5c0,0-2.7-0.1-6,0.9c-3.2,1-5,2.4-5,2.4
+			C180.1,231.9,179.6,232.1,179,232.1z"/>
+	</g>
+</g>
+    <g id="TABLE">
+	<g id="XMLID_248_">
+		<path id="XMLID_22_" fill="#99ADF9" d="M505.9,506.3H98.3c-4,0-7.2-3.2-7.2-7.2l0,0c0-4,3.2-7.2,7.2-7.2h407.6
+			c4,0,7.2,3.2,7.2,7.2l0,0C513.1,503,509.9,506.3,505.9,506.3z"/>
+        <path id="XMLID_198_" fill="#789FEF" d="M505.2,506.3H157.1c-4,0-7.2-3.2-7.2-7.2l0,0c0-4,3.2-7.2,7.2-7.2h348.1
+			c4,0,7.2,3.2,7.2,7.2l0,0C512.5,503,509.2,506.3,505.2,506.3z"/>
+	</g>
+</g>
+    <g id="DESKTOP">
+	<g id="XMLID_186_">
+		<g id="XMLID_182_">
+			<path id="XMLID_25_" fill="#E1ECFF" d="M457.6,444.7h-186c-3.3,0-5.9-3-5.3-6.3l19.8-118.7c0.4-2.6,2.7-4.5,5.3-4.5h186
+				c3.3,0,5.9,3,5.3,6.3L463,440.2C462.5,442.8,460.3,444.7,457.6,444.7z"/>
+            <path id="XMLID_29_" fill="#C7DCF9" d="M461.6,444.7H278c-3.3,0-5.9-3-5.3-6.3l19.8-118.7c0.4-2.6,2.7-4.5,5.3-4.5h183.6
+				c3.3,0,5.9,3,5.3,6.3l-19.8,118.7C466.5,442.8,464.2,444.7,461.6,444.7z"/>
+            <path id="XMLID_31_" fill="#B7D4F7" d="M442.2,432H302c-2.6,0-4.5-2.3-4.1-4.8l15.1-90.6c0.3-2,2.1-3.5,4.1-3.5h140.1
+				c2.6,0,4.5,2.3,4.1,4.8l-15.1,90.6C445.9,430.5,444.2,432,442.2,432z"/>
+		</g>
+        <g id="XMLID_183_">
+			<path id="XMLID_24_" fill="#E1ECFF" d="M382.3,484.5h-25.5c-2.4,0-4.2-2-4-4.4l6.7-66.5c0.2-2,1.9-3.6,4-3.6H389
+				c2.4,0,4.2,2,4,4.4l-6.7,66.5C386.1,483,384.4,484.5,382.3,484.5z"/>
+            <path id="XMLID_26_" fill="#C7DCF9" d="M384.1,484.5h-23.4c-1.5,0-2.7-1.3-2.6-2.8l7-69.4c0.1-1.3,1.2-2.3,2.6-2.3h23.4
+				c1.5,0,2.7,1.3,2.6,2.8l-7,69.4C386.5,483.5,385.4,484.5,384.1,484.5z"/>
+		</g>
+        <g id="XMLID_185_">
+			<path id="XMLID_27_" fill="#E1ECFF" d="M424.7,491.8H318.5c-2.2,0-4-1.8-4-4V479c0-2.2,1.8-4,4-4h106.2c2.2,0,4,1.8,4,4v8.8
+				C428.7,490,426.9,491.8,424.7,491.8z"/>
+            <path id="XMLID_30_" fill="#C7DCF9" d="M426.9,491.8H327c-2.3,0-4.2-1.9-4.2-4.2v-8.4c0-2.3,1.9-4.2,4.2-4.2h99.9
+				c2.3,0,4.2,1.9,4.2,4.2v8.4C431,489.9,429.2,491.8,426.9,491.8z"/>
+		</g>
+	</g>
+</g>
+    <g id="SIGN">
+	<g id="XMLID_21_">
+		<path id="XMLID_77_" fill="#FF97C9" d="M501.5,298.7c-1,0.7-2.3,1.2-3.7,1.2H402c-4.8,0-7.8-5-5.6-9.3l34.8-66.9l12.8-24.6
+			c2.4-4.5,8.8-4.5,11.2,0l48.2,91.5C505,293.6,503.9,297,501.5,298.7z"/>
+        <path id="XMLID_74_" fill="#FC72BB" d="M501.5,298.7c-1,0.7-2.3,1.2-3.7,1.2H402c-4.8,0-7.8-5-5.6-9.3l34.8-66.9L420.6,280
+			c-0.9,4.8,2.4,9.3,7.3,9.9L501.5,298.7z"/>
+        <g id="XMLID_32_">
+			<g id="XMLID_34_">
+				<path id="XMLID_35_" fill="#FFFFFF" d="M445.2,264.1l-5-35.8c-0.2-1.2,0.8-2.3,2-2.3h14.2c1.2,0,2.1,1.1,2,2.3l-5,35.8
+					c-0.1,1-1,1.7-2,1.7h-4.3C446.1,265.9,445.3,265.1,445.2,264.1z"/>
+			</g>
+            <circle id="XMLID_33_" fill="#FFFFFF" cx="449.3" cy="279.1" r="7.1"/>
+		</g>
+	</g>
+</g>
+    <g id="STAR">
+	<path id="XMLID_195_" fill="#FEC272" d="M189.7,141.2l1.8,3.7c0.2,0.5,0.7,0.8,1.2,0.8l4,0.6c1.3,0.2,1.8,1.7,0.8,2.6l-2.9,2.8
+		c-0.4,0.4-0.5,0.9-0.4,1.4l0.7,4c0.2,1.2-1.1,2.2-2.2,1.6l-3.6-1.9c-0.4-0.2-1-0.2-1.4,0l-3.6,1.9c-1.1,0.6-2.4-0.4-2.2-1.6l0.7-4
+		c0.1-0.5-0.1-1-0.4-1.4l-2.9-2.8c-0.9-0.9-0.4-2.4,0.8-2.6l4-0.6c0.5-0.1,0.9-0.4,1.2-0.8l1.8-3.7
+		C187.5,140.1,189.1,140.1,189.7,141.2"/>
+</g>
+    <g id="BUBBLE_1">
+	<path id="XMLID_23_" fill="#F0F6FF" d="M384.3,170.2c0,13.8-4,26.6-10.9,37.5c0,0,0,0,0,0c-2.5,5.8-15.1,30.3-57.9,49.9
+		c-44.9,20.6-84.7,5.9-84.7,5.9s24.5-16.1,19.9-43c-3.6-21.2-6.1-36.4-5.9-49.2c0-0.4,0-0.7,0-1.1c0-38.5,31.2-69.7,69.7-69.7
+		S384.3,131.7,384.3,170.2z"/>
+</g>
+    <g id="BUBBLE_2">
+	<path id="XMLID_187_" fill="#C7DCF9" d="M238.1,216.5c-3.7-9.5-7.4-9.1-9.9-7.3c-2.3,1.7-2.8,7.6,0,13.2s5.6,5.2,8.4,3.7
+		S239.8,220.9,238.1,216.5z"/>
+</g>
+    <g id="BUBBLE_3">
+	<path id="XMLID_249_" fill="#C7DCF9" d="M361.6,237.5c-15.4,8.2-14,14.5-10.4,18.3c3.4,3.6,13.5,3.2,22.4-2.6s7.8-10.5,4.7-15
+		C375.2,233.7,368.7,233.6,361.6,237.5z"/>
+</g>
+    <g id="Layer_23">
+	<g id="XMLID_75_">
+		<g id="XMLID_73_">
+			<path id="XMLID_274_" fill="#99ADF9" d="M364.6,191.8c0,3.8-1.8,7.6-5.2,9.9c-7.4,5.2-19.2,12.9-32.2,19.7
+				c-8.3,4.4-15.5,7.8-21.3,10.3c-4.8,2.1-10.1,1.7-14.4-0.7c-2.9-1.6-5.3-4.1-6.8-7.3c-1-2.2-1.6-4.6-1.6-7c0-2,0.4-4,1.1-6
+				l0.4-1.1l17.2-43.6l-23,12.4c-6.4,3.4-14.3,1.2-18-5.1c-0.1-0.2-0.2-0.4-0.3-0.6c-1-2-1.5-4.1-1.5-6.2c0-4.4,2.2-8.8,6.2-11.3
+				c7.3-4.7,17.9-11.1,30.5-17.8c24.2-12.9,36.2-11.3,39.6-4.8c3.4,6.6-16.1,61.8-16.1,61.8s26.1-13.1,28.9-14.1
+				c6-2.3,12.7,0.5,15.4,6.3c0.6,1.3,0.9,2.7,1,4.1C364.6,191.2,364.6,191.5,364.6,191.8z"/>
+            <path id="XMLID_267_" fill="#7D9AF9" d="M309.1,158.8c-5.8,14.3-19.5,47.2-24.3,50.9l17.2-43.6l-23,12.4
+				c-6.4,3.5-14.5,1.2-18.1-5.2c0.2-0.2,0,0,0.2-0.2c2.3,1.1,6.4,2.1,12.5-0.9c11.4-5.4,24.4-12.5,31.9-16.6
+				C307.6,154.5,310,156.6,309.1,158.8z"/>
+            <path id="XMLID_264_" fill="#7D9AF9" d="M364.6,191.8c0,3.8-1.8,7.6-5.2,9.9c-7.4,5.2-19.2,12.9-32.2,19.7
+				c-8.3,4.4-15.5,7.8-21.3,10.3c-4.8,2.1-10.1,1.7-14.4-0.7c0.9-0.2,1.8-0.4,2.6-0.7c4.5-1.5,24.8-12.2,44.7-22.9
+				c13-7,21.8-12.6,25.7-16.4C364.6,191.2,364.6,191.5,364.6,191.8z"/>
+		</g>
+        <path id="XMLID_76_" opacity="0.49" fill="#FFFFFF" d="M314.2,131.6c-9,3-13.6,8.6-2.8,8s16.5-6.1,14.6-7.9
+			C324.1,130,318.3,130.2,314.2,131.6z"/>
+        <path id="XMLID_80_" opacity="0.49" fill="#FFFFFF" d="M348.7,182.6c-5.7,1.9-8.7,5.5-1.8,5.1c6.9-0.4,10.5-3.9,9.3-5
+			C354.9,181.6,351.3,181.7,348.7,182.6z"/>
+	</g>
+</g>
+</svg>

BIN=BIN
src/assets/images/account-logo.png


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 156 - 0
src/assets/images/analysis.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 100 - 0
src/assets/images/exception/403.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 115 - 0
src/assets/images/exception/404.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 111 - 0
src/assets/images/exception/500.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 133 - 0
src/assets/images/exception/developing.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 178 - 0
src/assets/images/exception/load-error.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 106 - 0
src/assets/images/exception/nodata.svg


+ 49 - 0
src/assets/images/header-theme-dark.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 5 Copy 5</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox"
+                id="filter-1">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0" type="matrix"
+                           in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
+        <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox"
+                id="filter-4">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix"
+                           in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="setting-copy-2" transform="translate(-1190.000000, -136.000000)">
+            <g id="Group-8" transform="translate(1167.000000, 0.000000)">
+                <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
+                    <mask id="mask-3" fill="white">
+                        <use xlink:href="#path-2"></use>
+                    </mask>
+                    <g id="Rectangle-18">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    </g>
+                    <rect id="Rectangle-11" fill="#303648" mask="url(#mask-3)" x="-1" y="0" width="49"
+                          height="10"></rect>
+                    <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16"
+                          height="44"></rect>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 10 - 0
src/assets/images/login-bg.svg


BIN=BIN
src/assets/images/login-pic.png


+ 127 - 0
src/assets/images/login.svg

@@ -0,0 +1,127 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1361px"
+     height="609px" viewBox="0 0 1361 609" version="1.1">
+    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 21</title>
+    <desc>Created with Sketch.</desc>
+    <defs/>
+    <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
+            <g id="Group-21" transform="translate(77.000000, 73.000000)">
+                <g id="Group-18" opacity="0.8"
+                   transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
+                    <ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367"
+                             rx="21.7830479" ry="21.766008"/>
+                    <ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601"
+                             rx="5.2173913" ry="5.21330997"/>
+                    <path
+                            d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z"
+                            id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"/>
+                    <path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6"
+                          stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"/>
+                    <path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7"
+                          stroke-width="0.702678964" opacity="0.7" stroke-linecap="round"
+                          stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"/>
+                    <path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9"
+                          stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round"
+                          stroke-dasharray="1.405357899873153,2.108036953469981"/>
+                    <g id="Group-17"
+                       transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)"
+                       fill="#CFDAE6">
+                        <ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653"
+                                 ry="9.12768076"/>
+                        <path
+                                d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z"
+                                id="Oval-4"
+                                transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "/>
+                    </g>
+                </g>
+                <g id="Group-14"
+                   transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439"
+                             rx="29.1176471" ry="29.1402439"/>
+                    <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439"
+                             rx="21.5686275" ry="21.5853659"/>
+                    <ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341"
+                             rx="23.7254902" ry="23.7439024"/>
+                    <ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439"
+                             rx="10.7843137" ry="10.7926829"/>
+                    <path
+                            d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z"
+                            id="Oval-2" fill="#BACAD9"/>
+                    <g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)"
+                       fill="#E6A1A6">
+                        <ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824"
+                                 ry="6.47560976"/>
+                        <path
+                                d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z"
+                                id="Oval-2-Copy-2"
+                                transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "/>
+                    </g>
+                    <ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706"
+                             ry="1.61890244"/>
+                    <ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098"
+                             rx="1.61764706" ry="1.61890244"/>
+                    <ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488"
+                             rx="2.15686275" ry="2.15853659"/>
+                    <path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6"
+                          opacity="0.8"/>
+                </g>
+                <g id="Group-10" opacity="0.799999952"
+                   transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
+                    <ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32"
+                             rx="11.1864407" ry="11.2941176"/>
+                    <g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
+                        <ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627"
+                                 ry="8.55614973"/>
+                        <path
+                                d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z"
+                                id="Oval-7"/>
+                    </g>
+                    <path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6"
+                          stroke-width="0.941176471"/>
+                    <ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186"
+                             cy="3.29411765" rx="3.26271186" ry="3.29411765"/>
+                    <ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017"
+                             ry="2.82352941"/>
+                    <path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6"
+                          stroke-width="0.941176471"/>
+                </g>
+                <g id="Group-19" opacity="0.33"
+                   transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
+                    <g id="Group-17"
+                       transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)"
+                       fill="#BACAD9">
+                        <circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"/>
+                        <path
+                                d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z"
+                                id="Oval-4"
+                                transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "/>
+                    </g>
+                    <circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"/>
+                    <path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667"
+                              points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"/>
+                    <path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7"
+                          stroke-width="1.16666667" opacity="0.6"/>
+                    <path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9"
+                          stroke-width="1.16666667"/>
+                    <path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6"
+                          stroke-width="1.16666667"/>
+                    <circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"/>
+                    <circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"/>
+                    <circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25"
+                            r="8.75"/>
+                    <circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333"
+                            cy="30.3333333" r="5.83333333"/>
+                    <circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"/>
+                </g>
+            </g>
+        </g>
+    </g>
+    <div xmlns="" id="divScriptsUsed" style="display: none"/>
+    <script xmlns="" id="globalVarsDetection"
+            src="chrome-extension://cmkdbmfndkfgebldhnkbfhlneefdaaip/js/wrs_env.js"/>
+</svg>

BIN=BIN
src/assets/images/logo.png


+ 15 - 0
src/assets/images/nav-horizontal-mix.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="52px" height="45px" viewBox="0 0 52 45" enable-background="new 0 0 52 45" xml:space="preserve">  <image id="image0" width="52" height="45" x="0" y="0"
+    href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAtCAMAAADWf7iKAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
+AAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAdVBMVEX///8AAABkbnc9RVY7
+QE9fY3GIiJZjbHk9QFOCi5QAAAA9QlZfZHMAAAA4QFEAAADt7/Lf5OTt7/KChoYAAADu8PTf3+Nw
+c3MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyNUkyOEn////w8vWhURXFAAAAI3RS
+TlMAAE/2/uZJUP45AvfkBP4F9LrwPwP0vUkOAREsNjk0JwYHCLrjEiIAAAABYktHRACIBR1IAAAA
+CXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QgGAhE5kB5L+gAAAIZJREFUSMft1rsSgjAQhWEW
+FTUYIopKlPui7/+IZqFhbMxmhm7//qvPiaKgAOIN+rbdJQCE9qO3cR2OhFTKMYgn5ZDmGcy0Q4aJ
+0AhaoPdPnz8JEiRIkKCV0DkE5YQ0D12uBQ01B93uj9LSJdDPV1V71rRlMf0Iq7p+8Kw3aj4fAJYR
+TCigL0lMJ5P4y7LRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTA4LTA2VDAyOjE3OjU2KzAwOjAw
+Kbo8/wAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMS0wOC0wNlQwMjoxNzo1NiswMDowMFjnhEMAAAAA
+SUVORK5CYII=" />
+</svg>

+ 26 - 0
src/assets/images/nav-horizontal.svg

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="52px" height="45px"
+     viewBox="0 0 52 45" enable-background="new 0 0 52 45" xml:space="preserve">  <image id="image0"
+                                                                                         width="52"
+                                                                                         height="45"
+                                                                                         x="0" y="0"
+                                                                                         href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAtCAMAAADWf7iKAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
+AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAkFBMVEX+/v78/Pz6+vr39/f0
+9PTx8fHv7+/u7u729vbHyc1ESVsxNkgwNkg7QFFscH3T1NfGyMwxN0k9QlPa3N5vdID4+Pjz8/Pr
+6+s6QVLw8PDm5ubk5OTy8vLj4+Pt7e3u8PPw8vXu8PTn5+fw8fXs7Oz5+fnp6ene3t7b29vc3Nzf
+39/q6ur7+/vo6Oj9/f3///855aJlAAAAAWJLR0QvI9QgEQAAAAd0SU1FB+UHAxEtKCKzaD0AAAC8
+SURBVEjH7dbLGoIgEIbhEUHI6JyYgmWWnTzd/92FTzcws2vBt38f2P0DELGYi0SiSgSPWQTeqEW6
+1MhW643yiqntDkvm9gfFIBYpxWh9FBmYHP23X6dcQVHSjNYlB2mpyDqQFRVVDs7/ji41rYACCiig
+gHBIWiqyxo/alYga7ufzRkR35YeaaGrX+pOgeFTPF673x3Yi7ueDxcluKDE1Qy5N1o8AY98qbgQm
+Z+Yrx5sJxqhnrEXF2PzM9AV+UvDCWyYgmAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNy0wM1Qw
+OTo0NTo0MCswODowMOjZqbAAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDctMDNUMDk6NDU6NDAr
+MDg6MDCZhBEMAAAAIHRFWHRzb2Z0d2FyZQBodHRwczovL2ltYWdlbWFnaWNrLm9yZ7zPHZ0AAAAY
+dEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAXdEVYdFRodW1iOjpJbWFnZTo6SGVp
+Z2h0ADQ1+dH7kAAAABZ0RVh0VGh1bWI6OkltYWdlOjpXaWR0aAA1MoYBn/8AAAAZdEVYdFRodW1i
+OjpNaW1ldHlwZQBpbWFnZS9wbmc/slZOAAAAF3RFWHRUaHVtYjo6TVRpbWUAMTYyNTI3Njc0MKmy
+pv8AAAASdEVYdFRodW1iOjpTaXplADEzMzJCQoe7yB0AAABGdEVYdFRodW1iOjpVUkkAZmlsZTov
+Ly9hcHAvdG1wL2ltYWdlbGMvaW1ndmlldzJfOV8xNjIzOTEyMDA2MDA1NDY4Ml8yMl9bMF2ZTW7W
+AAAAAElFTkSuQmCC"></image>
+</svg>

+ 49 - 0
src/assets/images/nav-theme-dark.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 5 Copy 5</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox"
+                id="filter-1">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0" type="matrix"
+                           in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
+        <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox"
+                id="filter-4">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix"
+                           in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="setting-copy-2" transform="translate(-1190.000000, -136.000000)">
+            <g id="Group-8" transform="translate(1167.000000, 0.000000)">
+                <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)">
+                    <mask id="mask-3" fill="white">
+                        <use xlink:href="#path-2"></use>
+                    </mask>
+                    <g id="Rectangle-18">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    </g>
+                    <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="-1" y="0" width="49"
+                          height="10"></rect>
+                    <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16"
+                          height="44"></rect>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 49 - 0
src/assets/images/nav-theme-light.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 5</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox"
+                id="filter-1">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.15 0" type="matrix"
+                           in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect>
+        <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox"
+                id="filter-4">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1"
+                            result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix"
+                           in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="setting-copy-2" transform="translate(-1254.000000, -136.000000)">
+            <g id="Group-8" transform="translate(1167.000000, 0.000000)">
+                <g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 137.000000)">
+                    <mask id="mask-3" fill="white">
+                        <use xlink:href="#path-2"></use>
+                    </mask>
+                    <g id="Rectangle-18">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use>
+                    </g>
+                    <rect id="Rectangle-18" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="16"
+                          height="44"></rect>
+                    <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="-1" y="0" width="49"
+                          height="10"></rect>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
src/assets/images/order_count.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
src/assets/images/sale.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 43 - 0
src/assets/images/sales-dashboard.svg


BIN=BIN
src/assets/images/schoolboy.png


BIN=BIN
src/assets/images/tool.png


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
src/assets/images/visits.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
src/assets/images/volume.svg


+ 9 - 0
src/components/Application/Application.vue

@@ -0,0 +1,9 @@
+<template>
+  <ElConfigProvider>
+    <slot></slot>
+  </ElConfigProvider>
+</template>
+
+<script lang="ts" setup>
+  import { ElConfigProvider } from 'element-plus';
+</script>

+ 0 - 0
src/components/Application/index.ts


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio