Browse Source

refactor: refactor dashboard

Vben 4 years ago
parent
commit
8a14069e71
89 changed files with 1446 additions and 2471 deletions
  1. 1 1
      .husky/lintstagedrc.js
  2. 1 0
      CHANGELOG.zh_CN.md
  3. 1 1
      build/vite/alias.ts
  4. 1 1
      build/vite/plugin/html.ts
  5. 14 15
      package.json
  6. 0 0
      src/assets/icons/download-count.svg
  7. 0 0
      src/assets/icons/dynamic-avatar-1.svg
  8. 0 0
      src/assets/icons/dynamic-avatar-2.svg
  9. 0 0
      src/assets/icons/dynamic-avatar-3.svg
  10. 0 0
      src/assets/icons/dynamic-avatar-4.svg
  11. 0 0
      src/assets/icons/dynamic-avatar-5.svg
  12. 0 0
      src/assets/icons/dynamic-avatar-6.svg
  13. 0 0
      src/assets/icons/total-sales.svg
  14. 0 0
      src/assets/icons/transaction.svg
  15. 0 0
      src/assets/icons/visit-count.svg
  16. BIN
      src/assets/images/dashboard/wokb/approve.png
  17. BIN
      src/assets/images/dashboard/wokb/attendance.png
  18. BIN
      src/assets/images/dashboard/wokb/datashow1.png
  19. BIN
      src/assets/images/dashboard/wokb/datashow2.png
  20. BIN
      src/assets/images/dashboard/wokb/datashow3.png
  21. BIN
      src/assets/images/dashboard/wokb/datashow4.png
  22. BIN
      src/assets/images/dashboard/wokb/leave.png
  23. BIN
      src/assets/images/dashboard/wokb/meal.png
  24. BIN
      src/assets/images/dashboard/wokb/overtime.png
  25. BIN
      src/assets/images/dashboard/wokb/performance.png
  26. BIN
      src/assets/images/dashboard/wokb/stamp.png
  27. BIN
      src/assets/images/dashboard/wokb/travel.png
  28. BIN
      src/assets/images/dashboard/wokb/wokb.png
  29. 0 20
      src/assets/svg/dashboard/analysis-down.svg
  30. 0 21
      src/assets/svg/dashboard/analysis-icon1.svg
  31. 0 21
      src/assets/svg/dashboard/analysis-icon2.svg
  32. 0 21
      src/assets/svg/dashboard/analysis-icon3.svg
  33. 0 21
      src/assets/svg/dashboard/analysis-icon4.svg
  34. 0 20
      src/assets/svg/dashboard/analysis-rise.svg
  35. 0 0
      src/assets/svg/illustration.svg
  36. 1 1
      src/components/Basic/src/BasicTitle.vue
  37. 11 0
      src/components/Container/src/collapse/CollapseContainer.vue
  38. 1 1
      src/components/Page/src/PageWrapper.vue
  39. 3 3
      src/components/Scrollbar/src/index.vue
  40. 9 4
      src/components/Tree/src/TreeHeader.vue
  41. 1 1
      src/enums/pageEnum.ts
  42. 2 2
      src/layouts/default/header/components/user-dropdown/index.vue
  43. 1 1
      src/layouts/default/tabs/index.less
  44. 11 1
      src/plugins/echarts/index.ts
  45. 16 4
      src/router/menus/modules/dashboard.ts
  46. 2 1
      src/router/routes/modules/dashboard.ts
  47. 0 9
      src/utils/env.ts
  48. 0 90
      src/views/dashboard/analysis/components/AnalysisBar.vue
  49. 0 94
      src/views/dashboard/analysis/components/AnalysisLine.vue
  50. 0 75
      src/views/dashboard/analysis/components/AnalysisPie.vue
  51. 0 80
      src/views/dashboard/analysis/components/FlowAnalysis.tsx
  52. 31 106
      src/views/dashboard/analysis/components/GrowCard.vue
  53. 69 0
      src/views/dashboard/analysis/components/SalesProductPie.vue
  54. 46 0
      src/views/dashboard/analysis/components/SiteAnalysis.vue
  55. 0 154
      src/views/dashboard/analysis/components/TaskCard.vue
  56. 0 97
      src/views/dashboard/analysis/components/TrendLine.vue
  57. 146 0
      src/views/dashboard/analysis/components/VisitAnalysis.vue
  58. 62 0
      src/views/dashboard/analysis/components/VisitAnalysisBar.vue
  59. 107 0
      src/views/dashboard/analysis/components/VisitRadar.vue
  60. 88 0
      src/views/dashboard/analysis/components/VisitSource.vue
  61. 0 56
      src/views/dashboard/analysis/components/flow-ana.less
  62. 43 0
      src/views/dashboard/analysis/data.ts
  63. 0 107
      src/views/dashboard/analysis/data.tsx
  64. 25 60
      src/views/dashboard/analysis/index.vue
  65. 0 16
      src/views/dashboard/analysis/types.ts
  66. 0 494
      src/views/dashboard/house/index.less
  67. 0 89
      src/views/dashboard/house/index.vue
  68. 0 22
      src/views/dashboard/welcome/index.vue
  69. 37 0
      src/views/dashboard/workbench/components/DynamicInfo.vue
  70. 0 100
      src/views/dashboard/workbench/components/NewsList.vue
  71. 0 101
      src/views/dashboard/workbench/components/ProdTotal.vue
  72. 35 0
      src/views/dashboard/workbench/components/ProjectCard.vue
  73. 26 0
      src/views/dashboard/workbench/components/QuickNav.vue
  74. 107 0
      src/views/dashboard/workbench/components/SaleRadar.vue
  75. 0 102
      src/views/dashboard/workbench/components/ShortCuts.vue
  76. 0 114
      src/views/dashboard/workbench/components/TodoList.vue
  77. 37 0
      src/views/dashboard/workbench/components/WorkbenchHeader.vue
  78. 156 0
      src/views/dashboard/workbench/components/data.ts
  79. 0 48
      src/views/dashboard/workbench/data.ts
  80. 43 35
      src/views/dashboard/workbench/index.vue
  81. 107 0
      src/views/demo/charts/SaleRadar.vue
  82. 7 39
      src/views/demo/charts/apex/SaleRadar.vue
  83. 5 1
      src/views/demo/charts/apex/index.vue
  84. 1 1
      src/views/demo/comp/cropper/index.vue
  85. 3 0
      src/views/demo/feat/icon/index.vue
  86. 1 1
      src/views/demo/page/account/center/index.vue
  87. 1 1
      vite.config.ts
  88. 1 0
      windi.config.ts
  89. 186 218
      yarn.lock

+ 1 - 1
.husky/lintstagedrc.js

@@ -2,7 +2,7 @@ module.exports = {
   '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
   '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
   'package.json': ['prettier --write'],
-  '*.vue': ['prettier --write', 'stylelint --fix'],
+  '*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
   '*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write'],
   '*.md': ['prettier --write'],
 };

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -9,6 +9,7 @@
 
 - 移除 useFullScreen 函数
 - tinymce 由 Cdn 改为 npm(打包体积偏大)
+- Dashboard 重构
 
 ### 🐛 Bug Fixes
 

+ 1 - 1
build/vite/alias.ts

