zhb 7 meses atrás
commit
0a7e5ad64c
100 arquivos alterados com 7141 adições e 0 exclusões
  1. 13 0
      .editorconfig
  2. 5 0
      .env
  3. 5 0
      .env.development
  4. 5 0
      .env.production
  5. 6 0
      .env.test
  6. 20 0
      .eslintignore
  7. 79 0
      .eslintrc.js
  8. 25 0
      .gitignore
  9. 9 0
      .prettierignore
  10. 20 0
      .prettierrc.json
  11. 121 0
      index.html
  12. 104 0
      package.json
  13. BIN
      public/favicon.ico
  14. 17 0
      public/index.html
  15. BIN
      public/static/screen/bg.jpg
  16. BIN
      public/static/screen/bg.png
  17. BIN
      public/static/screen/footer2.png
  18. BIN
      public/static/screen/header-bg.png
  19. BIN
      public/static/screen/server-bg.png
  20. 7 0
      shims-vue.d.ts
  21. 37 0
      src/App.vue
  22. 44 0
      src/api/errorCodeType.ts
  23. 62 0
      src/api/request.ts
  24. 9 0
      src/api/user.ts
  25. BIN
      src/assets/403_images/403.png
  26. BIN
      src/assets/403_images/403_cloud.png
  27. BIN
      src/assets/404_images/404.png
  28. BIN
      src/assets/404_images/404_bg.png
  29. BIN
      src/assets/404_images/404_cloud.png
  30. 114 0
      src/assets/iconfont/iconfont.css
  31. 1 0
      src/assets/iconfont/iconfont.js
  32. 184 0
      src/assets/iconfont/iconfont.json
  33. BIN
      src/assets/iconfont/iconfont.ttf
  34. BIN
      src/assets/iconfont/iconfont.woff
  35. BIN
      src/assets/iconfont/iconfont.woff2
  36. BIN
      src/assets/image/allow.png
  37. BIN
      src/assets/image/avatar.png
  38. BIN
      src/assets/image/berserk.jpg
  39. BIN
      src/assets/image/center-inner1.png
  40. BIN
      src/assets/image/charts/1-1-bg.png
  41. BIN
      src/assets/image/circle-bg.png
  42. BIN
      src/assets/image/cro-avatar.jpg
  43. BIN
      src/assets/image/login/qrcode-icon.png
  44. BIN
      src/assets/image/login/side-logo.png
  45. BIN
      src/assets/image/logo.png
  46. BIN
      src/assets/image/we.png
  47. 85 0
      src/components/AvatarCropper/index.vue
  48. 120 0
      src/components/CodeMirror/index.vue
  49. 5 0
      src/components/CountTo/index.js
  50. 202 0
      src/components/CountTo/index.vue
  51. 51 0
      src/components/CountTo/requestAnimationFrame.js
  52. 269 0
      src/components/DataScreen/Multiline/index.vue
  53. 117 0
      src/components/DataScreen/barEcharts/index.vue
  54. 111 0
      src/components/DataScreen/lineEcharts/index.vue
  55. 38 0
      src/components/DataScreen/migrationEcharts/data.js
  56. 332 0
      src/components/DataScreen/migrationEcharts/index.vue
  57. 3043 0
      src/components/DataScreen/migrationEcharts/map.js
  58. 183 0
      src/components/DataScreen/pie/index.vue
  59. 18 0
      src/components/PageWrapLayout/index.scss
  60. 13 0
      src/components/PageWrapLayout/index.vue
  61. 116 0
      src/components/RightClickMenu/index.vue
  62. 61 0
      src/components/SearchForm/components/BaseFormItem.vue
  63. 127 0
      src/components/SearchForm/index.vue
  64. 35 0
      src/components/SvgIcon/index.vue
  65. 26 0
      src/components/SwitchDark/index.vue
  66. 306 0
      src/components/Table/EditableProTable/index.vue
  67. 206 0
      src/components/Table/PropTable/index.vue
  68. 163 0
      src/components/Theme/index.vue
  69. 88 0
      src/components/Upload/index.vue
  70. 80 0
      src/components/WangEdior/index.vue
  71. 8 0
      src/components/pipeline/index.vue
  72. 150 0
      src/components/pipeline/zb-pipeline-start.vue
  73. 30 0
      src/components/u-container-layout/index.vue
  74. 2 0
      src/config/index.ts
  75. 115 0
      src/hooks/useFullscreen.ts
  76. 39 0
      src/hooks/useResizeElement.ts
  77. 66 0
      src/hooks/useResizeHandler.ts
  78. 23 0
      src/hooks/useWrapComponents.ts
  79. 10 0
      src/icons/index.js
  80. 0 0
      src/icons/svg/borrow.svg
  81. 1 0
      src/icons/svg/compass.svg
  82. 0 0
      src/icons/svg/dashboard.svg
  83. 1 0
      src/icons/svg/entrust.svg
  84. 1 0
      src/icons/svg/example.svg
  85. 1 0
      src/icons/svg/exit-fullscreen.svg
  86. 1 0
      src/icons/svg/eye-open.svg
  87. 1 0
      src/icons/svg/eye.svg
  88. 0 0
      src/icons/svg/form.svg
  89. 1 0
      src/icons/svg/fullscreen.svg
  90. 1 0
      src/icons/svg/go-out.svg
  91. 1 0
      src/icons/svg/home.svg
  92. 1 0
      src/icons/svg/horn.svg
  93. 0 0
      src/icons/svg/inquiry.svg
  94. 1 0
      src/icons/svg/link.svg
  95. 1 0
      src/icons/svg/nested.svg
  96. 1 0
      src/icons/svg/notice.svg
  97. 1 0
      src/icons/svg/password.svg
  98. 1 0
      src/icons/svg/put-in.svg
  99. 1 0
      src/icons/svg/report-form.svg
  100. 0 0
      src/icons/svg/settings.svg

+ 13 - 0
.editorconfig

@@ -0,0 +1,13 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false

+ 5 - 0
.env

@@ -0,0 +1,5 @@
+
+# port
+VITE_PORT = 8100
+
+

+ 5 - 0
.env.development

@@ -0,0 +1,5 @@
+# 本地环境
+NODE_ENV = 'development'
+
+# 本地环境接口地址
+VITE_APP_BASE_API = '/api'

+ 5 - 0
.env.production

@@ -0,0 +1,5 @@
+# 线上环境
+NODE_ENV = "production"
+
+# 线上环境接口地址
+VITE_APP_BASE_API = '/api'

+ 6 - 0
.env.test

@@ -0,0 +1,6 @@
+# 测试环境
+NODE_ENV = "test"
+
+
+# 测试环境接口地址
+VITE_APP_BASE_API = '/api'

+ 20 - 0
.eslintignore

@@ -0,0 +1,20 @@
+
+*.sh
+node_modules
+*.css
+*.jpg
+*.jpeg
+*.png
+*.gif
+*.md
+*.woff
+*.ttf
+.vscode
+.idea
+dist
+/public
+/docs
+.husky
+.local
+/bin
+Dockerfile

+ 79 - 0
.eslintrc.js

@@ -0,0 +1,79 @@
+module.exports = {
+  env: {
+    browser: true,
+    es2021: true,
+    node: true,
+  },
+  extends: [
+    'plugin:vue/vue3-recommended',
+    'eslint:recommended',
+    'plugin:vue/vue3-essential',
+    'plugin:@typescript-eslint/recommended',
+    'plugin:prettier/recommended',
+  ],
+  parser: 'vue-eslint-parser',
+  parserOptions: {
+    ecmaVersion: 'latest',
+    parser: '@typescript-eslint/parser',
+    sourceType: 'module',
+    ecmaFeatures: {
+      jsx: true,
+    },
+  },
+  plugins: ['vue', '@typescript-eslint'],
+  globals: {
+    defineProps: 'readonly',
+    defineEmits: 'readonly',
+  },
+  rules: {
+    'no-console': 'off', // 禁止调用console对象的方法。
+    '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
+    'no-use-before-define': 'off',
+    '@typescript-eslint/no-use-before-define': 'off',
+    '@typescript-eslint/ban-ts-comment': 'off',
+    '@typescript-eslint/no-empty-function': ['off'], // 关闭空函数警告
+    '@typescript-eslint/no-inferrable-types': 'off', // 可以轻松推断的显式类型可能会增加不必要的冗长
+    '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间
+    '@typescript-eslint/ban-types': 'off', // 禁止使用特定类型
+    'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
+    'vue/no-v-html': 'off', // 禁止使用 v-html
+    'no-undef': 'off',
+    'no-redeclare': 'off',
+    'no-self-assign': 'off',
+    'no-sparse-arrays': 'off',
+    'vue/valid-v-for': 'off',
+    'vue/no-unused-vars': 'off',
+    'vue/require-v-for-key': 'off',
+    'no-useless-escape': 'off',
+    'vue/require-explicit-emits': 'off',
+    'no-case-declarations': 'off', // 不允许在 case 子句中使用词法声明
+    //禁止非空断言非空断言是在变量后面添加一个感叹号(!),表示该变量一定存在,不会为 null 或 undefined
+    '@typescript-eslint/no-non-null-assertion': 'off',
+    'vue/require-prop-types': 'off',
+    '@typescript-eslint/no-this-alias': 'off',
+    'no-async-promise-executor': 'off',
+    'vue/no-template-shadow': 'off',
+    'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值
+    '@typescript-eslint/no-unused-vars': [
+      // // 禁止定义未使用的变量
+      'off',
+      {
+        argsIgnorePattern: '^_',
+        varsIgnorePattern: '^_',
+      },
+    ],
+    // Prettier 格式规则
+    'prettier/prettier': [
+      'error',
+      {
+        tabWidth: 2,
+        useTabs: false,
+        singleQuote: true,
+        semi: false,
+        trailingComma: 'es5',
+        bracketSpacing: true,
+        endOfLine: 'auto',
+      },
+    ],
+  },
+}

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist-ssr
+dist
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+package-lock.json

+ 9 - 0
.prettierignore

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

+ 20 - 0
.prettierrc.json

@@ -0,0 +1,20 @@
+{
+  "printWidth": 100,
+  "tabWidth": 2,
+  "useTabs": false,
+  "semi": false,
+  "singleQuote": true,
+  "trailingComma": "es5",
+  "bracketSpacing": true,
+  "arrowParens": "always",
+  "endOfLine": "auto",
+  "vueIndentScriptAndStyle": true,
+  "overrides": [
+    {
+      "files": "*.vue",
+      "options": {
+        "vueIndentScriptAndStyle": true
+      }
+    }
+  ]
+}

+ 121 - 0
index.html

@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Vue admin perfect</title>
+  </head>
+  <body>
+    <div id="app">
+      <style>
+        .first-loading-wrp {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+          height: 90vh;
+          min-height: 90vh;
+        }
+        .first-loading-wrp > h1 {
+          font-size: 30px;
+          font-weight: bolder;
+        }
+        .first-loading-wrp .loading-wrp {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          padding: 98px;
+        }
+        .dot {
+          position: relative;
+          box-sizing: border-box;
+          display: inline-block;
+          width: 64px;
+          height: 64px;
+          font-size: 64px;
+          transform: rotate(45deg);
+          animation: antRotate 1.2s infinite linear;
+        }
+
+        .dot i {
+          position: absolute;
+          display: block;
+          width: 28px;
+          height: 28px;
+          background-color: #1890ff;
+          border-radius: 100%;
+          opacity: 0.3;
+          transform: scale(0.75);
+          transform-origin: 50% 50%;
+          animation: antSpinMove 1s infinite linear alternate;
+        }
+
+        .dot i:nth-child(1) {
+          top: 0;
+          left: 0;
+        }
+
+        .dot i:nth-child(2) {
+          top: 0;
+          right: 0;
+          -webkit-animation-delay: 0.4s;
+          animation-delay: 0.4s;
+        }
+
+        .dot i:nth-child(3) {
+          right: 0;
+          bottom: 0;
+          -webkit-animation-delay: 0.8s;
+          animation-delay: 0.8s;
+        }
+
+        .dot i:nth-child(4) {
+          bottom: 0;
+          left: 0;
+          -webkit-animation-delay: 1.2s;
+          animation-delay: 1.2s;
+        }
+        @keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+
+        @-webkit-keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+
+        @keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+
+        @-webkit-keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+      </style>
+      <div id="vue-admin-perfect">
+        <div class="first-loading-wrp">
+          <div class="loading-wrp">
+            <span class="dot dot-spin">
+              <i></i>
+              <i></i>
+              <i></i>
+              <i></i>
+            </span>
+          </div>
+          <h1>vue-admin-perfect</h1>
+        </div>
+      </div>
+    </div>
+    <script type="module" src="/src/main.ts"></script>
+  </body>
+</html>

+ 104 - 0
package.json

@@ -0,0 +1,104 @@
+{
+  "name": "vue-admin-perfect",
+  "private": true,
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build:dev": "vite build --mode development",
+    "build:test": "vite build --mode test",
+    "build:prod": "vite build --mode production",
+    "commit": "git add -A && czg && git push",
+    "build": "vite build",
+    "preview": "vite preview",
+    "build:ts": "vue-tsc --noEmit --skipLibCheck && vite build",
+    "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx",
+    "lint:fix": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix",
+    "lint:prettier": "prettier --write  \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
+    "prepare": "husky install"
+  },
+  "dependencies": {
+    "@better-scroll/core": "^2.4.2",
+    "@vueuse/core": "^9.1.1",
+    "@wangeditor/editor": "^5.1.14",
+    "@wangeditor/editor-for-vue": "^5.1.12",
+    "axios": "^0.27.2",
+    "clipboard": "^2.0.10",
+    "codemirror": "^5.65.9",
+    "core-js": "^3.6.5",
+    "dayjs": "^1.11.4",
+    "echarts": "^5.3.1",
+    "element-plus": "^2.2.28",
+    "exceljs": "^4.3.0",
+    "file-saver": "^2.0.5",
+    "fuse.js": "^6.6.2",
+    "jszip": "^3.9.1",
+    "mavon-editor": "^2.10.4",
+    "md-editor-v3": "^1.11.3",
+    "nprogress": "^0.2.0",
+    "path-browserify": "^1.0.1",
+    "path-to-regexp": "^6.2.0",
+    "pinia": "^2.0.21",
+    "pinia-plugin-persistedstate": "^2.1.1",
+    "print-js": "^1.6.0",
+    "raf": "^3.4.1",
+    "resize-observer-polyfill": "^1.5.1",
+    "sass": "^1.54.0",
+    "splitpanes": "^3.1.1",
+    "svg-sprite-loader": "^6.0.11",
+    "vue": "^3.2.39",
+    "vue-cropper": "^1.0.3",
+    "vue-cropperjs": "^5.0.0",
+    "vue-fuse": "^4.1.1",
+    "vue-mugen-scroll": "^0.2.6",
+    "vue-qr": "^4.0.6",
+    "vue-router": "^4.1.6",
+    "vue-splitpane": "^1.0.6",
+    "vue3-text-clamp": "^0.1.1",
+    "vuedraggable": "^4.1.0",
+    "vuex": "^4.0.0-0",
+    "xlsx": "^0.18.5"
+  },
+  "devDependencies": {
+    "@element-plus/icons-vue": "^2.3.1",
+    "@typescript-eslint/eslint-plugin": "^5.32.0",
+    "@typescript-eslint/parser": "^5.32.0",
+    "@vitejs/plugin-vue": "^3.0.0",
+    "@vue/eslint-config-typescript": "^12.0.0",
+    "commitizen": "^4.2.5",
+    "consola": "^2.15.3",
+    "cz-git": "^1.3.12",
+    "czg": "^1.3.12",
+    "dart-sass": "^1.25.0",
+    "eslint": "^8.21.0",
+    "eslint-config-prettier": "^8.5.0",
+    "eslint-plugin-prettier": "^4.2.1",
+    "eslint-plugin-vue": "^9.3.0",
+    "fast-glob": "^3.2.11",
+    "husky": "^7.0.4",
+    "lint-staged": "^12.3.4",
+    "mrm": "^3.0.10",
+    "prettier": "^2.7.1",
+    "typescript": "^4.6.4",
+    "unplugin-auto-import": "^0.10.3",
+    "unplugin-vue-components": "^0.21.2",
+    "unplugin-vue-define-options": "^0.7.3",
+    "vite": "^3.0.0",
+    "vite-plugin-compression": "^0.5.1",
+    "vite-plugin-style-import": "^2.0.0",
+    "vite-plugin-svg-icons": "^2.0.1",
+    "vite-plugin-vue-setup-extend": "^0.4.0",
+    "vue-tsc": "^0.38.4"
+  },
+  "config": {
+    "commitizen": {
+      "path": "node_modules/cz-git"
+    }
+  },
+  "lint-staged": {
+    "src/**/*.{vue,js,ts,jsx,tsx}": [
+      "npm run lint:prettier",
+      "npm run lint:fix",
+      "git add ."
+    ]
+  }
+}

BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="/favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

BIN
public/static/screen/bg.jpg


BIN
public/static/screen/bg.png


BIN
public/static/screen/footer2.png


BIN
public/static/screen/header-bg.png


BIN
public/static/screen/server-bg.png


+ 7 - 0
shims-vue.d.ts

@@ -0,0 +1,7 @@
+/// <reference types="vite/client" />
+
+declare module '*.vue' {
+  import type { DefineComponent } from 'vue'
+  const component: DefineComponent<{}, {}, any>
+  export default component
+}

+ 37 - 0
src/App.vue

@@ -0,0 +1,37 @@
+<template>
+  <el-config-provider :size="globalComSize" :locale="zhCn">
+    <router-view></router-view>
+  </el-config-provider>
+</template>
+
+<script lang="ts" setup>
+  import { computed } from 'vue'
+  import { useSettingStore } from '@/store/modules/setting'
+  // 配置element中文
+  import zhCn from 'element-plus/es/locale/lang/zh-cn'
+
+  const SettingStore = useSettingStore()
+  // 配置全局组件大小
+  const globalComSize = computed((): string => SettingStore.themeConfig.globalComSize)
+</script>
+
+<style lang="scss">
+  #app {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    font-family: Avenir, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    color: #2c3e50;
+  }
+  .el-pager li:focus {
+    border: none;
+  }
+  .el-dropdown:focus {
+    border: none;
+  }
+  .svg-icon:focus {
+    border: none;
+  }
+</style>

+ 44 - 0
src/api/errorCodeType.ts

@@ -0,0 +1,44 @@
+export const errorCodeType = function (code: string): string {
+  let errMessage = '未知错误'
+  switch (code) {
+    case 400:
+      errMessage = '请求失败!请您稍后重试'
+      break
+    case 401:
+      errMessage = '未授权,请重新登录'
+      break
+    case 403:
+      errMessage = '当前账号无权限访问!'
+      break
+    case 404:
+      errMessage = '你所访问的资源不存在!'
+      break
+    case 405:
+      errMessage = '请求方式错误!请您稍后重试'
+      break
+    case 408:
+      errMessage = '请求超时!请您稍后重试'
+      break
+    case 500:
+      errMessage = '服务器端出错'
+      break
+    case 501:
+      errMessage = '网络未实现'
+      break
+    case 502:
+      errMessage = '网络错误'
+      break
+    case 503:
+      errMessage = '服务不可用'
+      break
+    case 504:
+      errMessage = '网络超时'
+      break
+    case 505:
+      errMessage = 'http版本不支持该请求'
+      break
+    default:
+      errMessage = `其他连接错误 --${code}`
+  }
+  return errMessage
+}

+ 62 - 0
src/api/request.ts

@@ -0,0 +1,62 @@
+import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
+import { ElMessage } from 'element-plus'
+import { useUserStore } from '@/store/modules/user'
+// 创建axios实例 进行基本参数配置
+const service = axios.create({
+  // 默认请求地址,根据环境的不同可在.env 文件中进行修改
+  baseURL: import.meta.env.VITE_APP_BASE_API,
+  // 设置接口访问超时时间
+  timeout: 3000000, // request timeout,
+  // 跨域时候允许携带凭证
+  withCredentials: true,
+})
+
+//  request interceptor 接口请求拦截
+service.interceptors.request.use(
+  (config: AxiosRequestConfig) => {
+    /**
+     * 用户登录之后获取服务端返回的token,后面每次请求都在请求头中带上token进行JWT校验
+     * token 存储在本地储存中(storage)、vuex、pinia
+     */
+    const userStore = useUserStore()
+    const token: string = userStore.token
+    // 自定义请求头
+    if (token) {
+      config.headers['Authorization'] = token
+    }
+    return config
+  },
+  (error: AxiosError) => {
+    // 请求错误,这里可以用全局提示框进行提示
+    return Promise.reject(error)
+  }
+)
+
+//  response interceptor 接口响应拦截
+service.interceptors.response.use(
+  (response: AxiosResponse) => {
+    // 直接返回res,当然你也可以只返回res.data
+    // 系统如果有自定义code也可以在这里处理
+    return response
+  },
+  (error: AxiosError) => {
+    return Promise.reject(error)
+  }
+)
+
+// /**
+//  * @description 显示错误消息
+//  * opt 传入参数
+//  * err 错误信息
+//  * type 消息类型
+//  * duration 消息持续时间
+//  */
+// function showErrMessage(opt, err, type: any = 'error', duration = 5000) {
+//   ElMessage({
+//     message: err.msg,
+//     type: type,
+//     duration: duration,
+//   });
+// }
+
+export default service

+ 9 - 0
src/api/user.ts

@@ -0,0 +1,9 @@
+import request from './request'
+
+export function login(data) {
+  return request({
+    url: '/vue-element-perfect/user/login',
+    method: 'post',
+    data,
+  })
+}

BIN
src/assets/403_images/403.png


BIN
src/assets/403_images/403_cloud.png


BIN
src/assets/404_images/404.png


BIN
src/assets/404_images/404_bg.png


BIN
src/assets/404_images/404_cloud.png


+ 114 - 0
src/assets/iconfont/iconfont.css

@@ -0,0 +1,114 @@
+@font-face {
+  font-family: 'iconfont'; /* Project id 3641732 */
+  src: url('./iconfont.woff2?t=1663216428515') format('woff2'),
+    url('./iconfont.woff?t=1663216428515') format('woff'),
+    url('./iconfont.ttf?t=1663216428515') format('truetype');
+}
+
+.iconfont {
+  font-family: 'iconfont' !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-yin:before {
+  content: '\e6a0';
+}
+
+.icon-dabaoyu:before {
+  content: '\e6a7';
+}
+
+.icon-shuaxin1:before {
+  content: '\e627';
+}
+
+.icon-shuaxin:before {
+  content: '\e629';
+}
+
+.icon-duoyun-2-copy:before {
+  content: '\e68d';
+}
+
+.icon-duoyun-1:before {
+  content: '\e679';
+}
+
+.icon-daxue:before {
+  content: '\e67a';
+}
+
+.icon-dayu:before {
+  content: '\e67b';
+}
+
+.icon-feng:before {
+  content: '\e67c';
+}
+
+.icon-duoyun-3:before {
+  content: '\e67d';
+}
+
+.icon-duoyun-2:before {
+  content: '\e67e';
+}
+
+.icon-leiyujiaojia:before {
+  content: '\e67f';
+}
+
+.icon-duoyun:before {
+  content: '\e680';
+}
+
+.icon-zhongyu:before {
+  content: '\e681';
+}
+
+.icon-wu:before {
+  content: '\e682';
+}
+
+.icon-xiaoyu:before {
+  content: '\e683';
+}
+
+.icon-xiaoxue:before {
+  content: '\e684';
+}
+
+.icon-shandian:before {
+  content: '\e685';
+}
+
+.icon-xue:before {
+  content: '\e686';
+}
+
+.icon-zhongxue:before {
+  content: '\e687';
+}
+
+.icon-yangchen:before {
+  content: '\e688';
+}
+
+.icon-yueliang:before {
+  content: '\e689';
+}
+
+.icon-yujiaxue:before {
+  content: '\e68a';
+}
+
+.icon-qing:before {
+  content: '\e68b';
+}
+
+.icon-mai:before {
+  content: '\e68c';
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
src/assets/iconfont/iconfont.js


+ 184 - 0
src/assets/iconfont/iconfont.json

@@ -0,0 +1,184 @@
+{
+  "id": "3641732",
+  "name": "weather",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "28557556",
+      "name": "阴",
+      "font_class": "yin",
+      "unicode": "e6a0",
+      "unicode_decimal": 59040
+    },
+    {
+      "icon_id": "28557770",
+      "name": "大暴雨",
+      "font_class": "dabaoyu",
+      "unicode": "e6a7",
+      "unicode_decimal": 59047
+    },
+    {
+      "icon_id": "7724796",
+      "name": "刷新",
+      "font_class": "shuaxin1",
+      "unicode": "e627",
+      "unicode_decimal": 58919
+    },
+    {
+      "icon_id": "6999224",
+      "name": "刷新",
+      "font_class": "shuaxin",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "31772217",
+      "name": "多云-2-copy",
+      "font_class": "duoyun-2-copy",
+      "unicode": "e68d",
+      "unicode_decimal": 59021
+    },
+    {
+      "icon_id": "29265274",
+      "name": "多云-1",
+      "font_class": "duoyun-1",
+      "unicode": "e679",
+      "unicode_decimal": 59001
+    },
+    {
+      "icon_id": "29265275",
+      "name": "大雪",
+      "font_class": "daxue",
+      "unicode": "e67a",
+      "unicode_decimal": 59002
+    },
+    {
+      "icon_id": "29265276",
+      "name": "大雨",
+      "font_class": "dayu",
+      "unicode": "e67b",
+      "unicode_decimal": 59003
+    },
+    {
+      "icon_id": "29265277",
+      "name": "风",
+      "font_class": "feng",
+      "unicode": "e67c",
+      "unicode_decimal": 59004
+    },
+    {
+      "icon_id": "29265278",
+      "name": "多云-3",
+      "font_class": "duoyun-3",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "29265279",
+      "name": "多云-2",
+      "font_class": "duoyun-2",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "29265280",
+      "name": "雷雨交加",
+      "font_class": "leiyujiaojia",
+      "unicode": "e67f",
+      "unicode_decimal": 59007
+    },
+    {
+      "icon_id": "29265281",
+      "name": "多云",
+      "font_class": "duoyun",
+      "unicode": "e680",
+      "unicode_decimal": 59008
+    },
+    {
+      "icon_id": "29265282",
+      "name": "中雨",
+      "font_class": "zhongyu",
+      "unicode": "e681",
+      "unicode_decimal": 59009
+    },
+    {
+      "icon_id": "29265283",
+      "name": "雾",
+      "font_class": "wu",
+      "unicode": "e682",
+      "unicode_decimal": 59010
+    },
+    {
+      "icon_id": "29265284",
+      "name": "小雨",
+      "font_class": "xiaoyu",
+      "unicode": "e683",
+      "unicode_decimal": 59011
+    },
+    {
+      "icon_id": "29265285",
+      "name": "小雪",
+      "font_class": "xiaoxue",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "29265286",
+      "name": "闪电",
+      "font_class": "shandian",
+      "unicode": "e685",
+      "unicode_decimal": 59013
+    },
+    {
+      "icon_id": "29265287",
+      "name": "雪",
+      "font_class": "xue",
+      "unicode": "e686",
+      "unicode_decimal": 59014
+    },
+    {
+      "icon_id": "29265288",
+      "name": "中雪",
+      "font_class": "zhongxue",
+      "unicode": "e687",
+      "unicode_decimal": 59015
+    },
+    {
+      "icon_id": "29265289",
+      "name": "扬尘",
+      "font_class": "yangchen",
+      "unicode": "e688",
+      "unicode_decimal": 59016
+    },
+    {
+      "icon_id": "29265290",
+      "name": "月亮",
+      "font_class": "yueliang",
+      "unicode": "e689",
+      "unicode_decimal": 59017
+    },
+    {
+      "icon_id": "29265291",
+      "name": "雨夹雪",
+      "font_class": "yujiaxue",
+      "unicode": "e68a",
+      "unicode_decimal": 59018
+    },
+    {
+      "icon_id": "29265292",
+      "name": "晴",
+      "font_class": "qing",
+      "unicode": "e68b",
+      "unicode_decimal": 59019
+    },
+    {
+      "icon_id": "29265293",
+      "name": "霾",
+      "font_class": "mai",
+      "unicode": "e68c",
+      "unicode_decimal": 59020
+    }
+  ]
+}

