diff --git a/.gitignore b/.gitignore index 403adbc1..978f3df8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,23 @@ -.DS_Store -node_modules -/dist - - -# local env files -.env.local -.env.*.local - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md index b761442f..0d1616e1 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,10 @@ # vue-manage-system -<a href="https://github.com/vuejs/vue"> - <img src="https://img.shields.io/badge/vue-3.1.2-brightgreen.svg" alt="vue"> - </a> - <a href="https://github.com/vuejs/pinia"> - <img src="https://img.shields.io/badge/pinia-2.0.14-brightgreen.svg" alt="pinia"> - </a> - <a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> - <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> - </a> <a href="https://github.com/lin-xin/vue-manage-system/releases"> <img src="https://img.shields.io/github/release/lin-xin/vue-manage-system.svg" alt="GitHub release"> </a> - <a href="https://lin-xin.gitee.io/example/work/#/donate"> - <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate"> + <a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE"> + <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license"> </a> 基于 Vue3 + pinia + Element Plus 的后台管理系统解决方案。[线上地址](https://lin-xin.gitee.io/example/work/) @@ -28,7 +19,7 @@ [<img src="https://static.bestqa.net/logo/bestqa_haowen.png" width="220" height="100">](https://www.bestqa.net/home/index.html) -专业问卷服务,一对一客服,按需定制 +专业问卷服务,一对一客服,按需定制 ## 支持作者 @@ -46,21 +37,20 @@ - [x] vite 3 - [x] pinia - [x] typescript -- [x] 登录/注销 +- [x] 登录/注册 - [x] Dashboard -- [x] 表格 -- [x] Tab 选项卡 -- [x] 表单 +- [x] 表格/表单 - [x] 图表 :bar_chart: -- [x] 富文本/markdown编辑器 +- [x] 富文本/markdown 编辑器 - [x] 图片拖拽/裁剪上传 - [x] 权限管理 - [x] 三级菜单 - [x] 自定义图标 - +- [x] 主题切换 ## 安装步骤 -> 因为使用vite3,node版本需要 14.18+ + +> 因为使用 vite3,node 版本需要 14.18+ ``` git clone https://github.com/lin-xin/vue-manage-system.git // 把模板下载到本地 @@ -74,64 +64,16 @@ npm run dev npm run build ``` -## 组件使用说明与演示 - -### vue-schart - -vue.js 封装 sChart.js 的图表组件。访问地址:[vue-schart](https://github.com/lin-xin/vue-schart#/) - -<p><a href="https://www.npmjs.com/package/vue-schart"><img src="https://img.shields.io/npm/dm/vue-schart.svg" alt="Downloads"></a></p> - -```html -<template> - <div> - <schart class="wrapper" canvasId="myCanvas" :options="options"></schart> - </div> -</template> - -<script setup lang="ts"> -import { ref } from 'vue'; -import Schart from "vue-schart"; // 导入Schart组件 -const options = ref({ - type: "bar", - title: { - text: "最近一周各品类销售图", - }, - labels: ["周一", "周二", "周三", "周四", "周五"], - datasets: [ - { - label: "家电", - data: [234, 278, 270, 190, 230], - }, - { - label: "百货", - data: [164, 178, 190, 135, 160], - }, - { - label: "食品", - data: [144, 198, 150, 235, 120], - }, - ], -}) -</script> -<style> - .wrapper { - width: 7rem; - height: 5rem; - } -</style> -``` - ## 项目截图 -### 登录 - - - ### 首页  +### 登录 + + + ## License [MIT](https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE) diff --git a/components.d.ts b/components.d.ts index ca55e424..fe2b2b7f 100644 --- a/components.d.ts +++ b/components.d.ts @@ -7,17 +7,24 @@ export {} declare module '@vue/runtime-core' { export interface GlobalComponents { + Countup: typeof import('./src/components/countup.vue')['default'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElButton: typeof import('element-plus/es')['ElButton'] + ElCalendar: typeof import('element-plus/es')['ElCalendar'] ElCard: typeof import('element-plus/es')['ElCard'] + ElCarousel: typeof import('element-plus/es')['ElCarousel'] + ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] ElCascader: typeof import('element-plus/es')['ElCascader'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElCol: typeof import('element-plus/es')['ElCol'] + ElColorPicker: typeof import('element-plus/es')['ElColorPicker'] + ElCountdown: typeof import('element-plus/es')['ElCountdown'] ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem'] ElDialog: typeof import('element-plus/es')['ElDialog'] + ElDivider: typeof import('element-plus/es')['ElDivider'] ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] @@ -26,6 +33,7 @@ declare module '@vue/runtime-core' { ElIcon: typeof import('element-plus/es')['ElIcon'] ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] + ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElLink: typeof import('element-plus/es')['ElLink'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] @@ -33,9 +41,17 @@ declare module '@vue/runtime-core' { ElPagination: typeof import('element-plus/es')['ElPagination'] ElProgress: typeof import('element-plus/es')['ElProgress'] ElRadio: typeof import('element-plus/es')['ElRadio'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] + ElRate: typeof import('element-plus/es')['ElRate'] + ElResult: typeof import('element-plus/es')['ElResult'] ElRow: typeof import('element-plus/es')['ElRow'] ElSelect: typeof import('element-plus/es')['ElSelect'] + ElSlider: typeof import('element-plus/es')['ElSlider'] + ElSpace: typeof import('element-plus/es')['ElSpace'] + ElStatistic: typeof import('element-plus/es')['ElStatistic'] + ElStep: typeof import('element-plus/es')['ElStep'] + ElSteps: typeof import('element-plus/es')['ElSteps'] ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] @@ -43,15 +59,23 @@ declare module '@vue/runtime-core' { ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] + ElTimeline: typeof import('element-plus/es')['ElTimeline'] + ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] ElTimePicker: typeof import('element-plus/es')['ElTimePicker'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTour: typeof import('element-plus/es')['ElTour'] + ElTourStep: typeof import('element-plus/es')['ElTourStep'] + ElTransfer: typeof import('element-plus/es')['ElTransfer'] ElUpload: typeof import('element-plus/es')['ElUpload'] + ElWatermark: typeof import('element-plus/es')['ElWatermark'] Header: typeof import('./src/components/header.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] Sidebar: typeof import('./src/components/sidebar.vue')['default'] + TableCustom: typeof import('./src/components/table-custom.vue')['default'] TableDetail: typeof import('./src/components/table-detail.vue')['default'] TableEdit: typeof import('./src/components/table-edit.vue')['default'] - Tags: typeof import('./src/components/tags.vue')['default'] + TableSearch: typeof import('./src/components/table-search.vue')['default'] + Tabs: typeof import('./src/components/tabs.vue')['default'] } } diff --git a/index.html b/index.html index acbcb53e..e25abe55 100644 --- a/index.html +++ b/index.html @@ -6,13 +6,13 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>vue-manage-system后台管理系统</title> - <link rel="stylesheet" href="https://at.alicdn.com/t/font_830376_qzecyukz0s.css"> + <link rel="stylesheet" href="//at.alicdn.com/t/c/font_830376_92o68tc95je.css"> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. - Please enable it to continue.</strong> + Please enable it to continue.</strong> </noscript> <div id="app"></div> <script type="module" src="/src/main.ts"></script> diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index eeec21e2..00000000 --- a/package-lock.json +++ /dev/null @@ -1,1298 +0,0 @@ -{ - "name": "vue-manage-system", - "version": "5.3.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@antfu/utils": { - "version": "0.5.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/@antfu/utils/-/utils-0.5.2.tgz", - "integrity": "sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA==", - "dev": true - }, - "@babel/parser": { - "version": "7.18.11", - "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.18.11.tgz", - "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==" - }, - "@babel/runtime": { - "version": "7.18.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/runtime-corejs3": { - "version": "7.18.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz", - "integrity": "sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A==", - "requires": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" - } - }, - "@ctrl/tinycolor": { - "version": "3.4.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", - "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" - }, - "@element-plus/icons-vue": { - "version": "2.0.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@element-plus/icons-vue/-/icons-vue-2.0.9.tgz", - "integrity": "sha512-okdrwiVeKBmW41Hkl0eMrXDjzJwhQMuKiBOu17rOszqM+LS/yBYpNQNV5Jvoh06Wc+89fMmb/uhzf8NZuDuUaQ==" - }, - "@esbuild/linux-loong64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", - "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", - "dev": true, - "optional": true - }, - "@floating-ui/core": { - "version": "0.7.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/@floating-ui/core/-/core-0.7.3.tgz", - "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" - }, - "@floating-ui/dom": { - "version": "0.5.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/@floating-ui/dom/-/dom-0.5.4.tgz", - "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", - "requires": { - "@floating-ui/core": "^0.7.3" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "requires": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - } - }, - "@types/lodash": { - "version": "4.14.184", - "resolved": "https://repo.huaweicloud.com/repository/npm/@types/lodash/-/lodash-4.14.184.tgz", - "integrity": "sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==" - }, - "@types/lodash-es": { - "version": "4.17.6", - "resolved": "https://repo.huaweicloud.com/repository/npm/@types/lodash-es/-/lodash-es-4.17.6.tgz", - "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==", - "requires": { - "@types/lodash": "*" - } - }, - "@types/marked": { - "version": "4.0.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/@types/marked/-/marked-4.0.5.tgz", - "integrity": "sha512-jMN2moJ+lSf1VZXQo3VXeMCjoXuciVONig8+U0YNBop5aBvQw4qkolx1Nzn1i0T8L2l9IZ3jju6bS1pPwlaY1w==" - }, - "@types/web-bluetooth": { - "version": "0.0.15", - "resolved": "https://repo.huaweicloud.com/repository/npm/@types/web-bluetooth/-/web-bluetooth-0.0.15.tgz", - "integrity": "sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA==" - }, - "@vitejs/plugin-vue": { - "version": "3.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vitejs/plugin-vue/-/plugin-vue-3.0.3.tgz", - "integrity": "sha512-U4zNBlz9mg+TA+i+5QPc3N5lQvdUXENZLO2h0Wdzp56gI1MWhqJOv+6R+d4kOzoaSSq6TnGPBdZAXKOe4lXy6g==", - "dev": true - }, - "@volar/code-gen": { - "version": "0.38.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@volar/code-gen/-/code-gen-0.38.9.tgz", - "integrity": "sha512-n6LClucfA+37rQeskvh9vDoZV1VvCVNy++MAPKj2dT4FT+Fbmty/SDQqnsEBtdEe6E3OQctFvA/IcKsx3Mns0A==", - "dev": true, - "requires": { - "@volar/source-map": "0.38.9" - } - }, - "@volar/source-map": { - "version": "0.38.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@volar/source-map/-/source-map-0.38.9.tgz", - "integrity": "sha512-ba0UFoHDYry+vwKdgkWJ6xlQT+8TFtZg1zj9tSjj4PykW1JZDuM0xplMotLun4h3YOoYfY9K1huY5gvxmrNLIw==", - "dev": true - }, - "@volar/vue-code-gen": { - "version": "0.38.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@volar/vue-code-gen/-/vue-code-gen-0.38.9.tgz", - "integrity": "sha512-tzj7AoarFBKl7e41MR006ncrEmNPHALuk8aG4WdDIaG387X5//5KhWC5Ff3ZfB2InGSeNT+CVUd74M0gS20rjA==", - "dev": true, - "requires": { - "@volar/code-gen": "0.38.9", - "@volar/source-map": "0.38.9", - "@vue/compiler-core": "^3.2.37", - "@vue/compiler-dom": "^3.2.37", - "@vue/shared": "^3.2.37" - } - }, - "@volar/vue-typescript": { - "version": "0.38.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/@volar/vue-typescript/-/vue-typescript-0.38.9.tgz", - "integrity": "sha512-iJMQGU91ADi98u8V1vXd2UBmELDAaeSP0ZJaFjwosClQdKlJQYc6MlxxKfXBZisHqfbhdtrGRyaryulnYtliZw==", - "dev": true, - "requires": { - "@volar/code-gen": "0.38.9", - "@volar/source-map": "0.38.9", - "@volar/vue-code-gen": "0.38.9", - "@vue/compiler-sfc": "^3.2.37", - "@vue/reactivity": "^3.2.37" - } - }, - "@vue/compiler-core": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/compiler-core/-/compiler-core-3.2.37.tgz", - "integrity": "sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - } - }, - "@vue/compiler-dom": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz", - "integrity": "sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==", - "requires": { - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/compiler-sfc": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz", - "integrity": "sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-ssr": "3.2.37", - "@vue/reactivity-transform": "3.2.37", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - }, - "dependencies": { - "magic-string": { - "version": "0.25.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "@vue/compiler-ssr": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz", - "integrity": "sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==", - "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/devtools-api": { - "version": "6.2.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/devtools-api/-/devtools-api-6.2.1.tgz", - "integrity": "sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==" - }, - "@vue/reactivity": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/reactivity/-/reactivity-3.2.37.tgz", - "integrity": "sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==", - "requires": { - "@vue/shared": "3.2.37" - } - }, - "@vue/reactivity-transform": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz", - "integrity": "sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==", - "requires": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.37", - "@vue/shared": "3.2.37", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" - }, - "dependencies": { - "magic-string": { - "version": "0.25.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "@vue/runtime-core": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/runtime-core/-/runtime-core-3.2.37.tgz", - "integrity": "sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==", - "requires": { - "@vue/reactivity": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/runtime-dom": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz", - "integrity": "sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==", - "requires": { - "@vue/runtime-core": "3.2.37", - "@vue/shared": "3.2.37", - "csstype": "^2.6.8" - } - }, - "@vue/server-renderer": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/server-renderer/-/server-renderer-3.2.37.tgz", - "integrity": "sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==", - "requires": { - "@vue/compiler-ssr": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "@vue/shared": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vue/shared/-/shared-3.2.37.tgz", - "integrity": "sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==" - }, - "@vueuse/core": { - "version": "9.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vueuse/core/-/core-9.1.0.tgz", - "integrity": "sha512-BIroqvXEqt826aE9r3K5cox1zobuPuAzdYJ36kouC2TVhlXvFKIILgFVWrpp9HZPwB3aLzasmG3K87q7TSyXZg==", - "requires": { - "@types/web-bluetooth": "^0.0.15", - "@vueuse/metadata": "9.1.0", - "@vueuse/shared": "9.1.0", - "vue-demi": "*" - } - }, - "@vueuse/metadata": { - "version": "9.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vueuse/metadata/-/metadata-9.1.0.tgz", - "integrity": "sha512-8OEhlog1iaAGTD3LICZ8oBGQdYeMwByvXetOtAOZCJOzyCRSwqwdggTsmVZZ1rkgYIEqgUBk942AsAPwM21s6A==" - }, - "@vueuse/shared": { - "version": "9.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/@vueuse/shared/-/shared-9.1.0.tgz", - "integrity": "sha512-pB/3njQu4tfJJ78ajELNda0yMG6lKfpToQW7Soe09CprF1k3QuyoNi1tBNvo75wBDJWD+LOnr+c4B5HZ39jY/Q==", - "requires": { - "vue-demi": "*" - } - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true - }, - "adler-32": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", - "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "async-validator": { - "version": "4.2.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/async-validator/-/async-validator-4.2.5.tgz", - "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "0.27.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "cfb": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", - "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", - "requires": { - "adler-32": "~1.3.0", - "crc-32": "~1.2.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "codepage": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", - "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "core-js-pure": { - "version": "3.24.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/core-js-pure/-/core-js-pure-3.24.1.tgz", - "integrity": "sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg==" - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" - }, - "cropperjs": { - "version": "1.5.12", - "resolved": "https://repo.huaweicloud.com/repository/npm/cropperjs/-/cropperjs-1.5.12.tgz", - "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==" - }, - "csstype": { - "version": "2.6.20", - "resolved": "https://repo.huaweicloud.com/repository/npm/csstype/-/csstype-2.6.20.tgz", - "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==" - }, - "dayjs": { - "version": "1.11.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/dayjs/-/dayjs-1.11.5.tgz", - "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "element-plus": { - "version": "2.2.14", - "resolved": "https://repo.huaweicloud.com/repository/npm/element-plus/-/element-plus-2.2.14.tgz", - "integrity": "sha512-V5Pis0OHhePg1RgVogZrcefaVl8vjVn4Pn9Qsh/t2CbFgjg9kKOYFqf/tuP3ObSXGm3X89hpe0W+nLVAsaFnpw==", - "requires": { - "@ctrl/tinycolor": "^3.4.1", - "@element-plus/icons-vue": "^2.0.6", - "@floating-ui/dom": "^0.5.4", - "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", - "@types/lodash": "^4.14.182", - "@types/lodash-es": "^4.17.6", - "@vueuse/core": "^9.1.0", - "async-validator": "^4.2.5", - "dayjs": "^1.11.3", - "escape-html": "^1.0.3", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "lodash-unified": "^1.0.2", - "memoize-one": "^6.0.0", - "normalize-wheel-es": "^1.2.0" - }, - "dependencies": { - "@popperjs/core": { - "version": "npm:@sxzz/popperjs-es@2.11.7", - "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", - "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==" - } - } - }, - "esbuild": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild/-/esbuild-0.14.54.tgz", - "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", - "dev": true, - "requires": { - "@esbuild/linux-loong64": "0.14.54", - "esbuild-android-64": "0.14.54", - "esbuild-android-arm64": "0.14.54", - "esbuild-darwin-64": "0.14.54", - "esbuild-darwin-arm64": "0.14.54", - "esbuild-freebsd-64": "0.14.54", - "esbuild-freebsd-arm64": "0.14.54", - "esbuild-linux-32": "0.14.54", - "esbuild-linux-64": "0.14.54", - "esbuild-linux-arm": "0.14.54", - "esbuild-linux-arm64": "0.14.54", - "esbuild-linux-mips64le": "0.14.54", - "esbuild-linux-ppc64le": "0.14.54", - "esbuild-linux-riscv64": "0.14.54", - "esbuild-linux-s390x": "0.14.54", - "esbuild-netbsd-64": "0.14.54", - "esbuild-openbsd-64": "0.14.54", - "esbuild-sunos-64": "0.14.54", - "esbuild-windows-32": "0.14.54", - "esbuild-windows-64": "0.14.54", - "esbuild-windows-arm64": "0.14.54" - } - }, - "esbuild-android-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", - "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", - "dev": true, - "optional": true - }, - "esbuild-android-arm64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", - "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", - "dev": true, - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", - "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", - "dev": true, - "optional": true - }, - "esbuild-darwin-arm64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", - "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", - "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", - "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", - "dev": true, - "optional": true - }, - "esbuild-linux-32": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", - "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", - "dev": true, - "optional": true - }, - "esbuild-linux-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", - "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", - "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", - "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", - "dev": true, - "optional": true - }, - "esbuild-linux-mips64le": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", - "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", - "dev": true, - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", - "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", - "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", - "dev": true, - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", - "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", - "dev": true, - "optional": true - }, - "esbuild-netbsd-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", - "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", - "dev": true, - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", - "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", - "dev": true, - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", - "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", - "dev": true, - "optional": true - }, - "esbuild-windows-32": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", - "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", - "dev": true, - "optional": true - }, - "esbuild-windows-64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", - "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", - "dev": true, - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.14.54", - "resolved": "https://repo.huaweicloud.com/repository/npm/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", - "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", - "dev": true, - "optional": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://repo.huaweicloud.com/repository/npm/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "frac": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", - "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "jsonc-parser": { - "version": "3.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", - "dev": true - }, - "local-pkg": { - "version": "0.4.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/local-pkg/-/local-pkg-0.4.2.tgz", - "integrity": "sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==", - "dev": true - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://repo.huaweicloud.com/repository/npm/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash-es": { - "version": "4.17.21", - "resolved": "https://repo.huaweicloud.com/repository/npm/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "lodash-unified": { - "version": "1.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/lodash-unified/-/lodash-unified-1.0.2.tgz", - "integrity": "sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==" - }, - "magic-string": { - "version": "0.26.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/magic-string/-/magic-string-0.26.2.tgz", - "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - }, - "md-editor-v3": { - "version": "2.2.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/md-editor-v3/-/md-editor-v3-2.2.1.tgz", - "integrity": "sha512-nOd8mlEhvC99l9Y8pDMwEi6EdCAeBp88Ffl24We+2uz3/Iympctm92L1qyNicONJRhtZJacQ4oWTQGMYKGAxVg==", - "requires": { - "@types/marked": "^4.0.3" - } - }, - "memoize-one": { - "version": "6.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://repo.huaweicloud.com/repository/npm/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "5.1.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "mlly": { - "version": "0.5.13", - "resolved": "https://repo.huaweicloud.com/repository/npm/mlly/-/mlly-0.5.13.tgz", - "integrity": "sha512-0SK2fqoan+PMjADs4I2egAtrtNtpjqRez6PDTCeAdGjUQNJCvO5o9v2NEq52WA1jFmMU97qBr/JgdvCquehDbA==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "pathe": "^0.3.4", - "pkg-types": "^0.3.3", - "ufo": "^0.8.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-wheel-es": { - "version": "1.2.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", - "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://repo.huaweicloud.com/repository/npm/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "pathe": { - "version": "0.3.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/pathe/-/pathe-0.3.5.tgz", - "integrity": "sha512-grU/QeYP0ChuE5kjU2/k8VtAeODzbernHlue0gTa27+ayGIu3wqYBIPGfP9r5xSqgCgDd4nWrjKXEfxMillByg==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pinia": { - "version": "2.0.20", - "resolved": "https://repo.huaweicloud.com/repository/npm/pinia/-/pinia-2.0.20.tgz", - "integrity": "sha512-fdHHumXW/0U5HhxmY1emo3I4z85p8NJPdbtFQSlmJXFe3ktuF0pYNVgVtk2q+j2zCtTufY763xzaEMx0t6T59g==", - "requires": { - "@vue/devtools-api": "^6.2.1", - "vue-demi": "*" - } - }, - "pkg-types": { - "version": "0.3.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/pkg-types/-/pkg-types-0.3.4.tgz", - "integrity": "sha512-s214f/xkRpwlwVBToWq9Mu0XlU3HhZMYCnr2var8+jjbavBHh/VCh4pBLsJW29rJ//B1jb4HlpMIaNIMH+W2/w==", - "dev": true, - "requires": { - "jsonc-parser": "^3.1.0", - "mlly": "^0.5.13", - "pathe": "^0.3.5" - } - }, - "postcss": { - "version": "8.4.16", - "resolved": "https://repo.huaweicloud.com/repository/npm/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rollup": { - "version": "2.77.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/rollup/-/rollup-2.77.3.tgz", - "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "schart.js": { - "version": "3.0.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/schart.js/-/schart.js-3.0.4.tgz", - "integrity": "sha512-uylb2u9rrHX1jyAuSAJUQON8XTfyDKI9kWj1J3fUlCQCkLVZ4HG4+IiV8qm//Z71dqvLI78QZ/fCBw0reB22Zw==" - }, - "scule": { - "version": "0.3.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/scule/-/scule-0.3.2.tgz", - "integrity": "sha512-zIvPdjOH8fv8CgrPT5eqtxHQXmPNnV/vHJYffZhE43KZkvULvpCTvOt1HPlFaCZx287INL9qaqrZg34e8NgI4g==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "ssf": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", - "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", - "requires": { - "frac": "~1.1.2" - } - }, - "strip-literal": { - "version": "0.4.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/strip-literal/-/strip-literal-0.4.0.tgz", - "integrity": "sha512-ql/sBDoJOybTKSIOWrrh8kgUEMjXMwRAkZTD0EwiwxQH/6tTPkZvMIEjp0CRlpi6V5FMiJyvxeRkEi1KrGISoA==", - "dev": true, - "requires": { - "acorn": "^8.7.1" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://repo.huaweicloud.com/repository/npm/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", - "dev": true - }, - "ufo": { - "version": "0.8.5", - "resolved": "https://repo.huaweicloud.com/repository/npm/ufo/-/ufo-0.8.5.tgz", - "integrity": "sha512-e4+UtA5IRO+ha6hYklwj6r7BjiGMxS0O+UaSg9HbaTefg4kMkzj4tXzEBajRR+wkxf+golgAWKzLbytCUDMJAA==", - "dev": true - }, - "unimport": { - "version": "0.6.7", - "resolved": "https://repo.huaweicloud.com/repository/npm/unimport/-/unimport-0.6.7.tgz", - "integrity": "sha512-EMoVqDjswHkU+nD098QYHXH7Mkw7KwGDQAyeRF2lgairJnuO+wpkhIcmCqrD1OPJmsjkTbJ2tW6Ap8St0PuWZA==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^4.2.1", - "escape-string-regexp": "^5.0.0", - "fast-glob": "^3.2.11", - "local-pkg": "^0.4.2", - "magic-string": "^0.26.2", - "mlly": "^0.5.7", - "pathe": "^0.3.3", - "scule": "^0.3.2", - "strip-literal": "^0.4.0", - "unplugin": "^0.9.0" - } - }, - "unplugin": { - "version": "0.9.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/unplugin/-/unplugin-0.9.3.tgz", - "integrity": "sha512-GWXxizZG+tobNs8fuGTCeilerkkfZTZax2iivuE4pxLaF9wTnPJHOq8tbLKDb5ohVb+2BXNjrU9xx59yWTUnuw==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "chokidar": "^3.5.3", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.4.4" - } - }, - "unplugin-auto-import": { - "version": "0.11.2", - "resolved": "https://repo.huaweicloud.com/repository/npm/unplugin-auto-import/-/unplugin-auto-import-0.11.2.tgz", - "integrity": "sha512-1+VwBfn9dtiYv9SQLKP1AvZolUbK9xTVeAT+iOcEk4EHSFUlmIqBVLEKI76cifSQTLOJ3rZyPrEgptf3SZNLlQ==", - "dev": true, - "requires": { - "@antfu/utils": "^0.5.2", - "@rollup/pluginutils": "^4.2.1", - "local-pkg": "^0.4.2", - "magic-string": "^0.26.2", - "unimport": "^0.6.7", - "unplugin": "^0.9.3" - } - }, - "unplugin-vue-components": { - "version": "0.22.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/unplugin-vue-components/-/unplugin-vue-components-0.22.4.tgz", - "integrity": "sha512-2rRZcM9OnJGXnYxQNfaceEYuPeVACcWySIjy8WBwIiN3onr980TmA3XE5pRJFt8zoQrUA+c46oyIq96noLqrEQ==", - "dev": true, - "requires": { - "@antfu/utils": "^0.5.2", - "@rollup/pluginutils": "^4.2.1", - "chokidar": "^3.5.3", - "debug": "^4.3.4", - "fast-glob": "^3.2.11", - "local-pkg": "^0.4.2", - "magic-string": "^0.26.2", - "minimatch": "^5.1.0", - "resolve": "^1.22.1", - "unplugin": "^0.9.0" - } - }, - "vite": { - "version": "3.0.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/vite/-/vite-3.0.9.tgz", - "integrity": "sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==", - "dev": true, - "requires": { - "esbuild": "^0.14.47", - "fsevents": "~2.3.2", - "postcss": "^8.4.16", - "resolve": "^1.22.1", - "rollup": ">=2.75.6 <2.77.0 || ~2.77.0" - } - }, - "vite-plugin-vue-setup-extend": { - "version": "0.4.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz", - "integrity": "sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==", - "dev": true, - "requires": { - "@vue/compiler-sfc": "^3.2.29", - "magic-string": "^0.25.7" - }, - "dependencies": { - "magic-string": { - "version": "0.25.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "vue": { - "version": "3.2.37", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue/-/vue-3.2.37.tgz", - "integrity": "sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==", - "requires": { - "@vue/compiler-dom": "3.2.37", - "@vue/compiler-sfc": "3.2.37", - "@vue/runtime-dom": "3.2.37", - "@vue/server-renderer": "3.2.37", - "@vue/shared": "3.2.37" - } - }, - "vue-cropperjs": { - "version": "5.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue-cropperjs/-/vue-cropperjs-5.0.0.tgz", - "integrity": "sha512-RhnC8O33uRZNkn74aiHZwNHnBJOXWlS4P6gsRI0lw4cZlWjKSCywZI9oSI9POlIPI6OYv30jvnHMXGch85tw7w==", - "requires": { - "cropperjs": "^1.5.6" - } - }, - "vue-demi": { - "version": "0.13.8", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue-demi/-/vue-demi-0.13.8.tgz", - "integrity": "sha512-Vy1zbZhCOdsmvGR6tJhAvO5vhP7eiS8xkbYQSoVa7o6KlIy3W8Rc53ED4qI4qpeRDjv3mLfXSEpYU6Yq4pgXRg==" - }, - "vue-router": { - "version": "4.1.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue-router/-/vue-router-4.1.3.tgz", - "integrity": "sha512-XvK81bcYglKiayT7/vYAg/f36ExPC4t90R/HIpzrZ5x+17BOWptXLCrEPufGgZeuq68ww4ekSIMBZY1qdUdfjA==", - "requires": { - "@vue/devtools-api": "^6.1.4" - } - }, - "vue-schart": { - "version": "2.0.0", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue-schart/-/vue-schart-2.0.0.tgz", - "integrity": "sha512-qAu3e5wfMcq26wK1xeHExEWfGpnjfoN1R/9QXblNi+AsU/p52X7tTwhi+Fw7H/otfEufhEY2X7z7emaoF4QO+g==", - "requires": { - "schart.js": "^3.0.0" - } - }, - "vue-tsc": { - "version": "0.38.9", - "resolved": "https://repo.huaweicloud.com/repository/npm/vue-tsc/-/vue-tsc-0.38.9.tgz", - "integrity": "sha512-Yoy5phgvGqyF98Fb4mYqboR4Q149jrdcGv5kSmufXJUq++RZJ2iMVG0g6zl+v3t4ORVWkQmRpsV4x2szufZ0LQ==", - "dev": true, - "requires": { - "@volar/vue-typescript": "0.38.9" - } - }, - "wangeditor": { - "version": "4.7.15", - "resolved": "https://repo.huaweicloud.com/repository/npm/wangeditor/-/wangeditor-4.7.15.tgz", - "integrity": "sha512-aPTdREd8BxXVyJ5MI+LU83FQ7u1EPd341iXIorRNYSOvoimNoZ4nPg+yn3FGbB93/owEa6buLw8wdhYnMCJQLg==", - "requires": { - "@babel/runtime": "^7.11.2", - "@babel/runtime-corejs3": "^7.11.2", - "tslib": "^2.1.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true - }, - "webpack-virtual-modules": { - "version": "0.4.4", - "resolved": "https://repo.huaweicloud.com/repository/npm/webpack-virtual-modules/-/webpack-virtual-modules-0.4.4.tgz", - "integrity": "sha512-h9atBP/bsZohWpHnr+2sic8Iecb60GxftXsWNLLLSqewgIsGzByd2gcIID4nXcG+3tNe4GQG3dLcff3kXupdRA==", - "dev": true - }, - "wmf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", - "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==" - }, - "word": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", - "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==" - }, - "xlsx": { - "version": "0.18.5", - "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", - "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", - "requires": { - "adler-32": "~1.3.0", - "cfb": "~1.2.1", - "codepage": "~1.15.0", - "crc-32": "~1.2.1", - "ssf": "~0.11.2", - "wmf": "~1.0.1", - "word": "~0.3.0" - } - } - } -} diff --git a/package.json b/package.json index 06d26155..3423e5a6 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,44 @@ -{ - "name": "vue-manage-system", - "version": "5.3.5", - "private": true, - "scripts": { - "dev": "vite", - "build": "vue-tsc --noEmit && vite build", - "serve": "vite preview" - }, - "dependencies": { - "@element-plus/icons-vue": "*", - "@wangeditor/editor": "^5.1.23", - "@wangeditor/editor-for-vue": "^5.1.12", - "axios": "^1.6.3", - "element-plus": "^2.4.4", - "md-editor-v3": "^2.11.2", - "nprogress": "^0.2.0", - "pinia": "^2.1.7", - "vue": "^3.3.0", - "vue-cropperjs": "^5.0.0", - "vue-router": "^4.2.5", - "vue-schart": "^2.0.0", - "xlsx": "^0.18.5" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^3.0.0", - "@vue/compiler-sfc": "^3.1.2", - "typescript": "^4.6.4", - "unplugin-auto-import": "^0.11.2", - "unplugin-vue-components": "^0.22.4", - "vite": "^3.0.0", - "vite-plugin-vue-setup-extend": "^0.4.0", - "vue-tsc": "^0.38.4" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead" - ] -} +{ + "name": "vue-manage-system", + "version": "5.5.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "serve": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "*", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-vue": "^5.1.12", + "axios": "^1.6.3", + "countup.js": "^2.8.0", + "echarts": "^5.5.0", + "echarts-wordcloud": "^2.1.0", + "element-plus": "^2.6.3", + "md-editor-v3": "^2.11.2", + "nprogress": "^0.2.0", + "pinia": "^2.1.7", + "vue": "^3.4.5", + "vue-cropper": "1.1.1", + "vue-echarts": "^6.6.9", + "vue-router": "^4.2.5", + "vue-schart": "^2.0.0", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^3.0.0", + "@vue/compiler-sfc": "^3.1.2", + "typescript": "^4.6.4", + "unplugin-auto-import": "^0.11.2", + "unplugin-vue-components": "^0.22.4", + "vite": "^3.0.0", + "vite-plugin-vue-setup-extend": "^0.4.0", + "vue-tsc": "^0.38.4" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/public/mock/role.json b/public/mock/role.json new file mode 100644 index 00000000..3ee9f897 --- /dev/null +++ b/public/mock/role.json @@ -0,0 +1,46 @@ +{ + "list": [ + { + "id": 1, + "name": "管理员", + "key": "admin", + "status": true, + "permiss": [ + "0", + "1", + "11", + "12", + "13", + "2", + "21", + "22", + "23", + "24", + "3", + "31", + "32", + "33", + "331", + "332", + "4", + "41", + "42", + "5" + ] + }, + { + "id": 2, + "name": "普通用户", + "key": "user", + "status": true, + "permiss": [ + "0", + "1", + "11", + "12", + "13" + ] + } + ], + "pageTotal": 2 +} \ No newline at end of file diff --git a/public/table.json b/public/mock/table.json similarity index 85% rename from public/table.json rename to public/mock/table.json index ddd2e322..abbbace5 100644 --- a/public/table.json +++ b/public/mock/table.json @@ -1,40 +1,41 @@ -{ - "list": [{ - "id": 1, - "name": "张三", - "money": 123, - "address": "广东省东莞市长安镇", - "state": "成功", - "date": "2019-11-1", - "thumb": "https://lin-xin.gitee.io/images/post/wms.png" - }, - { - "id": 2, - "name": "李四", - "money": 456, - "address": "广东省广州市白云区", - "state": "成功", - "date": "2019-10-11", - "thumb": "https://lin-xin.gitee.io/images/post/node3.png" - }, - { - "id": 3, - "name": "王五", - "money": 789, - "address": "湖南省长沙市", - "state": "失败", - "date": "2019-11-11", - "thumb": "https://lin-xin.gitee.io/images/post/parcel.png" - }, - { - "id": 4, - "name": "赵六", - "money": 1011, - "address": "福建省厦门市鼓浪屿", - "state": "成功", - "date": "2019-10-20", - "thumb": "https://lin-xin.gitee.io/images/post/notice.png" - } - ], - "pageTotal": 4 +{ + "list": [ + { + "id": 1, + "name": "张三", + "money": 123, + "address": "广东省东莞市长安镇", + "state": true, + "date": "2019-11-1", + "thumb": "https://lin-xin.gitee.io/images/post/wms.png" + }, + { + "id": 2, + "name": "李四", + "money": 456, + "address": "广东省广州市白云区", + "state": true, + "date": "2019-10-11", + "thumb": "https://lin-xin.gitee.io/images/post/node3.png" + }, + { + "id": 3, + "name": "王五", + "money": 789, + "address": "湖南省长沙市", + "state": false, + "date": "2019-11-11", + "thumb": "https://lin-xin.gitee.io/images/post/parcel.png" + }, + { + "id": 4, + "name": "赵六", + "money": 1011, + "address": "福建省厦门市鼓浪屿", + "state": true, + "date": "2019-10-20", + "thumb": "https://lin-xin.gitee.io/images/post/notice.png" + } + ], + "pageTotal": 4 } \ No newline at end of file diff --git a/public/mock/user.json b/public/mock/user.json new file mode 100644 index 00000000..079b73bb --- /dev/null +++ b/public/mock/user.json @@ -0,0 +1,23 @@ +{ + "list": [ + { + "id": 1, + "name": "张三", + "password": "123", + "email": "123@qq.com", + "phone": "12345678944", + "date": "2024-01-01", + "role": "管理员" + }, + { + "id": 2, + "name": "李四", + "password": "123", + "email": "1234@qq.com", + "phone": "12345678945", + "date": "2024-01-01", + "role": "普通用户" + } + ], + "pageTotal": 2 +} \ No newline at end of file diff --git a/screenshots/wms1.png b/screenshots/wms1.png index 1bc275f5..92033483 100644 Binary files a/screenshots/wms1.png and b/screenshots/wms1.png differ diff --git a/screenshots/wms3.png b/screenshots/wms3.png index e61c1993..86b96aaf 100644 Binary files a/screenshots/wms3.png and b/screenshots/wms3.png differ diff --git a/src/App.vue b/src/App.vue index 8d681855..a8ce72b2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,14 +1,17 @@ -<template> - <el-config-provider :locale="zhCn"> - <router-view /> - </el-config-provider> -</template> - -<script setup lang="ts"> -import { ElConfigProvider } from 'element-plus'; -import zhCn from 'element-plus/es/locale/lang/zh-cn'; -</script> -<style> -@import './assets/css/main.css'; -@import './assets/css/color-dark.scss'; -</style> +<template> + <el-config-provider :locale="zhCn"> + <router-view /> + </el-config-provider> +</template> + +<script setup lang="ts"> +import { ElConfigProvider } from 'element-plus'; +import zhCn from 'element-plus/es/locale/lang/zh-cn'; +import { useThemeStore } from './store/theme'; + +const theme = useThemeStore(); +theme.initTheme(); +</script> +<style> +@import './assets/css/main.css'; +</style> diff --git a/src/api/index.ts b/src/api/index.ts index 99d85239..2814587b 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,8 +1,22 @@ -import request from '../utils/request'; - -export const fetchData = () => { - return request({ - url: 'https://www.fastmock.site/mock/dc695d037038802def4b989ba4650c3f/vms/getUser', - method: 'post' - }); -}; +import request from '../utils/request'; + +export const fetchData = () => { + return request({ + url: './mock/table.json', + method: 'get' + }); +}; + +export const fetchUserData = () => { + return request({ + url: './mock/user.json', + method: 'get' + }); +}; + +export const fetchRoleData = () => { + return request({ + url: './mock/role.json', + method: 'get' + }); +}; diff --git a/src/assets/css/color-dark.scss b/src/assets/css/color-dark.scss deleted file mode 100644 index a3e0b865..00000000 --- a/src/assets/css/color-dark.scss +++ /dev/null @@ -1,23 +0,0 @@ -.header{ - background-color: #242f42; -} -.login-wrap{ - background: #324157; -} -.plugins-tips{ - background: #eef1f6; -} -.plugins-tips a{ - color: var(--el-color-primary); -} - -.tags-li.active { - border: 1px solid var(--el-color-primary); - background-color: var(--el-color-primary); -} -.message-title{ - color: var(--el-color-primary); -} -.collapse-btn:hover{ - background: rgb(40,52,70); -} \ No newline at end of file diff --git a/src/assets/css/main.css b/src/assets/css/main.css index f6712160..da21f560 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -1,132 +1,95 @@ -* { - margin: 0; - padding: 0; -} - -html, -body, -#app, -.wrapper { - width: 100%; - height: 100%; - overflow: hidden; -} - -body { - font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif; -} - -a { - text-decoration: none -} - - -.content-box { - position: absolute; - left: 250px; - right: 0; - top: 70px; - bottom: 0; - padding-bottom: 30px; - -webkit-transition: left .3s ease-in-out; - transition: left .3s ease-in-out; - background: #f0f0f0; -} - -.content { - width: auto; - height: 100%; - padding: 10px; - overflow-y: scroll; - box-sizing: border-box; -} - -.content-collapse { - left: 65px; -} - -.container { - padding: 30px; - background: #fff; - border: 1px solid #ddd; - border-radius: 5px; -} - -.crumbs { - margin: 10px 0; -} - -.el-table th { - background-color: #f5f7fa !important; -} - -.pagination { - margin: 20px 0; - text-align: right; -} - -.plugins-tips { - padding: 20px 10px; - margin-bottom: 20px; -} - -.el-button+.el-tooltip { - margin-left: 10px; -} - -.mgb20 { - margin-bottom: 20px; -} - -.move-enter-active, -.move-leave-active { - transition: opacity .1s ease; -} - -.move-enter-from, -.move-leave-to { - opacity: 0; -} - -/*BaseForm*/ - -.form-box { - width: 600px; -} - -.form-box .line { - text-align: center; -} - -.el-time-panel__content::after, -.el-time-panel__content::before { - margin-top: -7px; -} - -.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { - padding-bottom: 0; -} - - -[class*=" el-icon-"], [class^=el-icon-] { - font-style: normal; - font-weight: 400; - font-variant: normal; - text-transform: none; - line-height: 1; - vertical-align: baseline; - display: inline-block; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.el-sub-menu [class^=el-icon-] { - vertical-align: middle; - margin-right: 5px; - width: 24px; - text-align: center; - font-size: 18px; -} - -[hidden]{ - display: none !important; -} \ No newline at end of file +* { + margin: 0; + padding: 0; + outline: 0 !important; +} + +html, +body, +#app, +.wrapper { + width: 100%; + height: 100%; + overflow: hidden; +} + +body { + font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif; +} + +a { + text-decoration: none; +} +i { + font-style: normal; +} + +.container { + padding: 30px; + background: #fff; + border: 1px solid #ddd; + border-radius: 5px; +} + +.el-table th { + background-color: #f5f7fa !important; +} + +.plugins-tips { + padding: 20px 10px; + margin-bottom: 20px; + background: #eef1f6; +} + +.plugins-tips a { + color: var(--el-color-primary); +} + +.el-button + .el-tooltip { + margin-left: 10px; +} + +.mgb20 { + margin-bottom: 20px; +} +.mgb10 { + margin-bottom: 10px; +} +.mr10 { + margin-right: 10px; +} + +.move-enter-active, +.move-leave-active { + transition: opacity 0.1s ease; +} + +.move-enter-from, +.move-leave-to { + opacity: 0; +} + +.el-time-panel__content::after, +.el-time-panel__content::before { + margin-top: -7px; +} + +.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default) { + padding-bottom: 0; +} + +[hidden] { + display: none !important; +} + +.flex-center { + display: flex; + justify-content: center; + align-items: center; +} + +:root { + --header-bg-color: #242f42; + --header-text-color: #fff; + --active-color: var(--el-color-primary); +} diff --git a/src/assets/img/logo.svg b/src/assets/img/logo.svg new file mode 100644 index 00000000..3d113c9b --- /dev/null +++ b/src/assets/img/logo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144.08 128.61"><title>资源 82</title><path d="M72.23 128.61c-7.1-.23-11.51-3.72-14.76-9.36C48 102.87 38.43 86.59 29.1 70.16a36 36 0 0 1-4.47-11.35A14.61 14.61 0 0 1 34 42.51c7.49-2.71 15.71-.21 19.67 6.43 7.52 12.56 14.77 25.27 22.12 37.92 3 5.17 5.89 10.43 9 15.51 5 8 3.45 18-4.22 23.31-2.3 1.62-5.52 1.99-8.34 2.93z" fill="#2ef2e9"/><path d="M72.66.33c6-.57 10.39 2.6 13.51 8C95.61 24.69 105 41.1 114.52 57.4c3.9 6.65-.28 17.13-6.39 20.44-8.93 4.83-17.88 1.28-21.86-5.62C76.82 55.86 67.14 39.62 58.11 23 52.06 12 59.61.24 72.66.33z" fill="#fa6663"/><path d="M144.08 15.83c-.58 8.62-6.73 15.57-15.51 15.66-9.31.09-16.87-7-16.95-15.62S119 0 127.87 0c9.13.09 16.22 7 16.21 15.83z" fill="#fbb355"/><path d="M16.24 31.5C7 31.33-.19 24.42 0 15.8.19 7.5 7.19-.06 14.64 0c10.53.08 18.27 6.73 17.61 15.9-.64 8.96-6.25 15.28-16.01 15.6z" fill="#8a56c2"/></svg> \ No newline at end of file diff --git a/src/assets/img/ucenter-bg.jpg b/src/assets/img/ucenter-bg.jpg new file mode 100644 index 00000000..9c190557 Binary files /dev/null and b/src/assets/img/ucenter-bg.jpg differ diff --git a/src/components/countup.vue b/src/components/countup.vue new file mode 100644 index 00000000..4e08b0ef --- /dev/null +++ b/src/components/countup.vue @@ -0,0 +1,39 @@ +<template> + <span ref="countRef"></span> +</template> + +<script setup lang="ts"> +import { onMounted, ref, watch } from 'vue'; +import { CountUp } from 'countup.js'; + +const props = defineProps({ + end: { + type: Number, + required: true, + }, + options: { + type: Object, + default: () => ({}), + required: false, + }, +}); + +const countRef = ref<any>(null); +let countUp: any; +onMounted(() => { + countUp = new CountUp(countRef.value, props.end, props.options); + if (countUp.error) { + console.error(countUp.error); + return; + } + countUp.start(); +}); + +watch(() => props.end, (newVal) => { + if (countUp) { + countUp.update(newVal); + } +}); + + +</script> \ No newline at end of file diff --git a/src/components/header.vue b/src/components/header.vue index 2c14ace0..54169d58 100644 --- a/src/components/header.vue +++ b/src/components/header.vue @@ -1,154 +1,200 @@ -<template> - <div class="header"> - <!-- 折叠按钮 --> - <div class="collapse-btn" @click="collapseChage"> - <el-icon v-if="sidebar.collapse"><Expand /></el-icon> - <el-icon v-else><Fold /></el-icon> - </div> - <div class="logo">后台管理系统</div> - <div class="header-right"> - <div class="header-user-con"> - <!-- 消息中心 --> - <div class="btn-bell" @click="router.push('/tabs')"> - <el-tooltip - effect="dark" - :content="message ? `有${message}条未读消息` : `消息中心`" - placement="bottom" - > - <i class="el-icon-lx-notice"></i> - </el-tooltip> - <span class="btn-bell-badge" v-if="message"></span> - </div> - <!-- 用户头像 --> - <el-avatar class="user-avator" :size="30" :src="imgurl" /> - <!-- 用户名下拉菜单 --> - <el-dropdown class="user-name" trigger="click" @command="handleCommand"> - <span class="el-dropdown-link"> - {{ username }} - <el-icon class="el-icon--right"> - <arrow-down /> - </el-icon> - </span> - <template #dropdown> - <el-dropdown-menu> - <a href="https://github.com/lin-xin/vue-manage-system" target="_blank"> - <el-dropdown-item>项目仓库</el-dropdown-item> - </a> - <el-dropdown-item command="user">个人中心</el-dropdown-item> - <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item> - </el-dropdown-menu> - </template> - </el-dropdown> - </div> - </div> - </div> -</template> -<script setup lang="ts"> -import { onMounted } from 'vue'; -import { useSidebarStore } from '../store/sidebar'; -import { useRouter } from 'vue-router'; -import imgurl from '../assets/img/img.jpg'; - -const username: string | null = localStorage.getItem('ms_username'); -const message: number = 2; - -const sidebar = useSidebarStore(); -// 侧边栏折叠 -const collapseChage = () => { - sidebar.handleCollapse(); -}; - -onMounted(() => { - if (document.body.clientWidth < 1500) { - collapseChage(); - } -}); - -// 用户名下拉菜单选择事件 -const router = useRouter(); -const handleCommand = (command: string) => { - if (command == 'loginout') { - localStorage.removeItem('ms_username'); - router.push('/login'); - } else if (command == 'user') { - router.push('/user'); - } -}; -</script> -<style scoped> -.header { - position: relative; - box-sizing: border-box; - width: 100%; - height: 70px; - font-size: 22px; - color: #fff; -} -.collapse-btn { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - float: left; - padding: 0 21px; - cursor: pointer; -} -.header .logo { - float: left; - width: 250px; - line-height: 70px; -} -.header-right { - float: right; - padding-right: 50px; -} -.header-user-con { - display: flex; - height: 70px; - align-items: center; -} -.btn-fullscreen { - transform: rotate(45deg); - margin-right: 5px; - font-size: 24px; -} -.btn-bell, -.btn-fullscreen { - position: relative; - width: 30px; - height: 30px; - text-align: center; - border-radius: 15px; - cursor: pointer; - display: flex; - align-items: center; -} -.btn-bell-badge { - position: absolute; - right: 4px; - top: 0px; - width: 8px; - height: 8px; - border-radius: 4px; - background: #f56c6c; - color: #fff; -} -.btn-bell .el-icon-lx-notice { - color: #fff; -} -.user-name { - margin-left: 10px; -} -.user-avator { - margin-left: 20px; -} -.el-dropdown-link { - color: #fff; - cursor: pointer; - display: flex; - align-items: center; -} -.el-dropdown-menu__item { - text-align: center; -} -</style> +<template> + <div class="header"> + <!-- 折叠按钮 --> + <div class="header-left"> + <img class="logo" src="../assets/img/logo.svg" alt=""> + <div class="web-title"> + 后台管理系统 + </div> + <div class="collapse-btn" @click="collapseChage"> + <el-icon v-if="sidebar.collapse"> + <Expand /> + </el-icon> + <el-icon v-else> + <Fold /> + </el-icon> + </div> + </div> + <div class="header-right"> + <div class="header-user-con"> + <div class="btn-icon" @click="router.push('/theme')"> + <el-tooltip effect="dark" content="设置主题" placement="bottom"> + <i class="el-icon-lx-skin"></i> + </el-tooltip> + </div> + <div class="btn-icon" @click="router.push('/ucenter')"> + <el-tooltip effect="dark" :content="message ? `有${message}条未读消息` : `消息中心`" placement="bottom"> + <i class="el-icon-lx-notice"></i> + </el-tooltip> + <span class="btn-bell-badge" v-if="message"></span> + </div> + <div class="btn-icon" @click="setFullScreen"> + <el-tooltip effect="dark" content="全屏" placement="bottom"> + <i class="el-icon-lx-full"></i> + </el-tooltip> + </div> + <!-- 用户头像 --> + <el-avatar class="user-avator" :size="30" :src="imgurl" /> + <!-- 用户名下拉菜单 --> + <el-dropdown class="user-name" trigger="click" @command="handleCommand"> + <span class="el-dropdown-link"> + {{ username }} + <el-icon class="el-icon--right"> + <arrow-down /> + </el-icon> + </span> + <template #dropdown> + <el-dropdown-menu> + <a href="https://github.com/lin-xin/vue-manage-system" target="_blank"> + <el-dropdown-item>项目仓库</el-dropdown-item> + </a> + <el-dropdown-item command="user">个人中心</el-dropdown-item> + <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + </div> + </div> + </div> +</template> +<script setup lang="ts"> +import { onMounted } from 'vue'; +import { useSidebarStore } from '../store/sidebar'; +import { useRouter } from 'vue-router'; +import imgurl from '../assets/img/img.jpg'; + +const username: string | null = localStorage.getItem('ms_username'); +const message: number = 2; + +const sidebar = useSidebarStore(); +// 侧边栏折叠 +const collapseChage = () => { + sidebar.handleCollapse(); +}; + +onMounted(() => { + if (document.body.clientWidth < 1500) { + collapseChage(); + } +}); + +// 用户名下拉菜单选择事件 +const router = useRouter(); +const handleCommand = (command: string) => { + if (command == 'loginout') { + localStorage.removeItem('ms_username'); + router.push('/login'); + } else if (command == 'user') { + router.push('/ucenter'); + } +}; + +const setFullScreen = () => { + if (document.fullscreenElement) { + document.exitFullscreen(); + } else { + document.body.requestFullscreen.call(document.body); + } +} +</script> +<style scoped> +.header { + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; + width: 100%; + height: 70px; + color: var(--header-text-color); + background-color: var(--header-bg-color); + border-bottom: 1px solid #ddd; +} + +.header-left { + display: flex; + align-items: center; + padding-left: 20px; + height: 100%; +} + +.logo { + width: 35px; +} + +.web-title { + margin: 0 40px 0 10px; + font-size: 22px; +} + +.collapse-btn { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + padding: 0 10px; + cursor: pointer; + opacity: 0.8; + font-size: 22px; +} + +.collapse-btn:hover { + opacity: 1; +} + +.header-right { + float: right; + padding-right: 50px; +} + +.header-user-con { + display: flex; + height: 70px; + align-items: center; +} + +.btn-fullscreen { + transform: rotate(45deg); + margin-right: 5px; + font-size: 24px; +} + +.btn-icon { + position: relative; + width: 30px; + height: 30px; + text-align: center; + cursor: pointer; + display: flex; + align-items: center; + color: var(--header-text-color); + margin: 0 5px; + font-size: 20px; +} + +.btn-bell-badge { + position: absolute; + right: 4px; + top: 0px; + width: 8px; + height: 8px; + border-radius: 4px; + background: #f56c6c; + color: var(--header-text-color); +} + + +.user-avator { + margin: 0 10px 0 20px; +} + +.el-dropdown-link { + color: var(--header-text-color); + cursor: pointer; + display: flex; + align-items: center; +} + +.el-dropdown-menu__item { + text-align: center; +} +</style> diff --git a/src/components/menu.ts b/src/components/menu.ts new file mode 100644 index 00000000..2644432b --- /dev/null +++ b/src/components/menu.ts @@ -0,0 +1,221 @@ +import { Menus } from '@/types/menu'; + +export const menuData: Menus[] = [ + { + id: '0', + title: '系统首页', + index: '/dashboard', + icon: 'Odometer', + }, + { + id: '1', + title: '系统管理', + index: '1', + icon: 'HomeFilled', + children: [ + { + id: '11', + pid: '1', + index: '/system-user', + title: '用户管理', + }, + { + id: '12', + pid: '1', + index: '/system-role', + title: '角色管理', + }, + { + id: '13', + pid: '1', + index: '/system-menu', + title: '菜单管理', + }, + ], + }, + { + id: '2', + title: '组件', + index: '2-1', + icon: 'Calendar', + children: [ + { + id: '21', + pid: '3', + index: '/form', + title: '表单', + }, + { + id: '22', + pid: '3', + index: '/upload', + title: '上传', + }, + { + id: '23', + pid: '2', + index: '/carousel', + title: '走马灯', + }, + { + id: '24', + pid: '2', + index: '/calendar', + title: '日历', + }, + { + id: '25', + pid: '2', + index: '/watermark', + title: '水印', + }, + { + id: '26', + pid: '2', + index: '/tour', + title: '分布引导', + }, + { + id: '27', + pid: '2', + index: '/steps', + title: '步骤条', + }, + { + id: '28', + pid: '2', + index: '/statistic', + title: '统计', + }, + { + id: '29', + pid: '3', + index: '29', + title: '三级菜单', + children: [ + { + id: '291', + pid: '29', + index: '/editor', + title: '富文本编辑器', + }, + { + id: '292', + pid: '29', + index: '/markdown', + title: 'markdown编辑器', + }, + ], + }, + ], + }, + { + id: '3', + title: '表格', + index: '3', + icon: 'Calendar', + children: [ + { + id: '31', + pid: '3', + index: '/table', + title: '基础表格', + }, + { + id: '32', + pid: '3', + index: '/table-editor', + title: '可编辑表格', + }, + { + id: '33', + pid: '3', + index: '/import', + title: '导入Excel', + }, + { + id: '34', + pid: '3', + index: '/export', + title: '导出Excel', + }, + ], + }, + { + id: '4', + icon: 'PieChart', + index: '4', + title: '图表', + children: [ + { + id: '41', + pid: '4', + index: '/schart', + title: 'schart图表', + }, + { + id: '42', + pid: '4', + index: '/echarts', + title: 'echarts图表', + }, + ], + }, + { + id: '5', + icon: 'Guide', + index: '/icon', + title: '图标', + permiss: '5', + }, + { + id: '7', + icon: 'Brush', + index: '/theme', + title: '主题', + }, + { + id: '6', + icon: 'DocumentAdd', + index: '6', + title: '附加页面', + children: [ + { + id: '61', + pid: '6', + index: '/ucenter', + title: '个人中心', + }, + { + id: '62', + pid: '6', + index: '/login', + title: '登录', + }, + { + id: '63', + pid: '6', + index: '/register', + title: '注册', + }, + { + id: '64', + pid: '6', + index: '/reset-pwd', + title: '重设密码', + }, + { + id: '65', + pid: '6', + index: '/403', + title: '403', + }, + { + id: '66', + pid: '6', + index: '/404', + title: '404', + }, + ], + }, +]; diff --git a/src/components/sidebar.vue b/src/components/sidebar.vue index 1bfd9b5f..18e8c895 100644 --- a/src/components/sidebar.vue +++ b/src/components/sidebar.vue @@ -1,181 +1,90 @@ -<template> - <div class="sidebar"> - <el-menu - class="sidebar-el-menu" - :default-active="onRoutes" - :collapse="sidebar.collapse" - background-color="#324157" - text-color="#bfcbd9" - active-text-color="#20a0ff" - unique-opened - router - > - <template v-for="item in items"> - <template v-if="item.subs"> - <el-sub-menu :index="item.index" :key="item.index" v-permiss="item.permiss"> - <template #title> - <el-icon> - <component :is="item.icon"></component> - </el-icon> - <span>{{ item.title }}</span> - </template> - <template v-for="subItem in item.subs"> - <el-sub-menu - v-if="subItem.subs" - :index="subItem.index" - :key="subItem.index" - v-permiss="item.permiss" - > - <template #title>{{ subItem.title }}</template> - <el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index"> - {{ threeItem.title }} - </el-menu-item> - </el-sub-menu> - <el-menu-item v-else :index="subItem.index" v-permiss="item.permiss"> - {{ subItem.title }} - </el-menu-item> - </template> - </el-sub-menu> - </template> - <template v-else> - <el-menu-item :index="item.index" :key="item.index" v-permiss="item.permiss"> - <el-icon> - <component :is="item.icon"></component> - </el-icon> - <template #title>{{ item.title }}</template> - </el-menu-item> - </template> - </template> - </el-menu> - </div> -</template> - -<script setup lang="ts"> -import { computed } from 'vue'; -import { useSidebarStore } from '../store/sidebar'; -import { useRoute } from 'vue-router'; - -const items = [ - { - icon: 'Odometer', - index: '/dashboard', - title: '系统首页', - permiss: '1', - }, - { - icon: 'Calendar', - index: '1', - title: '表格相关', - permiss: '2', - subs: [ - { - index: '/table', - title: '常用表格', - permiss: '2', - }, - { - index: '/import', - title: '导入Excel', - permiss: '2', - }, - { - index: '/export', - title: '导出Excel', - permiss: '2', - }, - ], - }, - { - icon: 'DocumentCopy', - index: '/tabs', - title: 'tab选项卡', - permiss: '3', - }, - { - icon: 'Edit', - index: '3', - title: '表单相关', - permiss: '4', - subs: [ - { - index: '/form', - title: '基本表单', - permiss: '5', - }, - { - index: '/upload', - title: '文件上传', - permiss: '6', - }, - { - index: '4', - title: '三级菜单', - permiss: '7', - subs: [ - { - index: '/editor', - title: '富文本编辑器', - permiss: '8', - }, - { - index: '/markdown', - title: 'markdown编辑器', - permiss: '9', - }, - ], - }, - ], - }, - { - icon: 'Setting', - index: '/icon', - title: '自定义图标', - permiss: '10', - }, - { - icon: 'PieChart', - index: '/charts', - title: 'schart图表', - permiss: '11', - }, - { - icon: 'Warning', - index: '/permission', - title: '权限管理', - permiss: '13', - }, - { - icon: 'CoffeeCup', - index: '/donate', - title: '支持作者', - permiss: '14', - }, -]; - -const route = useRoute(); -const onRoutes = computed(() => { - return route.path; -}); - -const sidebar = useSidebarStore(); -</script> - -<style scoped> -.sidebar { - display: block; - position: absolute; - left: 0; - top: 70px; - bottom: 0; - overflow-y: scroll; -} -.sidebar::-webkit-scrollbar { - width: 0; -} -.sidebar-el-menu:not(.el-menu--collapse) { - width: 250px; -} -.sidebar > ul { - height: 100%; -} -</style> +<template> + <div class="sidebar"> + <el-menu + class="sidebar-el-menu" + :default-active="onRoutes" + :collapse="sidebar.collapse" + :background-color="sidebar.bgColor" + :text-color="sidebar.textColor" + router + > + <template v-for="item in menuData"> + <template v-if="item.children"> + <el-sub-menu :index="item.index" :key="item.index" v-permiss="item.id"> + <template #title> + <el-icon> + <component :is="item.icon"></component> + </el-icon> + <span>{{ item.title }}</span> + </template> + <template v-for="subItem in item.children"> + <el-sub-menu + v-if="subItem.children" + :index="subItem.index" + :key="subItem.index" + v-permiss="item.id" + > + <template #title>{{ subItem.title }}</template> + <el-menu-item + v-for="(threeItem, i) in subItem.children" + :key="i" + :index="threeItem.index" + > + {{ threeItem.title }} + </el-menu-item> + </el-sub-menu> + <el-menu-item v-else :index="subItem.index" v-permiss="item.id"> + {{ subItem.title }} + </el-menu-item> + </template> + </el-sub-menu> + </template> + <template v-else> + <el-menu-item :index="item.index" :key="item.index" v-permiss="item.id"> + <el-icon> + <component :is="item.icon"></component> + </el-icon> + <template #title>{{ item.title }}</template> + </el-menu-item> + </template> + </template> + </el-menu> + </div> +</template> + +<script setup lang="ts"> +import { computed } from 'vue'; +import { useSidebarStore } from '../store/sidebar'; +import { useRoute } from 'vue-router'; +import { menuData } from '@/components/menu'; + +const route = useRoute(); +const onRoutes = computed(() => { + return route.path; +}); + +const sidebar = useSidebarStore(); +</script> + +<style scoped> +.sidebar { + display: block; + position: absolute; + left: 0; + top: 70px; + bottom: 0; + overflow-y: scroll; +} + +.sidebar::-webkit-scrollbar { + width: 0; +} + +.sidebar-el-menu:not(.el-menu--collapse) { + width: 250px; +} + +.sidebar-el-menu { + min-height: 100%; +} +</style> diff --git a/src/components/table-custom.vue b/src/components/table-custom.vue new file mode 100644 index 00000000..7286c6b0 --- /dev/null +++ b/src/components/table-custom.vue @@ -0,0 +1,211 @@ +<template> + <div> + <div class="table-toolbar" v-if="hasToolbar"> + <div class="table-toolbar-left"> + <slot name="toolbarBtn"></slot> + </div> + <div class="table-toolbar-right flex-center"> + <template v-if="multipleSelection.length > 0"> + <el-tooltip effect="dark" content="删除选中" placement="top"> + <el-icon class="columns-setting-icon" @click="delSelection(multipleSelection)"> + <Delete /> + </el-icon> + </el-tooltip> + <el-divider direction="vertical" /> + </template> + <el-tooltip effect="dark" content="刷新" placement="top"> + <el-icon class="columns-setting-icon" @click="refresh"> + <Refresh /> + </el-icon> + </el-tooltip> + <el-divider direction="vertical" /> + <el-tooltip effect="dark" content="列设置" placement="top"> + <el-dropdown :hide-on-click="false" size="small" trigger="click"> + <el-icon class="columns-setting-icon"> + <Setting /> + </el-icon> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item v-for="c in columns"> + <el-checkbox v-model="c.visible" :label="c.label" /> + </el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + </el-tooltip> + </div> + </div> + <el-table class="mgb20" :style="{ width: '100%' }" border :data="tableData" :row-key="rowKey" + @selection-change="handleSelectionChange" table-layout="auto"> + <template v-for="item in columns" :key="item.prop"> + <el-table-column v-if="item.visible" :prop="item.prop" :label="item.label" :width="item.width" + :type="item.type" :align="item.align || 'center'"> + + <template #default="{ row, column, $index }" v-if="item.type === 'index'"> + {{ getIndex($index) }} + </template> + <template #default="{ row, column, $index }" v-if="!item.type"> + <slot :name="item.prop" :rows="row" :index="$index"> + <template v-if="item.prop == 'operator'"> + <el-button type="warning" size="small" :icon="View" @click="viewFunc(row)"> + 查看 + </el-button> + <el-button type="primary" size="small" :icon="Edit" @click="editFunc(row)"> + 编辑 + </el-button> + <el-button type="danger" size="small" :icon="Delete" @click="handleDelete(row)"> + 删除 + </el-button> + </template> + <span v-else-if="item.formatter"> + {{ item.formatter(row[item.prop]) }} + </span> + <span v-else> + {{ row[item.prop] }} + </span> + </slot> + </template> + </el-table-column> + </template> + </el-table> + <el-pagination v-if="hasPagination" :current-page="currentPage" :page-size="pageSize" :background="true" + :layout="layout" :total="total" @current-change="handleCurrentChange" /> + </div> +</template> + +<script setup lang="ts"> +import { toRefs, PropType, ref } from 'vue' +import { Delete, Edit, View, Refresh } from '@element-plus/icons-vue'; +import { ElMessageBox } from 'element-plus'; + +const props = defineProps({ + // 表格相关 + tableData: { + type: Array, + default: [] + }, + columns: { + type: Array as PropType<any[]>, + default: [] + }, + rowKey: { + type: String, + default: 'id' + }, + hasToolbar: { + type: Boolean, + default: true + }, + // 分页相关 + hasPagination: { + type: Boolean, + default: true + }, + total: { + type: Number, + default: 0 + }, + currentPage: { + type: Number, + default: 1 + }, + pageSize: { + type: Number, + default: 10 + }, + + layout: { + type: String, + default: 'total, prev, pager, next' + }, + delFunc: { + type: Function, + default: () => { } + }, + viewFunc: { + type: Function, + default: () => { } + }, + editFunc: { + type: Function, + default: () => { } + }, + delSelection: { + type: Function, + default: () => { } + }, + refresh: { + type: Function, + default: () => { } + }, + changePage: { + type: Function, + default: () => { } + } +}) + +let { + tableData, + columns, + rowKey, + hasToolbar, + hasPagination, + total, + currentPage, + pageSize, + layout, +} = toRefs(props) + +columns.value.forEach((item) => { + if (item.visible === undefined) { + item.visible = true + } +}) + +// 当选择项发生变化时会触发该事件 +const multipleSelection = ref([]) +const handleSelectionChange = (selection: any[]) => { + multipleSelection.value = selection +} + +// 当前页码变化的事件 +const handleCurrentChange = (val: number) => { + props.changePage(val) +} + +const handleDelete = (row) => { + ElMessageBox.confirm('确定要删除吗?', '提示', { + type: 'warning' + }) + .then(async () => { + props.delFunc(row); + }) + .catch(() => { }); +}; + +const getIndex = (index: number) => { + return index + 1 + (currentPage.value - 1) * pageSize.value +} + +</script> + +<style scoped> +.table-toolbar { + display: flex; + justify-content: space-between; + align-items: flex-end; + margin-bottom: 10px; +} + +.columns-setting-icon { + display: block; + font-size: 18px; + cursor: pointer; + color: #676767; +} +</style> +<style> +.table-header .cell { + color: #333; +} +</style> \ No newline at end of file diff --git a/src/components/table-detail.vue b/src/components/table-detail.vue index 16064d03..a9ba021c 100644 --- a/src/components/table-detail.vue +++ b/src/components/table-detail.vue @@ -1,32 +1,10 @@ <template> - <el-descriptions title="" :column="2" border> - <el-descriptions-item> - <template #label> 用户ID </template> - {{ data.id }} - </el-descriptions-item> - <el-descriptions-item> - <template #label> 用户名 </template> - {{ data.name }} - </el-descriptions-item> - <el-descriptions-item> - <template #label> 账户余额 </template> - {{ data.money }} - </el-descriptions-item> - <el-descriptions-item> - <template #label> 账户状态 </template> - {{ data.state ? '正常' : '异常' }} - </el-descriptions-item> - <el-descriptions-item :span="2"> - <template #label> 地址 </template> - {{ data.address }} - </el-descriptions-item> - <el-descriptions-item> - <template #label> 日期 </template> - {{ data.date }} - </el-descriptions-item> - <el-descriptions-item> - <template #label> 头像 </template> - <img :src="data.thumb" style="width: 120px" alt="" /> + <el-descriptions :title="title" :column="column" border> + <el-descriptions-item v-for="item in list" :span="item.span"> + <template #label> {{ item.label }} </template> + <slot :name="item.prop" :rows="row"> + {{ item.value || row[item.prop] }} + </slot> </el-descriptions-item> </el-descriptions> </template> @@ -35,7 +13,9 @@ const props = defineProps({ data: { type: Object, - required: true + required: true, } }); +const { row, title, column = 2, list } = props.data; + </script> diff --git a/src/components/table-edit.vue b/src/components/table-edit.vue index 78b4293a..cbf0dc60 100644 --- a/src/components/table-edit.vue +++ b/src/components/table-edit.vue @@ -1,38 +1,36 @@ <template> - <el-form ref="formRef" :model="form" :rules="rules" label-width="100px"> - <el-form-item label="用户名" prop="name"> - <el-input v-model="form.name"></el-input> - </el-form-item> - <el-form-item label="账户余额" prop="money"> - <el-input v-model.number="form.money"></el-input> - </el-form-item> - <el-form-item label="地址" prop="address"> - <el-input v-model="form.address"></el-input> - </el-form-item> - <el-form-item label="账户状态" prop="state"> - <el-switch - v-model="form.state" - :active-value="1" - :inactive-value="0" - active-text="正常" - inactive-text="异常" - ></el-switch> - </el-form-item> - <el-form-item label="注册日期" prop="date"> - <el-date-picker type="date" v-model="form.date" value-format="YYYY-MM-DD"></el-date-picker> - </el-form-item> - <el-form-item label="上传头像" prop="thumb"> - <el-upload - class="avatar-uploader" - action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" - :show-file-list="false" - :on-success="handleAvatarSuccess" - :before-upload="beforeAvatarUpload" - > - <img v-if="form.thumb" :src="form.thumb" class="avatar" /> - <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon> - </el-upload> - </el-form-item> + <el-form ref="formRef" :model="form" :rules="rules" :label-width="options.labelWidth"> + <el-row> + <el-col :span="options.span" v-for="item in options.list"> + <el-form-item :label="item.label" :prop="item.prop"> + <!-- 文本框、数字框、下拉框、日期框、开关、上传 --> + <el-input v-if="item.type === 'input'" v-model="form[item.prop]" :disabled="item.disabled" + :placeholder="item.placeholder" clearable></el-input> + <el-input-number v-else-if="item.type === 'number'" v-model="form[item.prop]" + :disabled="item.disabled" controls-position="right"></el-input-number> + <el-select v-else-if="item.type === 'select'" v-model="form[item.prop]" :disabled="item.disabled" + :placeholder="item.placeholder" clearable> + <el-option v-for="opt in item.opts" :label="opt.label" :value="opt.value"></el-option> + </el-select> + <el-date-picker v-else-if="item.type === 'date'" type="date" v-model="form[item.prop]" + :value-format="item.format"></el-date-picker> + <el-switch v-else-if="item.type === 'switch'" v-model="form[item.prop]" + :active-value="item.activeValue" :inactive-value="item.inactiveValue" + :active-text="item.activeText" :inactive-text="item.inactiveText"></el-switch> + <el-upload v-else-if="item.type === 'upload'" class="avatar-uploader" action="#" + :show-file-list="false" :on-success="handleAvatarSuccess"> + <img v-if="form[item.prop]" :src="form[item.prop]" class="avatar" /> + <el-icon v-else class="avatar-uploader-icon"> + <Plus /> + </el-icon> + </el-upload> + <slot :name="item.prop" v-else> + + </slot> + </el-form-item> + </el-col> + </el-row> + <el-form-item> <el-button type="primary" @click="saveEdit(formRef)">保 存</el-button> </el-form-item> @@ -40,11 +38,16 @@ </template> <script lang="ts" setup> -import { ElMessage, FormInstance, FormRules, UploadProps } from 'element-plus'; -import { ref } from 'vue'; +import { FormOption } from '@/types/form-option'; +import { FormInstance, FormRules, UploadProps } from 'element-plus'; +import { PropType, ref } from 'vue'; -const props = defineProps({ - data: { +const { options, formData, edit, update } = defineProps({ + options: { + type: Object as PropType<FormOption>, + required: true + }, + formData: { type: Object, required: true }, @@ -58,28 +61,23 @@ const props = defineProps({ } }); -const defaultData = { - id: '', - name: '', - address: '', - thumb: '', - money: 0, - state: 0, - date: new Date() -}; -const form = ref({ ...(props.edit ? props.data : defaultData) }); +const form = ref({ ...(edit ? formData : {}) }); + +const rules: FormRules = options.list.map(item => { + if (item.required) { + return { [item.prop]: [{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }] }; + } + return {}; +}).reduce((acc, cur) => ({ ...acc, ...cur }), {}); + -const rules: FormRules = { - name: [{ required: true, message: '用户名', trigger: 'blur' }] -}; const formRef = ref<FormInstance>(); const saveEdit = (formEl: FormInstance | undefined) => { if (!formEl) return; formEl.validate(valid => { if (!valid) return false; - props.update(form.value); - ElMessage.success('保存成功!'); + update(form.value); }); }; @@ -87,16 +85,6 @@ const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => form.value.thumb = URL.createObjectURL(uploadFile.raw!); }; -const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => { - if (rawFile.type !== 'image/jpeg') { - ElMessage.error('Avatar picture must be JPG format!'); - return false; - } else if (rawFile.size / 1024 / 1024 > 2) { - ElMessage.error('Avatar picture size can not exceed 2MB!'); - return false; - } - return true; -}; </script> <style> diff --git a/src/components/table-search.vue b/src/components/table-search.vue new file mode 100644 index 00000000..116c3e60 --- /dev/null +++ b/src/components/table-search.vue @@ -0,0 +1,60 @@ +<template> + <div class="search-container"> + <el-form ref="searchRef" :model="query" :inline="true"> + <el-form-item :label="item.label" :prop="item.prop" v-for="item in options"> + <!-- 文本框、下拉框、日期框 --> + <el-input v-if="item.type === 'input'" v-model="query[item.prop]" :disabled="item.disabled" + :placeholder="item.placeholder" clearable></el-input> + <el-select v-else-if="item.type === 'select'" v-model="query[item.prop]" :disabled="item.disabled" + :placeholder="item.placeholder" clearable> + <el-option v-for="opt in item.opts" :label="opt.label" :value="opt.value"></el-option> + </el-select> + <el-date-picker v-else-if="item.type === 'date'" type="date" v-model="query[item.prop]" + :value-format="item.format"></el-date-picker> + </el-form-item> + <el-form-item> + <el-button type="primary" :icon="Search" @click="search">搜索</el-button> + <el-button :icon="Refresh" @click="resetForm(searchRef)">重置</el-button> + </el-form-item> + </el-form> + </div> +</template> + +<script lang="ts" setup> +import { FormInstance } from 'element-plus'; +import { Search, Refresh } from '@element-plus/icons-vue'; +import { PropType, ref } from 'vue'; +import { FormOptionList } from '@/types/form-option'; + +const props = defineProps({ + query: { + type: Object, + required: true + }, + options: { + type: Array as PropType<Array<FormOptionList>>, + required: true + }, + search: { + type: Function, + default: () => { } + } +}); + +const searchRef = ref<FormInstance>(); +const resetForm = (formEl: FormInstance | undefined) => { + if (!formEl) return + formEl.resetFields() + props.search(); +} +</script> + +<style scoped> +.search-container { + padding: 20px 30px 0; + background-color: #fff; + margin-bottom: 10px; + border: 1px solid #ddd; + border-radius: 5px +} +</style> diff --git a/src/components/tabs.vue b/src/components/tabs.vue new file mode 100644 index 00000000..4dfd6b95 --- /dev/null +++ b/src/components/tabs.vue @@ -0,0 +1,149 @@ +<template> + <div class="tabs-container"> + <el-tabs v-model="activePath" class="tabs" type="card" closable @tab-click="clickTabls" @tab-remove="closeTabs"> + <el-tab-pane v-for="item in tabs.list" :key="item.path" :label="item.title" :name="item.path" + @click="setTags(item)"></el-tab-pane> + </el-tabs> + <div class="Tabs-close-box"> + <el-dropdown @command="handleTags"> + <el-button size="small" type="primary" plain> + 标签选项 + <el-icon class="el-icon--right"> + <arrow-down /> + </el-icon> + </el-button> + <template #dropdown> + <el-dropdown-menu size="small"> + <el-dropdown-item command="other">关闭其他</el-dropdown-item> + <el-dropdown-item command="current">关闭当前</el-dropdown-item> + <el-dropdown-item command="all">关闭所有</el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + </div> + </div> +</template> + +<script setup lang="ts"> +import { ref, watch } from 'vue'; +import { useTabsStore } from '../store/tabs'; +import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'; + +const route = useRoute(); +const router = useRouter(); +const activePath = ref(route.fullPath) +const tabs = useTabsStore(); +// 设置标签 +const setTags = (route: any) => { + const isExist = tabs.list.some(item => { + return item.path === route.fullPath; + }); + if (!isExist) { + tabs.setTabsItem({ + name: route.name, + title: route.meta.title, + path: route.fullPath + }); + } +}; +setTags(route); +onBeforeRouteUpdate(to => { + setTags(to); +}); + +// 关闭全部标签 +const closeAll = () => { + tabs.clearTabs(); + router.push('/'); +}; +// 关闭其他标签 +const closeOther = () => { + const curItem = tabs.list.filter(item => { + return item.path === route.fullPath; + }); + tabs.closeTabsOther(curItem); +}; +const handleTags = (command: string) => { + switch (command) { + case 'current': + // 关闭当前页面的标签页 + tabs.closeCurrentTag({ + $router: router, + $route: route + }); + break; + case 'all': + closeAll(); + break; + + case 'other': + closeOther(); + break; + } +}; + +const clickTabls = (item: any) => { + router.push(item.props.name); +} +const closeTabs = (path: any) => { + console.log(path); + const index = tabs.list.findIndex((item) => item.path === path); + tabs.delTabsItem(index); + const item = tabs.list[index] ? tabs.list[index] : tabs.list[index - 1]; + if (item) { + path === route.fullPath && router.push(item.path); + } else { + router.push('/'); + } +} + +watch(() => route.fullPath, (newVal, oldVal) => { + activePath.value = newVal; +}) + +</script> + +<style scss> +.tabs-container { + position: relative; + overflow: hidden; + background: #fff; + padding: 2px 120px 0 0; +} + +.tabs { + + .el-tabs__header { + margin-bottom: 0; + } + + .el-tabs__nav { + height: 28px; + } + + .el-tabs__nav-next, + .el-tabs__nav-prev { + line-height: 32px; + } + + &.el-tabs { + --el-tabs-header-height: 28px; + } + + +} + +.Tabs-close-box { + position: absolute; + right: 0; + top: 0; + box-sizing: border-box; + padding-top: 1px; + text-align: center; + width: 110px; + height: 30px; + background: #fff; + box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1); + z-index: 10; +} +</style> diff --git a/src/components/tags.vue b/src/components/tags.vue deleted file mode 100644 index 79a4887b..00000000 --- a/src/components/tags.vue +++ /dev/null @@ -1,168 +0,0 @@ -<template> - <div class="tags" v-if="tags.show"> - <ul> - <li - class="tags-li" - v-for="(item, index) in tags.list" - :class="{ active: isActive(item.path) }" - :key="index" - > - <router-link :to="item.path" class="tags-li-title">{{ item.title }}</router-link> - <el-icon @click="closeTags(index)"><Close /></el-icon> - </li> - </ul> - <div class="tags-close-box"> - <el-dropdown @command="handleTags"> - <el-button size="small" type="primary"> - 标签选项 - <el-icon class="el-icon--right"> - <arrow-down /> - </el-icon> - </el-button> - <template #dropdown> - <el-dropdown-menu size="small"> - <el-dropdown-item command="other">关闭其他</el-dropdown-item> - <el-dropdown-item command="all">关闭所有</el-dropdown-item> - </el-dropdown-menu> - </template> - </el-dropdown> - </div> - </div> -</template> - -<script setup lang="ts"> -import { useTagsStore } from '../store/tags'; -import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'; - -const route = useRoute(); -const router = useRouter(); -const isActive = (path: string) => { - return path === route.fullPath; -}; - -const tags = useTagsStore(); -// 关闭单个标签 -const closeTags = (index: number) => { - const delItem = tags.list[index]; - tags.delTagsItem(index); - const item = tags.list[index] ? tags.list[index] : tags.list[index - 1]; - if (item) { - delItem.path === route.fullPath && router.push(item.path); - } else { - router.push('/'); - } -}; - -// 设置标签 -const setTags = (route: any) => { - const isExist = tags.list.some(item => { - return item.path === route.fullPath; - }); - if (!isExist) { - if (tags.list.length >= 8) tags.delTagsItem(0); - tags.setTagsItem({ - name: route.name, - title: route.meta.title, - path: route.fullPath - }); - } -}; -setTags(route); -onBeforeRouteUpdate(to => { - setTags(to); -}); - -// 关闭全部标签 -const closeAll = () => { - tags.clearTags(); - router.push('/'); -}; -// 关闭其他标签 -const closeOther = () => { - const curItem = tags.list.filter(item => { - return item.path === route.fullPath; - }); - tags.closeTagsOther(curItem); -}; -const handleTags = (command: string) => { - command === 'other' ? closeOther() : closeAll(); -}; - -// 关闭当前页面的标签页 -// tags.closeCurrentTag({ -// $router: router, -// $route: route -// }); -</script> - -<style> -.tags { - position: relative; - height: 30px; - overflow: hidden; - background: #fff; - padding-right: 120px; - box-shadow: 0 5px 10px #ddd; -} - -.tags ul { - box-sizing: border-box; - width: 100%; - height: 100%; -} - -.tags-li { - display: flex; - align-items: center; - float: left; - margin: 3px 5px 2px 3px; - border-radius: 3px; - font-size: 12px; - overflow: hidden; - cursor: pointer; - height: 23px; - border: 1px solid #e9eaec; - background: #fff; - padding: 0 5px 0 12px; - color: #666; - -webkit-transition: all 0.3s ease-in; - -moz-transition: all 0.3s ease-in; - transition: all 0.3s ease-in; -} - -.tags-li:not(.active):hover { - background: #f8f8f8; -} - -.tags-li.active { - color: #fff; -} - -.tags-li-title { - float: left; - max-width: 80px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - margin-right: 5px; - color: #666; -} - -.tags-li.active .tags-li-title { - color: #fff; -} - -.tags-close-box { - position: absolute; - right: 0; - top: 0; - box-sizing: border-box; - padding-top: 1px; - text-align: center; - width: 110px; - height: 30px; - background: #fff; - box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1); - z-index: 10; -} -</style> diff --git a/src/main.ts b/src/main.ts index 43ae5c79..d44c9a7c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,28 +1,28 @@ -import { createApp } from 'vue'; -import { createPinia } from 'pinia'; -import * as ElementPlusIconsVue from '@element-plus/icons-vue'; -import App from './App.vue'; -import router from './router'; -import { usePermissStore } from './store/permiss'; -import 'element-plus/dist/index.css'; -import './assets/css/icon.css'; - -const app = createApp(App); -app.use(createPinia()); -app.use(router); - -// 注册elementplus图标 -for (const [key, component] of Object.entries(ElementPlusIconsVue)) { - app.component(key, component); -} -// 自定义权限指令 -const permiss = usePermissStore(); -app.directive('permiss', { - mounted(el, binding) { - if (!permiss.key.includes(String(binding.value))) { - el['hidden'] = true; - } - }, -}); - -app.mount('#app'); +import { createApp } from 'vue'; +import { createPinia } from 'pinia'; +import * as ElementPlusIconsVue from '@element-plus/icons-vue'; +import App from './App.vue'; +import router from './router'; +import { usePermissStore } from './store/permiss'; +import 'element-plus/dist/index.css'; +import './assets/css/icon.css'; + +const app = createApp(App); +app.use(createPinia()); +app.use(router); + +// 注册elementplus图标 +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component); +} +// 自定义权限指令 +const permiss = usePermissStore(); +app.directive('permiss', { + mounted(el, binding) { + if (binding.value && !permiss.key.includes(String(binding.value))) { + el['hidden'] = true; + } + }, +}); + +app.mount('#app'); diff --git a/src/router/index.ts b/src/router/index.ts index 5bc3eb40..3edbf8e0 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,185 +1,293 @@ -import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'; -import { usePermissStore } from '../store/permiss'; -import Home from '../views/home.vue'; -import NProgress from 'nprogress' -import 'nprogress/nprogress.css' - -const routes: RouteRecordRaw[] = [ - { - path: '/', - redirect: '/dashboard', - }, - { - path: '/', - name: 'Home', - component: Home, - children: [ - { - path: '/dashboard', - name: 'dashboard', - meta: { - title: '系统首页', - permiss: '1', - }, - component: () => import(/* webpackChunkName: "dashboard" */ '../views/dashboard.vue'), - }, - { - path: '/table', - name: 'basetable', - meta: { - title: '表格', - permiss: '2', - }, - component: () => import(/* webpackChunkName: "table" */ '../views/table.vue'), - }, - { - path: '/charts', - name: 'basecharts', - meta: { - title: '图表', - permiss: '11', - }, - component: () => import(/* webpackChunkName: "charts" */ '../views/charts.vue'), - }, - { - path: '/form', - name: 'baseform', - meta: { - title: '表单', - permiss: '5', - }, - component: () => import(/* webpackChunkName: "form" */ '../views/form.vue'), - }, - { - path: '/tabs', - name: 'tabs', - meta: { - title: 'tab标签', - permiss: '3', - }, - component: () => import(/* webpackChunkName: "tabs" */ '../views/tabs.vue'), - }, - { - path: '/donate', - name: 'donate', - meta: { - title: '鼓励作者', - permiss: '14', - }, - component: () => import(/* webpackChunkName: "donate" */ '../views/donate.vue'), - }, - { - path: '/permission', - name: 'permission', - meta: { - title: '权限管理', - permiss: '13', - }, - component: () => import(/* webpackChunkName: "permission" */ '../views/permission.vue'), - }, - { - path: '/upload', - name: 'upload', - meta: { - title: '上传插件', - permiss: '6', - }, - component: () => import(/* webpackChunkName: "upload" */ '../views/upload.vue'), - }, - { - path: '/icon', - name: 'icon', - meta: { - title: '自定义图标', - permiss: '10', - }, - component: () => import(/* webpackChunkName: "icon" */ '../views/icon.vue'), - }, - { - path: '/user', - name: 'user', - meta: { - title: '个人中心', - }, - component: () => import(/* webpackChunkName: "user" */ '../views/user.vue'), - }, - { - path: '/editor', - name: 'editor', - meta: { - title: '富文本编辑器', - permiss: '8', - }, - component: () => import(/* webpackChunkName: "editor" */ '../views/editor.vue'), - }, - { - path: '/markdown', - name: 'markdown', - meta: { - title: 'markdown编辑器', - permiss: '9', - }, - component: () => import(/* webpackChunkName: "markdown" */ '../views/markdown.vue'), - }, - { - path: '/export', - name: 'export', - meta: { - title: '导出Excel', - permiss: '2', - }, - component: () => import(/* webpackChunkName: "export" */ '../views/export.vue'), - }, - { - path: '/import', - name: 'import', - meta: { - title: '导入Excel', - permiss: '2', - }, - component: () => import(/* webpackChunkName: "import" */ '../views/import.vue'), - }, - ], - }, - { - path: '/login', - name: 'Login', - meta: { - title: '登录', - }, - component: () => import(/* webpackChunkName: "login" */ '../views/login.vue'), - }, - { - path: '/403', - name: '403', - meta: { - title: '没有权限', - }, - component: () => import(/* webpackChunkName: "403" */ '../views/403.vue'), - }, -]; - -const router = createRouter({ - history: createWebHashHistory(), - routes, -}); - -router.beforeEach((to, from, next) => { - NProgress.start(); - const role = localStorage.getItem('ms_username'); - const permiss = usePermissStore(); - if (!role && to.path !== '/login') { - next('/login'); - } else if (to.meta.permiss && !permiss.key.includes(to.meta.permiss)) { - // 如果没有权限,则进入403 - next('/403'); - } else { - next(); - } -}); - -router.afterEach(() => { - NProgress.done() -}) - -export default router; +import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'; +import { usePermissStore } from '../store/permiss'; +import Home from '../views/home.vue'; +import NProgress from 'nprogress'; +import 'nprogress/nprogress.css'; + +const routes: RouteRecordRaw[] = [ + { + path: '/', + redirect: '/dashboard', + }, + { + path: '/', + name: 'Home', + component: Home, + children: [ + { + path: '/dashboard', + name: 'dashboard', + meta: { + title: '系统首页', + permiss: '0', + }, + component: () => import(/* webpackChunkName: "dashboard" */ '../views/dashboard.vue'), + }, + { + path: '/system-user', + name: 'system-user', + meta: { + title: '用户管理', + permiss: '11', + }, + component: () => import(/* webpackChunkName: "system-user" */ '../views/system/user.vue'), + }, + { + path: '/system-role', + name: 'system-role', + meta: { + title: '角色管理', + permiss: '12', + }, + component: () => import(/* webpackChunkName: "system-role" */ '../views/system/role.vue'), + }, + { + path: '/system-menu', + name: 'system-menu', + meta: { + title: '菜单管理', + permiss: '13', + }, + component: () => import(/* webpackChunkName: "system-menu" */ '../views/system/menu.vue'), + }, + { + path: '/table', + name: 'basetable', + meta: { + title: '基础表格', + permiss: '31', + }, + component: () => import(/* webpackChunkName: "table" */ '../views/table/basetable.vue'), + }, + { + path: '/table-editor', + name: 'table-editor', + meta: { + title: '可编辑表格', + permiss: '32', + }, + component: () => import(/* webpackChunkName: "table-editor" */ '../views/table/table-editor.vue'), + }, + { + path: '/schart', + name: 'schart', + meta: { + title: 'schart图表', + permiss: '41', + }, + component: () => import(/* webpackChunkName: "schart" */ '../views/chart/schart.vue'), + }, + { + path: '/echarts', + name: 'echarts', + meta: { + title: 'echarts图表', + permiss: '42', + }, + component: () => import(/* webpackChunkName: "echarts" */ '../views/chart/echarts.vue'), + }, + + { + path: '/icon', + name: 'icon', + meta: { + title: '图标', + permiss: '5', + }, + component: () => import(/* webpackChunkName: "icon" */ '../views/pages/icon.vue'), + }, + { + path: '/ucenter', + name: 'ucenter', + meta: { + title: '个人中心', + }, + component: () => import(/* webpackChunkName: "ucenter" */ '../views/pages/ucenter.vue'), + }, + { + path: '/editor', + name: 'editor', + meta: { + title: '富文本编辑器', + permiss: '291', + }, + component: () => import(/* webpackChunkName: "editor" */ '../views/pages/editor.vue'), + }, + { + path: '/markdown', + name: 'markdown', + meta: { + title: 'markdown编辑器', + permiss: '292', + }, + component: () => import(/* webpackChunkName: "markdown" */ '../views/pages/markdown.vue'), + }, + { + path: '/export', + name: 'export', + meta: { + title: '导出Excel', + permiss: '34', + }, + component: () => import(/* webpackChunkName: "export" */ '../views/table/export.vue'), + }, + { + path: '/import', + name: 'import', + meta: { + title: '导入Excel', + permiss: '33', + }, + component: () => import(/* webpackChunkName: "import" */ '../views/table/import.vue'), + }, + { + path: '/theme', + name: 'theme', + meta: { + title: '主题设置', + permiss: '7', + }, + component: () => import(/* webpackChunkName: "theme" */ '../views/pages/theme.vue'), + }, + { + path: '/calendar', + name: 'calendar', + meta: { + title: '日历', + permiss: '24', + }, + component: () => import(/* webpackChunkName: "calendar" */ '../views/element/calendar.vue'), + }, + { + path: '/watermark', + name: 'watermark', + meta: { + title: '水印', + permiss: '25', + }, + component: () => import(/* webpackChunkName: "watermark" */ '../views/element/watermark.vue'), + }, + { + path: '/carousel', + name: 'carousel', + meta: { + title: '走马灯', + permiss: '23', + }, + component: () => import(/* webpackChunkName: "carousel" */ '../views/element/carousel.vue'), + }, + { + path: '/tour', + name: 'tour', + meta: { + title: '分步引导', + permiss: '26', + }, + component: () => import(/* webpackChunkName: "tour" */ '../views/element/tour.vue'), + }, + { + path: '/steps', + name: 'steps', + meta: { + title: '步骤条', + permiss: '27', + }, + component: () => import(/* webpackChunkName: "steps" */ '../views/element/steps.vue'), + }, + { + path: '/form', + name: 'forms', + meta: { + title: '表单', + permiss: '21', + }, + component: () => import(/* webpackChunkName: "form" */ '../views/element/form.vue'), + }, + { + path: '/upload', + name: 'upload', + meta: { + title: '上传', + permiss: '22', + }, + component: () => import(/* webpackChunkName: "upload" */ '../views/element/upload.vue'), + }, + { + path: '/statistic', + name: 'statistic', + meta: { + title: '统计', + permiss: '28', + }, + component: () => import(/* webpackChunkName: "statistic" */ '../views/element/statistic.vue'), + }, + ], + }, + { + path: '/login', + meta: { + title: '登录', + noAuth: true, + }, + component: () => import(/* webpackChunkName: "login" */ '../views/pages/login.vue'), + }, + { + path: '/register', + meta: { + title: '注册', + noAuth: true, + }, + component: () => import(/* webpackChunkName: "register" */ '../views/pages/register.vue'), + }, + { + path: '/reset-pwd', + meta: { + title: '重置密码', + noAuth: true, + }, + component: () => import(/* webpackChunkName: "reset-pwd" */ '../views/pages/reset-pwd.vue'), + }, + { + path: '/403', + meta: { + title: '没有权限', + noAuth: true, + }, + component: () => import(/* webpackChunkName: "403" */ '../views/pages/403.vue'), + }, + { + path: '/404', + meta: { + title: '找不到页面', + noAuth: true, + }, + component: () => import(/* webpackChunkName: "404" */ '../views/pages/404.vue'), + }, + { path: '/:path(.*)', redirect: '/404' }, +]; + +const router = createRouter({ + history: createWebHashHistory(), + routes, +}); + +router.beforeEach((to, from, next) => { + NProgress.start(); + const role = localStorage.getItem('ms_username'); + const permiss = usePermissStore(); + + if (!role && to.meta.noAuth !== true) { + next('/login'); + } else if (to.meta.permiss && !permiss.key.includes(to.meta.permiss)) { + // 如果没有权限,则进入403 + next('/403'); + } else { + next(); + } +}); + +router.afterEach(() => { + NProgress.done(); +}); + +export default router; diff --git a/src/store/permiss.ts b/src/store/permiss.ts index 504d78ff..ac505b15 100644 --- a/src/store/permiss.ts +++ b/src/store/permiss.ts @@ -1,23 +1,58 @@ -import { defineStore } from 'pinia'; - -interface ObjectList { - [key: string]: string[]; -} - -export const usePermissStore = defineStore('permiss', { - state: () => { - const keys = localStorage.getItem('ms_keys'); - return { - key: keys ? JSON.parse(keys) : <string[]>[], - defaultList: <ObjectList>{ - admin: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], - user: ['1', '2', '3', '11', '13', '14', '15'] - } - }; - }, - actions: { - handleSet(val: string[]) { - this.key = val; - } - } -}); +import { defineStore } from 'pinia'; + +interface ObjectList { + [key: string]: string[]; +} + +export const usePermissStore = defineStore('permiss', { + state: () => { + const keys = localStorage.getItem('ms_keys'); + return { + key: keys ? JSON.parse(keys) : <string[]>[], + defaultList: <ObjectList>{ + admin: [ + '0', + '1', + '11', + '12', + '13', + '2', + '21', + '22', + '23', + '24', + '25', + '26', + '27', + '28', + '29', + '291', + '292', + '3', + '31', + '32', + '33', + '34', + '4', + '41', + '42', + '5', + '7', + '6', + '61', + '62', + '63', + '64', + '65', + '66', + ], + user: ['0', '1', '11', '12', '13'], + }, + }; + }, + actions: { + handleSet(val: string[]) { + this.key = val; + }, + }, +}); diff --git a/src/store/sidebar.ts b/src/store/sidebar.ts index ab7a146d..78d4c54d 100644 --- a/src/store/sidebar.ts +++ b/src/store/sidebar.ts @@ -1,15 +1,25 @@ -import { defineStore } from 'pinia'; - -export const useSidebarStore = defineStore('sidebar', { - state: () => { - return { - collapse: false - }; - }, - getters: {}, - actions: { - handleCollapse() { - this.collapse = !this.collapse; - } - } -}); +import { defineStore } from 'pinia'; + +export const useSidebarStore = defineStore('sidebar', { + state: () => { + return { + collapse: false, + bgColor: localStorage.getItem('sidebar-bg-color') || '#324157', + textColor: localStorage.getItem('sidebar-text-color') || '#bfcbd9' + }; + }, + getters: {}, + actions: { + handleCollapse() { + this.collapse = !this.collapse; + }, + setBgColor(color: string) { + this.bgColor = color; + localStorage.setItem('sidebar-bg-color', color); + }, + setTextColor(color: string) { + this.textColor = color; + localStorage.setItem('sidebar-text-color', color); + } + } +}); diff --git a/src/store/tags.ts b/src/store/tabs.ts similarity index 79% rename from src/store/tags.ts rename to src/store/tabs.ts index 7f8ff18b..b63719e0 100644 --- a/src/store/tags.ts +++ b/src/store/tabs.ts @@ -1,53 +1,53 @@ -import { defineStore } from 'pinia'; - -interface ListItem { - name: string; - path: string; - title: string; -} - -export const useTagsStore = defineStore('tags', { - state: () => { - return { - list: <ListItem[]>[] - }; - }, - getters: { - show: state => { - return state.list.length > 0; - }, - nameList: state => { - return state.list.map(item => item.name); - } - }, - actions: { - delTagsItem(index: number) { - this.list.splice(index, 1); - }, - setTagsItem(data: ListItem) { - this.list.push(data); - }, - clearTags() { - this.list = []; - }, - closeTagsOther(data: ListItem[]) { - this.list = data; - }, - closeCurrentTag(data: any) { - for (let i = 0, len = this.list.length; i < len; i++) { - const item = this.list[i]; - if (item.path === data.$route.fullPath) { - if (i < len - 1) { - data.$router.push(this.list[i + 1].path); - } else if (i > 0) { - data.$router.push(this.list[i - 1].path); - } else { - data.$router.push('/'); - } - this.list.splice(i, 1); - break; - } - } - } - } -}); +import { defineStore } from 'pinia'; + +interface ListItem { + name: string; + path: string; + title: string; +} + +export const useTabsStore = defineStore('tabs', { + state: () => { + return { + list: <ListItem[]>[] + }; + }, + getters: { + show: state => { + return state.list.length > 0; + }, + nameList: state => { + return state.list.map(item => item.name); + } + }, + actions: { + delTabsItem(index: number) { + this.list.splice(index, 1); + }, + setTabsItem(data: ListItem) { + this.list.push(data); + }, + clearTabs() { + this.list = []; + }, + closeTabsOther(data: ListItem[]) { + this.list = data; + }, + closeCurrentTag(data: any) { + for (let i = 0, len = this.list.length; i < len; i++) { + const item = this.list[i]; + if (item.path === data.$route.fullPath) { + if (i < len - 1) { + data.$router.push(this.list[i + 1].path); + } else if (i > 0) { + data.$router.push(this.list[i - 1].path); + } else { + data.$router.push('/'); + } + this.list.splice(i, 1); + break; + } + } + } + } +}); diff --git a/src/store/theme.ts b/src/store/theme.ts new file mode 100644 index 00000000..faf228d2 --- /dev/null +++ b/src/store/theme.ts @@ -0,0 +1,58 @@ +import { mix, setProperty } from '@/utils'; +import { defineStore } from 'pinia'; + +export const useThemeStore = defineStore('theme', { + state: () => { + return { + primary: '', + success: '', + warning: '', + danger: '', + info: '', + headerBgColor: '#242f42', + headerTextColor: '#fff', + }; + }, + getters: {}, + actions: { + initTheme() { + ['primary', 'success', 'warning', 'danger', 'info'].forEach((type) => { + const color = localStorage.getItem(`theme-${type}`) || ''; + if (color) { + this.setPropertyColor(color, type); // 设置主题色 + } + }); + const headerBgColor = localStorage.getItem('header-bg-color'); + headerBgColor && this.setHeaderBgColor(headerBgColor); + const headerTextColor = localStorage.getItem('header-text-color'); + headerTextColor && this.setHeaderTextColor(headerTextColor); + }, + resetTheme() { + ['primary', 'success', 'warning', 'danger', 'info'].forEach((type) => { + this.setPropertyColor('', type); // 重置主题色 + }); + }, + setPropertyColor(color: string, type: string = 'primary') { + this[type] = color; + setProperty(`--el-color-${type}`, color); + localStorage.setItem(`theme-${type}`, color); + this.setThemeLight(type); + }, + setThemeLight(type: string = 'primary') { + [3, 5, 7, 8, 9].forEach((v) => { + setProperty(`--el-color-${type}-light-${v}`, mix('#ffffff', this[type], v / 10)); + }); + setProperty(`--el-color-${type}-dark-2`, mix('#ffffff', this[type], 0.2)); + }, + setHeaderBgColor(color: string) { + this.headerBgColor = color; + setProperty('--header-bg-color', color); + localStorage.setItem(`header-bg-color`, color); + }, + setHeaderTextColor(color: string) { + this.headerTextColor = color; + setProperty('--header-text-color', color); + localStorage.setItem(`header-text-color`, color); + } + } +}); \ No newline at end of file diff --git a/src/types/form-option.ts b/src/types/form-option.ts new file mode 100644 index 00000000..8432704c --- /dev/null +++ b/src/types/form-option.ts @@ -0,0 +1,21 @@ +export interface FormOption { + list: FormOptionList[]; + labelWidth?: number | string; + span?: number; + +} + +export interface FormOptionList { + prop: string; + label: string; + type: string; + placeholder?: string; + disabled?: boolean; + opts?: any[]; + format?: string; + activeValue?: any; + inactiveValue?: any; + activeText?: string; + inactiveText?: string; + required?: boolean; +} \ No newline at end of file diff --git a/src/types/menu.ts b/src/types/menu.ts new file mode 100644 index 00000000..8002ac08 --- /dev/null +++ b/src/types/menu.ts @@ -0,0 +1,9 @@ +export interface Menus { + id: string; + pid?: string; + icon?: string; + index: string; + title: string; + permiss?: string; + children?: Menus[]; +} \ No newline at end of file diff --git a/src/types/role.ts b/src/types/role.ts new file mode 100644 index 00000000..26d4ace1 --- /dev/null +++ b/src/types/role.ts @@ -0,0 +1,8 @@ + +export interface Role { + id: number; + name: string; + key: string; + status: boolean; + permiss: string[] +} \ No newline at end of file diff --git a/src/types/table.ts b/src/types/table.ts new file mode 100644 index 00000000..578f4621 --- /dev/null +++ b/src/types/table.ts @@ -0,0 +1,9 @@ +export interface TableItem { + id: number; + name: string; + thumb: string; + money: number; + state: string; + date: string; + address: string; +} \ No newline at end of file diff --git a/src/types/user.ts b/src/types/user.ts new file mode 100644 index 00000000..42695c84 --- /dev/null +++ b/src/types/user.ts @@ -0,0 +1,16 @@ + +export interface User { + id: number; + name: string; + password: string; + email: string; + phone: string; + role: string; + date: string; +} + +export interface Register { + username: string; + password: string; + email: string; +} \ No newline at end of file diff --git a/src/utils/china.ts b/src/utils/china.ts new file mode 100644 index 00000000..c2042104 --- /dev/null +++ b/src/utils/china.ts @@ -0,0 +1,3 @@ +let chinaMap:any = {"type":"FeatureCollection","features":[{"id":"710000","geometry":{"type":"MultiPolygon","coordinates":[["@@°Ü¯Û","@@ƛĴÕƊÉɼģºðʀ\\ƎsÆNŌÔĚänÜƤɊĂǀĆĴĤNJŨxĚĮǂƺòƌâÔ®ĮXŦţƸZûÐƕƑGđ¨ĭMó·ęcëƝɉlÝƯֹÅŃ^Ó·śŃNjƏďíåɛGɉ¿IċããF¥ĘWǬÏĶñÄ","@@\\p|WoYG¿¥Ij@","@@ ¡@V^RqBbAnTXeQr©C","@@ÆEEkWqë I"]],"encodeOffsets":[[[122886,24033],[123335,22980],[122375,24193],[122518,24117],[124427,22618]]]},"properties":{"cp":[121.509062,25.044332],"name":"台湾","childNum":5}},{"id":"130000","geometry":{"type":"MultiPolygon","coordinates":[["@@\\aM`ǽÓnUK Ĝēs¤©yrý§uģcJ»eIP]ªrºc_ħ²G¼s`jΟnüsÂľP","@@U`Ts¿mÄ","@@FOhđ©OiÃ`ww^ÌkÑH«ƇǤŗĺtFu {Z}Ö@U´ ʚLg®¯Oı°Ãw ^VbÉsmA ê]]w§RRl£ŭuwNÁ`ÇFēÝčȻuT¡Ĺ¯Õ¯sŗő£YªhVƍ£ƅnëYNgq¼ś¿µı²UºÝUąąŖóxV@tƯJ]eR¾fe|rHA|h~Ėƍl§ÏjVë` ØoÅbbx³^zÃĶ¶Sj®AyÂhðk`«P˵EFÛ¬Y¨Ļrõqi¼Wi°§Ð±²°`[À|ĠO@ÆxO\\ta\\p_Zõ^û{ġȧXýĪÓjùÎRb^λj{íděYfíÙTymńŵōHim½éŅaVcř§ax¹XŻácWU£ôãºQ¨÷Ñws¥qEHÙ|šYQoŕÇyáĂ£MðoťÊP¡mWO¡v{ôvîēÜISpÌhp¨ jdeŔQÖjX³àĈ[n`Yp@UcM`RKhEbpŞlNut®EtqnsÁgAiúoHqCXhfgu~ÏWP½¢G^}¯ÅīGCÑ^ãziMáļMTÃƘrMc|O_¯Ŏ´|morDkO\\mĆJfl@cĢ¬¢aĦtRıÒXòë¬WP{ŵǫƝ īÛ÷ąV×qƥV¿aȉd³BqPBmaËđŻģmÅ®V¹d^KKonYg¯XhqaLdu¥ÍpDž¡KąÅkĝęěhq}HyÃ]¹ǧ£ Í÷¿qágPmoei¤o^á¾ZEY^ Ný{nOl±Í@Mċèk§daNaÇį¿]øRiiñEūiDZàUtėGyl}ÓM}jpEC~¡FtoQiHkk{ILgĽxqÈƋÄdeVDJj£J|ÅdzÂFt~KŨ¸IÆv|¢r}èonb}`RÎÄn°ÒdÞ²^®lnÐèĄlðÓ×]ªÆ}LiñÖ`^°Ç¶p®đDcŋ`ZÔ¶êqvFÆN®ĆTH®¦O¾IbÐã´BĐɢŴÆíȦpĐÞXR·nndO¤OÀĈƒQgµFo|gȒęSWb©osx|hYhgŃfmÖĩnºTÌSp¢dYĤ¶UĈjlǐpäðëx³kÛfw²Xjz~ÂqbTÑěŨ@|oMzv¢ZrÃVw¬ŧĖ¸f°ÐTªqs{S¯r æÝl¼ÖĞ džiGĘJ¼lr}~K¨ŸƐÌWö¼Þ°nÞoĦL|C~D©|q]SvKÑcwpÏÏĿćènĪWlĄkT}¬Tp~®Hgd˒ĺBVtEÀ¢ôPĎƗè@~kü\\rÊĔÖæW_§¼F´©òDòjYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkvGpuARhÞÆǶgĘTǼƹS£¨¡ù³ŘÍ]¿ÂyôEP xX¶¹ÜO¡gÚ¡IwÃé¦ÅBÏ|Ç° N«úmH¯âbęU~xĈbȒ{^xÖlD¸dɂ~"]],"encodeOffsets":[[[120023,41045],[121616,39981],[122102,42307]]]},"properties":{"cp":[114.502461,38.045474],"name":"河北","childNum":3}},{"id":"140000","geometry":{"type":"Polygon","coordinates":["@@ħÜ_ªlìwGkÛÃǏokćiµVZģ¡coTS˹ĪmnÕńehZg{gtwªpXaĚThȑp{¶Eh®RćƑP¿£PmcªaJyý{ýȥoÅîɡųAďä³aÏJ½¥PGąSMsWz½µÛYÓŖgxoOkĒCoȵ]¯_²ÕjāK~©ÅØ^ÔkïçămÏk]±cݯÑÃmQÍ~_apm ~ç¡qu{JÅŧ·Ls}EyÁÆcI{¤IiCfUcƌÃp§]ě«vD@¡SÀµMÅwuYY¡DbÑc¡h×]nkoQdaMç~eDÛtT©±@¥ù@É¡ZcW|WqOJmĩl«ħşvOÓ«IqăV¥D[mI~Ó¢cehiÍ]Ɠ~ĥqX·eƷn±}v[ěďŕ]_œ`¹§ÕōIo©bs^}Ét±ū«³p£ÿ¥WÑxçÁ«h×u×¥ř¾dÒ{ºvĴÎêÌɊ²¶ü¨|ÞƸµȲLLúÉƎ¤ϊęĔV`_bªS^|dzY|dz¥pZbÆ£¶ÒK}tĦÔņƠPYznÍvX¶Ěn ĠÔzý¦ª÷ÑĸÙUȌ¸dòÜJð´ìúNM¬XZ´¤ŊǸ_tldI{¦ƀðĠȤ¥NehXnYGR° ƬDj¬¸|CĞKqºfƐiĺ©ª~ĆOQª ¤@ìǦɌ²æBÊTĞHƘÁĪËĖĴŞȀÆÿȄlŤĒötνî¼ĨXh|ªM¤ÐzÞĩÒSrao³"],"encodeOffsets":[[117016,41452]]},"properties":{"cp":[112.549248,37.857014],"name":"山西","childNum":1}},{"id":"150000","geometry":{"type":"MultiPolygon","coordinates":[["@@ǪƫÌÛM Ă[`ÕCn}¶Vc ês¯PqFB |S³C|kñHdiÄ¥sʼnÅ PóÑÑE^ÅPpy_YtShQ·aHwsOnʼnÃs©iqjUSiº]ïW«gW¡ARëśijĘ ů`çõh]y»ǃǛҤxÒm~zf}pf|ÜroÈzrKÈĵSƧżĠu~è¬vîS¼ĂhĖMÈÄw\\fŦ°W ¢¾luŸDw\\Ŗĝ","@@GVu»Aylßí¹ãe]Eāò³C¹ð¾²iÒAdkò^P²CǜңDŽ z¼g^èöŰ_IJĕê}gÁnUI«m ]jvV¼euhwqAaW_µj »çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáGOUÛOB±XkŹ£k|e]olkVͼÕqtaÏõjgÁ£§U^RLËnX°ÇBz^~wfvypV ¯ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖM×ÍEyxþp]ÉvïèvƀnÂĴÖ@V~Ĉ³MEĸÅĖtējyÄDXÄxGQuv_i¦aBçw˛wD©{tāmQ{EJ§KPśƘƿ¥@sCTÉ}ɃwƇy±gÑ}T[÷kÐ禫 SÒ¥¸ëBX½HáŵÀğtSÝÂa[ƣ°¯¦Pï¡]£ġÒk®G²èQ°óMq}EóƐÇ\\@áügQÍu¥FTÕ¿Jû]|mvāÎYua^WoÀa·ząÒot׶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶¿A[¡{d×uQAMxVvMOmăl«ct[wº_ÇÊjb£ĦS_éQZ_lwgOiýe`YYJq¥IÁdz£ÙË[ÕªuƏ³ÍTs·bÁĽäė[b[ŗfãcn¥îC¿÷µ[ŏÀQōĉm¿Á^£mJVmL[{Ï_£F¥Ö{ŹA} ×Wu©ÅaųijƳhB{·TQqÙIķËZđ©Yc|M¡ LeVUóK_QWk_ĥ¿ãZ»X\\ĴuUèlG®ěłTĠğDŃGÆÍz]± ŭ©Å]ÅÐ}UË¥©TċïxgckfWgi\\ÏĒ¥HkµEë{»ÏetcG±ahUiñiWsɁ·cCÕk]wȑ|ća}w VaĚá G°ùnM¬¯{ÈÐÆA¥ÄêJxÙ¢hP¢ÛºµwWOóFÁz^ÀŗÎú´§¢T¤ǻƺSėǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇqZñiñC³ª »E`¨åXēÕqÉû[l}ç@čƘóO¿¡FUsAʽīccocÇS}£IS~ălkĩXçmĈ ŀÐoÐdxÒuL^T{r@¢ÍĝKén£kQyÅõËXŷƏL§~}kq»IHėDžjĝ»ÑÞoå°qTt|r©ÏS¯·eŨĕx«È[eM¿yupN~¹ÏyN£{©għWí»Í¾səšDž_ÃĀɗ±ąijĉʍŌŷSÉA±åǥɋ@ë£R©ąP©}ĹªƏj¹erLDĝ·{i«ƫC½ÉshVz GS|úþXgp{ÁX¿ć{ƱȏñZáĔyoÁhA}ŅĆfdʼn_¹Y°ėǩÑ¡H¯¶oMQqð¡Ë|Ñ`ƭŁX½·óÛxğįÅcQs«tȋDžFù^it«Č¯[hAi©á¥ÇĚ×l|¹y¯Kȝqgů{ñǙµïċĹzŚȭ¶¡oŽäÕG\\ÄT¿Òõr¯LguÏYęRƩɷŌO\\İТæ^Ŋ IJȶȆbÜGĝ¬¿ĚVĎgª^íu½jÿĕęjık@Ľ]ėl¥ËĭûÁėéV©±ćn©ȇÍq¯½YÃÔʼnÉNÑÅÝy¹NqáʅDǡËñƁYÅy̱os§ȋµʽǘǏƬɱàưN¢ƔÊuľýľώȪƺɂļxZĈ}ÌʼnŪĺœĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~ǼȳÐUfdIxÿ\\G zâɏÙOº·pqy£@qþ@Ǟ˽IBäƣzsÂZÁàĻdñ°ŕzéØűzșCìDȐĴĺf®Àľưø@ɜÖÞKĊŇƄ§͑těï͡VAġÑÑ»d³öǍÝXĉĕÖ{þĉu¸ËʅğU̎éhɹƆ̗̮ȘNJ֥ड़ࡰţાíϲäʮW¬®ҌeרūȠkɬɻ̼ãüfƠSצɩςåȈHϚÎKdzͲOðÏȆƘ¼CϚǚ࢚˼ФÔ¤ƌĞ̪Qʤ´¼mȠJˀƲÀɠmɆDŽĜƠ´ǠN~ʢĜ¶ƌĆĘźʆȬ˪ĚĒ¸ĞGȖƴƀj`ĢçĶāàŃºēĢĖćYÀŎüôQÐÂŎŞdžŞêƖoˆDĤÕºÑǘÛˤ³̀gńƘĔÀ^ªƂ`ªt¾äƚêĦĀ¼ÐĔǎ¨Ȕ»͠^ˮÊȦƤøxRrŜH¤¸ÂxDÄ|ø˂˜ƮЬɚwɲFjĔ²Äw°dždÀÉ_ĸdîàŎjÊêTЪŌŜWÈ|tqĢUB~´°ÎFCU¼pĀēƄN¦¾O¶łKĊOjĚj´ĜYp{¦SĚÍ\\TתV÷Ší¨ÅDK°ßtŇĔK¨ǵÂcḷ̌ĚǣȄĽFlġUĵŇȣFʉɁMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFxúQEr´Wrh¤Ɛ \\talĈDJÜ|[Pll̚¸ƎGú´P¬W¦^¦H]prRn|or¾wLVnÇIujkmon£cX^Bh`¥V¦U¤¸}xRj[^xN[~ªxQ[`ªHÆÂExx^wN¶Ê|¨ìMrdYpoRzNyÀDs~bcfÌ`L¾n|¾T°c¨È¢ar¤`[|òDŞĔöxElÖdHÀI`Ď\\Àì~ÆR¼tf¦^¢ķ¶eÐÚMptgjɡČÅyġLûŇV®ÄÈƀĎ°P|ªVVªj¬ĚÒêp¬E|ŬÂ_~¼rƐK f{ĘFĒƌXưăkÃĄ}nµo×q£çkX{uĩ«āíÓUŅÝVUŌ]Ť¥lyň[oi{¦Lĸ Ħ^ôâJ¨^UZðÚĒL¿Ìf£K£ʺoqNwğc`uetOj×°KJ±qÆġmĚŗos¬ qehqsuH{¸kH¡ ÊRǪÇƌbȆ¢´äÜ¢NìÉʖ¦â©Ɨؗ"]],"encodeOffsets":[[[128500,52752],[127089,51784]]]},"properties":{"cp":[111.670801,40.818311],"name":"内蒙古","childNum":2}},{"id":"210000","geometry":{"type":"MultiPolygon","coordinates":[["@@L@@s]","@@MnNm","@@dc","@@eÀC@b","@@f XwkbrÄ`qg","@@^jtWQ","@@~ Y[c","@@I`ĖN^_¿ZÁM","@@Ïxnj{q_×^Gigp","@@iX¶B Y","@@Y Z","@@L_yG`b","@@^WqCTZ","@@\\[§t|]","@@m`p[","@@@é^BntaÊU]x ¯ÄPIJ°hʙK³VÕ@Y~|EvĹsǦL^pòŸÒG Ël]xxÄ_fT¤Ď¤cPC¨¸TVjbgH²sdÎdHt`B²¬GJję¶[ÐhjeXdlwhðSȦªVÊÏÆZÆŶ®²^ÎyÅHńĚDMħĜŁHkçvV[ij¼WYÀäĦ`XlR`ôLUVfK¢{NZdĒªYĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~źB|¦ÕE¤Ð`\\|KUnnI]¤ÀÂĊnŎR®Ő¿¶\\ÀøíDm¦ÎbŨabaĘ\\ľã¸atÎSƐ´©v\\ÖÚÌǴ¤Â¨JKrZ_ZfjþhPkx`YRIjJcVf~sCN¤ EhæmsHy¨SðÑÌ\\\\ĐRÊwS¥fqŒßýáĞÙÉÖ[^¯ǤŲê´\\¦¬ĆPM¯£»uïpùzExanµyoluqe¦W^£ÊL}ñrkqWňûPUP¡ôJoo·U}£[·¨@XĸDXmÛݺGUCÁª½{íĂ^cjk¶Ã[q¤LÉö³cux«|Zd²BWÇ®Yß½ve±ÃCý£W{Ú^q^sÑ·¨ËMr¹·C¥GDrí@wÕKţëV·i}xËÍ÷i©ĝɝǡ]{c±OW³Ya±_ç©HĕoƫŇqr³Lys[ñ³¯OSďOMisZ±ÅFC¥Pq{Ã[Pg}\\¿ghćO k^ĩÃXaĕËĥMoEqqZûěʼn³F¦oĵhÕP{¯~TÍlªNßYÐ{Ps{ÃVUeĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀffdF~ĀeĖd`sx² ®EĦ¦dQÂd^~ăÔH¦\\LKpĄVez¤NP ǹÓRÆąJSha[¦´ÂghwmBШźhI|VV|p] ¼èNä¶ÜBÖ¼L`¼bØæKVpoúNZÞÒKxpw|ÊEMnzEQIZZNBčÚFÜçmĩWĪñtÞĵÇñZ«uD±|ƏlǗw·±PmÍada CLǑkùó¡³Ï«QaċÏOÃ¥ÕđQȥċƭy³ÁA"]],"encodeOffsets":[[[123686,41445],[126019,40435],[124393,40128],[126117,39963],[125322,40140],[126686,40700],[126041,40374],[125584,40168],[125509,40217],[125453,40165],[125362,40214],[125280,40291],[125774,39997],[125976,40496],[125822,39993],[122731,40949]]]},"properties":{"cp":[123.429096,41.796767],"name":"辽宁","childNum":16}},{"id":"220000","geometry":{"type":"Polygon","coordinates":["@@ñr½ÉKāGÁ¤ia Éȹ`\\xs¬dĆkNnuNUwNx¶c¸|\\¢ GªóĄ~RãÖÎĢùđŴÕhQxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp]vbÍZuĂ{n^IüÀSÖ¦EvRÎûh@â[ƏÈô~FNr¯ôçR±HÑlĢ^¤¢OðætxsŒ]ÞÁTĠs¶¿âÆGW¾ìA¦·TѬè¥ÏÐJ¨¼ÒÖ¼ƦɄxÊ~StD@Ă¼Ŵ¡jlºWvÐzƦZвCH AxiukdGgetqmcÛ£Ozy¥cE}| ¾cZ k¿uŐã[oxGikfeäT@ SUwpiÚFM©£è^Ú`@v¶eňf heP¶täOlÃUgÞzŸU`l}ÔÆUvØ_Ō¬Öi^ĉi§²ÃB~¡ĈÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYxƘDVÇĺĿg¿cwÅ\\¹¥Yĭl¤OvLjM_a W`zļMž·\\swqÝSAqŚij¯°kRē°wx^ĐkǂÒ\\]nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°G³¼XÀ¤¹i´o¤ŃÈ`ÌDzÄUĞd\\iÖmÈBĤÜɲDEh LG¾ƀľ{WaYÍÈĢĘÔRîĐj}ÇccjoUb½{h§Ǿ{KƖµÎ÷GĄØŜçưÌs«lyiē«`å§H¥Ae^§GK}iã\\c]v©ģZmÃ|[M}ģTɟĵÂÂ`ÀçmFK¥ÚíÁbX³ÌQÒHof{]ept·GŋĜYünĎųVY^ydõkÅZW«WUa~U·SbwGçǑiW^qFuNĝ·EwUtW·Ýďæ©PuqEzwAVXRãQ`©GY YhcUGorBd}ģÉb¡·µMicF«Yƅ» é\\ɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ýL¡ûsT\\rke\\PnwAKy}ywdSefµ]UhĿD@mÿvaÙNSkCun cÿ`lWėVâ¦÷~^fÏ~vwHCį`xqTlW«ï¸skmßEGqd¯R ©Ý¯¯S\\cZ¹iűƏCuƍÓXoR}M^o£ R}oªUF uuXHlEÅÏ©¤ßgXþ¤D²ÄufàÀXXȱAc{Yw¬dvõ´KÊ£\\rµÄlidā]|DÂVH¹Þ®ÜWnCķ W§@\\¸~¤Vp¸póIO¢VOŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúv𼤠N°ąO¥«³[éǣű]°Õ\\ÚÊĝôîŇÔaâBYlďQ[ Ë[ïÒ¥RI|`j]P"],"encodeOffsets":[[126831,44503]]},"properties":{"cp":[125.3245,43.886841],"name":"吉林","childNum":1}},{"id":"230000","geometry":{"type":"MultiPolygon","coordinates":[["@@UµNÿ¥īèçHÍøƕ¶Lǽ|g¨|a¾pVidd~ÈiíďÓQġėÇZÎXb½|ſÃH½KFgɱCģÛÇAnjÕc[VĝDZÃËÇ_ £ń³pj£º¿»WH´¯U¸đĢmtĜyzzNN|g¸÷äűѱĉā~mq^[ǁÑďlw]¯xQĔ¯l°řĴrBÞTxr[tŽ¸ĻN_yX`biNKu P£kZĮ¦[ºxÆÀdhĹŀUÈƗCwáZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFć}¢A±Äj¨]ĊÕjŋ«×`VuÓÅ~_kŷVÝyhVkÄãPsOµfgeŇ µf@u_Ù ÙcªNªÙEojVxT@ãSefjlwH\\pŏäÀvlY½d{F~¦dyz¤PÜndsrhfHcvlwjF£G±DÏƥYyÏu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|C˜zxAè¥bfudTrFWÁ¹Am|ĔĕsķÆF´N}ć UÕ@Áijſmuçuð^ÊýowFzØÎĕNőǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°Uzouxe]} AyÈW¯ÌmKQ]Īºif¸ÄX|sZt|½ÚUÎ lk^p{f¤lºlÆW A²PVÜPHÊâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi`¶bXrBgxfv»uUi^v~J¬mVp´£´VWrnP½ì¢BX¬hðX¹^TjVriªjtŊÄmtPGx¸bgRsT`ZozÆO]ÒFôÒOÆŊvÅpcGêsx´DR{AEOr°x|íb³Wm~DVjºéNNËܲɶGxŷCSt}]ûōSmtuÇÃĕNāg»íT«u}ç½BĵÞʣ¥ëÊ¡MÛ³ãȅ¡ƋaǩÈÉQG¢·lG|tvgrrf«ptęŘnÅĢrI²¯LiØsPf_vĠdxM prʹL¤¤eËÀđKïÙVY§]Ióáĥ]ķK¥j|pŇ\\kzţ¦šnņäÔVĂîĪ¬|vW®l¤èØrxm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄĄ»ƢjȦOǺ¨ìSŖÆƬyQv`cwZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨSfm ĊƀP̎ēz©ĊÄÕÊmgÇsJ¥ƔŊśæÎÑqv¿íUOµªÂnĦÁ_½ä@êí £P}Ġ[@gġ}gɊ×ûÏWXá¢užƻÌsNͽƎÁ§čŐAēeL³àydl¦ĘVçŁpśdžĽĺſÊQíÜçÛġÔsĕ¬Ǹ¯YßċġHµ ¡eå`ļrĉŘóƢFìĎWøxÊkƈdƬv|I|·©NqńRŀ¤éeŊŀàŀU²ŕƀBQ£Ď}L¹Îk@©ĈuǰųǨÚ§ƈnTËÇéƟÊcfčŤ^XmHĊĕË«W·ċëx³ǔķÐċJāwİ_ĸȀ^ôWr°oú¬Ħ ŨK~ȰCĐ´Ƕ£fNÎèâw¢XnŮeÂÆĶ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®ØCÔ ŬGƠƦYĜĘÜƬDJg_ͥœ@čŅĻA¶¯@wÎqC½Ĉ»NăëKďÍQÙƫ[«ÃígßÔÇOÝáWñuZ¯ĥŕā¡ÑķJu¤E 寰WKɱ_d_}}vyõu¬ï¹ÓU±½@gÏ¿rýDg Cdµ°MFYxw¿CG£Rƛ½Õ{]L§{qqą¿BÇƻğëܭNJË|c²}Fµ}ÙRsÓpg±QNqǫŋRwŕnéÑÉK«SeYR ŋ@{¤SJ}D Ûǖ֍]gr¡µŷjqWÛham³~S«Ü[","@@ƨĶTLÇyqpÇÛqe{~oyen}s`qiXGù]Ëp½©lÉÁp]Þñ´FĂ^fäîºkàz¼BUv¬D"]],"encodeOffsets":[[[134456,44547],[127123,51780]]]},"properties":{"cp":[126.642464,45.756967],"name":"黑龙江","childNum":2}},{"id":"320000","geometry":{"type":"Polygon","coordinates":["@@Õg^vÁbnÀ`Jnĝ¬òM¶ĘTÖŒbe¦¦{¸ZâćNp©Hp|`mjhSEb\\afv`sz^lkljÄtg¤D¾X¿À|ĐiZȀåB·î}GL¢õcßjayBFµÏC^ĭcÙt¿sğH]j{s©HM¢QnDÀ©DaÜÞ·jgàiDbPufjDk`dPOîhw¡ĥ¥GP²ĐobºrYî¶aHŢ´ ]´rılw³r_{£DB_Ûdåuk|Ũ¯F Cºyr{XFye³Þċ¿ÂkĭB¿MvÛpm`rÚã@Ę¹hågËÖƿxnlč¶Åì½Ot¾dJlVJĂǀŞqvnO^JZż·Q}êÍÅmµÒ]ƍ¦Dq}¬R^èĂ´ŀĻĊIÔtIJyQŐĠMNtR®òLhĚs©»}OÓGZz¶A\\jĨFäOĤHYJvÞHNiÜaĎÉnFQlNM¤B´ĄNöɂtpŬdZÅglmuÇUšŞÚb¤uŃJŴu»¹ĄlȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Yrřl¥i`ã__¢ćSÅr[Çq^ùzWmOĈaŐÝɞï²ʯʊáĘijĒǭPħ͍ôƋÄÄÍīçÛɈǥ£ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ¡RLčiXyÅNïă¡¸iĔÏNÌķoıdōîåŤûHcs}~Ûwbù¹£¦ÓCtOPrE^ÒogĉIµÛÅʹK ¤½phMú`mR¸¦PƚgÉLRs`£¯ãhD¨|³¤C"],"encodeOffsets":[[121451,32518]]},"properties":{"cp":[118.767413,32.041544],"name":"江苏","childNum":1}},{"id":"330000","geometry":{"type":"MultiPolygon","coordinates":[["@@jX^n ","@@sfdM","@@qP\\xz[_i","@@o\\VzRZ}mECy","@@R¢FX}°[m]","@@Cb\\}","@@e|v\\laus","@@v~s{","@@QxÂF©}","@@¹nvÞs©m","@@rQgYIh","@@bi«ZX","@@p[}ILd","@@À¿|","@@¹dnb ","@@rS}[Kl","@@g~h}","@@FlCk","@@ůTG°ĄLHm°UF","@@OdRe","@@v[u\\","@@FjâL~wyoo~sµLZ","@@¬e¹aH","@@\\nÔ¡q]L³ë\\ÿ®QÌ","@@ÊA©]ª","@@Kxv{","@@@hlIk_","@@pWcrxp","@@Md|_iA","@@¢ X£½z\\ðpN","@@hlÜ[LykAvyfw^E ","@@fp¤MusH","@@®_ma~LÁ¬`","@@@°¡mÛGĕ¨§Ianá[ýƤjfæÐNäGp","@@iMt\\","@@Zc[b","@@X®±GrÆ°Zæĉm","@@Z~dOSo|A¿qZv","@@@`EN£p","@@|s","@@@nDi","@@n a£¾uYL¯Qª mĉÅdMgÇjcº«ę¬K´B«Âącoċ\\xK`cįŧ«®á[~ıxu·ÅKsËÉc¢Ù\\ĭƛëbf¹ģSĜkáƉÔĈZB{aMµfzʼnfÓÔŹŁƋǝÊĉ{ğč±g³ne{çií´S¬\\ßðK¦w\\iqªĭiAuAµ_W¥ƣO\\lċĢttC¨£t`PZäuXßBsĻyekOđġĵHuXBµ]×\\°®¬F¢¾pµ¼kŘó¬Wät¸|@L¨¸µrºù³Ù~§WIZW®±Ð¨ÒÉx`²pĜrOògtÁZ{üÙ[|ûKwsPlU[}¦Rvn`hsª^nQ´ĘRWb_ rtČFIÖkĦPJ¶ÖÀÖJĈĄTĚòC ²@Pú Øz©PCÈÚĒ±hŖl¬â~nm¨f©iļ«mntqÒTÜÄjL®EÌFª²iÊxبIÈhhst[Ôx}dtüGæţŔïĬaĸpMËÐjē¢·ðĄÆMzjWKĎ¢Q¶À_ê_@ıi«pZgf¤Nrq]§ĂN®«H±yƳí¾×ŊďŀĐÏŴǝĂíÀBŖÕªÁŐTFqĉ¯³ËCĕģi¨hÜ·ñt»¯Ï","@@ºwZRkĕWK "]],"encodeOffsets":[[[125785,31436],[125729,31431],[125513,31380],[125329,30690],[125223,30438],[125115,30114],[124815,29155],[124419,28746],[124095,28635],[124005,28609],[125000,30713],[125111,30698],[125078,30682],[125150,30684],[124014,28103],[125008,31331],[125411,31468],[125329,31479],[125369,31139],[125626,30916],[125417,30956],[125254,30976],[125199,30997],[125095,31058],[125083,30915],[124885,31015],[125218,30798],[124867,30838],[124755,30788],[124802,30809],[125267,30657],[125218,30578],[125200,30562],[125192,30787],[124968,30474],[125167,30396],[125115,30363],[124955,29879],[124714,29781],[124762,29462],[124325,28754],[124863,30077],[125366,31477]]]},"properties":{"cp":[120.153576,30.287459],"name":"浙江","childNum":43}},{"id":"340000","geometry":{"type":"MultiPolygon","coordinates":[["@@^iuLV\\","@@e©Edh","@@´CE¶zAXêeödK¡~H¸íæAȽd{ďÅÀ½W®£ChÃsikkly]_teu[bFaTign{]GqªoĈMYá|·¥f¥őaSÕėNµñĞ«Im_m¿Âa]uĜp Z_§{Cäg¤°r[_YjÆOdý[I[á·¥Q_nùgL¾mzˆDÜƶĊJhpc¹O]iŠ]¥ jtsggDÑ¡w×jÉ©±EFËKiÛÃÕYv sm¬njĻª§emná}k«ŕgđ²ÙDÇ¤í¡ªOy×Où±@DñSęćăÕIÕ¿IµĥOlJÕÍRÍ|JìĻÒåyķrĕq§ÄĩsWÆßF¶X®¿mw RIÞfßoG³¾©uyHį{Ɓħ¯AFnuP ÍÔzVdàôº^Ðæd´oG¤{S¬ćxã}ŧ×Kǥĩ«ÕOEзÖdÖsƘѨ[Û^Xr¢¼§xvÄƵ`K§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē ßúLÃÃ_ÈÏ|]ÂÏHlg`ben¾¢pUh~ƴĖ¶_r sĄ~cƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³ ]u}f ïQl{skloNdjäËzDvčoQďHI¦rbrHĖ~BmlNRaĥTX\\{fÁKÁ®TLÂÄMtÊgĀDĄXƔvDcÎJbt[¤D@®hh~kt°ǾzÖ@¾ªdbYhüóV´ŮŒ¨Üc±r@J|àuYÇÔG·ĚąĐlŪÚpSJ¨ĸLvÞcPæķŨ®mÐálsgd×mQ¨ųÆ©Þ¤IÎs°KZpĄ|XwWdϵmkǀwÌÕæhºgBĝâqÙĊzÖgņtÀÁĂÆáhEz|WzqD¹°Eŧl{ævÜcA`¤C`|´qxIJkq^³³GšµbíZ ¹qpa±ď OH¦Ħx¢gPícOl_iCveaOjCh߸iÝbÛªCC¿mRV§¢A|tbkĜEÀtîm^g´fÄ"]],"encodeOffsets":[[[121722,32278],[119475,30423],[121606,33646]]]},"properties":{"cp":[117.283042,31.86119],"name":"安徽","childNum":3}},{"id":"350000","geometry":{"type":"MultiPolygon","coordinates":[["@@zht´}[","@@aj^~ĆGå","@@edH se","@@@vPGsyQ","@@sBzddW[O","@@S¨Qy","@@NVucW","@@qptB@q","@@¸[iu","@@Q\\pD[_","@@jSwUappI","@@eXª~","@@AjvFoo","@@fT_Çí\\v|ba¦jZÆy|®","@@IjLg","@@wJIx«¼AoNe{M¥","@@K±¡ÓČ~N¾","@@k¡¹Eh~c®uDqZì¡I~Māe£bN¨gZý¡a±Öcp©PhI¢Qq ÇGj|¥U g[Ky¬ŏv@OptÉEF\\@ åA¬V{XģĐBy cpě ¼³Ăp·¤¥ohqqÚ¡ŅLs^á§qlÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ßėuĕeûÒiÁŧS[¡Uûŗ½ùěcݧSùĩąSWó«íęACµeRåǃRCÒÇZÍ¢ź±^dlstjD¸ZpuÔâÃH¾oLUêÃÔjjēò´ĄWƛ ^Ñ¥Ħ@ÇòmOw¡õyJyD}¢ďÑÈġfZda©º²z£NjD°Ötj¶¬ZSÎ~¾c°¶ÐmxO¸¢Pl´SL|¥AȪĖMņIJg®áIJČĒü` QF¬h|ĂJ@zµ |ê³È ¸UÖŬŬÀCtrĸr]ðM¤ĶIJHtÏ AĬkvsq^aÎbvdfÊòSD´Z^xPsĂrvƞŀjJd×ŘÉ ®AΦĤdxĆqAZRÀMźnĊ»İÐZ YXæJyĊ²·¶q§·K@·{sXãô«lŗ¶»o½E¡«¢±¨Y®Ø¶^AvWĶGĒĢPlzfļtàAvWYãO_¤sD§ssČġ[kƤPX¦`¶®BBvĪjv©jx[L¥àï[F ¼ÍË»ğV`«Ip}ccÅĥZEãoP ´B@D¸m±z«Ƴ¿å³BRضWlâþäą`]Z£Tc ĹGµ¶Hm@_©k¾xĨôȉðX«½đCIbćqK³ÁÄš¬OAwã»aLʼnËĥW[ÂGIÂNxij¤D¢îĎÎB§°_JGs¥E@ ¤uć PåcuMuw¢BI¿]zG¹guĮI"]],"encodeOffsets":[[[123250,27563],[122541,27268],[123020,27189],[122916,27125],[122887,26845],[122808,26762],[122568,25912],[122778,26197],[122515,26757],[122816,26587],[123388,27005],[122450,26243],[122578,25962],[121255,25103],[120987,24903],[122339,25802],[121042,25093],[122439,26024]]]},"properties":{"cp":[119.306239,26.075302],"name":"福建","childNum":18}},{"id":"360000","geometry":{"type":"Polygon","coordinates":["@@ÖP¬ǦĪØLŨä~Ĉw«|TH£pc³Ïå¹]ĉđxe{ÎÓvOEm°BƂĨİ|Gvz½ª´HàpeJÝQxnÀWEµàXÅĪt¨ÃĖrÄwÀFÎ|Ă¡WÕ¸cf¥XaęST±m[r«_gmQu~¥V\\OkxtL E¢Ú^~ýØkbēqoě±_Êw§Ñ²ÏƟė¼mĉŹ¿NQ YBąrwģcÍ¥BŗÊcØiIƝĿuqtāwO]³YCñTeÉcaubÍ]trluī BÐGsĵıN£ï^ķqsq¿DūūVÕ·´Ç{éĈýÿOER_đûIċâJhŅıNȩĕB ¦K{Tk³¡OP·wnµÏd¯}½TÍ«YiµÕsC¯iM¤¦¯P|ÿUHvhe¥oFTuõ\\OSsMòđƇiaºćXĊĵà·çhƃ÷Ç{ígu^đgm[ÙxiIN¶Õ»lđÕwZSÆv©_ÈëJbVkĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B±ÌKyñ`w²¹· `gsÙfIěxŕeykpudjuTfb·hh¿Jd[\\LáƔĨƐAĈepÀÂMD~ņªe^\\^§ý©j×cZبzdÒa¶lÒJìõ`oz÷@¤u޸´ôęöY¼HČƶajlÞƩ¥éZ[|h}^U ¥pĄžƦO lt¸Æ Q\\aÆ|CnÂOjtĚĤdÈF`¶@Ðë ¦ōÒ¨SêvHĢÛ@[Æ QoxHW[ŰîÀt¦DŽ~NĠ¢lĄtZoCƞÔºCxrpČNpj¢{f_Y`_eq®Aot`@oDXfkp¨|s¬\\DÄSfè©Hn¬ ^DhÆyøJhØxĢĀLÊƠPżċĄwĮ¶"],"encodeOffsets":[[118923,30536]]},"properties":{"cp":[115.892151,28.676493],"name":"江西","childNum":1}},{"id":"370000","geometry":{"type":"MultiPolygon","coordinates":[["@@Xjd]mE","@@itnq","@@Dl@k","@@TGw","@@K¬U","@@Wd`c","@@PtMs","@@LnXlc","@@ppVu]Qn","@@cdzAU_","@@udRhnCE ","@@oIpP","@@M{ĿčwbxƨîKÎMĮ]ZF½Y]â£ph¶¨râøÀÎǨ¤^ºÄGz~grĚĜlĞÆLĆdž¢Îo¦cvKbgr°WhmZp L]LºcUÆnżĤÌĒbAnrOA´ȊcÀbƦUØrĆUÜøĬƞŶǬĴóò_Ä«ªdÎÉnb²ĦhņBĖįĦåXćì@L¯´ywƕCéõė ƿ¸lµZæyj|BíÂKNNnoƈfÈMZwnŐNàúÄsTJULîVjǎ¾ĒØDz²XPn±ŴPè¸ŔLƔÜƺ_TüÃĤBBċÈöA´faM¨{«M`¶d¡ôÖ°mȰBÔjj´PM|c^d¤u¤Û´ä«ƢfPk¶Môl]Lb}su^ke{lC MrDÇ]NÑFsmoõľHyGă{{çrnÓEƕZGª¹Fj¢ÿ©}ÌCǷë¡ąuhÛ¡^KxC`C\\bÅxì²ĝÝ¿_NīCȽĿåB¥¢·IŖÕy\\¹kxãČáKµË¤ÁçFQ¡KtŵƋ]CgÏAùSedcÚźuYfyMmhUWpSyGwMPqŀÁ¼zK¶GY§Ë@´śÇµƕBm@IogZ¯uTMx}CVKï{éƵP_K«pÛÙqċtkkù]gTğwoɁsMõ³ăAN£MRkmEÊčÛbMjÝGu IZGPģãħE[iµBEuDPÔ~ª¼ęt]ûG§¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~Ż¸YI] PumŝrƿIā[xedzL¯v¯s¬ÁY ~} ťuŁgƋpÝĄ_ņī¶ÏSR´ÁP~¿Cyċßdwk´SsX|t`Ä ÈðAªìÎT°¦Dda^lĎDĶÚY°`ĪŴǒàŠv\\ebZHŖR¬ŢƱùęOÑM³FÛaj"]],"encodeOffsets":[[[123806,39303],[123821,39266],[123742,39256],[123702,39203],[123649,39066],[123847,38933],[123580,38839],[123894,37288],[123043,36624],[123344,38676],[123522,38857],[123628,38858],[118267,36772]]]},"properties":{"cp":[117.000923,36.675807],"name":"山东","childNum":13}},{"id":"410000","geometry":{"type":"MultiPolygon","coordinates":[["@@dXD}~Hgq~ÔN~zkĘHVsDzßjŬŢ`Pûàl¢\\ÀEhİgÞē X¼`khÍLùµP³swIÓzeŠĠð´E®ÚPtºIŊʺL«šŕQGYfa[şußǑĩų_Z¯ĵÙčC]kbc¥CS¯ëÍB©ïÇÃ_{sWTt³xlàcČzÀD}ÂOQ³ÐTĬµƑпŸghłŦv~}ÂZ«¤lPÇ£ªÝŴÅR§ØnhctâknÏľŹUÓÝdKuķI§oTũÙďkęĆH¸Ó\\Ä¿PcnS{wBIvÉĽ[GqµuŇôYgûZca©@½Õǽys¯}lgg@C\\£asIdÍuCQñ[L±ęk·ţb¨©kK»KC²òGKmĨS`UQnk}AGēsqaJ¥ĐGRĎpCuÌy ã iMcplk|tRkðev~^´¦ÜSí¿_iyjI|ȑ|¿_»d}q^{Ƈdă}tqµ`ŷ飩V¡om½ZÙÏÁRD|JOÈpÀRsI{ùÓjuµ{t}uËRivGçJFjµåkWê´MÂHewixGw½Yŷpµú³XU½ġyłåkÚwZX·l¢Á¢KzOÎÎjc¼htoDHr |J½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ Ť]MÛfaQpě±ǽ¾]uFu÷nčįADp}AjmcEÇaª³o³ÆÍSƇĈÙDIzçñİ^KNiÞñ[aA²zzÌ÷D|[íijgfÕÞd®|`Ć~oĠƑô³ŊD×°¯Csø«ìUMhTº¨¸ǝêWÔDruÂÇZ£ĆPZW~ØØv¬gèÂÒw¦X¤Ā´oŬ¬²Ês~]®tªapŎJ¨Öº_ŔfŐ\\Đ\\Ĝu~m²Ƹ¸fWĦrƔ}Î^gjdfÔ¡J}\\n C¦þWxªJRÔŠu¬ĨĨmFdM{\\d\\YÊ¢ú@@¦ª²SÜsC}fNècbpRmlØ^gd¢aÒ¢CZZxvƶN¿¢T@uC¬^ĊðÄn|lIlXhun[","@@hzUq"]],"encodeOffsets":[[[116744,37216],[116480,33048]]]},"properties":{"cp":[113.665412,34.757975],"name":"河南","childNum":2}},{"id":"420000","geometry":{"type":"MultiPolygon","coordinates":[["@@ASd","@@ls{d","@@¾«}{ra®pîÃ\\{øCËyyB±b\\òÝjKL ]ĎĽÌJyÚCƈćÎT´Å´pb©ÈdFin~BCo°BĎÃømv®E^vǾ½Ĝ²RobÜeN^ĺ£R¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I¾®I{GqpCgyl{£ÍÍyPL¡¡¸kWxYlÙæŁĢz¾V´W¶ùŸo¾ZHxjwfxGNÁ³Xéæl¶EièIH ujÌQ~v|sv¶Ôi|ú¢FhQsğ¦SiŠBgÐE^ÁÐ{čnOÂÈUÎóĔÊēIJ}Z³½Mŧïeyp·uk³DsѨL¶_Åuèw»¡WqÜ]\\Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟOKÉġÿ×wg÷IÅzCg]m«ªGeçÃTC«[t§{loWeC@ps_Bprf_``Z|ei¡oċMqow¹DƝÓDYpûsYkıǃ}s¥ç³[§cY§HK«Qy]¢wwö¸ïx¼ņ¾Xv®ÇÀµRĠÐHM±cÏdƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy ¿³x¯No|¹HÏÛmjúË~TuęjCöAwě¬Rđl¯ ÑbŇTĿ_[IčĄʿnM¦ğ\\É[T·k¹©oĕ@A¾wya¥Y\\¥Âaz¯ãÁ¡k¥ne£ÛwE©Êō¶˓uoj_U¡cF¹[WvP©whuÕyBF`RqJUw\\i¡{jEPïÿ½fć QÑÀQ{°fLÔ~wXgītêݾĺHd³fJd]HJ² EoU¥HhwQsƐ»Xmg±çve]DmÍPoCc¾_hhøYrŊU¶eD°Č_N~øĹĚ·`z]Äþp¼ äÌQv\\rCé¾TnkžŐÚÜa¼ÝƆĢ¶Ûo d ĔňТJqPb ¾|J¾fXƐîĨ_Z¯À}úƲN_ĒÄ^ĈaŐyp»CÇÄKñL³ġM²wrIÒŭxjb[n«øæà ^²h¯ÚŐªÞ¸Y²ĒVø}Ā^İ´LÚm¥ÀJÞ{JVųÞŃx×sxxƈē ģMřÚðòIfĊŒ\\Ʈ±ŒdʧĘDvČ_Àæ~Dċ´A®µ¨ØLV¦êHÒ¤"]],"encodeOffsets":[[[113712,34000],[115612,30507],[113649,34054]]]},"properties":{"cp":[114.298572,30.584355],"name":"湖北","childNum":3}},{"id":"430000","geometry":{"type":"MultiPolygon","coordinates":[["@@nFZw","@@ãÆá½ÔXrCO ËRïÿĩTooQyÓ[ŅBE¬ÎÓXaį§Ã¸G °ITxpúxÚij¥ÏĢ¾edÄ©ĸG àGhM¤Â_U}Ċ}¢pczfþg¤ÇôAV","@@ȴÚĖÁĐiOĜ«BxDõĚivSÌ}iùÜnкG{p°M°yÂÒzJ²Ì ÂcXëöüiáÿñőФùTz²CȆȸǎŪƑÐc°dPÎğ˶[Ƚu¯½WM¡ÉB·rínZÒ `¨GA¾\\pēXhÃRCüWGġu Té§ŎÑ©êLM³}_EÇģc®ęisÁPDmÅ{b[RÅs·kPŽƥóRoOV~]{g\\êYƪ¦kÝbiċƵGZ»Ěõ ó·³vŝ£ø@pyö_ëIkѵbcѧy ×dYتiþUjŅ³C}ÁN»hĻħƏâƓKA·³CQ±µ§¿AUƑ¹AtćOwD]JUÖgk¯b£ylZFËѱH}EbóľA¡»Ku¦·³åş¥ùBD^{ÌC´¦ŷJ£^[ª¿ğ|ƅ N skóā¹¿ï]ă~÷O§@Vm¡Qđ¦¢Ĥ{ºjÔª¥nf´~Õo×ÛąGû¥cÑ[Z¶ŨĪ²SÊǔƐƀAÚŌ¦Qؼrŭ«}NÏürʬmjr@ĘrTW SsdHzƓ^ÇÂyUi¯DÅYlŹu{hT}mĉ¹¥ěDÿë©ıÓ[Oº£¥ótł¹MÕƪ`P DiÛU¾ÅâìUñBÈ£ýhedy¡oċ`pfmjP~kZa ZsÐd°wj§@Ĵ®w~^kÀÅKvNmX\\¨aŃqvíó¿F¤¡@ũÑVw}S@j}¾«pĂrªg àÀ²NJ¶¶Dô K|^ª°LX¾ŴäPĪ±£EXd^¶IJÞÜ~u¸ǔMRhsR e`ÄofIÔ\\Ø ićymnú¨cj ¢»GČìƊÿШXeĈĀ¾Oð Fi ¢|[jVxrIQ_EzAN¦zLU`cªxOTu RLĪpUĪȴ^ŎµªÉFx Üf¤ºgIJèy°Áb[¦Zb¦z½xBĖ@ªpºjS´rVźOd©ʪiĎăJP`"]],"encodeOffsets":[[[115640,30489],[112577,27316],[114113,30649]]]},"properties":{"cp":[112.982279,28.19409],"name":"湖南","childNum":3}},{"id":"440000","geometry":{"type":"MultiPolygon","coordinates":[["@@QdAsa","@@lxDRm","@@sbhNLo","@@Ă ý","@@WltOY[","@@Kr]S","@@e~AS}","@@I|Mym","@@Û³LS²Q","@@nvºBë¥cÕº","@@zdÛJm","@@°³","@@a yAª¸ËJIxØ@ĀHÉÕZofo o","@@sŗÃÔėAƁZÄ ~°ČPºb","@@¶ÝÌvmĞh¹Ĺ","@@HdSjĒ¢D}war u«ZqadY{K","@@el\\LqqO","@@~rMmX","@@f^E","@@øPªoj÷ÍÝħXČx°Q¨ıXJp","@@gÇƳmxatfu","@@EÆC½","@@¸B_¶ekWvSivc}p}Ăº¾NĎyj¦Èm th_®Ä}»âUzL˲Aā¡ßH©Ùñ}wkNÕ¹ÇO½¿£ēUlaUìIǪ`uTÅxYĒÖ¼kÖµMjJÚwn\\hĒv]îh|ÈƄøèg¸Ķß ĉĈWb¹ƀdéĘNTtP[öSvrCZaGubo´ŖÒÇĐ~¡zCI özx¢PnÈñ @ĥÒ¦]ƜX³ăĔñiiÄÓVépKG½ÄÓávYoC·sitiaÀyŧΡÈYDÑům}ý|m[węõĉZÅxUO}÷N¹³ĉo_qtăqwµŁYÙǝŕ¹tïÛUïmRCº ĭ|µÕÊK½Rē ó]GªęAxNqSF|ām¡diď×YïYWªʼnOeÚtĐ«zđ¹T āúEáÎÁWwíHcòßÎſ¿Çdğ·ùT×Çūʄ¡XgWÀLJğ·¿ÃOj YÇ÷Sğ³kzőõmĝ[³¡VÙæÅöM̳¹pÁaËýý©D©ÜJŹƕģGą¤{Ùū ÇO²«BƱéAÒĥ¡«BhlmtÃPµyU¯ucd·w_bŝcīímGOGBȅŹãĻFŷŽŕ@Óoo¿ē±ß}}ÓF÷tIJWÈCőâUâǙIğʼn©IijE× Á³AĥDĈ±ÌÜÓĨ£L]ĈÙƺZǾĆĖMĸĤfÎĵlŨnÈĐtFFĤêk¶^k°f¶g}®Faf`vXŲxl¦ÔÁ²¬Ð¦pqÊ̲iXØRDÎ}Ä@ZĠsx®AR~®ETtĄZƈfŠŠHâÒÐAµ\\S¸^wĖkRzalŜ|E¨ÈNĀňZTpBh£\\ĎƀuXĖtKL¶G|»ĺEļĞ~ÜĢÛĊrOÙîvd]n¬VÊĜ°RÖpMƀ¬HbwEÀ©\\ ¤]ŸI®¥D³|Ë]CúAŠ¦ æ´¥¸Lv¼¢ĽBaôF~®²GÌÒEYzk¤°ahlVÕI^CxĈPsBƒºVÀB¶¨R²´D","@@OR"]],"encodeOffsets":[[[117381,22988],[116552,22934],[116790,22617],[116973,22545],[116444,22536],[116931,22515],[116496,22490],[116453,22449],[113301,21439],[118726,21604],[118709,21486],[113210,20816],[115482,22082],[113171,21585],[113199,21590],[115232,22102],[115739,22373],[115134,22184],[113056,21175],[119573,21271],[119957,24020],[115859,22356],[116680,26053],[116561,22649]]]},"properties":{"cp":[113.280637,23.125178],"name":"广东","childNum":24}},{"id":"450000","geometry":{"type":"MultiPolygon","coordinates":[["@@H TI¡U","@@Ɣ_LÊFZg čPkini«qÇczÍY®¬Ů»qR×ō©DÕ§ƙǃŵTÉĩ±ıdÑnYYIJvNĆĆØÜ Öp}e³¦m©iÓ|¹ħņ|ª¦QF¢Â¬ʖovg¿em^ucäāmÇÖåB¡Õçĝ}FĻ¼Ĺ{µHKsLSđƃrč¤[AgoSŇYMÿ§Ç{FśbkylQxĕ]T·¶[B ÑÏGáşşƇe ăYSsFQ}BwtYğÃ@~ CÍQ ×Wj˱rÉ¥oÏ ±«ÓÂ¥kwWűue_bE~µh¯ecl¯Ïr¯EģJğ}w³Ƈē`ãògK_ÛsUʝćğ¶höO¤Ǜn³c`¡yię[ďĵűMę§]XÎ_íÛ]éÛUćİÕBƣ± dy¹T^dûÅÑŦ·PĻþÙ`K¦ ¢ÍeĥR¿³£[~äu¼dltW¸oRM¢ď\\z}Æzdvň{ÎXF¶°Â_ÒÂÏL©ÖTmu¼ãlīkiqéfA·Êµ\\őDc¥ÝFyÔćcűH_hLÜêĺШc}rn`½Ì@¸¶ªVLhŒ\\Ţĺk~Ġið°|gtTĭĸ^xvKVGréAébUuMJVÃO¡ qĂXËSģãlýà_juYÛÒBG^éÖ¶§EGÅzěƯ¤EkN[kdåucé¬dnYpAyČ{`]þ±X\\ÞÈk¡ĬjàhÂƄ¢Hè ŔâªLĒ^Öm¶ħĊAǦė¸zÚGn£¾rªŀÜt¬@ÖÚSx~øOŒŶÐÂæȠ\\ÈÜObĖw^oÞLf¬°bI lTØBÌF£Ć¹gñĤaYt¿¤VSñK¸¤nM¼JE±½¸ñoÜCƆæĪ^ĚQÖ¦^f´QüÜÊz¯lzUĺš@ìp¶n]sxtx¶@~ÒĂJb©gk{°~c°`Ô¬rV\\la¼¤ôá`¯¹LCÆbxEræOv[H[~|aB£ÖsºdAĐzNÂðsÞÆ Ĥªbab`ho¡³F«èVZs\\\\ÔRzpp®SĪº¨ÖºN ijd`a¦¤F³¢@`¢ĨĀìhYvlĆº¦Ċ~nS|gźv^kGÆÀè·"]],"encodeOffsets":[[[111707,21520],[113706,26955]]]},"properties":{"cp":[108.320004,22.82402],"name":"广西","childNum":2}},{"id":"460000","geometry":{"type":"Polygon","coordinates":["@@¦Ŝil¢XƦƞòïè§ŞCêɕrŧůÇąĻõ·ĉ³œ̅kÇm@ċȧŧĥĽʉƅſȓÒ˦ŝE}ºƑ[ÍĜȋ gÎfǐÏĤ¨êƺ\\Ɔ¸ĠĎvʄȀоjNðĀÒRZdžzÐĊ¢DÀɘZ"],"encodeOffsets":[[112750,20508]]},"properties":{"cp":[110.33119,20.031971],"name":"海南","childNum":1}},{"id":"510000","geometry":{"type":"MultiPolygon","coordinates":[["@@LqSn","@@ĆOìÛÐ@ĞǔNY{¤Á§d i´ezÝúØãwIþËQǦÃqÉSJ»ĂéʔõÔƁİlƞ¹§ĬqtÀƄmÀêErĒtD®ċæcQE®³^ĭ¥©l}äQtoŖÜqÆkµªÔĻĴ¡@Ċ°B²Èw^^RsºTĀ£ŚæQPJvÄz^Đ¹Æ¯fLà´GC²dtĀRt¼¤ĦOðğfÔðDŨŁĞƘïPÈ®âbMüÀXZ ¸£@Å»»QÉ]dsÖ×_Í_ÌêŮPrĔĐÕGĂeZÜîĘqBhtO ¤tE[h|YÔZśÎs´xº±Uñt|OĩĠºNbgþJy^dÂY Į]Řz¦gC³R`Āz¢Aj¸CL¤RÆ»@Ŏk\\Ç´£YW}z@Z}öoû¶]´^NÒ}èNªPÍy¹`S°´ATeVamdUĐwʄvĮÕ\\uÆŗ¨Yp¹àZÂmWh{á}WØǍÉüwga§ßAYrÅÂQĀÕ¬LŐý®Xøxª½Ű¦¦[þ`ÜUÖ´òrÙŠ°²ÄkijnDX{U~ET{ļº¦PZcjF²Ė@pg¨B{u¨ŦyhoÚD®¯¢ WòàFΤ¨GDäz¦kŮPġqË¥À]eâÚ´ªKxīPÖ|æ[xäJÞĥsNÖ½I¬nĨY´®ÐƐmDŝuäđđEb ee_v¡}ìęNJē}qÉåT¯µRs¡M@}ůaa¯wvƉåZw\\Z{åû`[±oiJDŦ]ĕãïrG réÏ·~ąSfy×Í·ºſƽĵȁŗūmHQ¡Y¡®ÁÃ×t«T¤JJJyJÈ`Ohߦ¡uËhIyCjmÿw ZG TiSsOB²fNmsPa{M{õE^Hj}gYpaeu¯oáwHjÁ½M¡pMuåmni{fk\\oÎqCwEZ¼KĝAy{m÷LwO×SimRI¯rKõBS«sFe]fµ¢óY_ÆPRcue°Cbo×bd£ŌIHgtrnyPt¦foaXďxlBowz_{ÊéWiêEGhܸºuFĈIxf®Y½ĀǙ]¤EyF²ċw¸¿@g¢§RGv»áW`ÃĵJwi]t¥wO½a[×]`ÃiüL¦LabbTÀåc}ÍhÆh®BHî|îºÉk¤Sy£ia©taį·Ɖ`ō¥UhO ĝLk}©Fos´JmµlŁu ønÑJWΪYÀïAetTŅÓGË«bo{ıwodƟ½OġܵxàNÖ¾P²§HKv¾]|BÆåoZ`¡Ø`ÀmºĠ~ÌЧnÇ ¿¤]wğ@srğu~Io[é±¹ ¿ſđÓ@qg¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@áťsZÏÅĭƋěpwDóÖáŻneQËq·GCœýS]x·ýq³OÕ¶Qzßti{řáÍÇWŝŭñzÇWpç¿JXĩè½cFÂLiVjx}\\NŇĖ¥GeJA¼ÄHfÈu~¸Æ«dE³ÉMA|bÒ ćhG¬CMõƤąAvüVéŀ_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»ÕZ³ġqDoy`L¬gdp°şp¦ėìÅĮZ°Iähzĵf²å ĚÑKpIN|Ñz]ń ·FU×é»R³MÉ»GM«kiér}Ã`¹ăÞmÈnÁîRǀ³ĜoİzŔwǶVÚ£À]ɜ»ĆlƂ²Ġ þTº·àUȞÏʦ¶I«dĽĢdĬ¿»Ĕ×h\\c¬ä²GêëĤł¥ÀǿżÃÆMº}BÕĢyFVvwxBèĻĒ©Ĉt@Ğû¸£B¯¨ˋäßkķ½ªôNÔ~t¼Ŵu^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ®Z´ğ~Sn|ªWÚ©òzPOȸbð¢|øĞA"]],"encodeOffsets":[[[108815,30935],[100197,35028]]]},"properties":{"cp":[104.065735,30.659462],"name":"四川","childNum":2}},{"id":"520000","geometry":{"type":"MultiPolygon","coordinates":[["@@G\\lY£cj","@@q|mc¯vÏV","@@hÑ£IsNgßHHªķÃh_¹¡ĝħń¦uÙùgS¯JH|sÝÅtÁïyMDč»eÕtA¤{b\\}G®u\\åPFqwÅaD K°ºâ_£ùbµmÁÛĹM[q|hlaªāI}ѵ@swtwm^oµD鼊yVky°ÉûÛR ³e¥]RÕěħ[ƅåÛDpJiVÂF²I »mN·£LbÒYbWsÀbpkiTZĄă¶Hq` ĥ_J¯ae«KpÝx]aĕÛPÇȟ[ÁåŵÏő÷Pw}TÙ@Õs«ĿÛq©½m¤ÙH·yǥĘĉBµĨÕnđ]K©œáG级ÕßgǗĦTèƤƺ{¶ÉHÎd¾ŚÊ·OÐjXWrãLyzÉAL¾ę¢bĶėy_qMĔąro¼hĊw¶øV¤w²Ĉ]ÊKx|`ź¦ÂÈdrcÈbe¸`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pĐ`oÒh¶pa^ÓĔ}D»^Xy`d[Kv JPhèhCrĂĚÂ^Êƌ wZLĠ£ÁbrzOIlMMĪŐžËr×ÎeŦtw|¢mKjSǘňĂStÎŦEtqFT¾E쬬ôxÌO¢ K³ŀºäYPVgŎ¦Ŋm޼VZwVlz¤ £Tl®ctĽÚó{GAÇge~Îd¿æaSba¥KKûj®_Ä^\\ؾbP®¦x^sxjĶI_Ä Xâ¼Hu¨Qh¡À@Ëô}±GNìĎlT¸ `V~R°tbÕĊ`¸úÛtÏFDu[MfqGH·¥yAztMFe|R_GkChZeÚ°tov`xbDnÐ{E}ZèxNEÞREn[Pv@{~rĆAB§EO¿|UZ~ìUf¨J²ĂÝÆsªB`s¶fvö¦Õ~dÔq¨¸º»uù[[§´sb¤¢zþF¢Æ ÀhÂW\\ıËIÝo±ĭŠ£þÊs}¡R]ěDg´VG¢j±®èºÃmpU[Á뺰rÜbNu¸}º¼`niºÔXĄ¤¼ÔdaµÁ_à ftQQgR·Ǔv}Ý×ĵ]µWc¤F²OĩųãW½¯K© ]{LóµCIµ±Mß¿h©āq¬o½~@i~TUxð´ĐhwÀEîôuĶb[§nWuMÆJl½]vuıµb"]],"encodeOffsets":[[[112158,27383],[112105,27474],[112095,27476]]]},"properties":{"cp":[106.713478,26.578343],"name":"贵州","childNum":3}},{"id":"530000","geometry":{"type":"Polygon","coordinates":["@@[ùx½}ÑRHYīĺûsÍniEoã½Ya²ė{c¬ĝgĂsAØÅwďõzFjw}«Dx¿}Uũlê@HÅF¨ÇoJ´Ónũuą¡Ã¢pÒÅØ TF²xa²ËXcÊlHîAßËŁkŻƑŷÉ©hWæßUËs¡¦}teèƶStÇÇ}Fd£jĈZĆƤTč\\D}O÷£U§~ŃGåŃDĝ¸Tsd¶¶Bª¤u¢ŌĎo~t¾ÍŶÒtD¦ÚiôözØX²ghįh½Û±¯ÿm·zR¦Ɵ`ªŊÃh¢rOÔ´£Ym¼èêf¯ŪĽncÚbw\\zlvWªâ ¦gmĿBĹ£¢ƹřbĥkǫßeeZkÙIKueT»sVesbaĕ ¶®dNĄÄpªy¼³BE®lGŭCǶwêżĔÂepÍÀQƞpC¼ŲÈAÎô¶RäQ^Øu¬°_Èôc´¹ò¨P΢hlϦ´ĦÆ´sâÇŲPnÊD^¯°Upv}®BP̪jǬxSöwlfòªvqĸ|`HviļndĜĆhňem·FyÞqóSį¯³X_ĞçêtryvL¤§z¦c¦¥jnŞklD¤øz½ĜàĂŧMÅ|áƆàÊcðÂFÜáŢ¥\\\\ºİøÒÐJĴîD¦zK²ǏÎEh~CDhMn^ÌöÄ©ČZÀaüfɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~ÄqêljN¬¼HÊNQ´ê¼VظE^ŃÒyM{JLoÒęæe±Ķygã¯JYÆĭĘëo¥Šo¯hcK«z_prC´ĢÖY¼ v¸¢RÅW³Â§fǸYi³xR´ďUË`êĿUûuĆBƣöNDH«ĈgÑaB{ÊNF´¬c·Åv}eÇÃGB»If¦HňĕM ~[iwjUÁKE¾dĪçWIèÀoÈXòyŞŮÈXâÎŚj|àsRyµÖPr´þ ¸^wþTDŔHr¸RÌmfżÕâCôoxĜƌÆĮÐYtâŦÔ@]ÈǮƒ\\Ī¼Ä£UsȯLbîƲŚºyhr@ĒÔƀÀ²º\\êpJ}ĠvqtĠ@^xÀ£È¨mËÏğ}n¹_¿¢×Y_æpÅA^{½Lu¨GO±Õ½ßM¶wÁĢÛPƢ¼pcIJx|ap̬HÐŊSfsðBZ¿©XÏÒKk÷Eû¿S rEFsÕūkóVǥʼniTL¡n{uxţÏhôŝ¬ğōNNJkyPaqÂğ¤K®YxÉƋÁ]āęDqçgOgILu\\_gz]W¼~CÔē]bµogpÑ_oď`´³Țkl`IªºÎȄqÔþ»E³ĎSJ»_f·adÇqÇc¥Á_Źw{L^ɱćxU£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣGË÷k°_^ý|_zċBZocmø¯hhcæ\\lMFlư£ĜÆyHF¨µêÕ]HA àÓ^it `þßäkĤÎT~Wlÿ¨ÔPzUCNVv [jâôDôď[}z¿msSh¯{jïğl}šĹ[őgK©U·µË@¾m_~q¡f¹ ÅË^»f³ø}Q¡Ö˳gͱ^Ç \\ëÃA_¿bWÏ[¶ƛé£F{īZgm@|kHǭƁć¦UĔť×ëǟ eċ¼ȡȘÏíBÉ£āĘPªij¶ʼnÿy©nď£G¹¡I±LÉĺÑdĉÜW¥}gÁ{aqÃ¥aıęÏZÁ`"],"encodeOffsets":[[104636,22969]]},"properties":{"cp":[102.712251,25.040609],"name":"云南","childNum":1}},{"id":"540000","geometry":{"type":"Polygon","coordinates":["@@ÂhľxŖxÒVºÅâAĪÝȆµę¯Ňa±r_w~uSÕňqOj]ɄQ £Z UDûoY»©M[L¼qãË{VÍçWVi]ë©Ä÷àyƛhÚU°adcQ~Mx¥caÛcSyFÖkuRýq¿ÔµQĽ³aG{¿FµëªéĜÿª@¬·K·àariĕĀ«V»ŶĴūgèLǴŇƶaftèBŚ£^âǐÝ®M¦ÁǞÿ¬LhJ¾óƾƺcxwf]Y ´¦|QLn°adĊ \\¨oǀÍŎ´ĩĀd`tÊQŞŕ|¨C^©Ĉ¦¦ÎJĊ{ëĎjª²rÐl`¼Ą[t|¦Stè¾PÜK¸dƄı]s¤î_v¹ÎVòŦj£Əsc¬_Ğ´|Ł¦Av¦w`ăaÝaa¢e¤ı²©ªSªÈMĄwÉØŔì@T¤Ę\\õª@þo´xA sÂtŎKzó²Çȵ¢r^nĊƬ×üG¢³ {âĊ]G~bÀgVjzlhǶfOfdªB]pjTOtĊn¤}®¦Č¥d¢¼»ddY¼t¢eȤJ¤}Ǿ¡°§¤AÐlc@ĝsªćļđAçwxUuzEÖġ~AN¹ÄÅȀŻ¦¿ģŁéì±H ãd«g[ؼēÀcīľġ¬cJµ ÐʥVȝ¸ßS¹ý±ğkƁ¼ą^ɛ¤Ûÿb[}¬ōõÃ]ËNm®g@Bg}ÍF±ǐyL¥íCIijÏ÷Ñį[¹¦[âšEÛïÁÉdƅß{âNÆāŨß¾ě÷yC£k´ÓH@¹TZ¥¢į·ÌAЧ®Zc v½Z¹|ÅWZqgW|ieZÅYVÓqdqbc²R@c¥Rã»GeeƃīQ}J[ÒK ¬Ə|oėjġĠÑN¡ð¯EBčnwôɍėª²CλŹġǝʅįĭạ̃ūȹ]ΓͧgšsgȽóϧµǛęgſ¶ҍć`ĘąŌJÞä¤rÅň¥ÖÁUětęuůÞiĊÄÀ\\Æs¦ÓRb|Â^řÌkÄŷ¶½÷f±iMÝ@ĥ°G¬ÃM¥n£Øąğ¯ß§aëbéüÑOčk£{\\eµª×MÉfm«Ƒ{Å×Gŏǩãy³©WÑăû··Qòı}¯ãIéÕÂZ¨īès¶ZÈsæĔTŘvgÌsN@îá¾ó@ÙwU±ÉT廣TđWxq¹Zobs[ׯcĩvėŧ³BM|¹kªħ¥TzNYnÝßpęrñĠĉRS~½ěVVµõ«M££µBĉ¥áºae~³AuĐh`ܳç@BÛïĿa©|z²Ý¼D£àč²ŸIûI āóK¥}rÝ_Á´éMaň¨~ªSĈ½½KÙóĿeƃÆB·¬ën×W|Uº}LJrƳlŒµ`bÔ`QÐÓ@s¬ñIÍ@ûws¡åQÑßÁ`ŋĴ{ĪTÚÅTSijYo|Ç[ǾµMW¢ĭiÕØ¿@Mh pÕ]jéò¿OƇĆƇpêĉâlØwěsǩĵ¸c bU¹ř¨WavquSMzeo_^gsÏ·¥Ó@~¯¿RiīB\\qTGªÇĜçPoÿfñòą¦óQīÈáPābß{ZŗĸIæÅhnszÁCËìñÏ·ąĚÝUm®óL·ăUÈíoù´Êj°ŁŤ_uµ^°ìÇ@tĶĒ¡ÆM³Ģ«İĨÅ®ğRāðggheÆ¢zÊ©Ô\\°ÝĎz~ź¤PnMĪÖB£kn駿ćĆKĒ°¼L¶èâz¨u¦¥LDĘz¬ýÎmĘd¾ßFzhg²Fy¦ĝ¤ċņbÎ@yĄæm°NĮZRÖíJ²öLĸÒ¨Y®ƌÐVàtt_ÚÂyĠz]ŢhzĎ{ÂĢXc|ÐqfO¢¤ögÌHNPKŖUú´xx[xvĐCûĀìÖT¬¸^}Ìsòd´_KgžLĴ ÀBon|H@Êx¦BpŰŌ¿fµƌA¾zLjRx¶FkĄźRzŀ~¶[´HnªVƞuĒȨƎcƽÌm¸ÁÈM¦x͊ëÀxdžBú^´W£dkɾĬpw˂ØɦļĬIŚÊnŔa¸~J°îlɌxĤÊÈðhÌ®gT´øàCÀ^ªerrƘd¢İP|Ė ŸWªĦ^¶´ÂLaT±üWƜǀRÂŶUńĖ[QhlLüAÜ\\qRĄ©"],"encodeOffsets":[[90849,37210]]},"properties":{"cp":[91.132212,29.660361],"name":"西藏","childNum":1}},{"id":"610000","geometry":{"type":"Polygon","coordinates":["@@¸ÂW¢xRFq§uF@N¢XLRMº[ğȣſï|¥Jkc`sʼnǷ£Y³WN«ùMëï³ÛIg÷±mTșÚÒķø©þ¥yÓğęmWµÎumZyOŅƟĥÓ~sÑL¤µaÅ Y¦ocyZ{y c]{Ta©`U_Ěē£ωÊƍKùK¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑdìUYOuFÕÈYvÁCqÓTǢí§·S¹NgV¬ë÷Át°DدC´ʼnƒópģ}ąiEË FéGU¥×K §¶³BČ}C¿åċ`wġB·¤őcƭ²ő[Å^axwQO ñJÙïŚĤNĔwƇÄńwĪo[_KÓª³ÙnKÇěÿ]ďă_d©·©Ýŏ°Ù®g]±ß×¥¬÷m\\iaǑkěX{¢|ZKlçhLtŇîŵœè[É@ƉĄEtƇϳħZ«mJ ×¾MtÝĦ£IwÄå\\Õ{OwĬ©LÙ³ÙTª¿^¦rÌĢŭO¥lãyC§HÍ£ßEñX¡°ÙCgpťzb`wIvA|¥hoĕ@E±iYd¥OÿµÇvPW|mCĴŜǂÒW¶¸AĜh^Wx{@¬F¸¡ķn£P|ªĴ@^ĠĈæbÔc¶lYi ^MicĎ°Â[ävï¶gv@ÀĬ·lJ¸sn|¼u~a]ÆÈtŌºJpþ£KKf~¦UbyäIĺãnÔ¿^ŵMThĠܤko¼Ŏìąǜh`[tRd²IJ_XPrɲlXiL§à¹H°Ȧqº®QCbAŌJ¸ĕÚ³ĺ§ `d¨YjiZvRĺ±öVKkjGȊÄePĞZmļKÀ[`ösìhïÎoĬdtKÞ{¬èÒÒBÔpIJÇĬJŊ¦±J«[©ārHµàåVKe§|P²ÇÓ·vUzgnN¾yI@oHĆÛķhxen¡QQ±ƝJǖRbzy¸ËÐl¼EºpĤ¼x¼½~Ğà@ÚüdK^mÌSjp²ȮµûGĦ}Ħðǚ¶òƄjɂz°{ºØkÈęâ¦jªBg\\ċ°s¬]jú EȌdž¬stRÆdĠİwܸôW¾ƮłÒ_{Ìû¼jº¹¢GǪÒ¯ĘZ`ºŊecņą~BÂgzpâēòYƲȐĎ"],"encodeOffsets":[[113634,40474]]},"properties":{"cp":[108.948024,34.263161],"name":"陕西","childNum":1}},{"id":"620000","geometry":{"type":"MultiPolygon","coordinates":[["@@Vu_^","@@ųEĠtt~nkh`Q¦ÅÄÜdwAb×ĠąJ¤DüègĺqBqj°lI¡Ĩ¶ĖIHdjÎB°aZ¢KJO[|A£Dx}NìHUnrk kp¼Y kMJn[aGáÚÏ[½rc}aQxOgsPMnUsncZ sKúvAtÞġ£®ĀYKdnFw¢JE°Latf`¼h¬we|Æbj}GA·~W`¢MC¤tL©IJ°qdfObÞĬ¹ttu`^ZúE`[@Æsîz®¡CƳƜG²R¢RmfwĸgÜą G@pzJM½mhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬²I¥IʼnÈīoıÓÑAçÑ|«LÝcspīðÍg të_õ\\ĉñLYnĝgRǡÁiHLlõUĹ²uQjYi§Z_c¨´ĹĖÙ·ŋI aBDR¹ȥr¯GºßK¨jWkɱOqWij\\aQ\\sg_ĆǛōëp»£lğÛgSŶN®À]ÓämĹãJaz¥V}Le¤Lýo¹IsŋÅÇ^bz ³tmEÁ´a¹cčecÇNĊãÁ\\č¯dNj]jZµkÓdaćå]ğij@ ©O{¤ĸm¢E·®«|@Xwg]Aģ±¯XǁÑdzªcwQÚŝñsÕ³ÛV_ý¥\\ů¥©¾÷w©WÕÊĩhÿÖÁRo¸V¬âDb¨hûxÊ×nj~Zâg|XÁnßYoº§ZÅŘv[ĭÖʃuďxcVbnUSf B¯³_TzºÎO©çMÑ~M³]µ^püµÄY~y@X~¤Z³[Èōl@®Å¼£QK·Di¡ByÿQ_´D¥hŗy^ĭÁZ]cIzýah¹MĪğPs{ò²Vw¹t³ŜË[Ñ}X\\gsF£sPAgěp×ëfYHāďÖqēŭOÏëdLü\\it^c®Rʺ¶¢H°mrY£B¹čIoľu¶uI]vģSQ{UŻÅ}QÂ|Ì°ƅ¤ĩŪU ęĄÌZÒ\\v²PĔ»ƢNHĂyAmƂwVm`]ÈbH`Ì¢²ILvĜH®¤Dlt_¢JJÄämèÔDëþgºƫaʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b ð÷®üszMzÖĖQdȨýv§Tè|ªHþa¸|Ð ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v·À|\\ƁĚN´ĜçèÁz]ġ¤²¨QÒŨTIlªťØ}¼˗ƦvÄùØE«FïËIqōTvāÜŏíÛßÛVj³âwGăÂíNOPìyV³ʼnĖýZso§HÑiYw[ß\\X¦¥c]ÔƩÜ·«jÐqvÁ¦m^ċ±R¦ƈťĚgÀ»IïĨʗƮ°ƝĻþÍAƉſ±tÍEÕÞāNUÍ¡\\ſčåÒʻĘm ƭÌŹöʥëQ¤µÇcƕªoIýIÉ_mkl³ăƓ¦j¡YzŇi}Msßõīʋ }ÁVm_[n}eıUĥ¼ªI{ΧDÓƻėojqYhĹT©oūĶ£]ďxĩǑMĝq`B´ƃ˺Чç~²ņj@¥@đ´ί}ĥtPńǾV¬ufÓÉCtÓ̻ ¹£G³]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼĤŊɲĖÂKqĘʼn¼ĔDzņɾªǀÞĈĂD½ĄĎÌŗĞrôñnN¼â¾ʄľԆ|DŽ֦ज़ȗlj̘̭ɺƅêgV̍ʆĠ·ÌĊv|ýĖÕWĊǎÞ´õ¼cÒÒBĢ͢UĜð͒s¨ňƃLĉÕÝ@ɛƯ÷¿ĽĹeȏijëCȚDŲyê×Ŗyò¯ļcÂßY tÁƤyAã˾J@ǝrý@¤ rz¸oP¹ɐÚyáHĀ[Jw cVeȴÏ»ÈĖ}ƒŰŐèȭǢόĀƪÈŶë;Ñ̆ȤМľĮEŔĹŊũ~ËUă{ĻƹɁύȩþĽvĽƓÉ@ēĽɲßǐƫʾǗĒpäWÐxnsÀ^ƆwW©¦cÅ¡Ji§vúF¶¨c~c¼īeXǚ\\đ¾JwÀďksãAfÕ¦L}waoZD½Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LFLzĈôe]gx}|KK}xklL]c¦£fRtív¦PŨ£","@@M T¥"]],"encodeOffsets":[[[108619,36299],[108594,36341],[108600,36306]]]},"properties":{"cp":[103.823557,36.058039],"name":"甘肃","childNum":3}},{"id":"630000","geometry":{"type":"MultiPolygon","coordinates":[["@@InJo","@@CƽOŃĦsΰ~Ē³¦@@Ņi±è}ШƄ˹A³r_ĞǒNĪĐw¤^ŬĵªpĺSZgrpiƼĘÔ¨C|ÍJ©Ħ»®VIJ~f\\m `UnÂ~ʌĬàöNt~ňjy¢ZiƔ¥Ąk´nl`JÊJþ©pdƖ®È£¶ìRʦźõƮËnʼėæÑƀĎ[¢VÎĂMÖÝÎF²sƊƀÎBļýƞ¯ʘƭðħ¼Jh¿ŦęΌƇ¥²Q]Č¥nuÂÏri¸¬ƪÛ^Ó¦d¥[Wà x\\ZjÒ¨GtpþYŊĕ´zUOëPîMĄÁxH´áiÜUàîÜŐĂÛSuŎrJð̬EFÁú×uÃÎkrĒ{V}İ«O_ÌËĬ©ÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u ºµ[gt£¸OƤĿéYõ·kĀq]juw¥DĩƍõÇPéĽG©ã¤G uȧþRcÕĕNyyûtøï»a½ē¿BMoį£Íj}éZËqbʍƬh¹ìÿÓAçãnIáI`ks£CGěUy×Cy @¶ʡÊBnāzGơMē¼±O÷õJËĚăVĪũƆ£¯{ËL½ÌzżVR|ĠTbuvJvµhĻĖHAëáa OÇðñęNw œľ·LmI±íĠĩPÉ×®ÿscB³±JKßĊ«` ađ»·QAmOVţéÿ¤¹SQt]]Çx±¯A@ĉij¢Óļ©l¶ÅÛrŕspãRk~¦ª]Į´FRådČsCqđéFn¿ÅƃmÉx{W©ºƝºįkÕƂƑ¸wWūЩÈF£\\tÈ¥ÄRÈýÌJ lGr^×äùyÞ³fjc¨£ÂZ|ǓMĝÏ@ëÜőRĝ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³ÞIňµç½©C¡į÷¯B»|St»]vųs»}MÓ ÿʪƟǭA¡fs»PY¼c¡»¦cċ¥£~msĉPSi^o©AecPeǵkgyUi¿h}aHĉ^|á´¡HØûÅ«ĉ®]m¡qċ¶±ÈyôōLÁstB®wn±ă¥HSòė£Së@לÊăxÇN©©T±ª£IJ¡fb®Þbb_Ą¥xu¥B{łĝ³«`dƐt¤ťiñÍUuºí`£^tƃIJc·ÛLO½sç¥Ts{ă\\_»kϱq©čiìĉ|ÍI¥ć¥]ª§D{ŝŖÉR_sÿc³ĪōƿΧp[ĉc¯bKmR¥{³Ze^wx¹dƽŽôIg §Mĕ ƹĴ¿ǣÜÍ]Ý]snåA{eƭ`ǻŊĿ\\ijŬűYÂÿ¬jĖqßb¸L«¸©@ěĀ©ê¶ìÀEH|´bRľÓ¶rÀQþvl®ÕETzÜdb hw¤{LRdcb¯ÙVgƜßzÃôì®^jUèXÎ|UäÌ»rK\\ªN¼pZCüVY¤ɃRi^rPŇTÖ}|br°qňbĚ°ªiƶGQ¾²x¦PmlŜ[Ĥ¡ΞsĦÔÏâ\\ªÚŒU\\f ¢N²§x|¤§xĔsZPòʛ²SÐqF`ªVÞŜĶƨVZÌL`¢dŐIqr\\oäõF礻Ŷ×h¹]ClÙ\\¦ďÌį¬řtTӺƙgQÇÓHţĒ´ÃbEÄlbʔC|CŮkƮ[ʼ¬ň´KŮÈΰÌĪ¶ƶlðļATUvdTGº̼ÔsÊDÔveMg"]],"encodeOffsets":[[[105308,37219],[95370,40081]]]},"properties":{"cp":[101.778916,36.623178],"name":"青海","childNum":2}},{"id":"640000","geometry":{"type":"Polygon","coordinates":["@@KëÀęĞ«Oęȿȕı]ʼn¡åįÕÔ«ǴõƪĚQÐZhv K°öqÀÑS[ÃÖHƖčËnL]ûc Ùß@ĝ¾}w»»oģF¹»kÌÏ·{zP§B¢íyÅt@@á]Yv_ssģ¼ißĻL¾ġsKD£¡N_ X¸}B~HaiÅf{«x»ge_bsKF¯¡IxmELcÿZ¤ĢÝsuBLùtYdmVtNmtOPhRw~bd ¾qÐ\\âÙH\\bImlNZ»loqlVmGā§~QCw¤{A\\PKNY¯bFkC¥sks_Ã\\ă«¢ħkJi¯rrAhĹûç£CUĕĊ_ÔBixÅÙĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~hw^ófćKyEKzuÔ¡qQ¤xZÑ¢^ļöܾEp±âbÊÑÆ^fk¬ NC¾YpxbK~¥eÖäBlt¿Đx½I[ĒǙWf»Ĭ}d§dµùEuj¨IÆ¢¥dXªƅx¿]mtÏwßRĶX¢͎vÆzƂZò®ǢÌʆCrâºMÞzÆMÒÊÓŊZľr°Î®Ȉmª²ĈUªĚîøºĮ¦ÌĘk^FłĬhĚiĀĖ¾iİbjË"],"encodeOffsets":[[109366,40242]]},"properties":{"cp":[106.278179,38.46637],"name":"宁夏","childNum":1}},{"id":"650000","geometry":{"type":"Polygon","coordinates":["@@QØĔ²X¨~ǘBºjʐßØvKƔX¨vĊO÷¢i@~cĝe_«E}QxgɪëÏÃ@sÅyXoŖ{ô«ŸuX êÎf`C¹ÂÿÐGĮÕĞXŪōŸMźÈƺQèĽôe|¿ƸJR¤ĘEjcUóº¯Ĩ_ŘÁMª÷Ð¥OéÈ¿ÖğǤǷÂFÒzÉx[]Ĥĝœ¦EP}ûƥé¿İƷTėƫœŕƅƱB»Đ±ēO ¦E}`cȺrĦáŖuÒª«IJπdƺÏØZƴwʄ¤ĖGĐǂZĶèH¶}ÚZצʥĪï|ÇĦMŔ»İĝLjì¥Βba¯¥ǕǚkĆŵĦɑĺƯxūД̵nơʃĽá½M»òmqóŘĝč˾ăC ćāƿÝɽ©DZŅ»ēėŊLrÁ®ɱĕģʼnǻ̋ȥơŻǛȡVï¹Ň۩ûkɗġƁ§ʇė̕ĩũƽō^ƕUv£ƁQïƵkŏ½ΉÃŭdzLŇʻ«ƭ\\lŭD{ʓDkaFÃÄa³ŤđÔGRÈƚhSӹŚsİ«ĐË[¥ÚDkº^Øg¼ŵ¸£EÍöůʼnT¡c_ËKYƧUśĵÝU_©rETÏʜ±OñtYwē¨{£¨uM³x½şL©Ùá[ÓÐĥ Νtģ¢\\śnkOw¥±T»ƷFɯàĩÞáB¹Æ ÑUwŕĽw]kE½Èå~Æ÷QyěCFmĭZīŵVÁƿQƛûXS²b½KϽĉS©ŷXĕ{ĕK·¥Ɨcqq©f¿]ßDõU³hgËÇïģÉɋwk¯í}I·œbmÉřīJɥĻˁ×xoɹīlc ¤³Xù]DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®ƝvUm©³G\\}µĿQyŹlăµEwLJQ½yƋBe¶ŋÀůo¥AÉw@{Gpm¿AijŽKLh³`ñcËtW±»ÕSëüÿďDu\\wwwù³VLŕOMËGh£õP¡erÏd{ġWÁ č|yšg^ğyÁzÙs`s|ÉåªÇ}m¢Ń¨`x¥ù^}Ì¥H«YªƅAйn~ź¯f¤áÀzgÇDIÔ´AňĀÒ¶ûEYospõD[{ù°]uJqU|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw ÞkrťË¿XGÉbřaDü·Ē÷Aê[ÄäI®BÕĐÞ_¢āĠpÛÄȉĖġDKwbmÄNôfƫVÉvidzHQµâFùÂœ³¦{YGd¢ĚÜO {Ö¦ÞÍÀP^bƾl[vt×ĈÍE˨¡Đ~´î¸ùÎhuè`¸HÕŔVºwĠââWò@{ÙNÝ´ə²ȕn{¿¥{l÷eé^eďXj©î\\ªÑòÜìc\\üqÕ[Č¡xoÂċªbØø|¶ȴZdÆÂońéG\\¼C°ÌÆn´nxÊOĨŪƴĸ¢¸òTxÊǪMīĞÖŲÃɎOvʦƢ~FRěò¿ġ~åŊúN¸qĘ[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾ĄYÒ©ÊfºmÔĘcDoĬMŬS¤s²ʘÚžȂVŦ èW°ªB|IJXŔþÈJĦÆæFĚêYĂªĂ]øªŖNÞüAfɨJ¯ÎrDDĤ`mz\\§~D¬{vJ«lµĂb¤pŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMTòP÷fØĶK¢ȝ˔Sô¹òEð`Ɩ½ǒÂň×äı§ĤƝ§C~¡hlåǺŦŞkâ~}FøàIJaĞfƠ¥Ŕd®U¸źXv¢aƆúŪtŠųƠjdƺƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹\\ĜÑŚ¶ZƄ³âjĦoâȴLÊȮĐĚăÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTiƢ¾ªì°`öøu®Ê¾ãÖ"],"encodeOffsets":[[88824,50096]]},"properties":{"cp":[87.617733,43.792818],"name":"新疆","childNum":1}},{"id":"110000","geometry":{"type":"Polygon","coordinates":["@@RºaYÕQaúÍÔiþĩȨWĢü|Ėu[qb[swP@ÅğP¿{\\¯Y²·Ñ¨j¯X\\¯MSvU¯YIŕY{[fkVÁûtŷmiÍt_H»Ĩ±d`¹{bw Yr³S]§§o¹qGtm_SŧoaFLgQN_dV@Zom_ć\\ßW´ÕiœRcfi o§ËgToÛJíĔóu |wP¤XnO¢ÉŦ¯pNÄā¤zâŖÈRpŢZÚ{GrFt¦Òx§ø¹RóäV¤XdżâºWbwŚ¨Ud®bêņ¾jnŎGŃŶnzÚScîĚZen¬"],"encodeOffsets":[[119421,42013]]},"properties":{"cp":[116.405285,39.904989],"name":"北京","childNum":1}},{"id":"120000","geometry":{"type":"Polygon","coordinates":["@@ŬgX§Ü«E ¶F̬O_ïlÁgz±AXeµÄĵ{¶]gitgIj·¥ì_iU¨ÐƎk}ĕ{gBqGf{¿aU^fIư³õ{YıëNĿk©ïËZukāAīlĕĥs¡bġ«@dekąI[nlPqCnp{ō³°`{PNdƗqSÄĻNNâyj]äÒD ĬH°Æ]~¡HO¾X}ÐxgpgWrDGpù^LrzWxZ^¨´T\\|~@IzbĤjeĊªz£®ĔvěLmV¾Ô_ÈNW~zbĬvG²ZmDM~~"],"encodeOffsets":[[120237,41215]]},"properties":{"cp":[117.190182,39.125596],"name":"天津","childNum":1}},{"id":"310000","geometry":{"type":"MultiPolygon","coordinates":[["@@ɧư¬EpƸÁx]","@@©²","@@MA","@@QpªKWT §¨","@@bŝÕÕEȣÚƥêImɇǦèÜĠÚÄÓŴ·ʌÇ","@@Sô¤r]ìƬįǜûȬɋŭ×^sYɍDŋŽąñCG²«ªč@h_p¯A{oloY¬j@IJ`gQÚpptǀ^MIJvtbe´Rh@oj¨","@@ÆLH{a}Eo¦"]],"encodeOffsets":[[[124702,32062],[124547,32200],[124808,31991],[124726,32110],[124903,32376],[124065,32166],[124870,31965]]]},"properties":{"cp":[121.472644,31.231706],"name":"上海","childNum":7}},{"id":"500000","geometry":{"type":"Polygon","coordinates":["@@TÂÛ`Ùƅően½SêqDu[Rå͹÷eXÍy¸_ĺę}÷`M¯ċfCVµqʼn÷Zgg^d½pDOÎCn^uf²ènh¼WtƏxRGg¦ pVFI±G^Ic´ecGĹÞ½sëÆNä̤KÓe¯|R¸§LÜkPoïƭNï¶}Gywdiù©nkĈzj@Óc£»Wă¹Óf§c[µo·Ó|MvÛaq½«è\\ÂoVnÓØͲ«bq¿ehCĜ^Q~ Évýş¤²ĮpEĶyhsŊwH½¿gÅ¡ýE¡ya£³t\\¨\\vú¹¼©·Ñr_oÒý¥et³]Et©uÖ¥±ă©KVeë]}wVPÀFA¨ąB}qTjgRemfFmQFÝ MyùnÑAmÑCawu_p¯sfÛ_gI_pNysB¦zG¸rHeN\\CvEsÐñÚkcDÖĉsaQ¯}_UzÁē}^R Äd^ÍĸZ¾·¶`wećJE¹vÛ·HgéFXjÉê`|ypxkAwWĐpb¥eOsmzwqChóUQl¥F^lafanòsrEvfQdÁUVfÎvÜ^eftET¬ôA\\¢sJnQTjPØxøK|nBzĞ»LY FDxÓvr[ehľvN¢o¾NiÂxGpâ¬zbfZo~hGi]öF||NbtOMn eA±tPTLjpYQ|SHYĀxinzDJÌg¢và¥Pg_ÇzIIII£®S¬Øs쥨^LnGIJļIJƤjÎƀƾ¹¸ØÎezĆT¸}êÐqHðqĖä¥^CÆIj²p \\_ æüY|[YxƊæu°xb® Űb@~¢NQt°¶Sæ Ê~rljĔëĚ¢~uf`faĔJåĊnÔ]jƎćÊ@£¾a®£Ű{ŶĕFègLk{Y|¡ĜWƔtƬJÑxq±ĢN´òKLÈüD|s`ŋć]Ã`đMùƱ¿~Y°ħ`ƏíW½eI½{aOIrÏ¡ĕŇapµÜƃġ²"],"encodeOffsets":[[111728,31311]]},"properties":{"cp":[106.504962,29.533155],"name":"重庆","childNum":1}},{"id":"810000","geometry":{"type":"MultiPolygon","coordinates":[["@@AlFi","@@mp","@@EpHo","@@rMUwAS¬]","@@ea¢pl¸Eõ¹hj[]ÔCÎ@lj¡uBX ´AI¹ [yDU]W`çwZkmc MpÅv}IoJlcafŃK°ä¬XJmÐ đhI®æÔtSHnEÒrÄc"]],"encodeOffsets":[[[117111,23002],[117072,22876],[117045,22887],[116882,22747],[116975,23082]]]},"properties":{"cp":[114.173355,22.320048],"name":"香港","childNum":5}},{"id":"820000","geometry":{"type":"Polygon","coordinates":["@@áw{Îr"],"encodeOffsets":[[116285,22746]]},"properties":{"cp":[113.54909,22.198951],"name":"澳门","childNum":1}}],"UTF8Encoding":true} + +export default chinaMap; \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..9d57118c --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,14 @@ +export const setProperty = (prop: string, val: any, dom = document.documentElement) => { + dom.style.setProperty(prop, val); +}; + +export const mix = (color1: string, color2: string, weight: number = 0.5): string => { + let color = '#'; + for (let i = 0; i <= 2; i++) { + const c1 = parseInt(color1.substring(1 + i * 2, 3 + i * 2), 16); + const c2 = parseInt(color2.substring(1 + i * 2, 3 + i * 2), 16); + const c = Math.round(c1 * weight + c2 * (1 - weight)); + color += c.toString(16).padStart(2, '0'); + } + return color; +}; diff --git a/src/utils/request.ts b/src/utils/request.ts index 2aaaf771..3453061a 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -1,31 +1,31 @@ -import axios, { AxiosInstance, AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; - -const service: AxiosInstance = axios.create({ - timeout: 5000 -}); - -service.interceptors.request.use( - (config: InternalAxiosRequestConfig) => { - return config; - }, - (error: AxiosError) => { - console.log(error); - return Promise.reject(); - } -); - -service.interceptors.response.use( - (response: AxiosResponse) => { - if (response.status === 200) { - return response; - } else { - Promise.reject(); - } - }, - (error: AxiosError) => { - console.log(error); - return Promise.reject(); - } -); - -export default service; +import axios, { AxiosInstance, AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; + +const service: AxiosInstance = axios.create({ + timeout: 5000 +}); + +service.interceptors.request.use( + (config: InternalAxiosRequestConfig) => { + return config; + }, + (error: AxiosError) => { + console.log(error); + return Promise.reject(); + } +); + +service.interceptors.response.use( + (response: AxiosResponse) => { + if (response.status === 200) { + return response; + } else { + Promise.reject(); + } + }, + (error: AxiosError) => { + console.log(error); + return Promise.reject(); + } +); + +export default service; diff --git a/src/views/403.vue b/src/views/403.vue deleted file mode 100644 index c7132708..00000000 --- a/src/views/403.vue +++ /dev/null @@ -1,54 +0,0 @@ -<template> - <div class="error-page"> - <div class="error-code">4<span>0</span>3</div> - <div class="error-desc">啊哦~ 你没有权限访问该页面哦</div> - <div class="error-handle"> - <router-link to="/"> - <el-button type="primary" size="large">返回首页</el-button> - </router-link> - <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> - </div> - </div> -</template> - -<script setup lang="ts" name="403"> -import { useRouter } from 'vue-router'; - -const router = useRouter(); -const goBack = () => { - router.go(-2); -}; -</script> - -<style scoped> -.error-page { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - width: 100%; - height: 100%; - background: #f3f3f3; - box-sizing: border-box; -} -.error-code { - line-height: 1; - font-size: 250px; - font-weight: bolder; - color: #f02d2d; -} -.error-code span { - color: #00a854; -} -.error-desc { - font-size: 30px; - color: #777; -} -.error-handle { - margin-top: 30px; - padding-bottom: 200px; -} -.error-btn { - margin-left: 100px; -} -</style> diff --git a/src/views/404.vue b/src/views/404.vue deleted file mode 100644 index a4dfcf20..00000000 --- a/src/views/404.vue +++ /dev/null @@ -1,54 +0,0 @@ -<template> - <div class="error-page"> - <div class="error-code">4<span>0</span>4</div> - <div class="error-desc">啊哦~ 你所访问的页面不存在</div> - <div class="error-handle"> - <router-link to="/"> - <el-button type="primary" size="large">返回首页</el-button> - </router-link> - <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> - </div> - </div> -</template> - -<script setup lang="ts" name="404"> -import { useRouter } from 'vue-router'; - -const router = useRouter(); -const goBack = () => { - router.go(-1); -}; -</script> - -<style scoped> -.error-page { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - width: 100%; - height: 100%; - background: #f3f3f3; - box-sizing: border-box; -} -.error-code { - line-height: 1; - font-size: 250px; - font-weight: bolder; - color: #2d8cf0; -} -.error-code span { - color: #00a854; -} -.error-desc { - font-size: 30px; - color: #777; -} -.error-handle { - margin-top: 30px; - padding-bottom: 200px; -} -.error-btn { - margin-left: 100px; -} -</style> diff --git a/src/views/chart/echarts.vue b/src/views/chart/echarts.vue new file mode 100644 index 00000000..9b9ef0d9 --- /dev/null +++ b/src/views/chart/echarts.vue @@ -0,0 +1,87 @@ +<template> + <div class="container"> + <div class="plugins-tips"> + vue-echarts:Apache ECharts™ 的 Vue.js 组件。 访问地址: + <a href="https://github.com/ecomfe/vue-echarts" target="_blank">vue-echarts</a> + </div> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">柱状图</div> + </template> + <v-chart class="schart" :option="barOptions" /> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">折线图</div> + </template> + <v-chart class="schart" :option="lineOptions" /> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">饼状图</div> + </template> + <v-chart class="schart" :option="pieOptions" /> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">环形图</div> + </template> + <v-chart class="schart" :option="ringOptions" /> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">词云图</div> + </template> + <v-chart class="schart" :option="wordOptions" /> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">地图</div> + </template> + <v-chart class="schart" :option="mapOptions" /> + </el-card> + </div> +</template> + +<script setup lang="ts" name="echarts"> +import { registerMap, use } from 'echarts/core'; +import { BarChart, LineChart, PieChart, MapChart } from 'echarts/charts'; +import { + GridComponent, + TooltipComponent, + LegendComponent, + TitleComponent, + VisualMapComponent, +} from 'echarts/components'; +import { CanvasRenderer } from 'echarts/renderers'; +import VChart from 'vue-echarts'; +import 'echarts-wordcloud'; +import { barOptions, lineOptions, pieOptions, ringOptions, wordOptions, mapOptions } from './options'; +import chinaMap from '@/utils/china'; +use([ + CanvasRenderer, + BarChart, + GridComponent, + LineChart, + PieChart, + MapChart, + TooltipComponent, + LegendComponent, + TitleComponent, + VisualMapComponent, +]); +registerMap('china', chinaMap); +</script> + +<style scoped> +.schart { + width: 100%; + height: 400px; +} + +.content-title { + font-weight: 400; + font-size: 22px; + color: #1f2f3d; +} +</style> diff --git a/src/views/chart/options.ts b/src/views/chart/options.ts new file mode 100644 index 00000000..75705ca1 --- /dev/null +++ b/src/views/chart/options.ts @@ -0,0 +1,345 @@ +import { graphic } from 'echarts/core'; +export const barOptions = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + color: ['#009688', '#f44336'], + series: [ + { + data: [120, 200, 150, 80, 70, 110, 130], + type: 'bar', + }, + { + data: [180, 230, 190, 120, 110, 230, 235], + type: 'bar', + }, + ], +}; + +export const lineOptions = { + tooltip: { + trigger: 'axis', + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + color: ['#009688', '#f44336'], + series: [ + { + name: 'Email', + type: 'line', + stack: 'Total', + areaStyle: {}, + smooth: true, + data: [120, 132, 101, 134, 90, 230, 210], + }, + { + name: 'Union Ads', + type: 'line', + stack: 'Total', + areaStyle: {}, + smooth: true, + data: [220, 182, 191, 234, 290, 330, 310], + }, + ], +}; + +export const pieOptions = { + title: { + text: 'Referer of a Website', + subtext: 'Fake Data', + left: 'center', + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'left', + }, + series: [ + { + name: 'Access From', + type: 'pie', + radius: '50%', + data: [ + { value: 1048, name: 'Search Engine' }, + { value: 735, name: 'Direct' }, + { value: 580, name: 'Email' }, + { value: 484, name: 'Union Ads' }, + { value: 300, name: 'Video Ads' }, + ], + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)', + }, + }, + }, + ], +}; + +export const wordOptions = { + series: [ + { + type: 'wordCloud', + rotationRange: [0, 0], + autoSize: { + enable: true, + minSize: 14, + }, + textStyle: { + fontFamily: '微软雅黑,sans-serif', + color: function () { + return ( + 'rgb(' + + [ + Math.round(Math.random() * 160), + Math.round(Math.random() * 160), + Math.round(Math.random() * 160), + ].join(',') + + ')' + ); + }, + }, + data: [ + { + name: 'Vue', + value: 10000, + }, + { + name: 'React', + value: 9000, + }, + { + name: '图表', + value: 4000, + }, + { + name: '产品', + value: 7000, + }, + { + name: 'vue-manage-system', + value: 2000, + }, + { + name: 'element-plus', + value: 6000, + }, + { + name: '管理系统', + value: 5000, + }, + { + name: '前端', + value: 4000, + }, + { + name: '测试', + value: 3000, + }, + { + name: '后端', + value: 8000, + }, + { + name: '软件开发', + value: 6000, + }, + { + name: '程序员', + value: 4000, + }, + ], + }, + ], +}; + +export const ringOptions = { + tooltip: { + trigger: 'item', + }, + legend: { + top: '5%', + left: 'center', + }, + + series: [ + { + name: 'Access From', + type: 'pie', + radius: ['40%', '70%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#fff', + borderWidth: 2, + }, + label: { + show: false, + position: 'center', + }, + emphasis: { + label: { + show: true, + fontSize: 40, + fontWeight: 'bold', + }, + }, + labelLine: { + show: false, + }, + data: [ + { value: 1048, name: 'Search Engine' }, + { value: 735, name: 'Direct' }, + { value: 580, name: 'Email' }, + { value: 484, name: 'Union Ads' }, + { value: 300, name: 'Video Ads' }, + ], + }, + ], +}; + +export const dashOpt1 = { + xAxis: { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + grid: { + top: '2%', + left: '2%', + right: '3%', + bottom: '2%', + containLabel: true, + }, + color: ['#009688', '#f44336'], + series: [ + { + type: 'line', + areaStyle: { + color: new graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgba(0, 150, 136,0.8)', + }, + { + offset: 1, + color: 'rgba(0, 150, 136,0.2)', + }, + ]), + }, + smooth: true, + data: [120, 132, 301, 134, 90, 230, 210], + }, + { + type: 'line', + smooth: true, + data: [220, 122, 191, 234, 190, 130, 310], + }, + ], +}; + +export const dashOpt2 = { + legend: { + bottom: '1%', + left: 'center', + }, + color: ['#3f51b5', '#009688', '#f44336', '#00bcd4', '#1ABC9C'], + series: [ + { + type: 'pie', + radius: ['40%', '70%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#fff', + borderWidth: 2, + }, + data: [ + { value: 1048, name: '数码' }, + { value: 735, name: '食品' }, + { value: 580, name: '母婴' }, + { value: 484, name: '家电' }, + { value: 300, name: '运动' }, + ], + }, + ], +}; + +export const mapOptions = { + tooltip: { + trigger: 'item', + }, + geo: { + map: 'china', + roam: false, + emphasis: { + label: { + show: false, + }, + }, + }, + visualMap: { + show: false, + min: 0, + max: 100, + realtime: false, + calculable: false, + inRange: { + color: ['#d2e0f5', '#71A9FF'], + }, + }, + series: [ + { + geoIndex: 0, + name: '地域分布', + type: 'map', + coordinateSystem: 'geo', + map: 'china', + data: [ + { name: '北京', value: 100 }, + { name: '上海', value: 100 }, + { name: '广东', value: 100 }, + { name: '浙江', value: 90 }, + { name: '江西', value: 80 }, + { name: '山东', value: 70 }, + { name: '广西', value: 60 }, + { name: '河南', value: 50 }, + { name: '河南', value: 40 }, + { name: '青海', value: 70 }, + { name: '河南', value: 30 }, + { name: '黑龙江', value: 20 }, + { name: '新疆', value: 20 }, + { name: '云南', value: 20 }, + { name: '甘肃', value: 20 }, + ], + }, + ], +}; diff --git a/src/views/charts.vue b/src/views/chart/schart.vue similarity index 64% rename from src/views/charts.vue rename to src/views/chart/schart.vue index 7e4df52a..4e1ac90a 100644 --- a/src/views/charts.vue +++ b/src/views/chart/schart.vue @@ -1,127 +1,129 @@ -<template> - <div class="container"> - <div class="plugins-tips"> - vue-schart:vue.js封装sChart.js的图表组件。 访问地址: - <a href="https://github.com/lin-xin/vue-schart" target="_blank">vue-schart</a> - </div> - <div class="schart-box"> - <div class="content-title">柱状图</div> - <schart class="schart" canvasId="bar" :options="options1"></schart> - </div> - <div class="schart-box"> - <div class="content-title">折线图</div> - <schart class="schart" canvasId="line" :options="options2"></schart> - </div> - <div class="schart-box"> - <div class="content-title">饼状图</div> - <schart class="schart" canvasId="pie" :options="options3"></schart> - </div> - <div class="schart-box"> - <div class="content-title">环形图</div> - <schart class="schart" canvasId="ring" :options="options4"></schart> - </div> - </div> -</template> - -<script setup lang="ts" name="basecharts"> -import Schart from 'vue-schart'; - -const options1 = { - type: 'bar', - title: { - text: '最近一周各品类销售图' - }, - bgColor: '#fbfbfb', - labels: ['周一', '周二', '周三', '周四', '周五'], - datasets: [ - { - label: '家电', - fillColor: 'rgba(241, 49, 74, 0.5)', - data: [234, 278, 270, 190, 230] - }, - { - label: '百货', - data: [164, 178, 190, 135, 160] - }, - { - label: '食品', - data: [144, 198, 150, 235, 120] - } - ] -}; -const options2 = { - type: 'line', - title: { - text: '最近几个月各品类销售趋势图' - }, - bgColor: '#fbfbfb', - labels: ['6月', '7月', '8月', '9月', '10月'], - datasets: [ - { - label: '家电', - data: [234, 278, 270, 190, 230] - }, - { - label: '百货', - data: [164, 178, 150, 135, 160] - }, - { - label: '食品', - data: [114, 138, 200, 235, 190] - } - ] -}; -const options3 = { - type: 'pie', - title: { - text: '服装品类销售饼状图' - }, - legend: { - position: 'left' - }, - bgColor: '#fbfbfb', - labels: ['T恤', '牛仔裤', '连衣裙', '毛衣', '七分裤', '短裙', '羽绒服'], - datasets: [ - { - data: [334, 278, 190, 235, 260, 200, 141] - } - ] -}; -const options4 = { - type: 'ring', - title: { - text: '环形三等分' - }, - showValue: false, - legend: { - position: 'bottom', - bottom: 40 - }, - bgColor: '#fbfbfb', - labels: ['vue', 'react', 'angular'], - datasets: [ - { - data: [500, 500, 500] - } - ] -}; -</script> - -<style scoped> -.schart-box { - display: inline-block; - margin: 20px; -} -.schart { - width: 600px; - height: 400px; -} -.content-title { - clear: both; - font-weight: 400; - line-height: 50px; - margin: 10px 0; - font-size: 22px; - color: #1f2f3d; -} -</style> +<template> + <div class="container"> + <div class="plugins-tips"> + vue-schart:vue.js封装sChart.js的图表组件。 访问地址: + <a href="https://github.com/lin-xin/vue-schart" target="_blank">vue-schart</a> + </div> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">柱状图</div> + </template> + <schart class="schart" canvasId="bar" :options="options1"></schart> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">折线图</div> + </template> + <schart class="schart" canvasId="line" :options="options2"></schart> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">饼状图</div> + </template> + <schart class="schart" canvasId="pie" :options="options3"></schart> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">环形图</div> + </template> + <schart class="schart" canvasId="ring" :options="options4"></schart> + </el-card> + </div> +</template> + +<script setup lang="ts" name="schart"> +import Schart from 'vue-schart'; + +const options1 = { + type: 'bar', + title: { + text: '最近一周各品类销售图' + }, + colorList: ["#3f51b5", "#009688", "#f44336", "#00bcd4", "#1ABC9C"], + labels: ['周一', '周二', '周三', '周四', '周五'], + datasets: [ + { + label: '家电', + // fillColor: 'rgba(241, 49, 74, 0.5)', + data: [234, 278, 270, 190, 230] + }, + { + label: '百货', + data: [164, 178, 190, 135, 160] + }, + { + label: '食品', + data: [144, 198, 150, 235, 120] + } + ] +}; +const options2 = { + type: 'line', + title: { + text: '最近几个月各品类销售趋势图' + }, + colorList: ["#3f51b5", "#009688", "#f44336", "#00bcd4", "#1ABC9C"], + labels: ['6月', '7月', '8月', '9月', '10月'], + datasets: [ + { + label: '家电', + data: [234, 278, 270, 190, 230] + }, + { + label: '百货', + data: [164, 178, 150, 135, 160] + }, + { + label: '食品', + data: [114, 138, 200, 235, 190] + } + ] +}; +const options3 = { + type: 'pie', + title: { + text: '服装品类销售饼状图' + }, + legend: { + position: 'left' + }, + colorList: ["#2196f3", '#673ab7', "#009688", "#1ABC9C", "#3f51b5", "#f44336", "#00bcd4"], + labels: ['T恤', '牛仔裤', '连衣裙', '毛衣', '七分裤', '短裙', '羽绒服'], + datasets: [ + { + data: [334, 278, 190, 235, 260, 200, 141] + } + ] +}; +const options4 = { + type: 'ring', + title: { + text: '环形三等分' + }, + showValue: false, + legend: { + position: 'bottom', + bottom: 40 + }, + colorList: ["#3f51b5", "#009688", "#f44336", "#00bcd4", "#1ABC9C"], + labels: ['vue', 'react', 'angular'], + datasets: [ + { + data: [500, 500, 500] + } + ] +}; +</script> + +<style scoped> +.schart { + width: 100%; + height: 400px; +} + +.content-title { + font-weight: 400; + font-size: 22px; + color: #1f2f3d; +} +</style> diff --git a/src/views/dashboard.vue b/src/views/dashboard.vue index 5e6d0391..5f27a4bc 100644 --- a/src/views/dashboard.vue +++ b/src/views/dashboard.vue @@ -1,301 +1,357 @@ -<template> - <div> - <el-row :gutter="20"> - <el-col :span="8"> - <el-card shadow="hover" class="mgb20" style="height: 252px"> - <div class="user-info"> - <el-avatar :size="120" :src="imgurl" /> - <div class="user-info-cont"> - <div class="user-info-name">{{ name }}</div> - <div>{{ role }}</div> - </div> - </div> - <div class="user-info-list"> - 上次登录时间: - <span>2022-10-01</span> - </div> - <div class="user-info-list"> - 上次登录地点: - <span>东莞</span> - </div> - </el-card> - <el-card shadow="hover" style="height: 252px"> - <template #header> - <div class="clearfix"> - <span>语言详情</span> - </div> - </template> - Vue - <el-progress :percentage="79.4" color="#42b983"></el-progress> - TypeScript - <el-progress :percentage="14" color="#f1e05a"></el-progress> - CSS - <el-progress :percentage="5.6"></el-progress> - HTML - <el-progress :percentage="1" color="#f56c6c"></el-progress> - </el-card> - </el-col> - <el-col :span="16"> - <el-row :gutter="20" class="mgb20"> - <el-col :span="8"> - <el-card shadow="hover" :body-style="{ padding: '0px' }"> - <div class="grid-content grid-con-1"> - <el-icon class="grid-con-icon"><User /></el-icon> - <div class="grid-cont-right"> - <div class="grid-num">1234</div> - <div>用户访问量</div> - </div> - </div> - </el-card> - </el-col> - <el-col :span="8"> - <el-card shadow="hover" :body-style="{ padding: '0px' }"> - <div class="grid-content grid-con-2"> - <el-icon class="grid-con-icon"><ChatDotRound /></el-icon> - <div class="grid-cont-right"> - <div class="grid-num">321</div> - <div>系统消息</div> - </div> - </div> - </el-card> - </el-col> - <el-col :span="8"> - <el-card shadow="hover" :body-style="{ padding: '0px' }"> - <div class="grid-content grid-con-3"> - <el-icon class="grid-con-icon"><Goods /></el-icon> - <div class="grid-cont-right"> - <div class="grid-num">5000</div> - <div>商品数量</div> - </div> - </div> - </el-card> - </el-col> - </el-row> - <el-card shadow="hover" style="height: 403px"> - <template #header> - <div class="clearfix"> - <span>待办事项</span> - <el-button style="float: right; padding: 3px 0" text>添加</el-button> - </div> - </template> - - <el-table :show-header="false" :data="todoList" style="width: 100%"> - <el-table-column width="40"> - <template #default="scope"> - <el-checkbox v-model="scope.row.status"></el-checkbox> - </template> - </el-table-column> - <el-table-column> - <template #default="scope"> - <div - class="todo-item" - :class="{ - 'todo-item-del': scope.row.status - }" - > - {{ scope.row.title }} - </div> - </template> - </el-table-column> - </el-table> - </el-card> - </el-col> - </el-row> - <el-row :gutter="20"> - <el-col :span="12"> - <el-card shadow="hover"> - <schart ref="bar" class="schart" canvasId="bar" :options="options"></schart> - </el-card> - </el-col> - <el-col :span="12"> - <el-card shadow="hover"> - <schart ref="line" class="schart" canvasId="line" :options="options2"></schart> - </el-card> - </el-col> - </el-row> - </div> -</template> - -<script setup lang="ts" name="dashboard"> -import Schart from 'vue-schart'; -import { reactive } from 'vue'; -import imgurl from '../assets/img/img.jpg'; - -const name = localStorage.getItem('ms_username'); -const role: string = name === 'admin' ? '超级管理员' : '普通用户'; - -const options = { - type: 'bar', - title: { - text: '最近一周各品类销售图' - }, - xRorate: 25, - labels: ['周一', '周二', '周三', '周四', '周五'], - datasets: [ - { - label: '家电', - data: [234, 278, 270, 190, 230] - }, - { - label: '百货', - data: [164, 178, 190, 135, 160] - }, - { - label: '食品', - data: [144, 198, 150, 235, 120] - } - ] -}; -const options2 = { - type: 'line', - title: { - text: '最近几个月各品类销售趋势图' - }, - labels: ['6月', '7月', '8月', '9月', '10月'], - datasets: [ - { - label: '家电', - data: [234, 278, 270, 190, 230] - }, - { - label: '百货', - data: [164, 178, 150, 135, 160] - }, - { - label: '食品', - data: [74, 118, 200, 235, 90] - } - ] -}; -const todoList = reactive([ - { - title: '今天要修复100个bug', - status: false - }, - { - title: '今天要修复100个bug', - status: false - }, - { - title: '今天要写100行代码加几个bug吧', - status: false - }, - { - title: '今天要修复100个bug', - status: false - }, - { - title: '今天要修复100个bug', - status: true - }, - { - title: '今天要写100行代码加几个bug吧', - status: true - } -]); -</script> - -<style scoped> -.el-row { - margin-bottom: 20px; -} - -.grid-content { - display: flex; - align-items: center; - height: 100px; -} - -.grid-cont-right { - flex: 1; - text-align: center; - font-size: 14px; - color: #999; -} - -.grid-num { - font-size: 30px; - font-weight: bold; -} - -.grid-con-icon { - font-size: 50px; - width: 100px; - height: 100px; - text-align: center; - line-height: 100px; - color: #fff; -} - -.grid-con-1 .grid-con-icon { - background: rgb(45, 140, 240); -} - -.grid-con-1 .grid-num { - color: rgb(45, 140, 240); -} - -.grid-con-2 .grid-con-icon { - background: rgb(100, 213, 114); -} - -.grid-con-2 .grid-num { - color: rgb(100, 213, 114); -} - -.grid-con-3 .grid-con-icon { - background: rgb(242, 94, 67); -} - -.grid-con-3 .grid-num { - color: rgb(242, 94, 67); -} - -.user-info { - display: flex; - align-items: center; - padding-bottom: 20px; - border-bottom: 2px solid #ccc; - margin-bottom: 20px; -} - -.user-info-cont { - padding-left: 50px; - flex: 1; - font-size: 14px; - color: #999; -} - -.user-info-cont div:first-child { - font-size: 30px; - color: #222; -} - -.user-info-list { - font-size: 14px; - color: #999; - line-height: 25px; -} - -.user-info-list span { - margin-left: 70px; -} - -.mgb20 { - margin-bottom: 20px; -} - -.todo-item { - font-size: 14px; -} - -.todo-item-del { - text-decoration: line-through; - color: #999; -} - -.schart { - width: 100%; - height: 300px; -} -</style> +<template> + <div> + <el-row :gutter="20" class="mgb20"> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg1"> + <User /> + </el-icon> + <div class="card-content"> + <countup class="card-num color1" :end="6666" /> + <div>用户访问量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg2"> + <ChatDotRound /> + </el-icon> + <div class="card-content"> + <countup class="card-num color2" :end="168" /> + <div>系统消息</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg3"> + <Goods /> + </el-icon> + <div class="card-content"> + <countup class="card-num color3" :end="8888" /> + <div>商品数量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg4"> + <ShoppingCartFull /> + </el-icon> + <div class="card-content"> + <countup class="card-num color4" :end="568" /> + <div>今日订单量</div> + </div> + </el-card> + </el-col> + </el-row> + + <el-row :gutter="20" class="mgb20"> + <el-col :span="18"> + <el-card shadow="hover"> + <div class="card-header"> + <p class="card-header-title">订单动态</p> + <p class="card-header-desc">最近一周订单状态,包括订单成交量和订单退货量</p> + </div> + <v-chart class="chart" :option="dashOpt1" /> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover"> + <div class="card-header"> + <p class="card-header-title">品类分布</p> + <p class="card-header-desc">最近一个月销售商品的品类情况</p> + </div> + <v-chart class="chart" :option="dashOpt2" /> + </el-card> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="7"> + <el-card shadow="hover" :body-style="{ height: '400px' }"> + <div class="card-header"> + <p class="card-header-title">时间线</p> + <p class="card-header-desc">最新的销售动态和活动信息</p> + </div> + <el-timeline> + <el-timeline-item v-for="(activity, index) in activities" :key="index" :color="activity.color"> + <div class="timeline-item"> + <div> + <p>{{ activity.content }}</p> + <p class="timeline-desc">{{ activity.description }}</p> + </div> + <div class="timeline-time">{{ activity.timestamp }}</div> + </div> + </el-timeline-item> + </el-timeline> + </el-card> + </el-col> + <el-col :span="10"> + <el-card shadow="hover" :body-style="{ height: '400px' }"> + <div class="card-header"> + <p class="card-header-title">渠道统计</p> + <p class="card-header-desc">最近一个月的订单来源统计</p> + </div> + <v-chart class="map-chart" :option="mapOptions" /> + </el-card> + </el-col> + <el-col :span="7"> + <el-card shadow="hover" :body-style="{ height: '400px' }"> + <div class="card-header"> + <p class="card-header-title">排行榜</p> + <p class="card-header-desc">销售商品的热门榜单Top5</p> + </div> + <div> + <div class="rank-item" v-for="(rank, index) in ranks"> + <div class="rank-item-avatar">{{ index + 1 }}</div> + <div class="rank-item-content"> + <div class="rank-item-top"> + <div class="rank-item-title">{{ rank.title }}</div> + <div class="rank-item-desc">销量:{{ rank.value }}</div> + </div> + <el-progress + :show-text="false" + striped + :stroke-width="10" + :percentage="rank.percent" + :color="rank.color" + /> + </div> + </div> + </div> + </el-card> + </el-col> + </el-row> + </div> +</template> + +<script setup lang="ts" name="dashboard"> +import countup from '@/components/countup.vue'; +import { use, registerMap } from 'echarts/core'; +import { BarChart, LineChart, PieChart, MapChart } from 'echarts/charts'; +import { + GridComponent, + TooltipComponent, + LegendComponent, + TitleComponent, + VisualMapComponent, +} from 'echarts/components'; +import { CanvasRenderer } from 'echarts/renderers'; +import VChart from 'vue-echarts'; +import { dashOpt1, dashOpt2, mapOptions } from './chart/options'; +import chinaMap from '@/utils/china'; +use([ + CanvasRenderer, + BarChart, + GridComponent, + LineChart, + PieChart, + TooltipComponent, + LegendComponent, + TitleComponent, + VisualMapComponent, + MapChart, +]); +registerMap('china', chinaMap); +const activities = [ + { + content: '收藏商品', + description: 'xxx收藏了你的商品,就是不买', + timestamp: '30分钟前', + color: '#00bcd4', + }, + { + content: '用户评价', + description: 'xxx给了某某商品一个差评,吐血啊', + timestamp: '55分钟前', + color: '#1ABC9C', + }, + { + content: '订单提交', + description: 'xxx提交了订单,快去收钱吧', + timestamp: '1小时前', + color: '#3f51b5', + }, + { + content: '退款申请', + description: 'xxx申请了仅退款,又要亏钱了', + timestamp: '15小时前', + color: '#f44336', + }, + { + content: '商品上架', + description: '运营专员瞒着你上架了一辆飞机', + timestamp: '1天前', + color: '#009688', + }, +]; + +const ranks = [ + { + title: '手机', + value: 10000, + percent: 80, + color: '#f25e43', + }, + { + title: '电脑', + value: 8000, + percent: 70, + color: '#00bcd4', + }, + { + title: '相机', + value: 6000, + percent: 60, + color: '#64d572', + }, + { + title: '衣服', + value: 5000, + percent: 55, + color: '#e9a745', + }, + { + title: '书籍', + value: 4000, + percent: 50, + color: '#009688', + }, +]; +</script> + +<style> +.card-body { + display: flex; + align-items: center; + height: 100px; + padding: 0; +} +</style> +<style scoped> +.card-content { + flex: 1; + text-align: center; + font-size: 14px; + color: #999; + padding: 0 20px; +} + +.card-num { + font-size: 30px; +} + +.card-icon { + font-size: 50px; + width: 100px; + height: 100px; + text-align: center; + line-height: 100px; + color: #fff; +} + +.bg1 { + background: #2d8cf0; +} + +.bg2 { + background: #64d572; +} + +.bg3 { + background: #f25e43; +} + +.bg4 { + background: #e9a745; +} + +.color1 { + color: #2d8cf0; +} + +.color2 { + color: #64d572; +} + +.color3 { + color: #f25e43; +} + +.color4 { + color: #e9a745; +} + +.chart { + width: 100%; + height: 400px; +} + +.card-header { + padding-left: 10px; + margin-bottom: 20px; +} + +.card-header-title { + font-size: 18px; + font-weight: bold; + margin-bottom: 5px; +} + +.card-header-desc { + font-size: 14px; + color: #999; +} + +.timeline-item { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 16px; + color: #000; +} + +.timeline-time, +.timeline-desc { + font-size: 12px; + color: #787878; +} + +.rank-item { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +.rank-item-avatar { + width: 40px; + height: 40px; + border-radius: 50%; + background: #f2f2f2; + text-align: center; + line-height: 40px; + margin-right: 10px; +} + +.rank-item-content { + flex: 1; +} + +.rank-item-top { + display: flex; + justify-content: space-between; + align-items: center; + color: #343434; + margin-bottom: 10px; +} + +.rank-item-desc { + font-size: 14px; + color: #999; +} +.map-chart { + width: 100%; + height: 350px; +} +</style> diff --git a/src/views/donate.vue b/src/views/donate.vue deleted file mode 100644 index c127e30d..00000000 --- a/src/views/donate.vue +++ /dev/null @@ -1,14 +0,0 @@ -<template> - <div class="container"> - <div class="plugins-tips"> - 如果该框架对你有帮助,那就请作者喝杯饮料吧!<el-icon><ColdDrink /></el-icon> 加微信号linxin_20探讨问题。 - </div> - <div> - <img src="https://lin-xin.gitee.io/images/weixin.jpg" /> - </div> - </div> -</template> - -<script setup lang="ts" name="donate"></script> - -<style></style> diff --git a/src/views/element/calendar.vue b/src/views/element/calendar.vue new file mode 100644 index 00000000..1b914747 --- /dev/null +++ b/src/views/element/calendar.vue @@ -0,0 +1,82 @@ +<template> + <div class="container"> + <el-calendar v-model="value"> + <template #date-cell="{ data }"> + <div>{{ data.date.getDate() }}</div> + <div class="notes-container" v-if="notes[data.day.toString()]"> + <div class="notes" v-for="note in notes[data.day.toString()]"> + <span :class="note.status === 1 ? 'text-success' : 'text-danger'"></span> + <div class="note-title">{{ note.title }}</div> + </div> + </div> + </template> + </el-calendar> + </div> +</template> + +<script lang="ts" setup> +import { ref } from 'vue'; + +const today = new Date(); +const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); +const value = ref(today); + +const todayDate = today.toISOString().slice(0, 10); +const yesterdayDate = yesterday.toISOString().slice(0, 10); + +const notes: any = { + [todayDate]: [ + { title: '吃饭', status: 1 }, + { title: '睡觉', status: 0 }, + { title: '吃饭', status: 1 }, + { title: '睡觉', status: 0 }, + { title: '吃饭', status: 1 }, + { title: '睡觉', status: 0 }, + ], + [yesterdayDate]: [{ title: '参加会议', status: 0 }], +}; +</script> + +<style scoped> +.notes-container { + height: 60px; + overflow-y: auto; +} + +.notes-container::-webkit-scrollbar { + width: 0; +} + +.notes { + display: flex; + align-items: center; + width: 100%; + font-size: 12px; +} + +.notes:hover { + background-color: #eee; +} + +.note-title { + flex: 1; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.notes span { + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 5px; +} + +.text-success { + background-color: #5cb85c; +} + +.text-danger { + background-color: #d9534f; +} +</style> diff --git a/src/views/element/carousel.vue b/src/views/element/carousel.vue new file mode 100644 index 00000000..dacbf4d4 --- /dev/null +++ b/src/views/element/carousel.vue @@ -0,0 +1,66 @@ +<template> + <div> + <el-card class="mgb20"> + <template #header>基础用法</template> + <el-carousel height="400px"> + <el-carousel-item v-for="item in 4" :key="item"> + <h3>{{ item }}</h3> + </el-carousel-item> + </el-carousel> + </el-card> + + <el-row :gutter="20"> + <el-col :span="12"> + <el-card class="mgb20"> + <template #header>轮播图</template> + <el-carousel height="300px"> + <el-carousel-item v-for="item in imgs" :key="item"> + <el-image class="carousel-img" :src="item" fit="cover" /> + </el-carousel-item> + </el-carousel> + </el-card> + </el-col> + <el-col :span="12"> + <el-card class="mgb20"> + <template #header>卡片模式</template> + <el-carousel height="300px" type="card"> + <el-carousel-item v-for="item in imgs" :key="item"> + <el-image class="carousel-img" :src="item" fit="cover" /> + </el-carousel-item> + </el-carousel> + </el-card> + </el-col> + </el-row> + </div> +</template> + +<script lang="ts" setup> +const imgs = [ + 'https://cdn.pixabay.com/photo/2017/08/07/08/23/sea-2601374_640.jpg', + 'https://cdn.pixabay.com/photo/2020/02/11/10/24/lake-4839058_640.jpg', + 'https://cdn.pixabay.com/photo/2024/02/21/08/06/coast-8587004_640.jpg', + 'https://cdn.pixabay.com/photo/2023/07/29/10/21/grasshopper-8156626_640.jpg', +]; +</script> + +<style scoped> +.el-carousel__item h3 { + color: #475669; + line-height: 400px; + margin: 0; + text-align: center; +} + +.el-carousel__item:nth-child(2n) { + background-color: #99a9bf; +} + +.el-carousel__item:nth-child(2n + 1) { + background-color: #d3dce6; +} + +.carousel-img { + width: 100%; + height: 100%; +} +</style> diff --git a/src/views/element/form.vue b/src/views/element/form.vue new file mode 100644 index 00000000..2c9a78b8 --- /dev/null +++ b/src/views/element/form.vue @@ -0,0 +1,189 @@ +<template> + <div class="container"> + <el-radio-group class="mgb20" v-model="labelPosition"> + <el-radio-button value="left">Left</el-radio-button> + <el-radio-button value="right">Right</el-radio-button> + <el-radio-button value="top">Top</el-radio-button> + </el-radio-group> + <el-form ref="formRef" :rules="rules" :model="form" label-width="120px" :label-position="labelPosition"> + <el-row :gutter="50"> + <el-col :span="10"> + <el-form-item label="文本框" prop="name"> + <el-input v-model="form.name"></el-input> + </el-form-item> + <el-form-item label="数字框" prop="num"> + <el-input-number v-model="form.num" :min="1" :max="10" /> + </el-form-item> + <el-form-item label="日期选择" prop="date"> + <el-date-picker type="date" placeholder="选择日期" v-model="form.date"></el-date-picker> + </el-form-item> + <el-form-item label="时间选择" prop="time"> + <el-time-picker placeholder="选择时间" v-model="form.time"> + </el-time-picker> + </el-form-item> + <el-form-item label="选择器" prop="region"> + <el-select v-model="form.region" placeholder="请选择"> + <el-option key="小明" label="小明" value="小明"></el-option> + <el-option key="小红" label="小红" value="小红"></el-option> + <el-option key="小白" label="小白" value="小白"></el-option> + </el-select> + </el-form-item> + <el-form-item label="城市级联" prop="options"> + <el-cascader :options="options" v-model="form.options"></el-cascader> + </el-form-item> + <el-form-item label="文本框" prop="desc"> + <el-input type="textarea" rows="5" v-model="form.desc"></el-input> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="评分" prop="rate"> + <el-rate v-model="form.rate" allow-half /> + </el-form-item> + <el-form-item label="滑块" prop="num"> + <el-slider v-model="form.num" :step="1" show-stops :max="10" /> + </el-form-item> + <el-form-item label="开关" prop="delivery"> + <el-switch v-model="form.delivery"></el-switch> + </el-form-item> + <el-form-item label="颜色选择" prop="color"> + <el-color-picker v-model="form.color" /> + </el-form-item> + <el-form-item label="多选框" prop="type"> + <el-checkbox-group v-model="form.type"> + <el-checkbox label="小明" value="小明" name="type"></el-checkbox> + <el-checkbox label="小红" value="小红" name="type"></el-checkbox> + <el-checkbox label="小白" value="小白" name="type"></el-checkbox> + </el-checkbox-group> + </el-form-item> + <el-form-item label="单选框" prop="resource"> + <el-radio-group v-model="form.resource"> + <el-radio label="小明" value="小明"></el-radio> + <el-radio label="小红" value="小红"></el-radio> + <el-radio label="小白" value="小白"></el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="穿梭框" prop="transfer"> + <el-transfer v-model="form.transfer" :data="transferData" /> + </el-form-item> + </el-col> + + <el-col :span="24"> + <el-form-item> + <el-button type="primary" @click="onSubmit(formRef)">表单提交</el-button> + <el-button @click="onReset(formRef)">重置表单</el-button> + </el-form-item> + </el-col> + </el-row> + </el-form> + </div> +</template> + +<script setup lang="ts" name="forms"> +import { reactive, ref } from 'vue'; +import { ElMessage } from 'element-plus'; +import type { FormInstance, FormProps, FormRules } from 'element-plus'; +const labelPosition = ref<FormProps['labelPosition']>('right') +const options = [ + { + value: 'guangdong', + label: '广东省', + children: [ + { + value: 'guangzhou', + label: '广州市', + children: [ + { + value: 'tianhe', + label: '天河区', + }, + { + value: 'haizhu', + label: '海珠区', + }, + ], + }, + { + value: 'dongguan', + label: '东莞市', + children: [ + { + value: 'changan', + label: '长安镇', + }, + { + value: 'humen', + label: '虎门镇', + }, + ], + }, + ], + }, + { + value: 'hunan', + label: '湖南省', + children: [ + { + value: 'changsha', + label: '长沙市', + children: [ + { + value: 'yuelu', + label: '岳麓区', + }, + ], + }, + ], + }, +]; +const rules: FormRules = { + name: [{ required: true, message: '请输入表单名称', trigger: 'blur' }], +}; +const formRef = ref<FormInstance>(); +const form = reactive({ + name: '', + region: '', + date: '', + time: '', + delivery: true, + type: ['小明'], + resource: '小红', + desc: '', + options: [], + color: '', + num: 1, + rate: 0, + transfer: [], + +}); +const generateData = () => { + const data = [] + for (let i = 1; i <= 15; i++) { + data.push({ + key: i, + label: `Option ${i}`, + disabled: i % 4 === 0, + }) + } + return data +} + +const transferData = ref(generateData()) +// 提交 +const onSubmit = (formEl: FormInstance | undefined) => { + // 表单校验 + if (!formEl) return; + formEl.validate((valid) => { + if (valid) { + console.log(form); + ElMessage.success('提交成功!'); + } else { + return false; + } + }); +}; +// 重置 +const onReset = (formEl: FormInstance | undefined) => { + if (!formEl) return; + formEl.resetFields(); +}; +</script> \ No newline at end of file diff --git a/src/views/element/statistic.vue b/src/views/element/statistic.vue new file mode 100644 index 00000000..2284a4aa --- /dev/null +++ b/src/views/element/statistic.vue @@ -0,0 +1,340 @@ +<template> + <div> + + + <el-card class="mgb20" shadow="hover"> + <template #header>基础用法</template> + <el-row> + <el-col :span="6" style="text-align: center"> + <el-statistic title="Daily active users" :value="268500" /> + </el-col> + <el-col :span="6" style="text-align: center"> + <el-statistic :value="138"> + <template #title> + <div style="display: inline-flex; align-items: center"> + Ratio of men to women + </div> + </template> + <template #suffix>/100</template> + </el-statistic> + </el-col> + <el-col :span="6" style="text-align: center"> + <el-statistic title="数字滚动" :value="outputValue" /> + </el-col> + <el-col :span="6" style="text-align: center"> + <el-countdown title="倒计时" :value="value" /> + </el-col> + </el-row> + </el-card> + + <el-card class="mgb20" shadow="hover"> + <template #header>CountUp.js</template> + <div class="plugins-tips"> + countup.js:用于快速创建以更有趣的方式显示数字数据的动画。 访问地址: + <a href="https://github.com/inorganik/countUp.js" target="_blank">countUp.js</a> + </div> + <el-row> + <el-col :span="8" style="text-align: center"> + <p>基础用法</p> + <countup class="countup" :end="6666" /> + </el-col> + <el-col :span="8" style="text-align: center"> + <p>具体配置</p> + <countup class="countup" :end="8888.5" :options="options" /> + </el-col> + <el-col :span="8" style="text-align: center"> + <p>更新数值</p> + <countup class="countup" :end="value1" /> + </el-col> + </el-row> + </el-card> + <el-card class="mgb20" shadow="never"> + <template #header>统计卡片</template> + + <el-row :gutter="20" class="mgb20"> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon color1"> + <User /> + </el-icon> + <div class="card-content text-right"> + <el-statistic title="日活跃用户量" :value="268500" /> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon color2"> + <ChatDotRound /> + </el-icon> + <div class="card-content text-right"> + <el-statistic title="系统消息" :value="16800" /> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon color3"> + <Goods /> + </el-icon> + <div class="card-content text-right"> + <el-statistic title="商品数量" :value="8888" /> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon color4"> + <ShoppingCartFull /> + </el-icon> + <div class="card-content text-right"> + <el-statistic title="今日订单量" :value="56888" /> + </div> + </el-card> + </el-col> + </el-row> + <el-row :gutter="20" class="mgb20"> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <div class="card-content text-left"> + <el-statistic :value-style="{ color: '#2d8cf0' }" title="日活跃用户量" :value="268500" /> + </div> + <el-icon class="card-icon color1"> + <User /> + </el-icon> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <div class="card-content text-left"> + <el-statistic :value-style="{ color: '#64d572' }" title="系统消息" :value="16800" /> + </div> + <el-icon class="card-icon color2"> + <ChatDotRound /> + </el-icon> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <div class="card-content text-left"> + <el-statistic :value-style="{ color: '#f25e43' }" title="商品数量" :value="8888" /> + </div> + <el-icon class="card-icon color3"> + <Goods /> + </el-icon> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <div class="card-content text-left"> + <el-statistic :value-style="{ color: '#e9a745' }" title="今日订单量" :value="56888" /> + </div> + <el-icon class="card-icon color4"> + <ShoppingCartFull /> + </el-icon> + </el-card> + </el-col> + </el-row> + <el-row :gutter="20" class="mgb20"> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg1"> + <User /> + </el-icon> + <div class="card-content"> + <countup class="card-num color1" :end="6666" /> + <div>用户访问量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg2"> + <ChatDotRound /> + </el-icon> + <div class="card-content"> + <countup class="card-num color2" :end="168" /> + <div>系统消息</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg3"> + <Goods /> + </el-icon> + <div class="card-content"> + <countup class="card-num color3" :end="8888" /> + <div>商品数量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body"> + <el-icon class="card-icon bg4"> + <ShoppingCartFull /> + </el-icon> + <div class="card-content"> + <countup class="card-num color4" :end="568" /> + <div>今日订单量</div> + </div> + </el-card> + </el-col> + </el-row> + <el-row :gutter="20" class="mgb20"> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body bg1"> + <el-icon class="card-icon "> + <User /> + </el-icon> + <div class="card-content color0"> + <countup class="card-num" :end="6666" /> + <div>用户访问量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body bg2"> + <el-icon class="card-icon"> + <ChatDotRound /> + </el-icon> + <div class="card-content color0"> + <countup class="card-num" :end="168" /> + <div>系统消息</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body bg3"> + <el-icon class="card-icon"> + <Goods /> + </el-icon> + <div class="card-content color0"> + <countup class="card-num " :end="8888" /> + <div>商品数量</div> + </div> + </el-card> + </el-col> + <el-col :span="6"> + <el-card shadow="hover" body-class="card-body bg4"> + <el-icon class="card-icon"> + <ShoppingCartFull /> + </el-icon> + <div class="card-content color0"> + <countup class="card-num " :end="568" /> + <div>今日订单量</div> + </div> + </el-card> + </el-col> + </el-row> + </el-card> + </div> +</template> + +<script lang="ts" setup> +import { ref } from 'vue' +import { useTransition } from '@vueuse/core' +import countup from '@/components/countup.vue'; + +const source = ref(0) +const outputValue = useTransition(source, { + duration: 1500, +}) +source.value = 172000 + +const value = ref(Date.now() + 1000 * 60 * 60 * 7) +const value1 = ref(1000); +setTimeout(() => { + value1.value = 8000; +}, 5000); +const options = { + startVal: 1000, + decimalPlaces: 2, + duration: 5, + useGrouping: false, + prefix: '$', + separator: ',', + decimal: '.', + suffix: '', +} +</script> + +<style> +.card-body { + display: flex; + align-items: center; + height: 100px; + padding: 0; +} + +.bg1 { + background: #2d8cf0; +} + +.bg2 { + background: #64d572; +} + +.bg3 { + background: #f25e43; +} + +.bg4 { + background: #e9a745; +} +</style> +<style scoped> +.countup { + font-size: 24px; +} + +.card-content { + flex: 1; + text-align: center; + font-size: 14px; + color: #999; + padding: 0 20px; +} + +.card-num { + font-size: 30px; +} + +.card-icon { + font-size: 50px; + width: 100px; + height: 100px; + text-align: center; + line-height: 100px; + color: #fff; +} + + +.color0 { + color: #fff; +} + +.color1 { + color: #2d8cf0; +} + +.color2 { + color: #64d572; +} + +.color3 { + color: #f25e43; +} + +.color4 { + color: #e9a745; +} + +.text-right { + text-align: right; +} + +.text-left { + text-align: left; +} +</style> \ No newline at end of file diff --git a/src/views/element/steps.vue b/src/views/element/steps.vue new file mode 100644 index 00000000..dec0ce1f --- /dev/null +++ b/src/views/element/steps.vue @@ -0,0 +1,61 @@ +<template> + <div class="container"> + <div class="step-div" v-if="step === 0"> + <p>输入注册时的邮箱,我们会发送验证码到您的邮箱</p> + <el-input placeholder="请输入邮箱"></el-input> + <el-button class="step-btn" type="primary" @click="step++">下一步</el-button> + </div> + <div class="step-div" v-else-if="step === 1"> + <p>验证码已发送至您的邮箱,请输入验证码</p> + <el-input placeholder="请输入验证码"></el-input> + <el-button class="step-btn" type="primary" @click="step++">下一步</el-button> + </div> + + <div class="step-div" v-else-if="step === 2"> + <p>请输入6位以上密码</p> + <el-input placeholder="请输入新密码"></el-input> + <el-button class="step-btn" type="primary" @click="step++">保存</el-button> + </div> + <div v-else> + <el-result icon="success" title="保存成功" sub-title="请退出后重新登录"></el-result> + </div> + <el-steps class="step-style" :active="step" align-center finish-status="success"> + <el-step title="Step 1" description="填写邮箱" /> + <el-step title="Step 2" description="填写验证码" /> + <el-step title="Step 3" description="修改密码" /> + </el-steps> + <el-steps class="step-style" :active="step" finish-status="success" simple> + <el-step title="填写邮箱" /> + <el-step title="填写验证码" /> + <el-step title="修改密码" /> + </el-steps> + </div> +</template> + +<script lang="ts" setup> +import { ref } from 'vue'; +const step = ref(0) +</script> + +<style scoped> +.step-div { + max-width: 500px; + margin: 0 auto; +} + +.step-div p { + margin-bottom: 20px; + color: #787878; +} + +.step-btn { + display: block; + width: 100%; + margin: 20px 0; +} + +.step-style { + max-width: 800px; + margin: 40px auto; +} +</style> \ No newline at end of file diff --git a/src/views/element/tabs.vue b/src/views/element/tabs.vue new file mode 100644 index 00000000..884ea0be --- /dev/null +++ b/src/views/element/tabs.vue @@ -0,0 +1,116 @@ +<template> + <el-tabs v-model="message" type="card"> + <el-tab-pane :label="`未读消息(${state.unread.length})`" name="first"> + <el-table :data="state.unread" :show-header="false" style="width: 100%"> + <el-table-column> + <template #default="scope"> + <span class="message-title">{{ scope.row.title }}</span> + </template> + </el-table-column> + <el-table-column prop="date" width="180"></el-table-column> + <el-table-column width="120"> + <template #default="scope"> + <el-button size="small" @click="handleRead(scope.$index)">标为已读</el-button> + </template> + </el-table-column> + </el-table> + <div class="handle-row"> + <el-button type="primary">全部标为已读</el-button> + </div> + </el-tab-pane> + <el-tab-pane :label="`已读消息(${state.read.length})`" name="second"> + <template v-if="message === 'second'"> + <el-table :data="state.read" :show-header="false" style="width: 100%"> + <el-table-column> + <template #default="scope"> + <span class="message-title">{{ scope.row.title }}</span> + </template> + </el-table-column> + <el-table-column prop="date" width="180"></el-table-column> + <el-table-column width="120"> + <template #default="scope"> + <el-button type="danger" size="small" @click="handleDel(scope.$index)">删除</el-button> + </template> + </el-table-column> + </el-table> + <div class="handle-row"> + <el-button type="danger">删除全部</el-button> + </div> + </template> + </el-tab-pane> + <el-tab-pane :label="`回收站(${state.recycle.length})`" name="third"> + <template v-if="message === 'third'"> + <el-table :data="state.recycle" :show-header="false" style="width: 100%"> + <el-table-column> + <template #default="scope"> + <span class="message-title">{{ scope.row.title }}</span> + </template> + </el-table-column> + <el-table-column prop="date" width="180"></el-table-column> + <el-table-column width="120"> + <template #default="scope"> + <el-button size="small" @click="handleRestore(scope.$index)">还原</el-button> + </template> + </el-table-column> + </el-table> + <div class="handle-row"> + <el-button type="danger">清空回收站</el-button> + </div> + </template> + </el-tab-pane> + </el-tabs> +</template> + +<script setup lang="ts" name="tabs"> +import { ref, reactive } from 'vue'; + +const message = ref('first'); +const state = reactive({ + unread: [ + { + date: '2018-04-19 20:00:00', + title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' + }, + { + date: '2018-04-19 21:00:00', + title: '今晚12点整发大红包,先到先得' + } + ], + read: [ + { + date: '2018-04-19 20:00:00', + title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' + } + ], + recycle: [ + { + date: '2018-04-19 20:00:00', + title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' + } + ] +}); + +const handleRead = (index: number) => { + const item = state.unread.splice(index, 1); + state.read = item.concat(state.read); +}; +const handleDel = (index: number) => { + const item = state.read.splice(index, 1); + state.recycle = item.concat(state.recycle); +}; +const handleRestore = (index: number) => { + const item = state.recycle.splice(index, 1); + state.read = item.concat(state.read); +}; +</script> + +<style> +.message-title { + cursor: pointer; + color: var(--el-color-primary); +} + +.handle-row { + margin-top: 30px; +} +</style> diff --git a/src/views/element/tour.vue b/src/views/element/tour.vue new file mode 100644 index 00000000..027f5079 --- /dev/null +++ b/src/views/element/tour.vue @@ -0,0 +1,33 @@ +<template> + <div class="container"> + <el-button type="primary" @click="open = true">开始引导</el-button> + + <el-divider /> + + <el-space> + <el-button ref="ref1">上传</el-button> + <el-button ref="ref2" type="primary">保存</el-button> + <el-button ref="ref3" :icon="MoreFilled" /> + </el-space> + + <el-tour v-model="open"> + <el-tour-step :target="ref1?.$el" title="上传文件"> + <img style="width: 120px" src="../../assets/img/img.jpg" alt="tour.png" /> + <div>点击这里选择文件</div> + </el-tour-step> + <el-tour-step :target="ref2?.$el" title="保存" description="点击进行上传" /> + <el-tour-step :target="ref3?.$el" title="更多操作" description="点击查看更多操作" /> + </el-tour> + </div> +</template> + +<script setup lang="ts"> +import { ref } from 'vue' +import { MoreFilled } from '@element-plus/icons-vue' + +const ref1 = ref() +const ref2 = ref() +const ref3 = ref() + +const open = ref(false) +</script> \ No newline at end of file diff --git a/src/views/upload.vue b/src/views/element/upload.vue similarity index 67% rename from src/views/upload.vue rename to src/views/element/upload.vue index 960edc3f..146b2414 100644 --- a/src/views/upload.vue +++ b/src/views/element/upload.vue @@ -1,48 +1,44 @@ -<template> - <div class="container"> - <div class="content-title">支持拖拽</div> - <div class="plugins-tips"> - Element Plus自带上传组件。 访问地址: - <a href="https://element-plus.org/zh-CN/component/upload.html" target="_blank">Element Plus Upload</a> - </div> - <el-upload - class="upload-demo" - drag - action="http://jsonplaceholder.typicode.com/api/posts/" - multiple - :on-change="handle" - > - <el-icon class="el-icon--upload"><upload-filled /></el-icon> - <div class="el-upload__text"> - 将文件拖到此处,或 - <em>点击上传</em> - </div> - </el-upload> - - <div class="content-title">支持裁剪</div> - <div class="plugins-tips"> - vue-cropperjs:一个封装了 cropperjs 的 Vue 组件。 访问地址: - <a href="https://github.com/Agontuk/vue-cropperjs" target="_blank">vue-cropperjs</a>。 示例请查看 - <router-link to="/user">个人中心</router-link> - </div> - </div> -</template> - -<script setup lang="ts"> -const handle = (rawFile: any) => { - console.log(rawFile); -}; -</script> - -<style scoped> -.content-title { - font-weight: 400; - line-height: 50px; - margin: 10px 0; - font-size: 22px; - color: #1f2f3d; -} -.upload-demo { - width: 360px; -} -</style> +<template> + <div class="container"> + <div class="content-title">支持拖拽</div> + <div class="plugins-tips"> + Element Plus自带上传组件。 访问地址: + <a href="https://element-plus.org/zh-CN/component/upload.html" target="_blank">Element Plus Upload</a> + </div> + <el-upload class="upload-demo" drag action="http://jsonplaceholder.typicode.com/api/posts/" multiple + :on-change="handle"> + <el-icon class="el-icon--upload"><upload-filled /></el-icon> + <div class="el-upload__text"> + 将文件拖到此处,或 + <em>点击上传</em> + </div> + </el-upload> + + <div class="content-title">支持裁剪</div> + <div class="plugins-tips"> + vue-cropper:一个简单的vue图片裁剪插件。 访问地址: + <a href="https://github.com/xyxiao001/vue-cropper" target="_blank">vue-cropper</a>。 示例请查看 + <router-link to="/ucenter">个人中心-我的头像</router-link> + </div> + </div> +</template> + +<script setup lang="ts"> +const handle = (rawFile: any) => { + console.log(rawFile); +}; +</script> + +<style scoped> +.content-title { + font-weight: 400; + line-height: 50px; + margin: 10px 0; + font-size: 22px; + color: #1f2f3d; +} + +.upload-demo { + width: 360px; +} +</style> diff --git a/src/views/element/watermark.vue b/src/views/element/watermark.vue new file mode 100644 index 00000000..a381128e --- /dev/null +++ b/src/views/element/watermark.vue @@ -0,0 +1,62 @@ +<template> + <div class="container"> + <el-row :gutter="20"> + <el-col :span="18"> + <el-watermark :content="config.content" :font="config.font" :z-index="config.zIndex" + :rotate="config.rotate" :gap="config.gap" :offset="config.offset"> + <div style="height: 600px" /> + </el-watermark> + </el-col> + <el-col :span="6"> + <el-form class="form" :model="config" label-position="top" label-width="50px"> + <el-form-item label="Content"> + <el-input v-model="config.content" /> + </el-form-item> + <el-form-item label="Color"> + <el-color-picker v-model="config.font.color" show-alpha /> + </el-form-item> + <el-form-item label="FontSize"> + <el-slider v-model="config.font.fontSize" /> + </el-form-item> + <el-form-item label="zIndex"> + <el-slider v-model="config.zIndex" /> + </el-form-item> + <el-form-item label="Rotate"> + <el-slider v-model="config.rotate" :min="-180" :max="180" /> + </el-form-item> + <el-form-item label="Gap"> + <el-space> + <el-input-number v-model="config.gap[0]" controls-position="right" /> + <el-input-number v-model="config.gap[1]" controls-position="right" /> + </el-space> + </el-form-item> + <el-form-item label="Offset"> + <el-space> + <el-input-number v-model="config.offset[0]" placeholder="offsetLeft" + controls-position="right" /> + <el-input-number v-model="config.offset[1]" placeholder="offsetTop" + controls-position="right" /> + </el-space> + </el-form-item> + </el-form> + </el-col> + </el-row> + + </div> +</template> + +<script setup lang="ts"> +import { reactive } from 'vue' + +const config = reactive({ + content: 'vue-manage-system', + font: { + fontSize: 16, + color: 'rgba(0, 0, 0, 0.15)', + }, + zIndex: -1, + rotate: -22, + gap: [100, 100] as [number, number], + offset: [] as unknown as [number, number], +}) +</script> \ No newline at end of file diff --git a/src/views/form.vue b/src/views/form.vue deleted file mode 100644 index 75609aeb..00000000 --- a/src/views/form.vue +++ /dev/null @@ -1,156 +0,0 @@ -<template> - <div class="container"> - <div class="form-box"> - <el-form ref="formRef" :rules="rules" :model="form" label-width="80px"> - <el-form-item label="表单名称" prop="name"> - <el-input v-model="form.name"></el-input> - </el-form-item> - <el-form-item label="选择器" prop="region"> - <el-select v-model="form.region" placeholder="请选择"> - <el-option key="小明" label="小明" value="小明"></el-option> - <el-option key="小红" label="小红" value="小红"></el-option> - <el-option key="小白" label="小白" value="小白"></el-option> - </el-select> - </el-form-item> - <el-form-item label="日期时间"> - <el-col :span="11"> - <el-form-item prop="date1"> - <el-date-picker - type="date" - placeholder="选择日期" - v-model="form.date1" - style="width: 100%" - ></el-date-picker> - </el-form-item> - </el-col> - <el-col class="line" :span="2">-</el-col> - <el-col :span="11"> - <el-form-item prop="date2"> - <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%"> - </el-time-picker> - </el-form-item> - </el-col> - </el-form-item> - <el-form-item label="城市级联" prop="options"> - <el-cascader :options="options" v-model="form.options"></el-cascader> - </el-form-item> - <el-form-item label="选择开关" prop="delivery"> - <el-switch v-model="form.delivery"></el-switch> - </el-form-item> - <el-form-item label="多选框" prop="type"> - <el-checkbox-group v-model="form.type"> - <el-checkbox label="小明" name="type"></el-checkbox> - <el-checkbox label="小红" name="type"></el-checkbox> - <el-checkbox label="小白" name="type"></el-checkbox> - </el-checkbox-group> - </el-form-item> - <el-form-item label="单选框" prop="resource"> - <el-radio-group v-model="form.resource"> - <el-radio label="小明"></el-radio> - <el-radio label="小红"></el-radio> - <el-radio label="小白"></el-radio> - </el-radio-group> - </el-form-item> - <el-form-item label="文本框" prop="desc"> - <el-input type="textarea" rows="5" v-model="form.desc"></el-input> - </el-form-item> - <el-form-item> - <el-button type="primary" @click="onSubmit(formRef)">表单提交</el-button> - <el-button @click="onReset(formRef)">重置表单</el-button> - </el-form-item> - </el-form> - </div> - </div> -</template> - -<script setup lang="ts" name="baseform"> -import { reactive, ref } from 'vue'; -import { ElMessage } from 'element-plus'; -import type { FormInstance, FormRules } from 'element-plus'; - -const options = [ - { - value: 'guangdong', - label: '广东省', - children: [ - { - value: 'guangzhou', - label: '广州市', - children: [ - { - value: 'tianhe', - label: '天河区', - }, - { - value: 'haizhu', - label: '海珠区', - }, - ], - }, - { - value: 'dongguan', - label: '东莞市', - children: [ - { - value: 'changan', - label: '长安镇', - }, - { - value: 'humen', - label: '虎门镇', - }, - ], - }, - ], - }, - { - value: 'hunan', - label: '湖南省', - children: [ - { - value: 'changsha', - label: '长沙市', - children: [ - { - value: 'yuelu', - label: '岳麓区', - }, - ], - }, - ], - }, -]; -const rules: FormRules = { - name: [{ required: true, message: '请输入表单名称', trigger: 'blur' }], -}; -const formRef = ref<FormInstance>(); -const form = reactive({ - name: '', - region: '', - date1: '', - date2: '', - delivery: true, - type: ['小明'], - resource: '小红', - desc: '', - options: [], -}); -// 提交 -const onSubmit = (formEl: FormInstance | undefined) => { - // 表单校验 - if (!formEl) return; - formEl.validate((valid) => { - if (valid) { - console.log(form); - ElMessage.success('提交成功!'); - } else { - return false; - } - }); -}; -// 重置 -const onReset = (formEl: FormInstance | undefined) => { - if (!formEl) return; - formEl.resetFields(); -}; -</script> diff --git a/src/views/home.vue b/src/views/home.vue index e8ba189a..bb8e7e17 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -1,26 +1,56 @@ -<template> - <v-header /> - <v-sidebar /> - <div class="content-box" :class="{ 'content-collapse': sidebar.collapse }"> - <v-tags></v-tags> - <div class="content"> - <router-view v-slot="{ Component }"> - <transition name="move" mode="out-in"> - <keep-alive :include="tags.nameList"> - <component :is="Component"></component> - </keep-alive> - </transition> - </router-view> - </div> - </div> -</template> -<script setup lang="ts"> -import { useSidebarStore } from '../store/sidebar'; -import { useTagsStore } from '../store/tags'; -import vHeader from '../components/header.vue'; -import vSidebar from '../components/sidebar.vue'; -import vTags from '../components/tags.vue'; - -const sidebar = useSidebarStore(); -const tags = useTagsStore(); -</script> +<template> + <v-header /> + <v-sidebar /> + <div class="content-box" :class="{ 'content-collapse': sidebar.collapse }"> + <v-tabs></v-tabs> + <div class="content"> + <router-view v-slot="{ Component }"> + <transition name="move" mode="out-in"> + <keep-alive :include="tabs.nameList"> + <component :is="Component"></component> + </keep-alive> + </transition> + </router-view> + </div> + </div> +</template> +<script setup lang="ts"> +import { useSidebarStore } from '@/store/sidebar'; +import { useTabsStore } from '@/store/tabs'; +import vHeader from '@/components/header.vue'; +import vSidebar from '@/components/sidebar.vue'; +import vTabs from '@/components/tabs.vue'; + +const sidebar = useSidebarStore(); +const tabs = useTabsStore(); +</script> + +<style> +.content-box { + position: absolute; + left: 250px; + right: 0; + top: 70px; + bottom: 0; + padding-bottom: 30px; + -webkit-transition: left 0.3s ease-in-out; + transition: left 0.3s ease-in-out; + background: #eef0fc; +} + +.content { + width: auto; + height: 100%; + padding: 20px; + overflow-y: scroll; + box-sizing: border-box; +} + +.content::-webkit-scrollbar { + width: 0; +} + +.content-collapse { + left: 65px; +} +</style> \ No newline at end of file diff --git a/src/views/pages/403.vue b/src/views/pages/403.vue new file mode 100644 index 00000000..eacb8926 --- /dev/null +++ b/src/views/pages/403.vue @@ -0,0 +1,67 @@ +<template> + <div class="error-page"> + <div class="error-box"> + <div class="error-code">403</div> + <div class="error-desc">啊哦~ 你没有权限访问该页面哦</div> + <div class="error-handle"> + <router-link to="/"> + <el-button type="primary" size="large">返回首页</el-button> + </router-link> + <el-button class="error-btn" size="large" @click="goBack">返回上一页</el-button> + </div> + </div> + </div> +</template> + +<script setup lang="ts" name="403"> +import { useRouter } from 'vue-router'; + +const router = useRouter(); +const goBack = () => { + router.go(-2); +}; +</script> + +<style scoped> +.error-page { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + width: 100%; + height: 100%; + background: #eef0fc; + box-sizing: border-box; +} + +.error-box { + width: 400px; + background-color: #fff; + padding: 80px 50px; + border-radius: 5px; +} + +.error-code { + line-height: 1; + font-size: 100px; + font-weight: bold; + color: var(--el-color-primary); + margin-bottom: 20px; + text-align: center +} + +.error-desc { + font-size: 20px; + color: #777; + text-align: center +} + +.error-handle { + margin-top: 50px; + text-align: center; +} + +.error-btn { + margin-left: 100px; +} +</style> diff --git a/src/views/pages/404.vue b/src/views/pages/404.vue new file mode 100644 index 00000000..31bae0df --- /dev/null +++ b/src/views/pages/404.vue @@ -0,0 +1,67 @@ +<template> + <div class="error-page"> + <div class="error-box"> + <div class="error-code">404</div> + <div class="error-desc">啊哦~ 你所访问的页面不存在</div> + <div class="error-handle"> + <router-link to="/"> + <el-button type="primary" size="large">返回首页</el-button> + </router-link> + <el-button class="error-btn" size="large" @click="goBack">返回上一页</el-button> + </div> + </div> + </div> +</template> + +<script setup lang="ts" name="404"> +import { useRouter } from 'vue-router'; + +const router = useRouter(); +const goBack = () => { + router.go(-1); +}; +</script> + +<style scoped> +.error-page { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + width: 100%; + height: 100%; + background: #eef0fc; + box-sizing: border-box; +} + +.error-box { + width: 400px; + background-color: #fff; + padding: 80px 50px; + border-radius: 5px; +} + +.error-code { + line-height: 1; + font-size: 100px; + font-weight: bold; + color: var(--el-color-primary); + margin-bottom: 20px; + text-align: center +} + +.error-desc { + font-size: 20px; + color: #777; + text-align: center +} + +.error-handle { + margin-top: 50px; + text-align: center; +} + +.error-btn { + margin-left: 100px; +} +</style> diff --git a/src/views/editor.vue b/src/views/pages/editor.vue similarity index 100% rename from src/views/editor.vue rename to src/views/pages/editor.vue diff --git a/src/views/icon.vue b/src/views/pages/icon.vue similarity index 51% rename from src/views/icon.vue rename to src/views/pages/icon.vue index 0b01ff3d..c08d8c4b 100644 --- a/src/views/icon.vue +++ b/src/views/pages/icon.vue @@ -1,212 +1,257 @@ -<template> - <div class="container"> - <h2>使用方法</h2> - <p style="line-height: 50px"> - 直接通过设置类名为 el-icon-lx-iconName 来使用即可。例如:(共{{ iconList.length }}个图标) - </p> - <p class="example-p"> - <i class="el-icon-lx-redpacket_fill" style="font-size: 30px; color: #ff5900"></i> - <span><i class="el-icon-lx-redpacket_fill"></i></span> - </p> - <p class="example-p"> - <i class="el-icon-lx-weibo" style="font-size: 30px; color: #fd5656"></i> - <span><i class="el-icon-lx-weibo"></i></span> - </p> - <p class="example-p"> - <i class="el-icon-lx-emojifill" style="font-size: 30px; color: #ffc300"></i> - <span><i class="el-icon-lx-emojifill"></i></span> - </p> - <br /> - <h2>图标</h2> - <div class="search-box"> - <el-input class="search" size="large" v-model="keyword" clearable placeholder="请输入图标名称"></el-input> - </div> - <ul> - <li class="icon-li" v-for="(item, index) in list" :key="index"> - <div class="icon-li-content"> - <i :class="`el-icon-lx-${item}`"></i> - <span>{{ item }}</span> - </div> - </li> - </ul> - </div> -</template> - -<script setup lang="ts" name="icon"> -import { computed, ref } from 'vue'; - -const iconList: Array<string> = [ - 'attentionforbid', - 'attentionforbidfill', - 'attention', - 'attentionfill', - 'tag', - 'tagfill', - 'people', - 'peoplefill', - 'notice', - 'noticefill', - 'mobile', - 'mobilefill', - 'voice', - 'voicefill', - 'unlock', - 'lock', - 'home', - 'homefill', - 'delete', - 'deletefill', - 'notification', - 'notificationfill', - 'notificationforbidfill', - 'like', - 'likefill', - 'comment', - 'commentfill', - 'camera', - 'camerafill', - 'warn', - 'warnfill', - 'time', - 'timefill', - 'location', - 'locationfill', - 'favor', - 'favorfill', - 'skin', - 'skinfill', - 'news', - 'newsfill', - 'record', - 'recordfill', - 'emoji', - 'emojifill', - 'message', - 'messagefill', - 'goods', - 'goodsfill', - 'crown', - 'crownfill', - 'move', - 'add', - 'hot', - 'hotfill', - 'service', - 'servicefill', - 'present', - 'presentfill', - 'pic', - 'picfill', - 'rank', - 'rankfill', - 'male', - 'female', - 'down', - 'top', - 'recharge', - 'rechargefill', - 'forward', - 'forwardfill', - 'info', - 'infofill', - 'redpacket', - 'redpacket_fill', - 'roundadd', - 'roundaddfill', - 'friendadd', - 'friendaddfill', - 'cart', - 'cartfill', - 'more', - 'moreandroid', - 'back', - 'right', - 'shop', - 'shopfill', - 'question', - 'questionfill', - 'roundclose', - 'roundclosefill', - 'roundcheck', - 'roundcheckfill', - 'global', - 'mail', - 'punch', - 'exit', - 'upload', - 'read', - 'file', - 'link', - 'full', - 'group', - 'friend', - 'profile', - 'addressbook', - 'calendar', - 'text', - 'copy', - 'share', - 'wifi', - 'vipcard', - 'weibo', - 'remind', - 'refresh', - 'filter', - 'settings', - 'scan', - 'qrcode', - 'cascades', - 'apps', - 'sort', - 'searchlist', - 'search', - 'edit' -]; -const keyword = ref(''); -const list = computed(() => { - return iconList.filter(item => { - return item.indexOf(keyword.value) !== -1; - }); -}); -</script> - -<style scoped> -.example-p { - height: 45px; - display: flex; - align-items: center; -} -.search-box { - text-align: center; - margin-top: 10px; -} -.search { - width: 300px; -} -ul, -li { - list-style: none; -} -.icon-li { - display: inline-block; - padding: 10px; - width: 120px; - height: 120px; -} -.icon-li-content { - display: flex; - height: 100%; - flex-direction: column; - align-items: center; - justify-content: center; - cursor: pointer; -} -.icon-li-content i { - font-size: 36px; - color: #606266; -} -.icon-li-content span { - margin-top: 10px; - color: #787878; -} -</style> +<template> + + <el-tabs type="border-card"> + <el-tab-pane label="自定义图标"> + <h2>使用方法</h2> + <p style="line-height: 50px"> + 直接通过设置类名为 el-icon-lx-iconName 来使用即可。例如:(共{{ iconList.length }}个图标) + </p> + <p class="example-p"> + <i class="el-icon-lx-redpacket_fill" style="font-size: 30px; color: #ff5900"></i> + <span><i class="el-icon-lx-redpacket_fill"></i></span> + </p> + <p class="example-p"> + <i class="el-icon-lx-weibo" style="font-size: 30px; color: #fd5656"></i> + <span><i class="el-icon-lx-weibo"></i></span> + </p> + <p class="example-p"> + <i class="el-icon-lx-emojifill" style="font-size: 30px; color: #ffc300"></i> + <span><i class="el-icon-lx-emojifill"></i></span> + </p> + <br /> + <h2>图标</h2> + <div class="search-box"> + <el-input class="search" size="large" v-model="keyword" clearable placeholder="请输入图标名称"></el-input> + </div> + <ul> + <li class="icon-li" v-for="(item, index) in list" :key="index"> + <div class="icon-li-content"> + <i :class="`el-icon-lx-${item}`"></i> + <span>{{ item }}</span> + </div> + </li> + </ul> + </el-tab-pane> + <el-tab-pane label="Element图标"> + <el-link type="primary" href="https://element-plus.org/zh-CN/component/icon.html#icon-collection" + target="_blank">前往官方文档查看</el-link> + </el-tab-pane> + </el-tabs> +</template> + +<script setup lang="ts" name="icon"> +import { computed, ref } from 'vue'; + +const iconList: Array<string> = [ + 'attentionforbid', + 'attentionforbidfill', + 'attention', + 'attentionfill', + 'tag', + 'tagfill', + 'people', + 'peoplefill', + 'notice', + 'noticefill', + 'mobile', + 'mobilefill', + 'voice', + 'voicefill', + 'unlock', + 'lock', + 'home', + 'homefill', + 'delete', + 'deletefill', + 'notification', + 'notificationfill', + 'notificationforbidfill', + 'like', + 'likefill', + 'comment', + 'commentfill', + 'camera', + 'camerafill', + 'warn', + 'warnfill', + 'time', + 'timefill', + 'location', + 'locationfill', + 'favor', + 'favorfill', + 'skin', + 'skinfill', + 'news', + 'newsfill', + 'record', + 'recordfill', + 'emoji', + 'emojifill', + 'message', + 'messagefill', + 'goods', + 'goodsfill', + 'crown', + 'crownfill', + 'move', + 'add', + 'hot', + 'hotfill', + 'service', + 'servicefill', + 'present', + 'presentfill', + 'pic', + 'picfill', + 'rank', + 'rankfill', + 'male', + 'female', + 'down', + 'top', + 'recharge', + 'rechargefill', + 'forward', + 'forwardfill', + 'info', + 'infofill', + 'redpacket', + 'redpacket_fill', + 'roundadd', + 'roundaddfill', + 'friendadd', + 'friendaddfill', + 'cart', + 'cartfill', + 'more', + 'moreandroid', + 'back', + 'right', + 'shop', + 'shopfill', + 'question', + 'questionfill', + 'roundclose', + 'roundclosefill', + 'roundcheck', + 'roundcheckfill', + 'global', + 'mail', + 'punch', + 'exit', + 'upload', + 'read', + 'file', + 'link', + 'full', + 'group', + 'friend', + 'profile', + 'addressbook', + 'calendar', + 'text', + 'copy', + 'share', + 'wifi', + 'vipcard', + 'weibo', + 'remind', + 'refresh', + 'filter', + 'settings', + 'scan', + 'qrcode', + 'cascades', + 'apps', + 'sort', + 'searchlist', + 'search', + 'edit', + 'apple-line', + 'baidu-fill', + 'amazon-fill', + 'netease-cloud-music-fill', + 'qq-line', + 'wechat-fill', + 'alipay-fill', + 'android-fill', + 'android-line', + 'whatsapp-line', + 'whatsapp-fill', + 'bilibili-fill', + 'chrome-fill', + 'dingding-fill', + 'dingding-line', + 'apple-fill', + 'github-fill', + 'qq-fill', + 'wechat-pay-fill', + 'windows-line', + 'windows-fill', + 'youtube-line', + 'youtube-fill', + 'wechat-pay-line', + 'zhihu-line' +]; + +const keyword = ref(''); +const list = computed(() => { + return iconList.filter(item => { + return item.indexOf(keyword.value) !== -1; + }); +}); +</script> + +<style scoped> +.example-p { + height: 45px; + display: flex; + align-items: center; +} + +.search-box { + text-align: center; + margin-top: 10px; +} + +.search { + width: 300px; +} + +ul, +li { + list-style: none; +} + +.icon-li { + display: inline-block; + padding: 10px; + width: 120px; + height: 120px; +} + +.icon-li-content { + display: flex; + height: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.icon-li-content i { + font-size: 36px; + color: #606266; +} + +.icon-li-content span { + margin-top: 10px; + color: #787878; +} + +.iframe { + width: 100%; + height: 700px; +} +</style> diff --git a/src/views/login.vue b/src/views/pages/login.vue similarity index 56% rename from src/views/login.vue rename to src/views/pages/login.vue index 38a0b4ea..16ef0472 100644 --- a/src/views/login.vue +++ b/src/views/pages/login.vue @@ -1,136 +1,172 @@ -<template> - <div class="login-wrap"> - <div class="ms-login"> - <div class="ms-title">后台管理系统</div> - <el-form :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content"> - <el-form-item prop="username"> - <el-input v-model="param.username" placeholder="username"> - <template #prepend> - <el-button :icon="User"></el-button> - </template> - </el-input> - </el-form-item> - <el-form-item prop="password"> - <el-input - type="password" - placeholder="password" - v-model="param.password" - @keyup.enter="submitForm(login)" - > - <template #prepend> - <el-button :icon="Lock"></el-button> - </template> - </el-input> - </el-form-item> - <div class="login-btn"> - <el-button type="primary" @click="submitForm(login)">登录</el-button> - </div> - <el-checkbox class="login-tips" v-model="checked" label="记住密码" size="large" /> - <p class="login-tips">Tips : 用户名和密码随便填。</p> - </el-form> - </div> - </div> -</template> - -<script setup lang="ts"> -import { ref, reactive } from 'vue'; -import { useTagsStore } from '../store/tags'; -import { usePermissStore } from '../store/permiss'; -import { useRouter } from 'vue-router'; -import { ElMessage } from 'element-plus'; -import type { FormInstance, FormRules } from 'element-plus'; -import { Lock, User } from '@element-plus/icons-vue'; - -interface LoginInfo { - username: string; - password: string; -} - -const lgStr = localStorage.getItem('login-param'); -const defParam = lgStr ? JSON.parse(lgStr) : null; -const checked = ref(lgStr ? true : false); - -const router = useRouter(); -const param = reactive<LoginInfo>({ - username: defParam ? defParam.username : '', - password: defParam ? defParam.password : '', -}); - -const rules: FormRules = { - username: [ - { - required: true, - message: '请输入用户名', - trigger: 'blur', - }, - ], - password: [{ required: true, message: '请输入密码', trigger: 'blur' }], -}; -const permiss = usePermissStore(); -const login = ref<FormInstance>(); -const submitForm = (formEl: FormInstance | undefined) => { - if (!formEl) return; - formEl.validate((valid: boolean) => { - if (valid) { - ElMessage.success('登录成功'); - localStorage.setItem('ms_username', param.username); - const keys = permiss.defaultList[param.username == 'admin' ? 'admin' : 'user']; - permiss.handleSet(keys); - localStorage.setItem('ms_keys', JSON.stringify(keys)); - router.push('/'); - if (checked.value) { - localStorage.setItem('login-param', JSON.stringify(param)); - } else { - localStorage.removeItem('login-param'); - } - } else { - ElMessage.error('登录失败'); - return false; - } - }); -}; - -const tags = useTagsStore(); -tags.clearTags(); -</script> - -<style scoped> -.login-wrap { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - background-image: url(../assets/img/login-bg.jpg); - background-size: 100%; -} -.ms-title { - line-height: 50px; - text-align: center; - font-size: 20px; - color: #333; - font-weight: bold; - padding-top: 10px; -} -.ms-login { - width: 350px; - border-radius: 5px; - background: #fff; -} -.ms-content { - padding: 10px 30px 30px; -} -.login-btn { - text-align: center; -} -.login-btn button { - width: 100%; - height: 36px; - margin-bottom: 10px; -} -.login-tips { - font-size: 12px; - line-height: 30px; - color: #333; -} -</style> +<template> + <div class="login-bg"> + <div class="login-container"> + <div class="login-header"> + <img class="logo mr10" src="../../assets/img/logo.svg" alt="" /> + <div class="login-title">后台管理系统</div> + </div> + <el-form :model="param" :rules="rules" ref="login" size="large"> + <el-form-item prop="username"> + <el-input v-model="param.username" placeholder="用户名"> + <template #prepend> + <el-icon> + <User /> + </el-icon> + </template> + </el-input> + </el-form-item> + <el-form-item prop="password"> + <el-input + type="password" + placeholder="密码" + v-model="param.password" + @keyup.enter="submitForm(login)" + > + <template #prepend> + <el-icon> + <Lock /> + </el-icon> + </template> + </el-input> + </el-form-item> + <div class="pwd-tips"> + <el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" /> + <el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link> + </div> + <el-button class="login-btn" type="primary" size="large" @click="submitForm(login)">登录</el-button> + <p class="login-tips">Tips : 用户名和密码随便填。</p> + <p class="login-text"> + 没有账号?<el-link type="primary" @click="$router.push('/register')">立即注册</el-link> + </p> + </el-form> + </div> + </div> +</template> + +<script setup lang="ts"> +import { ref, reactive } from 'vue'; +import { useTabsStore } from '@/store/tabs'; +import { usePermissStore } from '@/store/permiss'; +import { useRouter } from 'vue-router'; +import { ElMessage } from 'element-plus'; +import type { FormInstance, FormRules } from 'element-plus'; + +interface LoginInfo { + username: string; + password: string; +} + +const lgStr = localStorage.getItem('login-param'); +const defParam = lgStr ? JSON.parse(lgStr) : null; +const checked = ref(lgStr ? true : false); + +const router = useRouter(); +const param = reactive<LoginInfo>({ + username: defParam ? defParam.username : '', + password: defParam ? defParam.password : '', +}); + +const rules: FormRules = { + username: [ + { + required: true, + message: '请输入用户名', + trigger: 'blur', + }, + ], + password: [{ required: true, message: '请输入密码', trigger: 'blur' }], +}; +const permiss = usePermissStore(); +const login = ref<FormInstance>(); +const submitForm = (formEl: FormInstance | undefined) => { + if (!formEl) return; + formEl.validate((valid: boolean) => { + if (valid) { + ElMessage.success('登录成功'); + localStorage.setItem('ms_username', param.username); + const keys = permiss.defaultList[param.username == 'admin' ? 'admin' : 'user']; + permiss.handleSet(keys); + localStorage.setItem('ms_keys', JSON.stringify(keys)); + router.push('/'); + if (checked.value) { + localStorage.setItem('login-param', JSON.stringify(param)); + } else { + localStorage.removeItem('login-param'); + } + } else { + ElMessage.error('登录失败'); + return false; + } + }); +}; + +const tabs = useTabsStore(); +tabs.clearTabs(); +</script> + +<style scoped> +.login-bg { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + background: url(../../assets/img/login-bg.jpg) center/cover no-repeat; +} + +.login-header { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 40px; +} + +.logo { + width: 35px; +} + +.login-title { + font-size: 22px; + color: #333; + font-weight: bold; +} + +.login-container { + width: 450px; + border-radius: 5px; + background: #fff; + padding: 40px 50px 50px; + box-sizing: border-box; +} + +.pwd-tips { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 14px; + margin: -10px 0 10px; + color: #787878; +} + +.pwd-checkbox { + height: auto; +} + +.login-btn { + display: block; + width: 100%; +} + +.login-tips { + font-size: 12px; + color: #999; +} + +.login-text { + display: flex; + align-items: center; + margin-top: 20px; + font-size: 14px; + color: #787878; +} +</style> diff --git a/src/views/markdown.vue b/src/views/pages/markdown.vue similarity index 96% rename from src/views/markdown.vue rename to src/views/pages/markdown.vue index d435f9ca..286b679d 100644 --- a/src/views/markdown.vue +++ b/src/views/pages/markdown.vue @@ -1,21 +1,21 @@ -<template> - <div class="container"> - <div class="plugins-tips"> - md-editor-v3:vue3版本的 markdown 编辑器,配置丰富,请详看文档。 访问地址: - <a href="https://imzbf.github.io/md-editor-v3/index" target="_blank">md-editor-v3</a> - </div> - <md-editor class="mgb20" v-model="text" @on-upload-img="onUploadImg" /> - <el-button type="primary">提交</el-button> - </div> -</template> - -<script setup lang="ts" name="md"> -import { ref } from 'vue'; -import MdEditor from 'md-editor-v3'; -import 'md-editor-v3/lib/style.css'; - -const text = ref('Hello Editor!'); -const onUploadImg = (files: any) => { - console.log(files); -}; -</script> +<template> + <div class="container"> + <div class="plugins-tips"> + md-editor-v3:vue3版本的 markdown 编辑器,配置丰富,请详看文档。 访问地址: + <a href="https://imzbf.github.io/md-editor-v3/index" target="_blank">md-editor-v3</a> + </div> + <md-editor class="mgb20" v-model="text" @on-upload-img="onUploadImg" /> + <el-button type="primary">提交</el-button> + </div> +</template> + +<script setup lang="ts" name="md"> +import { ref } from 'vue'; +import MdEditor from 'md-editor-v3'; +import 'md-editor-v3/lib/style.css'; + +const text = ref('Hello Editor!'); +const onUploadImg = (files: any) => { + console.log(files); +}; +</script> diff --git a/src/views/pages/register.vue b/src/views/pages/register.vue new file mode 100644 index 00000000..c3cdec01 --- /dev/null +++ b/src/views/pages/register.vue @@ -0,0 +1,132 @@ +<template> + <div class="login-bg"> + <div class="login-container"> + <div class="login-header"> + <img class="logo mr10" src="../../assets/img/logo.svg" alt=""> + <div class="login-title"> + 后台管理系统 + </div> + </div> + <el-form :model="param" :rules="rules" ref="register" size="large"> + <el-form-item prop="username"> + <el-input v-model="param.username" placeholder="用户名"> + <template #prepend> + <el-icon> + <User /> + </el-icon> + </template> + </el-input> + </el-form-item> + <el-form-item prop="email"> + <el-input v-model="param.email" placeholder="邮箱"> + <template #prepend> + <el-icon> + <Message /> + </el-icon> + </template> + </el-input> + </el-form-item> + <el-form-item prop="password"> + <el-input type="password" placeholder="密码" v-model="param.password" + @keyup.enter="submitForm(register)"> + <template #prepend> + <el-icon> + <Lock /> + </el-icon> + </template> + </el-input> + </el-form-item> + <el-button class="login-btn" type="primary" size="large" @click="submitForm(register)">注册</el-button> + <p class="login-text">已有账号,<el-link type="primary" @click="$router.push('/login')">立即登录</el-link></p> + </el-form> + </div> + </div> +</template> + +<script setup lang="ts"> +import { ref, reactive } from 'vue'; +import { useRouter } from 'vue-router'; +import { ElMessage, type FormInstance, type FormRules } from 'element-plus'; +import { Register } from '@/types/user'; + +const router = useRouter(); +const param = reactive<Register>({ + username: '', + password: '', + email: '', +}); + +const rules: FormRules = { + username: [ + { + required: true, + message: '请输入用户名', + trigger: 'blur', + }, + ], + password: [{ required: true, message: '请输入密码', trigger: 'blur' }], + email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }], +}; +const register = ref<FormInstance>(); +const submitForm = (formEl: FormInstance | undefined) => { + if (!formEl) return; + formEl.validate((valid: boolean) => { + if (valid) { + ElMessage.success('注册成功,请登录'); + router.push('/login'); + } else { + return false; + } + }); +}; + +</script> + +<style scoped> +.login-bg { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + background: url(../../assets/img/login-bg.jpg) center/cover no-repeat; +} + +.login-header { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 40px; +} + +.logo { + width: 35px; +} + +.login-title { + font-size: 22px; + color: #333; + font-weight: bold; +} + +.login-container { + width: 450px; + border-radius: 5px; + background: #fff; + padding: 40px 50px 50px; + box-sizing: border-box; +} + +.login-btn { + display: block; + width: 100%; +} + +.login-text { + display: flex; + align-items: center; + margin-top: 20px; + font-size: 14px; + color: #787878; +} +</style> diff --git a/src/views/pages/reset-pwd.vue b/src/views/pages/reset-pwd.vue new file mode 100644 index 00000000..e042b93d --- /dev/null +++ b/src/views/pages/reset-pwd.vue @@ -0,0 +1,97 @@ +<template> + <div class="login-bg"> + <div class="login-container"> + <div class="reset-title">重置密码</div> + <p class="reset-text">输入你的邮箱,我们将发送重置密码邮件</p> + <el-form :model="param" :rules="rules" ref="register" size="large"> + <el-form-item prop="email"> + <el-input v-model="param.email" placeholder="邮箱"> + <template #prepend> + <el-icon> + <Message /> + </el-icon> + </template> + </el-input> + </el-form-item> + <el-button class="login-btn" type="primary" size="large" @click="submitForm(register)">发送邮件</el-button> + <p class="login-text"><el-link type="primary" @click="$router.push('/login')">返回登录</el-link></p> + </el-form> + </div> + </div> +</template> + +<script setup lang="ts"> +import { ref } from 'vue'; +import { ElMessage, type FormInstance, type FormRules } from 'element-plus'; + +const param = ref({ + email: '', +}); + +const rules: FormRules = { + email: [ + { required: true, message: '请输入邮箱', trigger: 'blur' }, + { pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, message: '请输入正确的邮箱格式', trigger: 'blur' } + ], +}; +const register = ref<FormInstance>(); +const submitForm = (formEl: FormInstance | undefined) => { + if (!formEl) return; + formEl.validate((valid: boolean) => { + if (valid) { + ElMessage.success('邮件已发送,请注意查收'); + } else { + return false; + } + }); +}; + +</script> + +<style scoped> +.login-bg { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + background: url(../../assets/img/login-bg.jpg) center/cover no-repeat; +} + +.reset-title { + text-align: center; + font-size: 22px; + color: #333; + font-weight: bold; + margin-bottom: 10px; +} + +.reset-text { + text-align: center; + font-size: 14px; + color: #787878; + margin-bottom: 40px; +} + +.login-container { + width: 450px; + border-radius: 5px; + background: #fff; + padding: 40px 50px 50px; + box-sizing: border-box; +} + +.login-btn { + display: block; + width: 100%; +} + +.login-text { + display: flex; + align-items: center; + justify-content: center; + margin-top: 20px; + font-size: 14px; + color: #333; +} +</style> diff --git a/src/views/pages/theme.vue b/src/views/pages/theme.vue new file mode 100644 index 00000000..b284ddb4 --- /dev/null +++ b/src/views/pages/theme.vue @@ -0,0 +1,205 @@ +<template> + <div> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">系统主题</div> + </template> + <div class="theme-list mgb20"> + <div class="theme-item" @click="setSystemTheme(item)" v-for="item in system" + :style="{ backgroundColor: item.color, color: '#fff' }">{{ item.name }} + </div> + </div> + <div class="flex-center"> + <el-button @click="resetSystemTheme">重置主题</el-button> + </div> + </el-card> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">Element-Plus主题</div> + </template> + <div class="theme-list mgb20"> + <div class="theme-item" v-for="theme in themes"> + <el-button :type="theme.name">{{ theme.name }}</el-button> + <div class="theme-color">{{ theme.color }}</div> + <el-color-picker v-model="color[theme.name]" @change="changeColor(theme.name)" /> + </div> + </div> + <div class="flex-center"> + <el-button @click="resetTheme">重置主题</el-button> + </div> + </el-card> + + <el-row :gutter="50"> + <el-col :span="12"> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">头部主题</div> + </template> + <div class="theme-list mgb20"> + <div class="theme-item"> + <el-button :color="color.headerBgColor">背景颜色</el-button> + <div class="theme-color">{{ color.headerBgColor }}</div> + <el-color-picker v-model="color.headerBgColor" + @change="themeStore.setHeaderBgColor(color.headerBgColor)" /> + </div> + <div class="theme-item"> + <el-button :color="color.headerTextColor">文字颜色</el-button> + <div class="theme-color">{{ color.headerTextColor }}</div> + <el-color-picker v-model="color.headerTextColor" + @change="themeStore.setHeaderTextColor(color.headerTextColor)" /> + </div> + </div> + <div class="flex-center"> + <el-button @click="resetHeader">重置主题</el-button> + </div> + </el-card> + </el-col> + + <el-col :span="12"> + <el-card class="mgb20" shadow="hover"> + <template #header> + <div class="content-title">菜单主题</div> + </template> + <div class="theme-list mgb20"> + <div class="theme-item"> + <el-button :color="sidebar.bgColor">背景颜色</el-button> + <div class="theme-color">{{ sidebar.bgColor }}</div> + <el-color-picker v-model="sidebarColor.bgColor" + @change="sidebar.setBgColor(sidebarColor.bgColor)" /> + </div> + <div class="theme-item"> + <el-button :color="sidebar.textColor">文字颜色</el-button> + <div class="theme-color">{{ sidebar.textColor }}</div> + <el-color-picker v-model="sidebarColor.textColor" + @change="sidebar.setTextColor(sidebarColor.textColor)" /> + </div> + </div> + <div class="flex-center"> + <el-button @click="resetSidebar">重置主题</el-button> + </div> + </el-card> + </el-col> + </el-row> + + </div> +</template> + +<script setup lang="ts"> +import { useSidebarStore } from '@/store/sidebar'; +import { useThemeStore } from '@/store/theme' +import { reactive } from 'vue'; +const themeStore = useThemeStore(); +const sidebar = useSidebarStore(); + +const color = reactive({ + primary: localStorage.getItem('theme-primary') || '#409eff', + success: localStorage.getItem('theme-success') || '#67c23a', + warning: localStorage.getItem('theme-warning') || '#e6a23c', + danger: localStorage.getItem('theme-danger') || '#f56c6c', + info: localStorage.getItem('theme-info') || '#909399', + headerBgColor: themeStore.headerBgColor, + headerTextColor: themeStore.headerTextColor, +}) +const sidebarColor = reactive({ + bgColor: sidebar.bgColor, + textColor: sidebar.textColor +}) +const themes = [ + { + name: 'primary', + color: themeStore.primary || color.primary + }, + { + name: 'success', + color: themeStore.success || color.success + }, + { + name: 'warning', + color: themeStore.warning || color.warning + }, + { + name: 'danger', + color: themeStore.danger || color.danger + }, + { + name: 'info', + color: themeStore.info || color.info + } +] + +const changeColor = (name: string) => { + themeStore.setPropertyColor(color[name], name) +} + +const resetTheme = () => { + themeStore.resetTheme() +} +const resetHeader = () => { + localStorage.removeItem('header-bg-color') + localStorage.removeItem('header-text-color') + location.reload() +} +const resetSidebar = () => { + localStorage.removeItem('sidebar-bg-color') + localStorage.removeItem('sidebar-text-color') + location.reload() +} +const system = [ + { + name: '默认', + color: '#242f42' + }, + { + name: '健康', + color: '#1ABC9C' + }, + { + name: '优雅', + color: '#722ed1' + }, + { + name: '热情', + color: '#f44336' + }, + { + name: '宁静', + color: '#00bcd4' + } +] +const setSystemTheme = (data: any) => { + if (data.name === '默认') { + resetSystemTheme() + } else { + themeStore.setHeaderBgColor(data.color) + themeStore.setHeaderTextColor('#fff') + sidebar.setBgColor('#fff') + sidebar.setTextColor('#5b6e88') + themeStore.setPropertyColor(data.color, 'primary') + } +} +const resetSystemTheme = () => { + resetTheme(); + resetHeader(); + resetSidebar(); +} +</script> + +<style scoped> +.theme-list { + display: flex; + justify-content: center; +} + +.theme-item { + margin-right: 20px; + padding: 30px; + border: 1px solid #dcdfe6; + border-radius: 4px; + text-align: center; +} + +.theme-color { + color: #787878; + margin: 20px 0; +} +</style> diff --git a/src/views/pages/ucenter.vue b/src/views/pages/ucenter.vue new file mode 100644 index 00000000..2f53081a --- /dev/null +++ b/src/views/pages/ucenter.vue @@ -0,0 +1,270 @@ +<template> + <div> + <div class="user-container"> + <el-card class="user-profile" shadow="hover" :body-style="{ padding: '0px' }"> + <div class="user-profile-bg"></div> + <div class="user-avatar-wrap"> + <el-avatar class="user-avatar" :size="120" :src="avatarImg" /> + </div> + <div class="user-info"> + <div class="info-name">{{ name }}</div> + <div class="info-desc"> + <span>@lin-xin</span> + <el-divider direction="vertical" /> + <el-link href="https://lin-xin.gitee.io" target="_blank">lin-xin.gitee.io</el-link> + </div> + <div class="info-desc">FE Developer</div> + <div class="info-icon"> + <a href="https://github.com/lin-xin" target="_blank"> <i class="el-icon-lx-github-fill"></i></a> + <i class="el-icon-lx-qq-fill"></i> + <i class="el-icon-lx-facebook-fill"></i> + <i class="el-icon-lx-twitter-fill"></i> + </div> + </div> + <div class="user-footer"> + <div class="user-footer-item"> + <el-statistic title="Follower" :value="1800" /> + </div> + <div class="user-footer-item"> + <el-statistic title="Following" :value="666" /> + </div> + <div class="user-footer-item"> + <el-statistic title="Total Post" :value="888" /> + </div> + </div> + </el-card> + <el-card + class="user-content" + shadow="hover" + :body-style="{ padding: '20px 50px', height: '100%', boxSizing: 'border-box' }" + > + <el-tabs tab-position="left" v-model="activeName"> + <el-tab-pane name="label1" label="消息通知" class="user-tabpane"> + <TabsComp /> + </el-tab-pane> + <el-tab-pane name="label2" label="我的头像" class="user-tabpane"> + <div class="crop-wrap" v-if="activeName === 'label2'"> + <vueCropper + ref="cropper" + :img="imgSrc" + :autoCrop="true" + :centerBox="true" + :full="true" + mode="contain" + > + </vueCropper> + </div> + <el-button class="crop-demo-btn" type="primary" + >选择图片 + <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" /> + </el-button> + <el-button type="success" @click="saveAvatar">上传并保存</el-button> + </el-tab-pane> + <el-tab-pane name="label3" label="修改密码" class="user-tabpane"> + <el-form class="w500" label-position="top"> + <el-form-item label="旧密码:"> + <el-input type="password" v-model="form.old"></el-input> + </el-form-item> + <el-form-item label="新密码:"> + <el-input type="password" v-model="form.new"></el-input> + </el-form-item> + <el-form-item label="确认新密码:"> + <el-input type="password" v-model="form.new1"></el-input> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="onSubmit">保存</el-button> + </el-form-item> + </el-form> + </el-tab-pane> + <el-tab-pane name="label4" label="赞赏作者" class="user-tabpane"> + <div class="plugins-tips"> + 如果该框架 + <el-link href="https://github.com/lin-xin/vue-manage-system" target="_blank" + >vue-manage-system</el-link + > + 对你有帮助,那就请作者喝杯饮料吧!<el-icon> + <ColdDrink /> + </el-icon> + 加微信号 linxin_20 探讨问题。 + </div> + <div> + <img src="https://lin-xin.gitee.io/images/weixin.jpg" /> + </div> + </el-tab-pane> + </el-tabs> + </el-card> + </div> + </div> +</template> + +<script setup lang="ts" name="ucenter"> +import { reactive, ref } from 'vue'; +import { VueCropper } from 'vue-cropper'; +import 'vue-cropper/dist/index.css'; +import avatar from '@/assets/img/img.jpg'; +import TabsComp from '../element/tabs.vue'; + +const name = localStorage.getItem('ms_username'); +const form = reactive({ + new1: '', + new: '', + old: '', +}); +const onSubmit = () => {}; + +const activeName = ref('label1'); + +const avatarImg = ref(avatar); +const imgSrc = ref(avatar); +const cropImg = ref(''); +const cropper: any = ref(); + +const setImage = (e: any) => { + const file = e.target.files[0]; + if (!file.type.includes('image/')) { + return; + } + const reader = new FileReader(); + reader.onload = (event: any) => { + imgSrc.value = event.target.result; + cropper.value && cropper.value.replace(event.target.result); + }; + reader.readAsDataURL(file); +}; + +const cropImage = () => { + cropImg.value = cropper.value?.getCroppedCanvas().toDataURL(); +}; + +const saveAvatar = () => { + avatarImg.value = cropImg.value; +}; +</script> + +<style scoped> +.user-container { + display: flex; +} + +.user-profile { + position: relative; +} + +.user-profile-bg { + width: 100%; + height: 200px; + background-image: url('../../assets/img/ucenter-bg.jpg'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; +} + +.user-profile { + width: 500px; + margin-right: 20px; + flex: 0 0 auto; + align-self: flex-start; +} + +.user-avatar-wrap { + position: absolute; + top: 135px; + width: 100%; + text-align: center; +} + +.user-avatar { + border: 5px solid #fff; + border-radius: 50%; + overflow: hidden; + box-shadow: 0 7px 12px 0 rgba(62, 57, 107, 0.16); +} + +.user-info { + text-align: center; + padding: 80px 0 30px; +} + +.info-name { + margin: 0 0 20px; + font-size: 22px; + font-weight: 500; + color: #373a3c; +} + +.info-desc { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 5px; +} + +.info-desc, +.info-desc a { + font-size: 18px; + color: #55595c; +} + +.info-icon { + margin-top: 10px; +} + +.info-icon i { + font-size: 30px; + margin: 0 10px; + color: #343434; +} + +.user-content { + flex: 1; +} + +.user-tabpane { + padding: 10px 20px; +} + +.crop-wrap { + width: 600px; + height: 350px; + margin-bottom: 20px; +} + +.crop-demo-btn { + position: relative; +} + +.crop-input { + position: absolute; + width: 100px; + height: 40px; + left: 0; + top: 0; + opacity: 0; + cursor: pointer; +} + +.w500 { + width: 500px; +} + +.user-footer { + display: flex; + border-top: 1px solid rgba(83, 70, 134, 0.1); +} + +.user-footer-item { + padding: 20px 0; + width: 33.3333333333%; + text-align: center; +} + +.user-footer > div + div { + border-left: 1px solid rgba(83, 70, 134, 0.1); +} +</style> + +<style> +.el-tabs.el-tabs--left { + height: 100%; +} +</style> diff --git a/src/views/pages/ucenter2.vue b/src/views/pages/ucenter2.vue new file mode 100644 index 00000000..96b8aec2 --- /dev/null +++ b/src/views/pages/ucenter2.vue @@ -0,0 +1,253 @@ +<template> + <div class="user-container"> + <el-card class="user-profile mgb20" shadow="hover" :body-style="{ padding: '0px' }"> + <div class="user-profile-bg"></div> + <div class="user-avatar-wrap"> + <el-avatar class="user-avatar" :size="120" :src="avatarImg" /> + </div> + <div class="user-info"> + <div class="info-name">{{ name }}</div> + <div class="info-desc"> + <!-- <span>{{ name }}</span> + <el-divider direction="vertical" /> --> + <span>FE Developer</span> + <el-divider direction="vertical" /> + <el-link href="https://lin-xin.gitee.io" target="_blank">lin-xin.gitee.io</el-link> + </div> + <!-- <div class="info-icon"> + <a href="https://github.com/lin-xin" target="_blank"> <i class="el-icon-lx-github-fill"></i></a> + <i class="el-icon-lx-qq-fill"></i> + <i class="el-icon-lx-facebook-fill"></i> + <i class="el-icon-lx-twitter-fill"></i> + </div> --> + </div> + <!-- <div class="user-footer"> + <div class="user-footer-item"> + <el-statistic title="Follower" value="18K" /> + </div> + <div class="user-footer-item"> + <el-statistic title="Following" :value="666" /> + </div> + <div class="user-footer-item"> + <el-statistic title="Total Post" :value="888" /> + </div> + </div> --> + </el-card> + <el-card class="user-content" shadow="hover" + :body-style="{ padding: '20px 50px', height: '100%', boxSizing: 'border-box' }"> + <el-tabs v-model="activeName"> + + <el-tab-pane name="label1" label="消息通知" class="user-tabpane"> + <TabsComp /> + </el-tab-pane> + <el-tab-pane name="label2" label="我的头像" class="user-tabpane"> + <div class="crop-wrap" v-if="activeName === 'label2'"> + <vueCropper ref="cropper" :img="imgSrc" :autoCrop="true" :centerBox="true" :full="true" + mode="contain"> + </vueCropper> + </div> + <el-button class="crop-demo-btn" type="primary">选择图片 + <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" /> + </el-button> + <el-button type="success" @click="saveAvatar">上传并保存</el-button> + </el-tab-pane> + <el-tab-pane name="label3" label="修改密码" class="user-tabpane"> + <el-form class="w500" label-position="top"> + <el-form-item label="旧密码:"> + <el-input type="password" v-model="form.old"></el-input> + </el-form-item> + <el-form-item label="新密码:"> + <el-input type="password" v-model="form.new"></el-input> + </el-form-item> + <el-form-item label="确认新密码:"> + <el-input type="password" v-model="form.new1"></el-input> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="onSubmit">保存</el-button> + </el-form-item> + </el-form> + </el-tab-pane> + <el-tab-pane name="label4" label="赞赏作者" class="user-tabpane"> + <div class="plugins-tips"> + 如果该框架 <el-link href="https://github.com/lin-xin/vue-manage-system" + target="_blank">vue-manage-system</el-link> 对你有帮助,那就请作者喝杯饮料吧!<el-icon> + <ColdDrink /> + </el-icon> 加微信号 linxin_20 探讨问题。 + </div> + <div> + <img src="https://lin-xin.gitee.io/images/weixin.jpg" /> + </div> + </el-tab-pane> + </el-tabs> + </el-card> + </div> +</template> + +<script setup lang="ts" name="ucenter"> +import { reactive, ref } from 'vue'; +import { VueCropper } from "vue-cropper" +import 'vue-cropper/dist/index.css' +import avatar from '@/assets/img/img.jpg'; +import TabsComp from '../element/tabs.vue'; + +const name = localStorage.getItem('ms_username'); +const form = reactive({ + new1: '', + new: '', + old: '' +}); +const onSubmit = () => { }; + +const activeName = ref('label1'); + +const avatarImg = ref(avatar); +const imgSrc = ref(avatar); +const cropImg = ref(''); +const cropper: any = ref(); + +const setImage = (e: any) => { + const file = e.target.files[0]; + if (!file.type.includes('image/')) { + return; + } + const reader = new FileReader(); + reader.onload = (event: any) => { + imgSrc.value = event.target.result; + cropper.value && cropper.value.replace(event.target.result); + }; + reader.readAsDataURL(file); +}; + +const cropImage = () => { + cropImg.value = cropper.value?.getCroppedCanvas().toDataURL(); +}; + +const saveAvatar = () => { + avatarImg.value = cropImg.value; +}; +</script> + +<style scoped> +/* .user-container { + display: flex; +} */ + +.user-profile-bg { + width: 100%; + height: 150px; + background-image: url('../../assets/img/bahnhofsidylle.jpg'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; +} + +.user-profile { + position: relative; + /* width: 500px; */ + /* margin-right: 20px; */ + /* flex: 0 0 auto; + align-self: flex-start; +} */ +} + +.user-avatar-wrap { + position: absolute; + top: 90px; + width: 100%; + text-align: center; +} + +.user-avatar { + border: 5px solid #fff; + border-radius: 50%; + overflow: hidden; + box-shadow: 0 7px 12px 0 rgba(62, 57, 107, .16) +} + +.user-info { + text-align: center; + padding: 70px 0 20px; +} + +.info-name { + margin: 0 0 10px; + font-size: 22px; + font-weight: 500; + color: #373a3c; +} + +.info-desc { + display: flex; + align-items: center; + justify-content: center; +} + +.info-desc, +.info-desc a { + font-size: 18px; + color: #55595c; +} + +.info-icon { + margin-top: 10px; +} + +.info-icon i { + font-size: 30px; + margin: 0 10px; + color: #343434; +} + +.user-content { + flex: 1 +} + +.user-tabpane { + padding: 10px 20px; +} + +.crop-wrap { + width: 600px; + height: 350px; + margin-bottom: 20px; +} + +.crop-demo-btn { + position: relative; +} + +.crop-input { + position: absolute; + width: 100px; + height: 40px; + left: 0; + top: 0; + opacity: 0; + cursor: pointer; +} + +.w500 { + width: 500px; +} + +.user-footer { + display: flex; + border-top: 1px solid rgba(83, 70, 134, 0.1); +} + +.user-footer-item { + padding: 20px 0; + width: 33.3333333333%; + text-align: center; +} + +.user-footer>div+div { + border-left: 1px solid rgba(83, 70, 134, 0.1); +} +</style> + +<style> +.el-tabs.el-tabs--left { + height: 100%; +} +</style> \ No newline at end of file diff --git a/src/views/permission.vue b/src/views/permission.vue deleted file mode 100644 index bf83327e..00000000 --- a/src/views/permission.vue +++ /dev/null @@ -1,137 +0,0 @@ -<template> - <div class="container"> - <div class="plugins-tips">通过 v-permiss 自定义指令实现权限管理,使用非 admin 账号登录,可查看效果。</div> - <div class="mgb20"> - <span class="label">角色:</span> - <el-select v-model="role" @change="handleChange"> - <el-option label="超级管理员" value="admin"></el-option> - <el-option label="普通用户" value="user"></el-option> - </el-select> - </div> - <div class="mgb20 tree-wrapper"> - <el-tree - ref="tree" - :data="data" - node-key="id" - default-expand-all - show-checkbox - :default-checked-keys="checkedKeys" - /> - </div> - <el-button type="primary" @click="onSubmit">保存权限</el-button> - </div> -</template> - -<script setup lang="ts" name="permission"> -import { ref } from 'vue'; -import { ElTree } from 'element-plus'; -import { usePermissStore } from '../store/permiss'; - -const role = ref<string>('admin'); - -interface Tree { - id: string; - label: string; - children?: Tree[]; -} - -const data: Tree[] = [ - { - id: '1', - label: '系统首页' - }, - { - id: '2', - label: '基础表格', - children: [ - { - id: '15', - label: '编辑' - }, - { - id: '16', - label: '删除' - } - ] - }, - { - id: '3', - label: 'tab选项卡' - }, - { - id: '4', - label: '表单相关', - children: [ - { - id: '5', - label: '基本表单' - }, - { - id: '6', - label: '文件上传' - }, - { - id: '7', - label: '三级菜单', - children: [ - { - id: '8', - label: '富文本编辑器' - }, - { - id: '9', - label: 'markdown编辑器' - } - ] - } - ] - }, - { - id: '10', - label: '自定义图标' - }, - { - id: '11', - label: 'schart图表' - }, - - { - id: '13', - label: '权限管理' - }, - { - id: '14', - label: '支持作者' - } -]; - -const permiss = usePermissStore(); - -// 获取当前权限 -const checkedKeys = ref<string[]>([]); -const getPremission = () => { - // 请求接口返回权限 - checkedKeys.value = permiss.defaultList[role.value]; -}; -getPremission(); - -// 保存权限 -const tree = ref<InstanceType<typeof ElTree>>(); -const onSubmit = () => { - // 获取选中的权限 - console.log(tree.value!.getCheckedKeys(false)); -}; - -const handleChange = (val: string[]) => { - tree.value!.setCheckedKeys(permiss.defaultList[role.value]); -}; -</script> - -<style scoped> -.tree-wrapper { - max-width: 500px; -} -.label { - font-size: 14px; -} -</style> diff --git a/src/views/system/menu.vue b/src/views/system/menu.vue new file mode 100644 index 00000000..bde753b5 --- /dev/null +++ b/src/views/system/menu.vue @@ -0,0 +1,144 @@ +<template> + <div> + <div class="container"> + <TableCustom :columns="columns" :tableData="menuData" row-key="index" :has-pagination="false" + :viewFunc="handleView" :delFunc="handleDelete" :editFunc="handleEdit"> + <template #toolbarBtn> + <el-button type="warning" :icon="CirclePlusFilled" @click="visible = true">新增</el-button> + </template> + <template #icon="{ rows }"> + <el-icon> + <component :is="rows.icon"></component> + </el-icon> + </template> + </TableCustom> + + </div> + <el-dialog :title="isEdit ? '编辑' : '新增'" v-model="visible" width="700px" destroy-on-close + :close-on-click-modal="false" @close="closeDialog"> + <TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData"> + <template #parent> + <el-cascader v-model="rowData.pid" :options="cascaderOptions" :props="{ checkStrictly: true }" + clearable /> + </template> + </TableEdit> + </el-dialog> + <el-dialog title="查看详情" v-model="visible1" width="700px" destroy-on-close> + <TableDetail :data="viewData"> + <template #icon="{ rows }"> + <el-icon> + <component :is="rows.icon"></component> + </el-icon> + </template> + </TableDetail> + </el-dialog> + </div> +</template> + +<script setup lang="ts" name="system-menu"> +import { ref } from 'vue'; +import { ElMessage } from 'element-plus'; +import { CirclePlusFilled } from '@element-plus/icons-vue'; +import { Menus } from '@/types/menu'; +import TableCustom from '@/components/table-custom.vue'; +import TableDetail from '@/components/table-detail.vue'; +import { FormOption } from '@/types/form-option'; +import { menuData } from '@/components/menu'; + +// 表格相关 +let columns = ref([ + { prop: 'title', label: '菜单名称', align: 'left' }, + { prop: 'icon', label: '图标' }, + { prop: 'index', label: '路由路径' }, + { prop: 'permiss', label: '权限标识' }, + { prop: 'operator', label: '操作', width: 250 }, +]) + +const getOptions = (data: any) => { + return data.map(item => { + const a: any = { + label: item.title, + value: item.id, + } + if (item.children) { + a.children = getOptions(item.children) + } + return a + }) +} +const cascaderOptions = ref(getOptions(menuData)); + + +// 新增/编辑弹窗相关 +let options = ref<FormOption>({ + labelWidth: '100px', + span: 12, + list: [ + { type: 'input', label: '菜单名称', prop: 'title', required: true }, + { type: 'input', label: '路由路径', prop: 'index', required: true }, + { type: 'input', label: '图标', prop: 'icon' }, + { type: 'input', label: '权限标识', prop: 'permiss' }, + { type: 'parent', label: '父菜单', prop: 'parent' }, + ] +}) +const visible = ref(false); +const isEdit = ref(false); +const rowData = ref<any>({}); +const handleEdit = (row: Menus) => { + rowData.value = { ...row }; + isEdit.value = true; + visible.value = true; +}; +const updateData = () => { + closeDialog(); +}; + +const closeDialog = () => { + visible.value = false; + isEdit.value = false; +}; + +// 查看详情弹窗相关 +const visible1 = ref(false); +const viewData = ref({ + row: {}, + list: [] +}); +const handleView = (row: Menus) => { + viewData.value.row = { ...row } + viewData.value.list = [ + { + prop: 'id', + label: '菜单ID', + }, + { + prop: 'pid', + label: '父菜单ID', + }, + { + prop: 'title', + label: '菜单名称', + }, + { + prop: 'index', + label: '路由路径', + }, + { + prop: 'permiss', + label: '权限标识', + }, + { + prop: 'icon', + label: '图标', + }, + ] + visible1.value = true; +}; + +// 删除相关 +const handleDelete = (row: Menus) => { + ElMessage.success('删除成功'); +} +</script> + +<style scoped></style> \ No newline at end of file diff --git a/src/views/system/role-permission.vue b/src/views/system/role-permission.vue new file mode 100644 index 00000000..eb31583c --- /dev/null +++ b/src/views/system/role-permission.vue @@ -0,0 +1,76 @@ +<template> + <div> + <el-tree + class="mgb10" + ref="tree" + :data="data" + node-key="id" + default-expand-all + show-checkbox + :default-checked-keys="checkedKeys" + /> + <el-button type="primary" @click="onSubmit">保存权限</el-button> + </div> +</template> + +<script setup lang="ts"> +import { ref } from 'vue'; +import { ElTree } from 'element-plus'; +import { menuData } from '@/components/menu'; + +const props = defineProps({ + permissOptions: { + type: Object, + required: true, + }, +}); + +const menuObj = ref({}); +// const data = menuData.map((item) => { +// if (item.children) { +// menuObj.value[item.id] = item.children.map((sub) => sub.id); +// } +// return { +// id: item.id, +// label: item.title, +// children: item.children?.map((child) => { +// return { +// id: child.id, +// label: child.title, +// }; +// }), +// }; +// }); + +const getTreeData = (data) => { + return data.map((item) => { + const obj: any = { + id: item.id, + label: item.title, + }; + if (item.children) { + menuObj.value[item.id] = item.children.map((sub) => sub.id); + obj.children = getTreeData(item.children); + } + return obj; + }); +}; +const data = getTreeData(menuData); +const checkData = (data: string[]) => { + return data.filter((item) => { + return !menuObj.value[item] || data.toString().includes(menuObj.value[item].toString()); + }); +}; +// 获取当前权限 +const checkedKeys = ref<string[]>(checkData(props.permissOptions.permiss)); + +// 保存权限 +const tree = ref<InstanceType<typeof ElTree>>(); +const onSubmit = () => { + // 获取选中的权限 + const keys = [...tree.value!.getCheckedKeys(false), ...tree.value!.getHalfCheckedKeys()] as number[]; + console.log(keys); +}; +</script> + +<style scoped></style> diff --git a/src/views/system/role.vue b/src/views/system/role.vue new file mode 100644 index 00000000..fa8a6488 --- /dev/null +++ b/src/views/system/role.vue @@ -0,0 +1,162 @@ +<template> + <div> + <TableSearch :query="query" :options="searchOpt" :search="handleSearch" /> + <div class="container"> + + <TableCustom :columns="columns" :tableData="tableData" :total="page.total" :viewFunc="handleView" + :delFunc="handleDelete" :page-change="changePage" :editFunc="handleEdit"> + <template #toolbarBtn> + <el-button type="warning" :icon="CirclePlusFilled" @click="visible = true">新增</el-button> + </template> + <template #status="{ rows }"> + <el-tag type="success" v-if="rows.status">启用</el-tag> + <el-tag type="danger" v-else>禁用</el-tag> + </template> + <template #permissions="{ rows }"> + <el-button type="primary" size="small" plain @click="handlePermission(rows)">管理</el-button> + </template> + </TableCustom> + </div> + <el-dialog :title="isEdit ? '编辑' : '新增'" v-model="visible" width="700px" destroy-on-close + :close-on-click-modal="false" @close="closeDialog"> + <TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData" /> + </el-dialog> + <el-dialog title="查看详情" v-model="visible1" width="700px" destroy-on-close> + <TableDetail :data="viewData"> + <template #status="{ rows }"> + <el-tag type="success" v-if="rows.status">启用</el-tag> + <el-tag type="danger" v-else>禁用</el-tag> + </template> + </TableDetail> + </el-dialog> + <el-dialog title="权限管理" v-model="visible2" width="500px" destroy-on-close> + <RolePermission :permiss-options="permissOptions" /> + </el-dialog> + </div> +</template> + +<script setup lang="ts" name="system-role"> +import { ref, reactive } from 'vue'; +import { ElMessage } from 'element-plus'; +import { Role } from '@/types/role'; +import { fetchRoleData } from '@/api'; +import TableCustom from '@/components/table-custom.vue'; +import TableDetail from '@/components/table-detail.vue'; +import RolePermission from './role-permission.vue' +import { CirclePlusFilled } from '@element-plus/icons-vue'; +import { FormOption, FormOptionList } from '@/types/form-option'; + +// 查询相关 +const query = reactive({ + name: '', +}); +const searchOpt = ref<FormOptionList[]>([ + { type: 'input', label: '角色名称:', prop: 'name' } +]) +const handleSearch = () => { + changePage(1); +}; + +// 表格相关 +let columns = ref([ + { type: 'index', label: '序号', width: 55, align: 'center' }, + { prop: 'name', label: '角色名称' }, + { prop: 'key', label: '角色标识' }, + { prop: 'status', label: '状态' }, + { prop: 'permissions', label: '权限管理' }, + { prop: 'operator', label: '操作', width: 250 }, +]) +const page = reactive({ + index: 1, + size: 10, + total: 0, +}) +const tableData = ref<Role[]>([]); +const getData = async () => { + const res = await fetchRoleData() + tableData.value = res.data.list; + page.total = res.data.pageTotal; +}; +getData(); +const changePage = (val: number) => { + page.index = val; + getData(); +}; + +// 新增/编辑弹窗相关 +const options = ref<FormOption>({ + labelWidth: '100px', + span: 24, + list: [ + { type: 'input', label: '角色名称', prop: 'name', required: true }, + { type: 'input', label: '角色标识', prop: 'key', required: true }, + { type: 'switch', label: '状态', prop: 'status', required: false, activeText: '启用', inactiveText: '禁用' }, + ] +}) +const visible = ref(false); +const isEdit = ref(false); +const rowData = ref({}); +const handleEdit = (row: Role) => { + rowData.value = { ...row }; + isEdit.value = true; + visible.value = true; +}; +const updateData = () => { + closeDialog(); + getData(); +}; +const closeDialog = () => { + visible.value = false; + isEdit.value = false; + rowData.value = {}; +}; + +// 查看详情弹窗相关 +const visible1 = ref(false); +const viewData = ref({ + row: {}, + list: [], + column: 1 +}); +const handleView = (row: Role) => { + viewData.value.row = { ...row } + viewData.value.list = [ + { + prop: 'id', + label: '角色ID', + }, + { + prop: 'name', + label: '角色名称', + }, + { + prop: 'key', + label: '角色标识', + }, + { + prop: 'status', + label: '角色状态', + }, + ] + visible1.value = true; +}; + +// 删除相关 +const handleDelete = (row: Role) => { + ElMessage.success('删除成功'); +} + + +// 权限管理弹窗相关 +const visible2 = ref(false); +const permissOptions = ref({}) +const handlePermission = (row: Role) => { + visible2.value = true; + permissOptions.value = { + id: row.id, + permiss: row.permiss + }; +} +</script> + +<style scoped></style> \ No newline at end of file diff --git a/src/views/system/user.vue b/src/views/system/user.vue new file mode 100644 index 00000000..ea3a3d53 --- /dev/null +++ b/src/views/system/user.vue @@ -0,0 +1,148 @@ +<template> + <div> + <TableSearch :query="query" :options="searchOpt" :search="handleSearch" /> + <div class="container"> + <TableCustom :columns="columns" :tableData="tableData" :total="page.total" :viewFunc="handleView" + :delFunc="handleDelete" :page-change="changePage" :editFunc="handleEdit"> + <template #toolbarBtn> + <el-button type="warning" :icon="CirclePlusFilled" @click="visible = true">新增</el-button> + </template> + </TableCustom> + + </div> + <el-dialog :title="isEdit ? '编辑' : '新增'" v-model="visible" width="700px" destroy-on-close + :close-on-click-modal="false" @close="closeDialog"> + <TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData" /> + </el-dialog> + <el-dialog title="查看详情" v-model="visible1" width="700px" destroy-on-close> + <TableDetail :data="viewData"></TableDetail> + </el-dialog> + </div> +</template> + +<script setup lang="ts" name="system-user"> +import { ref, reactive } from 'vue'; +import { ElMessage } from 'element-plus'; +import { CirclePlusFilled } from '@element-plus/icons-vue'; +import { User } from '@/types/user'; +import { fetchUserData } from '@/api'; +import TableCustom from '@/components/table-custom.vue'; +import TableDetail from '@/components/table-detail.vue'; +import TableSearch from '@/components/table-search.vue'; +import { FormOption, FormOptionList } from '@/types/form-option'; + +// 查询相关 +const query = reactive({ + name: '', +}); +const searchOpt = ref<FormOptionList[]>([ + { type: 'input', label: '用户名:', prop: 'name' } +]) +const handleSearch = () => { + changePage(1); +}; + +// 表格相关 +let columns = ref([ + { type: 'index', label: '序号', width: 55, align: 'center' }, + { prop: 'name', label: '用户名' }, + { prop: 'phone', label: '手机号' }, + { prop: 'role', label: '角色' }, + { prop: 'operator', label: '操作', width: 250 }, +]) +const page = reactive({ + index: 1, + size: 10, + total: 0, +}) +const tableData = ref<User[]>([]); +const getData = async () => { + const res = await fetchUserData() + tableData.value = res.data.list; + page.total = res.data.pageTotal; +}; +getData(); + +const changePage = (val: number) => { + page.index = val; + getData(); +}; + +// 新增/编辑弹窗相关 +let options = ref<FormOption>({ + labelWidth: '100px', + span: 12, + list: [ + { type: 'input', label: '用户名', prop: 'name', required: true }, + { type: 'input', label: '手机号', prop: 'phone', required: true }, + { type: 'input', label: '密码', prop: 'password', required: true }, + { type: 'input', label: '邮箱', prop: 'email', required: true }, + { type: 'input', label: '角色', prop: 'role', required: true }, + ] +}) +const visible = ref(false); +const isEdit = ref(false); +const rowData = ref({}); +const handleEdit = (row: User) => { + rowData.value = { ...row }; + isEdit.value = true; + visible.value = true; +}; +const updateData = () => { + closeDialog(); + getData(); +}; + +const closeDialog = () => { + visible.value = false; + isEdit.value = false; +}; + +// 查看详情弹窗相关 +const visible1 = ref(false); +const viewData = ref({ + row: {}, + list: [] +}); +const handleView = (row: User) => { + viewData.value.row = { ...row } + viewData.value.list = [ + { + prop: 'id', + label: '用户ID', + }, + { + prop: 'name', + label: '用户名', + }, + { + prop: 'password', + label: '密码', + }, + { + prop: 'email', + label: '邮箱', + }, + { + prop: 'phone', + label: '电话', + }, + { + prop: 'role', + label: '角色', + }, + { + prop: 'date', + label: '注册日期', + }, + ] + visible1.value = true; +}; + +// 删除相关 +const handleDelete = (row: User) => { + ElMessage.success('删除成功'); +} +</script> + +<style scoped></style> \ No newline at end of file diff --git a/src/views/table.vue b/src/views/table.vue deleted file mode 100644 index e38c1b6e..00000000 --- a/src/views/table.vue +++ /dev/null @@ -1,194 +0,0 @@ -<template> - <div> - <div class="container"> - <div class="search-box"> - <el-input v-model="query.name" placeholder="用户名" class="search-input mr10" clearable></el-input> - <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button> - <el-button type="warning" :icon="CirclePlusFilled" @click="visible = true">新增</el-button> - </div> - <el-table :data="tableData" border class="table" ref="multipleTable" header-cell-class-name="table-header"> - <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> - <el-table-column prop="name" label="用户名" align="center"></el-table-column> - <el-table-column label="账户余额" align="center"> - <template #default="scope">¥{{ scope.row.money }}</template> - </el-table-column> - <el-table-column label="头像(查看大图)" align="center"> - <template #default="scope"> - <el-image - class="table-td-thumb" - :src="scope.row.thumb" - :z-index="10" - :preview-src-list="[scope.row.thumb]" - preview-teleported - > - </el-image> - </template> - </el-table-column> - <el-table-column prop="address" label="地址" align="center"></el-table-column> - <el-table-column label="账户状态" align="center"> - <template #default="scope"> - <el-tag :type="scope.row.state ? 'success' : 'danger'"> - {{ scope.row.state ? '正常' : '异常' }} - </el-tag> - </template> - </el-table-column> - - <el-table-column prop="date" label="注册时间" align="center"></el-table-column> - <el-table-column label="操作" width="280" align="center"> - <template #default="scope"> - <el-button type="warning" size="small" :icon="View" @click="handleView(scope.row)"> - 查看 - </el-button> - <el-button - type="primary" - size="small" - :icon="Edit" - @click="handleEdit(scope.$index, scope.row)" - v-permiss="15" - > - 编辑 - </el-button> - <el-button - type="danger" - size="small" - :icon="Delete" - @click="handleDelete(scope.$index)" - v-permiss="16" - > - 删除 - </el-button> - </template> - </el-table-column> - </el-table> - <div class="pagination"> - <el-pagination - background - layout="total, prev, pager, next" - :current-page="query.pageIndex" - :page-size="query.pageSize" - :total="pageTotal" - @current-change="handlePageChange" - ></el-pagination> - </div> - </div> - <el-dialog - :title="idEdit ? '编辑用户' : '新增用户'" - v-model="visible" - width="500px" - destroy-on-close - :close-on-click-modal="false" - @close="closeDialog" - > - <TableEdit :data="rowData" :edit="idEdit" :update="updateData" /> - </el-dialog> - <el-dialog title="查看用户详情" v-model="visible1" width="700px" destroy-on-close> - <TableDetail :data="rowData" /> - </el-dialog> - </div> -</template> - -<script setup lang="ts" name="basetable"> -import { ref, reactive } from 'vue'; -import { ElMessage, ElMessageBox } from 'element-plus'; -import { Delete, Edit, Search, CirclePlusFilled, View } from '@element-plus/icons-vue'; -import { fetchData } from '../api/index'; -import TableEdit from '../components/table-edit.vue'; -import TableDetail from '../components/table-detail.vue'; - -interface TableItem { - id: number; - name: string; - thumb: string; - money: number; - state: string; - date: string; - address: string; -} - -const query = reactive({ - address: '', - name: '', - pageIndex: 1, - pageSize: 10 -}); -const tableData = ref<TableItem[]>([]); -const pageTotal = ref(0); -// 获取表格数据 -const getData = async () => { - const res = await fetchData(); - tableData.value = res.data.list; - pageTotal.value = res.data.pageTotal || 50; -}; -getData(); - -// 查询操作 -const handleSearch = () => { - query.pageIndex = 1; - getData(); -}; -// 分页导航 -const handlePageChange = (val: number) => { - query.pageIndex = val; - getData(); -}; - -// 删除操作 -const handleDelete = (index: number) => { - // 二次确认删除 - ElMessageBox.confirm('确定要删除吗?', '提示', { - type: 'warning' - }) - .then(() => { - ElMessage.success('删除成功'); - tableData.value.splice(index, 1); - }) - .catch(() => {}); -}; - -const visible = ref(false); -let idx: number = -1; -const idEdit = ref(false); -const rowData = ref({}); -const handleEdit = (index: number, row: TableItem) => { - idx = index; - rowData.value = row; - idEdit.value = true; - visible.value = true; -}; -const updateData = (row: TableItem) => { - idEdit.value ? (tableData.value[idx] = row) : tableData.value.unshift(row); - console.log(tableData.value); - closeDialog(); -}; - -const closeDialog = () => { - visible.value = false; - idEdit.value = false; -}; - -const visible1 = ref(false); -const handleView = (row: TableItem) => { - rowData.value = row; - visible1.value = true; -}; -</script> - -<style scoped> -.search-box { - margin-bottom: 20px; -} - -.search-input { - width: 200px; -} - -.mr10 { - margin-right: 10px; -} -.table-td-thumb { - display: block; - margin: auto; - width: 40px; - height: 40px; -} -</style> diff --git a/src/views/table/basetable.vue b/src/views/table/basetable.vue new file mode 100644 index 00000000..198acfd8 --- /dev/null +++ b/src/views/table/basetable.vue @@ -0,0 +1,169 @@ +<template> + <div> + <TableSearch :query="query" :options="searchOpt" :search="handleSearch" /> + <div class="container"> + <TableCustom :columns="columns" :tableData="tableData" :total="page.total" :viewFunc="handleView" + :delFunc="handleDelete" :editFunc="handleEdit" :refresh="getData" :currentPage="page.index" + :changePage="changePage"> + <template #toolbarBtn> + <el-button type="warning" :icon="CirclePlusFilled" @click="visible = true">新增</el-button> + </template> + <template #money="{ rows }"> + ¥{{ rows.money }} + </template> + <template #thumb="{ rows }"> + <el-image class="table-td-thumb" :src="rows.thumb" :z-index="10" :preview-src-list="[rows.thumb]" + preview-teleported> + </el-image> + </template> + <template #state="{ rows }"> + <el-tag :type="rows.state ? 'success' : 'danger'"> + {{ rows.state ? '正常' : '异常' }} + </el-tag> + </template> + </TableCustom> + + </div> + <el-dialog :title="isEdit ? '编辑' : '新增'" v-model="visible" width="700px" destroy-on-close + :close-on-click-modal="false" @close="closeDialog"> + <TableEdit :form-data="rowData" :options="options" :edit="isEdit" :update="updateData"> + <template #thumb="{ rows }"> + <img class="table-td-thumb" :src="rows.thumb"></img> + </template> + </TableEdit> + </el-dialog> + <el-dialog title="查看详情" v-model="visible1" width="700px" destroy-on-close> + <TableDetail :data="viewData"> + <template #thumb="{ rows }"> + <el-image :src="rows.thumb"></el-image> + </template> + </TableDetail> + </el-dialog> + </div> +</template> + +<script setup lang="ts" name="basetable"> +import { ref, reactive } from 'vue'; +import { ElMessage, } from 'element-plus'; +import { CirclePlusFilled } from '@element-plus/icons-vue'; +import { fetchData } from '@/api/index'; +import TableCustom from '@/components/table-custom.vue'; +import TableDetail from '@/components/table-detail.vue'; +import TableSearch from '@/components/table-search.vue'; +import { TableItem } from '@/types/table'; +import { FormOption, FormOptionList } from '@/types/form-option'; + +// 查询相关 +const query = reactive({ + name: '', +}); +const searchOpt = ref<FormOptionList[]>([ + { type: 'input', label: '用户名:', prop: 'name' } +]) +const handleSearch = () => { + changePage(1); +}; + +// 表格相关 +let columns = ref([ + { type: 'selection' }, + { type: 'index', label: '序号', width: 55, align: 'center' }, + { prop: 'name', label: '用户名' }, + { prop: 'money', label: '账户余额' }, + { prop: 'thumb', label: '头像' }, + { prop: 'state', label: '账户状态' }, + { prop: 'operator', label: '操作', width: 250 }, +]) +const page = reactive({ + index: 1, + size: 10, + total: 200, +}) +const tableData = ref<TableItem[]>([]); +const getData = async () => { + const res = await fetchData() + tableData.value = res.data.list; +}; +getData(); + +const changePage = (val: number) => { + page.index = val; + getData(); +}; + +// 新增/编辑弹窗相关 +let options = ref<FormOption>({ + labelWidth: '100px', + span: 24, + list: [ + { type: 'input', label: '用户名', prop: 'name', required: true }, + { type: 'number', label: '账户余额', prop: 'money', required: true }, + { type: 'switch', activeText: '正常', inactiveText: '异常', label: '账户状态', prop: 'state', required: true }, + { type: 'upload', label: '头像', prop: 'thumb', required: true }, + ] +}) +const visible = ref(false); +const isEdit = ref(false); +const rowData = ref({}); +const handleEdit = (row: TableItem) => { + rowData.value = { ...row }; + isEdit.value = true; + visible.value = true; +}; +const updateData = () => { + closeDialog(); + getData(); +}; + +const closeDialog = () => { + visible.value = false; + isEdit.value = false; +}; + +// 查看详情弹窗相关 +const visible1 = ref(false); +const viewData = ref({ + row: {}, + list: [] +}); +const handleView = (row: TableItem) => { + viewData.value.row = { ...row } + viewData.value.list = [ + { + prop: 'id', + label: '用户ID', + }, + { + prop: 'name', + label: '用户名', + }, + { + prop: 'money', + label: '账户余额', + }, + { + prop: 'state', + label: '账户状态', + }, + { + prop: 'thumb', + label: '头像', + }, + ] + visible1.value = true; +}; + +// 删除相关 +const handleDelete = (row: TableItem) => { + ElMessage.success('删除成功'); +} +</script> + +<style scoped> +.table-td-thumb { + display: block; + margin: auto; + width: 40px; + height: 40px; +} +</style> diff --git a/src/views/export.vue b/src/views/table/export.vue similarity index 95% rename from src/views/export.vue rename to src/views/table/export.vue index 21ecf6b2..a2c12898 100644 --- a/src/views/export.vue +++ b/src/views/table/export.vue @@ -1,98 +1,98 @@ -<template> - <div> - <div class="container"> - <div class="handle-box"> - <el-button type="primary" @click="exportXlsx">导出Excel</el-button> - </div> - <el-table :data="tableData" border class="table" header-cell-class-name="table-header"> - <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> - <el-table-column prop="name" label="姓名"></el-table-column> - <el-table-column prop="sno" label="学号"></el-table-column> - <el-table-column prop="class" label="班级"></el-table-column> - <el-table-column prop="age" label="年龄"></el-table-column> - <el-table-column prop="sex" label="性别"></el-table-column> - </el-table> - </div> - </div> -</template> - -<script setup lang="ts" name="export"> -import { ref } from 'vue'; -import * as XLSX from 'xlsx'; - -interface TableItem { - id: number; - name: string; - sno: string; - class: string; - age: string; - sex: string; -} - -const tableData = ref<TableItem[]>([]); -// 获取表格数据 -const getData = () => { - tableData.value = [ - { - id: 1, - name: '小明', - sno: 'S001', - class: '一班', - age: '10', - sex: '男', - }, - { - id: 2, - name: '小红', - sno: 'S002', - class: '一班', - age: '9', - sex: '女', - }, - ]; -}; -getData(); - -const list = [['序号', '姓名', '学号', '班级', '年龄', '性别']]; -const exportXlsx = () => { - tableData.value.map((item: any, i: number) => { - const arr: any[] = [i + 1]; - arr.push(...[item.name, item.sno, item.class, item.age, item.sex]); - list.push(arr); - }); - let WorkSheet = XLSX.utils.aoa_to_sheet(list); - let new_workbook = XLSX.utils.book_new(); - XLSX.utils.book_append_sheet(new_workbook, WorkSheet, '第一页'); - XLSX.writeFile(new_workbook, `表格.xlsx`); -}; -</script> - -<style scoped> -.handle-box { - margin-bottom: 20px; -} - -.handle-select { - width: 120px; -} - -.handle-input { - width: 300px; -} -.table { - width: 100%; - font-size: 14px; -} -.red { - color: #f56c6c; -} -.mr10 { - margin-right: 10px; -} -.table-td-thumb { - display: block; - margin: auto; - width: 40px; - height: 40px; -} -</style> +<template> + <div> + <div class="container"> + <div class="handle-box"> + <el-button type="primary" @click="exportXlsx">导出Excel</el-button> + </div> + <el-table :data="tableData" border class="table" header-cell-class-name="table-header"> + <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> + <el-table-column prop="name" label="姓名"></el-table-column> + <el-table-column prop="sno" label="学号"></el-table-column> + <el-table-column prop="class" label="班级"></el-table-column> + <el-table-column prop="age" label="年龄"></el-table-column> + <el-table-column prop="sex" label="性别"></el-table-column> + </el-table> + </div> + </div> +</template> + +<script setup lang="ts" name="export"> +import { ref } from 'vue'; +import * as XLSX from 'xlsx'; + +interface TableItem { + id: number; + name: string; + sno: string; + class: string; + age: string; + sex: string; +} + +const tableData = ref<TableItem[]>([]); +// 获取表格数据 +const getData = () => { + tableData.value = [ + { + id: 1, + name: '小明', + sno: 'S001', + class: '一班', + age: '10', + sex: '男', + }, + { + id: 2, + name: '小红', + sno: 'S002', + class: '一班', + age: '9', + sex: '女', + }, + ]; +}; +getData(); + +const list = [['序号', '姓名', '学号', '班级', '年龄', '性别']]; +const exportXlsx = () => { + tableData.value.map((item: any, i: number) => { + const arr: any[] = [i + 1]; + arr.push(...[item.name, item.sno, item.class, item.age, item.sex]); + list.push(arr); + }); + let WorkSheet = XLSX.utils.aoa_to_sheet(list); + let new_workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(new_workbook, WorkSheet, '第一页'); + XLSX.writeFile(new_workbook, `表格.xlsx`); +}; +</script> + +<style scoped> +.handle-box { + margin-bottom: 20px; +} + +.handle-select { + width: 120px; +} + +.handle-input { + width: 300px; +} + +.table { + width: 100%; + font-size: 14px; +} + +.red { + color: #f56c6c; +} + +.table-td-thumb { + display: block; + margin: auto; + width: 40px; + height: 40px; +} +</style> diff --git a/src/views/import.vue b/src/views/table/import.vue similarity index 90% rename from src/views/import.vue rename to src/views/table/import.vue index e0ca8c3d..ec65ea5d 100644 --- a/src/views/import.vue +++ b/src/views/table/import.vue @@ -1,118 +1,109 @@ -<template> - <div> - <div class="container"> - <div class="handle-box"> - <el-upload - action="#" - :limit="1" - accept=".xlsx, .xls" - :show-file-list="false" - :before-upload="beforeUpload" - :http-request="handleMany" - > - <el-button class="mr10" type="success">批量导入</el-button> - </el-upload> - <el-link href="/template.xlsx" target="_blank">下载模板</el-link> - </div> - <el-table :data="tableData" border class="table" header-cell-class-name="table-header"> - <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> - <el-table-column prop="name" label="姓名"></el-table-column> - <el-table-column prop="sno" label="学号"></el-table-column> - <el-table-column prop="class" label="班级"></el-table-column> - <el-table-column prop="age" label="年龄"></el-table-column> - <el-table-column prop="sex" label="性别"></el-table-column> - </el-table> - </div> - </div> -</template> - -<script setup lang="ts" name="import"> -import { UploadProps } from 'element-plus'; -import { ref, reactive } from 'vue'; -import * as XLSX from 'xlsx'; - -interface TableItem { - id: number; - name: string; - sno: string; - class: string; - age: string; - sex: string; -} - -const tableData = ref<TableItem[]>([]); -// 获取表格数据 -const getData = () => { - tableData.value = [ - { - id: 1, - name: '小明', - sno: 'S001', - class: '一班', - age: '10', - sex: '男', - }, - { - id: 2, - name: '小红', - sno: 'S002', - class: '一班', - age: '9', - sex: '女', - }, - ]; -}; -getData(); - -const importList = ref<any>([]); -const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => { - importList.value = await analysisExcel(rawFile); - return true; -}; -const analysisExcel = (file: any) => { - return new Promise(function (resolve, reject) { - const reader = new FileReader(); - reader.onload = function (e: any) { - const data = e.target.result; - let datajson = XLSX.read(data, { - type: 'binary', - }); - - const sheetName = datajson.SheetNames[0]; - const result = XLSX.utils.sheet_to_json(datajson.Sheets[sheetName]); - resolve(result); - }; - reader.readAsBinaryString(file); - }); -}; - -const handleMany = async () => { - // 把数据传给服务器后获取最新列表,这里只是示例,不做请求 - const list = importList.value.map((item: any, index: number) => { - return { - id: index, - name: item['姓名'], - sno: item['学号'], - class: item['班级'], - age: item['年龄'], - sex: item['性别'], - }; - }); - tableData.value.push(...list); -}; -</script> - -<style scoped> -.handle-box { - display: flex; - margin-bottom: 20px; -} - -.table { - width: 100%; - font-size: 14px; -} -.mr10 { - margin-right: 10px; -} -</style> +<template> + <div> + <div class="container"> + <div class="handle-box"> + <el-upload action="#" :limit="1" accept=".xlsx, .xls" :show-file-list="false" + :before-upload="beforeUpload" :http-request="handleMany"> + <el-button class="mr10" type="success">批量导入</el-button> + </el-upload> + <el-link href="/template.xlsx" target="_blank">下载模板</el-link> + </div> + <el-table :data="tableData" border class="table" header-cell-class-name="table-header"> + <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> + <el-table-column prop="name" label="姓名"></el-table-column> + <el-table-column prop="sno" label="学号"></el-table-column> + <el-table-column prop="class" label="班级"></el-table-column> + <el-table-column prop="age" label="年龄"></el-table-column> + <el-table-column prop="sex" label="性别"></el-table-column> + </el-table> + </div> + </div> +</template> + +<script setup lang="ts" name="import"> +import { UploadProps } from 'element-plus'; +import { ref, reactive } from 'vue'; +import * as XLSX from 'xlsx'; + +interface TableItem { + id: number; + name: string; + sno: string; + class: string; + age: string; + sex: string; +} + +const tableData = ref<TableItem[]>([]); +// 获取表格数据 +const getData = () => { + tableData.value = [ + { + id: 1, + name: '小明', + sno: 'S001', + class: '一班', + age: '10', + sex: '男', + }, + { + id: 2, + name: '小红', + sno: 'S002', + class: '一班', + age: '9', + sex: '女', + }, + ]; +}; +getData(); + +const importList = ref<any>([]); +const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => { + importList.value = await analysisExcel(rawFile); + return true; +}; +const analysisExcel = (file: any) => { + return new Promise(function (resolve, reject) { + const reader = new FileReader(); + reader.onload = function (e: any) { + const data = e.target.result; + let datajson = XLSX.read(data, { + type: 'binary', + }); + + const sheetName = datajson.SheetNames[0]; + const result = XLSX.utils.sheet_to_json(datajson.Sheets[sheetName]); + resolve(result); + }; + reader.readAsBinaryString(file); + }); +}; + +const handleMany = async () => { + // 把数据传给服务器后获取最新列表,这里只是示例,不做请求 + const list = importList.value.map((item: any, index: number) => { + return { + id: index, + name: item['姓名'], + sno: item['学号'], + class: item['班级'], + age: item['年龄'], + sex: item['性别'], + }; + }); + tableData.value.push(...list); +}; +</script> + +<style scoped> +.handle-box { + display: flex; + margin-bottom: 20px; +} + +.table { + width: 100%; + font-size: 14px; +} +</style> diff --git a/src/views/table/table-editor.vue b/src/views/table/table-editor.vue new file mode 100644 index 00000000..61bb6f77 --- /dev/null +++ b/src/views/table/table-editor.vue @@ -0,0 +1,79 @@ +<template> + <div class="container"> + <TableCustom :columns="columns" :tableData="tableData" :hasToolbar="false" :hasPagination="false"> + <template #name="{ rows }"> + <el-input v-if="rows.editing" v-model="rows.name"></el-input> + <span v-else>{{ rows.name }}</span> + </template> + <template #password="{ rows }"> + <el-input v-if="rows.editing" v-model="rows.password"></el-input> + <span v-else>{{ rows.password }}</span> + </template> + <template #email="{ rows }"> + <el-input v-if="rows.editing" v-model="rows.email"></el-input> + <span v-else>{{ rows.email }}</span> + </template> + <template #role="{ rows }"> + <el-select v-if="rows.editing" v-model="rows.role"> + <el-option label="管理员" value="管理员"></el-option> + <el-option label="普通用户" value="普通用户"></el-option> + </el-select> + <span v-else>{{ rows.role }}</span> + </template> + <template #operator="{ rows, index }"> + <template v-if="!rows.editing"> + <el-button type="primary" size="small" :icon="Edit" @click="handleEdit(rows)"> + 编辑 + </el-button> + <el-button type="danger" size="small" :icon="Delete" @click=""> + 删除 + </el-button> + </template> + <template v-else> + <el-button type="success" size="small" :icon="Select" @click="rows.editing = false"> + 保存 + </el-button> + <el-button type="default" size="small" :icon="CloseBold" @click="handleCancel(rows, index)"> + 取消 + </el-button> + </template> + </template> + </TableCustom> + </div> +</template> + +<script setup lang="ts" name="table-editor"> +import { ref } from 'vue'; +import { Delete, Edit, CloseBold, Select } from '@element-plus/icons-vue'; +import TableCustom from '@/components/table-custom.vue'; +import { fetchUserData } from '@/api/index'; + +let columns = ref([ + { type: 'index', label: '序号', width: 55, align: 'center' }, + { prop: 'name', label: '用户名' }, + { prop: 'password', label: '密码' }, + { prop: 'email', label: '邮箱' }, + { prop: 'role', label: '角色' }, + { prop: 'operator', label: '操作', width: 180 }, +]) +const tableData = ref([]); +const getData = async () => { + const res = await fetchUserData(); + tableData.value = res.data.list; +}; +getData(); + +const rowData = ref({}) + +const handleEdit = (row) => { + rowData.value = { ...row }; + row.editing = true; +}; + +const handleCancel = (row, index) => { + row.editing = false; + tableData.value[index] = { ...rowData.value }; +}; +</script> + +<style scoped></style> diff --git a/src/views/tabs.vue b/src/views/tabs.vue deleted file mode 100644 index 55b06435..00000000 --- a/src/views/tabs.vue +++ /dev/null @@ -1,116 +0,0 @@ -<template> - <div class="container"> - <el-tabs v-model="message"> - <el-tab-pane :label="`未读消息(${state.unread.length})`" name="first"> - <el-table :data="state.unread" :show-header="false" style="width: 100%"> - <el-table-column> - <template #default="scope"> - <span class="message-title">{{ scope.row.title }}</span> - </template> - </el-table-column> - <el-table-column prop="date" width="180"></el-table-column> - <el-table-column width="120"> - <template #default="scope"> - <el-button size="small" @click="handleRead(scope.$index)">标为已读</el-button> - </template> - </el-table-column> - </el-table> - <div class="handle-row"> - <el-button type="primary">全部标为已读</el-button> - </div> - </el-tab-pane> - <el-tab-pane :label="`已读消息(${state.read.length})`" name="second"> - <template v-if="message === 'second'"> - <el-table :data="state.read" :show-header="false" style="width: 100%"> - <el-table-column> - <template #default="scope"> - <span class="message-title">{{ scope.row.title }}</span> - </template> - </el-table-column> - <el-table-column prop="date" width="180"></el-table-column> - <el-table-column width="120"> - <template #default="scope"> - <el-button type="danger" size="small" @click="handleDel(scope.$index)">删除</el-button> - </template> - </el-table-column> - </el-table> - <div class="handle-row"> - <el-button type="danger">删除全部</el-button> - </div> - </template> - </el-tab-pane> - <el-tab-pane :label="`回收站(${state.recycle.length})`" name="third"> - <template v-if="message === 'third'"> - <el-table :data="state.recycle" :show-header="false" style="width: 100%"> - <el-table-column> - <template #default="scope"> - <span class="message-title">{{ scope.row.title }}</span> - </template> - </el-table-column> - <el-table-column prop="date" width="180"></el-table-column> - <el-table-column width="120"> - <template #default="scope"> - <el-button size="small" @click="handleRestore(scope.$index)">还原</el-button> - </template> - </el-table-column> - </el-table> - <div class="handle-row"> - <el-button type="danger">清空回收站</el-button> - </div> - </template> - </el-tab-pane> - </el-tabs> - </div> -</template> - -<script setup lang="ts" name="tabs"> -import { ref, reactive } from 'vue'; - -const message = ref('first'); -const state = reactive({ - unread: [ - { - date: '2018-04-19 20:00:00', - title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' - }, - { - date: '2018-04-19 21:00:00', - title: '今晚12点整发大红包,先到先得' - } - ], - read: [ - { - date: '2018-04-19 20:00:00', - title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' - } - ], - recycle: [ - { - date: '2018-04-19 20:00:00', - title: '【系统通知】该系统将于今晚凌晨2点到5点进行升级维护' - } - ] -}); - -const handleRead = (index: number) => { - const item = state.unread.splice(index, 1); - state.read = item.concat(state.read); -}; -const handleDel = (index: number) => { - const item = state.read.splice(index, 1); - state.recycle = item.concat(state.recycle); -}; -const handleRestore = (index: number) => { - const item = state.recycle.splice(index, 1); - state.read = item.concat(state.read); -}; -</script> - -<style> -.message-title { - cursor: pointer; -} -.handle-row { - margin-top: 30px; -} -</style> diff --git a/src/views/user.vue b/src/views/user.vue deleted file mode 100644 index c0728dab..00000000 --- a/src/views/user.vue +++ /dev/null @@ -1,174 +0,0 @@ -<template> - <div> - <el-row :gutter="20"> - <el-col :span="12"> - <el-card shadow="hover"> - <template #header> - <div class="clearfix"> - <span>基础信息</span> - </div> - </template> - <div class="info"> - <div class="info-image" @click="showDialog"> - <el-avatar :size="100" :src="avatarImg" /> - <span class="info-edit"> - <i class="el-icon-lx-camerafill"></i> - </span> - </div> - <div class="info-name">{{ name }}</div> - <div class="info-desc">不可能!我的代码怎么可能会有bug!</div> - </div> - </el-card> - </el-col> - <el-col :span="12"> - <el-card shadow="hover"> - <template #header> - <div class="clearfix"> - <span>账户编辑</span> - </div> - </template> - <el-form label-width="90px"> - <el-form-item label="用户名:"> {{ name }} </el-form-item> - <el-form-item label="旧密码:"> - <el-input type="password" v-model="form.old"></el-input> - </el-form-item> - <el-form-item label="新密码:"> - <el-input type="password" v-model="form.new"></el-input> - </el-form-item> - <el-form-item label="个人简介:"> - <el-input v-model="form.desc"></el-input> - </el-form-item> - <el-form-item> - <el-button type="primary" @click="onSubmit">保存</el-button> - </el-form-item> - </el-form> - </el-card> - </el-col> - </el-row> - <el-dialog title="裁剪图片" v-model="dialogVisible" width="600px"> - <vue-cropper - ref="cropper" - :src="imgSrc" - :ready="cropImage" - :zoom="cropImage" - :cropmove="cropImage" - style="width: 100%; height: 400px" - ></vue-cropper> - - <template #footer> - <span class="dialog-footer"> - <el-button class="crop-demo-btn" type="primary" - >选择图片 - <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" /> - </el-button> - <el-button type="primary" @click="saveAvatar">上传并保存</el-button> - </span> - </template> - </el-dialog> - </div> -</template> - -<script setup lang="ts" name="user"> -import { reactive, ref } from 'vue'; -import VueCropper from 'vue-cropperjs'; -import 'cropperjs/dist/cropper.css'; -import avatar from '../assets/img/img.jpg'; - -const name = localStorage.getItem('ms_username'); -const form = reactive({ - old: '', - new: '', - desc: '不可能!我的代码怎么可能会有bug!' -}); -const onSubmit = () => {}; - -const avatarImg = ref(avatar); -const imgSrc = ref(''); -const cropImg = ref(''); -const dialogVisible = ref(false); -const cropper: any = ref(); - -const showDialog = () => { - dialogVisible.value = true; - imgSrc.value = avatarImg.value; -}; - -const setImage = (e: any) => { - const file = e.target.files[0]; - if (!file.type.includes('image/')) { - return; - } - const reader = new FileReader(); - reader.onload = (event: any) => { - dialogVisible.value = true; - imgSrc.value = event.target.result; - cropper.value && cropper.value.replace(event.target.result); - }; - reader.readAsDataURL(file); -}; - -const cropImage = () => { - cropImg.value = cropper.value.getCroppedCanvas().toDataURL(); -}; - -const saveAvatar = () => { - avatarImg.value = cropImg.value; - dialogVisible.value = false; -}; -</script> - -<style scoped> -.info { - text-align: center; - padding: 35px 0; -} -.info-image { - position: relative; - margin: auto; - width: 100px; - height: 100px; - background: #f8f8f8; - border: 1px solid #eee; - border-radius: 50px; - overflow: hidden; -} - -.info-edit { - display: flex; - justify-content: center; - align-items: center; - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5); - opacity: 0; - transition: opacity 0.3s ease; -} -.info-edit i { - color: #eee; - font-size: 25px; -} -.info-image:hover .info-edit { - opacity: 1; -} -.info-name { - margin: 15px 0 10px; - font-size: 24px; - font-weight: 500; - color: #262626; -} -.crop-demo-btn { - position: relative; -} -.crop-input { - position: absolute; - width: 100px; - height: 40px; - left: 0; - top: 0; - opacity: 0; - cursor: pointer; -} -</style> diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index ff773960..56d7ddcb 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,10 +1,10 @@ -/// <reference types="vite/client" /> - -declare module '*.vue' { - import type { DefineComponent } from 'vue' - const component: DefineComponent<{}, {}, any> - export default component -} - -declare module 'vue-schart'; -declare module 'vue-cropperjs'; \ No newline at end of file +/// <reference types="vite/client" /> + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} + +declare module 'vue-schart'; +declare module 'nprogress' \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index cc6bbf2d..6949ea69 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,22 @@ -{ - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "moduleResolution": "Node", - "strict": false, - "jsx": "preserve", - "sourceMap": true, - "resolveJsonModule": true, - "isolatedModules": true, - "esModuleInterop": true, - "lib": ["ESNext", "DOM"], - "skipLibCheck": true - }, - "include": ["src/**/*.ts", "src/**/*.d.ts","src/**/*.vue"], - "references": [{ "path": "./tsconfig.node.json" }] -} +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": false, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.d.ts","src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json index 9d31e2ae..1f4ac32f 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,9 +1,9 @@ -{ - "compilerOptions": { - "composite": true, - "module": "ESNext", - "moduleResolution": "Node", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts index 30ed7089..2875fc54 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,22 +1,31 @@ -import { defineConfig } from 'vite'; -import vue from '@vitejs/plugin-vue'; -import VueSetupExtend from 'vite-plugin-vue-setup-extend'; -import AutoImport from 'unplugin-auto-import/vite'; -import Components from 'unplugin-vue-components/vite'; -import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; -export default defineConfig({ - base: './', - plugins: [ - vue(), - VueSetupExtend(), - AutoImport({ - resolvers: [ElementPlusResolver()] - }), - Components({ - resolvers: [ElementPlusResolver()] - }) - ], - optimizeDeps: { - include: ['schart.js'] - } -}); +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import VueSetupExtend from 'vite-plugin-vue-setup-extend'; +import AutoImport from 'unplugin-auto-import/vite'; +import Components from 'unplugin-vue-components/vite'; +import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'; +export default defineConfig({ + base: './', + plugins: [ + vue(), + VueSetupExtend(), + AutoImport({ + resolvers: [ElementPlusResolver()] + }), + Components({ + resolvers: [ElementPlusResolver()] + }) + ], + optimizeDeps: { + include: ['schart.js'] + }, + resolve: { + alias: { + '@': '/src', + '~': '/src/assets' + } + }, + define: { + __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "true", + }, +}); diff --git a/yarn.lock b/yarn.lock index 6b3abe9e..2f954cd5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,72 +3,70 @@ "@antfu/utils@^0.7.0", "@antfu/utils@^0.7.2": - version "0.7.2" - resolved "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.2.tgz#3bb6f37a6b188056fe9e2f363b6aa735ed65d7ca" - integrity sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g== + version "0.7.7" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.7.7.tgz#26ea493a831b4f3a85475e7157be02fb4eab51fb" + integrity sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg== -"@babel/parser@^7.16.4": - version "7.21.2" - resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" - integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== - -"@babel/parser@^7.23.6": - version "7.23.6" - resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" - integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== +"@babel/parser@^7.23.9": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88" + integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== "@babel/runtime@^7.12.0": - version "7.21.0" - resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" - integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd" + integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA== dependencies: - regenerator-runtime "^0.13.11" + regenerator-runtime "^0.14.0" "@ctrl/tinycolor@^3.4.1": - version "3.6.0" - resolved "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz#53fa5fe9c34faee89469e48f91d51a3766108bc8" - integrity sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ== + version "3.6.1" + resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31" + integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA== "@element-plus/icons-vue@*", "@element-plus/icons-vue@^2.3.1": version "2.3.1" - resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a" + resolved "https://registry.yarnpkg.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a" integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg== "@esbuild/android-arm@0.15.18": version "0.15.18" - resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80" integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw== "@esbuild/linux-loong64@0.15.18": version "0.15.18" - resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ== -"@floating-ui/core@^1.2.1": - version "1.2.1" - resolved "https://registry.npmmirror.com/@floating-ui/core/-/core-1.2.1.tgz#074182a1d277f94569c50a6b456e62585d463c8e" - integrity sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg== +"@floating-ui/core@^1.0.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" + integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g== + dependencies: + "@floating-ui/utils" "^0.2.1" "@floating-ui/dom@^1.0.1": - version "1.2.1" - resolved "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.2.1.tgz#8f93906e1a3b9f606ce78afb058e874344dcbe07" - integrity sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA== + version "1.6.3" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef" + integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw== dependencies: - "@floating-ui/core" "^1.2.1" + "@floating-ui/core" "^1.0.0" + "@floating-ui/utils" "^0.2.0" -"@jridgewell/sourcemap-codec@^1.4.13": - version "1.4.14" - resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" + integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" - resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -76,12 +74,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -89,13 +87,13 @@ "@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7": version "2.11.7" - resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671" + resolved "https://registry.yarnpkg.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671" integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ== "@rollup/pluginutils@^5.0.2": - version "5.0.2" - resolved "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" - integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -103,39 +101,39 @@ "@transloadit/prettier-bytes@0.0.7": version "0.0.7" - resolved "https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz#cdb5399f445fdd606ed833872fa0cabdbc51686b" + resolved "https://registry.yarnpkg.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz#cdb5399f445fdd606ed833872fa0cabdbc51686b" integrity sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA== "@types/estree@^1.0.0": - version "1.0.0" - resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/event-emitter@^0.3.3": - version "0.3.3" - resolved "https://registry.npmmirror.com/@types/event-emitter/-/event-emitter-0.3.3.tgz#727032a9fc67565f96bbd78b2e2809275c97d7e7" - integrity sha512-UfnOK1pIxO7P+EgPRZXD9jMpimd8QEFcEZ5R67R1UhGbv4zghU5+NE7U8M8G9H5Jc8FI51rqDWQs6FtUfq2e/Q== + version "0.3.5" + resolved "https://registry.yarnpkg.com/@types/event-emitter/-/event-emitter-0.3.5.tgz#ce9b513f72c50dcf0443a12165a93a79ba7a7092" + integrity sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ== "@types/lodash-es@^4.17.6": - version "4.17.6" - resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.6.tgz#c2ed4c8320ffa6f11b43eb89e9eaeec65966a0a0" - integrity sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg== + version "4.17.12" + resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b" + integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== dependencies: "@types/lodash" "*" "@types/lodash@*", "@types/lodash@^4.14.182": - version "4.14.191" - resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" - integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== + version "4.17.0" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.0.tgz#d774355e41f372d5350a4d0714abb48194a489c3" + integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== "@types/web-bluetooth@^0.0.16": version "0.0.16" - resolved "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8" + resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8" integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ== "@uppy/companion-client@^2.2.2": version "2.2.2" - resolved "https://registry.npmmirror.com/@uppy/companion-client/-/companion-client-2.2.2.tgz#c70b42fdcca728ef88b3eebf7ee3e2fa04b4923b" + resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-2.2.2.tgz#c70b42fdcca728ef88b3eebf7ee3e2fa04b4923b" integrity sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og== dependencies: "@uppy/utils" "^4.1.2" @@ -143,7 +141,7 @@ "@uppy/core@^2.1.1": version "2.3.4" - resolved "https://registry.npmmirror.com/@uppy/core/-/core-2.3.4.tgz#260b85b6bf3aa03cdc67da231f8c69cfbfdcc84a" + resolved "https://registry.yarnpkg.com/@uppy/core/-/core-2.3.4.tgz#260b85b6bf3aa03cdc67da231f8c69cfbfdcc84a" integrity sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ== dependencies: "@transloadit/prettier-bytes" "0.0.7" @@ -157,19 +155,19 @@ "@uppy/store-default@^2.1.1": version "2.1.1" - resolved "https://registry.npmmirror.com/@uppy/store-default/-/store-default-2.1.1.tgz#62a656a099bdaa012306e054d093754cb2d36e3e" + resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-2.1.1.tgz#62a656a099bdaa012306e054d093754cb2d36e3e" integrity sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ== "@uppy/utils@^4.1.2", "@uppy/utils@^4.1.3": version "4.1.3" - resolved "https://registry.npmmirror.com/@uppy/utils/-/utils-4.1.3.tgz#9d0be6ece4df25f228d30ef40be0f14208258ce3" + resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-4.1.3.tgz#9d0be6ece4df25f228d30ef40be0f14208258ce3" integrity sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw== dependencies: lodash.throttle "^4.1.1" "@uppy/xhr-upload@^2.0.3": version "2.1.3" - resolved "https://registry.npmmirror.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz#0d4e355332fe0c6eb372d7731315e04d02aeeb18" + resolved "https://registry.yarnpkg.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz#0d4e355332fe0c6eb372d7731315e04d02aeeb18" integrity sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ== dependencies: "@uppy/companion-client" "^2.2.2" @@ -178,24 +176,24 @@ "@vitejs/plugin-vue@^3.0.0": version "3.2.0" - resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz#a1484089dd85d6528f435743f84cdd0d215bbb54" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz#a1484089dd85d6528f435743f84cdd0d215bbb54" integrity sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw== "@volar/code-gen@0.38.9": version "0.38.9" - resolved "https://registry.npmmirror.com/@volar/code-gen/-/code-gen-0.38.9.tgz#8fed2c6a472c8f11ce695b08789bcc22b08e7fa6" + resolved "https://registry.yarnpkg.com/@volar/code-gen/-/code-gen-0.38.9.tgz#8fed2c6a472c8f11ce695b08789bcc22b08e7fa6" integrity sha512-n6LClucfA+37rQeskvh9vDoZV1VvCVNy++MAPKj2dT4FT+Fbmty/SDQqnsEBtdEe6E3OQctFvA/IcKsx3Mns0A== dependencies: "@volar/source-map" "0.38.9" "@volar/source-map@0.38.9": version "0.38.9" - resolved "https://registry.npmmirror.com/@volar/source-map/-/source-map-0.38.9.tgz#935d6def4b4342e8e2d63cd8e6bf9bf1155c58d8" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-0.38.9.tgz#935d6def4b4342e8e2d63cd8e6bf9bf1155c58d8" integrity sha512-ba0UFoHDYry+vwKdgkWJ6xlQT+8TFtZg1zj9tSjj4PykW1JZDuM0xplMotLun4h3YOoYfY9K1huY5gvxmrNLIw== "@volar/vue-code-gen@0.38.9": version "0.38.9" - resolved "https://registry.npmmirror.com/@volar/vue-code-gen/-/vue-code-gen-0.38.9.tgz#878f00fec82a2fc300396d70e26b0ea29952f740" + resolved "https://registry.yarnpkg.com/@volar/vue-code-gen/-/vue-code-gen-0.38.9.tgz#878f00fec82a2fc300396d70e26b0ea29952f740" integrity sha512-tzj7AoarFBKl7e41MR006ncrEmNPHALuk8aG4WdDIaG387X5//5KhWC5Ff3ZfB2InGSeNT+CVUd74M0gS20rjA== dependencies: "@volar/code-gen" "0.38.9" @@ -206,7 +204,7 @@ "@volar/vue-typescript@0.38.9": version "0.38.9" - resolved "https://registry.npmmirror.com/@volar/vue-typescript/-/vue-typescript-0.38.9.tgz#e5dfdc6f0d6dbea683647cd477fafbd483983b35" + resolved "https://registry.yarnpkg.com/@volar/vue-typescript/-/vue-typescript-0.38.9.tgz#e5dfdc6f0d6dbea683647cd477fafbd483983b35" integrity sha512-iJMQGU91ADi98u8V1vXd2UBmELDAaeSP0ZJaFjwosClQdKlJQYc6MlxxKfXBZisHqfbhdtrGRyaryulnYtliZw== dependencies: "@volar/code-gen" "0.38.9" @@ -215,158 +213,93 @@ "@vue/compiler-sfc" "^3.2.37" "@vue/reactivity" "^3.2.37" -"@vue/compiler-core@3.2.47", "@vue/compiler-core@^3.2.37": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz#3e07c684d74897ac9aa5922c520741f3029267f8" - integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig== +"@vue/compiler-core@3.4.21", "@vue/compiler-core@^3.2.37": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.21.tgz#868b7085378fc24e58c9aed14c8d62110a62be1a" + integrity sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og== dependencies: - "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.47" - estree-walker "^2.0.2" - source-map "^0.6.1" - -"@vue/compiler-core@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.5.tgz#9565aebaadef8649eb7c8e150a5f4f4e2542667d" - integrity sha512-Daka7P1z2AgKjzuueWXhwzIsKu0NkLB6vGbNVEV2iJ8GJTrzraZo/Sk4GWCMRtd/qVi3zwnk+Owbd/xSZbwHtQ== - dependencies: - "@babel/parser" "^7.23.6" - "@vue/shared" "3.4.5" + "@babel/parser" "^7.23.9" + "@vue/shared" "3.4.21" entities "^4.5.0" estree-walker "^2.0.2" source-map-js "^1.0.2" -"@vue/compiler-dom@3.2.47", "@vue/compiler-dom@^3.2.37": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz#a0b06caf7ef7056939e563dcaa9cbde30794f305" - integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ== - dependencies: - "@vue/compiler-core" "3.2.47" - "@vue/shared" "3.2.47" - -"@vue/compiler-dom@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.5.tgz#c53c9d7715b777b1d6d2adcbc491bfd4f9510edd" - integrity sha512-J8YlxknJVd90SXFJ4HwGANSAXsx5I0lK30sO/zvYV7s5gXf7gZR7r/1BmZ2ju7RGH1lnc6bpBc6nL61yW+PsAQ== +"@vue/compiler-dom@3.4.21", "@vue/compiler-dom@^3.2.37": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz#0077c355e2008207283a5a87d510330d22546803" + integrity sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA== dependencies: - "@vue/compiler-core" "3.4.5" - "@vue/shared" "3.4.5" + "@vue/compiler-core" "3.4.21" + "@vue/shared" "3.4.21" -"@vue/compiler-sfc@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.5.tgz#f93f986dfc5c7f72b9a5e00b48be75d9116cc948" - integrity sha512-jauvkDuSSUbP0ebhfNqljhShA90YEfX/0wZ+w40oZF43IjGyWYjqYaJbvMJwGOd+9+vODW6eSvnk28f0SGV7OQ== +"@vue/compiler-sfc@3.4.21", "@vue/compiler-sfc@^3.1.2", "@vue/compiler-sfc@^3.2.29", "@vue/compiler-sfc@^3.2.37": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz#4af920dc31ab99e1ff5d152b5fe0ad12181145b2" + integrity sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ== dependencies: - "@babel/parser" "^7.23.6" - "@vue/compiler-core" "3.4.5" - "@vue/compiler-dom" "3.4.5" - "@vue/compiler-ssr" "3.4.5" - "@vue/shared" "3.4.5" + "@babel/parser" "^7.23.9" + "@vue/compiler-core" "3.4.21" + "@vue/compiler-dom" "3.4.21" + "@vue/compiler-ssr" "3.4.21" + "@vue/shared" "3.4.21" estree-walker "^2.0.2" - magic-string "^0.30.5" - postcss "^8.4.32" + magic-string "^0.30.7" + postcss "^8.4.35" source-map-js "^1.0.2" -"@vue/compiler-sfc@^3.1.2", "@vue/compiler-sfc@^3.2.29", "@vue/compiler-sfc@^3.2.37": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d" - integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.47" - "@vue/compiler-dom" "3.2.47" - "@vue/compiler-ssr" "3.2.47" - "@vue/reactivity-transform" "3.2.47" - "@vue/shared" "3.2.47" - estree-walker "^2.0.2" - magic-string "^0.25.7" - postcss "^8.1.10" - source-map "^0.6.1" - -"@vue/compiler-ssr@3.2.47": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz#35872c01a273aac4d6070ab9d8da918ab13057ee" - integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw== - dependencies: - "@vue/compiler-dom" "3.2.47" - "@vue/shared" "3.2.47" - -"@vue/compiler-ssr@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.5.tgz#d412a4c9b10d69172a5ce0ec78de98dad441a58d" - integrity sha512-DDdEcDzj2lWTMfUMMtEpLDhURai9LhM0zSZ219jCt7b2Vyl0/jy3keFgCPMitG0V1S1YG4Cmws3lWHWdxHQOpg== - dependencies: - "@vue/compiler-dom" "3.4.5" - "@vue/shared" "3.4.5" - -"@vue/devtools-api@^6.5.0": - version "6.5.0" - resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07" - integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q== - -"@vue/reactivity-transform@3.2.47": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz#e45df4d06370f8abf29081a16afd25cffba6d84e" - integrity sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA== - dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.47" - "@vue/shared" "3.2.47" - estree-walker "^2.0.2" - magic-string "^0.25.7" - -"@vue/reactivity@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.5.tgz#68bc91cd356eed95dc5e9e0570e3f7becaee578b" - integrity sha512-BcWkKvjdvqJwb7BhhFkXPLDCecX4d4a6GATvCduJQDLv21PkPowAE5GKuIE5p6RC07/Lp9FMkkq4AYCTVF5KlQ== +"@vue/compiler-ssr@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz#b84ae64fb9c265df21fc67f7624587673d324fef" + integrity sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q== dependencies: - "@vue/shared" "3.4.5" + "@vue/compiler-dom" "3.4.21" + "@vue/shared" "3.4.21" + +"@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.5.1": + version "6.6.1" + resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.1.tgz#7c14346383751d9f6ad4bea0963245b30220ef83" + integrity sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA== -"@vue/reactivity@^3.2.37": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.47.tgz#1d6399074eadfc3ed35c727e2fd707d6881140b6" - integrity sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ== +"@vue/reactivity@3.4.21", "@vue/reactivity@^3.2.37": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.21.tgz#affd3415115b8ebf4927c8d2a0d6a24bccfa9f02" + integrity sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw== dependencies: - "@vue/shared" "3.2.47" + "@vue/shared" "3.4.21" -"@vue/runtime-core@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.5.tgz#2bf253a6f6b0430af1aacf0fdfd8f5782feefce9" - integrity sha512-wh9ELIOQKeWT9SaUPdLrsxRkZv14jp+SJm9aiQGWio+/MWNM3Lib0wE6CoKEqQ9+SCYyGjDBhTOTtO47kCgbkg== +"@vue/runtime-core@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.21.tgz#3749c3f024a64c4c27ecd75aea4ca35634db0062" + integrity sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA== dependencies: - "@vue/reactivity" "3.4.5" - "@vue/shared" "3.4.5" + "@vue/reactivity" "3.4.21" + "@vue/shared" "3.4.21" -"@vue/runtime-dom@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.5.tgz#b43736d66c32f6038778024587592cb9d68495de" - integrity sha512-n5ewvOjyG3IEpqGBahdPXODFSpVlSz3H4LF76Sx0XAqpIOqyJ5bIb2PrdYuH2ogBMAQPh+o5tnoH4nJpBr8U0Q== +"@vue/runtime-dom@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz#91f867ef64eff232cac45095ab28ebc93ac74588" + integrity sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw== dependencies: - "@vue/runtime-core" "3.4.5" - "@vue/shared" "3.4.5" + "@vue/runtime-core" "3.4.21" + "@vue/shared" "3.4.21" csstype "^3.1.3" -"@vue/server-renderer@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.5.tgz#4bfa7aa763217d8b2d4767d2c8d968a9d40352c1" - integrity sha512-jOFc/VE87yvifQpNju12VcqimH8pBLxdcT+t3xMeiED1K6DfH9SORyhFEoZlW5TG2Vwfn3Ul5KE+1aC99xnSBg== +"@vue/server-renderer@3.4.21": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.21.tgz#150751579d26661ee3ed26a28604667fa4222a97" + integrity sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg== dependencies: - "@vue/compiler-ssr" "3.4.5" - "@vue/shared" "3.4.5" - -"@vue/shared@3.2.47", "@vue/shared@^3.2.37": - version "3.2.47" - resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c" - integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ== + "@vue/compiler-ssr" "3.4.21" + "@vue/shared" "3.4.21" -"@vue/shared@3.4.5": - version "3.4.5" - resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.5.tgz#c8b4eb6399a7fc986565ea736d938b3a1579256d" - integrity sha512-6XptuzlMvN4l4cDnDw36pdGEV+9njYkQ1ZE0Q6iZLwrKefKaOJyiFmcP3/KBDHbt72cJZGtllAc1GaHe6XGAyg== +"@vue/shared@3.4.21", "@vue/shared@^3.2.37": + version "3.4.21" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.21.tgz#de526a9059d0a599f0b429af7037cd0c3ed7d5a1" + integrity sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g== "@vueuse/core@^9.1.0": version "9.13.0" - resolved "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz#2f69e66d1905c1e4eebc249a01759cf88ea00cf4" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-9.13.0.tgz#2f69e66d1905c1e4eebc249a01759cf88ea00cf4" integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw== dependencies: "@types/web-bluetooth" "^0.0.16" @@ -376,33 +309,33 @@ "@vueuse/metadata@9.13.0": version "9.13.0" - resolved "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz#bc25a6cdad1b1a93c36ce30191124da6520539ff" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-9.13.0.tgz#bc25a6cdad1b1a93c36ce30191124da6520539ff" integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ== "@vueuse/shared@9.13.0": version "9.13.0" - resolved "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz#089ff4cc4e2e7a4015e57a8f32e4b39d096353b9" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-9.13.0.tgz#089ff4cc4e2e7a4015e57a8f32e4b39d096353b9" integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw== dependencies: vue-demi "*" "@wangeditor/basic-modules@^1.1.7": version "1.1.7" - resolved "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz#a9c3ccf4ef53332f29550d59d3676e15f395946f" + resolved "https://registry.yarnpkg.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz#a9c3ccf4ef53332f29550d59d3676e15f395946f" integrity sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg== dependencies: is-url "^1.2.4" "@wangeditor/code-highlight@^1.0.3": version "1.0.3" - resolved "https://registry.npmmirror.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz#90256857714d5c0cf83ac475aea64db7bf29a7cd" + resolved "https://registry.yarnpkg.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz#90256857714d5c0cf83ac475aea64db7bf29a7cd" integrity sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw== dependencies: prismjs "^1.23.0" "@wangeditor/core@^1.1.19": version "1.1.19" - resolved "https://registry.npmmirror.com/@wangeditor/core/-/core-1.1.19.tgz#f9155f7fd92d03cb1982405b3b82e54c31f1c2b0" + resolved "https://registry.yarnpkg.com/@wangeditor/core/-/core-1.1.19.tgz#f9155f7fd92d03cb1982405b3b82e54c31f1c2b0" integrity sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q== dependencies: "@types/event-emitter" "^0.3.3" @@ -414,12 +347,12 @@ "@wangeditor/editor-for-vue@^5.1.12": version "5.1.12" - resolved "https://registry.npmmirror.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz#f7d5f239b39cdfc01d31151488de8443fe6edc64" + resolved "https://registry.yarnpkg.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz#f7d5f239b39cdfc01d31151488de8443fe6edc64" integrity sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ== "@wangeditor/editor@^5.1.23": version "5.1.23" - resolved "https://registry.npmmirror.com/@wangeditor/editor/-/editor-5.1.23.tgz#c9d2007b7cb0ceef6b72692b4ee87b01ee2367b3" + resolved "https://registry.yarnpkg.com/@wangeditor/editor/-/editor-5.1.23.tgz#c9d2007b7cb0ceef6b72692b4ee87b01ee2367b3" integrity sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ== dependencies: "@uppy/core" "^2.1.1" @@ -446,37 +379,37 @@ "@wangeditor/list-module@^1.0.5": version "1.0.5" - resolved "https://registry.npmmirror.com/@wangeditor/list-module/-/list-module-1.0.5.tgz#3fc0b167acddf885536b45fa0c127f9c6adaea33" + resolved "https://registry.yarnpkg.com/@wangeditor/list-module/-/list-module-1.0.5.tgz#3fc0b167acddf885536b45fa0c127f9c6adaea33" integrity sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ== "@wangeditor/table-module@^1.1.4": version "1.1.4" - resolved "https://registry.npmmirror.com/@wangeditor/table-module/-/table-module-1.1.4.tgz#757d4a5868b2b658041cd323854a4d707c8347e9" + resolved "https://registry.yarnpkg.com/@wangeditor/table-module/-/table-module-1.1.4.tgz#757d4a5868b2b658041cd323854a4d707c8347e9" integrity sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w== "@wangeditor/upload-image-module@^1.0.2": version "1.0.2" - resolved "https://registry.npmmirror.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz#89e9b9467e10cbc6b11dc5748e08dd23aaebee30" + resolved "https://registry.yarnpkg.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz#89e9b9467e10cbc6b11dc5748e08dd23aaebee30" integrity sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA== "@wangeditor/video-module@^1.1.4": version "1.1.4" - resolved "https://registry.npmmirror.com/@wangeditor/video-module/-/video-module-1.1.4.tgz#b9df1b3ab2cd53f678b19b4d927e200774a6f532" + resolved "https://registry.yarnpkg.com/@wangeditor/video-module/-/video-module-1.1.4.tgz#b9df1b3ab2cd53f678b19b4d927e200774a6f532" integrity sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg== -acorn@^8.8.2: - version "8.8.2" - resolved "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.10.0, acorn@^8.11.3: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== adler-32@~1.3.0: version "1.3.1" - resolved "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2" + resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2" integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A== anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -484,59 +417,59 @@ anymatch@~3.1.2: async-validator@^4.2.5: version "4.2.5" - resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339" integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== axios@^1.6.3: - version "1.6.5" - resolved "https://registry.npmmirror.com/axios/-/axios-1.6.5.tgz#2c090da14aeeab3770ad30c3a1461bc970fb0cd8" - integrity sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg== + version "1.6.8" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" + integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== dependencies: - follow-redirects "^1.15.4" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" cfb@~1.2.1: version "1.2.2" - resolved "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44" + resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44" integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA== dependencies: adler-32 "~1.3.0" crc-32 "~1.2.0" -chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +chokidar@^3.5.3, chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -550,72 +483,85 @@ chokidar@^3.5.3: codepage@~1.15.0: version "1.15.0" - resolved "https://registry.npmmirror.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" + resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA== combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" compute-scroll-into-view@^1.0.20: version "1.0.20" - resolved "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43" integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg== +countup.js@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/countup.js/-/countup.js-2.8.0.tgz#64951f2df3ede28839413d654d8fef28251c32a8" + integrity sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ== + crc-32@~1.2.0, crc-32@~1.2.1: version "1.2.2" - resolved "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== -cropperjs@^1.5.6: - version "1.5.13" - resolved "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.5.13.tgz#eb1682f01d17c70ed5244317091d745c9a249ef8" - integrity sha512-by7jKAo73y5/Do0K6sxdTKHgndY0NMjG2bEdgeJxycbcmHuCiMXqw8sxy5C5Y5WTOTcDGmbT7Sr5CgKOXR06OA== - csstype@^3.1.3: version "3.1.3" - resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.npmmirror.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== +d@1, d@^1.0.1, d@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" + integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== dependencies: - es5-ext "^0.10.50" - type "^1.0.1" + es5-ext "^0.10.64" + type "^2.7.2" dayjs@^1.11.3: - version "1.11.7" - resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== debug@^4.3.4: version "4.3.4" - resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== dom7@^3.0.0: version "3.0.0" - resolved "https://registry.npmmirror.com/dom7/-/dom7-3.0.0.tgz#b861ce5d67a6becd7aaa3ad02942ff14b1240331" + resolved "https://registry.yarnpkg.com/dom7/-/dom7-3.0.0.tgz#b861ce5d67a6becd7aaa3ad02942ff14b1240331" integrity sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g== dependencies: ssr-window "^3.0.0-alpha.1" -element-plus@^2.4.4: - version "2.4.4" - resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.4.4.tgz#962be40b4843381af04b8f799bfc142072184b8b" - integrity sha512-TlKubXJgxwhER0dw+8ULn9hr9kZjraV4R6Q/eidwWUwCKxwXYPBGmMKsZ/85tlxlhMYbcLZd/YZh6G3QkHX4fg== +echarts-wordcloud@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/echarts-wordcloud/-/echarts-wordcloud-2.1.0.tgz#c3de6fe267044f6c3343e4ff0e05eedb01c05096" + integrity sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ== + +echarts@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.5.0.tgz#c13945a7f3acdd67c134d8a9ac67e917830113ac" + integrity sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw== + dependencies: + tslib "2.3.0" + zrender "5.5.0" + +element-plus@^2.6.3: + version "2.7.0" + resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-2.7.0.tgz#1d72b06946c46a6f18e5315610b7f0147b8efb24" + integrity sha512-WAiaFLavuWFxof9qwkC27jvkh9nRcNnB506g1vvJSiVaVqjCBWUFCIyJKeN11M1qcv2cS5VV5PfSLjTIkrw87A== dependencies: "@ctrl/tinycolor" "^3.4.1" "@element-plus/icons-vue" "^2.3.1" @@ -635,21 +581,22 @@ element-plus@^2.4.4: entities@^4.5.0: version "4.5.0" - resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14: - version "0.10.62" - resolved "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.35, es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@^2.0.3: version "2.0.3" - resolved "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== dependencies: d "1" @@ -657,116 +604,116 @@ es6-iterator@^2.0.3: es6-symbol "^3.1.1" es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + version "3.1.4" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" + integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== dependencies: - d "^1.0.1" - ext "^1.1.2" + d "^1.0.2" + ext "^1.7.0" esbuild-android-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz#20a7ae1416c8eaade917fb2453c1259302c637a5" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz#20a7ae1416c8eaade917fb2453c1259302c637a5" integrity sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA== esbuild-android-arm64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz#9cc0ec60581d6ad267568f29cf4895ffdd9f2f04" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz#9cc0ec60581d6ad267568f29cf4895ffdd9f2f04" integrity sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ== esbuild-darwin-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz#428e1730ea819d500808f220fbc5207aea6d4410" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz#428e1730ea819d500808f220fbc5207aea6d4410" integrity sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg== esbuild-darwin-arm64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz#b6dfc7799115a2917f35970bfbc93ae50256b337" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz#b6dfc7799115a2917f35970bfbc93ae50256b337" integrity sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA== esbuild-freebsd-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz#4e190d9c2d1e67164619ae30a438be87d5eedaf2" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz#4e190d9c2d1e67164619ae30a438be87d5eedaf2" integrity sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA== esbuild-freebsd-arm64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz#18a4c0344ee23bd5a6d06d18c76e2fd6d3f91635" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz#18a4c0344ee23bd5a6d06d18c76e2fd6d3f91635" integrity sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA== esbuild-linux-32@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz#9a329731ee079b12262b793fb84eea762e82e0ce" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz#9a329731ee079b12262b793fb84eea762e82e0ce" integrity sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg== esbuild-linux-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz#532738075397b994467b514e524aeb520c191b6c" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz#532738075397b994467b514e524aeb520c191b6c" integrity sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw== esbuild-linux-arm64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz#5372e7993ac2da8f06b2ba313710d722b7a86e5d" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz#5372e7993ac2da8f06b2ba313710d722b7a86e5d" integrity sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug== esbuild-linux-arm@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz#e734aaf259a2e3d109d4886c9e81ec0f2fd9a9cc" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz#e734aaf259a2e3d109d4886c9e81ec0f2fd9a9cc" integrity sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA== esbuild-linux-mips64le@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz#c0487c14a9371a84eb08fab0e1d7b045a77105eb" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz#c0487c14a9371a84eb08fab0e1d7b045a77105eb" integrity sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ== esbuild-linux-ppc64le@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz#af048ad94eed0ce32f6d5a873f7abe9115012507" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz#af048ad94eed0ce32f6d5a873f7abe9115012507" integrity sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w== esbuild-linux-riscv64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz#423ed4e5927bd77f842bd566972178f424d455e6" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz#423ed4e5927bd77f842bd566972178f424d455e6" integrity sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg== esbuild-linux-s390x@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz#21d21eaa962a183bfb76312e5a01cc5ae48ce8eb" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz#21d21eaa962a183bfb76312e5a01cc5ae48ce8eb" integrity sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ== esbuild-netbsd-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz#ae75682f60d08560b1fe9482bfe0173e5110b998" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz#ae75682f60d08560b1fe9482bfe0173e5110b998" integrity sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg== esbuild-openbsd-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz#79591a90aa3b03e4863f93beec0d2bab2853d0a8" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz#79591a90aa3b03e4863f93beec0d2bab2853d0a8" integrity sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ== esbuild-sunos-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz#fd528aa5da5374b7e1e93d36ef9b07c3dfed2971" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz#fd528aa5da5374b7e1e93d36ef9b07c3dfed2971" integrity sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw== esbuild-windows-32@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz#0e92b66ecdf5435a76813c4bc5ccda0696f4efc3" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz#0e92b66ecdf5435a76813c4bc5ccda0696f4efc3" integrity sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ== esbuild-windows-64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz#0fc761d785414284fc408e7914226d33f82420d0" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz#0fc761d785414284fc408e7914226d33f82420d0" integrity sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw== esbuild-windows-arm64@0.15.18: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz#5b5bdc56d341d0922ee94965c89ee120a6a86eb7" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz#5b5bdc56d341d0922ee94965c89ee120a6a86eb7" integrity sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ== esbuild@^0.15.9: version "0.15.18" - resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz#ea894adaf3fbc036d32320a00d4d6e4978a2f36d" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.18.tgz#ea894adaf3fbc036d32320a00d4d6e4978a2f36d" integrity sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q== optionalDependencies: "@esbuild/android-arm" "0.15.18" @@ -794,38 +741,48 @@ esbuild@^0.15.9: escape-html@^1.0.3: version "1.0.3" - resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^5.0.0: version "5.0.0" - resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + estree-walker@^2.0.2: version "2.0.2" - resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== event-emitter@^0.3.5: version "0.3.5" - resolved "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== dependencies: d "1" es5-ext "~0.10.14" -ext@^1.1.2: +ext@^1.7.0: version "1.7.0" - resolved "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== dependencies: type "^2.7.2" fast-glob@^3.2.12: - version "3.2.12" - resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -834,27 +791,27 @@ fast-glob@^3.2.12: micromatch "^4.0.4" fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" -follow-redirects@^1.15.4: - version "1.15.4" - resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== +follow-redirects@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== form-data@^4.0.0: version "4.0.0" - resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" @@ -863,202 +820,202 @@ form-data@^4.0.0: frac@~1.1.2: version "1.1.2" - resolved "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" + resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA== fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmmirror.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" html-void-elements@^2.0.0: version "2.0.1" - resolved "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A== i18next@^20.4.0: version "20.6.1" - resolved "https://registry.npmmirror.com/i18next/-/i18next-20.6.1.tgz#535e5f6e5baeb685c7d25df70db63bf3cc0aa345" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.6.1.tgz#535e5f6e5baeb685c7d25df70db63bf3cc0aa345" integrity sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A== dependencies: "@babel/runtime" "^7.12.0" immer@^9.0.6: - version "9.0.19" - resolved "https://registry.npmmirror.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b" - integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ== + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has "^1.0.3" + hasown "^2.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-hotkey@^0.2.0: version "0.2.0" - resolved "https://registry.npmmirror.com/is-hotkey/-/is-hotkey-0.2.0.tgz#1835a68171a91e5c9460869d96336947c8340cef" + resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.2.0.tgz#1835a68171a91e5c9460869d96336947c8340cef" integrity sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw== is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-plain-object@^5.0.0: version "5.0.0" - resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== is-url@^1.2.4: version "1.2.4" - resolved "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== jsonc-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + version "3.2.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" + integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== local-pkg@^0.4.2, local-pkg@^0.4.3: version "0.4.3" - resolved "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== lodash-es@^4.17.21: version "4.17.21" - resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== lodash-unified@^1.0.2: version "1.0.3" - resolved "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz#80b1eac10ed2eb02ed189f08614a29c27d07c894" + resolved "https://registry.yarnpkg.com/lodash-unified/-/lodash-unified-1.0.3.tgz#80b1eac10ed2eb02ed189f08614a29c27d07c894" integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ== lodash.camelcase@^4.3.0: version "4.3.0" - resolved "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.clonedeep@^4.5.0: version "4.5.0" - resolved "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== lodash.debounce@^4.0.8: version "4.0.8" - resolved "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.foreach@^4.5.0: version "4.5.0" - resolved "https://registry.npmmirror.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" integrity sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ== lodash.isequal@^4.5.0: version "4.5.0" - resolved "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== lodash.throttle@^4.1.1: version "4.1.1" - resolved "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== lodash.toarray@^4.4.0: version "4.4.0" - resolved "https://registry.npmmirror.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" integrity sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw== lodash@^4.17.21: version "4.17.21" - resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== magic-string@^0.25.7: version "0.25.9" - resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== dependencies: sourcemap-codec "^1.4.8" magic-string@^0.26.7: version "0.26.7" - resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f" integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow== dependencies: sourcemap-codec "^1.4.8" magic-string@^0.27.0: version "0.27.0" - resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" -magic-string@^0.30.5: - version "0.30.5" - resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" - integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== +magic-string@^0.30.7: + version "0.30.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.9.tgz#8927ae21bfdd856310e07a1bc8dd5e73cb6c251d" + integrity sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" md-editor-v3@^2.11.2: version "2.11.3" - resolved "https://registry.npmmirror.com/md-editor-v3/-/md-editor-v3-2.11.3.tgz#f66e653034aeff03aca48d7728ce03c504db8d28" + resolved "https://registry.yarnpkg.com/md-editor-v3/-/md-editor-v3-2.11.3.tgz#f66e653034aeff03aca48d7728ce03c504db8d28" integrity sha512-SCfS4qMy0HldFdplcIGUMCpSv8qkNWkYShSdv2gTHeViKduA34zV89BOrWcqls2EZSlvt2n3G7nHRzYUvJjDKw== memoize-one@^6.0.0: version "6.0.0" - resolved "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== merge2@^1.3.0: version "1.4.1" - resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -1066,222 +1023,213 @@ micromatch@^4.0.4: mime-db@1.52.0: version "1.52.0" - resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-match@^1.0.2: version "1.0.2" - resolved "https://registry.npmmirror.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8" + resolved "https://registry.yarnpkg.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8" integrity sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg== dependencies: wildcard "^1.1.0" mime-types@^2.1.12: version "2.1.35" - resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" minimatch@^5.1.1: version "5.1.6" - resolved "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" -mlly@^1.1.0, mlly@^1.1.1: - version "1.1.1" - resolved "https://registry.npmmirror.com/mlly/-/mlly-1.1.1.tgz#f1838b14795e2cc284aa4ebcc76a258a52e6f537" - integrity sha512-Jnlh4W/aI4GySPo6+DyTN17Q75KKbLTyFK8BrGhjNP4rxuUjbRWhE6gHg3bs33URWAF44FRm7gdQA348i3XxRw== +mlly@^1.1.0, mlly@^1.2.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.6.1.tgz#0983067dc3366d6314fc5e12712884e6978d028f" + integrity sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA== dependencies: - acorn "^8.8.2" - pathe "^1.1.0" - pkg-types "^1.0.1" - ufo "^1.1.0" + acorn "^8.11.3" + pathe "^1.1.2" + pkg-types "^1.0.3" + ufo "^1.3.2" ms@2.1.2: version "2.1.2" - resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== namespace-emitter@^2.0.1: version "2.0.1" - resolved "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c" + resolved "https://registry.yarnpkg.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c" integrity sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g== -nanoid@^3.1.25, nanoid@^3.2.0, nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== - -nanoid@^3.3.7: +nanoid@^3.1.25, nanoid@^3.2.0, nanoid@^3.3.7: version "3.3.7" - resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== next-tick@^1.1.0: version "1.1.0" - resolved "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-wheel-es@^1.2.0: version "1.2.0" - resolved "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz#0fa2593d619f7245a541652619105ab076acf09e" + resolved "https://registry.yarnpkg.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz#0fa2593d619f7245a541652619105ab076acf09e" integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw== nprogress@^0.2.0: version "0.2.0" - resolved "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -pathe@^1.0.0, pathe@^1.1.0: - version "1.1.0" - resolved "https://registry.npmmirror.com/pathe/-/pathe-1.1.0.tgz#e2e13f6c62b31a3289af4ba19886c230f295ec03" - integrity sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w== +pathe@^1.0.0, pathe@^1.1.0, pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== picocolors@^1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pinia@^2.1.7: version "2.1.7" - resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc" + resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc" integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ== dependencies: "@vue/devtools-api" "^6.5.0" vue-demi ">=0.14.5" -pkg-types@^1.0.1: - version "1.0.2" - resolved "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.0.2.tgz#c233efc5210a781e160e0cafd60c0d0510a4b12e" - integrity sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ== +pkg-types@^1.0.1, pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== dependencies: jsonc-parser "^3.2.0" - mlly "^1.1.1" + mlly "^1.2.0" pathe "^1.1.0" -postcss@^8.1.10, postcss@^8.4.18: - version "8.4.21" - resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" - integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== - dependencies: - nanoid "^3.3.4" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -postcss@^8.4.32: - version "8.4.33" - resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742" - integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg== +postcss@^8.4.18, postcss@^8.4.35: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== dependencies: nanoid "^3.3.7" picocolors "^1.0.0" - source-map-js "^1.0.2" + source-map-js "^1.2.0" preact@^10.5.13: - version "10.13.0" - resolved "https://registry.npmmirror.com/preact/-/preact-10.13.0.tgz#f8bd3cf257a4dbe41da71a52131b79916d4ca89d" - integrity sha512-ERdIdUpR6doqdaSIh80hvzebHB7O6JxycOhyzAeLEchqOq/4yueslQbfnPwXaNhAYacFTyCclhwkEbOumT0tHw== + version "10.20.2" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.20.2.tgz#0b343299a8c020562311cc25db93b3d832ec5e71" + integrity sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg== prismjs@^1.23.0: version "1.29.0" - resolved "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +resize-detector@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/resize-detector/-/resize-detector-0.3.0.tgz#fe495112e184695500a8f51e0389f15774cb1cfc" + integrity sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ== resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" reusify@^1.0.4: version "1.0.4" - resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rollup@^2.79.1: version "2.79.1" - resolved "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== optionalDependencies: fsevents "~2.3.2" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" schart.js@^3.0.0: version "3.0.4" - resolved "https://registry.npmmirror.com/schart.js/-/schart.js-3.0.4.tgz#3bfb3e1ebbc63b4f5ce84606ee03fe575355defc" + resolved "https://registry.yarnpkg.com/schart.js/-/schart.js-3.0.4.tgz#3bfb3e1ebbc63b4f5ce84606ee03fe575355defc" integrity sha512-uylb2u9rrHX1jyAuSAJUQON8XTfyDKI9kWj1J3fUlCQCkLVZ4HG4+IiV8qm//Z71dqvLI78QZ/fCBw0reB22Zw== scroll-into-view-if-needed@^2.2.28: version "2.2.31" - resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587" + resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587" integrity sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA== dependencies: compute-scroll-into-view "^1.0.20" scule@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/scule/-/scule-1.0.0.tgz#895e6f4ba887e78d8b9b4111e23ae84fef82376d" - integrity sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ== + version "1.3.0" + resolved "https://registry.yarnpkg.com/scule/-/scule-1.3.0.tgz#6efbd22fd0bb801bdcc585c89266a7d2daa8fbd3" + integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g== slate-history@^0.66.0: version "0.66.0" - resolved "https://registry.npmmirror.com/slate-history/-/slate-history-0.66.0.tgz#ac63fddb903098ceb4c944433e3f75fe63acf940" + resolved "https://registry.yarnpkg.com/slate-history/-/slate-history-0.66.0.tgz#ac63fddb903098ceb4c944433e3f75fe63acf940" integrity sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng== dependencies: is-plain-object "^5.0.0" slate@^0.72.0: version "0.72.8" - resolved "https://registry.npmmirror.com/slate/-/slate-0.72.8.tgz#5a018edf24e45448655293a68bfbcf563aa5ba81" + resolved "https://registry.yarnpkg.com/slate/-/slate-0.72.8.tgz#5a018edf24e45448655293a68bfbcf563aa5ba81" integrity sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw== dependencies: immer "^9.0.6" @@ -1289,84 +1237,79 @@ slate@^0.72.0: tiny-warning "^1.0.3" snabbdom@^3.1.0: - version "3.5.1" - resolved "https://registry.npmmirror.com/snabbdom/-/snabbdom-3.5.1.tgz#25f80ef15b194baea703d9d5441892e369de18e1" - integrity sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.6.2.tgz#57dd66878f6320497fa7f67941df356a045c75a1" + integrity sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q== -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map-js@^1.0.2, source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== sourcemap-codec@^1.4.8: version "1.4.8" - resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== ssf@~0.11.2: version "0.11.2" - resolved "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" + resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g== dependencies: frac "~1.1.2" ssr-window@^3.0.0-alpha.1: version "3.0.0" - resolved "https://registry.npmmirror.com/ssr-window/-/ssr-window-3.0.0.tgz#fd5b82801638943e0cc704c4691801435af7ac37" + resolved "https://registry.yarnpkg.com/ssr-window/-/ssr-window-3.0.0.tgz#fd5b82801638943e0cc704c4691801435af7ac37" integrity sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA== strip-literal@^1.0.0: - version "1.0.1" - resolved "https://registry.npmmirror.com/strip-literal/-/strip-literal-1.0.1.tgz#0115a332710c849b4e46497891fb8d585e404bd2" - integrity sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q== + version "1.3.0" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-1.3.0.tgz#db3942c2ec1699e6836ad230090b84bb458e3a07" + integrity sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg== dependencies: - acorn "^8.8.2" + acorn "^8.10.0" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tiny-warning@^1.0.3: version "1.0.3" - resolved "https://registry.npmmirror.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" -type@^1.0.1: - version "1.2.0" - resolved "https://registry.npmmirror.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== type@^2.7.2: version "2.7.2" - resolved "https://registry.npmmirror.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== typescript@^4.6.4: version "4.9.5" - resolved "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -ufo@^1.1.0: - version "1.1.0" - resolved "https://registry.npmmirror.com/ufo/-/ufo-1.1.0.tgz#a5c4c814b0a98f7e0ca42c478688663fd3e3c037" - integrity sha512-LQc2s/ZDMaCN3QLpa+uzHUOQ7SdV0qgv3VBXOolQGXTaaZpIur6PwUclF5nN2hNkiTRcUugXd1zFOW3FLJ135Q== +ufo@^1.3.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.3.tgz#3325bd3c977b6c6cd3160bf4ff52989adc9d3344" + integrity sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw== unimport@^1.0.1: version "1.3.0" - resolved "https://registry.npmmirror.com/unimport/-/unimport-1.3.0.tgz#167ab78e60ea0e36a9a764c7b608ee95d7b2411c" + resolved "https://registry.yarnpkg.com/unimport/-/unimport-1.3.0.tgz#167ab78e60ea0e36a9a764c7b608ee95d7b2411c" integrity sha512-fOkrdxglsHd428yegH0wPH/6IfaSdDeMXtdRGn6en/ccyzc2aaoxiUTMrJyc6Bu+xoa18RJRPMfLUHEzjz8atw== dependencies: "@rollup/pluginutils" "^5.0.2" @@ -1383,7 +1326,7 @@ unimport@^1.0.1: unplugin-auto-import@^0.11.2: version "0.11.5" - resolved "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.11.5.tgz#84c27e5f230bc1fc9004c162a39b81fcf89da740" + resolved "https://registry.yarnpkg.com/unplugin-auto-import/-/unplugin-auto-import-0.11.5.tgz#84c27e5f230bc1fc9004c162a39b81fcf89da740" integrity sha512-nvbL2AQwLRR8wbHpJ6L1EBVNmjN045RSedTa4NtsGRkSQFXkI1iKHs4dTqJwcKZsnFrZOAKtLPiN1/oQTObLZw== dependencies: "@antfu/utils" "^0.7.0" @@ -1395,7 +1338,7 @@ unplugin-auto-import@^0.11.2: unplugin-vue-components@^0.22.4: version "0.22.12" - resolved "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.22.12.tgz#39013f77be72d32df9d6ca1599e592a484015612" + resolved "https://registry.yarnpkg.com/unplugin-vue-components/-/unplugin-vue-components-0.22.12.tgz#39013f77be72d32df9d6ca1599e592a484015612" integrity sha512-FxyzsuBvMCYPIk+8cgscGBQ345tvwVu+qY5IhE++eorkyvA4Z1TiD/HCiim+Kbqozl10i4K+z+NCa2WO2jexRA== dependencies: "@antfu/utils" "^0.7.2" @@ -1410,27 +1353,27 @@ unplugin-vue-components@^0.22.4: unplugin "^1.0.1" unplugin@^1.0.0, unplugin@^1.0.1: - version "1.1.0" - resolved "https://registry.npmmirror.com/unplugin/-/unplugin-1.1.0.tgz#96a14aa52d7637a56a88dec6baf4a73902f2db87" - integrity sha512-I8obQ8Rs/hnkxokRV6g8JKOQFgYNnTd9DL58vcSt5IJ9AkK8wbrtsnzD5hi4BJlvcY536JzfEXj9L6h7j559/A== + version "1.10.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.10.1.tgz#8ceda065dc71bc67d923dea0920f05c67f2cd68c" + integrity sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg== dependencies: - acorn "^8.8.2" - chokidar "^3.5.3" + acorn "^8.11.3" + chokidar "^3.6.0" webpack-sources "^3.2.3" - webpack-virtual-modules "^0.5.0" + webpack-virtual-modules "^0.6.1" vite-plugin-vue-setup-extend@^0.4.0: version "0.4.0" - resolved "https://registry.npmmirror.com/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz#ebbbe265320039b8c6a3b9fcae3b8d152ecf4a13" + resolved "https://registry.yarnpkg.com/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz#ebbbe265320039b8c6a3b9fcae3b8d152ecf4a13" integrity sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ== dependencies: "@vue/compiler-sfc" "^3.2.29" magic-string "^0.25.7" vite@^3.0.0: - version "3.2.5" - resolved "https://registry.npmmirror.com/vite/-/vite-3.2.5.tgz#dee5678172a8a0ab3e547ad4148c3d547f90e86a" - integrity sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ== + version "3.2.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.10.tgz#7ac79fead82cfb6b5bf65613cd82fba6dcc81340" + integrity sha512-Dx3olBo/ODNiMVk/cA5Yft9Ws+snLOXrhLtrI3F4XLt4syz2Yg8fayZMWScPKoz12v5BUv7VEmQHnsfpY80fYw== dependencies: esbuild "^0.15.9" postcss "^8.4.18" @@ -1439,83 +1382,89 @@ vite@^3.0.0: optionalDependencies: fsevents "~2.3.2" -vue-cropperjs@^5.0.0: - version "5.0.0" - resolved "https://registry.npmmirror.com/vue-cropperjs/-/vue-cropperjs-5.0.0.tgz#7f8cbc460737af3831b4ded634c95905198e329e" - integrity sha512-RhnC8O33uRZNkn74aiHZwNHnBJOXWlS4P6gsRI0lw4cZlWjKSCywZI9oSI9POlIPI6OYv30jvnHMXGch85tw7w== - dependencies: - cropperjs "^1.5.6" +vue-cropper@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/vue-cropper/-/vue-cropper-1.1.1.tgz#e1d2729f7139182a893e8badcb8f33257aa2a40f" + integrity sha512-WsqKMpaBf9Osi1LQlE/5AKdD0nHWOy1asLXocaG8NomOWO07jiZi968+/PbMmnD0QbPJOumDQaGuGa13qys85A== + +vue-demi@*, vue-demi@>=0.14.5: + version "0.14.7" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2" + integrity sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA== -vue-demi@*: +vue-demi@^0.13.11: version "0.13.11" - resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99" + resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99" integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A== -vue-demi@>=0.14.5: - version "0.14.6" - resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92" - integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w== +vue-echarts@^6.6.9: + version "6.6.9" + resolved "https://registry.yarnpkg.com/vue-echarts/-/vue-echarts-6.6.9.tgz#151372ecd086db985dafeeebd3ea83c8d4d2846b" + integrity sha512-mojIq3ZvsjabeVmDthhAUDV8Kgf2Rr/X4lV4da7gEFd1fP05gcSJ0j7wa7HQkW5LlFmF2gdCJ8p4Chas6NNIQQ== + dependencies: + resize-detector "^0.3.0" + vue-demi "^0.13.11" vue-router@^4.2.5: - version "4.2.5" - resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a" - integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw== + version "4.3.0" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.3.0.tgz#d5913f27bf68a0a178ee798c3c88be471811a235" + integrity sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ== dependencies: - "@vue/devtools-api" "^6.5.0" + "@vue/devtools-api" "^6.5.1" vue-schart@^2.0.0: version "2.0.0" - resolved "https://registry.npmmirror.com/vue-schart/-/vue-schart-2.0.0.tgz#744f26bbbf3c10bc5a584931e002335970810901" + resolved "https://registry.yarnpkg.com/vue-schart/-/vue-schart-2.0.0.tgz#744f26bbbf3c10bc5a584931e002335970810901" integrity sha512-qAu3e5wfMcq26wK1xeHExEWfGpnjfoN1R/9QXblNi+AsU/p52X7tTwhi+Fw7H/otfEufhEY2X7z7emaoF4QO+g== dependencies: schart.js "^3.0.0" vue-tsc@^0.38.4: version "0.38.9" - resolved "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-0.38.9.tgz#9e945937667f704325328db8af1cc6bc7314b85e" + resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.38.9.tgz#9e945937667f704325328db8af1cc6bc7314b85e" integrity sha512-Yoy5phgvGqyF98Fb4mYqboR4Q149jrdcGv5kSmufXJUq++RZJ2iMVG0g6zl+v3t4ORVWkQmRpsV4x2szufZ0LQ== dependencies: "@volar/vue-typescript" "0.38.9" -vue@^3.3.0: - version "3.4.5" - resolved "https://registry.npmmirror.com/vue/-/vue-3.4.5.tgz#c08b9d903a20faaf4df7270bf2fa7487741b2294" - integrity sha512-VH6nHFhLPjgu2oh5vEBXoNZxsGHuZNr3qf4PHClwJWw6IDqw6B3x+4J+ABdoZ0aJuT8Zi0zf3GpGlLQCrGWHrw== +vue@^3.4.5: + version "3.4.21" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.21.tgz#69ec30e267d358ee3a0ce16612ba89e00aaeb731" + integrity sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA== dependencies: - "@vue/compiler-dom" "3.4.5" - "@vue/compiler-sfc" "3.4.5" - "@vue/runtime-dom" "3.4.5" - "@vue/server-renderer" "3.4.5" - "@vue/shared" "3.4.5" + "@vue/compiler-dom" "3.4.21" + "@vue/compiler-sfc" "3.4.21" + "@vue/runtime-dom" "3.4.21" + "@vue/server-renderer" "3.4.21" + "@vue/shared" "3.4.21" webpack-sources@^3.2.3: version "3.2.3" - resolved "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack-virtual-modules@^0.5.0: - version "0.5.0" - resolved "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" - integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== +webpack-virtual-modules@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz#ac6fdb9c5adb8caecd82ec241c9631b7a3681b6f" + integrity sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg== wildcard@^1.1.0: version "1.1.2" - resolved "https://registry.npmmirror.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5" integrity sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng== wmf@~1.0.1: version "1.0.2" - resolved "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" + resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw== word@~0.3.0: version "0.3.0" - resolved "https://registry.npmmirror.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" + resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA== xlsx@^0.18.5: version "0.18.5" - resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0" + resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0" integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ== dependencies: adler-32 "~1.3.0" @@ -1525,3 +1474,10 @@ xlsx@^0.18.5: ssf "~0.11.2" wmf "~1.0.1" word "~0.3.0" + +zrender@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.5.0.tgz#54d0d6c4eda81a96d9f60a9cd74dc48ea026bc1e" + integrity sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w== + dependencies: + tslib "2.3.0"