@@ -2,7 +2,7 @@ import { resolve } from 'path';
 import type { Alias } from 'vite';
 
 function pathResolve(dir: string) {
-  return resolve(__dirname, '.', dir);
+  return resolve(process.cwd(), '.', dir);
 }
 
 export function createAlias(alias: [string, string][]): Alias[] {

+ 1 - 1
build/vite/plugin/html.ts

@@ -12,7 +12,7 @@ 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 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()}`;

+ 14 - 15
package.json

@@ -8,8 +8,8 @@
   },
   "scripts": {
     "bootstrap": "yarn install",
-    "serve": "npx --max_old_space_size=4096 vite",
-    "dev": "npx --max_old_space_size=4096 vite",
+    "serve": "cross-env --max_old_space_size=4096 vite",
+    "dev": "cross-env  --max_old_space_size=4096  vite",
     "build": "vite build && esno ./build/script/postBuild.ts",
     "build:no-cache": "yarn clean:cache && npm run build",
     "report": "cross-env REPORT=true npm run build ",
@@ -32,7 +32,7 @@
   },
   "dependencies": {
     "@iconify/iconify": "^2.0.0-rc.6",
-    "@vueuse/core": "^4.6.2",
+    "@vueuse/core": "^4.6.3",
     "@zxcvbn-ts/core": "^0.3.0",
     "ant-design-vue": "^2.1.2",
     "apexcharts": "^3.26.0",
@@ -49,7 +49,7 @@
     "sortablejs": "^1.13.0",
     "tinymce": "^5.7.1",
     "vditor": "^3.8.4",
-    "vue": "3.0.7",
+    "vue": "3.0.10",
     "vue-i18n": "^9.0.0",
     "vue-router": "^4.0.5",
     "vue-types": "^3.0.2",
@@ -60,7 +60,7 @@
   "devDependencies": {
     "@commitlint/cli": "^12.0.1",
     "@commitlint/config-conventional": "^12.0.1",
-    "@iconify/json": "^1.1.322",
+    "@iconify/json": "^1.1.323",
     "@purge-icons/generated": "^0.7.0",
     "@types/crypto-js": "^4.0.1",
     "@types/fs-extra": "^9.0.9",
@@ -72,21 +72,20 @@
     "@types/qs": "^6.9.6",
     "@types/rollup-plugin-visualizer": "^2.6.0",
     "@types/sortablejs": "^1.10.6",
-    "@typescript-eslint/eslint-plugin": "^4.19.0",
-    "@typescript-eslint/parser": "^4.19.0",
+    "@typescript-eslint/eslint-plugin": "^4.20.0",
+    "@typescript-eslint/parser": "^4.20.0",
     "@vitejs/plugin-legacy": "^1.3.2",
-    "@vitejs/plugin-vue": "^1.2.0",
+    "@vitejs/plugin-vue": "^1.2.1",
     "@vitejs/plugin-vue-jsx": "^1.1.2",
-    "@vue/compiler-sfc": "3.0.7",
+    "@vue/compiler-sfc": "3.0.10",
     "autoprefixer": "^10.2.5",
-    "body-parser": "^1.19.0",
     "commitizen": "^4.2.3",
     "conventional-changelog-cli": "^2.1.1",
     "cross-env": "^7.0.3",
     "dotenv": "^8.2.0",
     "eslint": "^7.23.0",
     "eslint-config-prettier": "^8.1.0",
-    "eslint-define-config": "^1.0.5",
+    "eslint-define-config": "^1.0.6",
     "eslint-plugin-prettier": "^3.3.1",
     "eslint-plugin-vue": "^7.8.0",
     "esno": "^0.5.0",
@@ -97,7 +96,7 @@
     "is-ci": "^3.0.0",
     "less": "^4.1.1",
     "lint-staged": "^10.5.4",
-    "postcss": "^8.2.8",
+    "postcss": "^8.2.9",
     "prettier": "^2.2.1",
     "pretty-quick": "^3.1.0",
     "rimraf": "^3.0.2",
@@ -108,17 +107,17 @@
     "stylelint-order": "^4.1.0",
     "ts-node": "^9.1.1",
     "typescript": "4.2.3",
-    "vite": "2.1.3",
+    "vite": "2.1.5",
     "vite-plugin-compression": "^0.2.3",
     "vite-plugin-html": "^2.0.3",
     "vite-plugin-imagemin": "^0.2.9",
-    "vite-plugin-mock": "^2.4.0",
+    "vite-plugin-mock": "^2.4.1",
     "vite-plugin-purge-icons": "^0.7.0",
     "vite-plugin-pwa": "^0.6.4",
     "vite-plugin-style-import": "^0.9.1",
     "vite-plugin-svg-icons": "^0.4.0",
     "vite-plugin-theme": "^0.5.0",
-    "vite-plugin-windicss": "0.11.0",
+    "vite-plugin-windicss": "0.10.4",
     "vue-eslint-parser": "^7.6.0"
   },
   "resolutions": {

File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/download-count.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-1.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-2.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-3.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-4.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-5.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/dynamic-avatar-6.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/total-sales.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/transaction.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/visit-count.svg


BIN
src/assets/images/dashboard/wokb/approve.png


BIN
src/assets/images/dashboard/wokb/attendance.png


BIN
src/assets/images/dashboard/wokb/datashow1.png


BIN
src/assets/images/dashboard/wokb/datashow2.png


BIN
src/assets/images/dashboard/wokb/datashow3.png


BIN
src/assets/images/dashboard/wokb/datashow4.png


BIN
src/assets/images/dashboard/wokb/leave.png


BIN
src/assets/images/dashboard/wokb/meal.png


BIN
src/assets/images/dashboard/wokb/overtime.png


BIN
src/assets/images/dashboard/wokb/performance.png


BIN
src/assets/images/dashboard/wokb/stamp.png


BIN
src/assets/images/dashboard/wokb/travel.png


BIN
src/assets/images/dashboard/wokb/wokb.png


+ 0 - 20
src/assets/svg/dashboard/analysis-down.svg

@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="20px" height="12px" viewBox="0 0 20 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>下跌-24px</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-850.000000, -241.000000)">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Total-Sales" transform="translate(598.000000, 0.000000)">
-                    <g id="8.5%-Up-from-yesterday" transform="translate(16.000000, 114.000000)">
-                        <g id="下跌-24px" transform="translate(0.000000, 1.000000)">
-                            <polygon id="Path" points="0 0 24 0 24 24 0 24"></polygon>
-                            <polygon id="Path" fill="#ED6F6F" fill-rule="nonzero" points="16 18 18.29 15.71 13.41 10.83 9.41 14.83 2 7.41 3.41 6 9.41 12 13.41 8 19.71 14.29 22 12 22 18"></polygon>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 21
src/assets/svg/dashboard/analysis-icon1.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>Icon1@3x</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-419.000000, -136.000000)" fill="#0593FF">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Total-Users">
-                    <g id="Icon1" transform="translate(185.000000, 16.000000)">
-                        <path d="M23,60 C10.2974508,60 1.55561363e-15,49.7025492 0,37 L0,23 C-1.55561363e-15,10.2974508 10.2974508,2.33342044e-15 23,0 L37,0 C49.7025492,-2.33342044e-15 60,10.2974508 60,23 L60,37 C60,49.7025492 49.7025492,60 37,60 L23,60 Z" id="Circle-2" opacity="0.209999993"></path>
-                        <g id="Group" transform="translate(14.000000, 18.000000)" fill-rule="nonzero">
-                            <path d="M24,6.66666667 C26.209139,6.66666667 28,8.45752767 28,10.6666667 C28,12.8758057 26.209139,14.6666667 24,14.6666667 C21.790861,14.6666667 20,12.8758057 20,10.6666667 C20,8.45752767 21.790861,6.66666667 24,6.66666667 Z M12,0 C14.9455187,0 17.3333333,2.38781467 17.3333333,5.33333333 C17.3333333,8.278852 14.9455187,10.6666667 12,10.6666667 C9.05448133,10.6666667 6.66666667,8.278852 6.66666667,5.33333333 C6.66666667,2.38781467 9.05448133,0 12,0 Z" id="Combined-Shape" opacity="0.587820871"></path>
-                            <path d="M23.4686027,16.0012776 L23.3172917,16 C27.927838,16 31.7158139,18.2931929 31.9979916,23.2 C32.0092328,23.3954741 31.9979916,24 31.2745999,24 L26.1333333,24 L26.1333333,24 C26.1333333,20.9989578 25.1418595,18.2294867 23.4686027,16.0012776 Z M11.9777884,13.3333333 C18.3616218,13.3333333 23.6065116,16.3909238 23.9972191,22.9333333 C24.0127839,23.1939654 23.9972191,24 22.9955999,24 L0.97000297,24 L0.97000297,24 C0.635616207,24 -0.027282334,23.2789066 0.000868912387,22.932274 C0.517678033,16.5686878 5.6825498,13.3333333 11.9777884,13.3333333 Z" id="Combined-Shape"></path>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 21
src/assets/svg/dashboard/analysis-icon2.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>Icon2@3x</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-719.000000, -136.000000)">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Total-Order" transform="translate(299.000000, 0.000000)">
-                    <g id="Icon2" transform="translate(186.000000, 16.000000)">
-                        <path d="M23,60 C10.2974508,60 1.55561363e-15,49.7025492 0,37 L0,23 C-1.55561363e-15,10.2974508 10.2974508,2.33342044e-15 23,0 L37,0 C49.7025492,-2.33342044e-15 60,10.2974508 60,23 L60,37 C60,49.7025492 49.7025492,60 37,60 L23,60 Z" id="Circle-2" fill="#FFD164" opacity="0.209999993"></path>
-                        <g id="icon" transform="translate(15.000000, 13.000000)">
-                            <path d="M0,11.3164701 L12.9004912,18.7645722 C13.0394036,18.8447733 13.1850623,18.9027046 13.3333333,18.9394739 L13.3333333,33.3847054 L0.920064885,26.0385088 C0.349783865,25.7010154 0,25.0875659 0,24.4249029 L0,11.3164701 Z M30,11.1184665 L30,24.4249029 C30,25.0875659 29.6502161,25.7010154 29.0799351,26.0385088 L16.6666667,33.3847054 L16.6666667,18.8129235 C16.6969108,18.7978151 16.7268876,18.7817016 16.7565565,18.7645722 L30,11.1184665 L30,11.1184665 Z" id="Combined-Shape" fill="#FFC741"></path>
-                            <path d="M0.405221909,7.70142332 C0.562796988,7.50243849 0.761684783,7.33426405 0.993563997,7.21076013 L14.118564,0.220099528 C14.6695479,-0.0733665093 15.3304521,-0.0733665093 15.881436,0.220099528 L29.006436,7.21076013 C29.1851826,7.30596446 29.3443248,7.42771319 29.480051,7.56965747 L15.0898899,15.8778209 C14.9952678,15.9324509 14.9080291,15.9949583 14.8285239,16.0640363 C14.7490186,15.9949583 14.66178,15.9324509 14.5671579,15.8778209 L0.405221909,7.70142332 Z" id="Path" fill="#FFD164" opacity="0.659481957"></path>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 21
src/assets/svg/dashboard/analysis-icon3.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>Icon3@3x</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-1018.000000, -136.000000)" fill="#55D187">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Total-Sales" transform="translate(598.000000, 0.000000)">
-                    <g id="Icon3" transform="translate(186.000000, 16.000000)">
-                        <path d="M23,60 C10.2974508,60 1.55561363e-15,49.7025492 0,37 L0,23 C-1.55561363e-15,10.2974508 10.2974508,2.33342044e-15 23,0 L37,0 C49.7025492,-2.33342044e-15 60,10.2974508 60,23 L60,37 C60,49.7025492 49.7025492,60 37,60 L23,60 Z" id="Circle-2" opacity="0.209999993"></path>
-                        <g id="icon" transform="translate(16.000000, 16.000000)" fill-rule="nonzero">
-                            <path d="M3.11111111,24.8888889 L26.4444444,24.8888889 C27.3035541,24.8888889 28,25.5853348 28,26.4444444 C28,27.3035541 27.3035541,28 26.4444444,28 L1.55555556,28 C0.696445945,28 0,27.3035541 0,26.4444444 L0,1.55555556 C0,0.696445945 0.696445945,0 1.55555556,0 C2.41466517,0 3.11111111,0.696445945 3.11111111,1.55555556 L3.11111111,24.8888889 Z" id="Path-95"></path>
-                            <path d="M8.91261343,18.1750195 C8.32503303,18.801772 7.34062178,18.8335272 6.71386936,18.2459468 C6.08711693,17.6583664 6.05536173,16.6739551 6.64294213,16.0472027 L12.4762755,9.82498047 C13.044535,9.21883699 13.9888279,9.16627114 14.6208522,9.70559855 L19.2248856,13.6343737 L25.2235157,6.03610888 C25.7558581,5.36180856 26.7340352,5.24672889 27.4083356,5.77907125 C28.0826359,6.31141362 28.1977156,7.28959079 27.6653732,7.96389112 L20.6653732,16.8305578 C20.118618,17.5231144 19.1059101,17.6227201 18.4347034,17.049957 L13.7306235,13.0358088 L8.91261343,18.1750195 Z" id="Path-97" opacity="0.657133557"></path>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 21
src/assets/svg/dashboard/analysis-icon4.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="60px" height="60px" viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>Icon</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-1317.000000, -136.000000)" fill="#FF9066">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Order-Pending" transform="translate(897.000000, 0.000000)">
-                    <g id="Icon" transform="translate(186.000000, 16.000000)">
-                        <path d="M23,60 C10.2974508,60 1.55561363e-15,49.7025492 0,37 L0,23 C-1.55561363e-15,10.2974508 10.2974508,2.33342044e-15 23,0 L37,0 C49.7025492,-2.33342044e-15 60,10.2974508 60,23 L60,37 C60,49.7025492 49.7025492,60 37,60 L23,60 Z" id="Circle-2" opacity="0.3"></path>
-                        <g id="icon" transform="translate(16.000000, 15.000000)">
-                            <path d="M13.1296822,8.34718934 L13.5475062,8.34718934 C13.8043819,8.34718934 14.0194647,8.54183658 14.0450248,8.79743748 L14.6666667,15.013856 L14.6666667,15.013856 L19.0814028,17.5365624 C19.2371903,17.6255838 19.3333333,17.7912555 19.3333333,17.9706839 L19.3333333,18.3592308 C19.3333333,18.6353732 19.1094757,18.8592308 18.8333333,18.8592308 C18.7888923,18.8592308 18.7446497,18.8533059 18.7017746,18.8416127 L12.3986612,17.1225818 C12.1672824,17.0594785 12.0132986,16.8409746 12.0316926,16.6018516 L12.631155,8.80884109 C12.6511933,8.54834251 12.8684141,8.34718934 13.1296822,8.34718934 Z" id="Path-107" opacity="0.779999971"></path>
-                            <path d="M6.01733907,-0.0772351689 C6.2288764,-0.254736066 6.5442542,-0.227144084 6.72175509,-0.0156067521 L6.72175509,-0.0156067521 L8.51913552,2.1273858 C10.2024553,1.41052645 12.054904,1.01385601 14,1.01385601 C21.7319865,1.01385601 28,7.28186951 28,15.013856 C28,22.6413562 21.9002476,28.8441829 14.312645,29.010434 L14,29.013856 L14,29.013856 C6.2680135,29.013856 0,22.7458425 0,15.013856 C0,13.7006992 0.180792724,12.4297687 0.518844853,11.224598 L3.08641434,11.944805 C2.80896017,12.9339413 2.66666667,13.9630912 2.66666667,15.013856 C2.66666667,21.2730832 7.74077284,26.3471893 14,26.3471893 C20.2592272,26.3471893 25.3333333,21.2730832 25.3333333,15.013856 C25.3333333,8.85242927 20.4165542,3.83937783 14.2925184,3.68422422 L14,3.68052267 L14,3.68052267 C12.7318949,3.68052267 11.4968995,3.88835566 10.3322213,4.2862714 L12.1330448,6.43331723 C12.2023675,6.51593278 12.24312,6.61874811 12.2492217,6.7264223 C12.2648452,7.00212236 12.0540114,7.23828671 11.7783113,7.25391015 L11.7783113,7.25391015 L4.73355552,7.65312407 C4.68508783,7.65587065 4.6364785,7.65154413 4.58925778,7.64028071 C4.32065092,7.57621071 4.15484104,7.30652283 4.21891104,7.03791597 L4.21891104,7.03791597 L5.85237713,0.189778054 C5.87728008,0.0853749765 5.93511798,-0.00824348388 6.01733907,-0.0772351689 Z" id="Combined-Shape" opacity="0.901274182"></path>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

+ 0 - 20
src/assets/svg/dashboard/analysis-rise.svg

@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="20px" height="12px" viewBox="0 0 20 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-    <!-- Generator: Sketch 61 (89581) - https://sketch.com -->
-    <title>上涨-24px</title>
-    <desc>Created with Sketch.</desc>
-    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
-        <g id="系统首页" transform="translate(-551.000000, -240.000000)">
-            <g id="1" transform="translate(234.000000, 120.000000)">
-                <g id="Total-Order" transform="translate(299.000000, 0.000000)">
-                    <g id="8.5%-Up-from-yesterday" transform="translate(16.000000, 114.000000)">
-                        <g id="上涨-24px">
-                            <polygon id="Path" points="0 0 24 0 24 24 0 24"></polygon>
-                            <polygon id="Path" fill="#55D187" fill-rule="nonzero" points="16 6 18.29 8.29 13.41 13.17 9.41 9.17 2 16.59 3.41 18 9.41 12 13.41 16 19.71 9.71 22 12 22 6"></polygon>
-                        </g>
-                    </g>
-                </g>
-            </g>
-        </g>
-    </g>
-</svg>

File diff suppressed because it is too large
+ 0 - 0
src/assets/svg/illustration.svg


+ 1 - 1
src/components/Basic/src/BasicTitle.vue

@@ -53,7 +53,7 @@
 
     &-normal {
       font-size: 14px;
-      font-weight: normal;
+      font-weight: 500;
     }
 
     &-show-span::before {

+ 11 - 0
src/components/Container/src/collapse/CollapseContainer.vue

@@ -9,6 +9,9 @@
       <template #title>
         <slot name="title"></slot>
       </template>
+      <template #action>
+        <slot name="action"></slot>
+      </template>
     </CollapseHeader>
 
     <div class="p-2">
@@ -19,6 +22,10 @@
         </div>
       </CollapseTransition>
     </div>
+
+    <div :class="`${prefixCls}__footer`" v-if="$slots.footer">
+      <slot name="footer"></slot>
+    </div>
   </div>
 </template>
 <script lang="ts">
@@ -106,6 +113,10 @@
       border-bottom: 1px solid @border-color-light;
     }
 
+    &__footer {
+      border-top: 1px solid @border-color-light;
+    }
+
     &__action {
       display: flex;
       text-align: right;

+ 1 - 1
src/components/Page/src/PageWrapper.vue

@@ -181,7 +181,7 @@
     position: relative;
 
     .@{prefix-cls}-content {
-      margin: 16px 16px 0 16px;
+      margin: 16px;
     }
 
     .ant-page-header {

+ 3 - 3
src/components/Scrollbar/src/index.vue

@@ -111,9 +111,9 @@
       onBeforeUnmount(() => {
         if (props.native) return;
         if (!props.noresize) {
-          //  removeResizeListener(unref(resize), update);
-          //  removeResizeListener(unref(wrap), update);
-          //  removeEventListener('resize', update);
+          removeResizeListener(unref(resize), update);
+          removeResizeListener(unref(wrap), update);
+          removeEventListener('resize', update);
         }
       });
 

+ 9 - 4
src/components/Tree/src/TreeHeader.vue

@@ -1,13 +1,18 @@
 <template>
   <div class="flex px-2 py-1.5 items-center border-b-1">
     <slot name="headerTitle" v-if="$slots.headerTitle"></slot>
-    <BasicTitle :helpMessage="helpMessage" v-if="!$slots.headerTitle && title">{{
-      title
-    }}</BasicTitle>
+    <BasicTitle :helpMessage="helpMessage" v-if="!$slots.headerTitle && title">
+      {{ title }}
+    </BasicTitle>
 
     <div class="flex flex-1 justify-end items-center cursor-pointer" v-if="search || toolbar">
       <div class="mr-1 w-2/3" v-if="search">
-        <InputSearch :placeholder="t('common.searchText')" size="small" @change="handleSearch" />
+        <InputSearch
+          :placeholder="t('common.searchText')"
+          size="small"
+          allowClear
+          @change="handleSearch"
+        />
       </div>
       <Dropdown @click.prevent v-if="toolbar">
         <Icon icon="ion:ellipsis-vertical" />

+ 1 - 1
src/enums/pageEnum.ts

@@ -2,7 +2,7 @@ export enum PageEnum {
   // basic login path
   BASE_LOGIN = '/login',
   // basic home path
-  BASE_HOME = '/home',
+  BASE_HOME = '/dashboard',
   // error page path
   ERROR_PAGE = '/exception',
   // error log page path

+ 2 - 2
src/layouts/default/header/components/user-dropdown/index.vue

@@ -136,8 +136,8 @@
     }
 
     img {
-      width: 26px;
-      height: 26px;
+      width: 24px;
+      height: 24px;
       margin-right: 12px;
     }
 

+ 1 - 1
src/layouts/default/tabs/index.less

@@ -30,7 +30,7 @@
         line-height: calc(@multiple-height - 2px);
         color: @text-color-call-out;
         background: @white;
-        border: 1px solid darken(@border-color-light, 6%);
+        border-bottom: 1px solid @header-light-bottom-border-color;
         transition: none;
 
         // &:not(.ant-tabs-tab-active)::before {

+ 11 - 1
src/plugins/echarts/index.ts

@@ -1,6 +1,13 @@
 import * as echarts from 'echarts/core';
 
-import { BarChart, LineChart, PieChart, MapChart, PictorialBarChart } from 'echarts/charts';
+import {
+  BarChart,
+  LineChart,
+  PieChart,
+  MapChart,
+  PictorialBarChart,
+  RadarChart,
+} from 'echarts/charts';
 
 import {
   TitleComponent,
@@ -10,6 +17,7 @@ import {
   AriaComponent,
   ParallelComponent,
   LegendComponent,
+  RadarComponent,
 } from 'echarts/components';
 
 import { SVGRenderer } from 'echarts/renderers';
@@ -26,8 +34,10 @@ echarts.use([
   LineChart,
   PieChart,
   MapChart,
+  RadarChart,
   SVGRenderer,
   PictorialBarChart,
+  RadarComponent,
 ]);
 
 export default echarts;

+ 16 - 4
src/router/menus/modules/dashboard.ts

@@ -6,14 +6,26 @@ const menu: MenuModule = {
   menu: {
     name: t('routes.dashboard.dashboard'),
     path: '/dashboard',
+    tag: {
+      dot: true,
+      type: 'warn',
+    },
     children: [
-      {
-        path: 'workbench',
-        name: t('routes.dashboard.workbench'),
-      },
       {
         path: 'analysis',
         name: t('routes.dashboard.analysis'),
+        tag: {
+          dot: true,
+          type: 'warn',
+        },
+      },
+      {
+        path: 'workbench',
+        name: t('routes.dashboard.workbench'),
+        tag: {
+          dot: true,
+          type: 'warn',
+        },
       },
     ],
   },

+ 2 - 1
src/router/routes/modules/dashboard.ts

@@ -7,7 +7,7 @@ const dashboard: AppRouteModule = {
   path: '/dashboard',
   name: 'Dashboard',
   component: LAYOUT,
-  redirect: '/dashboard/workbench',
+  redirect: '/dashboard/analysis',
   meta: {
     icon: 'ion:grid-outline',
     title: t('routes.dashboard.dashboard'),
@@ -26,6 +26,7 @@ const dashboard: AppRouteModule = {
       name: 'Analysis',
       component: () => import('/@/views/dashboard/analysis/index.vue'),
       meta: {
+        affix: true,
         title: t('routes.dashboard.analysis'),
       },
     },

+ 0 - 9
src/utils/env.ts

@@ -80,12 +80,3 @@ export function isDevMode(): boolean {
 export function isProdMode(): boolean {
   return import.meta.env.PROD;
 }
-
-/**
- * @description: Whether to open mock
- * @returns:
- * @example:
- */
-export function isUseMock(): boolean {
-  return import.meta.env.VITE_USE_MOCK === 'true';
-}

+ 0 - 90
src/views/dashboard/analysis/components/AnalysisBar.vue

@@ -1,90 +0,0 @@
-<template>
-  <div ref="chartRef" :style="{ height, width }"></div>
-</template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
-  import { useECharts } from '/@/hooks/web/useECharts';
-
-  import { basicProps } from './props';
-  export default defineComponent({
-    name: 'AnalysisLine',
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-
-      onMounted(() => {
-        setOptions({
-          tooltip: {
-            trigger: 'axis',
-            axisPointer: {
-              // 坐标轴指示器,坐标轴触发有效
-              type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
-            },
-          },
-          legend: {
-            itemWidth: 15,
-            right: 10,
-            data: ['产品一', '产品二', '产品三'],
-          },
-          grid: {
-            left: '3%',
-            right: '4%',
-            bottom: '3%',
-            containLabel: true,
-          },
-          xAxis: [
-            {
-              type: 'category',
-              axisTick: {
-                inside: true, // 刻度朝内
-              },
-              data: ['付费用户', '免费用户', '自主'],
-            },
-          ],
-          yAxis: [
-            {
-              type: 'value',
-              axisTick: {
-                inside: true, // 刻度朝内
-              },
-            },
-          ],
-          series: [
-            {
-              name: '产品一',
-              type: 'bar',
-              itemStyle: {
-                color: '#3ca0f6',
-              },
-              data: [3200, 3320, 3010],
-              animationDuration: 4000,
-            },
-            {
-              name: '产品二',
-              type: 'bar',
-              itemStyle: {
-                color: '#7dd9b9',
-              },
-              data: [1200, 2600, 1010],
-              animationDuration: 4000,
-            },
-
-            {
-              name: '产品三',
-              type: 'bar',
-              itemStyle: {
-                color: '#e6a23c',
-              },
-              data: [862, 2500, 964],
-              animationDuration: 4000,
-            },
-          ],
-        });
-      });
-
-      return { chartRef };
-    },
-  });
-</script>

+ 0 - 94
src/views/dashboard/analysis/components/AnalysisLine.vue

@@ -1,94 +0,0 @@
-<template>
-  <div ref="chartRef" :style="{ height, width }"></div>
-</template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
-  import { useECharts } from '/@/hooks/web/useECharts';
-
-  import { basicProps } from './props';
-  export default defineComponent({
-    name: 'AnalysisLine',
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-
-      onMounted(() => {
-        setOptions({
-          // title: {
-          //   text: '产品成交额',
-          // },
-          tooltip: {
-            trigger: 'axis',
-            padding: 3,
-            borderColor: '#777',
-            borderWidth: 1,
-          },
-          legend: {
-            itemWidth: 15,
-            itemHeight: 4,
-            left: 80,
-            top: 0,
-            orient: 'horizontal',
-            data: ['产品一', '产品二'],
-          },
-          grid: {
-            left: '3%',
-            right: '4%',
-            bottom: '3%',
-            containLabel: true,
-          },
-          xAxis: {
-            type: 'category',
-            boundaryGap: false,
-            axisTick: {
-              inside: true, // 刻度朝内
-            },
-            data: [
-              '一月',
-              '二月',
-              '三月',
-              '四月',
-              '五月',
-              '六月',
-              '七月',
-              '八月',
-              '九月',
-              '十月',
-              '十一月',
-              '十二月',
-            ],
-          },
-          yAxis: {
-            type: 'value',
-            axisTick: {
-              inside: true, // 刻度朝内
-            },
-          },
-          series: [
-            {
-              name: '产品一',
-              type: 'line',
-              itemStyle: {
-                color: '#5B8FF9',
-              },
-              data: [330, 132, 101, 134, 90, 230, 210, 150, 232, 234, 230, 400],
-              animationDuration: 4000,
-            },
-            {
-              name: '产品二',
-              type: 'line',
-              itemStyle: {
-                color: '#55D187',
-              },
-              data: [220, 182, 191, 234, 290, 330, 310, 330, 232, 201, 330, 190],
-              animationDuration: 4000,
-            },
-          ],
-        });
-      });
-      return { chartRef };
-    },
-  });
-</script>

+ 0 - 75
src/views/dashboard/analysis/components/AnalysisPie.vue

@@ -1,75 +0,0 @@
-<template>
-  <div ref="chartRef" :style="{ height, width }"></div>
-</template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
-  import { useECharts } from '/@/hooks/web/useECharts';
-
-  import { basicProps } from './props';
-
-  const m2R2Data = [
-    { value: 335, name: '移动设备', itemStyle: { color: '#1b65b9' } },
-    { value: 310, name: '网页端', itemStyle: { color: '#3ca0f6' } },
-    { value: 234, name: '手表', itemStyle: { color: '#2dc0c0' } },
-    { value: 234, name: '其他', itemStyle: { color: '#7dd9b9' } },
-  ];
-  export default defineComponent({
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-
-      onMounted(() => {
-        setOptions({
-          title: [
-            {
-              text: '总设备',
-              subtext: '1,430',
-              textStyle: {
-                fontSize: 12,
-                color: '#4B535E85',
-              },
-              subtextStyle: {
-                fontSize: 24,
-                color: 'black',
-              },
-              textAlign: 'center',
-              left: '34.5%',
-              top: '40%',
-            },
-          ],
-          tooltip: {
-            trigger: 'item',
-          },
-          legend: {
-            itemHeight: 10,
-            type: 'scroll',
-            orient: 'vertical',
-            left: '70%',
-            align: 'left',
-            top: 'middle',
-            textStyle: {
-              color: '#8C8C8C',
-            },
-            height: 250,
-          },
-          series: [
-            {
-              name: '成交额',
-              type: 'pie',
-              center: ['35%', '50%'],
-              radius: ['45%', '65%'],
-              label: {
-                show: false,
-              },
-              data: m2R2Data,
-              animationDuration: 3000,
-            },
-          ],
-        });
-      });
-      return { chartRef };
-    },
-  });
-</script>

+ 0 - 80
src/views/dashboard/analysis/components/FlowAnalysis.tsx

@@ -1,80 +0,0 @@
-import { defineComponent } from 'vue';
-import { Tabs, Row, Col, Progress, Divider } from 'ant-design-vue';
-import { CollapseContainer } from '/@/components/Container/index';
-import TrendLine from './TrendLine.vue';
-import './flow-ana.less';
-const prefixCls = 'flow-analysis';
-export default defineComponent({
-  name: 'AnalysisFLow',
-  setup() {
-    const renderContent = () => {
-      return (
-        <Row>
-          {() => (
-            <>
-              <Col md={24} lg={8}>
-                {() => (
-                  <CollapseContainer
-                    title="整体流量评分"
-                    canExpan={false}
-                    class={`${prefixCls}__left`}
-                  >
-                    {() => (
-                      <div>
-                        <div class={`${prefixCls}__score`}>
-                          86.2<span>分</span>
-                        </div>
-                        <div class={`${prefixCls}__rank`}>
-                          排名<span>前20%</span>
-                        </div>
-                        <Progress percent={70} showInfo={false} status="active" />
-                        <Divider />
-
-                        <ul class={`${prefixCls}__rs`}>
-                          <li>
-                            <span>平均分</span>
-                            <span>77.5</span>
-                          </li>
-                          <li>
-                            <span>最高分</span>
-                            <span>99.5</span>
-                          </li>
-                          <li>
-                            <span>最低分</span>
-                            <span>56.5</span>
-                          </li>
-                        </ul>
-                      </div>
-                    )}
-                  </CollapseContainer>
-                )}
-              </Col>
-              <Col md={24} lg={16}>
-                {() => (
-                  <CollapseContainer title="整体流量趋势" canExpan={false}>
-                    {() => <TrendLine />}
-                  </CollapseContainer>
-                )}
-              </Col>
-            </>
-          )}
-        </Row>
-      );
-    };
-    return () => (
-      <Tabs class={prefixCls} default-active-key="1">
-        {() => [
-          <Tabs.TabPane key="1" tab="产品一">
-            {() => renderContent()}
-          </Tabs.TabPane>,
-          <Tabs.TabPane key="2" tab="产品二">
-            {() => renderContent()}
-          </Tabs.TabPane>,
-          <Tabs.TabPane key="3" tab="产品三">
-            {() => renderContent()}
-          </Tabs.TabPane>,
-        ]}
-      </Tabs>
-    );
-  },
-});

+ 31 - 106
src/views/dashboard/analysis/components/GrowCard.vue

@@ -1,118 +1,43 @@
 <template>
-  <div class="grow-card">
-    <div class="grow-card-header">
-      <div class="grow-card__info">
-        <p class="grow-card__title">
-          {{ info.title }}
-        </p>
-        <CountTo prefix="$" :startVal="1" :endVal="info.price" />
-      </div>
-      <img :src="info.icon" />
-    </div>
-    <div class="grow-card-footer" :class="{ 'is-up': info.up }">
-      <Statistic :value="info.percent">
-        <template #prefix>
-          <img :src="info.up ? riseSvg : downSvg" />
+  <div class="md:flex">
+    <template v-for="(item, index) in growCardList" :key="item.title">
+      <Card
+        size="small"
+        :loading="$attrs.loading"
+        :title="item.title"
+        class="md:w-1/4 w-full md:mt-0 !mt-4"
+        :class="[index + 1 < 4 && '!md:mr-4']"
+        :canExpan="false"
+      >
+        <template #extra>
+          <Tag :color="item.color">{{ item.action }}</Tag>
         </template>
-      </Statistic>
-      <span class="grow-card__mom">{{ info.mom }}</span>
-    </div>
+
+        <div class="py-4 px-4 flex justify-between">
+          <CountTo prefix="$" :startVal="1" :endVal="item.value" class="text-2xl" />
+          <Icon :icon="item.icon" :size="40" />
+        </div>
+
+        <div class="p-2 px-4 flex justify-between">
+          <span>总{{ item.title }}</span>
+          <CountTo prefix="$" :startVal="1" :endVal="item.total" />
+        </div>
+      </Card>
+    </template>
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent, PropType } from 'vue';
-  import { Statistic } from 'ant-design-vue';
-  import { CountTo } from '/@/components/CountTo/index';
+  import { defineComponent } from 'vue';
 
-  import riseSvg from '/@/assets/svg/dashboard/analysis-rise.svg';
-  import downSvg from '/@/assets/svg/dashboard/analysis-down.svg';
-  import { GrowCardItem } from '../types';
+  import { CountTo } from '/@/components/CountTo/index';
+  import { Icon } from '/@/components/Icon';
+  import { Tag, Card } from 'ant-design-vue';
 
+  import { growCardList } from '../data';
   export default defineComponent({
-    components: { Statistic, CountTo },
-    props: {
-      info: {
-        type: Object as PropType<GrowCardItem>,
-        default: null,
-      },
-    },
+    components: { CountTo, Tag, Card, Icon },
     setup() {
-      return {
-        riseSvg,
-        downSvg,
-      };
+      return { growCardList };
     },
   });
 </script>
-<style lang="less">
-  .grow-card {
-    display: flex;
-    width: calc(100% - 12px);
-    height: 158px;
-    padding: 16px 16px 12px 16px;
-    // margin: 0 12px 12px 12px;
-    cursor: pointer;
-    background: @white;
-    border-radius: 4px;
-    box-shadow: 6px 6px 54px 0 rgba(0, 0, 0, 0.05);
-    flex-direction: column;
-
-    &:hover {
-      box-shadow: 6px 6px 54px 0 rgba(0, 0, 0, 0.1);
-    }
-
-    &-header {
-      display: flex;
-      width: 100%;
-      justify-content: space-between;
-    }
-
-    &__title {
-      font-family: PingFangSC-Regular;
-      font-size: 16px;
-      letter-spacing: 0;
-      color: @text-color-base;
-      opacity: 0.7;
-    }
-
-    &__info {
-      span {
-        font-family: NeoSans;
-        font-size: 26px;
-        line-height: 38px;
-      }
-    }
-
-    &-footer {
-      display: flex;
-      width: 100%;
-      margin-top: 24px;
-      align-items: center;
-
-      .ant-statistic-content-value {
-        color: @error-color;
-      }
-
-      .ant-statistic-content-prefix svg {
-        width: 0.98rem !important;
-        height: 0.98rem !important;
-      }
-
-      &.is-up {
-        .ant-statistic-content-value {
-          color: @success-color;
-        }
-      }
-    }
-
-    &__mom {
-      display: inline-block;
-      padding-left: 10px;
-      font-family: PingFangSC-Regular;
-      font-size: 12px;
-      line-height: 22px;
-      letter-spacing: 0;
-      color: #606060;
-    }
-  }
-</style>

+ 69 - 0
src/views/dashboard/analysis/components/SalesProductPie.vue

@@ -0,0 +1,69 @@
+<template>
+  <Card title="成交占比" :loading="loading">
+    <div ref="chartRef" :style="{ width, height }"></div>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, Ref, ref, watch } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  export default defineComponent({
+    components: { Card },
+    props: {
+      loading: Boolean,
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: '300px',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      watch(
+        () => props.loading,
+        () => {
+          if (props.loading) {
+            return;
+          }
+          setOptions({
+            tooltip: {
+              trigger: 'item',
+            },
+
+            series: [
+              {
+                name: '访问来源',
+                type: 'pie',
+                radius: '80%',
+                center: ['50%', '50%'],
+                color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
+                data: [
+                  { value: 500, name: '电子产品' },
+                  { value: 310, name: '服装' },
+                  { value: 274, name: '化妆品' },
+                  { value: 400, name: '家居' },
+                ].sort(function (a, b) {
+                  return a.value - b.value;
+                }),
+                roseType: 'radius',
+                animationType: 'scale',
+                animationEasing: 'exponentialInOut',
+                animationDelay: function () {
+                  return Math.random() * 400;
+                },
+              },
+            ],
+          });
+        },
+        { immediate: true }
+      );
+      return { chartRef };
+    },
+  });
+</script>

+ 46 - 0
src/views/dashboard/analysis/components/SiteAnalysis.vue

@@ -0,0 +1,46 @@
+<template>
+  <Card
+    :tab-list="tabListTitle"
+    v-bind="$attrs"
+    :active-tab-key="activeKey"
+    @tabChange="onTabChange"
+  >
+    <p v-if="activeKey === 'tab1'">
+      <VisitAnalysis />
+    </p>
+    <p v-if="activeKey === 'tab2'">
+      <VisitAnalysisBar />
+    </p>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+
+  import VisitAnalysis from './VisitAnalysis.vue';
+  import VisitAnalysisBar from './VisitAnalysisBar.vue';
+
+  export default defineComponent({
+    components: { Card, VisitAnalysis, VisitAnalysisBar },
+    setup() {
+      const activeKey = ref('tab1');
+
+      const tabListTitle = [
+        {
+          key: 'tab1',
+          tab: '流量趋势',
+        },
+        {
+          key: 'tab2',
+          tab: '访问量',
+        },
+      ];
+
+      function onTabChange(key) {
+        activeKey.value = key;
+      }
+      return { tabListTitle, activeKey, onTabChange };
+    },
+  });
+</script>

+ 0 - 154
src/views/dashboard/analysis/components/TaskCard.vue

@@ -1,154 +0,0 @@
-<template>
-  <div :class="prefixCls">
-    <div :class="`${prefixCls}-header`">
-      <div :class="`${prefixCls}__info`">
-        <span :class="`${prefixCls}__title`">{{ info.title }}</span>
-        <span :class="`${prefixCls}__desc`">{{ info.desc }}</span>
-      </div>
-      <span :class="`${prefixCls}__tag ${info.status}`">{{ info.text }}</span>
-    </div>
-
-    <div :class="`${prefixCls}-body mt-5`">
-      <div :class="`${prefixCls}__process-nfo`">
-        <span>进度</span>
-        <span>{{ info.percent }}%</span>
-      </div>
-      <Progress :percent="info.percent" :showInfo="false" :status="info.status" />
-    </div>
-    <div :class="`${prefixCls}-footer`">
-      <span :class="`${prefixCls}__date`">
-        更新日期: <span>{{ info.updateTime }}</span>
-      </span>
-      <div :class="`${prefixCls}__avatar`">
-        <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
-        <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
-        <Avatar>+3</Avatar>
-      </div>
-    </div>
-  </div>
-</template>
-<script lang="ts">
-  import { computed, defineComponent, PropType } from 'vue';
-  import { Progress, Avatar } from 'ant-design-vue';
-
-  import { TaskItem } from '../types';
-
-  export default defineComponent({
-    name: 'GrowCard',
-    components: { Progress, Avatar },
-    props: {
-      info: {
-        type: Object as PropType<TaskItem>,
-        default: null,
-      },
-    },
-    setup(props) {
-      return {
-        prefixCls: 'task-card',
-        text: computed(() => {
-          const { status } = props.info || {};
-          return status === 'active'
-            ? '进度正常'
-            : status === 'exception'
-            ? '进度滞后'
-            : '项目完成';
-        }),
-      };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .task-card {
-    display: flex;
-    width: calc(100% - 24px);
-    height: 199px;
-    padding: 24px 20px 12px 16px;
-    margin: 0 12px 12px 12px;
-    background: #fff;
-    border: 1px solid #ececf2;
-    border-radius: 12px;
-    flex-direction: column;
-
-    &-header {
-      display: flex;
-      width: 100%;
-      justify-content: space-between;
-      align-items: center;
-    }
-
-    &__tag {
-      display: inline-block;
-      padding: 4px 6px;
-      font-family: PingFangSC-Regular;
-      font-size: 12px;
-      border-radius: 6px;
-
-      &.success {
-        color: #55d187;
-        background: rgba(85, 209, 135, 0.16);
-      }
-
-      &.warn {
-        color: #ffa07d;
-        background: #ffd16416;
-      }
-
-      &.done {
-        color: #0593ff;
-        background: #0593ff16;
-      }
-    }
-
-    &__info {
-      display: flex;
-      flex-direction: column;
-    }
-
-    &__title {
-      font-family: PingFangSC-Medium;
-      font-size: 16px;
-      line-height: 24px;
-      color: rgba(0, 0, 0, 0.85);
-    }
-
-    &__desc {
-      font-family: PingFangSC-Regular;
-      font-size: 12px;
-      line-height: 21px;
-      color: #8181a5;
-    }
-
-    &__process-nfo {
-      display: flex;
-      justify-content: space-between;
-
-      span {
-        font-size: 14px;
-        line-height: 21px;
-        color: #8181a5;
-      }
-    }
-
-    &-footer {
-      display: flex;
-      width: 100%;
-      margin-top: 16px;
-      align-items: center;
-      justify-content: space-between;
-    }
-
-    &__date {
-      font-size: 12px;
-      line-height: 21px;
-      color: #2c3a61;
-
-      span {
-        color: #7c8087;
-      }
-    }
-
-    &__avatar {
-      display: flex;
-    }
-  }
-</style>

+ 0 - 97
src/views/dashboard/analysis/components/TrendLine.vue

@@ -1,97 +0,0 @@
-<template>
-  <div ref="chartRef" :style="{ height, width }"></div>
-</template>
-<script lang="ts">
-  import { defineComponent, onMounted, ref, Ref } from 'vue';
-
-  import { useECharts } from '/@/hooks/web/useECharts';
-
-  import { basicProps } from './props';
-  export default defineComponent({
-    props: basicProps,
-    setup() {
-      const chartRef = ref<HTMLDivElement | null>(null);
-      const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
-
-      onMounted(() => {
-        setOptions({
-          tooltip: {
-            trigger: 'axis',
-            padding: 3,
-            borderColor: '#777',
-            borderWidth: 1,
-          },
-          legend: {
-            show: false,
-          },
-          grid: {
-            left: '3%',
-            right: '4%',
-            bottom: '3%',
-            containLabel: true,
-          },
-          xAxis: {
-            type: 'category',
-            boundaryGap: false,
-            axisTick: {
-              inside: true,
-            },
-            data: [
-              '一月',
-              '二月',
-              '三月',
-              '四月',
-              '五月',
-              '六月',
-              '七月',
-              '八月',
-              '九月',
-              '十月',
-              '十一月',
-              '十二月',
-            ],
-          },
-          yAxis: {
-            type: 'value',
-            axisTick: {
-              inside: true,
-            },
-          },
-          series: [
-            {
-              name: '产品一',
-              type: 'line',
-              itemStyle: {
-                color: '#5B8FF9',
-              },
-              areaStyle: {
-                color: new echarts.graphic.LinearGradient(
-                  0,
-                  0,
-                  0,
-                  1,
-                  [
-                    {
-                      offset: 0,
-                      color: '#5B8FF9',
-                    },
-                    {
-                      offset: 1,
-                      color: 'rgba(118,168,248, 0)',
-                    },
-                  ],
-                  false
-                ),
-                shadowColor: 'rgba(118,168,248, 0.9)',
-                shadowBlur: 20,
-              },
-              data: [134, 330, 132, 101, 90, 230, 210, 150, 230, 400, 232, 234],
-              animationDuration: 3000,
-            },
-          ],
-        });
-      });
-      return { chartRef };
-    },
-  });
-</script>

+ 146 - 0
src/views/dashboard/analysis/components/VisitAnalysis.vue

@@ -0,0 +1,146 @@
+<template>
+  <div ref="chartRef" :style="{ height, width }"></div>
+</template>
+<script lang="ts">
+  import { defineComponent, onMounted, ref, Ref } from 'vue';
+
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  import { basicProps } from './props';
+  export default defineComponent({
+    props: basicProps,
+    setup() {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+
+      onMounted(() => {
+        setOptions({
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              lineStyle: {
+                width: 1,
+                color: '#019680',
+              },
+            },
+          },
+          xAxis: {
+            type: 'category',
+            boundaryGap: false,
+            data: [
+              '6:00',
+              '7:00',
+              '8:00',
+              '9:00',
+              '10:00',
+              '11:00',
+              '12:00',
+              '13:00',
+              '14:00',
+              '15:00',
+              '16:00',
+              '17:00',
+              '18:00',
+              '19:00',
+              '20:00',
+              '21:00',
+              '22:00',
+              '23:00',
+            ],
+            splitLine: {
+              show: true,
+              lineStyle: {
+                width: 1,
+                type: 'solid',
+                color: 'rgba(226,226,226,0.5)',
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+          yAxis: [
+            {
+              type: 'value',
+              max: 80000,
+              splitNumber: 4,
+              axisTick: {
+                show: false,
+              },
+              splitArea: {
+                show: true,
+                areaStyle: {
+                  color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
+                },
+              },
+            },
+          ],
+          grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
+          series: [
+            {
+              smooth: true,
+              data: [
+                111,
+                222,
+                4000,
+                18000,
+                33333,
+                55555,
+                66666,
+                33333,
+                14000,
+                36000,
+                66666,
+                44444,
+                22222,
+                11111,
+                4000,
+                2000,
+                500,
+                333,
+                222,
+                111,
+              ],
+              type: 'line',
+              areaStyle: {},
+              itemStyle: {
+                color: '#5ab1ef',
+              },
+            },
+            {
+              smooth: true,
+              data: [
+                33,
+                66,
+                88,
+                333,
+                3333,
+                5000,
+                18000,
+                3000,
+                1200,
+                13000,
+                22000,
+                11000,
+                2221,
+                1201,
+                390,
+                198,
+                60,
+                30,
+                22,
+                11,
+              ],
+              type: 'line',
+              areaStyle: {},
+              itemStyle: {
+                color: '#019680',
+              },
+            },
+          ],
+        });
+      });
+      return { chartRef };
+    },
+  });
+</script>

+ 62 - 0
src/views/dashboard/analysis/components/VisitAnalysisBar.vue

@@ -0,0 +1,62 @@
+<template>
+  <div ref="chartRef" :style="{ height, width }"></div>
+</template>
+<script lang="ts">
+  import { defineComponent, onMounted, ref, Ref } from 'vue';
+
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  import { basicProps } from './props';
+  export default defineComponent({
+    props: basicProps,
+    setup() {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+
+      onMounted(() => {
+        setOptions({
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: {
+              lineStyle: {
+                width: 1,
+                color: '#019680',
+              },
+            },
+          },
+          grid: { left: '1%', right: '1%', top: '2  %', bottom: 0, containLabel: true },
+          xAxis: {
+            type: 'category',
+            data: [
+              '1月',
+              '2月',
+              '3月',
+              '4月',
+              '5月',
+              '6月',
+              '7月',
+              '8月',
+              '9月',
+              '10月',
+              '11月',
+              '12月',
+            ],
+          },
+          yAxis: {
+            type: 'value',
+            max: 8000,
+            splitNumber: 4,
+          },
+          series: [
+            {
+              data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800],
+              type: 'bar',
+              barMaxWidth: 80,
+            },
+          ],
+        });
+      });
+      return { chartRef };
+    },
+  });
+</script>

+ 107 - 0
src/views/dashboard/analysis/components/VisitRadar.vue

@@ -0,0 +1,107 @@
+<template>
+  <Card title="转化率" :loading="loading">
+    <div ref="chartRef" :style="{ width, height }"></div>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, Ref, ref, watch } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  export default defineComponent({
+    components: { Card },
+    props: {
+      loading: Boolean,
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: '300px',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      watch(
+        () => props.loading,
+        () => {
+          if (props.loading) {
+            return;
+          }
+          setOptions({
+            backgroundColor: '#fff',
+            legend: {
+              bottom: 0,
+              data: ['访问', '购买'],
+            },
+            tooltip: {},
+            radar: {
+              radius: '60%',
+              splitNumber: 8,
+              indicator: [
+                {
+                  text: '电脑',
+                  max: 100,
+                },
+                {
+                  text: '充电器',
+                  max: 100,
+                },
+                {
+                  text: '耳机',
+                  max: 100,
+                },
+                {
+                  text: '手机',
+                  max: 100,
+                },
+                {
+                  text: 'Ipad',
+                  max: 100,
+                },
+                {
+                  text: '耳机',
+                  max: 100,
+                },
+              ],
+            },
+            series: [
+              {
+                type: 'radar',
+                symbolSize: 0,
+                areaStyle: {
+                  shadowBlur: 0,
+                  shadowColor: 'rgba(0,0,0,.2)',
+                  shadowOffsetX: 0,
+                  shadowOffsetY: 10,
+                  opacity: 1,
+                },
+                data: [
+                  {
+                    value: [90, 50, 86, 40, 50, 20],
+                    name: '访问',
+                    itemStyle: {
+                      color: '#b6a2de',
+                    },
+                  },
+                  {
+                    value: [70, 75, 70, 76, 20, 85],
+                    name: '购买',
+                    itemStyle: {
+                      color: '#5ab1ef',
+                    },
+                  },
+                ],
+              },
+            ],
+          });
+        },
+        { immediate: true }
+      );
+      return { chartRef };
+    },
+  });
+</script>

+ 88 - 0
src/views/dashboard/analysis/components/VisitSource.vue

@@ -0,0 +1,88 @@
+<template>
+  <Card title="访问来源" :loading="loading">
+    <div ref="chartRef" :style="{ width, height }"></div>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, Ref, ref, watch } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  export default defineComponent({
+    components: { Card },
+    props: {
+      loading: Boolean,
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: '300px',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      watch(
+        () => props.loading,
+        () => {
+          if (props.loading) {
+            return;
+          }
+          setOptions({
+            tooltip: {
+              trigger: 'item',
+            },
+            legend: {
+              bottom: '1%',
+              left: 'center',
+            },
+            series: [
+              {
+                color: ['#5ab1ef', '#b6a2de', '#67e0e3', '#2ec7c9'],
+                name: '访问来源',
+                type: 'pie',
+                radius: ['40%', '70%'],
+                avoidLabelOverlap: false,
+                itemStyle: {
+                  borderRadius: 10,
+                  borderColor: '#fff',
+                  borderWidth: 2,
+                },
+                label: {
+                  show: false,
+                  position: 'center',
+                },
+                emphasis: {
+                  label: {
+                    show: true,
+                    fontSize: '12',
+                    fontWeight: 'bold',
+                  },
+                },
+                labelLine: {
+                  show: false,
+                },
+                data: [
+                  { value: 1048, name: '搜索引擎' },
+                  { value: 735, name: '直接访问' },
+                  { value: 580, name: '邮件营销' },
+                  { value: 484, name: '联盟广告' },
+                ],
+                animationType: 'scale',
+                animationEasing: 'exponentialInOut',
+                animationDelay: function () {
+                  return Math.random() * 100;
+                },
+              },
+            ],
+          });
+        },
+        { immediate: true }
+      );
+      return { chartRef };
+    },
+  });
+</script>

+ 0 - 56
src/views/dashboard/analysis/components/flow-ana.less

@@ -1,56 +0,0 @@
-.flow-analysis {
-  width: 100%;
-  background: #fff;
-
-  &__left {
-    padding: 10px 20px !important;
-    border-right: 1px solid rgba(0, 0, 0, 0.06);
-    border-radius: 0;
-  }
-
-  &__score {
-    margin-top: 20px;
-    font-size: 30px;
-    line-height: 38px;
-    color: rgba(0, 0, 0, 0.85);
-
-    span {
-      font-size: 20px;
-      line-height: 28px;
-      color: rgba(0, 0, 0, 0.85);
-    }
-  }
-
-  &__rank {
-    margin: 16px 0;
-    font-size: 12px;
-    line-height: 20px;
-    color: #7c8087;
-
-    span {
-      display: inline-block;
-      margin-left: 10px;
-      color: #1c1d21;
-    }
-  }
-
-  &__rs {
-    li {
-      display: flex;
-      line-height: 28px;
-      justify-content: space-between;
-
-      span {
-        &:nth-child(1) {
-          font-size: 14px;
-          color: #1c1d21;
-        }
-
-        &:nth-child(2) {
-          font-size: 16px;
-          color: #1c1d21;
-        }
-      }
-    }
-  }
-}

+ 43 - 0
src/views/dashboard/analysis/data.ts

@@ -0,0 +1,43 @@
+export interface GrowCardItem {
+  icon: string;
+  title: string;
+  value: number;
+  total: number;
+  color: string;
+  action: string;
+}
+
+export const growCardList: GrowCardItem[] = [
+  {
+    title: '访问数',
+    icon: 'visit-count|svg',
+    value: 2000,
+    total: 120000,
+    color: 'green',
+    action: '月',
+  },
+  {
+    title: '成交额',
+    icon: 'total-sales|svg',
+    value: 20000,
+    total: 500000,
+    color: 'blue',
+    action: '月',
+  },
+  {
+    title: '下载数',
+    icon: 'download-count|svg',
+    value: 8000,
+    total: 120000,
+    color: 'orange',
+    action: '周',
+  },
+  {
+    title: '成交数',
+    icon: 'transaction|svg',
+    value: 5000,
+    total: 50000,
+    color: 'purple',
+    action: '年',
+  },
+];

+ 0 - 107
src/views/dashboard/analysis/data.tsx

@@ -1,107 +0,0 @@
-import { GrowCardItem, TaskItem } from './types';
-import iconSvg1 from '/@/assets/svg/dashboard/analysis-icon1.svg';
-import iconSvg2 from '/@/assets/svg/dashboard/analysis-icon2.svg';
-import iconSvg3 from '/@/assets/svg/dashboard/analysis-icon3.svg';
-import iconSvg4 from '/@/assets/svg/dashboard/analysis-icon4.svg';
-export const taskList: TaskItem[] = [
-  {
-    percent: 50,
-    title: '开发任务一',
-    updateTime: '2020.7.12',
-    desc: '开发任务一简介',
-    status: 'active',
-  },
-  {
-    percent: 67,
-    title: '开发任务二',
-    updateTime: '2020.3.12',
-    desc: '开发任务二简介',
-    status: 'exception',
-  },
-  {
-    percent: 100,
-    title: '开发任务三',
-    updateTime: '2020.4.12',
-    desc: '开发任务三简介',
-
-    status: 'success',
-  },
-];
-export const growCardList: GrowCardItem[] = [
-  {
-    title: '总用户数',
-    icon: iconSvg1,
-    price: 80000,
-    up: true,
-    mom: '环比增长',
-    percent: 2.5,
-  },
-  {
-    title: '产品数量',
-    icon: iconSvg2,
-    price: 4000,
-    up: true,
-    mom: '同比增长',
-    percent: 3,
-  },
-  {
-    title: '总营业额',
-    icon: iconSvg3,
-    price: 3000000,
-    up: false,
-    mom: '环比降低',
-    percent: 2,
-  },
-  {
-    title: '总任务数',
-    icon: iconSvg4,
-    price: 10000,
-    up: false,
-    mom: '同比降低',
-    percent: 1,
-  },
-];
-export const randomizeArray = function (arg: any) {
-  const array = arg.slice();
-  let currentIndex = array.length,
-    temporaryValue,
-    randomIndex;
-
-  while (0 !== currentIndex) {
-    randomIndex = Math.floor(Math.random() * currentIndex);
-    currentIndex -= 1;
-
-    temporaryValue = array[currentIndex];
-    array[currentIndex] = array[randomIndex];
-    array[randomIndex] = temporaryValue;
-  }
-
-  return array;
-};
-
-export const sparklineData = [
-  47,
-  45,
-  54,
-  38,
-  56,
-  24,
-  65,
-  31,
-  37,
-  39,
-  62,
-  51,
-  35,
-  41,
-  35,
-  27,
-  93,
-  53,
-  61,
-  27,
-  54,
-  43,
-  19,
-  46,
-];

+ 25 - 60
src/views/dashboard/analysis/index.vue

@@ -1,74 +1,39 @@
 <template>
-  <div class="p-4 analysis">
-    <a-row class="pl-2">
-      <template v-for="item in growCardList" :key="item.title">
-        <a-col :sm="24" :md="12" :lg="6">
-          <GrowCard :info="item" />
-        </a-col>
-      </template>
-    </a-row>
+  <div class="p-4">
+    <GrowCard :loading="loading" class="enter-y" />
+    <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
 
-    <a-row>
-      <a-col :md="24" :lg="17" class="my-3">
-        <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
-          <AnalysisLine />
-        </CollapseContainer>
-        <a-row class="mt-3">
-          <a-col :md="24" :lg="12" class="product-total">
-            <CollapseContainer class="mr-3" title="产品成交额" :canExpan="false">
-              <AnalysisPie />
-            </CollapseContainer>
-          </a-col>
-          <a-col :md="24" :lg="12">
-            <CollapseContainer class="mr-3" title="用户来源" :canExpan="false">
-              <AnalysisBar />
-            </CollapseContainer>
-          </a-col>
-        </a-row>
-      </a-col>
-      <a-col :md="24" :lg="7">
-        <CollapseContainer class="mt-3" title="项目进度" :canExpan="false">
-          <template v-for="item in taskList" :key="item.title">
-            <TaskCard :info="item" />
-          </template>
-        </CollapseContainer>
-      </a-col>
-    </a-row>
-    <a-row>
-      <FlowAnalysis />
-    </a-row>
+    <div class="md:flex enter-y">
+      <VisitRadar class="md:w-1/3 w-full" :loading="loading" />
+
+      <VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" />
+      <SalesProductPie class="md:w-1/3 w-full" :loading="loading" />
+    </div>
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, ref } from 'vue';
   import GrowCard from './components/GrowCard.vue';
-  import AnalysisLine from './components/AnalysisLine.vue';
-  import AnalysisPie from './components/AnalysisPie.vue';
-  import AnalysisBar from './components/AnalysisBar.vue';
-  import TaskCard from './components/TaskCard.vue';
-  import FlowAnalysis from './components/FlowAnalysis';
-  import { CollapseContainer } from '/@/components/Container/index';
-  import { Row, Col } from 'ant-design-vue';
-  import { growCardList, taskList } from './data';
+  import SiteAnalysis from './components/SiteAnalysis.vue';
+  import VisitSource from './components/VisitSource.vue';
+  import VisitRadar from './components/VisitRadar.vue';
+  import SalesProductPie from './components/SalesProductPie.vue';
+
   export default defineComponent({
     components: {
       GrowCard,
-      CollapseContainer,
-      AnalysisLine,
-      AnalysisPie,
-      AnalysisBar,
-      TaskCard,
-      FlowAnalysis,
-      [Row.name]: Row,
-      [Col.name]: Col,
+      SiteAnalysis,
+      VisitRadar,
+      VisitSource,
+      SalesProductPie,
     },
     setup() {
-      return { growCardList, taskList };
+      const loading = ref(true);
+
+      setTimeout(() => {
+        loading.value = false;
+      }, 1500);
+      return { loading };
     },
   });
 </script>
-<style lang="less" scoped>
-  .analysis {
-    width: 100%;
-  }
-</style>

+ 0 - 16
src/views/dashboard/analysis/types.ts

@@ -1,16 +0,0 @@
-export interface GrowCardItem {
-  icon: string;
-  title: string;
-  price: number;
-  up: boolean;
-  mom: string;
-  percent: number;
-}
-
-export interface TaskItem {
-  percent: number;
-  status: 'success' | 'exception' | 'active';
-  updateTime: string;
-  title: string;
-  desc: string;
-}

+ 0 - 494
src/views/dashboard/house/index.less

@@ -1,494 +0,0 @@
-.house-wrap {
-  position: relative;
-  width: 600px;
-  height: 600px;
-  transform: scale(0.5);
-
-  .house {
-    position: absolute;
-    position: relative;
-    top: 50%;
-    left: 50%;
-    display: flex;
-    width: 400px;
-    height: 300px;
-    transform: translateX(-50%) translateY(-13%);
-    justify-content: center;
-    perspective: 200px;
-  }
-
-  .floor {
-    position: absolute;
-    bottom: 0;
-    display: flex;
-    width: 95%;
-    height: 30px;
-    background-color: #e1f6fd;
-    border: 4px solid #314b70;
-    border-top-right-radius: 4px;
-    border-top-left-radius: 4px;
-    box-shadow: inset 4px 4px 0 #fffdff;
-    justify-content: center;
-  }
-
-  .floor::before,
-  .floor::after {
-    position: absolute;
-    bottom: 0;
-    width: 32%;
-    height: 60%;
-    background-image: linear-gradient(to bottom, #e0f5fc 50%, #aac4d0 50%);
-    border-top: 4px solid #314b70;
-    border-right: 4px solid #314b70;
-    border-left: 4px solid #314b70;
-    border-top-right-radius: 4px;
-    border-top-left-radius: 4px;
-    content: '';
-    box-shadow: 4px 0 0 #aac4d0;
-  }
-
-  .floor::after {
-    top: 0;
-    width: 25%;
-    height: 40%;
-    border-top: none;
-    border-top-right-radius: 0;
-    border-top-left-radius: 0;
-  }
-
-  .wall {
-    position: absolute;
-    bottom: 30px;
-    display: flex;
-    width: 91%;
-    height: 175px;
-    overflow: hidden;
-    background: #c3e0e7;
-    border-right: 4px solid #314b70;
-    border-left: 4px solid #314b70;
-    justify-content: space-between;
-    align-items: flex-end;
-  }
-
-  .window {
-    position: relative;
-    width: 34%;
-    height: 125px;
-    background: #aac4d0;
-    border-top: 4px solid #314b70;
-    border-right: 4px solid #314b70;
-    border-bottom: none;
-    border-left: none;
-    border-top-right-radius: 8px;
-    box-shadow: inset 0 4px 2px #e0f5fc;
-  }
-
-  .window::before {
-    position: absolute;
-    top: 6%;
-    left: 0;
-    width: 94%;
-    height: 88%;
-    background-image: linear-gradient(to top, #f3f6fa 47%, #9ab2d3 47%, #9ab2d3 50%, #f3f6fa 50%);
-    border-top: 4px solid #314b70;
-    border-right: 4px solid #314b70;
-    border-bottom: 4px solid #314b70;
-    border-left: none;
-    border-top-right-radius: 4px;
-    border-bottom-right-radius: 4px;
-    content: '';
-  }
-
-  .window::after {
-    position: absolute;
-    top: 19%;
-    left: 20%;
-    width: 30px;
-    height: 40px;
-    background-color: #f9aabe;
-    border: 4px solid #9ab2d3;
-    content: '';
-  }
-
-  .window:nth-of-type(3) {
-    border-top: none;
-    border-right: 4px solid #314b70;
-    border-bottom: 4px solid #314b70;
-    border-left: none;
-    border-top-right-radius: 0;
-    border-bottom-right-radius: 8px;
-    transform: rotateZ(180deg);
-    box-shadow: inset 0 -4px 2px #e0f5fc;
-  }
-
-  .window:nth-of-type(3)::after {
-    content: none;
-  }
-
-  .door {
-    display: flex;
-    width: 20%;
-    height: 130px;
-    padding-left: 8px;
-    background-color: #ffc26b;
-    border: 4px solid #314b70;
-    border-bottom: none;
-    border-top-right-radius: 10px;
-    border-top-left-radius: 10px;
-    box-shadow: inset 3px 3px #ffe0ad, inset -10px -8px #ffad61, 4px 0 #aac4d0;
-    flex-direction: column;
-    justify-content: space-evenly;
-    align-items: flex-start;
-  }
-
-  .door__square {
-    width: 85%;
-    height: 47px;
-    border: 4px solid #314b70;
-    border-radius: 4px;
-    box-shadow: inset 3px 3px #ffe0ad;
-  }
-
-  .door__line {
-    width: 25%;
-    height: 4px;
-    background: #314b70;
-    border-radius: 4px;
-  }
-
-  .top {
-    position: absolute;
-    width: 82%;
-    height: 30px;
-    background-color: #aac4d0;
-    border: 4px solid #314b70;
-    border-top-right-radius: 4px;
-    border-top-left-radius: 4px;
-    box-shadow: inset 4px 4px 0 #e1f6fd;
-  }
-
-  .circle {
-    position: absolute;
-    top: -10%;
-    display: flex;
-    width: 115px;
-    height: 115px;
-    background-color: #e0f5fc;
-    border: 4px solid #314b70;
-    border-radius: 50%;
-    content: '';
-    box-shadow: inset 4px 4px 0 #fffdff, inset 4px -4px 0 #fffdff, inset -4px 4px 0 #fffdff,
-      inset -4px -4px 0 #fffdff;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .circle::before,
-  .circle::after {
-    position: absolute;
-    top: 35%;
-    width: 70%;
-    height: 4px;
-    background-color: #314b70;
-    content: '';
-  }
-
-  .circle::after {
-    top: 20%;
-    width: 35%;
-  }
-
-  .plastic {
-    position: absolute;
-    top: 30%;
-    z-index: 100;
-    width: 100%;
-    height: 30px;
-    overflow: hidden;
-  }
-
-  .plastic__g {
-    display: flex;
-    justify-content: center;
-    width: 100%;
-    overflow: hidden;
-    transform: translateY(-22px);
-  }
-
-  .plastic__item {
-    width: 43px;
-    height: 43px;
-    margin-bottom: 4px;
-    border: 3px solid #314b70;
-    border-radius: 50%;
-    box-shadow: 0 4px 0 #aac4d0;
-  }
-
-  .plastic__item:nth-child(odd) {
-    background: #0792d9;
-    box-shadow: 0 4px 0 #aac4d0, inset 4px 4px 0 #66c8fa;
-  }
-
-  .plastic__item:nth-child(even) {
-    background: #fffdff;
-  }
-
-  .plastic__item:nth-of-type(1),
-  .plastic__item:nth-last-of-type(1) {
-    width: 45px;
-    height: 45px;
-    box-shadow: none;
-    box-shadow: inset 4px 4px 0 #66c8fa;
-  }
-
-  .plastic__item:nth-of-type(5) {
-    width: 45px;
-    height: 45px;
-  }
-
-  .line {
-    position: absolute;
-    top: 15px;
-    display: flex;
-    width: 90%;
-    height: 85px;
-    background-color: #e1f6fd;
-    border-right: 4px solid #314b70;
-    border-bottom: 4px solid #314b70;
-    border-left: 4px solid #314b70;
-    border-radius: 4px;
-    transform: rotateX(25deg);
-    transform-style: preserve-3d;
-  }
-
-  .line__item {
-    height: 100%;
-    flex-grow: 1;
-    border-right: 4px solid #314b70;
-  }
-
-  .line__item:nth-child(odd) {
-    background: #00affa;
-    box-shadow: inset 4px 4px 0 #66c8fa;
-  }
-
-  .line__item:nth-child(even) {
-    background: #fffdff;
-  }
-
-  .line__item:nth-last-of-type(1) {
-    border-right: none;
-  }
-
-  .line__item:nth-child(4),
-  .line__item:nth-child(5),
-  .line__item:nth-child(6) {
-    border-top: 6px solid #314b70;
-  }
-
-  .tree {
-    position: absolute;
-    bottom: 19%;
-    left: 10%;
-    display: flex;
-    width: 100px;
-    height: 165px;
-    background-color: #00d398;
-    border: 4px solid #314b70;
-    border-radius: 50px;
-    box-shadow: inset 4px 0 0 #77e4c6, inset -4px 0 0 #00a073;
-    animation: tree 1s linear alternate infinite;
-    justify-content: center;
-    transform-origin: 0% 100%;
-  }
-
-  .tree__item {
-    position: absolute;
-    bottom: -80px;
-    width: 4px;
-    height: 140px;
-    background: #314b70;
-  }
-
-  .tree__item:nth-of-type(2) {
-    bottom: 80px;
-    height: 40px;
-    border-radius: 20px;
-    box-shadow: 0 0 0 8px #77e4c6;
-  }
-
-  .tree__item:nth-of-type(2)::before {
-    position: absolute;
-    bottom: -45px;
-    left: -30px;
-    width: 20px;
-    height: 35px;
-    background-color: #77e4c6;
-    border-radius: 15px;
-    content: '';
-  }
-
-  .tree__item:nth-of-type(3) {
-    bottom: 20px;
-    left: 36%;
-    width: 4px;
-    height: 30px;
-    background-color: #314b70;
-    transform: rotateZ(-45deg);
-  }
-
-  .dot {
-    position: absolute;
-    bottom: 38px;
-    width: 100%;
-    height: 4px;
-    background-image: linear-gradient(
-      to right,
-      #314b70 10%,
-      transparent 10%,
-      transparent 11%,
-      #314b70 11%,
-      #314b70 85%,
-      transparent 85%,
-      transparent 86%,
-      #314b70 86%
-    );
-  }
-
-  .bush__item {
-    position: absolute;
-    bottom: 40px;
-    left: 18%;
-    width: 80px;
-    height: 60px;
-    background-color: #00d398;
-    border: 1px solid red;
-    border: 4px solid #314b70;
-    border-bottom: none;
-    border-top-right-radius: 100px;
-    border-top-left-radius: 50px;
-    box-shadow: inset 4px 0 0 #77e4c6, inset -4px 0 0 #00a073;
-    animation: bush 2s alternate infinite;
-    transform-origin: bottom center;
-  }
-
-  .bush__item:nth-of-type(2) {
-    left: 13%;
-    width: 50px;
-    height: 40px;
-    border-top-right-radius: 10px;
-    border-top-left-radius: 50px;
-    animation: tree 2s alternate reverse infinite 0.5s;
-  }
-
-  .bush__item::before {
-    position: absolute;
-    top: 10px;
-    left: 10px;
-    width: 20px;
-    height: 20px;
-    background: #77e4c6;
-    border-radius: 50%;
-    content: '';
-  }
-
-  .cloud {
-    position: absolute;
-    top: 200px;
-    left: 60px;
-    display: flex;
-    justify-content: center;
-    width: 85px;
-    height: 20px;
-    border-bottom: 4px solid #e1e8f2;
-    animation: cloud 4s infinite alternate;
-  }
-
-  .cloud:nth-of-type(2) {
-    top: 150px;
-    left: 50%;
-    animation: cloud 4s infinite reverse alternate 0.5s;
-  }
-
-  .cloud:nth-of-type(3) {
-    top: 250px;
-    left: 80%;
-    animation: cloud 4s ease infinite alternate 0.75s;
-  }
-
-  .cloud__item {
-    position: relative;
-    border-top: 20px solid #e1e8f2;
-    border-right: 20px solid transparent;
-    border-bottom: 20px solid transparent;
-    border-left: 20px solid #e1e8f2;
-    border-radius: 50%;
-    transform: rotateZ(45deg);
-  }
-
-  .cloud__item:nth-of-type(2) {
-    margin-top: 5px;
-    margin-left: -7px;
-    border-top: 15px solid #e1e8f2;
-    border-right: 15px solid transparent;
-    border-bottom: 15px solid transparent;
-    border-left: 15px solid #e1e8f2;
-  }
-
-  .bird {
-    position: absolute;
-    right: 10%;
-    bottom: 40%;
-    z-index: -1;
-    width: 20px;
-    height: 20px;
-    border-top: 4px solid #becde2;
-    border-left: 4px solid #becde2;
-    transform: rotateZ(-135deg);
-    animation: bird 1s ease alternate infinite;
-  }
-
-  .bird:nth-of-type(2) {
-    right: 20%;
-    bottom: 30%;
-    width: 15px;
-    height: 15px;
-  }
-
-  @keyframes bird {
-    0% {
-      transform: scaleY(0.7) rotateZ(-135deg) translateX(0) translateY(0) skew(-10deg, -10deg);
-    }
-
-    100% {
-      transform: scaleY(1) rotateZ(-135deg) translateX(50%) translateY(50%) skew(-10deg, -10deg);
-    }
-  }
-  @keyframes tree {
-    0% {
-      transform: scaleY(1);
-    }
-
-    100% {
-      transform: scaleY(0.975);
-    }
-  }
-  @keyframes bush {
-    0% {
-      transform: skewX(-2deg);
-    }
-
-    100% {
-      transform: skewX(5deg);
-    }
-  }
-  @keyframes cloud {
-    0% {
-      transform: translateX(-10%);
-    }
-
-    100% {
-      transform: translateX(20%);
-    }
-  }
-}

+ 0 - 89
src/views/dashboard/house/index.vue

@@ -1,89 +0,0 @@
-<template>
-  <div class="house-wrap">
-    <div class="house">
-      <div class="floor"></div>
-      <div class="wall">
-        <div class="window"></div>
-        <div class="door">
-          <div class="door__square"></div>
-          <div class="door__line"></div>
-          <div class="door__square"></div>
-        </div>
-        <div class="window"></div>
-      </div>
-      <div class="top"></div>
-      <div class="circle"></div>
-      <div class="plastic">
-        <div class="plastic__g">
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-          <div class="plastic__item"></div>
-        </div>
-      </div>
-      <div class="line">
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-        <div class="line__item"></div>
-      </div>
-    </div>
-    <div class="clouds">
-      <div class="cloud">
-        <div class="cloud__item"></div>
-        <div class="cloud__item"></div>
-      </div>
-      <div class="cloud">
-        <div class="cloud__item"></div>
-        <div class="cloud__item"></div>
-      </div>
-      <div class="cloud">
-        <div class="cloud__item"></div>
-        <div class="cloud__item"></div>
-      </div>
-      <div class="bird"></div>
-    </div>
-    <div class="birds">
-      <div class="bird"></div>
-      <div class="bird"></div>
-    </div>
-    <div class="tree">
-      <div class="tree__item"></div>
-      <div class="tree__item"></div>
-      <div class="tree__item"></div>
-    </div>
-    <div class="bush">
-      <div class="bush__item"></div>
-      <div class="bush__item"></div>
-    </div>
-    <div class="dot"></div>
-  </div>
-</template>
-<script lang="ts">
-  import type { PropType } from 'vue';
-  import { defineComponent } from 'vue';
-  export default defineComponent({
-    name: 'House',
-    props: {
-      size: {
-        type: Number as PropType<number>,
-        default: 600,
-      },
-    },
-    setup() {
-      return {};
-    },
-  });
-</script>
-<style lang="less" scoped>
-  @import './index.less';
-</style>

+ 0 - 22
src/views/dashboard/welcome/index.vue

@@ -1,22 +0,0 @@
-<template>
-  <div class="welcome">
-    <House />
-  </div>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import House from '../house/index.vue';
-  export default defineComponent({
-    name: 'Welcome',
-    components: { House },
-  });
-</script>
-<style lang="less" scoped>
-  .welcome {
-    display: flex;
-    width: 100%;
-    height: 100%;
-    justify-content: center;
-    align-items: center;
-  }
-</style>

+ 37 - 0
src/views/dashboard/workbench/components/DynamicInfo.vue

@@ -0,0 +1,37 @@
+<template>
+  <Card title="最新动态" v-bind="$attrs">
+    <template #extra>
+      <a-button type="link" size="small">更多</a-button>
+    </template>
+    <List item-layout="horizontal" :data-source="items">
+      <template #renderItem="{ item }">
+        <ListItem>
+          <ListItemMeta>
+            <template #description>
+              {{ item.date }}
+            </template>
+            <template #title> {{ item.name }} <span v-html="item.desc"> </span> </template>
+            <template #avatar>
+              <Icon :icon="item.avatar" :size="30" />
+            </template>
+          </ListItemMeta>
+        </ListItem>
+      </template>
+    </List>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+
+  import { Card, List } from 'ant-design-vue';
+  import { dynamicInfoItems } from './data';
+  import headerImg from '/@/assets/images/header.jpg';
+  import { Icon } from '/@/components/Icon';
+
+  export default defineComponent({
+    components: { Card, List, ListItem: List.Item, ListItemMeta: List.Item.Meta, Icon },
+    setup() {
+      return { items: dynamicInfoItems, headerImg };
+    },
+  });
+</script>

+ 0 - 100
src/views/dashboard/workbench/components/NewsList.vue

@@ -1,100 +0,0 @@
-<template>
-  <CollapseContainer class="news-list" title="动态" :canExpan="false">
-    <ScrollContainer>
-      <List>
-        <template v-for="item in newList" :key="item.id">
-          <ListItem class="news-list__item">
-            <ListItemMeta>
-              <template #avatar>
-                <img :src="headerImg" class="news-list__item-avatar" />
-              </template>
-              <template #description>
-                <div class="news-list__item-desc">
-                  <div class="news-list__item-time mb-1">
-                    {{ item.sendTime }}
-                  </div>
-                  <div class="news-list__item-title mb-1">
-                    <span class="news-list__item-light">{{ item.sender }}&nbsp;</span>申请迭代
-                    <span class="news-list__item-light">&nbsp;{{ item.title }}&nbsp;</span>发布
-                  </div>
-                  <div class="news-list__item-cnte p-2">
-                    <span class="news-list__item-cnte__title"> {{ item.cnteId }}</span>
-                    <br />
-                    Status: {{ item.cnteStas }}
-                    <br />
-                    Repository: {{ item.cnteRepo }}
-                    <br />
-                  </div>
-                </div>
-              </template>
-            </ListItemMeta>
-          </ListItem>
-        </template>
-      </List>
-    </ScrollContainer>
-  </CollapseContainer>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { List } from 'ant-design-vue';
-  import { CollapseContainer, ScrollContainer } from '/@/components/Container/index';
-  import headerImg from '/@/assets/images/header.jpg';
-
-  import { newList } from '../data';
-  export default defineComponent({
-    components: {
-      List,
-      ListItem: List.Item,
-      ListItemMeta: List.Item.Meta,
-      CollapseContainer,
-      ScrollContainer,
-    },
-    setup() {
-      return { newList, headerImg };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .news-list {
-    &__item {
-      &-avatar {
-        width: 35px;
-        height: 35px;
-        border-radius: 50%;
-      }
-
-      &-title {
-        font-size: 14px;
-        line-height: 22px;
-        color: #000;
-        opacity: 0.65;
-      }
-
-      &-time {
-        font-size: 14px;
-        line-height: 22px;
-        color: #000;
-        opacity: 0.45;
-      }
-
-      &-light {
-        font-size: 14px;
-        line-height: 22px;
-        color: #000;
-        opacity: 0.85;
-      }
-
-      &-cnte {
-        background: #eef3fb;
-        border-radius: 2px;
-        opacity: 0.6;
-
-        &__title {
-          font-size: 14px;
-          line-height: 22px;
-          color: rgba(0, 0, 0, 0.85);
-        }
-      }
-    }
-  }
-</style>

+ 0 - 101
src/views/dashboard/workbench/components/ProdTotal.vue

@@ -1,101 +0,0 @@
-<template>
-  <a-row class="prod-total">
-    <template v-for="(item, index) in wokbProd" :key="item.type">
-      <a-col :xs="12" :sm="6" class="prod-total__item" :class="`prod-total__item-${index}`">
-        <div class="img" :class="`prod-total__item-${index}-img`"></div>
-        <div>{{ item.amount }}</div>
-        <span>{{ item.type }}</span>
-      </a-col>
-    </template>
-  </a-row>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { Row, Col } from 'ant-design-vue';
-
-  import { wokbProd } from '../data';
-  // import {ProdTypeEnum} from '@/api/dashboard/model/wokbModel'
-  export default defineComponent({
-    components: { [Row.name]: Row, [Col.name]: Col },
-    setup() {
-      return { wokbProd };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .prod-total {
-    padding: 12px 4px 12px 12px;
-    background: #fff;
-
-    &__item {
-      display: inline-block;
-      flex: 0 0 calc(25% - 8px);
-      padding: 20px 10px;
-      margin-right: 8px;
-      border-radius: 4px;
-
-      span {
-        font-size: 14px;
-        line-height: 28px;
-      }
-
-      div {
-        font-size: 26px;
-      }
-
-      .img {
-        float: left;
-        width: 62px;
-        height: 62px;
-      }
-
-      &-0 {
-        background: rgba(254, 97, 178, 0.1);
-
-        &-img {
-          background: url(../../../../assets/images/dashboard/wokb/datashow1.png) no-repeat;
-        }
-
-        div {
-          color: #fe61b2;
-        }
-      }
-
-      &-1 {
-        background: rgba(254, 163, 64, 0.1);
-
-        &-img {
-          background: url(../../../..//assets/images/dashboard/wokb/datashow2.png) no-repeat;
-        }
-
-        div {
-          color: #fea340;
-        }
-      }
-
-      &-2 {
-        background: rgba(172, 70, 255, 0.1);
-
-        &-img {
-          background: url(../../../..//assets/images/dashboard/wokb/datashow3.png) no-repeat;
-        }
-
-        div {
-          color: #9e55ff;
-        }
-      }
-
-      &-3 {
-        background: rgba(0, 196, 186, 0.1);
-
-        &-img {
-          background: url(../../../..//assets/images/dashboard/wokb/datashow4.png) no-repeat;
-        }
-
-        div {
-          color: #00c4ba;
-        }
-      }
-    }
-  }
-</style>

+ 35 - 0
src/views/dashboard/workbench/components/ProjectCard.vue

@@ -0,0 +1,35 @@
+<template>
+  <Card title="项目" v-bind="$attrs">
+    <template #extra>
+      <a-button type="link" size="small">更多</a-button>
+    </template>
+
+    <template v-for="item in items" :key="item">
+      <CardGrid class="!md:w-1/3 !w-full">
+        <span class="flex">
+          <Icon :icon="item.icon" :color="item.color" size="30" />
+          <span class="text-lg ml-4">{{ item.title }}</span>
+        </span>
+        <div class="flex mt-2 h-10 text-secondary"> {{ item.desc }} </div>
+        <div class="flex justify-between text-secondary">
+          <span>{{ item.group }}</span>
+          <span>{{ item.date }}</span>
+        </div>
+      </CardGrid>
+    </template>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { Icon } from '/@/components/Icon';
+  import { groupItems } from './data';
+
+  export default defineComponent({
+    components: { Card, CardGrid: Card.Grid, Icon },
+    setup() {
+      return { items: groupItems };
+    },
+  });
+</script>

+ 26 - 0
src/views/dashboard/workbench/components/QuickNav.vue

@@ -0,0 +1,26 @@
+<template>
+  <Card title="快捷导航" v-bind="$attrs">
+    <template v-for="item in items" :key="item">
+      <CardGrid>
+        <span class="flex flex-col items-center">
+          <Icon :icon="item.icon" :color="item.color" size="20" />
+          <span class="text-md mt-2">{{ item.title }}</span>
+        </span>
+      </CardGrid>
+    </template>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { Icon } from '/@/components/Icon';
+  import { navItems } from './data';
+
+  export default defineComponent({
+    components: { Card, CardGrid: Card.Grid, Icon },
+    setup() {
+      return { items: navItems };
+    },
+  });
+</script>

+ 107 - 0
src/views/dashboard/workbench/components/SaleRadar.vue

@@ -0,0 +1,107 @@
+<template>
+  <Card title="销售统计" :loading="loading">
+    <div ref="chartRef" :style="{ width, height }"></div>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, Ref, ref, watch } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  export default defineComponent({
+    components: { Card },
+    props: {
+      loading: Boolean,
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: '400px',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      watch(
+        () => props.loading,
+        () => {
+          if (props.loading) {
+            return;
+          }
+          setOptions({
+            backgroundColor: '#fff',
+            legend: {
+              bottom: 0,
+              data: ['Visits', 'Sales'],
+            },
+            tooltip: {},
+            radar: {
+              radius: '60%',
+              splitNumber: 8,
+              indicator: [
+                {
+                  text: '2017',
+                  max: 100,
+                },
+                {
+                  text: '2017',
+                  max: 100,
+                },
+                {
+                  text: '2018',
+                  max: 100,
+                },
+                {
+                  text: '2019',
+                  max: 100,
+                },
+                {
+                  text: '2020',
+                  max: 100,
+                },
+                {
+                  text: '2021',
+                  max: 100,
+                },
+              ],
+            },
+            series: [
+              {
+                type: 'radar',
+                symbolSize: 0,
+                areaStyle: {
+                  shadowBlur: 0,
+                  shadowColor: 'rgba(0,0,0,.2)',
+                  shadowOffsetX: 0,
+                  shadowOffsetY: 10,
+                  opacity: 1,
+                },
+                data: [
+                  {
+                    value: [90, 50, 86, 40, 50, 20],
+                    name: 'Visits',
+                    itemStyle: {
+                      color: '#b6a2de',
+                    },
+                  },
+                  {
+                    value: [70, 75, 70, 76, 20, 85],
+                    name: 'Sales',
+                    itemStyle: {
+                      color: '#67e0e3',
+                    },
+                  },
+                ],
+              },
+            ],
+          });
+        },
+        { immediate: true }
+      );
+      return { chartRef };
+    },
+  });
+</script>

+ 0 - 102
src/views/dashboard/workbench/components/ShortCuts.vue

@@ -1,102 +0,0 @@
-<template>
-  <CollapseContainer class="shortcuts" title="快捷入口" :canExpan="false">
-    <template #action>
-      <a-button size="small" type="link"> 新建 </a-button>
-    </template>
-    <a-row>
-      <template v-for="item in shortCuts" :key="item.img">
-        <a-col :span="8" class="p-3 shortcuts__item">
-          <img :src="item.img" class="mb-2 shortcuts__item-img" />
-          <span>{{ item.name }}</span>
-        </a-col>
-      </template>
-
-      <a-col :span="8" class="p-3 shortcuts__item">
-        <span class="mb-2 shortcuts__item-all">
-          <RightOutlined />
-        </span>
-        <br />
-        <span>查看全部</span>
-      </a-col>
-    </a-row>
-  </CollapseContainer>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { Row, Col } from 'ant-design-vue';
-  import { CollapseContainer } from '/@/components/Container/index';
-
-  import { RightOutlined } from '@ant-design/icons-vue';
-  import wokbImg1 from '/@/assets/images/dashboard/wokb/attendance.png';
-  import wokbImg2 from '/@/assets/images/dashboard/wokb/overtime.png';
-  import wokbImg3 from '/@/assets/images/dashboard/wokb/meal.png';
-  import wokbImg4 from '/@/assets/images/dashboard/wokb/leave.png';
-  import wokbImg5 from '/@/assets/images/dashboard/wokb/stamp.png';
-  import wokbImg6 from '/@/assets/images/dashboard/wokb/travel.png';
-  import wokbImg7 from '/@/assets/images/dashboard/wokb/performance.png';
-  import wokbImg8 from '/@/assets/images/dashboard/wokb/approve.png';
-  const shortCuts = [
-    {
-      img: wokbImg1,
-      name: '考勤记录',
-    },
-    {
-      img: wokbImg2,
-      name: '加班申请',
-    },
-    {
-      img: wokbImg3,
-      name: '餐补申请',
-    },
-    {
-      img: wokbImg4,
-      name: '请假',
-    },
-    {
-      img: wokbImg5,
-      name: '用章申请',
-    },
-    {
-      img: wokbImg6,
-      name: '差旅报销',
-    },
-    {
-      img: wokbImg7,
-      name: '绩效申请',
-    },
-    {
-      img: wokbImg8,
-      name: '审批',
-    },
-  ];
-  export default defineComponent({
-    components: { [Row.name]: Row, [Col.name]: Col, CollapseContainer, RightOutlined },
-    setup() {
-      return { shortCuts };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .shortcuts {
-    &__item {
-      text-align: center;
-
-      &-img {
-        width: 36px;
-        margin-left: auto;
-        margin-right: auto;
-      }
-
-      &-all {
-        display: inline-block;
-        width: 36px;
-        height: 36px;
-        line-height: 36px;
-        color: #000;
-        cursor: pointer;
-        background: lightgrey;
-        border-radius: 50%;
-      }
-    }
-  }
-</style>

+ 0 - 114
src/views/dashboard/workbench/components/TodoList.vue

@@ -1,114 +0,0 @@
-<template>
-  <CollapseContainer class="todo-list" title="待办事项" :canExpan="false">
-    <template #title>
-      <span> 待办事项 <span class="todo-list__total">30</span> </span>
-    </template>
-
-    <List>
-      <template v-for="item in todoList" :key="item.id">
-        <ListItem class="todo-list__item">
-          <ListItemMeta>
-            <template #title>
-              <div>
-                <span class="todo-list__item-title">{{ item.title }}</span>
-                <span class="todo-list__item-memo">{{ item.memo }}</span>
-              </div>
-            </template>
-            <template #description>
-              <div class="todo-list__item-desc">
-                提交人:{{ item.sbmter }}
-                <br />
-                提交时间:{{ item.sbmtTime }}
-              </div>
-            </template>
-          </ListItemMeta>
-          <a-button type="link">
-            <Tag color="blue"> 待审批 </Tag>
-          </a-button>
-        </ListItem>
-      </template>
-    </List>
-    <div class="todo-list__all">
-      <Tooltip placement="topRight">
-        <template #title> 查看更多 </template>
-        <EllipsisOutlined />
-      </Tooltip>
-    </div>
-  </CollapseContainer>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { List, Tag, Tooltip } from 'ant-design-vue';
-  import { CollapseContainer } from '/@/components/Container/index';
-
-  import { EllipsisOutlined } from '@ant-design/icons-vue';
-  import { todoList } from '../data';
-
-  export default defineComponent({
-    name: 'TodoList',
-    components: {
-      CollapseContainer,
-      List,
-      ListItem: List.Item,
-      ListItemMeta: List.Item.Meta,
-      Tag,
-      Tooltip,
-      EllipsisOutlined,
-    },
-    setup() {
-      return { todoList };
-    },
-  });
-</script>
-<style lang="less" scoped>
-  .todo-list {
-    position: relative;
-
-    &__total {
-      display: inline-block;
-      width: 20px;
-      height: 20px;
-      font-size: 12px;
-      line-height: 20px;
-      color: #fff;
-      text-align: center;
-      background: rgba(255, 0, 0, 0.7);
-      border-radius: 50%;
-    }
-
-    &__all {
-      position: absolute;
-      top: 0;
-      right: 10px;
-      height: 56px;
-      font-size: 24px;
-      line-height: 56px;
-      text-align: center;
-      cursor: pointer;
-    }
-
-    &__item {
-      padding: 8px;
-
-      &-title {
-        font-size: 14px;
-        font-weight: normal;
-        line-height: 22px;
-        color: #1c1d21;
-      }
-
-      &-memo {
-        font-size: 12px;
-        font-weight: normal;
-        line-height: 22px;
-        color: #7c8087;
-      }
-
-      &-desc {
-        font-size: 12px;
-        line-height: 22px;
-        color: #7c8087;
-      }
-    }
-  }
-</style>

+ 37 - 0
src/views/dashboard/workbench/components/WorkbenchHeader.vue

@@ -0,0 +1,37 @@
+<template>
+  <div class="lg:flex">
+    <Avatar :src="headerImg" :size="72" class="!mx-auto !block" />
+    <div class="md:ml-6 flex flex-col justify-center md:mt-0 mt-2">
+      <h1 class="md:text-lg text-md">早安, Vben, 开始您一天的工作吧!</h1>
+      <span class="text-secondary"> 今日晴,20℃ - 32℃! </span>
+    </div>
+    <div class="flex flex-1 justify-end md:mt-0 mt-4">
+      <div class="flex flex-col justify-center text-right">
+        <span class="text-secondary"> 待办 </span>
+        <span class="text-2xl">2/10</span>
+      </div>
+
+      <div class="flex flex-col justify-center text-right md:mx-16 mx-12">
+        <span class="text-secondary"> 项目 </span>
+        <span class="text-2xl">8</span>
+      </div>
+      <div class="flex flex-col justify-center text-right md:mr-10 mr-4">
+        <span class="text-secondary"> 团队 </span>
+        <span class="text-2xl">300</span>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+
+  import { Avatar } from 'ant-design-vue';
+
+  import headerImg from '/@/assets/images/header.jpg';
+  export default defineComponent({
+    components: { Avatar },
+    setup() {
+      return { headerImg };
+    },
+  });
+</script>

+ 156 - 0
src/views/dashboard/workbench/components/data.ts

@@ -0,0 +1,156 @@
+interface GroupItem {
+  title: string;
+  icon: string;
+  color: string;
+  desc: string;
+  date: string;
+  group: string;
+}
+
+interface NavItem {
+  title: string;
+  icon: string;
+  color: string;
+}
+
+interface DynamicInfoItem {
+  avatar: string;
+  name: string;
+  date: string;
+  desc: string;
+}
+
+export const navItems: NavItem[] = [
+  {
+    title: '首页',
+    icon: 'ion:home-outline',
+    color: '#1fdaca',
+  },
+  {
+    title: '仪表盘',
+    icon: 'ion:grid-outline',
+    color: '#bf0c2c',
+  },
+  {
+    title: '组件',
+    icon: 'ion:layers-outline',
+    color: '#e18525',
+  },
+  {
+    title: '系统管理',
+    icon: 'ion:settings-outline',
+    color: '#3fb27f',
+  },
+  {
+    title: '权限管理',
+    icon: 'ion:key-outline',
+    color: '#4daf1bc9',
+  },
+  {
+    title: '图表',
+    icon: 'ion:bar-chart-outline',
+    color: '#00d8ff',
+  },
+];
+
+export const dynamicInfoItems: DynamicInfoItem[] = [
+  {
+    avatar: 'dynamic-avatar-1|svg',
+    name: '威廉',
+    date: '刚刚',
+    desc: `在 <a>开源组</a> 创建了项目 <a>Vue</a>`,
+  },
+  {
+    avatar: 'dynamic-avatar-2|svg',
+    name: '艾文',
+    date: '1个小时前',
+    desc: `关注了 <a>威廉</a> `,
+  },
+  {
+    avatar: 'dynamic-avatar-3|svg',
+    name: '克里斯',
+    date: '1天前',
+    desc: `发布了 <a>个人动态</a> `,
+  },
+  {
+    avatar: 'dynamic-avatar-4|svg',
+    name: 'Vben',
+    date: '2天前',
+    desc: `发表文章 <a>如何编写一个Vite插件</a> `,
+  },
+  {
+    avatar: 'dynamic-avatar-5|svg',
+    name: '皮特',
+    date: '3天前',
+    desc: `回复了 <a>杰克</a> 的问题 <a>如何进行项目优化?</a>`,
+  },
+  {
+    avatar: 'dynamic-avatar-6|svg',
+    name: '杰克',
+    date: '1周前',
+    desc: `关闭了问题 <a>如何运行项目</a> `,
+  },
+  {
+    avatar: 'dynamic-avatar-1|svg',
+    name: '威廉',
+    date: '1周前',
+    desc: `发布了 <a>个人动态</a> `,
+  },
+  {
+    avatar: 'dynamic-avatar-1|svg',
+    name: '威廉',
+    date: '2021-04-01 20:00',
+    desc: `推送了代码到 <a>Github</a>`,
+  },
+];
+
+export const groupItems: GroupItem[] = [
+  {
+    title: 'Github',
+    icon: 'carbon:logo-github',
+    color: '',
+    desc: '不要等待机会,而要创造机会。',
+    group: '开源组',
+    date: '2021-04-01',
+  },
+  {
+    title: 'Vue',
+    icon: 'ion:logo-vue',
+    color: '#3fb27f',
+    desc: '现在的你决定将来的你。',
+    group: '算法组',
+    date: '2021-04-01',
+  },
+  {
+    title: 'Html5',
+    icon: 'ion:logo-html5',
+    color: '#e18525',
+    desc: '没有什么才能比努力更重要。',
+    group: '上班摸鱼',
+    date: '2021-04-01',
+  },
+  {
+    title: 'Angular',
+    icon: 'ion:logo-angular',
+    color: '#bf0c2c',
+    desc: '热情和欲望可以突破一切难关。',
+    group: 'UI',
+    date: '2021-04-01',
+  },
+  {
+    title: 'React',
+    icon: 'bx:bxl-react',
+    color: '#00d8ff',
+    desc: '健康的身体是实目标的基石。',
+    group: '技术牛',
+    date: '2021-04-01',
+  },
+  {
+    title: 'Js',
+    icon: 'ion:logo-javascript',
+    color: '#4daf1bc9',
+    desc: '路是走出来的,而不是空想出来的。',
+    group: '架构组',
+    date: '2021-04-01',
+  },
+];

+ 0 - 48
src/views/dashboard/workbench/data.ts

@@ -1,48 +0,0 @@
-export const wokbProd = [
-  {
-    amount: '20',
-    type: '成品总数',
-  },
-  {
-    amount: '50',
-    type: '未发布',
-  },
-  {
-    amount: '80',
-    type: '发布中',
-  },
-  {
-    amount: '100',
-    type: '异常',
-  },
-];
-
-export const todoList = (() => {
-  const ret: any[] = [];
-  for (let index = 0; index < 3; index++) {
-    ret.push({
-      id: index,
-      sbmter: '张三',
-      sbmtTime: new Date().toLocaleString(),
-      title: '主要',
-      memo: '工作任务',
-    });
-  }
-  return ret;
-})();
-export const newList = (() => {
-  const ret: any[] = [];
-  for (let index = 0; index < 3; index++) {
-    ret.push({
-      id: index,
-      sender: '李四',
-      sendTime: new Date().toLocaleString(),
-      title: '代码',
-      memo: '工作任务',
-      cnteId: `c${index}`,
-      cnteStas: 'opened',
-      cnteRepo: index,
-    });
-  }
-  return ret;
-})();

+ 43 - 35
src/views/dashboard/workbench/index.vue

@@ -1,46 +1,54 @@
 <template>
-  <a-row class="workbench p-4" :gutter="12">
-    <a-col :md="24" :lg="17">
-      <ProdTotal class="mb-3" />
-      <TodoList class="mb-3" />
-      <NewsList class="mb-3" />
-    </a-col>
-    <a-col :md="24" :lg="7">
-      <img src="/@/assets/images/dashboard/wokb/wokb.png" class="workbench__wokb-img mb-3" />
-      <ShortCuts class="mb-3" />
-      <Week class="mb-3" />
-    </a-col>
-  </a-row>
+  <PageWrapper>
+    <template #headerContent> <WorkbenchHeader /> </template>
+    <div class="lg:flex">
+      <div class="lg:w-7/10 w-full !mr-4 enter-y">
+        <ProjectCard :loading="loading" class="enter-y" />
+        <DynamicInfo :loading="loading" class="!my-4 enter-y" />
+      </div>
+      <div class="lg:w-3/10 w-full enter-y">
+        <QuickNav :loading="loading" class="enter-y" />
+
+        <Card class="!my-4 enter-y" :loading="loading">
+          <img class="xl:h-50 h-30 mx-auto" src="../../../assets/svg/illustration.svg" />
+        </Card>
+
+        <SaleRadar :loading="loading" class="enter-y" />
+      </div>
+    </div>
+  </PageWrapper>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
-  import ProdTotal from './components/ProdTotal.vue';
-  import TodoList from './components/TodoList.vue';
-  import Week from './components/Week.vue';
-  import NewsList from './components/NewsList.vue';
-  import ShortCuts from './components/ShortCuts.vue';
-  import { Row, Col } from 'ant-design-vue';
+  import { defineComponent, ref } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { PageWrapper } from '/@/components/Page';
+  import WorkbenchHeader from './components/WorkbenchHeader.vue';
+  import ProjectCard from './components/ProjectCard.vue';
+  import QuickNav from './components/QuickNav.vue';
+  import DynamicInfo from './components/DynamicInfo.vue';
+  import SaleRadar from './components/SaleRadar.vue';
 
   export default defineComponent({
     components: {
-      ProdTotal,
-      TodoList,
-      Week,
-      ShortCuts,
-      NewsList,
-      [Row.name]: Row,
-      [Col.name]: Col,
+      PageWrapper,
+      WorkbenchHeader,
+      ProjectCard,
+      QuickNav,
+      DynamicInfo,
+      SaleRadar,
+      Card,
     },
     setup() {
-      return {};
+      const loading = ref(true);
+
+      setTimeout(() => {
+        loading.value = false;
+      }, 1500);
+
+      return {
+        loading,
+      };
     },
   });
 </script>
-<style lang="less" scoped>
-  .workbench {
-    &__wokb-img {
-      width: 100%;
-      height: 240px;
-    }
-  }
-</style>

+ 107 - 0
src/views/demo/charts/SaleRadar.vue

@@ -0,0 +1,107 @@
+<template>
+  <Card title="销售统计" :loading="loading">
+    <div ref="chartRef" :style="{ width, height }"></div>
+  </Card>
+</template>
+<script lang="ts">
+  import { defineComponent, Ref, ref, watch } from 'vue';
+
+  import { Card } from 'ant-design-vue';
+  import { useECharts } from '/@/hooks/web/useECharts';
+
+  export default defineComponent({
+    components: { Card },
+    props: {
+      loading: Boolean,
+      width: {
+        type: String as PropType<string>,
+        default: '100%',
+      },
+      height: {
+        type: String as PropType<string>,
+        default: '400px',
+      },
+    },
+    setup(props) {
+      const chartRef = ref<HTMLDivElement | null>(null);
+      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+      watch(
+        () => props.loading,
+        () => {
+          if (props.loading) {
+            return;
+          }
+          setOptions({
+            backgroundColor: '#fff',
+            legend: {
+              bottom: 0,
+              data: ['Visits', 'Sales'],
+            },
+            tooltip: {},
+            radar: {
+              radius: '60%',
+              splitNumber: 8,
+              indicator: [
+                {
+                  text: '2017',
+                  max: 100,
+                },
+                {
+                  text: '2017',
+                  max: 100,
+                },
+                {
+                  text: '2018',
+                  max: 100,
+                },
+                {
+                  text: '2019',
+                  max: 100,
+                },
+                {
+                  text: '2020',
+                  max: 100,
+                },
+                {
+                  text: '2021',
+                  max: 100,
+                },
+              ],
+            },
+            series: [
+              {
+                type: 'radar',
+                symbolSize: 0,
+                areaStyle: {
+                  shadowBlur: 0,
+                  shadowColor: 'rgba(0,0,0,.2)',
+                  shadowOffsetX: 0,
+                  shadowOffsetY: 10,
+                  opacity: 1,
+                },
+                data: [
+                  {
+                    value: [90, 50, 86, 40, 50, 20],
+                    name: 'Visits',
+                    itemStyle: {
+                      color: '#9f8ed7',
+                    },
+                  },
+                  {
+                    value: [70, 75, 70, 76, 20, 85],
+                    name: 'Sales',
+                    itemStyle: {
+                      color: '#1edec5',
+                    },
+                  },
+                ],
+              },
+            ],
+          });
+        },
+        { immediate: true }
+      );
+      return { chartRef };
+    },
+  });
+</script>

+ 7 - 39
src/views/dashboard/workbench/components/Week.vue → src/views/demo/charts/apex/SaleRadar.vue

@@ -1,16 +1,12 @@
 <template>
-  <CollapseContainer title="销售统计" :canExpan="false">
-    <div ref="chartRef" :style="{ width: '100%' }"></div>
-  </CollapseContainer>
+  <div ref="chartRef" :style="{ width: '100%' }"></div>
 </template>
 <script lang="ts">
   import { defineComponent, Ref, ref, onMounted } from 'vue';
 
-  import { CollapseContainer } from '/@/components/Container/index';
   import { useApexCharts } from '/@/hooks/web/useApexCharts';
 
   export default defineComponent({
-    components: { CollapseContainer },
     setup() {
       const chartRef = ref<HTMLDivElement | null>(null);
       const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>);
@@ -20,59 +16,31 @@
             { name: 'Visits', data: [90, 50, 86, 40, 100, 20] },
             { name: 'Sales', data: [70, 75, 70, 76, 20, 85] },
           ],
-          dataLabels: {
-            style: {
-              colors: ['#b9c3cd', '#b9c3cd', '#b9c3cd', '#b9c3cd', '#b9c3cd', '#b9c3cd'],
-            },
-          },
           chart: {
             height: 350,
             type: 'radar',
-            dropShadow: {
-              enabled: true,
-              blur: 1,
-              left: 1,
-              top: 1,
+            toolbar: {
+              show: false,
             },
           },
           yaxis: {
             show: false,
           },
-          grid: {
-            show: false,
-          },
-          legend: { show: false },
+
           title: {
             show: false,
           },
-          tooltip: {
-            x: { show: false },
-          },
           markers: {
-            size: 0,
+            // size: 0,
           },
           xaxis: {
-            categories: ['2011', '2012', '2013', '2014', '2015', '2016'],
+            categories: ['2016', '2017', '2018', '2019', '2020', '2021'],
           },
           stroke: {
             width: 0,
           },
           colors: ['#9f8ed7', '#1edec5'],
-          plotOptions: {
-            radar: {
-              polygons: {
-                strokeColors: [
-                  '#e8e8e8',
-                  'transparent',
-                  'transparent',
-                  'transparent',
-                  'transparent',
-                  'transparent',
-                ],
-                connectorColors: 'transparent',
-              },
-            },
-          },
+
           fill: {
             type: 'gradient',
             gradient: {

+ 5 - 1
src/views/demo/charts/apex/index.vue

@@ -12,6 +12,9 @@
     <div class="demo-box">
       <Mixed />
     </div>
+    <div class="demo-box">
+      <SaleRadar />
+    </div>
   </div>
 </template>
 <script>
@@ -21,8 +24,9 @@
   import Bar from './Bar.vue';
   import Area from './Area.vue';
   import Mixed from './Mixed.vue';
+  import SaleRadar from './SaleRadar.vue';
   export default defineComponent({
-    components: { Line, Bar, Area, Mixed },
+    components: { Line, Bar, Area, Mixed, SaleRadar },
     setup() {},
   });
 </script>

+ 1 - 1
src/views/demo/comp/cropper/index.vue

@@ -1,6 +1,6 @@
 <template>
   <PageWrapper title="图片裁剪示例" contentBackground>
-    <CropperImage src="https://fengyuanchen.github.io/cropperjs/images/picture.jpg"></CropperImage>
+    <CropperImage src="https://fengyuanchen.github.io/cropperjs/images/picture.jpg" />
   </PageWrapper>
 </template>
 <script lang="ts">

+ 3 - 0
src/views/demo/feat/icon/index.vue

@@ -24,6 +24,9 @@
     <CollapseContainer title="svg 雪碧图" class="my-5">
       <div class="flex justify-around flex-wrap">
         <SvgIcon name="test" size="32" />
+        <template v-for="item in 6" :key="item">
+          <SvgIcon :name="`dynamic-avatar-${item}`" size="32" />
+        </template>
       </div>
     </CollapseContainer>
 

+ 1 - 1
src/views/demo/page/account/center/index.vue

@@ -6,7 +6,7 @@
           <a-col :span="8">
             <div :class="`${prefixCls}-top__avatar`">
               <img width="70" :src="headerImg" />
-              <span>Serati Ma</span>
+              <span>Vben</span>
               <div>海纳百川,有容乃大</div>
             </div>
           </a-col>

+ 1 - 1
vite.config.ts

@@ -85,7 +85,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
         'ant-design-vue/es/locale/en_US',
         'moment/dist/locale/eu',
       ],
-      exclude: ['vue-demi', 'consolidate'],
+      exclude: ['vue-demi'],
     },
   };
 };

+ 1 - 0
windi.config.ts

@@ -12,6 +12,7 @@ export default defineConfig({
       colors: {
         ...colors,
         primary: primaryColor,
+        secondary: 'rgba(0, 0, 0, 0.45)',
       },
       screens: {
         sm: '576px',

+ 186 - 218
yarn.lock

@@ -297,6 +297,11 @@
   resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.13.11.tgz#f93ebfc99d21c1772afbbaa153f47e7ce2f50b88"
   integrity sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q==
 
+"@babel/parser@^7.13.9":
+  version "7.13.13"
+  resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df"
+  integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==
+
 "@babel/plugin-proposal-async-generator-functions@^7.13.8":
   version "7.13.8"
   resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1"
@@ -1121,10 +1126,10 @@
   dependencies:
     cross-fetch "^3.0.6"
 
-"@iconify/json@^1.1.322":
-  version "1.1.322"
-  resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.322.tgz#5559ba4efc658a423ce39e7af7ab5f5e8ee7bf7a"
-  integrity sha512-D4o3P8Mrrvd/Gz2qBFVNZYeEn+A/OQkdfT9eh6hz3mz49ob/nk8Q3IRUC0xvVdE4PLawqcKAiKjUyYC8tk8+lA==
+"@iconify/json@^1.1.323":
+  version "1.1.323"
+  resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.323.tgz#38cf0059904cbb18ed0d32b458491aee59497e91"
+  integrity sha512-sSW9u/75hTRdxgNJ0midhBAR2dXe04umm0wn2TXTsKwVQouyv1Ik01ZtA19qMRRvY0CyCc+2CeSYDSxZcfjyKQ==
 
 "@intlify/core-base@9.0.0":
   version "9.0.0"
@@ -1398,10 +1403,10 @@
     "@babel/helper-module-imports" "^7.10.4"
     "@rollup/pluginutils" "^3.1.0"
 
-"@rollup/plugin-node-resolve@^11.2.0":
-  version "11.2.0"
-  resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.0.tgz#a5ab88c35bb7622d115f44984dee305112b6f714"
-  integrity sha512-qHjNIKYt5pCcn+5RUBQxK8krhRvf1HnyVgUCcFFcweDS7fhkOLZeYh0mhHK6Ery8/bb9tvN/ubPzmfF0qjDCTA==
+"@rollup/plugin-node-resolve@^11.2.1":
+  version "11.2.1"
+  resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60"
+  integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==
   dependencies:
     "@rollup/pluginutils" "^3.1.0"
     "@types/resolve" "1.17.1"
@@ -1806,13 +1811,13 @@
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/eslint-plugin@^4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.19.0.tgz#56f8da9ee118fe9763af34d6a526967234f6a7f0"
-  integrity sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw==
+"@typescript-eslint/eslint-plugin@^4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92"
+  integrity sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ==
   dependencies:
-    "@typescript-eslint/experimental-utils" "4.19.0"
-    "@typescript-eslint/scope-manager" "4.19.0"
+    "@typescript-eslint/experimental-utils" "4.20.0"
+    "@typescript-eslint/scope-manager" "4.20.0"
     debug "^4.1.1"
     functional-red-black-tree "^1.0.1"
     lodash "^4.17.15"
@@ -1832,15 +1837,15 @@
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
-"@typescript-eslint/experimental-utils@4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz#9ca379919906dc72cb0fcd817d6cb5aa2d2054c6"
-  integrity sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA==
+"@typescript-eslint/experimental-utils@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz#a8ab2d7b61924f99042b7d77372996d5f41dc44b"
+  integrity sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/scope-manager" "4.19.0"
-    "@typescript-eslint/types" "4.19.0"
-    "@typescript-eslint/typescript-estree" "4.19.0"
+    "@typescript-eslint/scope-manager" "4.20.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/typescript-estree" "4.20.0"
     eslint-scope "^5.0.0"
     eslint-utils "^2.0.0"
 
@@ -1854,14 +1859,14 @@
     "@typescript-eslint/typescript-estree" "4.18.0"
     debug "^4.1.1"
 
-"@typescript-eslint/parser@^4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.19.0.tgz#4ae77513b39f164f1751f21f348d2e6cb2d11128"
-  integrity sha512-/uabZjo2ZZhm66rdAu21HA8nQebl3lAIDcybUoOxoI7VbZBYavLIwtOOmykKCJy+Xq6Vw6ugkiwn8Js7D6wieA==
+"@typescript-eslint/parser@^4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.20.0.tgz#8dd403c8b4258b99194972d9799e201b8d083bdd"
+  integrity sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA==
   dependencies:
-    "@typescript-eslint/scope-manager" "4.19.0"
-    "@typescript-eslint/types" "4.19.0"
-    "@typescript-eslint/typescript-estree" "4.19.0"
+    "@typescript-eslint/scope-manager" "4.20.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/typescript-estree" "4.20.0"
     debug "^4.1.1"
 
 "@typescript-eslint/scope-manager@4.18.0":
@@ -1872,23 +1877,23 @@
     "@typescript-eslint/types" "4.18.0"
     "@typescript-eslint/visitor-keys" "4.18.0"
 
-"@typescript-eslint/scope-manager@4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz#5e0b49eca4df7684205d957c9856f4e720717a4f"
-  integrity sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==
+"@typescript-eslint/scope-manager@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz#953ecbf3b00845ece7be66246608be9d126d05ca"
+  integrity sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ==
   dependencies:
-    "@typescript-eslint/types" "4.19.0"
-    "@typescript-eslint/visitor-keys" "4.19.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/visitor-keys" "4.20.0"
 
 "@typescript-eslint/types@4.18.0":
   version "4.18.0"
   resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.18.0.tgz#bebe323f81f2a7e2e320fac9415e60856267584a"
   integrity sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==
 
-"@typescript-eslint/types@4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz#5181d5d2afd02e5b8f149ebb37ffc8bd7b07a568"
-  integrity sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==
+"@typescript-eslint/types@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.20.0.tgz#c6cf5ef3c9b1c8f699a9bbdafb7a1da1ca781225"
+  integrity sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w==
 
 "@typescript-eslint/typescript-estree@4.18.0":
   version "4.18.0"
@@ -1903,13 +1908,13 @@
     semver "^7.3.2"
     tsutils "^3.17.1"
 
-"@typescript-eslint/typescript-estree@4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz#8a709ffa400284ab72df33376df085e2e2f61147"
-  integrity sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==
+"@typescript-eslint/typescript-estree@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz#8b3b08f85f18a8da5d88f65cb400f013e88ab7be"
+  integrity sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA==
   dependencies:
-    "@typescript-eslint/types" "4.19.0"
-    "@typescript-eslint/visitor-keys" "4.19.0"
+    "@typescript-eslint/types" "4.20.0"
+    "@typescript-eslint/visitor-keys" "4.20.0"
     debug "^4.1.1"
     globby "^11.0.1"
     is-glob "^4.0.1"
@@ -1924,12 +1929,12 @@
     "@typescript-eslint/types" "4.18.0"
     eslint-visitor-keys "^2.0.0"
 
-"@typescript-eslint/visitor-keys@4.19.0":
-  version "4.19.0"
-  resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz#cbea35109cbd9b26e597644556be4546465d8f7f"
-  integrity sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==
+"@typescript-eslint/visitor-keys@4.20.0":
+  version "4.20.0"
+  resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz#1e84db034da13f208325e6bfc995c3b75f7dbd62"
+  integrity sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A==
   dependencies:
-    "@typescript-eslint/types" "4.19.0"
+    "@typescript-eslint/types" "4.20.0"
     eslint-visitor-keys "^2.0.0"
 
 "@vitejs/plugin-legacy@^1.3.2":
@@ -1954,10 +1959,10 @@
     "@vue/babel-plugin-jsx" "^1.0.3"
     hash-sum "^2.0.0"
 
-"@vitejs/plugin-vue@^1.2.0":
-  version "1.2.0"
-  resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.2.0.tgz#f0a92470b74761f90afc8cda204fa3bec9df09f4"
-  integrity sha512-IhSJfJH6IDNEAnhr91+2vhLLe/1SqkA/2BP19jwtn54DGI+cNbZIxiPhHIdKUpdRo0QwErOh6Jy1Maxk2uVo7A==
+"@vitejs/plugin-vue@^1.2.1":
+  version "1.2.1"
+  resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.2.1.tgz#6de49436fc346f829a56676066428e3f011522ac"
+  integrity sha512-TG+LbEUNwfFrx1VyN+iq+PsiGd9MT16hUdJY+BnMXj3MrLAF8m3VYUspTDM3aXoh48YDmAkMjG4gWFRg3lbG5A==
 
 "@vue/babel-helper-vue-transform-on@^1.0.2":
   version "1.0.2"
@@ -1979,6 +1984,17 @@
     html-tags "^3.1.0"
     svg-tags "^1.0.0"
 
+"@vue/compiler-core@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.10.tgz#ced92120c6b9bab7b6c44dfe5e3e5cf2ea422531"
+  integrity sha512-rayD+aODgX9CWgWv0cAI+whPLyMmtkWfNGsZpdpsaIloh8mY2hX8+SvE1Nn3755YhGWJ/7oaDEcNpOctGwZbsA==
+  dependencies:
+    "@babel/parser" "^7.12.0"
+    "@babel/types" "^7.12.0"
+    "@vue/shared" "3.0.10"
+    estree-walker "^2.0.1"
+    source-map "^0.6.1"
+
 "@vue/compiler-core@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.7.tgz#421782a4c67cc3f2b7c30457ef446d74f8524f74"
@@ -1990,6 +2006,14 @@
     estree-walker "^2.0.1"
     source-map "^0.6.1"
 
+"@vue/compiler-dom@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.10.tgz#59d3597498e7d4b0b92f3886a823f99d5b08f1fe"
+  integrity sha512-SzN1li9xAxtqkZimR1AFU2t1N0vzsAJxR/5764xoS0xedwhUU9s8s+Tks2FNMLsXiqdkP2Qd4zAM+9EwTbZmRw==
+  dependencies:
+    "@vue/compiler-core" "3.0.10"
+    "@vue/shared" "3.0.10"
+
 "@vue/compiler-dom@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.7.tgz#54d2e12fb9a7aff53abd19dac2c2679533f0c919"
@@ -1998,17 +2022,17 @@
     "@vue/compiler-core" "3.0.7"
     "@vue/shared" "3.0.7"
 
-"@vue/compiler-sfc@3.0.7":
-  version "3.0.7"
-  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.7.tgz#900414750cc726553b870490f48073451fd14f07"
-  integrity sha512-37/QILpGE+J3V+bP9Slg9e6xGqfk+MmS2Yj8ChR4fS0/qWUU/YoYHE0GPIzjmBdH0JVOOmJqunxowIXmqNiHng==
+"@vue/compiler-sfc@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.10.tgz#de6bc9be7f5ab1d944048a9be04c72c3571d4321"
+  integrity sha512-LLbXHwKMM72aomKsj9AySkLP1xIHREh/3w0nueenKhsWuaKTL1/XUhIPml23+Z+tX55qeJiUIHDeJuFSxfgQfg==
   dependencies:
-    "@babel/parser" "^7.12.0"
-    "@babel/types" "^7.12.0"
-    "@vue/compiler-core" "3.0.7"
-    "@vue/compiler-dom" "3.0.7"
-    "@vue/compiler-ssr" "3.0.7"
-    "@vue/shared" "3.0.7"
+    "@babel/parser" "^7.13.9"
+    "@babel/types" "^7.13.0"
+    "@vue/compiler-core" "3.0.10"
+    "@vue/compiler-dom" "3.0.10"
+    "@vue/compiler-ssr" "3.0.10"
+    "@vue/shared" "3.0.10"
     consolidate "^0.16.0"
     estree-walker "^2.0.1"
     hash-sum "^2.0.0"
@@ -2020,19 +2044,26 @@
     postcss-selector-parser "^6.0.4"
     source-map "^0.6.1"
 
-"@vue/compiler-ssr@3.0.7":
-  version "3.0.7"
-  resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.7.tgz#28b85d497381d75fe44234057b140b0065ca9dbf"
-  integrity sha512-nHRbHeSpfXwjypettjrA16TjgfDcPEwq3m/zHnGyLC1QqdLtklXmpSM43/CPwwTCRa/qdt0pldJf22MiCEuTSQ==
+"@vue/compiler-ssr@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.10.tgz#6ccc647bda49c0fc1ca100219e9c71268e048120"
+  integrity sha512-skrPSp9pjZG3unqHpUaEaRRpO1yYxbCXRfJ1kZW8PTGAg5g3Y/hrUet5+Q6zCIZwr5j1mSMBSLXMDCjFuyyZLg==
   dependencies:
-    "@vue/compiler-dom" "3.0.7"
-    "@vue/shared" "3.0.7"
+    "@vue/compiler-dom" "3.0.10"
+    "@vue/shared" "3.0.10"
 
 "@vue/devtools-api@^6.0.0-beta.5":
   version "6.0.0-beta.7"
   resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.7.tgz#1d306613c93b9a837a3776b1b9255502662f850f"
   integrity sha512-mIfqX8ZF6s2ulelIzfxGk9sFoigpoeK/2/DlWrtBGWfvwaK3kR1P2bxNkZ0LbJeuKHfcRP6hGZtGist7nxUN9A==
 
+"@vue/reactivity@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.10.tgz#012830733291e60827f3b228d425ad53b83484ce"
+  integrity sha512-0GOSqlIv/a5wy4r6fAcdaglQ8v2sLYMRUpu49yK8Z2vHccK85Ym3R9C9K3vo6dfBRGbbCVvoKxYtQw49LvE8Ug==
+  dependencies:
+    "@vue/shared" "3.0.10"
+
 "@vue/reactivity@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.7.tgz#e6ccc7bef7fc10b0972e4d974bad71679d3b26ad"
@@ -2040,6 +2071,14 @@
   dependencies:
     "@vue/shared" "3.0.7"
 
+"@vue/runtime-core@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.10.tgz#cb8730c0ec86ea5c1cfa701facc0a97bf59b15a2"
+  integrity sha512-qKhCOwHGff5YEdyClO1gf9Q9xgaPPz/qJ2GyzNZkPb00WcXJ3l+yTgHZWaSywRLs9GD1y9Ff3C0MIowzj95NHA==
+  dependencies:
+    "@vue/reactivity" "3.0.10"
+    "@vue/shared" "3.0.10"
+
 "@vue/runtime-core@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.7.tgz#d44c0b0a57d7e392912a87362a4430ccf446ecea"
@@ -2048,6 +2087,15 @@
     "@vue/reactivity" "3.0.7"
     "@vue/shared" "3.0.7"
 
+"@vue/runtime-dom@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.10.tgz#80c6ee28caeabf74f31357d2c64d177945bd8a5f"
+  integrity sha512-8yRAALc/884UlYWY7hJImecvow1Cngbl2B6n0ThYTms08FVQ3W9tdW0MEvR3JVit06JyQLS1Qvwdn1PwNPPDqg==
+  dependencies:
+    "@vue/runtime-core" "3.0.10"
+    "@vue/shared" "3.0.10"
+    csstype "^2.6.8"
+
 "@vue/runtime-dom@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.7.tgz#b70668d729020bc4ad608c20367223f259576ba6"
@@ -2057,30 +2105,35 @@
     "@vue/shared" "3.0.7"
     csstype "^2.6.8"
 
+"@vue/shared@3.0.10":
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.10.tgz#5476d5615d01bf339c65c2e804f5909bbc27844a"
+  integrity sha512-p8GJ+bGpEGiEHICwcCH/EtJnkZQllrOfm1J2J+Ep0ydMte25bPnArgrY/h2Tn1LKqqR3LXyQlOSYY6gJgiW2LQ==
+
 "@vue/shared@3.0.7":
   version "3.0.7"
   resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.0.7.tgz#96d52988efc07444c108c7c6803ba7cc93e40045"
   integrity sha512-dn5FyfSc4ky424jH4FntiHno7Ss5yLkqKNmM/NXwANRnlkmqu74pnGetexDFVG5phMk9/FhwovUZCWGxsotVKg==
 
-"@vueuse/core@^4.6.2":
-  version "4.6.2"
-  resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.6.2.tgz#73a07ddbb3d01c66ef7d79500190f25a7ca7afac"
-  integrity sha512-FNI3qYazSrh4HReffs41qUl9ptu3HGe6Jn5ttGcfg3WHuHqhPV8VdhSWEO4wCx+rm131ta4CMGN7TNN54pTODw==
+"@vueuse/core@^4.6.3":
+  version "4.6.3"
+  resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.6.3.tgz#9684b602cb0d08583ee9151c52760c4db1707da2"
+  integrity sha512-x/ymdXfEOaLgxDdxGvK5v8bcImWUDXUDPJJ0xZ4GjJWYmZ1PkMgbQTyEq48kd+qKhSwgKzMAYWkL2BAbToTtOg==
   dependencies:
-    "@vueuse/shared" "4.6.2"
+    "@vueuse/shared" "4.6.3"
     vue-demi latest
 
-"@vueuse/shared@4.6.2":
-  version "4.6.2"
-  resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.6.2.tgz#5237615d56cc872723b2352f8b2b420bbdb97533"
-  integrity sha512-niGuwfS9QjRhA44qopwczanH0u8TUgkgmUnTsOAz9a+iwGIxOK3ImpX1iCW7Dshqkz3YhPtmpycOrwF07s5jIQ==
+"@vueuse/shared@4.6.3":
+  version "4.6.3"
+  resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.6.3.tgz#2659b731d1a5701d98ed85c3990331f70c7c6513"
+  integrity sha512-YWgMLvDJ51I+1waSP79Wdc1P78qmYUnLfHquNlzZCZXzR9nDx7cGXm+6HV4xEK3h8mAV38oozJOebQCoCo1DDw==
   dependencies:
     vue-demi latest
 
-"@windicss/plugin-utils@0.11.0":
-  version "0.11.0"
-  resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.11.0.tgz#142fe810c9cf71719074518295f65bd01f0ac895"
-  integrity sha512-NIBJ7/wG8Ty///Qxktefud4OI18XjZkycW6DSkWV7++aYyZOdDgGRn493pU+5QZuXeXU8iNR6NKZDtFNcYD7kQ==
+"@windicss/plugin-utils@0.10.4":
+  version "0.10.4"
+  resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-0.10.4.tgz#ed9163b09e030f7358cc4742b1f2b6c92d084d5d"
+  integrity sha512-jQu69qzA56Lv18OK8U4mUTDV17st4EdPawQuaRG2VNK+ZEQWYsMNnqGxhzDTl/NhWTGCcTb3D6mlFPNo0QDOFg==
   dependencies:
     debug "^4.3.2"
     fast-glob "^3.2.5"
@@ -2088,7 +2141,7 @@
     micromatch "^4.0.2"
     pirates "^4.0.1"
     sucrase "^3.17.1"
-    windicss "^2.5.8"
+    windicss "^2.5.7"
 
 "@zxcvbn-ts/core@^0.3.0":
   version "0.3.0"
@@ -2673,22 +2726,6 @@ bluebird@^3.5.0, bluebird@^3.7.2:
   resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
   integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
 
-body-parser@^1.19.0:
-  version "1.19.0"
-  resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
-  integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
-  dependencies:
-    bytes "3.1.0"
-    content-type "~1.0.4"
-    debug "2.6.9"
-    depd "~1.1.2"
-    http-errors "1.7.2"
-    iconv-lite "0.4.24"
-    on-finished "~2.3.0"
-    qs "6.7.0"
-    raw-body "2.4.0"
-    type-is "~1.6.17"
-
 boolbase@^1.0.0, boolbase@~1.0.0:
   version "1.0.0"
   resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
@@ -2796,11 +2833,6 @@ builtin-modules@^3.1.0:
   resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887"
   integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==
 
-bytes@3.1.0:
-  version "3.1.0"
-  resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
-  integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
-
 cache-base@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@@ -3348,11 +3380,6 @@ content-disposition@^0.5.2:
   dependencies:
     safe-buffer "5.1.2"
 
-content-type@~1.0.4:
-  version "1.0.4"
-  resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-  integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
-
 conventional-changelog-angular@^5.0.11, conventional-changelog-angular@^5.0.12:
   version "5.0.12"
   resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz#c979b8b921cbfe26402eb3da5bbfda02d865a2b9"
@@ -3942,11 +3969,6 @@ delayed-stream@~1.0.0:
   resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
   integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
 
-depd@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
-  integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
-
 detect-file@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
@@ -4286,12 +4308,17 @@ esbuild-register@^2.2.0:
     esbuild "^0.9.2"
     jsonc-parser "^3.0.0"
 
+esbuild@^0.11.2:
+  version "0.11.2"
+  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.2.tgz#3b995e107f2054d9090402b98a3b79ceffd05eb6"
+  integrity sha512-8d5FCQrR+juXC2u9zjTQ3+IYiuFuaWyKYwmApFJLquTrYNbk36H/+MkRQeTuOJg7IjUchRX2Ulwo1zRYXZ1pUg==
+
 esbuild@^0.9.2:
   version "0.9.4"
   resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.9.4.tgz#4480ffc4c1e5d5bb25958f889b5de0279bfb2d6f"
   integrity sha512-bF6laCiYE5+iAfZsX+v6Lwvi5QbvKN3tThxDIR2WLyLYzTzNn0ijdpqkvTVsafmRZjic2Nq1nkSf5RSWySDTjA==
 
-esbuild@^0.9.3, esbuild@^0.9.7:
+esbuild@^0.9.3:
   version "0.9.7"
   resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.9.7.tgz#ea0d639cbe4b88ec25fbed4d6ff00c8d788ef70b"
   integrity sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==
@@ -4333,10 +4360,10 @@ eslint-config-prettier@^8.1.0:
   resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.1.0.tgz#4ef1eaf97afe5176e6a75ddfb57c335121abc5a6"
   integrity sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw==
 
-eslint-define-config@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.npmjs.org/eslint-define-config/-/eslint-define-config-1.0.5.tgz#e4799d27a75f51ab1ce151f00b6802f03948b1fc"
-  integrity sha512-kwBMdZ7UKpzTkymYnBZrTSOGbawoCnPOKVUjSbOype9dj7YRczT1nDKk0tPRawtcm7y7zfoGf5nBUrcYO60Avg==
+eslint-define-config@^1.0.6:
+  version "1.0.6"
+  resolved "https://registry.npmjs.org/eslint-define-config/-/eslint-define-config-1.0.6.tgz#b2e47832dcefab62bb853ffb78cb4963524efc44"
+  integrity sha512-Kq/XwRSYm5N3KTdK1IKT6I8IZFjtTxxgBjOb47iPvKfzjqfAu3xcaEJYqN1QtnsJoJf8lPCKBDMmKXu2f9ayZw==
 
 eslint-plugin-jest@^24.1.5:
   version "24.3.2"
@@ -5643,17 +5670,6 @@ http-cache-semantics@3.8.1:
   resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
   integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
 
-http-errors@1.7.2:
-  version "1.7.2"
-  resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
-  integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
-  dependencies:
-    depd "~1.1.2"
-    inherits "2.0.3"
-    setprototypeof "1.1.1"
-    statuses ">= 1.5.0 < 2"
-    toidentifier "1.0.0"
-
 http-proxy@^1.18.0:
   version "1.18.1"
   resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
@@ -5869,11 +5885,6 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
   resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
 
-inherits@2.0.3:
-  version "2.0.3"
-  resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
 ini@^1.3.2, ini@^1.3.4, ini@^1.3.5:
   version "1.3.8"
   resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
@@ -6771,11 +6782,6 @@ jest@^26.6.3:
     import-local "^3.0.2"
     jest-cli "^26.6.3"
 
-joycon@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.npmjs.org/joycon/-/joycon-3.0.1.tgz#9074c9b08ccf37a6726ff74a18485f85efcaddaf"
-  integrity sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==
-
 js-base64@^2.1.9:
   version "2.6.4"
   resolved "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
@@ -7362,11 +7368,6 @@ mdn-data@2.0.4:
   resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
   integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==
 
-media-typer@0.3.0:
-  version "0.3.0"
-  resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
-  integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-
 meow@^3.3.0:
   version "3.7.0"
   resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
@@ -7506,7 +7507,7 @@ mime-db@1.46.0, mime-db@^1.28.0:
   resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
   integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==
 
-mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24:
+mime-types@^2.1.12, mime-types@~2.1.19:
   version "2.1.29"
   resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2"
   integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==
@@ -8556,7 +8557,7 @@ postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.2
     source-map "^0.6.1"
     supports-color "^6.1.0"
 
-postcss@^8.1.10, postcss@^8.2.1, postcss@^8.2.8:
+postcss@^8.1.10, postcss@^8.2.1:
   version "8.2.8"
   resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece"
   integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==
@@ -8565,6 +8566,15 @@ postcss@^8.1.10, postcss@^8.2.1, postcss@^8.2.8:
     nanoid "^3.1.20"
     source-map "^0.6.1"
 
+postcss@^8.2.9:
+  version "8.2.9"
+  resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.9.tgz#fd95ff37b5cee55c409b3fdd237296ab4096fba3"
+  integrity sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==
+  dependencies:
+    colorette "^1.2.2"
+    nanoid "^3.1.22"
+    source-map "^0.6.1"
+
 posthtml-parser@^0.2.0, posthtml-parser@^0.2.1:
   version "0.2.1"
   resolved "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.2.1.tgz#35d530de386740c2ba24ff2eb2faf39ccdf271dd"
@@ -8741,11 +8751,6 @@ qrcode@^1.4.4:
     pngjs "^3.3.0"
     yargs "^13.2.4"
 
-qs@6.7.0:
-  version "6.7.0"
-  resolved "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
-  integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
-
 qs@^6.4.0:
   version "6.10.0"
   resolved "https://registry.npmjs.org/qs/-/qs-6.10.0.tgz#8b6519121ab291c316a3e4d49cecf6d13d8c7fe5"
@@ -8792,16 +8797,6 @@ randombytes@^2.1.0:
   dependencies:
     safe-buffer "^5.1.0"
 
-raw-body@2.4.0:
-  version "2.4.0"
-  resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
-  integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
-  dependencies:
-    bytes "3.1.0"
-    http-errors "1.7.2"
-    iconv-lite "0.4.24"
-    unpipe "1.0.0"
-
 react-is@^17.0.1:
   version "17.0.1"
   resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
@@ -9187,15 +9182,6 @@ rimraf@^3.0.0, rimraf@^3.0.2:
   dependencies:
     glob "^7.1.3"
 
-rollup-plugin-esbuild@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-3.0.2.tgz#85a1afd59510ef143813b46f515e92a49779a60b"
-  integrity sha512-uq+oBCeLXF1m6g9V0qpqbPbgyq24aXBKF474BvqgxfNmTP6FZ+oVk5/pCWQ/2rfSNJs4IimNU/k0q8xMaa0iCA==
-  dependencies:
-    "@rollup/pluginutils" "^4.1.0"
-    joycon "^3.0.0"
-    jsonc-parser "^3.0.0"
-
 rollup-plugin-purge-icons@^0.7.0:
   version "0.7.0"
   resolved "https://registry.npmjs.org/rollup-plugin-purge-icons/-/rollup-plugin-purge-icons-0.7.0.tgz#4419b810d5d75f1bba3af72a238e70b4a675f03c"
@@ -9239,13 +9225,6 @@ rollup@^2.25.0, rollup@^2.38.5:
   optionalDependencies:
     fsevents "~2.3.1"
 
-rollup@^2.42.4:
-  version "2.42.4"
-  resolved "https://registry.npmjs.org/rollup/-/rollup-2.42.4.tgz#97c910a48bd0db6aaa4271dd48745870cbbbf970"
-  integrity sha512-Zqv3EvNfcllBHyyEUM754npqsZw82VIjK34cDQMwrQ1d6aqxzeYu5yFb7smGkPU4C1Bj7HupIMeT6WU7uIdnMw==
-  optionalDependencies:
-    fsevents "~2.3.1"
-
 rsvp@^4.8.4:
   version "4.8.5"
   resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
@@ -9408,11 +9387,6 @@ set-value@^2.0.0, set-value@^2.0.1:
     is-plain-object "^2.0.3"
     split-string "^3.0.1"
 
-setprototypeof@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
-  integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
-
 shallow-equal@^1.0.0:
   version "1.2.1"
   resolved "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
@@ -9721,7 +9695,7 @@ static-extend@^0.1.1:
     define-property "^0.2.5"
     object-copy "^0.1.0"
 
-"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
+statuses@~1.5.0:
   version "1.5.0"
   resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
   integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
@@ -10395,11 +10369,6 @@ to-regex@^3.0.1, to-regex@^3.0.2:
     regex-not "^1.0.2"
     safe-regex "^1.1.0"
 
-toidentifier@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
-  integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
-
 tough-cookie@^2.3.3, tough-cookie@~2.5.0:
   version "2.5.0"
   resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@@ -10579,14 +10548,6 @@ type-fest@^0.8.1:
   resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
   integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
 
-type-is@~1.6.17:
-  version "1.6.18"
-  resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
-  integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
-  dependencies:
-    media-typer "0.3.0"
-    mime-types "~2.1.24"
-
 typedarray-to-buffer@^3.1.5:
   version "3.1.5"
   resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@@ -10715,7 +10676,7 @@ universalify@^2.0.0:
   resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
   integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
 
-unpipe@1.0.0, unpipe@~1.0.0:
+unpipe@~1.0.0:
   version "1.0.0"
   resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
   integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
@@ -10920,22 +10881,20 @@ vite-plugin-imagemin@^0.2.9:
     imagemin-svgo "^8.0.0"
     imagemin-webp "^6.0.0"
 
-vite-plugin-mock@^2.4.0:
-  version "2.4.0"
-  resolved "https://registry.npmjs.org/vite-plugin-mock/-/vite-plugin-mock-2.4.0.tgz#41a71e40c4557d1052e94b9d16bdb6c5efa779a7"
-  integrity sha512-tt38JCkxYQty2GXMB46KupCSL6qsWyvyT8hRUWSMwz5ak9jQ6Wkktcti/cPYnHkI1IVIUNIpxaqvpHUht3pN/A==
+vite-plugin-mock@^2.4.1:
+  version "2.4.1"
+  resolved "https://registry.npmjs.org/vite-plugin-mock/-/vite-plugin-mock-2.4.1.tgz#f1095068a3ab9c7ce07634ce392c7bdb0e196a45"
+  integrity sha512-HKHLwzje9ubo7/nKuGTQkvBnbHMj6ReAYxTXM/6QTp2p4oyE4kLNSMinJu9YvR7xmlcxlfWEpz5qMhY7yY+Ctg==
   dependencies:
-    "@rollup/plugin-node-resolve" "^11.2.0"
+    "@rollup/plugin-node-resolve" "^11.2.1"
     "@types/mockjs" "^1.0.3"
     chalk "^4.1.0"
     chokidar "^3.5.1"
     connect "^3.7.0"
     debug "^4.3.2"
-    esbuild "^0.9.7"
+    esbuild "^0.11.2"
     fast-glob "^3.2.5"
     path-to-regexp "^6.2.0"
-    rollup "^2.42.4"
-    rollup-plugin-esbuild "^3.0.2"
 
 vite-plugin-purge-icons@^0.7.0:
   version "0.7.0"
@@ -11010,20 +10969,20 @@ vite-plugin-theme@^0.5.0:
     tinycolor2 "^1.4.2"
     ts-jest "^26.5.3"
 
-vite-plugin-windicss@0.11.0:
-  version "0.11.0"
-  resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.11.0.tgz#784b3b7c72d29e85d52dad705a846f8e2366a2fc"
-  integrity sha512-DSXomaGHXAXIF9zPk7T9KG8m1bMNNiIHpeoClX44qxNHT7ryI6iDI8gkWdNfYVjxjcoXSTxKqKa11MA+C7mmAA==
+vite-plugin-windicss@0.10.4:
+  version "0.10.4"
+  resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-0.10.4.tgz#e93577111ea0a55befbe4e2aa2e596f55f6b74b2"
+  integrity sha512-P7alH2dGGw3OTgjs9yZG2w0i+o1HKD8PChwhm2ftP+lLCe1xDL3LReheuRil9p2xPYzrVouER2YTbIdLUEThrQ==
   dependencies:
-    "@windicss/plugin-utils" "0.11.0"
+    "@windicss/plugin-utils" "0.10.4"
     chalk "^4.1.0"
     debug "^4.3.2"
-    windicss "^2.5.8"
+    windicss "^2.5.7"
 
-vite@2.1.3:
-  version "2.1.3"
-  resolved "https://registry.npmjs.org/vite/-/vite-2.1.3.tgz#a31a844d26d3846b5a78f06970d1ea1f8a442955"
-  integrity sha512-bUzArZIUwADVJS/3ywCr4KKFn3a7izs4M87ZDlAlY2V34E4g1kH6p3sVNAh8/IXCn/56fwgMh3rRavPUW7qEQQ==
+vite@2.1.5:
+  version "2.1.5"
+  resolved "https://registry.npmjs.org/vite/-/vite-2.1.5.tgz#4857da441c62f7982c83cbd5f42a00330f20c9c1"
+  integrity sha512-tYU5iaYeUgQYvK/CNNz3tiJ8vYqPWfCE9IQ7K0iuzYovWw7lzty7KRYGWwV3CQPh0NKxWjOczAqiJsCL0Xb+Og==
   dependencies:
     esbuild "^0.9.3"
     postcss "^8.2.1"
@@ -11070,7 +11029,16 @@ vue-types@^3.0.0, vue-types@^3.0.2:
   dependencies:
     is-plain-object "3.0.1"
 
-vue@3.0.7, vue@^3.0.0:
+vue@3.0.10:
+  version "3.0.10"
+  resolved "https://registry.npmjs.org/vue/-/vue-3.0.10.tgz#b5d2801c6ac0e756c850ad7a8f9a78cbccbad02a"
+  integrity sha512-6arZ722uqIArSNUU94aqx0Pq0IMHFqYZuJ+U+q9HGdZZu11VFpyFP/L/hakijGFKp56Jr0yxJdWbDiJGWPxwww==
+  dependencies:
+    "@vue/compiler-dom" "3.0.10"
+    "@vue/runtime-dom" "3.0.10"
+    "@vue/shared" "3.0.10"
+
+vue@^3.0.0:
   version "3.0.7"
   resolved "https://registry.npmjs.org/vue/-/vue-3.0.7.tgz#8bcff51f8be570f9e4ce8cc5f52e2ab0fe3c74a1"
   integrity sha512-8h4TikD+JabbMK9aRlBO4laG0AtNHRPHynxYgWZ9sq1YUPfzynd9Jeeb27XNyZytC7aCQRX9xe1+TQJuc181Tw==
@@ -11192,7 +11160,7 @@ which@^2.0.1, which@^2.0.2:
   dependencies:
     isexe "^2.0.0"
 
-windicss@^2.5.8:
+windicss@^2.5.7:
   version "2.5.8"
   resolved "https://registry.npmjs.org/windicss/-/windicss-2.5.8.tgz#254980044de3031276062b90cfce53c13ee489bf"
   integrity sha512-zHkozdIqv1YTIGHBOHeFGsuZVTN5yAMz6FW5Bp8im9JZxSRZLOLKdJB0K75SL13iLHKXHrC1ukwJjjL8CohrUw==

Some files were not shown because too many files changed in this diff