BIN
src/assets/iconfont/iconfont.ttf


BIN
src/assets/iconfont/iconfont.woff


BIN
src/assets/iconfont/iconfont.woff2


BIN
src/assets/image/allow.png


BIN
src/assets/image/avatar.png


BIN
src/assets/image/berserk.jpg


BIN
src/assets/image/center-inner1.png


BIN
src/assets/image/charts/1-1-bg.png


BIN
src/assets/image/circle-bg.png


BIN
src/assets/image/cro-avatar.jpg


BIN
src/assets/image/login/qrcode-icon.png


BIN
src/assets/image/login/side-logo.png


BIN
src/assets/image/logo.png


BIN
src/assets/image/we.png


+ 85 - 0
src/components/AvatarCropper/index.vue

@@ -0,0 +1,85 @@
+<template>
+  <vue-cropper
+    ref="cropper"
+    :img="avatarUrl"
+    :output-size="defaultOptions.outputSize"
+    :output-type="defaultOptions.outputType"
+    :info="defaultOptions.info"
+    :full="defaultOptions.full"
+    :fixed="defaultOptions.fixed"
+    :auto-crop-width="defaultOptions.autoCropWidth"
+    :auto-crop-height="defaultOptions.autoCropHeight"
+    :fixed-box="defaultOptions.fixedBox"
+    :auto-crop="defaultOptions.autoCrop"
+    :center-box="defaultOptions.centerBox"
+    @real-time="realTime"
+  />
+</template>
+
+<script lang="ts" setup>
+  import { defineExpose, reactive, ref } from 'vue'
+  import { VueCropper } from 'vue-cropper'
+  import 'vue-cropper/dist/index.css'
+
+  const emit = defineEmits(['change'])
+  let props = defineProps({
+    avatarUrl: {
+      type: String,
+    },
+    options: {
+      type: Object,
+      default: () => {},
+    },
+  })
+
+  let cropper = ref()
+
+  const defaultOptions = reactive({
+    outputSize: 0.8, // 裁剪生成图片的质量
+    outputType: 'png', // 生成图片的格式
+    info: true, // 裁剪框的大小信息
+    fixed: true, // 是否开启截图框宽高固定比例
+    autoCrop: true, // 是否默认生成截图框
+    anMoveBox: true, // 截图框能否拖动
+    original: false, // 上传图片按照原始比例渲染
+    autoCropWidth: 300, // 默认生成截图框宽度
+    autoCropHeight: 300, // 默认生成截图框高度
+    // 只有自动截图开启 宽度高度才生效
+    centerBox: false, // 截图框是否被限制在图片里面
+    high: true, // 是否按照dpr设备比例图片
+    fixedBox: false, // 固定截图框大小 不允许改变
+    full: false, // 是否输出原图比例的截图
+    ...props.options,
+  })
+
+  const getBase64 = () => {
+    return new Promise((resolve) => {
+      cropper.value.getCropData((data) => {
+        resolve(data)
+      })
+    })
+  }
+
+  const rotateLeft = () => {
+    cropper.value.rotateLeft()
+  }
+  const rotateRight = () => {
+    cropper.value.rotateRight()
+  }
+
+  const zoom = (percent) => {
+    cropper.value.changeScale(percent)
+  }
+
+  // 实时预览图片
+  const realTime = (data) => {
+    emit('change', data)
+  }
+
+  defineExpose({
+    getBase64,
+    rotateLeft,
+    rotateRight,
+    zoom,
+  })
+</script>

+ 120 - 0
src/components/CodeMirror/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <textarea ref="codeEditor" placeholder="请输入..."></textarea>
+</template>
+
+<script>
+  import { defineComponent, onBeforeUnmount, onMounted, ref, toRefs, watch } from 'vue'
+  // codemirror基础资源引入
+  import _CodeMirror from 'codemirror'
+  import 'codemirror/lib/codemirror.css'
+  // language
+  import 'codemirror/mode/javascript/javascript.js'
+
+  // theme css
+  import 'codemirror/theme/monokai.css'
+  // 折叠资源引入:开始
+  import 'codemirror/addon/fold/foldgutter.css'
+  import 'codemirror/addon/fold/foldcode.js'
+  import 'codemirror/addon/fold/brace-fold.js'
+  import 'codemirror/addon/fold/comment-fold.js'
+  import 'codemirror/addon/fold/indent-fold.js'
+  import 'codemirror/addon/fold/foldgutter.js'
+  // 折叠资源引入:结束
+
+  // 搜索资源引入:开始
+  import 'codemirror/addon/scroll/annotatescrollbar.js'
+  import 'codemirror/addon/search/matchesonscrollbar.js'
+  import 'codemirror/addon/search/match-highlighter.js'
+  import 'codemirror/addon/search/jump-to-line.js'
+
+  import 'codemirror/addon/dialog/dialog.js'
+  import 'codemirror/addon/dialog/dialog.css'
+  import 'codemirror/addon/search/searchcursor.js'
+  import 'codemirror/addon/search/search.js'
+  // 搜索资源引入:结束
+
+  // 启用placeholder
+  import 'codemirror/addon/display/placeholder.js'
+
+  import 'codemirror/addon/selection/active-line.js' //光标行背景高亮,配置里面也需要styleActiveLine设置为true
+
+  const CodeMirror = window.CodeMirror || _CodeMirror
+
+  export default defineComponent({
+    props: {
+      modelValue: String,
+      defaultValue: String,
+      readOnly: {
+        type: Boolean,
+        default: false,
+      },
+    },
+    setup(props, context) {
+      const { modelValue, defaultValue, readOnly } = toRefs(props)
+      const codeEditor = ref()
+      let editor
+      watch(modelValue, () => {
+        if (null != editor && modelValue.value && modelValue.value !== editor.getValue()) {
+          // 触发v-model的双向绑定
+          editor.setValue(modelValue.value)
+        }
+      })
+      watch(readOnly, () => {
+        if (null != editor) {
+          editor.setOption('readOnly', readOnly.value)
+        }
+      })
+      onMounted(() => {
+        editor = CodeMirror.fromTextArea(codeEditor.value, {
+          value: modelValue.value,
+          // mime: "text/javascript",
+          mode: 'application/json',
+          indentWithTabs: false, // 在缩进时,是否需要把 n*tab宽度个空格替换成n个tab字符,默认为false
+          smartIndent: true, // 自动缩进,设置是否根据上下文自动缩进(和上一行相同的缩进量)。默认为true
+          lineNumbers: true, // 是否在编辑器左侧显示行号
+          matchBrackets: true, // 括号匹配
+          readOnly: readOnly.value,
+          // 启用代码折叠相关功能:开始
+          foldGutter: true,
+          lineWrapping: true, //是否自动换行
+          gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
+          // 启用代码折叠相关功能:结束
+          styleActiveLine: false, // 光标行高亮
+        })
+        // 监听编辑器的change事件
+        editor.on('change', () => {
+          // 触发v-model的双向绑定
+          context.emit('update:modelValue', editor.getValue())
+        })
+        if (defaultValue.value) {
+          editor.setValue(defaultValue.value)
+        }
+      })
+      onBeforeUnmount(() => {
+        if (null !== editor) {
+          editor.toTextArea()
+          editor = null
+        }
+      })
+      return { codeEditor }
+    },
+  })
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style lang="scss">
+  .CodeMirror-wrap {
+    height: 100%;
+  }
+
+  .CodeMirror-gutters {
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 3;
+    min-height: 100%;
+    white-space: nowrap;
+    background-color: transparent;
+    border-right: 1px solid #ddd;
+  }
+</style>

+ 5 - 0
src/components/CountTo/index.js

@@ -0,0 +1,5 @@
+import CountTo from './index.vue'
+export default CountTo
+if (typeof window !== 'undefined' && window.Vue) {
+  window.Vue.component('count-to', CountTo)
+}

+ 202 - 0
src/components/CountTo/index.vue

@@ -0,0 +1,202 @@
+<template>
+  <span>
+    {{ displayValue }}
+  </span>
+</template>
+<script lang="ts">
+  import { requestAnimationFrame, cancelAnimationFrame } from './requestAnimationFrame.js'
+  export default {
+    props: {
+      startVal: {
+        type: Number,
+        required: false,
+        default: 0,
+      },
+      endVal: {
+        type: Number,
+        required: false,
+        default: 2017,
+      },
+      duration: {
+        type: Number,
+        required: false,
+        default: 3000,
+      },
+      autoplay: {
+        type: Boolean,
+        required: false,
+        default: true,
+      },
+      decimals: {
+        type: Number,
+        required: false,
+        default: 0,
+        validator(value) {
+          return value >= 0
+        },
+      },
+      decimal: {
+        type: String,
+        required: false,
+        default: '.',
+      },
+      separator: {
+        type: String,
+        required: false,
+        default: ',',
+      },
+      prefix: {
+        type: String,
+        required: false,
+        default: '',
+      },
+      suffix: {
+        type: String,
+        required: false,
+        default: '',
+      },
+      useEasing: {
+        type: Boolean,
+        required: false,
+        default: true,
+      },
+      easingFn: {
+        type: Function,
+        default(t, b, c, d) {
+          return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b
+        },
+      },
+    },
+    data() {
+      return {
+        localStartVal: this.startVal,
+        displayValue: this.formatNumber(this.startVal),
+        printVal: null,
+        paused: false,
+        localDuration: this.duration,
+        startTime: null,
+        timestamp: null,
+        remaining: null,
+        rAF: null,
+      }
+    },
+    computed: {
+      countDown() {
+        return this.startVal > this.endVal
+      },
+    },
+    watch: {
+      startVal() {
+        if (this.autoplay) {
+          this.start()
+        }
+      },
+      endVal() {
+        if (this.autoplay) {
+          this.start()
+        }
+      },
+    },
+    mounted() {
+      if (this.autoplay) {
+        this.start()
+      }
+      this.$emit('mountedCallback')
+    },
+    unmounted() {
+      cancelAnimationFrame(this.rAF)
+    },
+    methods: {
+      start() {
+        this.localStartVal = this.startVal
+        this.startTime = null
+        this.localDuration = this.duration
+        this.paused = false
+        this.rAF = requestAnimationFrame(this.count)
+      },
+      pauseResume() {
+        if (this.paused) {
+          this.resume()
+          this.paused = false
+        } else {
+          this.pause()
+          this.paused = true
+        }
+      },
+      pause() {
+        cancelAnimationFrame(this.rAF)
+      },
+      resume() {
+        this.startTime = null
+        this.localDuration = +this.remaining
+        this.localStartVal = +this.printVal
+        requestAnimationFrame(this.count)
+      },
+      reset() {
+        this.startTime = null
+        cancelAnimationFrame(this.rAF)
+        this.displayValue = this.formatNumber(this.startVal)
+      },
+      count(timestamp) {
+        if (!this.startTime) this.startTime = timestamp
+        this.timestamp = timestamp
+        const progress = timestamp - this.startTime
+        this.remaining = this.localDuration - progress
+
+        if (this.useEasing) {
+          if (this.countDown) {
+            this.printVal =
+              this.localStartVal -
+              this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)
+          } else {
+            this.printVal = this.easingFn(
+              progress,
+              this.localStartVal,
+              this.endVal - this.localStartVal,
+              this.localDuration
+            )
+          }
+        } else {
+          if (this.countDown) {
+            this.printVal =
+              this.localStartVal -
+              (this.localStartVal - this.endVal) * (progress / this.localDuration)
+          } else {
+            this.printVal =
+              this.localStartVal +
+              (this.endVal - this.localStartVal) * (progress / this.localDuration)
+          }
+        }
+        if (this.countDown) {
+          this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal
+        } else {
+          this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal
+        }
+
+        this.displayValue = this.formatNumber(this.printVal)
+        if (progress < this.localDuration) {
+          this.rAF = requestAnimationFrame(this.count)
+        } else {
+          this.$emit('callback')
+        }
+      },
+      isNumber(val) {
+        return !isNaN(parseFloat(val))
+      },
+      formatNumber(num) {
+        num = num.toFixed(this.decimals)
+        num += ''
+        const x = num.split('.')
+        let x1 = x[0]
+        const x2 = x.length > 1 ? this.decimal + x[1] : ''
+        const rgx = /(\d+)(\d{3})/
+        if (this.separator && !this.isNumber(this.separator)) {
+          while (rgx.test(x1)) {
+            x1 = x1.replace(rgx, '$1' + this.separator + '$2')
+          }
+        }
+        return this.prefix + x1 + x2 + this.suffix
+      },
+    },
+  }
+</script>

+ 51 - 0
src/components/CountTo/requestAnimationFrame.js

@@ -0,0 +1,51 @@
+let lastTime = 0
+const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀
+
+let requestAnimationFrame
+let cancelAnimationFrame
+
+const isServer = typeof window === 'undefined'
+if (isServer) {
+  requestAnimationFrame = function () {
+    return
+  }
+  cancelAnimationFrame = function () {
+    return
+  }
+} else {
+  requestAnimationFrame = window.requestAnimationFrame
+  cancelAnimationFrame = window.cancelAnimationFrame
+  let prefix
+  // 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
+  for (let i = 0; i < prefixes.length; i++) {
+    if (requestAnimationFrame && cancelAnimationFrame) {
+      break
+    }
+    prefix = prefixes[i]
+    requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']
+    cancelAnimationFrame =
+      cancelAnimationFrame ||
+      window[prefix + 'CancelAnimationFrame'] ||
+      window[prefix + 'CancelRequestAnimationFrame']
+  }
+
+  // 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
+  if (!requestAnimationFrame || !cancelAnimationFrame) {
+    requestAnimationFrame = function (callback) {
+      const currTime = new Date().getTime()
+      // 为了使setTimteout的尽可能的接近每秒60帧的效果
+      const timeToCall = Math.max(0, 16 - (currTime - lastTime))
+      const id = window.setTimeout(() => {
+        callback(currTime + timeToCall)
+      }, timeToCall)
+      lastTime = currTime + timeToCall
+      return id
+    }
+
+    cancelAnimationFrame = function (id) {
+      window.clearTimeout(id)
+    }
+  }
+}
+
+export { requestAnimationFrame, cancelAnimationFrame }

+ 269 - 0
src/components/DataScreen/Multiline/index.vue

@@ -0,0 +1,269 @@
+<template>
+  <div ref="chartsRef" class="echarts" />
+</template>
+<script lang="ts" setup>
+  import * as echarts from 'echarts'
+  import { EChartsType } from 'echarts/core'
+  import { onMounted, ref } from 'vue'
+  const chartsRef = ref<HTMLElement | null>()
+
+  let colorList = ['#46ea91', '#2ba0ff', '#ed593b', '#7357ff', '#f2d750']
+  const options = {
+    legend: {
+      icon: 'circle',
+      top: '5%',
+      right: '5%',
+      itemWidth: 6,
+      itemGap: 5,
+      textStyle: {
+        color: '#fff',
+        padding: [3, 0, 0, 0],
+      },
+    },
+    tooltip: {
+      trigger: 'axis',
+    },
+    grid: {
+      top: '14%',
+      left: '3%',
+      right: '4%',
+      bottom: '10%',
+      containLabel: true,
+    },
+    xAxis: [
+      {
+        type: 'category',
+        data: ['1', '2', '3', '4', '5', '6', '7', '8'],
+        axisLine: {
+          lineStyle: {
+            color: '#33BBFF',
+          },
+        },
+        axisTick: {
+          show: false,
+        },
+        axisLabel: {
+          interval: 0,
+          textStyle: {
+            color: '#5FBBEB',
+          },
+          // 默认x轴字体大小
+          fontSize: 12,
+          // margin:文字到x轴的距离
+          margin: 10,
+        },
+        axisPointer: {
+          label: {
+            // padding: [11, 5, 7],
+            padding: [0, 0, 0, 0],
+            // 这里的margin和axisLabel的margin要一致!
+            margin: 10,
+            // 移入时的字体大小
+            fontSize: 12,
+            backgroundColor: 'rgba(0,0,0,0)',
+          },
+        },
+        boundaryGap: false,
+      },
+    ],
+    yAxis: [
+      {
+        name: '单位/件',
+        axisTick: {
+          show: false,
+        },
+        axisLine: {
+          show: true,
+          lineStyle: {
+            color: '#05D5FF',
+          },
+        },
+        axisLabel: {
+          textStyle: {
+            color: '#5FBBEB',
+          },
+        },
+        splitLine: {
+          show: false,
+        },
+      },
+    ],
+    series: [
+      {
+        name: '咨询',
+        type: 'line',
+        data: [100, 20, 30, 102, 15, 30, 20, 18],
+        symbolSize: 1,
+        symbol: 'circle',
+        smooth: true,
+        showSymbol: false,
+        lineStyle: {
+          width: 2,
+          color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+            {
+              offset: 0,
+              color: '#90ffc6',
+            },
+            {
+              offset: 1,
+              color: '#46ea91',
+            },
+          ]),
+          shadowColor: 'rgba(144, 255, 198, .3)',
+          shadowBlur: 5,
+          shadowOffsetY: 5,
+        },
+        itemStyle: {
+          normal: {
+            color: colorList[0],
+            borderColor: colorList[0],
+          },
+        },
+      },
+      {
+        name: '求助',
+        type: 'line',
+        data: [20, 12, 11, 14, 25, 16, 10, 20],
+        symbolSize: 1,
+        symbol: 'circle',
+        smooth: true,
+        showSymbol: false,
+        lineStyle: {
+          width: 2,
+          color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+            {
+              offset: 0,
+              color: '#67bcfc',
+            },
+            {
+              offset: 1,
+              color: '#2ba0ff',
+            },
+          ]),
+          shadowColor: 'rgba(105, 188, 252,.3)',
+          shadowBlur: 5,
+          shadowOffsetY: 5,
+        },
+        itemStyle: {
+          normal: {
+            color: colorList[1],
+            borderColor: colorList[1],
+          },
+        },
+      },
+      {
+        name: '无效',
+        type: 'line',
+        data: [150, 120, 170, 140, 100, 160, 110, 110],
+        symbolSize: 1,
+        symbol: 'circle',
+        smooth: true,
+        showSymbol: false,
+        lineStyle: {
+          width: 2,
+          color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+            {
+              offset: 0,
+              color: '#fc937e ',
+            },
+            {
+              offset: 1,
+              color: '#ed593b',
+            },
+          ]),
+          shadowColor: 'rgb(252, 147, 126,.3)',
+          shadowBlur: 2,
+          shadowOffsetY: 2,
+        },
+        itemStyle: {
+          normal: {
+            color: colorList[2],
+            borderColor: colorList[2],
+          },
+        },
+      },
+      {
+        name: '投诉举报',
+        type: 'line',
+        data: [200, 80, 100, 30, 60, 50, 110, 20],
+        symbolSize: 1,
+        symbol: 'circle',
+        smooth: true,
+        showSymbol: false,
+        lineStyle: {
+          width: 2,
+          color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+            {
+              offset: 0,
+              color: '#a390ff',
+            },
+            {
+              offset: 1,
+              color: '#7357ff',
+            },
+          ]),
+          shadowColor: 'rgba(115, 87, 255, .1)',
+          shadowBlur: 5,
+          shadowOffsetY: 5,
+        },
+        itemStyle: {
+          normal: {
+            color: colorList[3],
+            borderColor: colorList[3],
+          },
+        },
+      },
+      {
+        name: '建议',
+        type: 'line',
+        data: [20, 80, 150, 30, 60, 50, 50, 20],
+        symbolSize: 1,
+        symbol: 'circle',
+        smooth: true,
+        showSymbol: false,
+        lineStyle: {
+          width: 2,
+          color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+            {
+              offset: 0,
+              color: '#ffeb86',
+            },
+            {
+              offset: 1,
+              color: '#f2d750',
+            },
+          ]),
+          shadowColor: 'rgba(255, 235, 134, .5)',
+          shadowBlur: 5,
+          shadowOffsetY: 5,
+        },
+        itemStyle: {
+          normal: {
+            color: colorList[4],
+            borderColor: colorList[4],
+          },
+        },
+      },
+    ],
+  }
+
+  let chart: EChartsType
+  const initChart = () => {
+    const chart = echarts.init(chartsRef.value)
+    chart.setOption(options)
+    return chart
+  }
+  onMounted(() => {
+    chart = initChart()
+    window.addEventListener('resize', function () {
+      chart && chart.resize()
+    })
+  })
+</script>
+
+<style lang="scss" scoped>
+  .echarts {
+    width: 100%;
+    height: 100%;
+  }
+</style>

+ 117 - 0
src/components/DataScreen/barEcharts/index.vue

@@ -0,0 +1,117 @@
+<template>
+  <div ref="chartsRef" class="echarts" />
+</template>
+<script setup lang="ts">
+  import BarCharts from './components/bar.vue'
+  import * as echarts from 'echarts'
+  import { EChartsType } from 'echarts/core'
+  import { onMounted, ref, reactive } from 'vue'
+  const chartsRef = ref<HTMLElement | null>()
+  const data = [154, 230, 224, 218, 135, 147, 260]
+  const color = ['#fa796f', '#54c1fb', '#ca6cd4', '#59dcc1', '#09a4ea', '#e98f4d', '#ea8e49']
+  const dataOptions = []
+
+  data.forEach((item, index) => {
+    let obj = {
+      value: data[index],
+      itemStyle: {
+        color: color[index],
+      },
+    }
+    dataOptions.push(obj)
+  })
+
+  const options = {
+    color,
+    grid: {
+      top: '10%',
+      left: '3%',
+      right: '4%',
+      bottom: '10%',
+      containLabel: true,
+    },
+    tooltip: {
+      trigger: 'axis',
+      backgroundColor: 'rgba(0,0,0,0.7)',
+      borderWidth: 0,
+      borderColor: 'rgba(0,0,0,0.7)',
+      formatter: (name, val) => {
+        const tipHtml = `
+                     <div class="m-info" style=" opacity: 0.95;font-size: 12px; color: white;" >
+                         <div class="title" ></div>
+                         <div class="title" >完成占比${name[0].value}</div>
+                 </div>`
+        return tipHtml
+      },
+    },
+    yAxis: {
+      type: 'value',
+      // 设置坐标轴的 文字样式
+      axisLabel: {
+        color: '#bbdaff',
+        margin: 20, // 刻度标签与轴线之间的距离。
+      },
+      axisTick: {
+        // 取消坐标轴刻度线
+        show: false,
+      },
+      // 坐标轴轴线相关设置。
+      splitLine: {
+        lineStyle: {
+          color: '#2d5baf',
+        },
+      },
+    },
+    xAxis: {
+      type: 'category',
+      splitLine: {
+        show: false,
+      },
+      // 坐标轴轴线相关设置。
+      axisLine: {
+        lineStyle: {
+          color: '#2d5baf',
+        },
+      },
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+      axisLabel: {
+        // 设置坐标轴的 文字样式
+        color: '#bbdaff',
+        margin: 20, // 刻度标签与轴线之间的距离。
+      },
+      axisTick: {
+        // 取消坐标轴刻度线
+        show: false,
+      },
+    },
+    series: [
+      {
+        data: dataOptions,
+        type: 'bar',
+        barMaxWidth: 18,
+        markLine: {
+          silent: true,
+        },
+      },
+    ],
+  }
+
+  let chart: EChartsType
+  const initChart = () => {
+    const chart = echarts.init(chartsRef.value)
+    chart.setOption(options)
+    return chart
+  }
+  onMounted(() => {
+    chart = initChart()
+    window.addEventListener('resize', function () {
+      chart && chart.resize()
+    })
+  })
+</script>
+<style lang="scss" scoped>
+  .echarts {
+    height: 100%;
+    width: 100%;
+  }
+</style>

+ 111 - 0
src/components/DataScreen/lineEcharts/index.vue

@@ -0,0 +1,111 @@
+<template>
+  <div ref="chartsRef" class="echarts" />
+</template>
+<script setup lang="ts">
+  import BarCharts from './components/bar.vue'
+  import * as echarts from 'echarts'
+  import { EChartsType } from 'echarts/core'
+  import { onMounted, ref, reactive } from 'vue'
+  const chartsRef = ref<HTMLElement | null>()
+
+  const options = {
+    grid: {
+      top: '10%',
+      left: '3%',
+      right: '4%',
+      bottom: '10%',
+      containLabel: true,
+    },
+    tooltip: {
+      trigger: 'axis',
+      backgroundColor: 'rgba(0,0,0,0.7)',
+      borderWidth: 0,
+      borderColor: 'rgba(0,0,0,0.7)',
+      formatter: (name, val) => {
+        const tipHtml = `
+                     <div class="m-info" style=" opacity: 0.95;font-size: 12px; color: white;" >
+                         <div class="title" ></div>
+                         <div class="title" >完成占比${name[0].data}</div>
+                 </div>`
+        return tipHtml
+      },
+    },
+    yAxis: {
+      // 设置坐标轴的 文字样式
+      axisLabel: {
+        color: '#bbdaff',
+        margin: 20, // 刻度标签与轴线之间的距离。
+      },
+      // 坐标轴轴线相关设置。
+      splitLine: {
+        lineStyle: {
+          color: '#2d5baf',
+        },
+      },
+    },
+    xAxis: {
+      splitLine: {
+        show: false,
+      },
+      // 坐标轴轴线相关设置。
+      axisLine: {
+        lineStyle: {
+          color: '#2d5baf',
+        },
+      },
+      type: 'category',
+      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
+      axisLabel: {
+        // 设置坐标轴的 文字样式
+        color: '#bbdaff',
+        margin: 20, // 刻度标签与轴线之间的距离。
+      },
+      boundaryGap: false, // 设置坐标轴两边的留白 ,从刻度原点开始,
+      axisTick: {
+        // 取消坐标轴刻度线
+        show: false,
+      },
+    },
+    series: [
+      {
+        data: [154, 230, 224, 218, 135, 147, 260],
+        type: 'line',
+        // smooth:false,   //关键点,为true是不支持虚线的,实线就用true
+        symbolSize: 12, // 拐点圆的大小
+        symbol: 'circle',
+        markLine: {
+          silent: true,
+        },
+        itemStyle: {
+          normal: {
+            color: '#920783', // 设置 symbol的颜色
+            lineStyle: {
+              width: 3,
+              color: '#920783',
+              type: 'solid', // 'dotted'虚线 'solid'实线
+            },
+          },
+        },
+      },
+    ],
+  }
+
+  let chart: EChartsType
+  const initChart = () => {
+    const chart = echarts.init(chartsRef.value)
+    chart.setOption(options)
+    return chart
+  }
+  onMounted(() => {
+    chart = initChart()
+    window.addEventListener('resize', function () {
+      chart && chart.resize()
+    })
+  })
+</script>
+<style lang="scss" scoped>
+  .echarts {
+    height: 100%;
+    width: 100%;
+  }
+</style>

+ 38 - 0
src/components/DataScreen/migrationEcharts/data.js

@@ -0,0 +1,38 @@
+export const cityIconData = [
+  {
+    adcode: 650000,
+    name: '新疆维吾尔自治区',
+    value: [88.999903, 43.607078],
+  },
+  {
+    // adcode: 150000,
+    name: '内蒙古自治区',
+    value: [119.24787, 42.205741],
+  },
+  ,
+  {
+    // adcode: 150000,
+    name: '内蒙古自治区',
+    value: [110.627161, 41.16628],
+  },
+  {
+    // adcode: 540000,
+    name: '西藏自治区',
+    value: [89.483714, 30.251951],
+  },
+  {
+    // adcode: 630000,
+    name: '青海省',
+    value: [102.064693, 37.084008],
+  },
+  {
+    // adcode: 530000,
+    name: '云南省',
+    value: [102.187665, 25.083688],
+  },
+  {
+    // adcode: 610000,
+    name: '陕西省',
+    value: [109.20663, 35.018625],
+  },
+]

+ 332 - 0
src/components/DataScreen/migrationEcharts/index.vue

@@ -0,0 +1,332 @@
+<template>
+  <div :id="id" :class="className" :style="{ height: height, width: width }" />
+</template>
+<script lang="ts" setup>
+  import { geoJson } from './map.js'
+  import * as echarts from 'echarts'
+  import { EChartsType } from 'echarts/core'
+  import { onMounted, onUnmounted } from 'vue'
+  import { cityIconData } from './data.js'
+  import logo from '@/assets/image/logo.png'
+  const props = defineProps({
+    className: {
+      type: String,
+      default: 'chart',
+    },
+    config: {
+      type: Object,
+      default: () => {},
+    },
+    id: {
+      type: String,
+      default: 'chart',
+    },
+    width: {
+      type: String,
+      default: '200px',
+    },
+    height: {
+      type: String,
+      default: '200px',
+    },
+  })
+
+  var geoGpsMap = [109.1162, 34.2004]
+  var geoCoordMap = {
+    江苏: [118.8062, 31.9208],
+    内蒙古: [110.3467, 41.4899],
+    辽宁: [123.1238, 42.1216],
+    陕西: [109.1162, 34.2004],
+    甘肃: [103.5901, 36.3043],
+    青海: [101.4038, 36.8207],
+    新疆: [87.9236, 43.5883],
+
+    河南: [113.4668, 34.6234],
+    西藏: [91.091762, 30.037072],
+    浙江: [119.5313, 29.8773],
+    福建: [119.4543, 25.9222],
+    湖南: [113.0823, 28.2568],
+    四川: [113.0823, 28.2568],
+    云南: [102.9199, 25.4663],
+    广东: [113.12244, 23.009505],
+    海南: [110.3893, 19.8516],
+  }
+
+  var value = {
+    江苏: 10000,
+    内蒙古: 10000,
+    辽宁: 10000,
+    陕西: 10000,
+    福建: 10000,
+    甘肃: 10000,
+    青海: 10000,
+    新疆: 10000,
+    湖北: 10000,
+    浙江: 10000,
+    河南: 10000,
+    湖南: 10000,
+    云南: 10000,
+    广东: 10000,
+    海南: 10000,
+    西藏: 10000,
+  }
+  var colors = '#f9b207'
+
+  var year = ['长春', '长春', '青岛', '青岛', '成都', '成都']
+  var mapData = []
+
+  /* 柱子Y名称 */
+  var categoryData = []
+  var barData = []
+
+  for (var key in geoCoordMap) {
+    mapData.push({
+      year: '陕西',
+      name: key,
+      value: value[key] / 100,
+      value1: value[key] / 100,
+    })
+  }
+
+  mapData.sort(function sortNumber(a, b) {
+    return a.value - b.value
+  })
+  for (var j = 0; j < mapData.length; j++) {
+    barData.push(mapData[j].value1)
+    categoryData.push(mapData[j].name)
+  }
+
+  echarts.registerMap('china', geoJson)
+  var convertData = function (data) {
+    var res = []
+    for (var i = 0; i < data.length; i++) {
+      var geoCoord = geoCoordMap[data[i].name]
+      if (geoCoord) {
+        res.push({
+          name: data[i].name,
+          value: geoCoord.concat(data[i].value),
+        })
+      }
+    }
+    return res
+  }
+  var convertToLineData = function (data, gps) {
+    var res = []
+    for (var i = 0; i < data.length; i++) {
+      var dataItem = data[i]
+      var toCoord = geoCoordMap[dataItem.name]
+      // debugger;
+      var fromCoord = gps // 郑州
+      //  var toCoord = geoGps[Math.random()*3];
+      if (fromCoord && toCoord) {
+        res.push([
+          {
+            coord: fromCoord,
+            value: dataItem.value,
+          },
+          {
+            coord: toCoord,
+          },
+        ])
+      }
+    }
+    return res
+  }
+
+  const options = {
+    tooltip: {
+      trigger: 'item',
+      formatter(val) {
+        // console.log('val==========',val)
+      },
+    },
+    // backgroundColor: '#001540',// 设置背景色
+    geo: {
+      show: true,
+      map: 'china',
+      roam: true,
+      zoom: 1,
+      center: [101.4038, 36.8207],
+      label: {
+        emphasis: {
+          show: false,
+        },
+      },
+      itemStyle: {
+        normal: {
+          borderColor: 'rgba(147, 235, 248, 1)',
+          borderWidth: 1,
+          areaColor: {
+            type: 'radial',
+            x: 0.5,
+            y: 0.5,
+            r: 0.8,
+            colorStops: [
+              {
+                offset: 0,
+                color: 'rgba(147, 235, 248, 0)', // 0% 处的颜色
+              },
+              {
+                offset: 1,
+                color: 'rgba(147, 235, 248, .2)', // 100% 处的颜色
+              },
+            ],
+            globalCoord: false, // 缺省为 false
+          },
+          shadowColor: 'rgba(128, 217, 248, 1)',
+          // shadowColor: 'rgba(255, 255, 255, 1)',
+          shadowOffsetX: -2,
+          shadowOffsetY: 2,
+          shadowBlur: 10,
+        },
+        emphasis: {
+          areaColor: '#389BB7',
+          borderWidth: 0,
+        },
+      },
+    },
+    series: [
+      // 地图?
+      {
+        type: 'map',
+        map: 'china',
+        geoIndex: 0,
+        aspectScale: 0.75, // 长宽比
+        showLegendSymbol: false, // 存在legend时显示
+        label: {
+          normal: {
+            show: false,
+          },
+          emphasis: {
+            show: false,
+            textStyle: {
+              color: '#fff',
+            },
+          },
+        },
+
+        roam: true,
+        itemStyle: {
+          normal: {
+            areaColor: '#031525',
+            borderColor: '#FFFFFF',
+          },
+          emphasis: {
+            areaColor: '#2B91B7',
+          },
+        },
+        animation: false,
+      },
+      // 地图点的动画效果
+      {
+        //  name: 'Top 5',
+        type: 'effectScatter',
+        coordinateSystem: 'geo',
+        data: convertData(
+          mapData
+            .sort(function (a, b) {
+              return b.value - a.value
+            })
+            .slice(0, 20)
+        ),
+        symbolSize: function (val) {
+          return val[2] / 10
+        },
+        showEffectOn: 'render',
+        rippleEffect: {
+          brushType: 'stroke',
+        },
+        hoverAnimation: true,
+        label: {
+          normal: {
+            formatter: '{b}',
+            position: 'right',
+            show: true,
+          },
+        },
+        itemStyle: {
+          normal: {
+            color: colors,
+            shadowBlur: 10,
+            shadowColor: colors,
+          },
+        },
+        zlevel: 1,
+      },
+      // 地图线的动画效果
+      {
+        type: 'lines',
+        zlevel: 2,
+        effect: {
+          show: true,
+          period: 4, // 箭头指向速度,值越小速度越快
+          trailLength: 0.02, // 特效尾迹长度[0,1]值越大,尾迹越长重
+          symbol: 'arrow', // 箭头图标
+          symbolSize: 3, // 图标大小
+        },
+        lineStyle: {
+          normal: {
+            color: colors,
+            width: 0.1, // 尾迹线条宽度
+            opacity: 0.5, // 尾迹线条透明度
+            curveness: 0.3, // 尾迹线条曲直度
+          },
+        },
+        data: convertToLineData(mapData, geoGpsMap),
+      },
+      {
+        type: 'scatter',
+        zlevel: 16,
+        coordinateSystem: 'geo',
+        symbolSize: 30,
+        symbol: `image://${logo}`,
+        data: cityIconData,
+        rippleEffect: {
+          period: 4,
+          brushType: 'stroke',
+          scale: 4,
+        },
+        tooltip: {
+          trigger: 'item',
+          padding: 0,
+          borderColor: 'black',
+          background: 'rgba(0,0,0,0.7)',
+          textStyle: {
+            fontSize: 20,
+          },
+          formatter(val) {
+            console.log('val=======', val)
+            let tipHtml = `
+                     <div class="m-info" style=" opacity: 0.95;background: rgba(25,27,29,1);" >
+                         <div class="title" style="padding-left: 12px;
+                         padding-top: 10px;
+                         padding-bottom: 10px;
+                         background: rgba(25,27,29,1);font-size: 20px;color: white;padding-right: 20px">${val.name}</div>
+<!--                         <div class="content" style=" padding: 12px; background: rgba(0,2,4,1);">-->
+          <!--                               <div style=" font-size: 22px; color: #ff0000;">258944</div>-->
+          <!--                        </div>-->
+          </div>`
+            return tipHtml
+          },
+        },
+      },
+    ],
+  }
+  let chart: EChartsType
+  const initChart = () => {
+    const chart = echarts.init(document.getElementById(props.id))
+    chart.setOption(options)
+    return chart
+  }
+
+  onUnmounted(() => {
+    chart && chart.dispose()
+  })
+
+  onMounted(() => {
+    chart = initChart()
+    window.addEventListener('resize', function () {
+      chart && chart.resize()
+    })
+  })
+</script>

+ 3043 - 0
src/components/DataScreen/migrationEcharts/map.js

@@ -0,0 +1,3043 @@
+export const geoJson = {
+  type: 'FeatureCollection',
+  features: [
+    {
+      type: 'Feature',
+      id: 'xin_jiang',
+      properties: { name: '新疆', cp: [84.9023, 41.748], childNum: 18 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [96.416, 42.7588],
+            [96.416, 42.7148],
+            [95.9766, 42.4951],
+            [96.0645, 42.3193],
+            [96.2402, 42.2314],
+            [95.9766, 41.9238],
+            [95.2734, 41.6162],
+            [95.1855, 41.792],
+            [94.5703, 41.4844],
+            [94.043, 41.0889],
+            [93.8672, 40.6934],
+            [93.0762, 40.6494],
+            [92.6367, 39.6387],
+            [92.373, 39.3311],
+            [92.373, 39.1113],
+            [92.373, 39.0234],
+            [90.1758, 38.4961],
+            [90.3516, 38.2324],
+            [90.6152, 38.3203],
+            [90.5273, 37.8369],
+            [91.0547, 37.4414],
+            [91.3184, 37.0898],
+            [90.7031, 36.7822],
+            [90.791, 36.6064],
+            [91.0547, 36.5186],
+            [91.0547, 36.0791],
+            [90.8789, 36.0352],
+            [90, 36.2549],
+            [89.9121, 36.0791],
+            [89.7363, 36.0791],
+            [89.209, 36.2988],
+            [88.7695, 36.3428],
+            [88.5938, 36.4746],
+            [87.3633, 36.4307],
+            [86.2207, 36.167],
+            [86.1328, 35.8594],
+            [85.6055, 35.6836],
+            [85.0781, 35.7275],
+            [84.1992, 35.376],
+            [83.1445, 35.4199],
+            [82.8809, 35.6836],
+            [82.4414, 35.7275],
+            [82.002, 35.332],
+            [81.6504, 35.2441],
+            [80.4199, 35.4199],
+            [80.2441, 35.2881],
+            [80.332, 35.1563],
+            [80.2441, 35.2002],
+            [79.8926, 34.8047],
+            [79.8047, 34.4971],
+            [79.1016, 34.4531],
+            [79.0137, 34.3213],
+            [78.2227, 34.7168],
+            [78.0469, 35.2441],
+            [78.0469, 35.5078],
+            [77.4316, 35.4639],
+            [76.8164, 35.6396],
+            [76.5527, 35.8594],
+            [76.2012, 35.8154],
+            [75.9375, 36.0352],
+            [76.0254, 36.4746],
+            [75.8496, 36.6943],
+            [75.498, 36.7383],
+            [75.4102, 36.958],
+            [75.0586, 37.002],
+            [74.8828, 36.9141],
+            [74.7949, 37.0459],
+            [74.5313, 37.0898],
+            [74.5313, 37.2217],
+            [74.8828, 37.2217],
+            [75.1465, 37.4414],
+            [74.8828, 37.5732],
+            [74.9707, 37.749],
+            [74.8828, 38.4521],
+            [74.3555, 38.6719],
+            [74.1797, 38.6719],
+            [74.0918, 38.54],
+            [73.8281, 38.584],
+            [73.7402, 38.8477],
+            [73.8281, 38.9795],
+            [73.4766, 39.375],
+            [73.916, 39.5068],
+            [73.916, 39.6826],
+            [73.8281, 39.7705],
+            [74.0039, 40.0342],
+            [74.8828, 40.3418],
+            [74.7949, 40.5176],
+            [75.2344, 40.4297],
+            [75.5859, 40.6494],
+            [75.7617, 40.2979],
+            [76.377, 40.3857],
+            [76.9043, 41.001],
+            [77.6074, 41.001],
+            [78.1348, 41.2207],
+            [78.1348, 41.3965],
+            [80.1563, 42.0557],
+            [80.2441, 42.2754],
+            [80.1563, 42.627],
+            [80.2441, 42.8467],
+            [80.5078, 42.8906],
+            [80.4199, 43.0664],
+            [80.7715, 43.1982],
+            [80.4199, 44.165],
+            [80.4199, 44.6045],
+            [79.9805, 44.8242],
+            [79.9805, 44.9561],
+            [81.7383, 45.3955],
+            [82.0898, 45.2197],
+            [82.5293, 45.2197],
+            [82.2656, 45.6592],
+            [83.0566, 47.2412],
+            [83.6719, 47.0215],
+            [84.7266, 47.0215],
+            [84.9023, 46.8896],
+            [85.5176, 47.0654],
+            [85.6934, 47.2852],
+            [85.5176, 48.1201],
+            [85.7813, 48.4277],
+            [86.5723, 48.5596],
+            [86.8359, 48.8232],
+            [86.748, 48.9551],
+            [86.8359, 49.1309],
+            [87.8027, 49.1748],
+            [87.8906, 48.999],
+            [87.7148, 48.9111],
+            [88.0664, 48.7354],
+            [87.9785, 48.6035],
+            [88.5059, 48.3838],
+            [88.6816, 48.1641],
+            [89.1211, 47.9883],
+            [89.5605, 48.0322],
+            [89.7363, 47.8564],
+            [90.0879, 47.8564],
+            [90.3516, 47.6807],
+            [90.5273, 47.2412],
+            [90.8789, 46.9775],
+            [91.0547, 46.582],
+            [90.8789, 46.3184],
+            [91.0547, 46.0107],
+            [90.7031, 45.7471],
+            [90.7031, 45.5273],
+            [90.8789, 45.2197],
+            [91.582, 45.0879],
+            [93.5156, 44.9561],
+            [94.7461, 44.3408],
+            [95.3613, 44.2969],
+            [95.3613, 44.0332],
+            [95.5371, 43.9014],
+            [95.8887, 43.2422],
+            [96.3281, 42.9346],
+            [96.416, 42.7588],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'xi_zang',
+      properties: { name: '西藏', cp: [88.7695, 31.6846], childNum: 7 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [79.0137, 34.3213],
+            [79.1016, 34.4531],
+            [79.8047, 34.4971],
+            [79.8926, 34.8047],
+            [80.2441, 35.2002],
+            [80.332, 35.1563],
+            [80.2441, 35.2881],
+            [80.4199, 35.4199],
+            [81.6504, 35.2441],
+            [82.002, 35.332],
+            [82.4414, 35.7275],
+            [82.8809, 35.6836],
+            [83.1445, 35.4199],
+            [84.1992, 35.376],
+            [85.0781, 35.7275],
+            [85.6055, 35.6836],
+            [86.1328, 35.8594],
+            [86.2207, 36.167],
+            [87.3633, 36.4307],
+            [88.5938, 36.4746],
+            [88.7695, 36.3428],
+            [89.209, 36.2988],
+            [89.7363, 36.0791],
+            [89.3848, 36.0352],
+            [89.4727, 35.9033],
+            [89.7363, 35.7715],
+            [89.7363, 35.4199],
+            [89.4727, 35.376],
+            [89.4727, 35.2441],
+            [89.5605, 34.8926],
+            [89.8242, 34.8486],
+            [89.7363, 34.6729],
+            [89.8242, 34.3652],
+            [89.6484, 34.0137],
+            [90.0879, 33.4863],
+            [90.7031, 33.1348],
+            [91.4063, 33.1348],
+            [91.9336, 32.8271],
+            [92.1973, 32.8271],
+            [92.2852, 32.7393],
+            [92.9883, 32.7393],
+            [93.5156, 32.4756],
+            [93.7793, 32.5635],
+            [94.1309, 32.4316],
+            [94.6582, 32.6074],
+            [95.1855, 32.4316],
+            [95.0098, 32.2998],
+            [95.1855, 32.3438],
+            [95.2734, 32.2119],
+            [95.3613, 32.168],
+            [95.3613, 31.9922],
+            [95.4492, 31.8164],
+            [95.8008, 31.6846],
+            [95.9766, 31.8164],
+            [96.1523, 31.5967],
+            [96.2402, 31.9482],
+            [96.5039, 31.7285],
+            [96.8555, 31.6846],
+            [96.7676, 31.9922],
+            [97.2949, 32.0801],
+            [97.3828, 32.5635],
+            [97.7344, 32.5195],
+            [98.1738, 32.3438],
+            [98.4375, 31.8604],
+            [98.877, 31.4209],
+            [98.6133, 31.2012],
+            [98.9648, 30.7617],
+            [99.1406, 29.2676],
+            [98.9648, 29.1357],
+            [98.9648, 28.8281],
+            [98.7891, 28.8721],
+            [98.7891, 29.0039],
+            [98.7012, 28.916],
+            [98.6133, 28.5205],
+            [98.7891, 28.3447],
+            [98.7012, 28.2129],
+            [98.3496, 28.125],
+            [98.2617, 28.3887],
+            [98.1738, 28.125],
+            [97.5586, 28.5205],
+            [97.2949, 28.0811],
+            [97.3828, 27.9053],
+            [97.0313, 27.7295],
+            [96.5039, 28.125],
+            [95.7129, 28.2568],
+            [95.3613, 28.125],
+            [95.2734, 27.9492],
+            [94.2188, 27.5537],
+            [93.8672, 27.0264],
+            [93.6035, 26.9385],
+            [92.1094, 26.8506],
+            [92.0215, 27.4658],
+            [91.582, 27.5537],
+            [91.582, 27.9053],
+            [91.4063, 28.0371],
+            [91.0547, 27.8613],
+            [90.7031, 28.0811],
+            [89.8242, 28.2129],
+            [89.6484, 28.1689],
+            [89.1211, 27.5977],
+            [89.1211, 27.334],
+            [89.0332, 27.2021],
+            [88.7695, 27.4219],
+            [88.8574, 27.9932],
+            [88.6816, 28.125],
+            [88.1543, 27.9053],
+            [87.8906, 27.9492],
+            [87.7148, 27.8174],
+            [87.0996, 27.8174],
+            [86.748, 28.125],
+            [86.5723, 28.125],
+            [86.4844, 27.9053],
+            [86.1328, 28.125],
+            [86.0449, 27.9053],
+            [85.6934, 28.3447],
+            [85.6055, 28.2568],
+            [85.166, 28.3447],
+            [85.166, 28.6523],
+            [84.9023, 28.5645],
+            [84.4629, 28.7402],
+            [84.2871, 28.8721],
+            [84.1992, 29.2236],
+            [84.1113, 29.2676],
+            [83.584, 29.1797],
+            [83.2324, 29.5752],
+            [82.1777, 30.0586],
+            [82.0898, 30.3223],
+            [81.3867, 30.3662],
+            [81.2109, 30.0146],
+            [81.0352, 30.2344],
+            [80.0684, 30.5859],
+            [79.7168, 30.9375],
+            [79.0137, 31.0693],
+            [78.75, 31.333],
+            [78.8379, 31.5967],
+            [78.6621, 31.8164],
+            [78.75, 31.9043],
+            [78.4863, 32.124],
+            [78.3984, 32.5195],
+            [78.75, 32.6953],
+            [78.9258, 32.3438],
+            [79.2773, 32.5635],
+            [79.1016, 33.1787],
+            [78.6621, 33.6621],
+            [78.6621, 34.1016],
+            [78.9258, 34.1455],
+            [79.0137, 34.3213],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'nei_meng_gu',
+      properties: { name: '内蒙古', cp: [117.5977, 44.3408], childNum: 12 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [97.207, 42.8027],
+            [99.4922, 42.583],
+            [100.8105, 42.6709],
+            [101.7773, 42.4951],
+            [102.041, 42.2314],
+            [102.7441, 42.1436],
+            [103.3594, 41.8799],
+            [103.8867, 41.792],
+            [104.502, 41.8799],
+            [104.502, 41.6602],
+            [105.0293, 41.5723],
+            [105.7324, 41.9238],
+            [107.4023, 42.4512],
+            [109.4238, 42.4512],
+            [110.3906, 42.7588],
+            [111.0059, 43.3301],
+            [111.9727, 43.6816],
+            [111.9727, 43.8135],
+            [111.4453, 44.3848],
+            [111.7969, 45],
+            [111.9727, 45.0879],
+            [113.6426, 44.7363],
+            [114.1699, 44.9561],
+            [114.5215, 45.3955],
+            [115.6641, 45.4395],
+            [116.1914, 45.7031],
+            [116.2793, 45.9668],
+            [116.543, 46.2744],
+            [117.334, 46.3623],
+            [117.4219, 46.582],
+            [117.7734, 46.5381],
+            [118.3008, 46.7578],
+            [118.7402, 46.7139],
+            [118.916, 46.7578],
+            [119.0918, 46.6699],
+            [119.707, 46.626],
+            [119.9707, 46.7139],
+            [119.707, 47.1973],
+            [118.4766, 47.9883],
+            [117.8613, 48.0322],
+            [117.334, 47.6807],
+            [116.8066, 47.9004],
+            [116.1914, 47.8564],
+            [115.9277, 47.6807],
+            [115.5762, 47.9004],
+            [115.4883, 48.1641],
+            [115.8398, 48.252],
+            [115.8398, 48.5596],
+            [116.7188, 49.834],
+            [117.7734, 49.5264],
+            [118.5645, 49.9219],
+            [119.2676, 50.0977],
+            [119.3555, 50.3174],
+            [119.1797, 50.3613],
+            [119.5313, 50.7568],
+            [119.5313, 50.8887],
+            [119.707, 51.0645],
+            [120.1465, 51.6797],
+            [120.6738, 51.9434],
+            [120.7617, 52.1191],
+            [120.7617, 52.251],
+            [120.5859, 52.3389],
+            [120.6738, 52.5146],
+            [120.4102, 52.6465],
+            [120.0586, 52.6025],
+            [120.0586, 52.7344],
+            [120.8496, 53.2617],
+            [121.4648, 53.3496],
+            [121.8164, 53.042],
+            [121.2012, 52.5586],
+            [121.6406, 52.4268],
+            [121.7285, 52.2949],
+            [121.9922, 52.2949],
+            [122.168, 52.5146],
+            [122.6953, 52.251],
+            [122.6074, 52.0752],
+            [122.959, 51.3281],
+            [123.3105, 51.2402],
+            [123.6621, 51.3721],
+            [124.3652, 51.2842],
+            [124.541, 51.3721],
+            [124.8926, 51.3721],
+            [125.0684, 51.6357],
+            [125.332, 51.6357],
+            [126.0352, 51.0205],
+            [125.7715, 50.7568],
+            [125.7715, 50.5371],
+            [125.332, 50.1416],
+            [125.1563, 49.834],
+            [125.2441, 49.1748],
+            [124.8047, 49.1309],
+            [124.4531, 48.1201],
+            [124.2773, 48.5156],
+            [122.4316, 47.373],
+            [123.0469, 46.7139],
+            [123.3984, 46.8896],
+            [123.3984, 46.9775],
+            [123.4863, 46.9775],
+            [123.5742, 46.8457],
+            [123.5742, 46.8896],
+            [123.5742, 46.6699],
+            [123.0469, 46.582],
+            [123.2227, 46.2305],
+            [122.7832, 46.0107],
+            [122.6953, 45.7031],
+            [122.4316, 45.8789],
+            [122.2559, 45.791],
+            [121.8164, 46.0107],
+            [121.7285, 45.7471],
+            [121.9043, 45.7031],
+            [122.2559, 45.2637],
+            [122.0801, 44.8682],
+            [122.3438, 44.2529],
+            [123.1348, 44.4727],
+            [123.4863, 43.7256],
+            [123.3105, 43.5059],
+            [123.6621, 43.374],
+            [123.5742, 43.0225],
+            [123.3105, 42.9785],
+            [123.1348, 42.8027],
+            [122.7832, 42.7148],
+            [122.3438, 42.8467],
+            [122.3438, 42.6709],
+            [121.9922, 42.7148],
+            [121.7285, 42.4512],
+            [121.4648, 42.4951],
+            [120.498, 42.0996],
+            [120.1465, 41.7041],
+            [119.8828, 42.1875],
+            [119.5313, 42.3633],
+            [119.3555, 42.2754],
+            [119.2676, 41.7041],
+            [119.4434, 41.6162],
+            [119.2676, 41.3086],
+            [118.3887, 41.3086],
+            [118.125, 41.748],
+            [118.3008, 41.792],
+            [118.3008, 42.0996],
+            [118.125, 42.0557],
+            [117.9492, 42.2314],
+            [118.0371, 42.4072],
+            [117.7734, 42.627],
+            [117.5098, 42.583],
+            [117.334, 42.4512],
+            [116.8945, 42.4072],
+            [116.8066, 42.0117],
+            [116.2793, 42.0117],
+            [116.0156, 41.792],
+            [115.9277, 41.9238],
+            [115.2246, 41.5723],
+            [114.9609, 41.6162],
+            [114.873, 42.0996],
+            [114.5215, 42.1436],
+            [114.1699, 41.792],
+            [114.2578, 41.5723],
+            [113.9063, 41.4404],
+            [113.9941, 41.2207],
+            [113.9063, 41.1328],
+            [114.082, 40.7373],
+            [114.082, 40.5176],
+            [113.8184, 40.5176],
+            [113.5547, 40.3418],
+            [113.2031, 40.3857],
+            [112.7637, 40.166],
+            [112.3242, 40.2539],
+            [111.9727, 39.5947],
+            [111.4453, 39.6387],
+            [111.3574, 39.4189],
+            [111.0938, 39.375],
+            [111.0938, 39.5947],
+            [110.6543, 39.2871],
+            [110.127, 39.4629],
+            [110.2148, 39.2871],
+            [109.8633, 39.2432],
+            [109.9512, 39.1553],
+            [108.9844, 38.3203],
+            [109.0723, 38.0127],
+            [108.8965, 37.9688],
+            [108.8086, 38.0127],
+            [108.7207, 37.7051],
+            [108.1934, 37.6172],
+            [107.666, 37.8809],
+            [107.3145, 38.1006],
+            [106.7871, 38.1885],
+            [106.5234, 38.3203],
+            [106.9629, 38.9795],
+            [106.7871, 39.375],
+            [106.3477, 39.2871],
+            [105.9082, 38.7158],
+            [105.8203, 37.793],
+            [104.3262, 37.4414],
+            [103.4473, 37.8369],
+            [103.3594, 38.0127],
+            [103.5352, 38.1445],
+            [103.4473, 38.3643],
+            [104.2383, 38.9795],
+            [104.0625, 39.4189],
+            [103.3594, 39.3311],
+            [103.0078, 39.1113],
+            [102.4805, 39.2432],
+            [101.8652, 39.1113],
+            [102.041, 38.8916],
+            [101.7773, 38.6719],
+            [101.3379, 38.7598],
+            [101.25, 39.0234],
+            [100.9863, 38.9355],
+            [100.8105, 39.4189],
+            [100.5469, 39.4189],
+            [100.0195, 39.7705],
+            [99.4922, 39.8584],
+            [100.1074, 40.2539],
+            [100.1953, 40.6494],
+            [99.9316, 41.001],
+            [99.2285, 40.8691],
+            [99.0527, 40.6934],
+            [98.9648, 40.7813],
+            [98.7891, 40.6055],
+            [98.5254, 40.7373],
+            [98.6133, 40.6494],
+            [98.3496, 40.5615],
+            [98.3496, 40.9131],
+            [97.4707, 41.4844],
+            [97.8223, 41.6162],
+            [97.8223, 41.748],
+            [97.207, 42.8027],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'qing_hai',
+      properties: { name: '青海', cp: [96.2402, 35.4199], childNum: 8 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [89.7363, 36.0791],
+            [89.9121, 36.0791],
+            [90, 36.2549],
+            [90.8789, 36.0352],
+            [91.0547, 36.0791],
+            [91.0547, 36.5186],
+            [90.791, 36.6064],
+            [90.7031, 36.7822],
+            [91.3184, 37.0898],
+            [91.0547, 37.4414],
+            [90.5273, 37.8369],
+            [90.6152, 38.3203],
+            [90.3516, 38.2324],
+            [90.1758, 38.4961],
+            [92.373, 39.0234],
+            [92.373, 39.1113],
+            [93.1641, 39.1992],
+            [93.1641, 38.9795],
+            [93.6914, 38.9355],
+            [93.8672, 38.7158],
+            [94.3066, 38.7598],
+            [94.5703, 38.3643],
+            [95.0098, 38.4082],
+            [95.4492, 38.2764],
+            [95.7129, 38.3643],
+            [96.2402, 38.1006],
+            [96.416, 38.2324],
+            [96.6797, 38.1885],
+            [96.6797, 38.4521],
+            [97.1191, 38.584],
+            [97.0313, 39.1992],
+            [98.1738, 38.8037],
+            [98.3496, 39.0234],
+            [98.6133, 38.9355],
+            [98.7891, 39.0674],
+            [99.1406, 38.9355],
+            [99.8438, 38.3643],
+            [100.1953, 38.2764],
+            [100.0195, 38.4521],
+            [100.1074, 38.4961],
+            [100.459, 38.2764],
+            [100.7227, 38.2324],
+            [101.1621, 37.8369],
+            [101.5137, 37.8809],
+            [101.7773, 37.6172],
+            [101.9531, 37.7051],
+            [102.1289, 37.4414],
+            [102.5684, 37.1777],
+            [102.4805, 36.958],
+            [102.6563, 36.8262],
+            [102.5684, 36.7383],
+            [102.832, 36.3428],
+            [103.0078, 36.2549],
+            [102.9199, 36.0791],
+            [102.9199, 35.9033],
+            [102.6563, 35.7715],
+            [102.832, 35.5957],
+            [102.4805, 35.5957],
+            [102.3047, 35.4199],
+            [102.3926, 35.2002],
+            [101.9531, 34.8486],
+            [101.9531, 34.6289],
+            [102.2168, 34.4092],
+            [102.1289, 34.2773],
+            [101.6895, 34.1016],
+            [100.9863, 34.3652],
+            [100.8105, 34.2773],
+            [101.25, 33.6621],
+            [101.5137, 33.7061],
+            [101.6016, 33.5303],
+            [101.7773, 33.5303],
+            [101.6895, 33.3105],
+            [101.7773, 33.2227],
+            [101.6016, 33.1348],
+            [101.1621, 33.2227],
+            [101.25, 32.6953],
+            [100.7227, 32.6514],
+            [100.7227, 32.5195],
+            [100.3711, 32.7393],
+            [100.1074, 32.6514],
+            [100.1074, 32.8711],
+            [99.8438, 33.0029],
+            [99.7559, 32.7393],
+            [99.2285, 32.915],
+            [99.2285, 33.0469],
+            [98.877, 33.1787],
+            [98.4375, 34.0576],
+            [97.8223, 34.1895],
+            [97.6465, 34.1016],
+            [97.7344, 33.9258],
+            [97.3828, 33.8818],
+            [97.4707, 33.5742],
+            [97.7344, 33.3984],
+            [97.3828, 32.8711],
+            [97.4707, 32.6953],
+            [97.7344, 32.5195],
+            [97.3828, 32.5635],
+            [97.2949, 32.0801],
+            [96.7676, 31.9922],
+            [96.8555, 31.6846],
+            [96.5039, 31.7285],
+            [96.2402, 31.9482],
+            [96.1523, 31.5967],
+            [95.9766, 31.8164],
+            [95.8008, 31.6846],
+            [95.4492, 31.8164],
+            [95.3613, 31.9922],
+            [95.3613, 32.168],
+            [95.2734, 32.2119],
+            [95.1855, 32.3438],
+            [95.0098, 32.2998],
+            [95.1855, 32.4316],
+            [94.6582, 32.6074],
+            [94.1309, 32.4316],
+            [93.7793, 32.5635],
+            [93.5156, 32.4756],
+            [92.9883, 32.7393],
+            [92.2852, 32.7393],
+            [92.1973, 32.8271],
+            [91.9336, 32.8271],
+            [91.4063, 33.1348],
+            [90.7031, 33.1348],
+            [90.0879, 33.4863],
+            [89.6484, 34.0137],
+            [89.8242, 34.3652],
+            [89.7363, 34.6729],
+            [89.8242, 34.8486],
+            [89.5605, 34.8926],
+            [89.4727, 35.2441],
+            [89.4727, 35.376],
+            [89.7363, 35.4199],
+            [89.7363, 35.7715],
+            [89.4727, 35.9033],
+            [89.3848, 36.0352],
+            [89.7363, 36.0791],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'si_chuan',
+      properties: { name: '四川', cp: [102.9199, 30.1904], childNum: 21 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [101.7773, 33.5303],
+            [101.8652, 33.5742],
+            [101.9531, 33.4424],
+            [101.8652, 33.0908],
+            [102.4805, 33.4424],
+            [102.2168, 33.9258],
+            [102.9199, 34.3213],
+            [103.0957, 34.1895],
+            [103.1836, 33.7939],
+            [104.1504, 33.6182],
+            [104.2383, 33.3984],
+            [104.4141, 33.3105],
+            [104.3262, 33.2227],
+            [104.4141, 33.0469],
+            [104.3262, 32.8711],
+            [104.4141, 32.7393],
+            [105.2051, 32.6074],
+            [105.3809, 32.7393],
+            [105.3809, 32.8711],
+            [105.4688, 32.915],
+            [105.5566, 32.7393],
+            [106.084, 32.8711],
+            [106.084, 32.7393],
+            [106.3477, 32.6514],
+            [107.0508, 32.6953],
+            [107.1387, 32.4756],
+            [107.2266, 32.4316],
+            [107.4023, 32.5195],
+            [108.0176, 32.168],
+            [108.2813, 32.2559],
+            [108.5449, 32.2119],
+            [108.3691, 32.168],
+            [108.2813, 31.9043],
+            [108.5449, 31.6846],
+            [108.1934, 31.5088],
+            [107.9297, 30.8496],
+            [107.4902, 30.8496],
+            [107.4023, 30.7617],
+            [107.4902, 30.6299],
+            [107.0508, 30.0146],
+            [106.7871, 30.0146],
+            [106.6113, 30.3223],
+            [106.2598, 30.1904],
+            [105.8203, 30.4541],
+            [105.6445, 30.2783],
+            [105.5566, 30.1025],
+            [105.7324, 29.8828],
+            [105.293, 29.5313],
+            [105.4688, 29.3115],
+            [105.7324, 29.2676],
+            [105.8203, 28.96],
+            [106.2598, 28.8721],
+            [106.3477, 28.5205],
+            [105.9961, 28.7402],
+            [105.6445, 28.4326],
+            [105.9082, 28.125],
+            [106.1719, 28.125],
+            [106.3477, 27.8174],
+            [105.6445, 27.6416],
+            [105.5566, 27.7734],
+            [105.293, 27.7295],
+            [105.2051, 27.9932],
+            [105.0293, 28.0811],
+            [104.8535, 27.9053],
+            [104.4141, 27.9492],
+            [104.3262, 28.0371],
+            [104.4141, 28.125],
+            [104.4141, 28.2568],
+            [104.2383, 28.4326],
+            [104.4141, 28.6084],
+            [103.8867, 28.6523],
+            [103.7988, 28.3008],
+            [103.4473, 28.125],
+            [103.4473, 27.7734],
+            [102.9199, 27.29],
+            [103.0078, 26.3672],
+            [102.6563, 26.1914],
+            [102.5684, 26.3672],
+            [102.1289, 26.1035],
+            [101.8652, 26.0596],
+            [101.6016, 26.2354],
+            [101.6895, 26.3672],
+            [101.4258, 26.5869],
+            [101.4258, 26.8066],
+            [101.4258, 26.7188],
+            [101.1621, 27.0264],
+            [101.1621, 27.1582],
+            [100.7227, 27.8613],
+            [100.3711, 27.8174],
+            [100.2832, 27.7295],
+            [100.0195, 28.125],
+            [100.1953, 28.3447],
+            [99.668, 28.8281],
+            [99.4043, 28.5205],
+            [99.4043, 28.1689],
+            [99.2285, 28.3008],
+            [99.1406, 29.2676],
+            [98.9648, 30.7617],
+            [98.6133, 31.2012],
+            [98.877, 31.4209],
+            [98.4375, 31.8604],
+            [98.1738, 32.3438],
+            [97.7344, 32.5195],
+            [97.4707, 32.6953],
+            [97.3828, 32.8711],
+            [97.7344, 33.3984],
+            [97.4707, 33.5742],
+            [97.3828, 33.8818],
+            [97.7344, 33.9258],
+            [97.6465, 34.1016],
+            [97.8223, 34.1895],
+            [98.4375, 34.0576],
+            [98.877, 33.1787],
+            [99.2285, 33.0469],
+            [99.2285, 32.915],
+            [99.7559, 32.7393],
+            [99.8438, 33.0029],
+            [100.1074, 32.8711],
+            [100.1074, 32.6514],
+            [100.3711, 32.7393],
+            [100.7227, 32.5195],
+            [100.7227, 32.6514],
+            [101.25, 32.6953],
+            [101.1621, 33.2227],
+            [101.6016, 33.1348],
+            [101.7773, 33.2227],
+            [101.6895, 33.3105],
+            [101.7773, 33.5303],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'hei_long_jiang',
+      properties: { name: '黑龙江', cp: [128.1445, 48.5156], childNum: 13 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [121.4648, 53.3496],
+            [123.6621, 53.5693],
+            [124.8926, 53.0859],
+            [125.0684, 53.2178],
+            [125.5957, 53.0859],
+            [125.6836, 52.9102],
+            [126.123, 52.7783],
+            [126.0352, 52.6025],
+            [126.2109, 52.5146],
+            [126.3867, 52.2949],
+            [126.3867, 52.207],
+            [126.5625, 52.1631],
+            [126.4746, 51.9434],
+            [126.9141, 51.3721],
+            [126.8262, 51.2842],
+            [127.002, 51.3281],
+            [126.9141, 51.1084],
+            [127.2656, 50.7568],
+            [127.3535, 50.2734],
+            [127.6172, 50.2295],
+            [127.5293, 49.8779],
+            [127.793, 49.6143],
+            [128.7598, 49.5703],
+            [129.1113, 49.3506],
+            [129.4629, 49.4385],
+            [130.2539, 48.8672],
+            [130.6934, 48.8672],
+            [130.5176, 48.6475],
+            [130.8691, 48.2959],
+            [130.6934, 48.1201],
+            [131.0449, 47.6807],
+            [132.5391, 47.7246],
+            [132.627, 47.9443],
+            [133.0664, 48.1201],
+            [133.5059, 48.1201],
+            [134.209, 48.3838],
+            [135.0879, 48.4277],
+            [134.7363, 48.252],
+            [134.5605, 47.9883],
+            [134.7363, 47.6807],
+            [134.5605, 47.4609],
+            [134.3848, 47.4609],
+            [134.209, 47.2852],
+            [134.209, 47.1533],
+            [133.8574, 46.5381],
+            [133.9453, 46.2744],
+            [133.5059, 45.835],
+            [133.418, 45.5713],
+            [133.2422, 45.5273],
+            [133.0664, 45.1318],
+            [132.8906, 45.0439],
+            [131.9238, 45.3516],
+            [131.5723, 45.0439],
+            [131.0449, 44.8682],
+            [131.3086, 44.0771],
+            [131.2207, 43.7256],
+            [131.3086, 43.4619],
+            [130.8691, 43.418],
+            [130.5176, 43.6377],
+            [130.3418, 43.9893],
+            [129.9902, 43.8574],
+            [129.9023, 44.0332],
+            [129.8145, 43.9014],
+            [129.2871, 43.8135],
+            [129.1992, 43.5938],
+            [128.8477, 43.5498],
+            [128.4961, 44.165],
+            [128.4082, 44.4727],
+            [128.0566, 44.3408],
+            [128.0566, 44.1211],
+            [127.7051, 44.1211],
+            [127.5293, 44.6045],
+            [127.0898, 44.6045],
+            [127.002, 44.7803],
+            [127.0898, 45],
+            [126.9141, 45.1318],
+            [126.5625, 45.2637],
+            [126.0352, 45.1758],
+            [125.7715, 45.3076],
+            [125.6836, 45.5273],
+            [125.0684, 45.3955],
+            [124.8926, 45.5273],
+            [124.3652, 45.4395],
+            [124.0137, 45.7471],
+            [123.9258, 46.2305],
+            [123.2227, 46.2305],
+            [123.0469, 46.582],
+            [123.5742, 46.6699],
+            [123.5742, 46.8896],
+            [123.5742, 46.8457],
+            [123.4863, 46.9775],
+            [123.3984, 46.9775],
+            [123.3984, 46.8896],
+            [123.0469, 46.7139],
+            [122.4316, 47.373],
+            [124.2773, 48.5156],
+            [124.4531, 48.1201],
+            [124.8047, 49.1309],
+            [125.2441, 49.1748],
+            [125.1563, 49.834],
+            [125.332, 50.1416],
+            [125.7715, 50.5371],
+            [125.7715, 50.7568],
+            [126.0352, 51.0205],
+            [125.332, 51.6357],
+            [125.0684, 51.6357],
+            [124.8926, 51.3721],
+            [124.541, 51.3721],
+            [124.3652, 51.2842],
+            [123.6621, 51.3721],
+            [123.3105, 51.2402],
+            [122.959, 51.3281],
+            [122.6074, 52.0752],
+            [122.6953, 52.251],
+            [122.168, 52.5146],
+            [121.9922, 52.2949],
+            [121.7285, 52.2949],
+            [121.6406, 52.4268],
+            [121.2012, 52.5586],
+            [121.8164, 53.042],
+            [121.4648, 53.3496],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'gan_su',
+      properties: { name: '甘肃', cp: [95.7129, 40.166], childNum: 14 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [96.416, 42.7148],
+            [97.207, 42.8027],
+            [97.8223, 41.748],
+            [97.8223, 41.6162],
+            [97.4707, 41.4844],
+            [98.3496, 40.9131],
+            [98.3496, 40.5615],
+            [98.6133, 40.6494],
+            [98.5254, 40.7373],
+            [98.7891, 40.6055],
+            [98.9648, 40.7813],
+            [99.0527, 40.6934],
+            [99.2285, 40.8691],
+            [99.9316, 41.001],
+            [100.1953, 40.6494],
+            [100.1074, 40.2539],
+            [99.4922, 39.8584],
+            [100.0195, 39.7705],
+            [100.5469, 39.4189],
+            [100.8105, 39.4189],
+            [100.9863, 38.9355],
+            [101.25, 39.0234],
+            [101.3379, 38.7598],
+            [101.7773, 38.6719],
+            [102.041, 38.8916],
+            [101.8652, 39.1113],
+            [102.4805, 39.2432],
+            [103.0078, 39.1113],
+            [103.3594, 39.3311],
+            [104.0625, 39.4189],
+            [104.2383, 38.9795],
+            [103.4473, 38.3643],
+            [103.5352, 38.1445],
+            [103.3594, 38.0127],
+            [103.4473, 37.8369],
+            [104.3262, 37.4414],
+            [104.5898, 37.4414],
+            [104.5898, 37.2217],
+            [104.8535, 37.2217],
+            [105.293, 36.8262],
+            [105.2051, 36.6943],
+            [105.4688, 36.123],
+            [105.293, 35.9912],
+            [105.3809, 35.7715],
+            [105.7324, 35.7275],
+            [105.8203, 35.5518],
+            [105.9961, 35.4639],
+            [105.9082, 35.4199],
+            [105.9961, 35.4199],
+            [106.084, 35.376],
+            [106.2598, 35.4199],
+            [106.3477, 35.2441],
+            [106.5234, 35.332],
+            [106.4355, 35.6836],
+            [106.6992, 35.6836],
+            [106.9629, 35.8154],
+            [106.875, 36.123],
+            [106.5234, 36.2549],
+            [106.5234, 36.4746],
+            [106.4355, 36.5625],
+            [106.6113, 36.7822],
+            [106.6113, 37.0898],
+            [107.3145, 37.0898],
+            [107.3145, 36.9141],
+            [108.7207, 36.3428],
+            [108.6328, 35.9912],
+            [108.5449, 35.8594],
+            [108.6328, 35.5518],
+            [108.5449, 35.2881],
+            [107.7539, 35.2881],
+            [107.7539, 35.1123],
+            [107.8418, 35.0244],
+            [107.666, 34.9365],
+            [107.2266, 34.8926],
+            [106.9629, 35.0684],
+            [106.6113, 35.0684],
+            [106.5234, 34.7607],
+            [106.3477, 34.585],
+            [106.6992, 34.3213],
+            [106.5234, 34.2773],
+            [106.6113, 34.1455],
+            [106.4355, 33.9258],
+            [106.5234, 33.5303],
+            [105.9961, 33.6182],
+            [105.7324, 33.3984],
+            [105.9961, 33.1787],
+            [105.9082, 33.0029],
+            [105.4688, 32.915],
+            [105.3809, 32.8711],
+            [105.3809, 32.7393],
+            [105.2051, 32.6074],
+            [104.4141, 32.7393],
+            [104.3262, 32.8711],
+            [104.4141, 33.0469],
+            [104.3262, 33.2227],
+            [104.4141, 33.3105],
+            [104.2383, 33.3984],
+            [104.1504, 33.6182],
+            [103.1836, 33.7939],
+            [103.0957, 34.1895],
+            [102.9199, 34.3213],
+            [102.2168, 33.9258],
+            [102.4805, 33.4424],
+            [101.8652, 33.0908],
+            [101.9531, 33.4424],
+            [101.8652, 33.5742],
+            [101.7773, 33.5303],
+            [101.6016, 33.5303],
+            [101.5137, 33.7061],
+            [101.25, 33.6621],
+            [100.8105, 34.2773],
+            [100.9863, 34.3652],
+            [101.6895, 34.1016],
+            [102.1289, 34.2773],
+            [102.2168, 34.4092],
+            [101.9531, 34.6289],
+            [101.9531, 34.8486],
+            [102.3926, 35.2002],
+            [102.3047, 35.4199],
+            [102.4805, 35.5957],
+            [102.832, 35.5957],
+            [102.6563, 35.7715],
+            [102.9199, 35.9033],
+            [102.9199, 36.0791],
+            [103.0078, 36.2549],
+            [102.832, 36.3428],
+            [102.5684, 36.7383],
+            [102.6563, 36.8262],
+            [102.4805, 36.958],
+            [102.5684, 37.1777],
+            [102.1289, 37.4414],
+            [101.9531, 37.7051],
+            [101.7773, 37.6172],
+            [101.5137, 37.8809],
+            [101.1621, 37.8369],
+            [100.7227, 38.2324],
+            [100.459, 38.2764],
+            [100.1074, 38.4961],
+            [100.0195, 38.4521],
+            [100.1953, 38.2764],
+            [99.8438, 38.3643],
+            [99.1406, 38.9355],
+            [98.7891, 39.0674],
+            [98.6133, 38.9355],
+            [98.3496, 39.0234],
+            [98.1738, 38.8037],
+            [97.0313, 39.1992],
+            [97.1191, 38.584],
+            [96.6797, 38.4521],
+            [96.6797, 38.1885],
+            [96.416, 38.2324],
+            [96.2402, 38.1006],
+            [95.7129, 38.3643],
+            [95.4492, 38.2764],
+            [95.0098, 38.4082],
+            [94.5703, 38.3643],
+            [94.3066, 38.7598],
+            [93.8672, 38.7158],
+            [93.6914, 38.9355],
+            [93.1641, 38.9795],
+            [93.1641, 39.1992],
+            [92.373, 39.1113],
+            [92.373, 39.3311],
+            [92.6367, 39.6387],
+            [93.0762, 40.6494],
+            [93.8672, 40.6934],
+            [94.043, 41.0889],
+            [94.5703, 41.4844],
+            [95.1855, 41.792],
+            [95.2734, 41.6162],
+            [95.9766, 41.9238],
+            [96.2402, 42.2314],
+            [96.0645, 42.3193],
+            [95.9766, 42.4951],
+            [96.416, 42.7148],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'yun_nan',
+      properties: { name: '云南', cp: [101.8652, 25.1807], childNum: 16 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [98.1738, 28.125],
+            [98.2617, 28.3887],
+            [98.3496, 28.125],
+            [98.7012, 28.2129],
+            [98.7891, 28.3447],
+            [98.6133, 28.5205],
+            [98.7012, 28.916],
+            [98.7891, 29.0039],
+            [98.7891, 28.8721],
+            [98.9648, 28.8281],
+            [98.9648, 29.1357],
+            [99.1406, 29.2676],
+            [99.2285, 28.3008],
+            [99.4043, 28.1689],
+            [99.4043, 28.5205],
+            [99.668, 28.8281],
+            [100.1953, 28.3447],
+            [100.0195, 28.125],
+            [100.2832, 27.7295],
+            [100.3711, 27.8174],
+            [100.7227, 27.8613],
+            [101.1621, 27.1582],
+            [101.1621, 27.0264],
+            [101.4258, 26.7188],
+            [101.4258, 26.8066],
+            [101.4258, 26.5869],
+            [101.6895, 26.3672],
+            [101.6016, 26.2354],
+            [101.8652, 26.0596],
+            [102.1289, 26.1035],
+            [102.5684, 26.3672],
+            [102.6563, 26.1914],
+            [103.0078, 26.3672],
+            [102.9199, 27.29],
+            [103.4473, 27.7734],
+            [103.4473, 28.125],
+            [103.7988, 28.3008],
+            [103.8867, 28.6523],
+            [104.4141, 28.6084],
+            [104.2383, 28.4326],
+            [104.4141, 28.2568],
+            [104.4141, 28.125],
+            [104.3262, 28.0371],
+            [104.4141, 27.9492],
+            [104.8535, 27.9053],
+            [105.0293, 28.0811],
+            [105.2051, 27.9932],
+            [105.293, 27.7295],
+            [105.2051, 27.3779],
+            [104.5898, 27.334],
+            [104.4141, 27.4658],
+            [104.1504, 27.2461],
+            [103.8867, 27.4219],
+            [103.623, 27.0264],
+            [103.7109, 26.9824],
+            [103.7109, 26.7627],
+            [103.8867, 26.543],
+            [104.4141, 26.6748],
+            [104.6777, 26.4111],
+            [104.3262, 25.708],
+            [104.8535, 25.2246],
+            [104.5898, 25.0488],
+            [104.6777, 24.9609],
+            [104.502, 24.7412],
+            [104.6777, 24.3457],
+            [104.7656, 24.4775],
+            [105.0293, 24.4336],
+            [105.2051, 24.082],
+            [105.4688, 24.0381],
+            [105.5566, 24.126],
+            [105.9961, 24.126],
+            [106.1719, 23.8184],
+            [106.1719, 23.5547],
+            [105.6445, 23.4229],
+            [105.5566, 23.2031],
+            [105.293, 23.3789],
+            [104.8535, 23.1592],
+            [104.7656, 22.8516],
+            [104.3262, 22.6758],
+            [104.1504, 22.8076],
+            [103.9746, 22.5439],
+            [103.623, 22.7637],
+            [103.5352, 22.5879],
+            [103.3594, 22.8076],
+            [103.0957, 22.4561],
+            [102.4805, 22.7637],
+            [102.3047, 22.4121],
+            [101.8652, 22.3682],
+            [101.7773, 22.5],
+            [101.6016, 22.1924],
+            [101.8652, 21.6211],
+            [101.7773, 21.1377],
+            [101.6016, 21.2256],
+            [101.25, 21.1816],
+            [101.1621, 21.7529],
+            [100.6348, 21.4453],
+            [100.1074, 21.4893],
+            [99.9316, 22.0605],
+            [99.2285, 22.1484],
+            [99.4043, 22.5879],
+            [99.3164, 22.7197],
+            [99.4922, 23.0713],
+            [98.877, 23.2031],
+            [98.7012, 23.9502],
+            [98.877, 24.126],
+            [98.1738, 24.082],
+            [97.7344, 23.8623],
+            [97.5586, 23.9063],
+            [97.7344, 24.126],
+            [97.6465, 24.4336],
+            [97.5586, 24.4336],
+            [97.5586, 24.7412],
+            [97.7344, 24.8291],
+            [97.8223, 25.2686],
+            [98.1738, 25.4004],
+            [98.1738, 25.6201],
+            [98.3496, 25.5762],
+            [98.5254, 25.8398],
+            [98.7012, 25.8838],
+            [98.6133, 26.0596],
+            [98.7012, 26.1475],
+            [98.7891, 26.5869],
+            [98.7012, 27.5098],
+            [98.5254, 27.6416],
+            [98.3496, 27.5098],
+            [98.1738, 28.125],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'guang_xi',
+      properties: { name: '广西', cp: [108.2813, 23.6426], childNum: 14 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [104.502, 24.7412],
+            [104.6777, 24.6094],
+            [105.2051, 24.9609],
+            [105.9961, 24.6533],
+            [106.1719, 24.7852],
+            [106.1719, 24.9609],
+            [106.875, 25.1807],
+            [107.0508, 25.2686],
+            [106.9629, 25.4883],
+            [107.2266, 25.6201],
+            [107.4902, 25.2246],
+            [107.7539, 25.2246],
+            [107.8418, 25.1367],
+            [108.1055, 25.2246],
+            [108.1934, 25.4443],
+            [108.3691, 25.5322],
+            [108.6328, 25.3125],
+            [108.6328, 25.5762],
+            [109.0723, 25.5322],
+            [108.9844, 25.752],
+            [109.3359, 25.708],
+            [109.5117, 26.0156],
+            [109.7754, 25.8838],
+            [109.9512, 26.1914],
+            [110.2148, 25.9717],
+            [110.5664, 26.3232],
+            [111.1816, 26.3232],
+            [111.2695, 26.2354],
+            [111.2695, 25.8838],
+            [111.4453, 25.8398],
+            [111.0059, 25.0049],
+            [111.0938, 24.9609],
+            [111.3574, 25.1367],
+            [111.5332, 24.6533],
+            [111.709, 24.7852],
+            [112.0605, 24.7412],
+            [111.8848, 24.6533],
+            [112.0605, 24.3457],
+            [111.8848, 24.2139],
+            [111.8848, 23.9941],
+            [111.7969, 23.8184],
+            [111.6211, 23.8184],
+            [111.6211, 23.6865],
+            [111.3574, 23.4668],
+            [111.4453, 23.0273],
+            [111.2695, 22.8076],
+            [110.7422, 22.5439],
+            [110.7422, 22.2803],
+            [110.6543, 22.1484],
+            [110.3027, 22.1484],
+            [110.3027, 21.8848],
+            [109.9512, 21.8408],
+            [109.8633, 21.665],
+            [109.7754, 21.6211],
+            [109.7754, 21.4014],
+            [109.5996, 21.4453],
+            [109.1602, 21.3574],
+            [109.248, 20.874],
+            [109.0723, 20.9619],
+            [109.0723, 21.5332],
+            [108.7207, 21.5332],
+            [108.6328, 21.665],
+            [108.2813, 21.4893],
+            [107.8418, 21.6211],
+            [107.4023, 21.6211],
+            [107.0508, 21.7969],
+            [107.0508, 21.9287],
+            [106.6992, 22.0166],
+            [106.6113, 22.4121],
+            [106.7871, 22.7637],
+            [106.6992, 22.8955],
+            [105.9082, 22.9395],
+            [105.5566, 23.0713],
+            [105.5566, 23.2031],
+            [105.6445, 23.4229],
+            [106.1719, 23.5547],
+            [106.1719, 23.8184],
+            [105.9961, 24.126],
+            [105.5566, 24.126],
+            [105.4688, 24.0381],
+            [105.2051, 24.082],
+            [105.0293, 24.4336],
+            [104.7656, 24.4775],
+            [104.6777, 24.3457],
+            [104.502, 24.7412],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'hu_nan',
+      properties: { name: '湖南', cp: [111.5332, 27.3779], childNum: 14 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [109.248, 28.4766],
+            [109.248, 29.1357],
+            [109.5117, 29.6191],
+            [109.6875, 29.6191],
+            [109.7754, 29.751],
+            [110.4785, 29.6631],
+            [110.6543, 29.751],
+            [110.4785, 30.0146],
+            [110.8301, 30.1465],
+            [111.7969, 29.9268],
+            [112.2363, 29.5313],
+            [112.5, 29.6191],
+            [112.6758, 29.5752],
+            [112.9395, 29.7949],
+            [113.0273, 29.751],
+            [112.9395, 29.4873],
+            [113.0273, 29.4434],
+            [113.5547, 29.8389],
+            [113.5547, 29.707],
+            [113.7305, 29.5752],
+            [113.6426, 29.3115],
+            [113.7305, 29.0918],
+            [113.9063, 29.0479],
+            [114.1699, 28.8281],
+            [114.082, 28.5645],
+            [114.2578, 28.3447],
+            [113.7305, 27.9492],
+            [113.6426, 27.5977],
+            [113.6426, 27.3779],
+            [113.8184, 27.29],
+            [113.7305, 27.1143],
+            [113.9063, 26.9385],
+            [113.9063, 26.6309],
+            [114.082, 26.5869],
+            [113.9941, 26.1914],
+            [114.2578, 26.1475],
+            [113.9941, 26.0596],
+            [113.9063, 25.4443],
+            [113.6426, 25.3125],
+            [113.2031, 25.5322],
+            [112.8516, 25.3564],
+            [113.0273, 25.2246],
+            [113.0273, 24.9609],
+            [112.8516, 24.917],
+            [112.5879, 25.1367],
+            [112.2363, 25.1807],
+            [112.1484, 24.873],
+            [112.0605, 24.7412],
+            [111.709, 24.7852],
+            [111.5332, 24.6533],
+            [111.3574, 25.1367],
+            [111.0938, 24.9609],
+            [111.0059, 25.0049],
+            [111.4453, 25.8398],
+            [111.2695, 25.8838],
+            [111.2695, 26.2354],
+            [111.1816, 26.3232],
+            [110.5664, 26.3232],
+            [110.2148, 25.9717],
+            [109.9512, 26.1914],
+            [109.7754, 25.8838],
+            [109.5117, 26.0156],
+            [109.4238, 26.2793],
+            [109.248, 26.3232],
+            [109.4238, 26.5869],
+            [109.3359, 26.7188],
+            [109.5117, 26.8066],
+            [109.5117, 27.0264],
+            [109.3359, 27.1582],
+            [108.8965, 27.0264],
+            [108.8086, 27.1143],
+            [109.4238, 27.5977],
+            [109.3359, 27.9053],
+            [109.3359, 28.2568],
+            [109.248, 28.4766],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'shan_xi_1',
+      properties: { name: '陕西', cp: [109.5996, 35.6396], childNum: 10 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [105.4688, 32.915],
+            [105.9082, 33.0029],
+            [105.9961, 33.1787],
+            [105.7324, 33.3984],
+            [105.9961, 33.6182],
+            [106.5234, 33.5303],
+            [106.4355, 33.9258],
+            [106.6113, 34.1455],
+            [106.5234, 34.2773],
+            [106.6992, 34.3213],
+            [106.3477, 34.585],
+            [106.5234, 34.7607],
+            [106.6113, 35.0684],
+            [106.9629, 35.0684],
+            [107.2266, 34.8926],
+            [107.666, 34.9365],
+            [107.8418, 35.0244],
+            [107.7539, 35.1123],
+            [107.7539, 35.2881],
+            [108.5449, 35.2881],
+            [108.6328, 35.5518],
+            [108.5449, 35.8594],
+            [108.6328, 35.9912],
+            [108.7207, 36.3428],
+            [107.3145, 36.9141],
+            [107.3145, 37.0898],
+            [107.3145, 37.6172],
+            [107.666, 37.8809],
+            [108.1934, 37.6172],
+            [108.7207, 37.7051],
+            [108.8086, 38.0127],
+            [108.8965, 37.9688],
+            [109.0723, 38.0127],
+            [108.9844, 38.3203],
+            [109.9512, 39.1553],
+            [109.8633, 39.2432],
+            [110.2148, 39.2871],
+            [110.127, 39.4629],
+            [110.6543, 39.2871],
+            [111.0938, 39.5947],
+            [111.0938, 39.375],
+            [111.1816, 39.2432],
+            [110.918, 38.7158],
+            [110.8301, 38.4961],
+            [110.4785, 38.1885],
+            [110.4785, 37.9688],
+            [110.8301, 37.6611],
+            [110.3906, 37.002],
+            [110.4785, 36.123],
+            [110.5664, 35.6396],
+            [110.2148, 34.8926],
+            [110.2148, 34.6729],
+            [110.3906, 34.585],
+            [110.4785, 34.2334],
+            [110.6543, 34.1455],
+            [110.6543, 33.8379],
+            [111.0059, 33.5303],
+            [111.0059, 33.2666],
+            [110.7422, 33.1348],
+            [110.5664, 33.2666],
+            [110.3027, 33.1787],
+            [109.5996, 33.2666],
+            [109.4238, 33.1348],
+            [109.7754, 33.0469],
+            [109.7754, 32.915],
+            [110.127, 32.7393],
+            [110.127, 32.6074],
+            [109.6875, 32.6074],
+            [109.5117, 32.4316],
+            [109.5996, 31.7285],
+            [109.248, 31.7285],
+            [109.0723, 31.9482],
+            [108.5449, 32.2119],
+            [108.2813, 32.2559],
+            [108.0176, 32.168],
+            [107.4023, 32.5195],
+            [107.2266, 32.4316],
+            [107.1387, 32.4756],
+            [107.0508, 32.6953],
+            [106.3477, 32.6514],
+            [106.084, 32.7393],
+            [106.084, 32.8711],
+            [105.5566, 32.7393],
+            [105.4688, 32.915],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'guang_dong',
+      properties: { name: '广东', cp: [113.4668, 22.8076], childNum: 21 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [109.7754, 21.4014],
+            [109.7754, 21.6211],
+            [109.8633, 21.665],
+            [109.9512, 21.8408],
+            [110.3027, 21.8848],
+            [110.3027, 22.1484],
+            [110.6543, 22.1484],
+            [110.7422, 22.2803],
+            [110.7422, 22.5439],
+            [111.2695, 22.8076],
+            [111.4453, 23.0273],
+            [111.3574, 23.4668],
+            [111.6211, 23.6865],
+            [111.6211, 23.8184],
+            [111.7969, 23.8184],
+            [111.8848, 23.9941],
+            [111.8848, 24.2139],
+            [112.0605, 24.3457],
+            [111.8848, 24.6533],
+            [112.0605, 24.7412],
+            [112.1484, 24.873],
+            [112.2363, 25.1807],
+            [112.5879, 25.1367],
+            [112.8516, 24.917],
+            [113.0273, 24.9609],
+            [113.0273, 25.2246],
+            [112.8516, 25.3564],
+            [113.2031, 25.5322],
+            [113.6426, 25.3125],
+            [113.9063, 25.4443],
+            [113.9941, 25.2686],
+            [114.6094, 25.4004],
+            [114.7852, 25.2686],
+            [114.6973, 25.1367],
+            [114.4336, 24.9609],
+            [114.1699, 24.6973],
+            [114.4336, 24.5215],
+            [115.4004, 24.7852],
+            [115.8398, 24.5654],
+            [115.752, 24.7852],
+            [115.9277, 24.917],
+            [116.2793, 24.7852],
+            [116.3672, 24.873],
+            [116.543, 24.6094],
+            [116.7188, 24.6533],
+            [116.9824, 24.1699],
+            [116.9824, 23.9063],
+            [117.1582, 23.5547],
+            [117.334, 23.2471],
+            [116.8945, 23.3789],
+            [116.6309, 23.1152],
+            [116.543, 22.8516],
+            [115.9277, 22.7197],
+            [115.6641, 22.7637],
+            [115.5762, 22.6318],
+            [115.0488, 22.6758],
+            [114.6094, 22.3682],
+            [114.3457, 22.5439],
+            [113.9941, 22.5],
+            [113.8184, 22.1924],
+            [114.3457, 22.1484],
+            [114.4336, 22.0166],
+            [114.082, 21.9287],
+            [113.9941, 21.7969],
+            [113.5547, 22.0166],
+            [113.1152, 21.8408],
+            [112.9395, 21.5771],
+            [112.4121, 21.4453],
+            [112.2363, 21.5332],
+            [111.5332, 21.4893],
+            [111.2695, 21.3574],
+            [110.7422, 21.3574],
+            [110.6543, 21.2256],
+            [110.7422, 20.918],
+            [110.4785, 20.874],
+            [110.6543, 20.2588],
+            [110.5664, 20.2588],
+            [110.3906, 20.127],
+            [110.0391, 20.127],
+            [109.8633, 20.127],
+            [109.8633, 20.3027],
+            [109.5996, 20.918],
+            [109.7754, 21.4014],
+            [109.7754, 21.4014],
+          ],
+          [
+            [113.5986, 22.1649],
+            [113.6096, 22.1265],
+            [113.5547, 22.11],
+            [113.5437, 22.2034],
+            [113.5767, 22.2034],
+            [113.5986, 22.1649],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'ji_lin',
+      properties: { name: '吉林', cp: [126.4746, 43.5938], childNum: 9 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [123.2227, 46.2305],
+            [123.9258, 46.2305],
+            [124.0137, 45.7471],
+            [124.3652, 45.4395],
+            [124.8926, 45.5273],
+            [125.0684, 45.3955],
+            [125.6836, 45.5273],
+            [125.7715, 45.3076],
+            [126.0352, 45.1758],
+            [126.5625, 45.2637],
+            [126.9141, 45.1318],
+            [127.0898, 45],
+            [127.002, 44.7803],
+            [127.0898, 44.6045],
+            [127.5293, 44.6045],
+            [127.7051, 44.1211],
+            [128.0566, 44.1211],
+            [128.0566, 44.3408],
+            [128.4082, 44.4727],
+            [128.4961, 44.165],
+            [128.8477, 43.5498],
+            [129.1992, 43.5938],
+            [129.2871, 43.8135],
+            [129.8145, 43.9014],
+            [129.9023, 44.0332],
+            [129.9902, 43.8574],
+            [130.3418, 43.9893],
+            [130.5176, 43.6377],
+            [130.8691, 43.418],
+            [131.3086, 43.4619],
+            [131.3086, 43.3301],
+            [131.1328, 42.9346],
+            [130.4297, 42.7148],
+            [130.6055, 42.6709],
+            [130.6055, 42.4512],
+            [130.2539, 42.7588],
+            [130.2539, 42.8906],
+            [130.166, 42.9785],
+            [129.9023, 43.0225],
+            [129.7266, 42.4951],
+            [129.375, 42.4512],
+            [128.9355, 42.0117],
+            [128.0566, 42.0117],
+            [128.3203, 41.5723],
+            [128.1445, 41.3525],
+            [127.0898, 41.5283],
+            [127.1777, 41.5723],
+            [126.9141, 41.792],
+            [126.6504, 41.6602],
+            [126.4746, 41.3965],
+            [126.123, 40.957],
+            [125.6836, 40.8691],
+            [125.5957, 40.9131],
+            [125.7715, 41.2207],
+            [125.332, 41.6602],
+            [125.332, 41.9678],
+            [125.4199, 42.0996],
+            [125.332, 42.1436],
+            [124.8926, 42.8027],
+            [124.8926, 43.0664],
+            [124.7168, 43.0664],
+            [124.4531, 42.8467],
+            [124.2773, 43.2422],
+            [123.8379, 43.4619],
+            [123.6621, 43.374],
+            [123.3105, 43.5059],
+            [123.4863, 43.7256],
+            [123.1348, 44.4727],
+            [122.3438, 44.2529],
+            [122.0801, 44.8682],
+            [122.2559, 45.2637],
+            [121.9043, 45.7031],
+            [121.7285, 45.7471],
+            [121.8164, 46.0107],
+            [122.2559, 45.791],
+            [122.4316, 45.8789],
+            [122.6953, 45.7031],
+            [122.7832, 46.0107],
+            [123.2227, 46.2305],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'he_bei',
+      properties: { name: '河北', cp: [115.4004, 37.9688], childNum: 11 },
+      geometry: {
+        type: 'MultiPolygon',
+        coordinates: [
+          [
+            [
+              [114.5215, 39.5068],
+              [114.3457, 39.8584],
+              [113.9941, 39.9902],
+              [114.5215, 40.3418],
+              [114.3457, 40.3857],
+              [114.2578, 40.6055],
+              [114.082, 40.7373],
+              [113.9063, 41.1328],
+              [113.9941, 41.2207],
+              [113.9063, 41.4404],
+              [114.2578, 41.5723],
+              [114.1699, 41.792],
+              [114.5215, 42.1436],
+              [114.873, 42.0996],
+              [114.9609, 41.6162],
+              [115.2246, 41.5723],
+              [115.9277, 41.9238],
+              [116.0156, 41.792],
+              [116.2793, 42.0117],
+              [116.8066, 42.0117],
+              [116.8945, 42.4072],
+              [117.334, 42.4512],
+              [117.5098, 42.583],
+              [117.7734, 42.627],
+              [118.0371, 42.4072],
+              [117.9492, 42.2314],
+              [118.125, 42.0557],
+              [118.3008, 42.0996],
+              [118.3008, 41.792],
+              [118.125, 41.748],
+              [118.3887, 41.3086],
+              [119.2676, 41.3086],
+              [118.8281, 40.8252],
+              [119.2676, 40.5176],
+              [119.5313, 40.5615],
+              [119.707, 40.1221],
+              [119.8828, 39.9463],
+              [119.5313, 39.6826],
+              [119.4434, 39.4189],
+              [118.916, 39.0674],
+              [118.4766, 38.9355],
+              [118.125, 39.0234],
+              [118.0371, 39.1992],
+              [118.0371, 39.2432],
+              [117.8613, 39.4189],
+              [117.9492, 39.5947],
+              [117.6855, 39.5947],
+              [117.5098, 39.7705],
+              [117.5098, 39.9902],
+              [117.6855, 39.9902],
+              [117.6855, 40.0781],
+              [117.4219, 40.21],
+              [117.2461, 40.5176],
+              [117.4219, 40.6494],
+              [116.9824, 40.6934],
+              [116.6309, 41.0449],
+              [116.3672, 40.9131],
+              [116.4551, 40.7813],
+              [116.1914, 40.7813],
+              [116.1035, 40.6055],
+              [115.752, 40.5615],
+              [115.9277, 40.2539],
+              [115.4004, 39.9463],
+              [115.4883, 39.6387],
+              [115.752, 39.5068],
+              [116.1914, 39.5947],
+              [116.3672, 39.4629],
+              [116.543, 39.5947],
+              [116.8066, 39.5947],
+              [116.8945, 39.1113],
+              [116.7188, 38.9355],
+              [116.7188, 38.8037],
+              [117.2461, 38.54],
+              [117.5977, 38.6279],
+              [117.9492, 38.3203],
+              [117.4219, 37.8369],
+              [116.8066, 37.8369],
+              [116.4551, 37.4854],
+              [116.2793, 37.5732],
+              [116.2793, 37.3535],
+              [116.0156, 37.3535],
+              [115.752, 36.9141],
+              [115.3125, 36.5186],
+              [115.4883, 36.167],
+              [115.3125, 36.0791],
+              [115.1367, 36.2109],
+              [114.9609, 36.0791],
+              [114.873, 36.123],
+              [113.7305, 36.3428],
+              [113.4668, 36.6504],
+              [113.7305, 36.8701],
+              [113.7305, 37.1338],
+              [114.1699, 37.6611],
+              [113.9941, 37.7051],
+              [113.8184, 38.1445],
+              [113.5547, 38.2764],
+              [113.5547, 38.54],
+              [113.8184, 38.8037],
+              [113.8184, 38.9355],
+              [113.9063, 39.0234],
+              [114.3457, 39.0674],
+              [114.5215, 39.5068],
+            ],
+          ],
+          [
+            [
+              [117.2461, 40.0781],
+              [117.1582, 39.8145],
+              [117.1582, 39.6387],
+              [116.8945, 39.6826],
+              [116.8945, 39.8145],
+              [116.8066, 39.9902],
+              [117.2461, 40.0781],
+            ],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'hu_bei',
+      properties: { name: '湖北', cp: [112.2363, 31.1572], childNum: 17 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [110.2148, 31.1572],
+            [110.127, 31.377],
+            [109.6875, 31.5527],
+            [109.7754, 31.6846],
+            [109.5996, 31.7285],
+            [109.5117, 32.4316],
+            [109.6875, 32.6074],
+            [110.127, 32.6074],
+            [110.127, 32.7393],
+            [109.7754, 32.915],
+            [109.7754, 33.0469],
+            [109.4238, 33.1348],
+            [109.5996, 33.2666],
+            [110.3027, 33.1787],
+            [110.5664, 33.2666],
+            [110.7422, 33.1348],
+            [111.0059, 33.2666],
+            [111.5332, 32.6074],
+            [112.3242, 32.3438],
+            [113.2031, 32.4316],
+            [113.4668, 32.2998],
+            [113.7305, 32.4316],
+            [113.8184, 31.8604],
+            [113.9941, 31.7725],
+            [114.1699, 31.8604],
+            [114.5215, 31.7725],
+            [114.6094, 31.5527],
+            [114.7852, 31.4648],
+            [115.1367, 31.5967],
+            [115.2246, 31.4209],
+            [115.4004, 31.4209],
+            [115.5762, 31.2012],
+            [116.0156, 31.0254],
+            [115.752, 30.6738],
+            [116.1035, 30.1904],
+            [116.1035, 29.8389],
+            [115.9277, 29.707],
+            [115.4883, 29.7949],
+            [114.873, 29.3994],
+            [114.2578, 29.3555],
+            [113.9063, 29.0479],
+            [113.7305, 29.0918],
+            [113.6426, 29.3115],
+            [113.7305, 29.5752],
+            [113.5547, 29.707],
+            [113.5547, 29.8389],
+            [113.0273, 29.4434],
+            [112.9395, 29.4873],
+            [113.0273, 29.751],
+            [112.9395, 29.7949],
+            [112.6758, 29.5752],
+            [112.5, 29.6191],
+            [112.2363, 29.5313],
+            [111.7969, 29.9268],
+            [110.8301, 30.1465],
+            [110.4785, 30.0146],
+            [110.6543, 29.751],
+            [110.4785, 29.6631],
+            [109.7754, 29.751],
+            [109.6875, 29.6191],
+            [109.5117, 29.6191],
+            [109.248, 29.1357],
+            [109.0723, 29.3555],
+            [108.9844, 29.3115],
+            [108.6328, 29.8389],
+            [108.457, 29.7949],
+            [108.5449, 30.2344],
+            [108.457, 30.4102],
+            [108.6328, 30.5859],
+            [108.8086, 30.498],
+            [109.0723, 30.6299],
+            [109.1602, 30.542],
+            [109.248, 30.6299],
+            [109.4238, 30.542],
+            [109.8633, 30.8936],
+            [110.0391, 30.8057],
+            [110.2148, 31.1572],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'gui_zhou',
+      properties: { name: '贵州', cp: [106.6113, 26.9385], childNum: 9 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [104.1504, 27.2461],
+            [104.4141, 27.4658],
+            [104.5898, 27.334],
+            [105.2051, 27.3779],
+            [105.293, 27.7295],
+            [105.5566, 27.7734],
+            [105.6445, 27.6416],
+            [106.3477, 27.8174],
+            [106.1719, 28.125],
+            [105.9082, 28.125],
+            [105.6445, 28.4326],
+            [105.9961, 28.7402],
+            [106.3477, 28.5205],
+            [106.5234, 28.5645],
+            [106.4355, 28.7842],
+            [106.5234, 28.7842],
+            [106.6113, 28.6523],
+            [106.6113, 28.5205],
+            [106.6992, 28.4766],
+            [106.875, 28.7842],
+            [107.4023, 28.8721],
+            [107.4023, 29.1797],
+            [107.5781, 29.2236],
+            [107.8418, 29.1357],
+            [107.8418, 29.0039],
+            [108.2813, 29.0918],
+            [108.3691, 28.6523],
+            [108.5449, 28.6523],
+            [108.5449, 28.3887],
+            [108.7207, 28.4766],
+            [108.7207, 28.2129],
+            [109.0723, 28.2129],
+            [109.248, 28.4766],
+            [109.3359, 28.2568],
+            [109.3359, 27.9053],
+            [109.4238, 27.5977],
+            [108.8086, 27.1143],
+            [108.8965, 27.0264],
+            [109.3359, 27.1582],
+            [109.5117, 27.0264],
+            [109.5117, 26.8066],
+            [109.3359, 26.7188],
+            [109.4238, 26.5869],
+            [109.248, 26.3232],
+            [109.4238, 26.2793],
+            [109.5117, 26.0156],
+            [109.3359, 25.708],
+            [108.9844, 25.752],
+            [109.0723, 25.5322],
+            [108.6328, 25.5762],
+            [108.6328, 25.3125],
+            [108.3691, 25.5322],
+            [108.1934, 25.4443],
+            [108.1055, 25.2246],
+            [107.8418, 25.1367],
+            [107.7539, 25.2246],
+            [107.4902, 25.2246],
+            [107.2266, 25.6201],
+            [106.9629, 25.4883],
+            [107.0508, 25.2686],
+            [106.875, 25.1807],
+            [106.1719, 24.9609],
+            [106.1719, 24.7852],
+            [105.9961, 24.6533],
+            [105.2051, 24.9609],
+            [104.6777, 24.6094],
+            [104.502, 24.7412],
+            [104.6777, 24.9609],
+            [104.5898, 25.0488],
+            [104.8535, 25.2246],
+            [104.3262, 25.708],
+            [104.6777, 26.4111],
+            [104.4141, 26.6748],
+            [103.8867, 26.543],
+            [103.7109, 26.7627],
+            [103.7109, 26.9824],
+            [103.623, 27.0264],
+            [103.8867, 27.4219],
+            [104.1504, 27.2461],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'shan_dong',
+      properties: { name: '山东', cp: [118.7402, 36.4307], childNum: 17 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [115.4883, 36.167],
+            [115.3125, 36.5186],
+            [115.752, 36.9141],
+            [116.0156, 37.3535],
+            [116.2793, 37.3535],
+            [116.2793, 37.5732],
+            [116.4551, 37.4854],
+            [116.8066, 37.8369],
+            [117.4219, 37.8369],
+            [117.9492, 38.3203],
+            [118.125, 38.1445],
+            [118.916, 38.1445],
+            [119.3555, 37.6611],
+            [119.0039, 37.5293],
+            [119.0039, 37.3535],
+            [119.3555, 37.1338],
+            [119.707, 37.1338],
+            [119.8828, 37.3975],
+            [120.498, 37.8369],
+            [120.5859, 38.1445],
+            [120.9375, 38.4521],
+            [121.0254, 37.8369],
+            [121.2012, 37.6611],
+            [121.9043, 37.4854],
+            [122.168, 37.6172],
+            [122.2559, 37.4854],
+            [122.6074, 37.4854],
+            [122.6953, 37.3535],
+            [122.6074, 36.9141],
+            [122.4316, 36.7822],
+            [121.8164, 36.8701],
+            [121.7285, 36.6943],
+            [121.1133, 36.6064],
+            [121.1133, 36.4307],
+            [121.377, 36.2549],
+            [120.7617, 36.167],
+            [120.9375, 35.8594],
+            [120.6738, 36.0352],
+            [119.707, 35.4639],
+            [119.9707, 34.9805],
+            [119.3555, 35.0244],
+            [119.2676, 35.1123],
+            [118.916, 35.0244],
+            [118.7402, 34.7168],
+            [118.4766, 34.6729],
+            [118.3887, 34.4092],
+            [118.2129, 34.4092],
+            [118.125, 34.6289],
+            [117.9492, 34.6729],
+            [117.5977, 34.4531],
+            [117.334, 34.585],
+            [117.2461, 34.4531],
+            [116.8066, 34.9365],
+            [116.4551, 34.8926],
+            [116.3672, 34.6289],
+            [116.1914, 34.585],
+            [115.5762, 34.585],
+            [115.4004, 34.8486],
+            [114.7852, 35.0684],
+            [115.0488, 35.376],
+            [115.2246, 35.4199],
+            [115.4883, 35.7275],
+            [116.1035, 36.0791],
+            [115.3125, 35.8154],
+            [115.4883, 36.167],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'jiang_xi',
+      properties: { name: '江西', cp: [116.0156, 27.29], childNum: 11 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [114.2578, 28.3447],
+            [114.082, 28.5645],
+            [114.1699, 28.8281],
+            [113.9063, 29.0479],
+            [114.2578, 29.3555],
+            [114.873, 29.3994],
+            [115.4883, 29.7949],
+            [115.9277, 29.707],
+            [116.1035, 29.8389],
+            [116.2793, 29.7949],
+            [116.7188, 30.0586],
+            [116.8945, 29.9268],
+            [116.7188, 29.751],
+            [116.7188, 29.6191],
+            [117.1582, 29.707],
+            [117.0703, 29.8389],
+            [117.1582, 29.9268],
+            [117.5098, 29.6191],
+            [118.0371, 29.5752],
+            [118.2129, 29.3994],
+            [118.0371, 29.1797],
+            [118.0371, 29.0479],
+            [118.3887, 28.7842],
+            [118.4766, 28.3447],
+            [118.4766, 28.3008],
+            [118.3008, 28.0811],
+            [117.7734, 27.8174],
+            [117.5098, 27.9932],
+            [116.9824, 27.6416],
+            [117.1582, 27.29],
+            [117.0703, 27.1143],
+            [116.543, 26.8066],
+            [116.6309, 26.4551],
+            [116.3672, 26.2354],
+            [116.4551, 26.1035],
+            [116.1914, 25.8838],
+            [116.0156, 25.2686],
+            [115.8398, 25.2246],
+            [115.9277, 24.917],
+            [115.752, 24.7852],
+            [115.8398, 24.5654],
+            [115.4004, 24.7852],
+            [114.4336, 24.5215],
+            [114.1699, 24.6973],
+            [114.4336, 24.9609],
+            [114.6973, 25.1367],
+            [114.7852, 25.2686],
+            [114.6094, 25.4004],
+            [113.9941, 25.2686],
+            [113.9063, 25.4443],
+            [113.9941, 26.0596],
+            [114.2578, 26.1475],
+            [113.9941, 26.1914],
+            [114.082, 26.5869],
+            [113.9063, 26.6309],
+            [113.9063, 26.9385],
+            [113.7305, 27.1143],
+            [113.8184, 27.29],
+            [113.6426, 27.3779],
+            [113.6426, 27.5977],
+            [113.7305, 27.9492],
+            [114.2578, 28.3447],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'he_nan',
+      properties: { name: '河南', cp: [113.4668, 33.8818], childNum: 17 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [110.3906, 34.585],
+            [110.8301, 34.6289],
+            [111.1816, 34.8047],
+            [111.5332, 34.8486],
+            [111.7969, 35.0684],
+            [112.0605, 35.0684],
+            [112.0605, 35.2881],
+            [112.7637, 35.2002],
+            [113.1152, 35.332],
+            [113.6426, 35.6836],
+            [113.7305, 36.3428],
+            [114.873, 36.123],
+            [114.9609, 36.0791],
+            [115.1367, 36.2109],
+            [115.3125, 36.0791],
+            [115.4883, 36.167],
+            [115.3125, 35.8154],
+            [116.1035, 36.0791],
+            [115.4883, 35.7275],
+            [115.2246, 35.4199],
+            [115.0488, 35.376],
+            [114.7852, 35.0684],
+            [115.4004, 34.8486],
+            [115.5762, 34.585],
+            [116.1914, 34.585],
+            [116.1914, 34.4092],
+            [116.543, 34.2773],
+            [116.6309, 33.9258],
+            [116.1914, 33.7061],
+            [116.0156, 33.9697],
+            [115.6641, 34.0576],
+            [115.5762, 33.9258],
+            [115.5762, 33.6621],
+            [115.4004, 33.5303],
+            [115.3125, 33.1787],
+            [114.873, 33.1348],
+            [114.873, 33.0029],
+            [115.1367, 32.8711],
+            [115.2246, 32.6074],
+            [115.5762, 32.4316],
+            [115.8398, 32.5195],
+            [115.9277, 31.7725],
+            [115.4883, 31.6846],
+            [115.4004, 31.4209],
+            [115.2246, 31.4209],
+            [115.1367, 31.5967],
+            [114.7852, 31.4648],
+            [114.6094, 31.5527],
+            [114.5215, 31.7725],
+            [114.1699, 31.8604],
+            [113.9941, 31.7725],
+            [113.8184, 31.8604],
+            [113.7305, 32.4316],
+            [113.4668, 32.2998],
+            [113.2031, 32.4316],
+            [112.3242, 32.3438],
+            [111.5332, 32.6074],
+            [111.0059, 33.2666],
+            [111.0059, 33.5303],
+            [110.6543, 33.8379],
+            [110.6543, 34.1455],
+            [110.4785, 34.2334],
+            [110.3906, 34.585],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'liao_ning',
+      properties: { name: '辽宁', cp: [122.3438, 41.0889], childNum: 14 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [119.2676, 41.3086],
+            [119.4434, 41.6162],
+            [119.2676, 41.7041],
+            [119.3555, 42.2754],
+            [119.5313, 42.3633],
+            [119.8828, 42.1875],
+            [120.1465, 41.7041],
+            [120.498, 42.0996],
+            [121.4648, 42.4951],
+            [121.7285, 42.4512],
+            [121.9922, 42.7148],
+            [122.3438, 42.6709],
+            [122.3438, 42.8467],
+            [122.7832, 42.7148],
+            [123.1348, 42.8027],
+            [123.3105, 42.9785],
+            [123.5742, 43.0225],
+            [123.6621, 43.374],
+            [123.8379, 43.4619],
+            [124.2773, 43.2422],
+            [124.4531, 42.8467],
+            [124.7168, 43.0664],
+            [124.8926, 43.0664],
+            [124.8926, 42.8027],
+            [125.332, 42.1436],
+            [125.4199, 42.0996],
+            [125.332, 41.9678],
+            [125.332, 41.6602],
+            [125.7715, 41.2207],
+            [125.5957, 40.9131],
+            [125.6836, 40.8691],
+            [124.541, 40.21],
+            [124.1016, 39.6826],
+            [123.3984, 39.6826],
+            [123.1348, 39.4189],
+            [123.1348, 39.0234],
+            [122.0801, 39.0234],
+            [121.5527, 38.7158],
+            [121.1133, 38.6719],
+            [120.9375, 38.9795],
+            [121.377, 39.1992],
+            [121.2012, 39.5508],
+            [122.0801, 40.3857],
+            [121.9922, 40.6934],
+            [121.7285, 40.8252],
+            [121.2012, 40.8252],
+            [120.5859, 40.21],
+            [119.8828, 39.9463],
+            [119.707, 40.1221],
+            [119.5313, 40.5615],
+            [119.2676, 40.5176],
+            [118.8281, 40.8252],
+            [119.2676, 41.3086],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'shan_xi_2',
+      properties: { name: '山西', cp: [112.4121, 37.6611], childNum: 11 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [110.918, 38.7158],
+            [111.1816, 39.2432],
+            [111.0938, 39.375],
+            [111.3574, 39.4189],
+            [111.4453, 39.6387],
+            [111.9727, 39.5947],
+            [112.3242, 40.2539],
+            [112.7637, 40.166],
+            [113.2031, 40.3857],
+            [113.5547, 40.3418],
+            [113.8184, 40.5176],
+            [114.082, 40.5176],
+            [114.082, 40.7373],
+            [114.2578, 40.6055],
+            [114.3457, 40.3857],
+            [114.5215, 40.3418],
+            [113.9941, 39.9902],
+            [114.3457, 39.8584],
+            [114.5215, 39.5068],
+            [114.3457, 39.0674],
+            [113.9063, 39.0234],
+            [113.8184, 38.9355],
+            [113.8184, 38.8037],
+            [113.5547, 38.54],
+            [113.5547, 38.2764],
+            [113.8184, 38.1445],
+            [113.9941, 37.7051],
+            [114.1699, 37.6611],
+            [113.7305, 37.1338],
+            [113.7305, 36.8701],
+            [113.4668, 36.6504],
+            [113.7305, 36.3428],
+            [113.6426, 35.6836],
+            [113.1152, 35.332],
+            [112.7637, 35.2002],
+            [112.0605, 35.2881],
+            [112.0605, 35.0684],
+            [111.7969, 35.0684],
+            [111.5332, 34.8486],
+            [111.1816, 34.8047],
+            [110.8301, 34.6289],
+            [110.3906, 34.585],
+            [110.2148, 34.6729],
+            [110.2148, 34.8926],
+            [110.5664, 35.6396],
+            [110.4785, 36.123],
+            [110.3906, 37.002],
+            [110.8301, 37.6611],
+            [110.4785, 37.9688],
+            [110.4785, 38.1885],
+            [110.8301, 38.4961],
+            [110.918, 38.7158],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'an_hui',
+      properties: { name: '安徽', cp: [117.2461, 32.0361], childNum: 17 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [116.6309, 33.9258],
+            [116.543, 34.2773],
+            [116.1914, 34.4092],
+            [116.1914, 34.585],
+            [116.3672, 34.6289],
+            [116.8945, 34.4092],
+            [117.1582, 34.0576],
+            [117.5977, 34.0137],
+            [117.7734, 33.7061],
+            [118.125, 33.75],
+            [117.9492, 33.2227],
+            [118.0371, 33.1348],
+            [118.2129, 33.2227],
+            [118.3008, 32.7832],
+            [118.7402, 32.7393],
+            [118.916, 32.959],
+            [119.1797, 32.8271],
+            [119.1797, 32.4756],
+            [118.5645, 32.5635],
+            [118.6523, 32.2119],
+            [118.4766, 32.168],
+            [118.3887, 31.9482],
+            [118.916, 31.5527],
+            [118.7402, 31.377],
+            [118.8281, 31.2451],
+            [119.3555, 31.2891],
+            [119.4434, 31.1572],
+            [119.6191, 31.1133],
+            [119.6191, 31.0693],
+            [119.4434, 30.6738],
+            [119.2676, 30.6299],
+            [119.3555, 30.4102],
+            [118.916, 30.3223],
+            [118.916, 29.9707],
+            [118.7402, 29.707],
+            [118.2129, 29.3994],
+            [118.0371, 29.5752],
+            [117.5098, 29.6191],
+            [117.1582, 29.9268],
+            [117.0703, 29.8389],
+            [117.1582, 29.707],
+            [116.7188, 29.6191],
+            [116.7188, 29.751],
+            [116.8945, 29.9268],
+            [116.7188, 30.0586],
+            [116.2793, 29.7949],
+            [116.1035, 29.8389],
+            [116.1035, 30.1904],
+            [115.752, 30.6738],
+            [116.0156, 31.0254],
+            [115.5762, 31.2012],
+            [115.4004, 31.4209],
+            [115.4883, 31.6846],
+            [115.9277, 31.7725],
+            [115.8398, 32.5195],
+            [115.5762, 32.4316],
+            [115.2246, 32.6074],
+            [115.1367, 32.8711],
+            [114.873, 33.0029],
+            [114.873, 33.1348],
+            [115.3125, 33.1787],
+            [115.4004, 33.5303],
+            [115.5762, 33.6621],
+            [115.5762, 33.9258],
+            [115.6641, 34.0576],
+            [116.0156, 33.9697],
+            [116.1914, 33.7061],
+            [116.6309, 33.9258],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'fu_jian',
+      properties: { name: '福建', cp: [118.3008, 25.9277], childNum: 9 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [118.4766, 28.3008],
+            [118.8281, 28.2568],
+            [118.7402, 28.0371],
+            [118.916, 27.4658],
+            [119.2676, 27.4219],
+            [119.6191, 27.6855],
+            [119.7949, 27.29],
+            [120.2344, 27.4219],
+            [120.4102, 27.1582],
+            [120.7617, 27.0264],
+            [120.6738, 26.8945],
+            [120.2344, 26.8506],
+            [120.2344, 26.7188],
+            [120.4102, 26.6748],
+            [120.498, 26.3672],
+            [120.2344, 26.2793],
+            [120.4102, 26.1475],
+            [120.0586, 26.1914],
+            [119.9707, 25.9277],
+            [119.7949, 25.9277],
+            [119.9707, 25.4004],
+            [119.7949, 25.2686],
+            [119.5313, 25.1367],
+            [119.4434, 25.0049],
+            [119.2676, 25.0928],
+            [118.916, 24.8291],
+            [118.6523, 24.5215],
+            [118.4766, 24.5215],
+            [118.4766, 24.4336],
+            [118.2129, 24.3457],
+            [118.2129, 24.1699],
+            [117.8613, 23.9941],
+            [117.7734, 23.7744],
+            [117.5098, 23.5986],
+            [117.1582, 23.5547],
+            [116.9824, 23.9063],
+            [116.9824, 24.1699],
+            [116.7188, 24.6533],
+            [116.543, 24.6094],
+            [116.3672, 24.873],
+            [116.2793, 24.7852],
+            [115.9277, 24.917],
+            [115.8398, 25.2246],
+            [116.0156, 25.2686],
+            [116.1914, 25.8838],
+            [116.4551, 26.1035],
+            [116.3672, 26.2354],
+            [116.6309, 26.4551],
+            [116.543, 26.8066],
+            [117.0703, 27.1143],
+            [117.1582, 27.29],
+            [116.9824, 27.6416],
+            [117.5098, 27.9932],
+            [117.7734, 27.8174],
+            [118.3008, 28.0811],
+            [118.4766, 28.3008],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'zhe_jiang',
+      properties: { name: '浙江', cp: [120.498, 29.0918], childNum: 11 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [118.2129, 29.3994],
+            [118.7402, 29.707],
+            [118.916, 29.9707],
+            [118.916, 30.3223],
+            [119.3555, 30.4102],
+            [119.2676, 30.6299],
+            [119.4434, 30.6738],
+            [119.6191, 31.0693],
+            [119.6191, 31.1133],
+            [119.9707, 31.1572],
+            [120.498, 30.8057],
+            [120.9375, 31.0254],
+            [121.2891, 30.6738],
+            [121.9922, 30.8057],
+            [122.6953, 30.8936],
+            [122.8711, 30.7178],
+            [122.959, 30.1465],
+            [122.6074, 30.1025],
+            [122.6074, 29.9268],
+            [122.168, 29.5313],
+            [122.3438, 28.8721],
+            [121.9922, 28.8721],
+            [121.9922, 28.4326],
+            [121.7285, 28.3447],
+            [121.7285, 28.2129],
+            [121.4648, 28.2129],
+            [121.5527, 28.0371],
+            [121.2891, 27.9492],
+            [121.1133, 27.4219],
+            [120.6738, 27.334],
+            [120.6738, 27.1582],
+            [120.9375, 27.0264],
+            [120.7617, 27.0264],
+            [120.4102, 27.1582],
+            [120.2344, 27.4219],
+            [119.7949, 27.29],
+            [119.6191, 27.6855],
+            [119.2676, 27.4219],
+            [118.916, 27.4658],
+            [118.7402, 28.0371],
+            [118.8281, 28.2568],
+            [118.4766, 28.3008],
+            [118.4766, 28.3447],
+            [118.3887, 28.7842],
+            [118.0371, 29.0479],
+            [118.0371, 29.1797],
+            [118.2129, 29.3994],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'jiang_su',
+      properties: { name: '江苏', cp: [120.0586, 32.915], childNum: 13 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [116.3672, 34.6289],
+            [116.4551, 34.8926],
+            [116.8066, 34.9365],
+            [117.2461, 34.4531],
+            [117.334, 34.585],
+            [117.5977, 34.4531],
+            [117.9492, 34.6729],
+            [118.125, 34.6289],
+            [118.2129, 34.4092],
+            [118.3887, 34.4092],
+            [118.4766, 34.6729],
+            [118.7402, 34.7168],
+            [118.916, 35.0244],
+            [119.2676, 35.1123],
+            [119.3555, 35.0244],
+            [119.3555, 34.8486],
+            [119.707, 34.585],
+            [120.3223, 34.3652],
+            [120.9375, 33.0469],
+            [121.0254, 32.6514],
+            [121.377, 32.4756],
+            [121.4648, 32.168],
+            [121.9043, 31.9922],
+            [121.9922, 31.6846],
+            [121.9922, 31.5967],
+            [121.2012, 31.8604],
+            [121.1133, 31.7285],
+            [121.377, 31.5088],
+            [121.2012, 31.4648],
+            [120.9375, 31.0254],
+            [120.498, 30.8057],
+            [119.9707, 31.1572],
+            [119.6191, 31.1133],
+            [119.4434, 31.1572],
+            [119.3555, 31.2891],
+            [118.8281, 31.2451],
+            [118.7402, 31.377],
+            [118.916, 31.5527],
+            [118.3887, 31.9482],
+            [118.4766, 32.168],
+            [118.6523, 32.2119],
+            [118.5645, 32.5635],
+            [119.1797, 32.4756],
+            [119.1797, 32.8271],
+            [118.916, 32.959],
+            [118.7402, 32.7393],
+            [118.3008, 32.7832],
+            [118.2129, 33.2227],
+            [118.0371, 33.1348],
+            [117.9492, 33.2227],
+            [118.125, 33.75],
+            [117.7734, 33.7061],
+            [117.5977, 34.0137],
+            [117.1582, 34.0576],
+            [116.8945, 34.4092],
+            [116.3672, 34.6289],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'chong_qing',
+      properties: { name: '重庆', cp: [107.7539, 30.1904], childNum: 40 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [108.5449, 31.6846],
+            [108.2813, 31.9043],
+            [108.3691, 32.168],
+            [108.5449, 32.2119],
+            [109.0723, 31.9482],
+            [109.248, 31.7285],
+            [109.5996, 31.7285],
+            [109.7754, 31.6846],
+            [109.6875, 31.5527],
+            [110.127, 31.377],
+            [110.2148, 31.1572],
+            [110.0391, 30.8057],
+            [109.8633, 30.8936],
+            [109.4238, 30.542],
+            [109.248, 30.6299],
+            [109.1602, 30.542],
+            [109.0723, 30.6299],
+            [108.8086, 30.498],
+            [108.6328, 30.5859],
+            [108.457, 30.4102],
+            [108.5449, 30.2344],
+            [108.457, 29.7949],
+            [108.6328, 29.8389],
+            [108.9844, 29.3115],
+            [109.0723, 29.3555],
+            [109.248, 29.1357],
+            [109.248, 28.4766],
+            [109.0723, 28.2129],
+            [108.7207, 28.2129],
+            [108.7207, 28.4766],
+            [108.5449, 28.3887],
+            [108.5449, 28.6523],
+            [108.3691, 28.6523],
+            [108.2813, 29.0918],
+            [107.8418, 29.0039],
+            [107.8418, 29.1357],
+            [107.5781, 29.2236],
+            [107.4023, 29.1797],
+            [107.4023, 28.8721],
+            [106.875, 28.7842],
+            [106.6992, 28.4766],
+            [106.6113, 28.5205],
+            [106.6113, 28.6523],
+            [106.5234, 28.7842],
+            [106.4355, 28.7842],
+            [106.5234, 28.5645],
+            [106.3477, 28.5205],
+            [106.2598, 28.8721],
+            [105.8203, 28.96],
+            [105.7324, 29.2676],
+            [105.4688, 29.3115],
+            [105.293, 29.5313],
+            [105.7324, 29.8828],
+            [105.5566, 30.1025],
+            [105.6445, 30.2783],
+            [105.8203, 30.4541],
+            [106.2598, 30.1904],
+            [106.6113, 30.3223],
+            [106.7871, 30.0146],
+            [107.0508, 30.0146],
+            [107.4902, 30.6299],
+            [107.4023, 30.7617],
+            [107.4902, 30.8496],
+            [107.9297, 30.8496],
+            [108.1934, 31.5088],
+            [108.5449, 31.6846],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'ning_xia',
+      properties: { name: '宁夏', cp: [105.9961, 37.3096], childNum: 5 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [104.3262, 37.4414],
+            [105.8203, 37.793],
+            [105.9082, 38.7158],
+            [106.3477, 39.2871],
+            [106.7871, 39.375],
+            [106.9629, 38.9795],
+            [106.5234, 38.3203],
+            [106.7871, 38.1885],
+            [107.3145, 38.1006],
+            [107.666, 37.8809],
+            [107.3145, 37.6172],
+            [107.3145, 37.0898],
+            [106.6113, 37.0898],
+            [106.6113, 36.7822],
+            [106.4355, 36.5625],
+            [106.5234, 36.4746],
+            [106.5234, 36.2549],
+            [106.875, 36.123],
+            [106.9629, 35.8154],
+            [106.6992, 35.6836],
+            [106.4355, 35.6836],
+            [106.5234, 35.332],
+            [106.3477, 35.2441],
+            [106.2598, 35.4199],
+            [106.084, 35.376],
+            [105.9961, 35.4199],
+            [106.084, 35.4639],
+            [105.9961, 35.4639],
+            [105.8203, 35.5518],
+            [105.7324, 35.7275],
+            [105.3809, 35.7715],
+            [105.293, 35.9912],
+            [105.4688, 36.123],
+            [105.2051, 36.6943],
+            [105.293, 36.8262],
+            [104.8535, 37.2217],
+            [104.5898, 37.2217],
+            [104.5898, 37.4414],
+            [104.3262, 37.4414],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'hai_nan',
+      properties: { name: '海南', cp: [109.9512, 19.2041], childNum: 18 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [108.6328, 19.3799],
+            [109.0723, 19.6436],
+            [109.248, 19.9512],
+            [109.5996, 20.0391],
+            [110.0391, 20.127],
+            [110.3906, 20.127],
+            [110.5664, 20.2588],
+            [110.6543, 20.2588],
+            [111.0938, 19.9512],
+            [111.2695, 19.9951],
+            [110.6543, 19.1602],
+            [110.5664, 18.6768],
+            [110.2148, 18.5889],
+            [110.0391, 18.3691],
+            [109.8633, 18.3691],
+            [109.6875, 18.1055],
+            [108.9844, 18.2813],
+            [108.6328, 18.457],
+            [108.6328, 19.3799],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'tai_wan',
+      properties: { name: '台湾', cp: [121.0254, 23.5986], childNum: 1 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [121.9043, 25.0488],
+            [121.9922, 25.0049],
+            [121.8164, 24.7412],
+            [121.9043, 24.5654],
+            [121.6406, 24.0381],
+            [121.377, 23.1152],
+            [121.0254, 22.6758],
+            [120.8496, 22.0605],
+            [120.7617, 21.9287],
+            [120.6738, 22.3242],
+            [120.2344, 22.5879],
+            [120.0586, 23.0713],
+            [120.1465, 23.6865],
+            [121.0254, 25.0488],
+            [121.5527, 25.3125],
+            [121.9043, 25.0488],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'bei_jing',
+      properties: { name: '北京', cp: [116.4551, 40.2539], childNum: 19 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [117.4219, 40.21],
+            [117.334, 40.1221],
+            [117.2461, 40.0781],
+            [116.8066, 39.9902],
+            [116.8945, 39.8145],
+            [116.8945, 39.6826],
+            [116.8066, 39.5947],
+            [116.543, 39.5947],
+            [116.3672, 39.4629],
+            [116.1914, 39.5947],
+            [115.752, 39.5068],
+            [115.4883, 39.6387],
+            [115.4004, 39.9463],
+            [115.9277, 40.2539],
+            [115.752, 40.5615],
+            [116.1035, 40.6055],
+            [116.1914, 40.7813],
+            [116.4551, 40.7813],
+            [116.3672, 40.9131],
+            [116.6309, 41.0449],
+            [116.9824, 40.6934],
+            [117.4219, 40.6494],
+            [117.2461, 40.5176],
+            [117.4219, 40.21],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'tian_jin',
+      properties: { name: '天津', cp: [117.4219, 39.4189], childNum: 18 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [116.8066, 39.5947],
+            [116.8945, 39.6826],
+            [117.1582, 39.6387],
+            [117.1582, 39.8145],
+            [117.2461, 40.0781],
+            [117.334, 40.1221],
+            [117.4219, 40.21],
+            [117.6855, 40.0781],
+            [117.6855, 39.9902],
+            [117.5098, 39.9902],
+            [117.5098, 39.7705],
+            [117.6855, 39.5947],
+            [117.9492, 39.5947],
+            [117.8613, 39.4189],
+            [118.0371, 39.2432],
+            [118.0371, 39.1992],
+            [117.8613, 39.1113],
+            [117.5977, 38.6279],
+            [117.2461, 38.54],
+            [116.7188, 38.8037],
+            [116.7188, 38.9355],
+            [116.8945, 39.1113],
+            [116.8066, 39.5947],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'shang_hai',
+      properties: { name: '上海', cp: [121.4648, 31.2891], childNum: 19 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [120.9375, 31.0254],
+            [121.2012, 31.4648],
+            [121.377, 31.5088],
+            [121.1133, 31.7285],
+            [121.2012, 31.8604],
+            [121.9922, 31.5967],
+            [121.9043, 31.1572],
+            [121.9922, 30.8057],
+            [121.2891, 30.6738],
+            [120.9375, 31.0254],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'xiang_gang',
+      properties: { name: '香港', cp: [114.2578, 22.3242], childNum: 1 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [114.6094, 22.4121],
+            [114.5215, 22.1484],
+            [114.3457, 22.1484],
+            [113.9063, 22.1484],
+            [113.8184, 22.1924],
+            [113.9063, 22.4121],
+            [114.1699, 22.5439],
+            [114.3457, 22.5439],
+            [114.4336, 22.5439],
+            [114.4336, 22.4121],
+            [114.6094, 22.4121],
+          ],
+        ],
+      },
+    },
+    {
+      type: 'Feature',
+      id: 'ao_men',
+      properties: { name: '澳门', cp: [113.5547, 22.1484], childNum: 1 },
+      geometry: {
+        type: 'Polygon',
+        coordinates: [
+          [
+            [113.5986, 22.1649],
+            [113.6096, 22.1265],
+            [113.5547, 22.11],
+            [113.5437, 22.2034],
+            [113.5767, 22.2034],
+            [113.5986, 22.1649],
+          ],
+        ],
+      },
+    },
+  ],
+}

+ 183 - 0
src/components/DataScreen/pie/index.vue

@@ -0,0 +1,183 @@
+<template>
+  <div ref="chartsRef" class="echarts" />
+</template>
+<script lang="ts" setup>
+  import * as echarts from 'echarts'
+  import { EChartsType } from 'echarts/core'
+  import { onMounted, ref } from 'vue'
+  const chartsRef = ref<HTMLElement | null>()
+  var trafficWay = [
+    {
+      name: 'Ⅰ类',
+      value: 20,
+    },
+    {
+      name: 'Ⅱ类',
+      value: 20,
+    },
+    {
+      name: 'Ⅲ类',
+      value: 20,
+    },
+    {
+      name: 'Ⅳ类',
+      value: 20,
+    },
+    { name: 'Ⅴ类', value: 20 },
+    { name: '劣Ⅴ类', value: 20 },
+  ]
+
+  var data = []
+  var color = ['#fd566a', '#9787ff', '#fdb36a', '#fdd56a', '#6da7ff', '#63e1f2', '#ff3000']
+  for (var i = 0; i < trafficWay.length; i++) {
+    data.push(
+      {
+        value: trafficWay[i].value,
+        name: trafficWay[i].name,
+        itemStyle: {
+          normal: {
+            borderWidth: 5,
+            shadowBlur: 20,
+            borderColor: color[i],
+            shadowColor: color[i],
+          },
+        },
+      },
+      {
+        value: 2,
+        name: '',
+        itemStyle: {
+          normal: {
+            label: {
+              show: false,
+            },
+            labelLine: {
+              show: false,
+            },
+            color: 'rgba(0, 0, 0, 0)',
+            borderColor: 'rgba(0, 0, 0, 0)',
+            borderWidth: 0,
+          },
+        },
+      }
+    )
+  }
+  var seriesOption = [
+    {
+      name: '',
+      type: 'pie',
+      clockWise: false,
+      radius: [105, 109],
+      hoverAnimation: false,
+      itemStyle: {
+        normal: {
+          label: {
+            show: true,
+            position: 'outside',
+
+            formatter: function (params) {
+              var percent = 0
+              var total = 0
+              for (var i = 0; i < trafficWay.length; i++) {
+                total += trafficWay[i].value
+              }
+              percent = ((params.value / total) * 100).toFixed(0)
+              if (params.name !== '') {
+                return params.name + '\t' + percent + '%'
+              } else {
+                return ''
+              }
+            },
+          },
+          labelLine: {
+            length: 10,
+            length2: 20,
+            show: true,
+            color: '#00ffff',
+          },
+        },
+      },
+      data: data,
+    },
+  ]
+  let options = {
+    color: color,
+    title: [
+      {
+        text: '水质监测',
+        top: '44%',
+        textAlign: 'center',
+        left: '49.50%',
+        backgroundColor: '#163253',
+        borderRadius: 100,
+        textStyle: {
+          color: '#fff',
+          fontSize: 20,
+          fontWeight: '400',
+        },
+      },
+      {
+        text: '水环境监测站',
+        top: '49%',
+        textAlign: 'center',
+        left: '49.50%',
+        textStyle: {
+          color: '#fff',
+          fontSize: 20,
+          fontWeight: '400',
+        },
+      },
+      {
+        text: '9',
+        top: '53%',
+        textAlign: 'center',
+        left: '48%',
+        textStyle: {
+          color: '#f6ea2f',
+          fontSize: 25,
+          fontWeight: '800',
+          fontStyle: 'italic',
+        },
+      },
+      {
+        text: '个',
+        top: '53.5%',
+        textAlign: 'center',
+        left: '50.5%',
+        textStyle: {
+          color: '#fff',
+          fontSize: 16,
+          fontWeight: '400',
+        },
+      },
+    ],
+    tooltip: {
+      show: false,
+    },
+
+    toolbox: {
+      show: false,
+    },
+    series: seriesOption,
+  }
+
+  let chart: EChartsType
+  const initChart = () => {
+    const chart = echarts.init(chartsRef.value)
+    chart.setOption(options)
+    return chart
+  }
+  onMounted(() => {
+    chart = initChart()
+    window.addEventListener('resize', function () {
+      chart && chart.resize()
+    })
+  })
+</script>
+
+<style lang="scss" scoped>
+  .echarts {
+    width: 100%;
+    height: 100%;
+  }
+</style>

+ 18 - 0
src/components/PageWrapLayout/index.scss

@@ -0,0 +1,18 @@
+.m-container-layout {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  padding: 10px 12px;
+  box-sizing: border-box;
+  .m-container-layout-inner {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    background: white;
+    padding: 20px;
+    width: 100%;
+    height: 100%;
+    box-sizing: border-box;
+  }
+}

+ 13 - 0
src/components/PageWrapLayout/index.vue

@@ -0,0 +1,13 @@
+<template>
+  <div class="m-container-layout">
+    <div class="m-container-layout-inner">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup></script>
+
+<style lang="scss" scoped>
+  @import './index.scss';
+</style>

+ 116 - 0
src/components/RightClickMenu/index.vue

@@ -0,0 +1,116 @@
+<template>
+  <div v-if="isShow" ref="rightMenu" class="g-right-click-menu" :style="style">
+    <div
+      v-for="(item, index) in data"
+      :key="index"
+      class="operating"
+      @click.stop="operatingRightAction($event, item)"
+    >
+      {{ item.label }}
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  export default {
+    props: {
+      data: {
+        type: Array,
+        default: () => [],
+      },
+      left: {
+        type: Number,
+        default: 0,
+      },
+      type: {
+        type: Number,
+        default: 1,
+      },
+      dataInfo: {
+        type: Object,
+        default: () => {},
+      },
+      top: {
+        type: Number,
+        default: 0,
+      },
+      isViewInfo: {
+        type: Boolean,
+        default: true,
+      },
+    },
+    data() {
+      return {
+        isShow: false,
+      }
+    },
+    computed: {
+      style() {
+        let clientHeight = document.body.clientHeight
+        let y = this.top
+        if (clientHeight - y < 100) {
+          return `left:${this.left}px;bottom:${clientHeight - y}px`
+        } else {
+          return `left:${this.left}px;top:${this.top}px`
+        }
+      },
+    },
+    watch: {
+      left: {
+        handler(newName, oldName) {
+          if (newName) {
+            this.isShow = true
+          }
+        },
+        // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
+        // immediate: true
+      },
+    },
+    mounted() {
+      let _self = this
+      window.addEventListener('click', function () {
+        _self.isShow = false
+      })
+      window.addEventListener('mousedown', function (e) {
+        if (e.which === 3) {
+          _self.isShow = false
+        }
+      })
+    },
+    methods: {
+      /**
+       * @func 点击操作
+       * @param val 1、置顶/取消置顶 2、开启/关闭免打扰 3、开启/关闭星标 4、删除会话
+       */
+      operatingRightAction($event, val) {
+        this.$emit('ok', $event, val)
+        this.isShow = false
+      },
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .g-right-click-menu {
+    left: 0;
+    background: white;
+    width: 148px;
+    height: auto;
+    position: fixed;
+    //border: 1px solid #c4c4c4;
+    z-index: 9;
+    //box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.1);
+    box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
+    .operating {
+      font-size: 12px;
+      padding-left: 23px;
+      cursor: pointer;
+      line-height: 27px;
+    }
+    .operating:hover {
+      background: #e2e2e2;
+    }
+
+    .last-delete {
+      border-top: 1px solid #ededed;
+    }
+  }
+</style>

+ 61 - 0
src/components/SearchForm/components/BaseFormItem.vue

@@ -0,0 +1,61 @@
+<template>
+  <el-form-item v-if="config.valueType === 'input'" :label="config?.label" style="width: 100%">
+    <el-input v-model="value" v-bind="$attrs" />
+  </el-form-item>
+  <el-form-item v-if="config.valueType === 'select'" :label="config?.label" style="width: 100%">
+    <el-select v-model="value" v-bind="$attrs" style="width: 100%">
+      <el-option
+        v-for="item in config.options"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value"
+      />
+    </el-select>
+  </el-form-item>
+  <el-form-item
+    v-if="config.valueType === 'date-picker'"
+    :label="config?.label"
+    style="width: 100%"
+  >
+    <el-date-picker v-model="value" v-bind="$attrs" style="width: 100%" />
+  </el-form-item>
+  <el-form-item v-if="config.valueType === 'cascader'" :label="config?.label" style="width: 100%">
+    <el-cascader v-model="value" v-bind="$attrs" style="width: 100%" />
+  </el-form-item>
+  <el-form-item
+    v-if="config.valueType === 'time-select'"
+    :label="config?.label"
+    style="width: 100%"
+  >
+    <el-time-select v-model="value" v-bind="$attrs" style="width: 100%" />
+  </el-form-item>
+</template>
+<script setup lang="ts">
+  import { computed } from 'vue'
+
+  type ConfigType = {
+    modelValue?: any
+    config?: any
+  }
+
+  const props = defineProps<ConfigType>()
+
+  const emits = defineEmits<{
+    (e: 'update:modelValue', value: any): void
+  }>()
+
+  const value = computed({
+    get() {
+      return props?.modelValue
+    },
+    set(value) {
+      emits('update:modelValue', value)
+    },
+  })
+</script>
+<script lang="ts">
+  export default {
+    inheritAttrs: false,
+  }
+</script>
+<style lang="less" scoped></style>

+ 127 - 0
src/components/SearchForm/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="advancedForm">
+    <el-form
+      ref="ruleFormRef"
+      :inline="true"
+      :label-position="'right'"
+      :model="formParams"
+      class="form-inline"
+    >
+      <el-row :class="{ 'not-show': byHeight && !isExpand }" :gutter="gutterWidth">
+        <template v-for="(item, index) in columns">
+          <el-col
+            v-if="item.valueType"
+            v-show="byHeight ? true : index < showRow * 3 || isExpand"
+            :span="item.span"
+          >
+            <BaseFormItem :key="index" v-bind="item.attrs" v-model="item.value" :config="item" />
+          </el-col>
+        </template>
+      </el-row>
+    </el-form>
+    <div class="search-btn">
+      <el-button type="primary" @click="onSubmit">查询</el-button>
+      <el-button @click="resetForm(ruleFormRef)">重置</el-button>
+      <el-button v-if="columns.length > 3" link type="primary" @click="isExpand = !isExpand">
+        {{ isExpand ? '合并' : '展开' }}
+        <el-icon>
+          <arrow-down v-if="!isExpand" />
+          <arrow-up v-else />
+        </el-icon>
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { onMounted, reactive, ref } from 'vue'
+  import type { FormInstance } from 'element-plus'
+  import BaseFormItem from './components/BaseFormItem.vue'
+  const ruleFormRef = ref<FormInstance>()
+  let props = defineProps({
+    // 宽度
+    labelWidth: {
+      default: '100px',
+    },
+    gutterWidth: {
+      type: Number,
+      default: 24,
+    },
+    showRow: {
+      type: Number,
+      default: 1,
+    },
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+    byHeight: {
+      type: Boolean,
+      default: false,
+    },
+  })
+
+  const emit = defineEmits(['submit', 'reset'])
+  // 收缩展开
+  const isExpand = ref(false)
+  const formParams = reactive({})
+
+  const initFormParams = () => {
+    for (let item of props.columns) {
+      formParams[item.name] = item?.value
+    }
+  }
+
+  // 进行遍历获取参数
+  const getFormParams = () => {
+    let searchParams = {}
+    for (let item of props.columns) {
+      searchParams[item.name] = item?.value
+    }
+    return searchParams
+  }
+
+  onMounted(() => {
+    initFormParams()
+  })
+
+  // 获取参数进行组装为 obj
+  const onSubmit = () => {
+    let searchParams = getFormParams()
+    emit('submit', searchParams)
+  }
+
+  // 重置参数
+  const resetForm = (formEl: FormInstance | undefined) => {
+    if (!formEl) return
+    formEl.resetFields()
+    const keys = Object.keys(formParams)
+    keys.forEach((key) => {
+      let itemColums = props.columns.find((item) => item.name === key)
+      itemColums.value = formParams[key]
+    })
+    let searchParams = getFormParams()
+    emit('reset', searchParams)
+  }
+</script>
+
+<style lang="scss" scoped>
+  .advancedForm {
+    display: flex;
+    justify-content: space-between;
+    .form-inline {
+      flex: 1;
+    }
+    .el-form--inline .el-form-item {
+      width: 100%;
+      margin-right: 10px;
+    }
+    .search-btn {
+      margin-left: 40px;
+    }
+    .not-show {
+      height: 40px;
+      overflow: hidden;
+    }
+  }
+</style>

+ 35 - 0
src/components/SvgIcon/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <svg :class="svgClass" aria-hidden="true">
+    <use :xlink:href="iconName"></use>
+  </svg>
+</template>
+
+<script lang="ts">
+  import { computed } from 'vue'
+  export default {
+    name: 'BaseSvgIcon',
+    props: {
+      iconClass: { type: String },
+      className: { type: String },
+    },
+    setup(props) {
+      const iconName = computed(() => {
+        return props.iconClass ? `#icon-${props.iconClass}` : '#icon'
+      })
+      const svgClass = computed(() => {
+        return props.className ? 'svg-icon ' + props.className : 'svg-icon'
+      })
+      return { iconName, svgClass }
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .svg-icon {
+    width: 1em;
+    height: 1em;
+    vertical-align: -0.15em;
+    fill: currentColor;
+    overflow: hidden;
+  }
+</style>

+ 26 - 0
src/components/SwitchDark/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <el-switch
+    v-model="themeConfig.isDark"
+    inline-prompt
+    :active-icon="Sunny"
+    :inactive-icon="Moon"
+    @change="switchDark"
+  />
+</template>
+
+<script setup lang="ts" name="switchDark">
+  import { Sunny, Moon } from '@element-plus/icons-vue'
+  import { computed, ref } from 'vue'
+  import { useSettingStore } from '@/store/modules/setting'
+
+  const SettingStore = useSettingStore()
+  // 设置信息
+  const themeConfig = computed(() => SettingStore.themeConfig)
+
+  // 切换暗黑模式
+  const switchDark = () => {
+    const body = document.documentElement as HTMLElement
+    if (themeConfig.value.isDark) body.setAttribute('class', 'dark')
+    else body.setAttribute('class', '')
+  }
+</script>

+ 306 - 0
src/components/Table/EditableProTable/index.vue

@@ -0,0 +1,306 @@
+<template>
+  <div class="m-edit-table">
+    <div v-if="mode !== 'hide' && mode !== 'bottom'" style="margin-top: 15px; margin-bottom: 15px">
+      <el-button style="width: 100%" @click="add">
+        <el-icon style="margin-right: 4px"><plus /></el-icon>
+        添加一行数据
+      </el-button>
+    </div>
+    <el-table :data="transData" style="width: 100%" row-key="id" border>
+      <template v-for="item in columns">
+        <el-table-column
+          v-if="item.type"
+          :type="item.type"
+          :width="item.width"
+          :align="item.align"
+          :fixed="item.fixed"
+          :label="item.label"
+        />
+        <el-table-column
+          v-else
+          :prop="item.name"
+          :width="item.width"
+          :align="item.align"
+          :fixed="item.fixed"
+          :label="item.label"
+        >
+          <template #default="scope">
+            <template v-if="!item.slot">
+              <template v-if="item.readonly">
+                {{ scope.row[item.name] }}
+              </template>
+              <template v-else-if="item.valueType === 'select'">
+                <el-select
+                  v-if="scope.row.edit"
+                  v-model="scope.row[item.name]"
+                  clearable
+                  :placeholder="`请选择`"
+                >
+                  <el-option
+                    v-for="ite in item.options"
+                    :key="ite.value"
+                    :label="ite.label"
+                    :value="ite.value"
+                  />
+                </el-select>
+                <span v-else>{{ filterOption(item, scope) }}</span>
+              </template>
+
+              <template v-else-if="item.valueType === 'date'">
+                <el-date-picker
+                  v-if="scope.row.edit"
+                  v-model="scope.row[item.name]"
+                  type="date"
+                  value-format="YYYY-MM-DD"
+                  clearable
+                  placeholder="请选择"
+                />
+                <span v-else>{{ scope.row[item.name] || '--' }}</span>
+              </template>
+              <template v-else>
+                <el-input
+                  v-if="scope.row.edit"
+                  v-model="scope.row[item.name]"
+                  clearable
+                  placeholder="请输入"
+                ></el-input>
+                <span v-else>{{ scope.row[item.name] || '--' }}</span>
+              </template>
+            </template>
+            <slot v-else :name="item.name" :item="item" :row="scope.row"></slot>
+          </template>
+        </el-table-column>
+      </template>
+      <el-table-column prop="operator" label="操作" width="250px" fixed="right">
+        <template #default="scope">
+          <el-button
+            v-if="scope.row.edit"
+            type="primary"
+            size="small"
+            icon="CircleCheckFilled"
+            @click="confirmEdit(scope.row)"
+          >
+            保存
+          </el-button>
+          <el-button
+            v-else
+            type="primary"
+            size="small"
+            icon="Edit"
+            @click="scope.row.edit = !scope.row.edit"
+          >
+            编辑
+          </el-button>
+          <el-popover
+            v-model:visible="scope.row.visible"
+            trigger="click"
+            placement="top"
+            :width="160"
+          >
+            <p style="display: flex; align-items: center; margin-bottom: 10px">
+              <el-icon color="#faad14" style="margin-right: 10px"><warning-filled /></el-icon>
+              删除此行?
+            </p>
+            <div style="text-align: right; margin: 0">
+              <el-button size="small" @click="scope.row.visible = false">取消</el-button>
+              <el-button size="small" type="primary" @click="deleteAction(scope.row)">
+                确定
+              </el-button>
+            </div>
+            <template #reference>
+              <el-button icon="Delete" type="danger" size="small" @click="deleteCurrent(scope.row)">
+                删除
+              </el-button>
+            </template>
+          </el-popover>
+          <el-button
+            v-if="scope.row.edit"
+            type="primary"
+            size="small"
+            icon="Edit"
+            @click="cancelEdit(scope.row)"
+          >
+            取消
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div v-if="mode !== 'hide' && mode !== 'top'" style="margin-top: 15px">
+      <el-button style="width: 100%" @click="add">
+        <el-icon style="margin-right: 4px"><plus /></el-icon>
+        添加一行数据
+      </el-button>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, onMounted, ref, watch } from 'vue'
+  import { deepObjClone } from '@/utils/index'
+  import { ElMessage, ElMessageBox } from 'element-plus'
+  import { reactive } from 'vue'
+  const emit = defineEmits(['del', 'add', 'onChange'])
+  let transData = ref([])
+
+  let props = defineProps({
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+    data: {
+      type: Array,
+      default: () => [],
+    },
+    editableKeys: {
+      type: Array,
+      default: () => [],
+    },
+    mode: {
+      type: String,
+      default: 'bottom',
+    },
+  })
+
+  // 删除当前此行
+  const deleteCurrent = (row) => {
+    // console.log('----------',row)
+    // row.visible = true
+  }
+
+  const getData = () => {
+    let arr = deepObjClone(transData.value)
+    for (let item of arr) {
+      for (let attr in item) {
+        if (attr.includes('te__mp')) {
+          delete item[attr]
+        }
+      }
+    }
+    emit('onChange', arr)
+  }
+
+  let obj = {}
+  for (let item of props.columns) {
+    props.data.forEach((it) => {
+      if (!obj[item.name]) {
+        obj[item.name] = null
+      }
+    })
+  }
+
+  // 重置数据
+  const reset = () => {
+    transData.value = props.data
+    for (let item of transData.value) {
+      if (props.editableKeys.includes(item.id)) {
+        item.edit = true
+      }
+    }
+    getData()
+  }
+
+  onMounted(() => {
+    watch(
+      () => props.data,
+      (val) => {
+        // // 转换数据
+        transData.value = deepObjClone(val)
+        // 存储一个临时变量
+        for (let item of transData.value) {
+          if (props.editableKeys.includes(item.id)) {
+            item.edit = true
+          }
+          for (let attr in item) {
+            let temp = `${attr}te__mp`
+            item[temp] = item[attr]
+          }
+        }
+      },
+      {
+        immediate: true,
+        deep: true,
+      }
+    )
+  })
+
+  const visible = ref(false)
+
+  const handleSizeChange = (val: number) => {
+    console.log(`${val} items per page`)
+  }
+
+  const listLoading = ref(false)
+
+  // 保存
+  const confirmEdit = (row) => {
+    row.edit = false
+    for (let attr in row) {
+      if (attr.includes('te__mp')) {
+        row[attr] = row[attr.replace('te__mp', '')]
+      }
+    }
+    getData()
+  }
+  // 取消
+  const cancelEdit = (row) => {
+    row.edit = !row.edit
+    for (let attr in row) {
+      if (attr !== 'edit') {
+        if (!attr.includes('te__mp')) {
+          row[attr] = row[attr + 'te__mp']
+        }
+      }
+    }
+  }
+
+  const deleteAction = (row) => {
+    row.visible = false
+    transData.value = transData.value.filter((item) => item.id !== row.id)
+    emit('del', row)
+  }
+
+  // 添加
+  const add = () => {
+    let id = ~~(Math.random() * 1000000).toFixed(0)
+    let obj1 = Object.assign({}, obj, {
+      id: id,
+      edit: true,
+      visible: false,
+    })
+    for (let attr in obj1) {
+      let temp = `${attr}te__mp`
+      obj1[temp] = obj1[attr]
+    }
+
+    if (props.mode === 'bottom') {
+      transData.value.push(obj1)
+    }
+    if (props.mode === 'top') {
+      transData.value.unshift(obj1)
+    }
+  }
+
+  const filterOption = (item, scope) => {
+    let obj = item.options.find((ite) => ite.value === scope.row[item.name])
+    if (obj) {
+      return obj.label
+    }
+    return '--'
+  }
+
+  defineExpose({
+    reset,
+  })
+</script>
+<style scoped>
+  .edit-input {
+    padding-right: 100px;
+  }
+  .cancel-btn {
+    position: absolute;
+    right: 15px;
+    top: 10px;
+  }
+  .inline-edit-table {
+    width: 100%;
+  }
+</style>

+ 206 - 0
src/components/Table/PropTable/index.vue

@@ -0,0 +1,206 @@
+<template>
+  <div class="zb-pro-table">
+    <div class="header">
+      <SearchForm :columns="baseFormColumns" @submit="onSubmit" />
+    </div>
+
+    <!----------底部---------------------->
+    <div class="footer">
+      <!-----------工具栏操作工具----------------->
+      <div class="operator">
+        <slot name="btn"></slot>
+      </div>
+
+      <!-- ------------表格--------------->
+      <div class="table">
+        <el-table
+          v-loading="loading"
+          class="zb-table"
+          :data="list"
+          :border="true"
+          @selection-change="(val) => emit('selection-change', val)"
+        >
+          <template v-for="item in columns">
+            <el-table-column v-if="item.slot" v-bind="{ ...item, ...{ prop: item.name } }">
+              <template #default="scope">
+                <slot :name="item.name" :item="item" :row="scope.row"></slot>
+              </template>
+            </el-table-column>
+            <el-table-column v-else v-bind="{ ...item, ...{ prop: item.name } }" />
+          </template>
+        </el-table>
+      </div>
+      <!-- ------------分页--------------->
+      <div class="pagination">
+        <el-pagination
+          v-model:current-page="pagination.currentPage"
+          :page-size="10"
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="data.length"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, ref } from 'vue'
+  import SearchForm from '@/components/SearchForm/index.vue'
+  import { ElMessage, ElMessageBox } from 'element-plus'
+  import type { FormInstance } from 'element-plus'
+  const ruleFormRef = ref<FormInstance>()
+  const emit = defineEmits(['reset', 'onSubmit', 'selection-change'])
+  let props = defineProps({
+    columns: {
+      type: Array,
+      default: () => [],
+    },
+    data: {
+      type: Array,
+      default: () => [],
+    },
+    loading: {
+      type: Boolean,
+      default: false,
+    },
+  })
+
+  // 过滤调需要进行搜索选择的
+  const baseFormColumns = computed(() => {
+    return props.columns.filter((item) => item.valueType && item.search)
+  })
+
+  const pagination = reactive({
+    currentPage: 1,
+    pageSize: 10,
+  })
+
+  const currentPage = ref(1)
+  // 收缩展开
+  const isExpand = ref(false)
+  const handleSizeChange = (val: number) => {
+    console.log(`${val} items per page`)
+  }
+  const handleCurrentChange = (val: number) => {
+    console.log(`current page: ${val}`)
+    pagination.currentPage = val
+  }
+
+  const list = computed(() => {
+    let arr = JSON.parse(JSON.stringify(props.data))
+    return arr.splice((pagination.currentPage - 1) * 10, 10)
+  })
+
+  const listLoading = ref(false)
+  const confirmEdit = (row) => {
+    row.edit = false
+  }
+  const cancelEdit = (row) => {
+    row.edit = false
+  }
+
+  import { reactive } from 'vue'
+
+  let obj = {}
+  let search = []
+  for (let item of props.columns) {
+    if (item.inSearch) {
+      obj[item.name] = null
+    }
+    if (item.inSearch) {
+      search.push(item)
+    }
+  }
+  const formSearchData = ref(search)
+  const formInline = reactive(obj)
+
+  const onSubmit = () => {
+    emit('onSubmit', formInline)
+  }
+
+  const reset = (formEl: FormInstance | undefined) => {
+    formSearchData.value.forEach((item) => {
+      formInline[item.name] = null
+    })
+    emit('reset')
+  }
+  const deleteAction = (row) => {
+    ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+      draggable: true,
+    })
+      .then(() => {
+        list.value = list.value.filter((item) => item.id !== row.id)
+        ElMessage.success('删除成功')
+      })
+      .catch(() => {})
+  }
+</script>
+<style scoped lang="scss">
+  .edit-input {
+    padding-right: 100px;
+  }
+  .cancel-btn {
+    position: absolute;
+    right: 15px;
+    top: 10px;
+  }
+  .zb-pro-table {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .header {
+      display: flex;
+      padding: 16px 16px 0 16px;
+      margin-bottom: 16px;
+      border-radius: 4px;
+      background: white;
+      box-shadow: 0 0 12px rgb(0 0 0 / 5%);
+      :deep(.advancedForm) {
+        flex: 1;
+      }
+    }
+    .footer {
+      flex: 1;
+      display: flex;
+      padding: 16px;
+      flex-direction: column;
+      border-radius: 4px;
+      overflow: hidden;
+      background: white;
+      box-shadow: 0 0 12px rgb(0 0 0 / 5%);
+      min-height: 300px;
+      .operator {
+        margin-bottom: 15px;
+      }
+      .table {
+        position: relative;
+        flex: 1;
+      }
+      .zb-table {
+        position: absolute;
+        height: 100%;
+      }
+    }
+    ::v-deep {
+      .el-table__header th {
+        font-size: 15px;
+        font-weight: 700;
+        color: #252525;
+      }
+    }
+    .pagination {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      padding-top: 20px;
+      box-sizing: border-box;
+    }
+  }
+</style>

+ 163 - 0
src/components/Theme/index.vue

@@ -0,0 +1,163 @@
+<template>
+  <div>
+    <el-drawer v-model="drawer" title="主题配置" size="300px">
+      <div class="theme-item">
+        <label>导航栏布局</label>
+        <el-select
+          v-model="layout"
+          placeholder="请选择"
+          style="width: 150px"
+          @change="(val) => changeSwitch('mode', val)"
+        >
+          <el-option label="纵向" value="vertical"></el-option>
+          <el-option label="横向" value="horizontal"></el-option>
+          <el-option label="分栏" value="columns"></el-option>
+        </el-select>
+      </div>
+      <div class="theme-item">
+        <label>主题颜色</label>
+        <el-color-picker v-model="primary" :predefine="predefineColor" @change="changePrimary" />
+      </div>
+      <div class="theme-item">
+        <label>暗黑模式</label>
+        <switch-dark></switch-dark>
+      </div>
+      <div class="theme-item">
+        <label>灰色模式</label>
+        <el-switch v-model="gray" @change="(val) => changeGrayWeak('gray', val)" />
+      </div>
+      <div class="theme-item">
+        <label>色弱模式</label>
+        <el-switch v-model="weak" @change="(val) => changeGrayWeak('weak', val)" />
+      </div>
+      <div class="theme-item">
+        <label>标签栏</label>
+        <el-switch v-model="showTag" @change="(val) => changeSwitch('showTag', val)" />
+      </div>
+      <div class="theme-item">
+        <label>侧边栏 Logo</label>
+        <el-switch v-model="showLogo" @change="(val) => changeSwitch('showLogo', val)" />
+      </div>
+      <div class="theme-item">
+        <label>保持一个子菜单的展开</label>
+        <el-switch v-model="uniqueOpened" @change="(val) => changeSwitch('uniqueOpened', val)" />
+      </div>
+      <div class="theme-item">
+        <label>固定header</label>
+        <el-switch v-model="fixedHeader" @change="(val) => changeSwitch('fixedHeader', val)" />
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { computed, ref, watch } from 'vue'
+  import { ElMessage } from 'element-plus'
+  import { openLoading, closeLoading } from '@/utils/element'
+  import SwitchDark from '@/components/SwitchDark/index.vue'
+  import { PRIMARY_COLOR } from '@/config/index'
+  import { useSettingStore } from '@/store/modules/setting'
+
+  const SettingStore = useSettingStore()
+  const layout = ref(SettingStore.themeConfig.mode)
+  const showTag = ref(SettingStore.themeConfig.showTag)
+  const showLogo = ref(SettingStore.themeConfig.showLogo)
+  const uniqueOpened = ref(SettingStore.themeConfig.uniqueOpened)
+  const primary = ref(SettingStore.themeConfig.primary)
+  const fixedHeader = ref(SettingStore.themeConfig.fixedHeader)
+  const gray = ref(SettingStore.themeConfig.gray)
+  const weak = ref(SettingStore.themeConfig.weak)
+
+  const drawer = computed({
+    get() {
+      return SettingStore.themeConfig.showSetting
+    },
+    set() {
+      changeSwitch('showSetting', !SettingStore.themeConfig.showSetting)
+    },
+  })
+
+  // 预定义主题颜色
+  const predefineColor = [
+    '#409EFF',
+    '#1890ff',
+    '#304156',
+    '#212121',
+    '#11a983',
+    '#13c2c2',
+    '#6959CD',
+    '#f5222d',
+  ]
+
+  const operator = (type) => {
+    switch (type) {
+      case 1:
+        drawer.value = true
+        return
+      case 2:
+        window.open('https://github.com/zouzhibin/vue-admin-perfect')
+        return
+    }
+  }
+
+  // 进行配置
+  const changeSwitch = (key, val) => {
+    SettingStore.setThemeConfig({ key, val })
+    if (key === 'mode') {
+      openLoading()
+      setTimeout(() => {
+        closeLoading()
+      }, 600)
+    }
+  }
+
+  // 监听布局变化
+  watch(
+    () => layout.value,
+    () => {
+      const body = document.body as HTMLElement
+      body.setAttribute('class', `layout-${layout.value}`)
+    },
+    { immediate: true }
+  )
+
+  // 修改主题颜色
+  const changePrimary = (val) => {
+    if (!val) {
+      primary.value = val = PRIMARY_COLOR
+      ElMessage({ type: 'success', message: `主题颜色已重置为 ${PRIMARY_COLOR}` })
+    }
+    document.documentElement.style.setProperty('--el-color-primary', val)
+    changeSwitch('primary', val)
+  }
+
+  // 修改灰色模式
+  const changeGrayWeak = (type, val) => {
+    const body = document.documentElement as HTMLElement
+    if (!val) return body.setAttribute('style', '')
+    if (type === 'gray') body.setAttribute('style', 'filter: grayscale(1)')
+    if (type === 'weak') body.setAttribute('style', 'filter: invert(80%)')
+    changeSwitch(type, val)
+  }
+</script>
+
+<style lang="scss" scoped>
+  ::v-deep(.el-drawer__header) {
+    border-bottom: 1px solid #ebeef5;
+    padding: 15px 20px 14px;
+    margin-bottom: 0;
+  }
+  :deep(.el-drawer__title) {
+    font-weight: bold;
+    color: black;
+  }
+  .theme-item {
+    width: 100%;
+    display: flex;
+    margin-bottom: 15px;
+    align-items: center;
+    font-size: 14px;
+    color: black;
+    justify-content: space-between;
+  }
+</style>

+ 88 - 0
src/components/Upload/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <el-upload
+    action=""
+    :before-upload="beforeUploadAction"
+    :list-type="listType"
+    :multiple="multiple"
+    :on-preview="handlePictureCardPreview"
+    :on-remove="handleRemove"
+    :file-list="fileList"
+  >
+    <el-icon><Plus /></el-icon>
+  </el-upload>
+
+  <el-dialog v-model="dialogVisible" width="50%" top="80px">
+    <img w-full :src="dialogImageUrl" alt="预览图片" style="width: 100%" />
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+  import { onMounted, ref, watch } from 'vue'
+  import { Plus } from '@element-plus/icons-vue'
+
+  import type { UploadProps, UploadUserFile } from 'element-plus'
+  import { ElMessage } from 'element-plus'
+  let emit = defineEmits(['update'])
+  let props = defineProps({
+    modelValue: Array,
+    multiple: {
+      type: Boolean,
+      default: true,
+    },
+    listType: {
+      type: String,
+      default: 'picture-card',
+    },
+    showFileList: {
+      type: Boolean,
+      default: true,
+    },
+  })
+  let fileList = ref([])
+
+  const dialogImageUrl = ref('')
+  const dialogVisible = ref(false)
+
+  const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
+    console.log(uploadFile, uploadFiles)
+  }
+
+  const beforeUploadAction = (file, fileLi) => {
+    return new Promise((resolve, reject) => {
+      var reader = new FileReader()
+      let reg = /\.jpg$|\.jpeg$|\.gif$|\.png$/i
+      reader.readAsDataURL(file)
+      let name = file.name
+      if (reg.test(name)) {
+        reader.onload = (e: FileReader) => {
+          fileList.value.push({
+            name: name,
+            url: e.target.result,
+          })
+          emit('update', fileList.value)
+          resolve(e.target.result)
+        }
+      } else {
+        ElMessage.error('请上传图片')
+        reject()
+      }
+    })
+  }
+
+  const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
+    dialogImageUrl.value = uploadFile.url!
+    dialogVisible.value = true
+  }
+
+  onMounted(() => {
+    watch(
+      () => props.modelValue,
+      (value) => {
+        fileList.value = value
+      },
+      {
+        immediate: true,
+      }
+    )
+  })
+</script>

+ 80 - 0
src/components/WangEdior/index.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="m-wangEditor">
+    <Toolbar
+      style="border-bottom: 1px solid #ccc"
+      :editor="editorRef"
+      :default-config="toolbarConfig"
+      :mode="mode"
+    />
+    <Editor
+      v-model="valueHtml"
+      class="editor-content'"
+      style="height: 300px; overflow-y: hidden"
+      :default-config="editorConfig"
+      :mode="mode"
+      @on-created="handleCreated"
+    />
+  </div>
+</template>
+<script lang="ts" setup>
+  // 引入 wangEditor
+  import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
+  import '@wangeditor/editor/dist/css/style.css' // 引入 css
+  import { onBeforeUnmount, onMounted, watch, shallowRef, ref, computed } from 'vue'
+  let editors = null
+  // 编辑器实例,必须用 shallowRef
+  const editorRef = shallowRef()
+  const toolbarConfig = {}
+  const editorConfig = { placeholder: '请输入内容...' }
+
+  // 内容 HTML
+  const mode = ref('default')
+  let emit = defineEmits(['update:modelValue'])
+  let props = defineProps({
+    modelValue: String,
+  })
+
+  const getEditorData = () => {
+    // 通过代码获取编辑器内容
+    let data = editors.txt.html()
+    alert(data)
+  }
+
+  const handleCreated = (editor) => {
+    editorRef.value = editor // 记录 editor 实例,重要!
+  }
+
+  const valueHtml = computed({
+    get() {
+      return props.modelValue
+    },
+    set(val) {
+      // 防止富文本内容为空时,校验失败
+      if (editorRef.value.isEmpty()) val = ''
+      emit('update:modelValue', val)
+    },
+  })
+
+  // 组件销毁时,也及时销毁编辑器
+  onBeforeUnmount(() => {
+    // 调用销毁 API 对当前编辑器实例进行销毁
+    const editor = editorRef.value
+    if (editor == null) {
+      return
+    }
+    editor.destroy()
+  })
+</script>
+<style lang="scss" scoped>
+  .m-wangEditor {
+    z-index: 99;
+    width: 100%;
+    border: 1px solid #cccccc;
+    .editor-toolbar {
+      border-bottom: 1px solid #cccccc;
+    }
+    .editor-content {
+      overflow-y: hidden;
+    }
+  }
+</style>

+ 8 - 0
src/components/pipeline/index.vue

@@ -0,0 +1,8 @@
+<template>
+  <div class="zb-pipeline">
+    <zb-pipeline-start />
+  </div>
+</template>
+<script lang="ts" setup>
+  import ZbPipelineStart from './zb-pipeline-start'
+</script>

+ 150 - 0
src/components/pipeline/zb-pipeline-start.vue

@@ -0,0 +1,150 @@
+<template>
+  <div class="zb-pipeline-start-wrapper">
+    <div class="zb-pipeline-start" :class="control === value ? 'active' : ''" @click="handleClick">
+      <div class="zb-pipeline-start-header">
+        <zb-icon type="play-filled" />
+      </div>
+      <div class="zb-pipeline-start-body">
+        <div class="zb-pipeline-start-title">开始</div>
+        <div class="zb-pipeline-start-tooltip">
+          <el-tooltip placement="top-start" content="点击进行构建基础设置">
+            <el-icon>
+              <Help />
+            </el-icon>
+          </el-tooltip>
+          <!--          <zb-tooltip placement="right">-->
+          <!--            <zb-icon type="help" />-->
+          <!--            <div slot="content">点击进行构建基础设置</div>-->
+          <!--          </zb-tooltip>-->
+        </div>
+      </div>
+    </div>
+    <slot></slot>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { Help } from '@element-plus/icons-vue'
+</script>
+<style>
+  /* zb-pipeline-start-wrapper */
+  .zb-pipeline-start-wrapper {
+    position: relative;
+    padding: 0 40px;
+  }
+
+  /* zb-pipeline-start */
+  .zb-pipeline-start {
+    cursor: pointer;
+    user-select: none;
+    position: relative;
+    display: flex;
+    justify-content: flex-start;
+    align-items: stretch;
+    width: 200px;
+    height: 40px;
+    border-radius: 2px;
+    background-color: #fff;
+  }
+  .zb-pipeline-start:after {
+    content: '';
+    position: absolute;
+    top: 20px;
+    right: -40px;
+    display: block;
+    width: 40px;
+    height: 1px;
+    background-color: #2d8cf0;
+  }
+  .zb-pipeline-start .zb-pipeline-start-header {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 40px;
+    border-width: 1px 0 1px 1px;
+    border-style: solid;
+    border-color: #2d8cf0;
+    border-radius: 2px 0 0 2px;
+    background-color: #2d8cf0;
+    color: #fff;
+    font-size: 14px;
+    font-weight: 600;
+    transition: all 0.2s cubic-bezier(0.23, 1, 0.32, 1);
+  }
+  .zb-pipeline-start .zb-pipeline-start-body {
+    flex: 1;
+    display: flex;
+    border-width: 1px 1px 1px 0;
+    border-style: solid;
+    border-color: #e3e8f0;
+    border-radius: 0 2px 2px 0;
+    padding: 0 8px;
+    overflow: hidden;
+    transition: all 0.2s cubic-bezier(0.23, 1, 0.32, 1);
+  }
+  .zb-pipeline-start .zb-pipeline-start-title {
+    flex: 1;
+    display: block;
+    overflow: hidden;
+    color: #262626;
+    font-size: 14px;
+    font-weight: 600;
+    line-height: 38px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .zb-pipeline-start .zb-pipeline-start-tooltip {
+    cursor: pointer;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-left: 8px;
+  }
+  .zb-pipeline-start .zb-pipeline-start-tooltip .zb-tooltip {
+    display: block;
+  }
+  .zb-pipeline-start .zb-pipeline-start-tooltip .zb-icon {
+    display: block;
+    color: #595959;
+    font-size: 14px;
+  }
+
+  /* zb-pipeline-start hover */
+  .zb-pipeline-start:hover {
+  }
+  .zb-pipeline-start:hover:after {
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-header {
+    border-color: #2d8cf0;
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-body {
+    border-color: #2d8cf0;
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-title {
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-tooltip {
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-tooltip .zb-tooltip {
+  }
+  .zb-pipeline-start:hover .zb-pipeline-start-tooltip .zb-icon {
+  }
+
+  /* zb-pipeline-start active */
+  .zb-pipeline-start.active {
+  }
+  .zb-pipeline-start.active:after {
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-header {
+    border-color: #2d8cf0;
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-body {
+    border-color: #2d8cf0;
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-title {
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-tooltip {
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-tooltip .zb-tooltip {
+  }
+  .zb-pipeline-start.active .zb-pipeline-start-tooltip .zb-icon {
+  }
+</style>

+ 30 - 0
src/components/u-container-layout/index.vue

@@ -0,0 +1,30 @@
+<template>
+  <div class="m-container-layout">
+    <div class="m-container-layout-inner">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup></script>
+
+<style lang="scss" scoped>
+  .m-container-layout {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    padding: 10px 12px;
+    box-sizing: border-box;
+    .m-container-layout-inner {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      background: white;
+      padding: 20px;
+      width: 100%;
+      height: 100%;
+      box-sizing: border-box;
+    }
+  }
+</style>

+ 2 - 0
src/config/index.ts

@@ -0,0 +1,2 @@
+// * 默认主题颜色
+export const PRIMARY_COLOR = '#409eff'

+ 115 - 0
src/hooks/useFullscreen.ts

@@ -0,0 +1,115 @@
+/**
+ *  @description 方法用来切换元素 进入全屏
+ *  @vueuse/core 提供了 useFullscreen 方法,因此项目中采用 useFullscreen,实现效果功能是一样得,目的是为了减少代码量
+ *  它原理原理实现如下:
+ */
+
+import { ElMessage } from 'element-plus'
+import { onMounted } from 'vue'
+
+export const useFullscreen = () => {
+  /**
+   * @description: 是否支持全屏+判断浏览器前缀
+   */
+  const isFullscreen = () => {
+    let prefixName = '' // 浏览器前缀
+    let fullscreenEnabled = false
+    // 判断浏览器前缀
+    if (document.fullscreenEnabled) {
+      fullscreenEnabled = document.fullscreenEnabled
+      // webkit
+    } else if (document.webkitFullscreenEnabled) {
+      fullscreenEnabled = document.webkitFullscreenEnabled
+      prefixName = 'webkit'
+      // moz
+    } else if (document.mozFullScreenEnabled) {
+      fullscreenEnabled = document.mozFullScreenEnabled
+      prefixName = 'moz'
+      // ms
+    } else if (document.msFullscreenEnabled) {
+      fullscreenEnabled = document.msFullscreenEnabled
+      prefixName = 'ms'
+    }
+    return {
+      fullscreenEnabled,
+      prefixName,
+    }
+  }
+
+  /**
+   * @description: 检测有没有元素处于全屏状态
+   * @return 布尔值
+   */
+  const isElementFullScreen = () => {
+    const fullscreenElement =
+      document.fullscreenElement ||
+      document.msFullscreenElement ||
+      document.mozFullScreenElement ||
+      document.webkitFullscreenElement
+    if (fullscreenElement === null) {
+      return false // 当前没有元素在全屏状态
+    } else {
+      return true // 有元素在全屏状态
+    }
+  }
+
+  /**
+   * @description: 将传进来的元素全屏
+   * @param {String} domName 要全屏的dom名称
+   */
+  const Fullscreen = (target) => {
+    const targetRef = target || (document == null ? void 0 : document.querySelector('html'))
+    const { prefixName } = isFullscreen()
+    const methodName = prefixName === '' ? 'requestFullscreen' : `${prefixName}RequestFullScreen`
+    targetRef[methodName]()
+  }
+
+  // 退出全屏
+  const exitFullscreen = () => {
+    const { prefixName } = isFullscreen()
+    const methodName = prefixName === '' ? 'exitFullscreen' : `${prefixName}ExitFullscreen`
+    document[methodName]()
+  }
+
+  /**
+   * @description: 浏览器无法进入全屏时触发,可能是技术原因,也可能是用户拒绝:比如全屏请求不是在事件处理函数中调用,会在这里拦截到错误
+   * @param {Function} enterErrorFn 回调
+   */
+  const screenError = () => {
+    const { prefixName } = isFullscreen()
+    const methodName = `on${prefixName}fullscreenerror`
+    document[methodName] = (e) => {
+      ElMessage.error('进入全屏失败')
+    }
+  }
+
+  /**
+   * @description: 监听进入/离开全屏
+   * @param {Function} enter 进入全屏的回调
+   *  @param {Function} quit 离开全屏的回调
+   */
+  const screenChange = (enter, quit) => {
+    const { fullscreenEnabled, prefixName } = isFullscreen()
+    if (!fullscreenEnabled) return
+    const methodName = `on${prefixName}fullscreenchange`
+    document[methodName] = (e) => {
+      if (isElementFullScreen()) {
+        enter && enter(e) // 进入全屏回调
+      } else {
+        quit && quit(e) // 离开全屏的回调
+      }
+    }
+  }
+
+  onMounted(() => {
+    screenError()
+  })
+
+  return {
+    isFullscreen,
+    isElementFullScreen,
+    Fullscreen,
+    exitFullscreen,
+    screenChange,
+  }
+}

+ 39 - 0
src/hooks/useResizeElement.ts

@@ -0,0 +1,39 @@
+import ResizeObserver from 'resize-observer-polyfill'
+import { onBeforeUnmount } from 'vue'
+import requestAnimationFrameThrottle from '@/utils/requestAnimationFrameThrottle'
+export const useResizeElement = (chart, chartsRef) => {
+  let observer = null
+  let widthW = 0
+  let heightW = 0
+  const handleResize = (entries) => {
+    const { contentRect } = entries[0]
+    let { width, height } = contentRect
+    width = Math.floor(width)
+    height = Math.floor(height)
+    if (widthW !== width || heightW !== height) {
+      widthW = width
+      heightW = height
+      chart && chart.resize()
+    }
+  }
+  const addObserver = () => {
+    observer = new ResizeObserver(requestAnimationFrameThrottle(handleResize))
+    observer.observe(chartsRef)
+  }
+
+  const removeObserver = () => {
+    if (observer) {
+      observer.disconnect()
+      observer = null
+    }
+    chart && chart.dispose()
+  }
+
+  onBeforeUnmount(() => {
+    removeObserver()
+  })
+
+  return {
+    addObserver,
+  }
+}

+ 66 - 0
src/hooks/useResizeHandler.ts

@@ -0,0 +1,66 @@
+import { useSettingStore } from '@/store/modules/setting'
+import { computed, onMounted, onUnmounted, watch } from 'vue'
+import { useRoute } from 'vue-router'
+
+const { body } = document
+
+const WIDTH = 800 // refer to Bootstrap's responsive design
+const MAX_WIDTH = 1200
+
+export const useResizeHandler = () => {
+  const SettingStore = useSettingStore()
+  const route = useRoute()
+  const device = computed(() => {
+    return SettingStore.device
+  })
+  function $_isMobile() {
+    const rect = body.getBoundingClientRect()
+    return rect.width - 1 < WIDTH
+  }
+
+  function collapse() {
+    const rect = body.getBoundingClientRect()
+    if (rect.width - 1 > MAX_WIDTH) {
+      return true
+    } else {
+      return false
+    }
+  }
+
+  function $_resizeHandler() {
+    if (!document.hidden) {
+      // bool型,表示页面是否处于隐藏状态。页面隐藏包括页面在后台标签页或者浏览器最小化
+      const isMobile = $_isMobile()
+      const isCollapse = collapse()
+      SettingStore.toggleDevice(isMobile ? 'mobile' : 'desktop')
+
+      if (isMobile) {
+        SettingStore.closeSideBar({ withoutAnimation: true })
+      }
+
+      if (!isMobile) {
+        SettingStore.setCollapse(isCollapse)
+      }
+    }
+  }
+  onMounted(() => {
+    const isMobile = $_isMobile()
+    if (isMobile) {
+      SettingStore.toggleDevice('mobile')
+      SettingStore.closeSideBar({ withoutAnimation: true })
+    }
+    window.addEventListener('resize', $_resizeHandler)
+
+    watch(route, () => {
+      if (device.value === 'mobile' && SettingStore.isCollapse) {
+        SettingStore.closeSideBar({ withoutAnimation: false })
+      }
+    })
+  })
+
+  onUnmounted(() => {
+    window.removeEventListener('resize', $_resizeHandler)
+  })
+
+  return { device }
+}

+ 23 - 0
src/hooks/useWrapComponents.ts

@@ -0,0 +1,23 @@
+// 自定义name的壳的集合
+import { h } from 'vue'
+
+const wrapperMap = new Map()
+
+export const useWrapComponents = (Component, route) => {
+  let wrapper
+  if (Component) {
+    const wrapperName = route.name
+    if (wrapperMap.has(wrapperName)) {
+      wrapper = wrapperMap.get(wrapperName)
+    } else {
+      wrapper = {
+        name: wrapperName,
+        render() {
+          return h('div', { className: 'app-main-inner' }, Component)
+        },
+      }
+      wrapperMap.set(wrapperName, wrapper)
+    }
+    return h(wrapper)
+  }
+}

+ 10 - 0
src/icons/index.js

@@ -0,0 +1,10 @@
+import Vue from 'vue'
+import SvgIcon from '@/components/SvgIcon' // svg component
+
+// const req = require.context('./svg', false, /\.svg$/)
+const req = import.meta.globEager('./svg/*.svg')
+
+const requireAll = (requireContext) => requireContext.keys().map(requireContext)
+requireAll(req)
+
+export default SvgIcon

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/icons/svg/borrow.svg


+ 1 - 0
src/icons/svg/compass.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1611049126119" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6991" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M507.592348 170.411409l286.702191 850.632348-286.702191-184.943305L222.608696 1021.043757l284.983652-850.632348z m-57.904974-63.256487V2.72473h13.677078l38.039374 65.82094 11.112626 21.512904h0.712348c-0.712348-10.542748-1.709635-22.225252-1.709635-33.052939V2.72473h12.537322v104.430192h-13.534609l-38.039374-65.963409-11.255095-21.512904h-0.569879c0.569878 10.542748 1.567165 21.655374 1.567166 32.62553v54.850783h-12.537322z" p-id="6992"></path></svg>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/icons/svg/dashboard.svg


+ 1 - 0
src/icons/svg/entrust.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1611639887130" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2534" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M12.672 576.896c-15.744-17.92-15.744-37.12 0-57.92 26.048-22.4 63.232-21.312 111.552 3.456l169.92 123.84H512l63.488-56.064-111.68-21.184C407.744 558.72 381.12 537.6 384 505.6c2.816-31.872 19.904-51.584 51.2-59.008h333.952a12.8 12.8 0 0 1 8.64 3.328l236.8 216.448a12.8 12.8 0 0 1 0.768 18.112L823.424 893.952a12.8 12.8 0 0 1-17.472 1.28l-109.76-89.024H274.304a12.8 12.8 0 0 1-8.512-3.264L12.672 576.896z m93.952-215.68a12.8 12.8 0 0 1-12.8-12.8v-51.2c0-7.104 5.76-12.8 12.8-12.8h486.4c7.04 0 12.8 5.696 12.8 12.8v51.2a12.8 12.8 0 0 1-12.8 12.8h-486.4z m0-153.344a12.8 12.8 0 0 1-12.8-12.8v-51.2c0-7.04 5.76-12.8 12.8-12.8h486.4c7.04 0 12.8 5.76 12.8 12.8v51.2a12.8 12.8 0 0 1-12.8 12.8h-486.4z" p-id="2535"></path></svg>

+ 1 - 0
src/icons/svg/example.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 1 - 0
src/icons/svg/exit-fullscreen.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg>

+ 1 - 0
src/icons/svg/eye-open.svg

@@ -0,0 +1 @@
+<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

+ 1 - 0
src/icons/svg/eye.svg

@@ -0,0 +1 @@
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/icons/svg/form.svg


+ 1 - 0
src/icons/svg/fullscreen.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>

+ 1 - 0
src/icons/svg/go-out.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1597029567541" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10079" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M73.56 719.53l139.377-139.377a50.404 50.404 0 0 1 47.047-15.246c14.336 3.754 20.992 15.246 24.804 28.16 3.811 12.97-3.812 36.181-17.351 47.786l-74.81 70.429h290.987c16.896 0 32.598 5.916 41.017 20.537a47.388 47.388 0 0 1 0 47.445c-8.42 14.62-24.12 19.342-41.017 19.342H192.628l74.809 72.59c12.003 11.947 21.845 33.337 17.35 47.787-4.55 14.507-13.425 21.049-25.998 24.52-12.572 3.413-33.848-0.171-45.852-12.118L70.715 789.163a47.332 47.332 0 0 1-13.312-40.335 47.275 47.275 0 0 1 16.156-29.297z" p-id="10080"></path><path d="M718.62 944.754a47.388 47.388 0 0 1-41.016-23.723c-8.534-14.62-8.534-25.088 0-39.765A47.388 47.388 0 0 1 718.62 857.6h150.073l-3.015-495.275L512 152.405 143.132 362.382v116.054c0 26.168-17.066 45.226-43.235 45.226-26.283-0.057-43.008-19.058-43.008-45.226V336.213c0-16.327 8.363-31.573 22.243-40.277L486.798 62.692a47.388 47.388 0 0 1 50.29 0l393.216 233.244c13.88 8.704 22.357 23.893 22.3 40.334l3.016 561.095c0 26.17-21.22 47.389-47.446 47.389h-189.61 0.056z" p-id="10081"></path></svg>

+ 1 - 0
src/icons/svg/home.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1598501102472" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5445" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M515.072 47.104c1.024 0 4.096 0 6.144 2.048l422.912 422.912c-32.768 2.048-55.296 25.6-55.296 59.392l0 430.08c-3.072 8.192-8.192 14.336-10.24 15.36l-200.704 0c-3.072 0-9.216-6.144-10.24-9.216L667.648 727.04c0-34.816-24.576-59.392-59.392-59.392L417.792 667.648c-34.816 0-59.392 24.576-59.392 59.392l0 239.616c0 2.048 0 9.216-9.216 9.216l-201.728 0c-3.072 0-9.216-6.144-10.24-9.216L137.216 537.6c0-33.792-22.528-58.368-55.296-59.392L508.928 49.152C510.976 47.104 514.048 47.104 515.072 47.104M515.072 6.144C502.784 6.144 489.472 11.264 480.256 20.48l-466.944 466.944c-6.144 6.144-25.6 31.744 6.144 31.744l56.32 0c12.288 0 18.432 6.144 18.432 18.432l0 429.056c0 25.6 25.6 50.176 50.176 50.176L348.16 1016.832c31.744 0 50.176-25.6 50.176-50.176L398.336 727.04c0-12.288 6.144-18.432 18.432-18.432l189.44 0c12.288 0 18.432 6.144 18.432 18.432l0 239.616c0 25.6 25.6 50.176 50.176 50.176l201.728 0c25.6 0 44.032-25.6 50.176-50.176L926.72 531.456c0-12.288 6.144-18.432 18.432-18.432l56.32 0c39.936 0 12.288-25.6 12.288-25.6L549.888 20.48C540.672 11.264 527.36 6.144 515.072 6.144L515.072 6.144z" p-id="5446"></path></svg>

+ 1 - 0
src/icons/svg/horn.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1598520407375" class="icon" viewBox="0 0 1144 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1915" xmlns:xlink="http://www.w3.org/1999/xlink" width="223.4375" height="200"><defs><style type="text/css"></style></defs><path d="M787.012239 1024L260.43588 797.717621H0V226.232989h260.43588L787.012239 0zM43.21665 754.500971h226.109513l474.469426 203.859111v-892.732512l-474.469426 203.859112H43.21665zM855.763755 801.113215v-43.21665c135.6015 0 245.915086-110.313586 245.915086-245.915086s-110.313586-245.927434-245.915086-245.927434v-43.21665a287.242551 287.242551 0 0 1 204.451798 84.679939 287.242551 287.242551 0 0 1 84.692286 204.464145 287.242551 287.242551 0 0 1-84.692286 204.451797 287.242551 287.242551 0 0 1-204.451798 84.679939z" p-id="1916"></path></svg>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/icons/svg/inquiry.svg


+ 1 - 0
src/icons/svg/link.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

+ 1 - 0
src/icons/svg/nested.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 1 - 0
src/icons/svg/notice.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1602473140401" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.390625" height="200"><defs><style type="text/css"></style></defs><path d="M990.802993 1024H52.604489c-18.386035 0-33.197007-14.810973-33.197008-33.197007V395.299751c0-18.386035 14.810973-33.197007 33.197008-33.197008H990.802993c18.386035 0 33.197007 14.810973 33.197007 33.197008V990.802993c0 18.386035-14.810973 33.197007-33.197007 33.197007z m-915.215961-56.179551h892.233417V418.282294H75.587032v549.538155z" p-id="4055"></path><path d="M518.894763 64.351122m-64.351122 0a64.351122 64.351122 0 1 0 128.702244 0 64.351122 64.351122 0 1 0-128.702244 0Z" p-id="4056"></path><path d="M766.084788 403.471322l-244.636409-244.636409L277.322693 403.471322l-39.836409-39.836409 283.962095-284.472818 284.472818 284.472818z" p-id="4057"></path><path d="M821.753616 631.253865H221.653865c-15.321696 0-28.089776-12.76808-28.089775-28.089775s12.76808-28.089776 28.089775-28.089776h600.099751c15.321696 0 28.089776 12.76808 28.089776 28.089776s-12.76808 28.089776-28.089776 28.089775zM524.512718 805.410474H221.653865c-15.321696 0-28.089776-12.76808-28.089775-28.089776s12.76808-28.089776 28.089775-28.089775h302.858853c15.321696 0 28.089776 12.76808 28.089776 28.089775s-12.76808 28.089776-28.089776 28.089776z" p-id="4058"></path></svg>

+ 1 - 0
src/icons/svg/password.svg

@@ -0,0 +1 @@
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

+ 1 - 0
src/icons/svg/put-in.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1597029634880" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10822" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M514.332 719.53L374.955 580.154a50.404 50.404 0 0 0-47.047-15.246c-14.336 3.754-20.992 15.246-24.804 28.16-3.812 12.97 3.812 36.181 17.351 47.786l74.809 70.429H104.277c-16.896 0-32.597 5.916-41.017 20.537a47.388 47.388 0 0 0 0 47.445c8.42 14.62 24.121 19.342 41.017 19.342h290.987l-74.809 72.59c-12.003 11.947-21.845 33.337-17.351 47.787 4.551 14.507 13.426 21.049 25.998 24.52 12.573 3.413 33.85-0.171 45.853-12.118l142.222-142.222a47.332 47.332 0 0 0 13.312-40.335 47.275 47.275 0 0 0-16.157-29.297z" p-id="10823"></path><path d="M718.62 944.754a47.388 47.388 0 0 1-41.016-23.723c-8.534-14.62-8.534-25.088 0-39.765A47.388 47.388 0 0 1 718.62 857.6h150.073l-3.015-495.275L512 152.405 143.132 362.382v116.054c0 26.168-17.066 45.226-43.235 45.226-26.283-0.057-43.008-19.058-43.008-45.226V336.213c0-16.327 8.363-31.573 22.243-40.277L486.798 62.692a47.388 47.388 0 0 1 50.29 0l393.216 233.244c13.88 8.704 22.357 23.893 22.3 40.334l3.016 561.095c0 26.17-21.22 47.389-47.446 47.389h-189.61z" p-id="10824"></path></svg>

+ 1 - 0
src/icons/svg/report-form.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1597029353518" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8423" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M938.688 938.688V512H1024v512H0v-85.312h938.688zM682.688 0H1024v341.312h-85.312V145.088l-384 384L384 358.4 115.2 627.2l-59.712-59.712L384 238.912 554.688 409.6l324.224-324.288h-196.224V0zM213.312 640h85.376v213.312H213.312V640zM384 554.688h85.312v298.624H384V554.688zM554.688 640H640v213.312H554.688V640z m170.624-170.688h85.376v384h-85.376v-384z" p-id="8424"></path></svg>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
src/icons/svg/settings.svg


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff