Compare commits

...

30 Commits

Author SHA1 Message Date
xiaoxian521
cafc588e4c chore: update 2.1.0 version 2021-10-14 17:50:03 +08:00
xiaoxian521
1687097e63 fix: element-plus locale config 2021-10-14 17:36:16 +08:00
xiaoxian521
b87183cb75 types: fix some types 2021-10-13 21:44:49 +08:00
xiaoxian521
80328d2e20 types: add mitt types 2021-10-13 19:51:47 +08:00
xiaoxian521
ea97cb20f3 docs: update settings.json 2021-10-13 16:17:54 +08:00
xiaoxian521
262113525d perf: route 2021-10-13 13:14:28 +08:00
xiaoxian521
e080fe4128 feat: 额外图标(比如这个是新加的页面,路由菜单右上角显示个新图标) 2021-10-13 11:57:27 +08:00
xiaoxian521
b1702ed7fe feat: 路由动画(每个路由都可添加不同动画) 2021-10-13 10:31:38 +08:00
啝裳
a31d154806 perf/route (#54)
* perf: router

* perf: route
2021-10-12 23:33:13 +08:00
xiaoxian521
0408fa6f96 workflow: update linter.yml 2021-10-12 23:24:31 +08:00
xiaoxian521
45c2c4a301 fix: showLink is false,children menu 404 2021-10-12 15:06:33 +08:00
xiaoxian521
c8e90b4bd7 fix: showLink is false,children menu still showing 2021-10-12 13:45:59 +08:00
xiaoxian521
9c70c5a8dc docs: update readme 2021-10-11 16:36:04 +08:00
xiaoxian521
4cf8c215fc chore: update responsive-storage lastest 2021-10-11 16:11:59 +08:00
xiaoxian521
a139ef80f5 chore: update element-plus lastest 2021-10-11 15:28:52 +08:00
xiaoxian521
11178d8fd5 perf: layout 2021-10-11 15:14:00 +08:00
xiaoxian521
c49fbde0b5 workflow: update linter.yml 2021-10-11 14:21:37 +08:00
hb0730
86cde31aaa feat: export router (#53)
在store模块中,可能需要router跳转
2021-10-09 19:43:11 +08:00
xiaoxian521
fc5cec54b0 feat: 抽离默认配置选项 2021-10-08 11:32:50 +08:00
xiaoxian521
13749c784d fix: some bug 2021-10-05 16:58:59 +08:00
xiaoxian521
37a967942b perf: layout 2021-10-04 11:14:13 +08:00
啝裳
6b16a04229 perf: layout (#50) 2021-10-03 13:09:12 +08:00
xiaoxian521
77b7abcbc3 types: add element-plus/global to tsconfig 2021-10-03 08:46:29 +08:00
xiaoxian521
34782fe351 chore: update 2021-10-03 08:38:48 +08:00
啝裳
52dba8a79c Merge pull request #49 from xiaoxian521/feat/layout
style: [sidebar.scss] delete overflow-x: auto
2021-10-01 21:15:49 +08:00
xiaoxian521
d4d4157cc4 style: [sidebar.scss] delete overflow-x: auto 2021-10-01 21:06:54 +08:00
xiaoxian521
b18654f52e chore: update element-plus lastest 2021-10-01 10:35:18 +08:00
xiaoxian521
28eb447de7 chore: update element-plus 2021-09-29 09:55:50 +08:00
hb0730
e661f60f13 feat(storage): add new storage (#48)
* feat(storage): add new storage,新增 database 和 cookie 存储
* fix(storage): 区分用户,获取当前存储路径时,应该获取当前用户,用来区分用户
* fix: ts alias mapping
* chore: remove lodash
* fix(storage): replace lodash with lodash-es
* fix(storage): initialization,Initialization failed, unable to write
2021-09-29 09:07:54 +08:00
xiaoxian521
6d814316c2 docs: update log 2021-09-29 02:38:50 +08:00
81 changed files with 2078 additions and 1310 deletions

5
.env
View File

@@ -1,6 +1,9 @@
# port
VITE_PORT = 8848
# title
VITE_TITLE = vue-pure-admin
# version
VITE_VERSION = 2.1.0
# open
VITE_OPEN = false

View File

@@ -1,6 +1,9 @@
# port
VITE_PORT = 8848
# title
VITE_TITLE = vue-pure-admin
# version
VITE_VERSION = 2.1.0
# open
VITE_OPEN = false

View File

@@ -16,10 +16,11 @@ name: Lint Code Base
#############################
on:
push:
branches-ignore: main
# Remove the line above to run when pushing to master
branches:
- main
pull_request:
branches: main
branches:
- main
###############
# Set the Job #
@@ -48,7 +49,7 @@ jobs:
run: |
yarn install
yarn lint
yarn run build
yarn build
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: main

1
.gitignore vendored
View File

@@ -12,7 +12,6 @@ tests/**/coverage/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj

47
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,47 @@
{
// You should install these plugins:
// ESLint
// Prettier - Code formatter
// stylelint
// vscode-icons
// TypeScript Vue Plugin (Volar)
// Vue Language Features (Volar)
"terminal.integrated.rendererType": "dom",
"editor.formatOnType": true,
"editor.formatOnSave": true,
"window.zoomLevel": 1,
"javascript.updateImportsOnFileMove.enabled": "always",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"editor.tabSize": 2,
"editor.formatOnPaste": true,
"files.autoSave": "afterDelay",
"git.confirmSync": false,
"workbench.startupEditor": "newUntitledFile",
"editor.suggestSelection": "first",
"editor.acceptSuggestionOnCommitCharacter": false,
"css.lint.propertyIgnoredDueToDisplay": "ignore",
// Prevent inline styles from being automatically formatted to all lowercase
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
// Automatically fix some syntax errors of ts
"tslint.autoFixOnSave": true,
"files.associations": {
// Specifies the location of snippets in the suggestion widget
"editor.snippetSuggestions": "top"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"cSpell.userWords": ["sourcemap", "vite"],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}

View File

@@ -1,3 +1,24 @@
# 2.1.0(2021-10-14)
### 🎫 Feat
- Route animation (each route can add different animations)
- Extra icons (for example, this is a newly added page, a new icon is displayed in the upper right corner of the routing menu)
- Extract the default configuration options
- Perfect type file
### 🐞 Bug fixes
- Fix the issue of element-plus internationalization
- Fix routing issues
- Fix navigation adaptation problem
# 2.0.1(2021-9-29)
### 🎫 Feat
- Feat horizontal nav
# 2.0.0(2021-4-13)
### 🎫 Chores

View File

@@ -1,3 +1,24 @@
# 2.1.0(2021-10-14)
### 🎫 Feat
- Route animation (each route can add different animations)
- Extra icons (for example, this is a newly added page, a new icon is displayed in the upper right corner of the routing menu)
- Extract the default configuration options
- Perfect type file
### 🐞 Bug fixes
- Fix the issue of element-plus internationalization
- Fix routing issues
- Fix navigation adaptation problem
# 2.0.1(2021-9-29)
### 🎫 Feat
- Feat horizontal nav
# 2.0.0(2021-4-13)
### 🎫 Chores

View File

@@ -1,5 +1,26 @@
# 2.1.0(2021-10-14)
### 🎫 Feat
- 路由动画(每个路由都可添加不同动画)
- 额外图标(比如这个是新加的页面,路由菜单右上角显示个新图标)
- 抽离默认配置选项
- 完善类型文件
### 🐞 Bug fixes
- 修复 element-plus 国际化使用问题
- 修复路由问题
- 修复导航适配问题
# 2.0.1(2021-9-29)
### 🎫 Feat
- 添加 horizontal 水平模式导航
# 2.0.0(2021-4-13)
### 🎫 Chores
- 发布2.0.0版本
- 发布 2.0.0 版本

View File

@@ -129,7 +129,7 @@ If you think this project is helpful to you, you can help the author buy a cup o
Please scan the code to join the WeChat exchange group, if you have any questions, you can communicate in the group!
![group](https://yiming_chang.gitee.io/manages/wechat.jpg)
![group](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0c5f882422bd47b5af691906ea994ccf~tplv-k3u1fbpfcp-watermark.awebp?)
## License

View File

@@ -129,7 +129,7 @@ yarn build
请扫码加入微信交流群,有问题可以在群里沟通!
![group](https://yiming_chang.gitee.io/manages/wechat.jpg)
![group](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0c5f882422bd47b5af691906ea994ccf~tplv-k3u1fbpfcp-watermark.awebp?)
## License

View File

@@ -10,7 +10,6 @@ const systemRouter = {
icon: "el-icon-setting",
title: "message.hssysManagement",
showLink: true,
savedPosition: true,
rank: 6
},
children: [
@@ -19,8 +18,7 @@ const systemRouter = {
name: "user",
meta: {
title: "message.hsBaseinfo",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -28,8 +26,7 @@ const systemRouter = {
name: "dict",
meta: {
title: "message.hsDict",
showLink: true,
savedPosition: true
showLink: true
}
}
]
@@ -43,7 +40,6 @@ const permissionRouter = {
title: "message.permission",
icon: "el-icon-lollipop",
showLink: true,
savedPosition: true,
rank: 3
},
children: [
@@ -52,8 +48,7 @@ const permissionRouter = {
name: "permissionPage",
meta: {
title: "message.permissionPage",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -62,7 +57,6 @@ const permissionRouter = {
meta: {
title: "message.permissionButton",
showLink: true,
savedPosition: true,
authority: []
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "vue-pure-admin",
"version": "2.0.0",
"version": "2.1.0",
"private": true,
"scripts": {
"dev": "cross-env --max_old_space_size=4096 vite",
@@ -21,29 +21,30 @@
"@amap/amap-jsapi-loader": "^1.0.1",
"@logicflow/core": "^0.4.6",
"@logicflow/extension": "^0.4.6",
"@vueuse/core": "^6.4.1",
"@vueuse/core": "^6.5.3",
"animate.css": "^4.1.1",
"await-to-js": "^3.0.0",
"axios": "^0.21.1",
"cropperjs": "^1.5.11",
"dayjs": "^1.10.6",
"dotenv": "^8.2.0",
"echarts": "^5.1.2",
"element-plus": "^1.1.0-beta.16",
"dayjs": "^1.10.7",
"echarts": "^5.2.1",
"element-plus": "1.1.0-beta.20",
"element-resize-detector": "^1.2.3",
"font-awesome": "^4.7.0",
"lodash-es": "^4.17.21",
"mitt": "^2.1.0",
"lowdb": "^3.0.0",
"mitt": "^3.0.0",
"mockjs": "^1.1.0",
"nprogress": "^0.2.0",
"path": "^0.12.7",
"path-to-regexp": "^6.2.0",
"pinia": "^2.0.0-rc.6",
"pinia": "2.0.0-rc.10",
"resize-observer-polyfill": "^1.5.1",
"responsive-storage": "^1.0.10",
"responsive-storage": "^1.0.11",
"sortablejs": "1.13.0",
"typescript-cookie": "^1.0.0",
"v-contextmenu": "^3.0.0",
"vue": "^3.2.19",
"vue": "^3.2.20",
"vue-i18n": "^9.2.0-beta.3",
"vue-json-pretty": "^2.0.2",
"vue-router": "^4.0.11",
@@ -66,7 +67,7 @@
"@typescript-eslint/parser": "^4.31.0",
"@vitejs/plugin-vue": "^1.6.0",
"@vitejs/plugin-vue-jsx": "^1.1.7",
"@vue/compiler-sfc": "^3.2.19",
"@vue/compiler-sfc": "^3.2.20",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"autoprefixer": "^10.2.4",
@@ -90,8 +91,8 @@
"stylelint-config-standard": "^22.0.0",
"stylelint-order": "^4.1.0",
"typescript": "^4.4.2",
"unplugin-element-plus": "^0.0.1",
"vite": "^2.5.10",
"unplugin-element-plus": "^0.1.0",
"vite": "^2.6.7",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-style-import": "^1.2.1",
"vite-svg-loader": "^2.2.0",

View File

@@ -1,15 +1,14 @@
{
"version": "1.0.0",
"keepAlive": true,
"Version": "2.0.0",
"KeepAlive": true,
"Locale": "zh",
"Layout": "vertical-dark",
"MapConfigure": {
"amapKey": "97b3248d1553172e81f168cf94ea667e",
"baiduKey": "wTHbkkEweiFqZLKunMIjcrb2RcqNXkhc",
"options": {
"resizeEnable": true,
"center": [
113.6401,
34.72468
],
"center": [113.6401, 34.72468],
"zoom": 12
}
}

View File

@@ -1,25 +1,28 @@
<script setup lang="ts">
import { getCurrentInstance } from "vue";
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/lib/locale/lang/zh-cn";
import en from "element-plus/lib/locale/lang/en";
let locale: string =
getCurrentInstance().appContext.config.globalProperties.$storage?.locale
?.locale;
let currentLocale = () => {
switch (locale) {
case "zh":
return zhCn;
case "en":
return en;
}
};
</script>
<template>
<el-config-provider :locale="currentLocale()">
<el-config-provider :locale="currentLocale">
<router-view />
</el-config-provider>
</template>
<script lang="ts">
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/lib/locale/lang/zh-cn";
import en from "element-plus/lib/locale/lang/en";
export default {
name: "app",
components: {
[ElConfigProvider.name]: ElConfigProvider
},
computed: {
// eslint-disable-next-line vue/return-in-computed-property
currentLocale() {
switch (this.$storage.locale?.locale) {
case "zh":
return zhCn;
case "en":
return en;
}
}
}
};
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2208059 */
src: url("iconfont.woff2?t=1632557807050") format("woff2"),
url("iconfont.woff?t=1632557807050") format("woff"),
url("iconfont.ttf?t=1632557807050") format("truetype");
src: url("iconfont.woff2?t=1634092870259") format("woff2"),
url("iconfont.woff?t=1634092870259") format("woff"),
url("iconfont.ttf?t=1634092870259") format("truetype");
}
.iconfont {
@@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale;
}
.team-iconzuixinlianzai::before {
content: "\e6da";
}
.team-iconxinpin::before {
content: "\e614";
}
.team-iconxinpinrenqiwang::before {
content: "\e615";
}
.team-iconinternationality::before {
content: "\e67a";
}

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,27 @@
"css_prefix_text": "team-icon",
"description": "pure-admin",
"glyphs": [
{
"icon_id": "2508809",
"name": "最新连载",
"font_class": "zuixinlianzai",
"unicode": "e6da",
"unicode_decimal": 59098
},
{
"icon_id": "7795613",
"name": "新品",
"font_class": "xinpin",
"unicode": "e614",
"unicode_decimal": 58900
},
{
"icon_id": "7795615",
"name": "新品人气王",
"font_class": "xinpinrenqiwang",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "18367956",
"name": "中英文2 中文",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="globalization" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>

After

Width:  |  Height:  |  Size: 965 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconinternationality" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 512 512"><path d="M478.33 433.6l-90-218a22 22 0 0 0-40.67 0l-90 218a22 22 0 1 0 40.67 16.79L316.66 406h102.67l18.33 44.39A22 22 0 0 0 458 464a22 22 0 0 0 20.32-30.4zM334.83 362L368 281.65L401.17 362z" fill="currentColor"></path><path d="M267.84 342.92a22 22 0 0 0-4.89-30.7c-.2-.15-15-11.13-36.49-34.73c39.65-53.68 62.11-114.75 71.27-143.49H330a22 22 0 0 0 0-44H214V70a22 22 0 0 0-44 0v20H54a22 22 0 0 0 0 44h197.25c-9.52 26.95-27.05 69.5-53.79 108.36c-31.41-41.68-43.08-68.65-43.17-68.87a22 22 0 0 0-40.58 17c.58 1.38 14.55 34.23 52.86 83.93c.92 1.19 1.83 2.35 2.74 3.51c-39.24 44.35-77.74 71.86-93.85 80.74a22 22 0 1 0 21.07 38.63c2.16-1.18 48.6-26.89 101.63-85.59c22.52 24.08 38 35.44 38.93 36.1a22 22 0 0 0 30.75-4.9z" fill="currentColor"></path></svg>

Before

Width:  |  Height:  |  Size: 972 B

View File

@@ -1,10 +0,0 @@
import { App } from "vue";
import reBreadCrumb from "./src/index.vue";
export const ReBreadCrumb = Object.assign(reBreadCrumb, {
install(app: App) {
app.component(reBreadCrumb.name, reBreadCrumb);
}
});
export default ReBreadCrumb;

View File

@@ -1,3 +1,14 @@
<script setup lang="ts">
import { ref } from "vue";
const lists = ref([
{ type: "", label: "善良" },
{ type: "success", label: "好学" },
{ type: "info", label: "幽默" },
{ type: "danger", label: "旅游" },
{ type: "warning", label: "追剧" }
]);
</script>
<template>
<el-descriptions
class="margin-top"
@@ -75,17 +86,6 @@
</el-descriptions>
</template>
<script setup lang="ts">
import { ref } from "vue";
const lists = ref<ForDataType<undefined>>([
{ type: "", label: "善良" },
{ type: "success", label: "好学" },
{ type: "info", label: "幽默" },
{ type: "danger", label: "旅游" },
{ type: "warning", label: "追剧" }
]);
</script>
<style scoped>
.el-tag--mini {
margin-right: 10px !important;

View File

@@ -5,7 +5,7 @@ import SeamlessScroll from "/@/components/ReSeamlessScroll";
const scroll = templateRef<ElRef | null>("scroll", null);
let listData = ref<ForDataType<undefined>>([
let listData = ref([
{
date: "2021-09-01",
name: "vue-pure-admin",

View File

@@ -1,10 +0,0 @@
import { App } from "vue";
import reHamBurger from "./src/index.vue";
export const ReHamBurger = Object.assign(reHamBurger, {
install(app: App) {
app.component(reHamBurger.name, reHamBurger);
}
});
export default ReHamBurger;

View File

@@ -0,0 +1,12 @@
import { App } from "vue";
import icon from "./src/Icon.vue";
export const Icon = Object.assign(icon, {
install(app: App) {
app.component(icon.name, icon);
}
});
export default {
Icon
};

View File

@@ -0,0 +1,97 @@
<script lang="ts">
export default {
name: "Icon"
};
</script>
<script setup lang="ts">
import { ref, computed } from "vue";
const props = defineProps({
content: {
type: String,
default: ""
},
size: {
type: Number,
default: 18
},
width: {
type: Number,
default: 20
},
height: {
type: Number,
default: 20
},
color: {
type: String,
default: ""
},
svg: {
type: Boolean,
default: false
}
});
const emit = defineEmits<{
(e: "click"): void;
}>();
let text = ref("");
let className = computed(() => {
if (props.content.indexOf("fa-") > -1) {
return props.content.indexOf("fa ") === 0
? props.content
: ["fa", props.content];
} else if (props.content.indexOf("el-icon-") > -1) {
return props.content;
} else if (props.content.indexOf("#") > -1) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
text.value = props.content;
return "iconfont";
} else {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
text.value = props.content;
return "";
}
});
let iconStyle = computed(() => {
return (
"font-size: " +
props.size +
"px; color: " +
props.color +
"; width: " +
props.width +
"px; height: " +
props.height +
"px; font-style: normal;"
);
});
const clickHandle = () => {
emit("click");
};
</script>
<template>
<i
v-if="!props.svg"
:class="className"
:style="iconStyle"
v-html="text"
@click="clickHandle"
></i>
<svg
class="icon-svg"
v-if="props.svg"
aria-hidden="true"
:style="iconStyle"
@click="clickHandle"
>
<use :xlink:href="`#${props.content}`" />
</svg>
</template>

View File

@@ -1,16 +1,15 @@
<script setup lang="ts">
import { ref, unref, computed, getCurrentInstance } from "vue";
import { useSettingStoreHook } from "/@/store/modules/settings";
import { ref, computed, getCurrentInstance } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";
const keepAlive: Boolean = ref(
getCurrentInstance().appContext.config.globalProperties.$config?.keepAlive
getCurrentInstance().appContext.config.globalProperties.$config?.KeepAlive
);
const getCachedPageList = computed((): string[] => {
if (!unref(keepAlive)) {
return [];
}
return useSettingStoreHook().cachedPageList;
const transition = computed(() => {
return route => {
return route.meta.transition;
};
});
</script>
@@ -18,8 +17,28 @@ const getCachedPageList = computed((): string[] => {
<section class="app-main">
<router-view>
<template #default="{ Component, route }">
<transition appear name="fade-transform" mode="out-in">
<keep-alive v-if="keepAlive" :include="getCachedPageList">
<transition
:name="
transition(route) && route.meta.transition.enterTransition
? 'pure-classes-transition'
: (transition(route) && route.meta.transition.name) ||
'fade-transform'
"
:enter-active-class="
transition(route) &&
`animate__animated ${route.meta.transition.enterTransition}`
"
:leave-active-class="
transition(route) &&
`animate__animated ${route.meta.transition.leaveTransition}`
"
mode="out-in"
appear
>
<keep-alive
v-if="keepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<component v-else :is="Component" :key="route.fullPath" />

View File

@@ -1,3 +1,59 @@
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { emitter } from "/@/utils/mitt";
import Hamburger from "./sidebar/hamBurger.vue";
import { useRouter, useRoute } from "vue-router";
import { storageSession } from "/@/utils/storage";
import Breadcrumb from "./sidebar/breadCrumb.vue";
import { useAppStoreHook } from "/@/store/modules/app";
import { unref, watch, getCurrentInstance } from "vue";
import { deviceDetection } from "/@/utils/deviceDetection";
import screenfull from "../components/screenfull/index.vue";
import globalization from "/@/assets/svg/globalization.svg";
const instance =
getCurrentInstance().appContext.config.globalProperties.$storage;
const pureApp = useAppStoreHook();
const router = useRouter();
const route = useRoute();
let usename = storageSession.getItem("info")?.username;
const { locale, t } = useI18n();
watch(
() => locale.value,
() => {
//@ts-ignore
document.title = t(unref(route.meta.title)); // 动态title
}
);
// 退出登录
const logout = (): void => {
storageSession.removeItem("info");
router.push("/login");
};
function onPanel() {
emitter.emit("openPanel");
}
function toggleSideBar() {
pureApp.toggleSideBar();
}
// 简体中文
function translationCh() {
instance.locale = { locale: "zh" };
locale.value = "zh";
}
// English
function translationEn() {
instance.locale = { locale: "en" };
locale.value = "en";
}
</script>
<template>
<div class="navbar">
<Hamburger
@@ -13,7 +69,7 @@
<screenfull v-show="!deviceDetection()" />
<!-- 国际化 -->
<el-dropdown trigger="click">
<iconinternationality />
<globalization />
<template #dropdown>
<el-dropdown-menu class="translation">
<el-dropdown-item
@@ -60,101 +116,6 @@
</div>
</template>
<script lang="ts">
import { defineComponent, unref, watch, getCurrentInstance } from "vue";
import Breadcrumb from "/@/components/ReBreadCrumb";
import Hamburger from "/@/components/ReHamBurger";
import screenfull from "../components/screenfull/index.vue";
import { useRouter, useRoute } from "vue-router";
import { useAppStoreHook } from "/@/store/modules/app";
import { storageSession } from "/@/utils/storage";
import favicon from "/favicon.ico";
import { emitter } from "/@/utils/mitt";
import { deviceDetection } from "/@/utils/deviceDetection";
import { useI18n } from "vue-i18n";
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
export default defineComponent({
name: "Navbar",
components: {
Breadcrumb,
Hamburger,
screenfull,
iconinternationality
},
// @ts-ignore
computed: {
// eslint-disable-next-line vue/return-in-computed-property
currentLocale() {
switch (this.$storage.locale?.locale) {
case "zh":
return true;
case "en":
return false;
}
}
},
setup() {
const instance =
getCurrentInstance().appContext.config.globalProperties.$storage;
const pureApp = useAppStoreHook();
const router = useRouter();
const route = useRoute();
let usename = storageSession.getItem("info")?.username;
const { locale, t } = useI18n();
watch(
() => locale.value,
() => {
//@ts-ignore
document.title = t(unref(route.meta.title)); // 动态title
}
);
// 退出登录
const logout = (): void => {
storageSession.removeItem("info");
router.push("/login");
};
function onPanel() {
emitter.emit("openPanel");
}
function toggleSideBar() {
pureApp.toggleSideBar();
}
// 简体中文
function translationCh() {
instance.locale = { locale: "zh" };
locale.value = "zh";
window.location.reload();
}
// English
function translationEn() {
instance.locale = { locale: "en" };
locale.value = "en";
window.location.reload();
}
return {
locale,
usename,
pureApp,
favicon,
logout,
onPanel,
translationCh,
translationEn,
toggleSideBar,
deviceDetection
};
}
});
</script>
<style lang="scss" scoped>
.navbar {
width: 100%;
@@ -192,7 +153,7 @@ export default defineComponent({
}
}
.iconinternationality {
.globalization {
height: 48px;
width: 40px;
padding: 11px;

View File

@@ -4,8 +4,17 @@ import panel from "../panel/index.vue";
import { useRouter } from "vue-router";
import { emitter } from "/@/utils/mitt";
import { templateRef } from "@vueuse/core";
import { debounce } from "/@/utils/debounce";
import { useAppStoreHook } from "/@/store/modules/app";
import { storageLocal, storageSession } from "/@/utils/storage";
import { reactive, ref, unref, useCssModule, getCurrentInstance } from "vue";
import {
reactive,
ref,
unref,
watch,
useCssModule,
getCurrentInstance
} from "vue";
const router = useRouter();
const { isSelect } = useCssModule();
@@ -124,13 +133,51 @@ function logoChange() {
emitter.emit("logoChange", unref(logoVal));
}
function setTheme(layout: string, theme: string, dom: HTMLElement) {
function setFalse(Doms): any {
Doms.forEach(v => {
toggleClass(false, isSelect, unref(v));
});
}
watch(instance, ({ layout }) => {
switch (layout["layout"]) {
case "vertical-dark":
toggleClass(true, isSelect, unref(verticalDarkDom));
debounce(
setFalse([verticalLightDom, horizontalDarkDom, horizontalLightDom]),
50
);
break;
case "vertical-light":
toggleClass(true, isSelect, unref(verticalLightDom));
debounce(
setFalse([verticalDarkDom, horizontalDarkDom, horizontalLightDom]),
50
);
break;
case "horizontal-dark":
toggleClass(true, isSelect, unref(horizontalDarkDom));
debounce(
setFalse([verticalDarkDom, verticalLightDom, horizontalLightDom]),
50
);
break;
case "horizontal-light":
toggleClass(true, isSelect, unref(horizontalLightDom));
debounce(
setFalse([verticalDarkDom, verticalLightDom, horizontalDarkDom]),
50
);
break;
}
});
function setTheme(layout: string, theme: string) {
dataTheme.value.layout = `${layout}-${theme}`;
window.document.body.setAttribute("data-layout", layout);
window.document.body.setAttribute("data-theme", theme);
instance.layout = { layout: `${layout}-${theme}` };
toggleClass(true, isSelect, unref(dom));
toggleClass(false, isSelect, unref(dom));
useAppStoreHook().setLayout(layout);
}
</script>
@@ -141,13 +188,13 @@ function setTheme(layout: string, theme: string, dom: HTMLElement) {
<el-tooltip
class="item"
effect="dark"
content="暗色主题"
content="左侧菜单暗色模式"
placement="bottom"
>
<li
:class="dataTheme.layout === 'vertical-dark' ? $style.isSelect : ''"
ref="verticalDarkDom"
@click="setTheme('vertical', 'dark', verticalDarkDom)"
@click="setTheme('vertical', 'dark')"
>
<div></div>
<div></div>
@@ -157,13 +204,13 @@ function setTheme(layout: string, theme: string, dom: HTMLElement) {
<el-tooltip
class="item"
effect="dark"
content="亮色主题"
content="左侧菜单亮色模式"
placement="bottom"
>
<li
:class="dataTheme.layout === 'vertical-light' ? $style.isSelect : ''"
ref="verticalLightDom"
@click="setTheme('vertical', 'light', verticalLightDom)"
@click="setTheme('vertical', 'light')"
>
<div></div>
<div></div>
@@ -173,13 +220,13 @@ function setTheme(layout: string, theme: string, dom: HTMLElement) {
<el-tooltip
class="item"
effect="dark"
content="暗色主题"
content="顶部菜单暗色模式"
placement="bottom"
>
<li
:class="dataTheme.layout === 'horizontal-dark' ? $style.isSelect : ''"
ref="horizontalDarkDom"
@click="setTheme('horizontal', 'dark', horizontalDarkDom)"
@click="setTheme('horizontal', 'dark')"
>
<div></div>
<div></div>
@@ -189,7 +236,7 @@ function setTheme(layout: string, theme: string, dom: HTMLElement) {
<el-tooltip
class="item"
effect="dark"
content="暗色主题"
content="顶部菜单亮色模式"
placement="bottom"
>
<li
@@ -197,7 +244,7 @@ function setTheme(layout: string, theme: string, dom: HTMLElement) {
dataTheme.layout === 'horizontal-light' ? $style.isSelect : ''
"
ref="horizontalLightDom"
@click="setTheme('horizontal', 'light', horizontalLightDom)"
@click="setTheme('horizontal', 'light')"
>
<div></div>
<div></div>

View File

@@ -1,3 +1,115 @@
<script setup lang="ts">
import {
computed,
unref,
watch,
nextTick,
onMounted,
getCurrentInstance
} from "vue";
import { useI18n } from "vue-i18n";
import settings from "/@/settings";
import { emitter } from "/@/utils/mitt";
import { templateRef } from "@vueuse/core";
import SidebarItem from "./sidebarItem.vue";
import { algorithm } from "/@/utils/algorithm";
import screenfull from "../screenfull/index.vue";
import { useRoute, useRouter } from "vue-router";
import { storageSession } from "/@/utils/storage";
import { deviceDetection } from "/@/utils/deviceDetection";
import globalization from "/@/assets/svg/globalization.svg";
import { usePermissionStoreHook } from "/@/store/modules/permission";
const instance =
getCurrentInstance().appContext.config.globalProperties.$storage;
const menuRef = templateRef<ElRef | null>("menu", null);
const routeStore = usePermissionStoreHook();
const route = useRoute();
const router = useRouter();
const routers = useRouter().options.routes;
let usename = storageSession.getItem("info")?.username;
const { locale, t } = useI18n();
watch(
() => locale.value,
() => {
//@ts-ignore
// 动态title
document.title = t(unref(route.meta.title));
}
);
// 退出登录
const logout = (): void => {
storageSession.removeItem("info");
router.push("/login");
};
function onPanel() {
emitter.emit("openPanel");
}
const activeMenu = computed(() => {
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
});
const menuSelect = (indexPath: string): void => {
let parentPath = "";
let parentPathIndex = indexPath.lastIndexOf("/");
if (parentPathIndex > 0) {
parentPath = indexPath.slice(0, parentPathIndex);
}
// 找到当前路由的信息
function findCurrentRoute(routes) {
return routes.map(item => {
if (item.path === indexPath) {
// 切换左侧菜单 通知标签页
emitter.emit("changLayoutRoute", {
indexPath,
parentPath
});
} else {
if (item.children) findCurrentRoute(item.children);
}
});
}
findCurrentRoute(algorithm.increaseIndexes(routers));
};
function backHome() {
router.push("/welcome");
}
function handleResize() {
// @ts-ignore
menuRef.value.handleResize();
}
// 简体中文
function translationCh() {
instance.locale = { locale: "zh" };
locale.value = "zh";
handleResize();
}
// English
function translationEn() {
instance.locale = { locale: "en" };
locale.value = "en";
handleResize();
}
onMounted(() => {
nextTick(() => {
handleResize();
});
});
</script>
<template>
<div class="horizontal-header">
<div class="horizontal-header-left" @click="backHome">
@@ -5,6 +117,7 @@
<h4>{{ settings.title }}</h4>
</div>
<el-menu
ref="menu"
:default-active="activeMenu"
unique-opened
router
@@ -24,7 +137,7 @@
<screenfull v-show="!deviceDetection()" />
<!-- 国际化 -->
<el-dropdown trigger="click">
<iconinternationality />
<globalization />
<template #dropdown>
<el-dropdown-menu class="translation">
<el-dropdown-item
@@ -71,162 +184,6 @@
</div>
</template>
<script lang="ts">
import {
computed,
defineComponent,
unref,
watch,
getCurrentInstance
} from "vue";
import { useI18n } from "vue-i18n";
import settings from "/@/settings";
import { emitter } from "/@/utils/mitt";
import SidebarItem from "./sidebarItem.vue";
import { algorithm } from "/@/utils/algorithm";
import screenfull from "../screenfull/index.vue";
import { useRoute, useRouter } from "vue-router";
import { storageSession } from "/@/utils/storage";
import { deviceDetection } from "/@/utils/deviceDetection";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import iconinternationality from "/@/assets/svg/iconinternationality.svg";
let routerArrays: Array<object> = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true,
savedPosition: false
}
}
];
export default defineComponent({
name: "sidebar",
components: { SidebarItem, screenfull, iconinternationality },
// @ts-ignore
computed: {
// eslint-disable-next-line vue/return-in-computed-property
currentLocale() {
if (
!this.$storage.routesInStorage ||
this.$storage.routesInStorage.length === 0
) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.$storage.routesInStorage = routerArrays;
}
if (!this.$storage.locale) {
// eslint-disable-next-line
this.$storage.locale = { locale: "zh" };
useI18n().locale.value = "zh";
}
switch (this.$storage.locale?.locale) {
case "zh":
return true;
case "en":
return false;
}
}
},
setup() {
const instance =
getCurrentInstance().appContext.config.globalProperties.$storage;
const routeStore = usePermissionStoreHook();
const route = useRoute();
const router = useRouter();
const routers = useRouter().options.routes;
let usename = storageSession.getItem("info")?.username;
const { locale, t } = useI18n();
watch(
() => locale.value,
() => {
//@ts-ignore
// 动态title
document.title = t(unref(route.meta.title));
}
);
// 退出登录
const logout = (): void => {
storageSession.removeItem("info");
router.push("/login");
};
function onPanel() {
emitter.emit("openPanel");
}
const activeMenu = computed(() => {
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
});
const menuSelect = (indexPath: string): void => {
let parentPath = "";
let parentPathIndex = indexPath.lastIndexOf("/");
if (parentPathIndex > 0) {
parentPath = indexPath.slice(0, parentPathIndex);
}
// 找到当前路由的信息
function findCurrentRoute(routes) {
return routes.map(item => {
if (item.path === indexPath) {
// 切换左侧菜单 通知标签页
emitter.emit("changLayoutRoute", {
indexPath,
parentPath
});
} else {
if (item.children) findCurrentRoute(item.children);
}
});
}
findCurrentRoute(algorithm.increaseIndexes(routers));
};
function backHome() {
router.push("/welcome");
}
// 简体中文
function translationCh() {
instance.locale = { locale: "zh" };
locale.value = "zh";
window.location.reload();
}
// English
function translationEn() {
instance.locale = { locale: "en" };
locale.value = "en";
window.location.reload();
}
return {
locale,
usename,
settings,
routeStore,
activeMenu,
logout,
onPanel,
backHome,
menuSelect,
translationCh,
translationEn,
deviceDetection
};
}
});
</script>
<style lang="scss" scoped>
.translation {
.el-dropdown-menu__item {

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import path from "path";
import { PropType, ref } from "vue";
import Icon from "/@/components/ReIcon/src/Icon.vue";
import { RouteRecordRaw } from "vue-router";
const props = defineProps({
@@ -34,13 +35,8 @@ function hasOneShowingChild(
parent: RouteRecordRaw
) {
const showingChildren = children.filter((item: any) => {
if (item.hidden) {
// 不显示hidden属性为true的菜单
return false;
} else {
onlyOneChild.value = item;
return true;
}
onlyOneChild.value = item;
return true;
});
if (showingChildren.length === 1) {
@@ -78,6 +74,11 @@ function resolvePath(routePath) {
/>
<template #title>
<span>{{ $t(onlyOneChild.meta.title) }}</span>
<Icon
v-if="onlyOneChild.meta.extraIcon"
:svg="onlyOneChild.meta.extraIcon.svg ? true : false"
:content="`${onlyOneChild.meta.extraIcon.name}`"
/>
</template>
</el-menu-item>
</template>
@@ -91,6 +92,11 @@ function resolvePath(routePath) {
<template #title>
<i :class="props.item.meta.icon"></i>
<span>{{ $t(props.item.meta.title) }}</span>
<Icon
v-if="props.item.meta.extraIcon"
:svg="props.item.meta.extraIcon.svg ? true : false"
:content="`${props.item.meta.extraIcon.name}`"
/>
</template>
<sidebar-item
v-for="child in props.item.children"

View File

@@ -1,3 +1,61 @@
<script setup lang="ts">
import Logo from "./logo.vue";
import { emitter } from "/@/utils/mitt";
import SidebarItem from "./sidebarItem.vue";
import { algorithm } from "/@/utils/algorithm";
import { storageLocal } from "/@/utils/storage";
import { useRoute, useRouter } from "vue-router";
import { computed, ref, onBeforeMount } from "vue";
import { useAppStoreHook } from "/@/store/modules/app";
import { usePermissionStoreHook } from "/@/store/modules/permission";
const route = useRoute();
const pureApp = useAppStoreHook();
const router = useRouter().options.routes;
const routeStore = usePermissionStoreHook();
const showLogo = ref(storageLocal.getItem("logoVal") || "1");
const isCollapse = computed(() => {
return !pureApp.getSidebarStatus;
});
const activeMenu = computed(() => {
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
});
const menuSelect = (indexPath: string): void => {
let parentPath = "";
let parentPathIndex = indexPath.lastIndexOf("/");
if (parentPathIndex > 0) {
parentPath = indexPath.slice(0, parentPathIndex);
}
// 找到当前路由的信息
// eslint-disable-next-line no-inner-declarations
function findCurrentRoute(routes) {
return routes.map(item => {
if (item.path === indexPath) {
// 切换左侧菜单 通知标签页
emitter.emit("changLayoutRoute", {
indexPath,
parentPath
});
} else {
if (item.children) findCurrentRoute(item.children);
}
});
}
findCurrentRoute(algorithm.increaseIndexes(router));
};
onBeforeMount(() => {
emitter.on("logoChange", key => {
showLogo.value = key;
});
});
</script>
<template>
<div :class="['sidebar-container', showLogo ? 'has-logo' : '']">
<Logo v-if="showLogo === '1'" :collapse="isCollapse" />
@@ -21,77 +79,3 @@
</el-scrollbar>
</div>
</template>
<script lang="ts">
import Logo from "./logo.vue";
import { emitter } from "/@/utils/mitt";
import SidebarItem from "./sidebarItem.vue";
import { algorithm } from "/@/utils/algorithm";
import { storageLocal } from "/@/utils/storage";
import { useRoute, useRouter } from "vue-router";
import { useAppStoreHook } from "/@/store/modules/app";
import { computed, defineComponent, ref, onBeforeMount } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";
export default defineComponent({
name: "sidebar",
components: { SidebarItem, Logo },
setup() {
const routeStore = usePermissionStoreHook();
const router = useRouter().options.routes;
const pureApp = useAppStoreHook();
const route = useRoute();
const showLogo = ref(storageLocal.getItem("logoVal") || "1");
const activeMenu = computed(() => {
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
});
const menuSelect = (indexPath: string): void => {
let parentPath = "";
let parentPathIndex = indexPath.lastIndexOf("/");
if (parentPathIndex > 0) {
parentPath = indexPath.slice(0, parentPathIndex);
}
// 找到当前路由的信息
// eslint-disable-next-line no-inner-declarations
function findCurrentRoute(routes) {
return routes.map(item => {
if (item.path === indexPath) {
// 切换左侧菜单 通知标签页
emitter.emit("changLayoutRoute", {
indexPath,
parentPath
});
} else {
if (item.children) findCurrentRoute(item.children);
}
});
}
findCurrentRoute(algorithm.increaseIndexes(router));
};
onBeforeMount(() => {
emitter.on("logoChange", key => {
showLogo.value = key;
});
});
return {
activeMenu,
isCollapse: computed(() => !pureApp.getSidebarStatus),
menuSelect,
showLogo,
routeStore
};
}
});
</script>

View File

@@ -1,3 +1,446 @@
<script setup lang="ts">
import {
ref,
watch,
onBeforeMount,
unref,
nextTick,
computed,
getCurrentInstance,
ComputedRef
} from "vue";
import { RouteConfigs, relativeStorageType, tagsViewsType } from "../../types";
import { emitter } from "/@/utils/mitt";
import { templateRef } from "@vueuse/core";
import { handleAliveRoute } from "/@/router";
import { storageLocal } from "/@/utils/storage";
import { useRoute, useRouter } from "vue-router";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
import close from "/@/assets/svg/close.svg";
import refresh from "/@/assets/svg/refresh.svg";
import closeAll from "/@/assets/svg/close_all.svg";
import closeLeft from "/@/assets/svg/close_left.svg";
import closeOther from "/@/assets/svg/close_other.svg";
import closeRight from "/@/assets/svg/close_right.svg";
let refreshButton = "refresh-button";
const instance = getCurrentInstance();
// 响应式storage
let relativeStorage: relativeStorageType;
const route = useRoute();
const router = useRouter();
const showTags = ref(storageLocal.getItem("tagsVal") || false);
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
const activeIndex = ref(-1);
let routerArrays: Array<RouteConfigs> = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true
}
}
];
const tagsViews = ref<Array<tagsViewsType>>([
{
icon: refresh,
text: "message.hsreload",
divided: false,
disabled: false,
show: true
},
{
icon: close,
text: "message.hscloseCurrentTab",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: closeLeft,
text: "message.hscloseLeftTabs",
divided: true,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: closeRight,
text: "message.hscloseRightTabs",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: closeOther,
text: "message.hscloseOtherTabs",
divided: true,
disabled: routerArrays.length > 2 ? false : true,
show: true
},
{
icon: closeAll,
text: "message.hscloseAllTabs",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
}
]);
const dynamicTagList: ComputedRef<Array<RouteConfigs>> = computed(() => {
return relativeStorage.routesInStorage;
});
// 显示模式,默认灵动模式显示
const showModel = ref(storageLocal.getItem("showModel") || "smart");
if (!showModel.value) {
storageLocal.setItem("showModel", "card");
}
let visible = ref(false);
let buttonLeft = ref(0);
let buttonTop = ref(0);
// 当前右键选中的路由信息
let currentSelect = ref({});
function dynamicRouteTag(value: string, parentPath: string): void {
const hasValue = relativeStorage.routesInStorage.some((item: any) => {
return item.path === value;
});
function concatPath(arr: object[], value: string, parentPath: string) {
if (!hasValue) {
arr.forEach((arrItem: any) => {
let pathConcat = parentPath + arrItem.path;
if (arrItem.path === value || pathConcat === value) {
routerArrays.push({
path: value,
parentPath: `/${parentPath.split("/")[1]}`,
meta: arrItem.meta
});
relativeStorage.routesInStorage = routerArrays;
} else {
if (arrItem.children && arrItem.children.length > 0) {
concatPath(arrItem.children, value, parentPath);
}
}
});
}
}
concatPath(router.options.routes, value, parentPath);
}
// 重新加载
function onFresh() {
toggleClass(true, refreshButton, document.querySelector(".rotate"));
const { fullPath } = unref(route);
router.replace({
path: "/redirect" + fullPath
});
setTimeout(() => {
removeClass(document.querySelector(".rotate"), refreshButton);
}, 600);
}
function deleteDynamicTag(obj: any, current: any, tag?: string) {
let valueIndex: number = routerArrays.findIndex((item: any) => {
return item.path === obj.path;
});
const spliceRoute = (start?: number, end?: number, other?: boolean): void => {
if (other) {
relativeStorage.routesInStorage = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true
}
},
obj
];
routerArrays = relativeStorage.routesInStorage;
} else {
routerArrays.splice(start, end);
relativeStorage.routesInStorage = routerArrays;
}
router.push(obj.path);
// 删除缓存路由
handleAliveRoute(route.matched, "delete");
};
if (tag === "other") {
spliceRoute(1, 1, true);
} else if (tag === "left") {
spliceRoute(1, valueIndex - 1);
} else if (tag === "right") {
spliceRoute(valueIndex + 1, routerArrays.length);
} else {
// 从当前匹配到的路径中删除
spliceRoute(valueIndex, 1);
}
if (current === obj.path) {
// 如果删除当前激活tag就自动切换到最后一个tag
let newRoute: any = routerArrays.slice(-1);
nextTick(() => {
router.push({
path: newRoute[0].path
});
});
}
}
function deleteMenu(item, tag?: string) {
deleteDynamicTag(item, item.path, tag);
}
function onClickDrop(key, item, selectRoute?: RouteConfigs) {
if (item && item.disabled) return;
// 当前路由信息
switch (key) {
case 0:
// 重新加载
onFresh();
break;
case 1:
// 关闭当前标签页
selectRoute
? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
: deleteMenu({ path: route.path, meta: route.meta });
break;
case 2:
// 关闭左侧标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"left"
)
: deleteMenu({ path: route.path, meta: route.meta }, "left");
break;
case 3:
// 关闭右侧标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"right"
)
: deleteMenu({ path: route.path, meta: route.meta }, "right");
break;
case 4:
// 关闭其他标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"other"
)
: deleteMenu({ path: route.path, meta: route.meta }, "other");
break;
case 5:
// 关闭全部标签页
routerArrays.splice(1, routerArrays.length);
relativeStorage.routesInStorage = routerArrays;
usePermissionStoreHook().clearAllCachePage();
router.push("/welcome");
break;
}
setTimeout(() => {
showMenuModel(route.fullPath);
});
}
// 触发右键中菜单的点击事件
function selectTag(key, item) {
onClickDrop(key, item, currentSelect.value);
}
function closeMenu() {
visible.value = false;
}
function showMenus(value: Boolean) {
Array.of(1, 2, 3, 4, 5).forEach(v => {
tagsViews.value[v].show = value;
});
}
function disabledMenus(value: Boolean) {
Array.of(1, 2, 3, 4, 5).forEach(v => {
tagsViews.value[v].disabled = value;
});
}
// 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
function showMenuModel(currentPath: string, refresh = false) {
let allRoute = unref(relativeStorage.routesInStorage);
let routeLength = unref(relativeStorage.routesInStorage).length;
// currentIndex为1时左侧的菜单是首页则不显示关闭左侧标签页
let currentIndex = allRoute.findIndex(v => v.path === currentPath);
// 如果currentIndex等于routeLength-1右侧没有菜单则不显示关闭右侧标签页
showMenus(true);
if (refresh) {
tagsViews.value[0].show = true;
}
if (currentIndex === 1 && routeLength !== 2) {
// 左侧的菜单是首页,右侧存在别的菜单
tagsViews.value[2].show = false;
Array.of(1, 3, 4, 5).forEach(v => {
tagsViews.value[v].disabled = false;
});
tagsViews.value[2].disabled = true;
} else if (currentIndex === 1 && routeLength === 2) {
disabledMenus(false);
// 左侧的菜单是首页,右侧不存在别的菜单
Array.of(2, 3, 4).forEach(v => {
tagsViews.value[v].show = false;
tagsViews.value[v].disabled = true;
});
} else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
// 当前路由是所有路由中的最后一个
tagsViews.value[3].show = false;
Array.of(1, 2, 4, 5).forEach(v => {
tagsViews.value[v].disabled = false;
});
tagsViews.value[3].disabled = true;
} else if (currentIndex === 0 || currentPath === "/redirect/welcome") {
// 当前路由为首页
disabledMenus(true);
} else {
disabledMenus(false);
}
}
function openMenu(tag, e) {
closeMenu();
if (tag.path === "/welcome") {
// 右键菜单为首页,只显示刷新
showMenus(false);
tagsViews.value[0].show = true;
} else if (route.path !== tag.path) {
// 右键菜单不匹配当前路由,隐藏刷新
tagsViews.value[0].show = false;
showMenuModel(tag.path);
} else if (
// eslint-disable-next-line no-dupe-else-if
relativeStorage.routesInStorage.length === 2 &&
route.path !== tag.path
) {
showMenus(true);
// 只有两个标签时不显示关闭其他标签页
tagsViews.value[4].show = false;
} else if (route.path === tag.path) {
// 右键当前激活的菜单
showMenuModel(tag.path, true);
}
currentSelect.value = tag;
const menuMinWidth = 105;
const offsetLeft = unref(containerDom).getBoundingClientRect().left;
const offsetWidth = unref(containerDom).offsetWidth;
const maxLeft = offsetWidth - menuMinWidth;
const left = e.clientX - offsetLeft + 5;
if (left > maxLeft) {
buttonLeft.value = maxLeft;
} else {
buttonLeft.value = left;
}
buttonTop.value = e.clientY + 10;
setTimeout(() => {
visible.value = true;
}, 10);
}
// 触发tags标签切换
function tagOnClick(item) {
showMenuModel(item.path);
}
// 鼠标移入
function onMouseenter(item, index) {
if (index) activeIndex.value = index;
if (unref(showModel) === "smart") {
if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
} else {
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
toggleClass(true, "card-in", instance.refs["dynamic" + index]);
toggleClass(false, "card-out", instance.refs["dynamic" + index]);
}
}
// 鼠标移出
function onMouseleave(item, index) {
activeIndex.value = -1;
if (unref(showModel) === "smart") {
if (hasClass(instance.refs["schedule" + index], "schedule-active")) return;
toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
} else {
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
toggleClass(false, "card-in", instance.refs["dynamic" + index]);
toggleClass(true, "card-out", instance.refs["dynamic" + index]);
}
}
watch(
() => visible.value,
val => {
if (val) {
document.body.addEventListener("click", closeMenu);
} else {
document.body.removeEventListener("click", closeMenu);
}
}
);
onBeforeMount(() => {
if (!instance) return;
relativeStorage = instance.appContext.app.config.globalProperties.$storage;
routerArrays = relativeStorage.routesInStorage ?? routerArrays;
// 根据当前路由初始化操作标签页的禁用状态
showMenuModel(route.fullPath);
// 触发隐藏标签页
emitter.on("tagViewsChange", key => {
if (unref(showTags) === key) return;
showTags.value = key;
});
// 改变标签风格
emitter.on("tagViewsShowModel", key => {
showModel.value = key;
});
// 接收侧边栏切换传递过来的参数
emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
dynamicRouteTag(indexPath, parentPath);
setTimeout(() => {
showMenuModel(indexPath);
});
});
});
</script>
<template>
<div ref="containerDom" class="tags-view" v-if="!showTags">
<el-scrollbar wrap-class="scrollbar-wrapper" class="scroll-container">
@@ -47,7 +490,7 @@
>
<li v-if="item.show" @click="selectTag(key, item)">
<component :is="item.icon" :key="key" />
{{ item.text }}
{{ $t(item.text) }}
</li>
</div>
</ul>
@@ -74,7 +517,7 @@
@click="onClickDrop(key, item)"
>
<component :is="item.icon" :key="key" />
{{ item.text }}
{{ $t(item.text) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
@@ -87,479 +530,6 @@
</div>
</template>
<script lang="ts">
import {
ref,
watch,
onBeforeMount,
unref,
nextTick,
getCurrentInstance
} from "vue";
import { useRoute, useRouter } from "vue-router";
import { storageLocal } from "/@/utils/storage";
import { emitter } from "/@/utils/mitt";
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
import { templateRef } from "@vueuse/core";
import closeOther from "/@/assets/svg/close_other.svg";
import closeLeft from "/@/assets/svg/close_left.svg";
import closeRight from "/@/assets/svg/close_right.svg";
import close from "/@/assets/svg/close.svg";
import refresh from "/@/assets/svg/refresh.svg";
import closeAll from "/@/assets/svg/close_all.svg";
let refreshButton = "refresh-button";
let routerArrays: Array<object> = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true,
savedPosition: false
}
}
];
export default {
name: "tag",
components: {
closeOther,
closeLeft,
closeRight,
close,
refresh,
closeAll
},
// @ts-ignore
computed: {
dynamicTagList() {
return this.$storage.routesInStorage;
}
},
setup() {
const instance = getCurrentInstance();
let st: any;
const route = useRoute();
const router = useRouter();
const showTags = ref(storageLocal.getItem("tagsVal") || false);
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
const activeIndex = ref(-1);
const tagsViews = ref([
{
icon: "refresh",
text: "重新加载",
divided: false,
disabled: false,
show: true
},
{
icon: "close",
text: "关闭当前标签页",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: "closeLeft",
text: "关闭左侧标签页",
divided: true,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: "closeRight",
text: "关闭右侧标签页",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
},
{
icon: "closeOther",
text: "关闭其他标签页",
divided: true,
disabled: routerArrays.length > 2 ? false : true,
show: true
},
{
icon: "closeAll",
text: "关闭全部标签页",
divided: false,
disabled: routerArrays.length > 1 ? false : true,
show: true
}
]);
// 显示模式,默认灵动模式显示
const showModel = ref(storageLocal.getItem("showModel") || "smart");
if (!showModel.value) {
storageLocal.setItem("showModel", "card");
}
let visible = ref(false);
let buttonLeft = ref(0);
let buttonTop = ref(0);
// 当前右键选中的路由信息
let currentSelect = ref({});
function dynamicRouteTag(value: string, parentPath: string): void {
const hasValue = st.routesInStorage.some((item: any) => {
return item.path === value;
});
function concatPath(arr: object[], value: string, parentPath: string) {
if (!hasValue) {
arr.forEach((arrItem: any) => {
let pathConcat = parentPath + arrItem.path;
if (arrItem.path === value || pathConcat === value) {
routerArrays.push({
path: value,
parentPath: `/${parentPath.split("/")[1]}`,
meta: arrItem.meta
});
st.routesInStorage = routerArrays;
} else {
if (arrItem.children && arrItem.children.length > 0) {
concatPath(arrItem.children, value, parentPath);
}
}
});
}
}
concatPath(router.options.routes, value, parentPath);
}
// 重新加载
function onFresh() {
toggleClass(true, refreshButton, document.querySelector(".rotate"));
const { fullPath } = unref(route);
router.replace({
path: "/redirect" + fullPath
});
setTimeout(() => {
removeClass(document.querySelector(".rotate"), refreshButton);
}, 600);
}
function deleteDynamicTag(obj: any, current: any, tag?: string) {
let valueIndex: number = routerArrays.findIndex((item: any) => {
return item.path === obj.path;
});
const spliceRoute = (
start?: number,
end?: number,
other?: boolean
): void => {
if (other) {
st.routesInStorage = routerArrays = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true,
savedPosition: false
}
},
obj
];
} else {
routerArrays.splice(start, end);
st.routesInStorage = routerArrays;
}
router.push(obj.path);
};
if (tag === "other") {
spliceRoute(1, 1, true);
} else if (tag === "left") {
spliceRoute(1, valueIndex - 1);
} else if (tag === "right") {
spliceRoute(valueIndex + 1, routerArrays.length);
} else {
// 从当前匹配到的路径中删除
spliceRoute(valueIndex, 1);
}
if (current === obj.path) {
// 如果删除当前激活tag就自动切换到最后一个tag
let newRoute: any = routerArrays.slice(-1);
nextTick(() => {
router.push({
path: newRoute[0].path
});
});
}
}
function deleteMenu(item, tag?: string) {
deleteDynamicTag(item, item.path, tag);
}
function onClickDrop(key, item, selectRoute) {
if (item && item.disabled) return;
// 当前路由信息
switch (key) {
case 0:
// 重新加载
onFresh();
break;
case 1:
// 关闭当前标签页
selectRoute
? deleteMenu({ path: selectRoute.path, meta: selectRoute.meta })
: deleteMenu({ path: route.path, meta: route.meta });
break;
case 2:
// 关闭左侧标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"left"
)
: deleteMenu({ path: route.path, meta: route.meta }, "left");
break;
case 3:
// 关闭右侧标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"right"
)
: deleteMenu({ path: route.path, meta: route.meta }, "right");
break;
case 4:
// 关闭其他标签页
selectRoute
? deleteMenu(
{
path: selectRoute.path,
meta: selectRoute.meta
},
"other"
)
: deleteMenu({ path: route.path, meta: route.meta }, "other");
break;
case 5:
// 关闭全部标签页
routerArrays.splice(1, routerArrays.length);
st.routesInStorage = routerArrays;
router.push("/welcome");
break;
}
setTimeout(() => {
showMenuModel(route.fullPath);
});
}
// 触发右键中菜单的点击事件
function selectTag(key, item) {
onClickDrop(key, item, currentSelect.value);
}
function closeMenu() {
visible.value = false;
}
function showMenus(value: Boolean) {
Array.of(1, 2, 3, 4, 5).forEach(v => {
tagsViews.value[v].show = value;
});
}
function disabledMenus(value: Boolean) {
Array.of(1, 2, 3, 4, 5).forEach(v => {
tagsViews.value[v].disabled = value;
});
}
// 检查当前右键的菜单两边是否存在别的菜单,如果左侧的菜单是首页,则不显示关闭左侧标签页,如果右侧没有菜单,则不显示关闭右侧标签页
function showMenuModel(currentPath: string, refresh = false) {
let allRoute = unref(st.routesInStorage);
let routeLength = unref(st.routesInStorage).length;
// currentIndex为1时左侧的菜单是首页则不显示关闭左侧标签页
let currentIndex = allRoute.findIndex(v => v.path === currentPath);
// 如果currentIndex等于routeLength-1右侧没有菜单则不显示关闭右侧标签页
showMenus(true);
if (refresh) {
tagsViews.value[0].show = true;
}
if (currentIndex === 1 && routeLength !== 2) {
// 左侧的菜单是首页,右侧存在别的菜单
tagsViews.value[2].show = false;
Array.of(1, 3, 4, 5).forEach(v => {
tagsViews.value[v].disabled = false;
});
tagsViews.value[2].disabled = true;
} else if (currentIndex === 1 && routeLength === 2) {
disabledMenus(false);
// 左侧的菜单是首页,右侧不存在别的菜单
Array.of(2, 3, 4).forEach(v => {
tagsViews.value[v].show = false;
tagsViews.value[v].disabled = true;
});
} else if (routeLength - 1 === currentIndex && currentIndex !== 0) {
// 当前路由是所有路由中的最后一个
tagsViews.value[3].show = false;
Array.of(1, 2, 4, 5).forEach(v => {
tagsViews.value[v].disabled = false;
});
tagsViews.value[3].disabled = true;
} else if (currentIndex === 0) {
// 当前路由为首页
disabledMenus(true);
} else {
disabledMenus(false);
}
}
function openMenu(tag, e) {
closeMenu();
if (tag.path === "/welcome") {
// 右键菜单为首页,只显示刷新
showMenus(false);
tagsViews.value[0].show = true;
} else if (route.path !== tag.path) {
// 右键菜单不匹配当前路由,隐藏刷新
tagsViews.value[0].show = false;
showMenuModel(tag.path);
// eslint-disable-next-line no-dupe-else-if
} else if (st.routesInStorage.length === 2 && route.path !== tag.path) {
showMenus(true);
// 只有两个标签时不显示关闭其他标签页
tagsViews.value[4].show = false;
} else if (route.path === tag.path) {
// 右键当前激活的菜单
showMenuModel(tag.path, true);
}
currentSelect.value = tag;
const menuMinWidth = 105;
const offsetLeft = unref(containerDom).getBoundingClientRect().left;
const offsetWidth = unref(containerDom).offsetWidth;
const maxLeft = offsetWidth - menuMinWidth;
const left = e.clientX - offsetLeft + 5;
if (left > maxLeft) {
buttonLeft.value = maxLeft;
} else {
buttonLeft.value = left;
}
buttonTop.value = e.clientY + 10;
setTimeout(() => {
visible.value = true;
}, 10);
}
// 触发tags标签切换
function tagOnClick(item) {
showMenuModel(item.path);
}
// 鼠标移入
function onMouseenter(item, index) {
if (index) activeIndex.value = index;
if (unref(showModel) === "smart") {
if (hasClass(instance.refs["schedule" + index], "schedule-active"))
return;
toggleClass(true, "schedule-in", instance.refs["schedule" + index]);
toggleClass(false, "schedule-out", instance.refs["schedule" + index]);
} else {
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
toggleClass(true, "card-in", instance.refs["dynamic" + index]);
toggleClass(false, "card-out", instance.refs["dynamic" + index]);
}
}
// 鼠标移出
function onMouseleave(item, index) {
activeIndex.value = -1;
if (unref(showModel) === "smart") {
if (hasClass(instance.refs["schedule" + index], "schedule-active"))
return;
toggleClass(false, "schedule-in", instance.refs["schedule" + index]);
toggleClass(true, "schedule-out", instance.refs["schedule" + index]);
} else {
if (hasClass(instance.refs["dynamic" + index], "card-active")) return;
toggleClass(false, "card-in", instance.refs["dynamic" + index]);
toggleClass(true, "card-out", instance.refs["dynamic" + index]);
}
}
watch(
() => visible.value,
val => {
if (val) {
document.body.addEventListener("click", closeMenu);
} else {
document.body.removeEventListener("click", closeMenu);
}
}
);
onBeforeMount(() => {
if (!instance) return;
st = instance.appContext.app.config.globalProperties.$storage;
routerArrays = st.routesInStorage ?? routerArrays;
// 根据当前路由初始化操作标签页的禁用状态
showMenuModel(route.fullPath);
// 触发隐藏标签页
emitter.on("tagViewsChange", key => {
if (unref(showTags) === key) return;
showTags.value = key;
});
// 改变标签风格
emitter.on("tagViewsShowModel", key => {
showModel.value = key;
});
// 接收侧边栏切换传递过来的参数
emitter.on("changLayoutRoute", ({ indexPath, parentPath }) => {
dynamicRouteTag(indexPath, parentPath);
setTimeout(() => {
showMenuModel(indexPath);
});
});
});
return {
deleteMenu,
showTags,
onFresh,
tagsViews,
onClickDrop,
visible,
buttonLeft,
buttonTop,
openMenu,
closeMenu,
selectTag,
currentSelect,
onMouseenter,
onMouseleave,
tagOnClick,
activeIndex,
showModel,
showMenuModel
};
}
};
</script>
<style lang="scss" scoped>
@keyframes scheduleInWidth {
from {

View File

@@ -1,16 +1,5 @@
<script lang="ts">
let routerArrays: Array<object> = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true,
savedPosition: false
}
}
];
import { routerArrays } from "./types";
export default {
computed: {
layout() {
@@ -42,15 +31,19 @@ import {
unref,
reactive,
computed,
watchEffect,
onMounted,
watchEffect,
useCssModule,
onBeforeMount,
useCssModule
getCurrentInstance
} from "vue";
import { setType } from "./types";
import options from "/@/settings";
import { useI18n } from "vue-i18n";
import { emitter } from "/@/utils/mitt";
import { toggleClass } from "/@/utils/operate";
import { useEventListener } from "@vueuse/core";
import { storageLocal } from "/@/utils/storage";
import { useAppStoreHook } from "/@/store/modules/app";
import fullScreen from "/@/assets/svg/full_screen.svg";
import exitScreen from "/@/assets/svg/exit_screen.svg";
@@ -63,28 +56,21 @@ import setting from "./components/setting/index.vue";
import Vertical from "./components/sidebar/vertical.vue";
import Horizontal from "./components/sidebar/horizontal.vue";
interface setInter {
sidebar: any;
device: string;
fixedHeader: boolean;
classes: any;
}
const pureApp = useAppStoreHook();
const pureSetting = useSettingStoreHook();
const { hiddenMainContainer } = useCssModule();
const WIDTH = ref(992);
const instance =
getCurrentInstance().appContext.app.config.globalProperties.$storage;
let containerHiddenSideBar = ref(options.hiddenSideBar);
const set: setInter = reactive({
const set: setType = reactive({
sidebar: computed(() => {
return pureApp.sidebar;
return useAppStoreHook().sidebar;
}),
device: computed(() => {
return pureApp.device;
return useAppStoreHook().device;
}),
fixedHeader: computed(() => {
@@ -102,9 +88,23 @@ const set: setInter = reactive({
});
const handleClickOutside = (params: boolean) => {
pureApp.closeSideBar({ withoutAnimation: params });
useAppStoreHook().closeSideBar({ withoutAnimation: params });
};
function setTheme(layoutModel: string) {
let { layout } = storageLocal.getItem("responsive-layout");
let theme = layout.match(/-(.*)/)[1];
window.document.body.setAttribute("data-layout", layoutModel);
window.document.body.setAttribute("data-theme", theme);
instance.layout = { layout: `${layoutModel}-${theme}` };
}
// 监听容器
emitter.on("resize", ({ detail }) => {
let { width } = detail;
width <= 670 ? setTheme("vertical") : setTheme(useAppStoreHook().layout);
});
watchEffect(() => {
if (set.device === "mobile" && !set.sidebar.opened) {
handleClickOutside(false);
@@ -113,13 +113,13 @@ watchEffect(() => {
const $_isMobile = () => {
const rect = document.body.getBoundingClientRect();
return rect.width - 1 < WIDTH.value;
return rect.width - 1 < 992;
};
const $_resizeHandler = () => {
if (!document.hidden) {
const isMobile = $_isMobile();
pureApp.toggleDevice(isMobile ? "mobile" : "desktop");
useAppStoreHook().toggleDevice(isMobile ? "mobile" : "desktop");
if (isMobile) {
handleClickOutside(true);
}
@@ -147,7 +147,7 @@ function onFullScreen() {
onMounted(() => {
const isMobile = $_isMobile();
if (isMobile) {
pureApp.toggleDevice("mobile");
useAppStoreHook().toggleDevice("mobile");
handleClickOutside(true);
}
toggleClass(
@@ -163,7 +163,7 @@ onBeforeMount(() => {
</script>
<template>
<div :class="['app-wrapper', set.classes]">
<div :class="['app-wrapper', set.classes]" v-resize>
<div
v-show="
set.device === 'mobile' &&
@@ -181,7 +181,9 @@ onBeforeMount(() => {
v-show="!containerHiddenSideBar && layout.includes('vertical')"
/>
<!-- tabs标签页 -->
<Horizontal v-show="layout.includes('horizontal')" />
<Horizontal
v-show="!containerHiddenSideBar && layout.includes('horizontal')"
/>
<tag>
<span @click="onFullScreen">
<fullScreen v-if="!containerHiddenSideBar" />
@@ -204,7 +206,6 @@ onBeforeMount(() => {
</style>
<style lang="scss" scoped>
$sideBarWidth: 210px;
@mixin clearfix {
&::after {
content: "";
@@ -241,7 +242,7 @@ $sideBarWidth: 210px;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$sideBarWidth});
width: calc(100% - 210px);
transition: width 0.28s;
}

55
src/layout/types.ts Normal file
View File

@@ -0,0 +1,55 @@
export type RouteConfigs = {
path?: string;
parentPath?: string;
meta?: {
title?: string;
icon?: string;
showLink?: boolean;
savedPosition?: boolean;
};
};
export type relativeStorageType = {
routesInStorage: Array<RouteConfigs>;
};
export type tagsViewsType = {
icon: string;
text: string;
divided: {
valueOf: () => boolean;
};
disabled: {
valueOf: () => boolean;
};
show: {
valueOf: () => boolean;
};
};
export interface setType {
sidebar: {
opened: boolean;
withoutAnimation: boolean;
};
device: string;
fixedHeader: boolean;
classes: {
hideSidebar: boolean;
openSidebar: boolean;
withoutAnimation: boolean;
mobile: boolean;
};
}
export const routerArrays: Array<RouteConfigs> = [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true
}
}
];

View File

@@ -6,6 +6,7 @@ import { createApp, Directive } from "vue";
import { usI18n } from "../src/plugins/i18n";
import { useTable } from "../src/plugins/vxe-table";
import { useElementPlus } from "../src/plugins/element-plus";
import { injectResponsiveStorage } from "/@/utils/storage/responsive";
import "animate.css";
// 导入公共样式
@@ -17,49 +18,14 @@ import "v-contextmenu/dist/themes/default.css";
const app = createApp(App);
// 响应式storage
import Storage from "responsive-storage";
// @ts-ignore
app.use(Storage, {
// 默认显示首页tag
routesInStorage: {
type: Array,
default: Storage.getData(undefined, "routesInStorage") ?? [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true,
savedPosition: false
}
}
]
},
// 国际化 默认中文zh
locale: {
type: Object,
default: Storage.getData(undefined, "locale") ?? {
locale: "zh"
}
},
// layout模式以及主题
layout: {
type: Object,
default: Storage.getData(undefined, "layout") ?? {
layout: "vertical-dark"
}
}
});
// 自定义指令
import * as directives from "/@/directives";
Object.keys(directives).forEach(key => {
app.directive(key, (directives as { [key: string]: Directive })[key]);
});
getServerConfig(app).then(async () => {
getServerConfig(app).then(async config => {
injectResponsiveStorage(app, config);
setupStore(app);
app.use(router).use(useElementPlus).use(useTable).use(usI18n);
await router.isReady();

View File

@@ -100,7 +100,13 @@ export const buttonConfig = {
hsexpendAll: "全部展开",
hscollapseAll: "全部折叠",
hssystemSet: "系统设置",
hsdelete: "删除"
hsdelete: "删除",
hsreload: "重新加载",
hscloseCurrentTab: "关闭当前标签页",
hscloseLeftTabs: "关闭左侧标签页",
hscloseRightTabs: "关闭右侧标签页",
hscloseOtherTabs: "关闭其他标签页",
hscloseAllTabs: "关闭全部标签页"
}
},
en: {
@@ -118,7 +124,13 @@ export const buttonConfig = {
hsexpendAll: "Expand All",
hscollapseAll: "Collapse All",
hssystemSet: "System Set",
hsdelete: "Delete"
hsdelete: "Delete",
hsreload: "Reload",
hscloseCurrentTab: "Close CurrentTab",
hscloseLeftTabs: "Close LeftTabs",
hscloseRightTabs: "Close RightTabs",
hscloseOtherTabs: "Close OtherTabs",
hscloseAllTabs: "Close AllTabs"
}
}
};

View File

@@ -2,12 +2,14 @@ import {
Router,
createRouter,
RouteComponent,
createWebHashHistory
createWebHashHistory,
RouteRecordNormalized
} from "vue-router";
import { split } from "lodash-es";
import { i18n } from "/@/plugins/i18n";
import NProgress from "/@/utils/progress";
import { openLink } from "/@/utils/link";
import NProgress from "/@/utils/progress";
import { useTimeoutFn } from "@vueuse/core";
import { storageSession, storageLocal } from "/@/utils/storage";
import { usePermissionStoreHook } from "/@/store/modules/permission";
@@ -49,6 +51,59 @@ export const constantRoutesArr: Array<RouteComponent> = ascending(
constantRoutes
).concat(...remainingRouter);
// 过滤meta中showLink为false的路由
export const filterTree = data => {
const newTree = data.filter(v => v.meta.showLink);
newTree.forEach(v => v.children && (v.children = filterTree(v.children)));
return newTree;
};
// 从路由中提取keepAlive为true的name组成数组此处本项目中并没有用到只是暴露个方法
export const getAliveRoute = () => {
const alivePageList = [];
const recursiveSearch = treeLists => {
if (!treeLists || !treeLists.length) {
return;
}
for (let i = 0; i < treeLists.length; i++) {
if (treeLists[i]?.meta?.keepAlive) alivePageList.push(treeLists[i].name);
recursiveSearch(treeLists[i].children);
}
};
recursiveSearch(router.options.routes);
return alivePageList;
};
// 处理缓存路由(添加、删除、刷新)
export const handleAliveRoute = (
matched: RouteRecordNormalized[],
mode?: string
) => {
switch (mode) {
case "add":
matched.forEach(v => {
usePermissionStoreHook().cacheOperate({ mode: "add", name: v.name });
});
break;
case "delete":
usePermissionStoreHook().cacheOperate({
mode: "delete",
name: matched[matched.length - 1].name
});
break;
default:
usePermissionStoreHook().cacheOperate({
mode: "delete",
name: matched[matched.length - 1].name
});
useTimeoutFn(() => {
matched.forEach(v => {
usePermissionStoreHook().cacheOperate({ mode: "add", name: v.name });
});
}, 100);
}
};
// 过滤后端传来的动态路由 重新生成规范路由
export const addAsyncRoutes = (arrRoutes: Array<RouteComponent>) => {
if (!arrRoutes || !arrRoutes.length) return;
@@ -65,9 +120,10 @@ export const addAsyncRoutes = (arrRoutes: Array<RouteComponent>) => {
return arrRoutes;
};
const router: Router = createRouter({
// 创建路由实例
export const router: Router = createRouter({
history: createWebHashHistory(),
routes: ascending(constantRoutes).concat(...remainingRouter),
routes: filterTree(ascending(constantRoutes)).concat(...remainingRouter),
scrollBehavior(to, from, savedPosition) {
return new Promise(resolve => {
if (savedPosition) {
@@ -83,6 +139,7 @@ const router: Router = createRouter({
}
});
// 初始化路由
export const initRouter = name => {
return new Promise(resolve => {
getAsyncRoutes({ name }).then(({ info }) => {
@@ -115,7 +172,7 @@ export const initRouter = name => {
});
};
// reset router
// 重置路由
export function resetRouter() {
router.getRoutes().forEach(route => {
const { name } = route;
@@ -125,9 +182,18 @@ export function resetRouter() {
});
}
// 路由白名单
const whiteList = ["/login", "/register"];
router.beforeEach((to, _from, next) => {
if (to.meta?.keepAlive) {
const newMatched = to.matched;
handleAliveRoute(newMatched, "add");
// 页面整体刷新和点击标签页刷新
if (_from.name === undefined || _from.name === "redirect") {
handleAliveRoute(newMatched);
}
}
const name = storageSession.getItem("info");
NProgress.start();
const externalLink = to?.redirectedFrom?.fullPath;

View File

@@ -9,7 +9,6 @@ const componentsRouter = {
icon: "el-icon-menu",
title: "message.hscomponents",
showLink: true,
savedPosition: true,
rank: 4
},
children: [
@@ -19,8 +18,7 @@ const componentsRouter = {
component: () => import("/@/views/components/video/index.vue"),
meta: {
title: "message.hsvideo",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -30,7 +28,10 @@ const componentsRouter = {
meta: {
title: "message.hsmap",
showLink: true,
savedPosition: true
keepAlive: true,
transition: {
name: "fade"
}
}
},
{
@@ -40,7 +41,10 @@ const componentsRouter = {
meta: {
title: "message.hsdraggable",
showLink: true,
savedPosition: true
transition: {
enterTransition: "animate__zoomIn",
leaveTransition: "animate__zoomOut"
}
}
},
@@ -51,7 +55,10 @@ const componentsRouter = {
meta: {
title: "message.hssplitPane",
showLink: true,
savedPosition: true
extraIcon: {
svg: true,
name: "team-iconxinpinrenqiwang"
}
}
},
{
@@ -60,8 +67,7 @@ const componentsRouter = {
component: () => import("/@/views/components/button/index.vue"),
meta: {
title: "message.hsbutton",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -70,8 +76,7 @@ const componentsRouter = {
component: () => import("/@/views/components/cropping/index.vue"),
meta: {
title: "message.hscropping",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -80,8 +85,7 @@ const componentsRouter = {
component: () => import("/@/views/components/count-to/index.vue"),
meta: {
title: "message.hscountTo",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -90,8 +94,7 @@ const componentsRouter = {
component: () => import("/@/views/components/selector/index.vue"),
meta: {
title: "message.hsselector",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -100,8 +103,7 @@ const componentsRouter = {
component: () => import("/@/views/components/seamless-scroll/index.vue"),
meta: {
title: "message.hsseamless",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -110,8 +112,7 @@ const componentsRouter = {
component: () => import("/@/views/components/contextmenu/index.vue"),
meta: {
title: "message.hscontextmenu",
showLink: true,
savedPosition: true
showLink: true
}
}
]

View File

@@ -2,25 +2,28 @@ import Layout from "/@/layout/index.vue";
const editorRouter = {
path: "/editor",
name: "editor",
name: "reEditor",
component: Layout,
redirect: "/editor/index",
meta: {
icon: "el-icon-edit-outline",
title: "message.hseditor",
showLink: true,
savedPosition: true,
rank: 2
},
children: [
{
path: "/editor/index",
name: "editor",
name: "reEditor",
component: () => import("/@/views/editor/index.vue"),
meta: {
title: "message.hseditor",
showLink: true,
savedPosition: true
keepAlive: true,
extraIcon: {
svg: true,
name: "team-iconxinpin"
}
}
}
]

View File

@@ -9,7 +9,6 @@ const errorRouter = {
icon: "el-icon-position",
title: "message.hserror",
showLink: true,
savedPosition: true,
rank: 7
},
children: [
@@ -19,8 +18,7 @@ const errorRouter = {
component: () => import("/@/views/error/401.vue"),
meta: {
title: "message.hsfourZeroOne",
showLink: true,
savedPosition: true
showLink: true
}
},
{
@@ -29,8 +27,7 @@ const errorRouter = {
component: () => import("/@/views/error/404.vue"),
meta: {
title: "message.hsfourZeroFour",
showLink: true,
savedPosition: true
showLink: true
}
}
]

View File

@@ -8,7 +8,6 @@ const externalLink = {
icon: "el-icon-link",
title: "message.externalLink",
showLink: true,
savedPosition: true,
rank: 190
},
children: [
@@ -18,7 +17,6 @@ const externalLink = {
icon: "el-icon-link",
title: "message.externalLink",
showLink: true,
savedPosition: true,
rank: 191
}
}

View File

@@ -9,7 +9,6 @@ const flowChartRouter = {
icon: "el-icon-set-up",
title: "message.hsflowChart",
showLink: true,
savedPosition: true,
rank: 1
},
children: [
@@ -19,8 +18,7 @@ const flowChartRouter = {
component: () => import("/@/views/flow-chart/index.vue"),
meta: {
title: "message.hsflowChart",
showLink: true,
savedPosition: true
showLink: true
}
}
]

View File

@@ -8,7 +8,6 @@ const homeRouter = {
meta: {
icon: "el-icon-s-home",
showLink: true,
savedPosition: false,
rank: 0
},
children: [
@@ -18,8 +17,7 @@ const homeRouter = {
component: () => import("/@/views/welcome.vue"),
meta: {
title: "message.hshome",
showLink: true,
savedPosition: false
showLink: true
}
}
]

View File

@@ -9,7 +9,6 @@ const nestedRouter = {
title: "message.hsmenus",
icon: "el-icon-s-data",
showLink: true,
savedPosition: false,
rank: 5
},
children: [
@@ -20,7 +19,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1",
showLink: true,
savedPosition: false
keepAlive: true
},
redirect: "/nested/menu1/menu1-1",
children: [
@@ -31,7 +30,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1-1",
showLink: true,
savedPosition: false
keepAlive: true
}
},
{
@@ -42,7 +41,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1-2",
showLink: true,
savedPosition: false
keepAlive: true
},
children: [
{
@@ -53,7 +52,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1-2-1",
showLink: true,
savedPosition: false
keepAlive: true
}
},
{
@@ -64,7 +63,11 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1-2-2",
showLink: true,
savedPosition: false
keepAlive: true,
extraIcon: {
svg: true,
name: "team-iconxinpinrenqiwang"
}
}
}
]
@@ -76,7 +79,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu1-3",
showLink: true,
savedPosition: false
keepAlive: true
}
}
]
@@ -88,7 +91,7 @@ const nestedRouter = {
meta: {
title: "message.hsmenu2",
showLink: true,
savedPosition: false
keepAlive: true
}
}
]

View File

@@ -29,7 +29,6 @@ const remainingRouter = [
icon: "el-icon-s-home",
title: "message.hshome",
showLink: false,
savedPosition: false,
rank: 104
},
children: [

View File

@@ -8,6 +8,7 @@ interface AppState {
opened: boolean;
withoutAnimation: boolean;
};
layout: string;
device: string;
}
@@ -20,6 +21,9 @@ export const useAppStore = defineStore({
: true,
withoutAnimation: false
},
layout:
storageLocal.getItem("responsive-layout")?.layout.match(/(.*)-/)[1] ??
"vertical",
device: deviceDetection() ? "mobile" : "desktop"
}),
getters: {
@@ -56,6 +60,9 @@ export const useAppStore = defineStore({
},
toggleDevice(device) {
this.TOGGLE_DEVICE(device);
},
setLayout(layout) {
this.layout = layout;
}
}
});

View File

@@ -1,7 +1,7 @@
import { defineStore } from "pinia";
import { store } from "/@/store";
import { constantRoutesArr, ascending } from "/@/router/index";
import { cacheType } from "./types";
import { constantRoutesArr, ascending, filterTree } from "/@/router/index";
export const usePermissionStore = defineStore({
id: "pure-permission",
@@ -9,13 +9,15 @@ export const usePermissionStore = defineStore({
// 静态路由
constantRoutes: constantRoutesArr,
wholeRoutes: [],
buttonAuth: []
buttonAuth: [],
// 缓存页面keepAlive
cachePageList: []
}),
actions: {
asyncActionRoutes(routes) {
if (this.wholeRoutes.length > 0) return;
this.wholeRoutes = ascending(this.constantRoutes.concat(routes)).filter(
v => v.meta.showLink
this.wholeRoutes = filterTree(
ascending(this.constantRoutes.concat(routes))
);
const getButtonAuth = (arrRoutes: Array<string>) => {
@@ -34,6 +36,23 @@ export const usePermissionStore = defineStore({
},
async changeSetting(routes) {
await this.asyncActionRoutes(routes);
},
cacheOperate({ mode, name }: cacheType) {
switch (mode) {
case "add":
this.cachePageList.push(name);
this.cachePageList = [...new Set(this.cachePageList)];
break;
case "delete":
// eslint-disable-next-line no-case-declarations
const delIndex = this.cachePageList.findIndex(v => v === name);
this.cachePageList.splice(delIndex, 1);
break;
}
},
// 清空缓存页面
clearAllCachePage() {
this.cachePageList = [];
}
}
});

View File

@@ -5,16 +5,13 @@ import { store } from "/@/store";
interface SettingState {
title: string;
fixedHeader: boolean;
cachedPageList: string[];
}
export const useSettingStore = defineStore({
id: "pure-setting",
state: (): SettingState => ({
title: defaultSettings.title,
fixedHeader: defaultSettings.fixedHeader,
// 需要开启keepalive的页面数组里面放页面的name即可
cachedPageList: ["welcome", "reEditor"]
fixedHeader: defaultSettings.fixedHeader
}),
getters: {
getTitle() {

View File

@@ -0,0 +1,6 @@
import { RouteRecordName } from "vue-router";
export type cacheType = {
mode: string;
name?: RouteRecordName;
};

View File

@@ -48,7 +48,7 @@
z-index: -1;
}
// el-tooltip,的权重
// .is-dark {
// z-index: 99999 !important;
// }
// el-tooltip的权重
.is-dark {
z-index: 99999 !important;
}

View File

@@ -161,8 +161,6 @@
height: 100%;
min-width: 0;
flex: 1;
// todo::
overflow-x: auto;
align-items: center;
}
@@ -181,7 +179,7 @@
}
}
.iconinternationality {
.globalization {
height: 62px;
width: 40px;
padding: 11px;

View File

@@ -1,4 +1,21 @@
import type { Emitter } from "mitt";
import mitt from "mitt";
export const emitter: Emitter = mitt();
type Events = {
resize: {
detail: {
width: number;
height: number;
};
};
openPanel: string;
tagViewsChange: string;
tagViewsShowModel: string;
logoChange: string;
changLayoutRoute: {
indexPath: string;
parentPath: string;
};
};
export const emitter: Emitter<Events> = mitt<Events>();

View File

@@ -0,0 +1,53 @@
import { loadEnv } from "@build/utils";
import { merge } from "lodash-es";
import tsCookies from "typescript-cookie/dist/src/compat";
class Cookies {
private static env = loadEnv();
constructor() {}
/**
* 存储 cookie 值
* @param name
* @param value
* @param cookieSetting
*/
set(name = "default", value = "", cookieSetting = {}) {
const currentCookieSetting = {
expires: 1
};
merge(currentCookieSetting, cookieSetting);
tsCookies.set(
`${Cookies.env.VITE_TITLE}-${Cookies.env.VITE_VERSION}-${name}`,
value,
currentCookieSetting
);
}
/**
* 拿到 cookie 值
* @param name
* @returns
*/
get(name = "default") {
return tsCookies.get(
`${Cookies.env.VITE_TITLE}-${Cookies.env.VITE_VERSION}-${name}`
);
}
/**
* 拿到 cookie 全部的值
* @returns
*/
getAll() {
return tsCookies.get();
}
/**
* 删除 cookie
* @param name
*/
remove(name = "default") {
tsCookies.remove(
`${Cookies.env.VITE_TITLE}-${Cookies.env.VITE_VERSION}-${name}`
);
}
}
export const cookies = new Cookies();

87
src/utils/storage/db.ts Normal file
View File

@@ -0,0 +1,87 @@
import { loadEnv } from "@build/utils";
import { LocalStorage, LowSync } from "lowdb";
import { chain, cloneDeep } from "lodash-es";
import { storageLocal } from ".";
import { cookies } from "./cookie";
type Data = {
database: {};
sys: {};
};
/**
* db 数据存储,采用 LocalStorage存储
*/
class DB {
private db: LowSync<Data>;
private static env = loadEnv();
constructor() {
this.db = new LowSync<Data>(
new LocalStorage<Data>(`${DB.env.VITE_TITLE}-${DB.env.VITE_VERSION}`)
);
this.initialization();
this.db.chain = chain(this.db.data);
}
private initialization() {
this.db.data = storageLocal.getItem(
`${DB.env.VITE_TITLE}-${DB.env.VITE_VERSION}`
) || { database: {}, sys: {} };
this.db.write();
}
/**
* 检查路径是否存在 不存在的话初始化
* @param param0
* @returns path
*/
pathInit({
dbName = "database",
path = "",
user = true,
validator = () => true,
defaultValue = ""
}): string {
const uuid = cookies.get("uuid") || "ghost-uuid";
const currentPath = `${dbName}.${user ? `user.${uuid}` : "public"}${
path ? `.${path}` : ""
}`;
const value = this.db.chain.get(currentPath).value();
if (!(value !== undefined && validator(value))) {
this.db.chain.set(currentPath, defaultValue).value();
this.db.write();
}
return currentPath;
}
/**
*将数据存储到指定位置 | 路径不存在会自动初始化
*
* 效果类似于取值 dbName.path = value
* @param param0
*/
dbSet({ dbName = "database", path = "", value = "", user = false }): void {
const currentPath = this.pathInit({
dbName,
path,
user
});
this.db.chain.set(currentPath, value).value();
this.db.write();
}
/**
* 获取数据
*
* 效果类似于取值 dbName.path || defaultValue
* @param param0
* @returns
*/
dbGet({
dbName = "database",
path = "",
defaultValue = "",
user = false
}): any {
const values = this.db.chain
.get(this.pathInit({ dbName, path, user, defaultValue }))
.value();
return cloneDeep(values);
}
}
export const db = new DB();

View File

@@ -0,0 +1,37 @@
// 响应式storage
import { App } from "vue";
import Storage from "responsive-storage";
export const injectResponsiveStorage = (app: App, config: ServerConfigs) => {
app.use(Storage, {
// 默认显示首页tag
routesInStorage: {
type: Array,
default: Storage.getData(undefined, "routesInStorage") ?? [
{
path: "/welcome",
parentPath: "/",
meta: {
title: "message.hshome",
icon: "el-icon-s-home",
showLink: true
}
}
]
},
// 国际化 默认中文zh
locale: {
type: Object,
default: Storage.getData(undefined, "locale") ?? {
locale: config.Locale
}
},
// layout模式以及主题
layout: {
type: Object,
default: Storage.getData(undefined, "layout") ?? {
layout: config.Layout
}
}
});
};

View File

@@ -21,7 +21,7 @@ let lists = ref<Array<Object>>([
{ people: "cn", id: 4, name: "www.google.com" }
]);
let cutLists = ref<Array<Object>>([
let cutLists = ref([
{ people: "cn", id: 1, name: "cut1" },
{ people: "cn", id: 2, name: "cut2" },
{ people: "cn", id: 3, name: "cut3" },

View File

@@ -6,7 +6,7 @@ import SeamlessScroll from "/@/components/ReSeamlessScroll";
// eslint-disable-next-line no-undef
const scroll = templateRef<ElRef | null>("scroll", null);
let listData = ref<ForDataType<undefined>>([
let listData = ref([
{
title: "无缝滚动第一行无缝滚动第一行!!!!!!!!!!"
},

View File

@@ -3,7 +3,7 @@ import { ref } from "vue";
import Selector from "/@/components/ReSelector";
let selectRange = ref<string>("");
let dataLists = ref<ForDataType<undefined>>([
let dataLists = ref([
{
title: "基本使用",
echo: [],

View File

@@ -1,16 +1,17 @@
<script setup lang="ts">
import { reactive, onBeforeMount } from "vue";
import info, { ContextProps } from "../components/ReInfo/index.vue";
import { getVerify, getLogin } from "/@/api/user";
import { infoType } from "./type";
import { useRouter } from "vue-router";
import { reactive, onBeforeMount } from "vue";
import { getVerify, getLogin } from "/@/api/user";
import { storageSession } from "/@/utils/storage";
import { warnMessage, successMessage } from "/@/utils/message";
import info, { ContextProps } from "../components/ReInfo/index.vue";
const router = useRouter();
// 刷新验证码
const refreshGetVerify = async () => {
let { svg } = await getVerify();
let { svg }: infoType = await getVerify();
contextInfo.svg = svg;
};
@@ -29,7 +30,7 @@ const toPage = (info: Object): void => {
// 登录
const onLogin = async () => {
let { userName, passWord, verify } = contextInfo;
let { code, info, accessToken } = await getLogin({
let { code, info, accessToken }: infoType = await getLogin({
username: userName,
password: passWord,
verify: verify

View File

@@ -1,10 +1,35 @@
<template>
<div class="app-container">
<p>{{ $t("message.hsmenu1") }}</p>
<router-view v-slot="{ Component }">
<transition>
<component :is="Component" />
</transition>
<router-view>
<template #default="{ Component, route }">
<transition appear name="fade-transform" mode="out-in">
<keep-alive
v-if="keepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<component v-else :is="Component" :key="route.fullPath" />
</transition>
</template>
</router-view>
</div>
</template>
<script lang="ts">
import { ref, getCurrentInstance } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";
export default {
name: "Menu1",
setup() {
const keepAlive: Boolean = ref(
getCurrentInstance().appContext.config.globalProperties.$config?.KeepAlive
);
return {
keepAlive,
usePermissionStoreHook
};
}
};
</script>

View File

@@ -1,3 +1,18 @@
<template>
<p style="text-indent: 2em">{{ $t("message.hsmenu1-1") }}</p>
<div>
<p style="text-indent: 2em">{{ $t("message.hsmenu1-1") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-1",
setup() {
return {
input: ref("")
};
}
});
</script>

View File

@@ -1,10 +1,35 @@
<template>
<div>
<p style="text-indent: 2em">{{ $t("message.hsmenu1-2") }}</p>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
<router-view>
<template #default="{ Component, route }">
<transition appear name="fade-transform" mode="out-in">
<keep-alive
v-if="keepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<component v-else :is="Component" :key="route.fullPath" />
</transition>
</template>
</router-view>
</div>
</template>
<script lang="ts">
import { ref, getCurrentInstance } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";
export default {
name: "Menu1-2",
setup() {
const keepAlive: Boolean = ref(
getCurrentInstance().appContext.config.globalProperties.$config?.KeepAlive
);
return {
keepAlive,
usePermissionStoreHook
};
}
};
</script>

View File

@@ -1,3 +1,18 @@
<template>
<p style="text-indent: 4em">{{ $t("message.hsmenu1-2-1") }}</p>
<div>
<p style="text-indent: 4em">{{ $t("message.hsmenu1-2-1") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-2-1",
setup() {
return {
input: ref("")
};
}
});
</script>

View File

@@ -1,3 +1,18 @@
<template>
<p style="text-indent: 4em">{{ $t("message.hsmenu1-2-2") }}</p>
<div>
<p style="text-indent: 4em">{{ $t("message.hsmenu1-2-2") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-2-2",
setup() {
return {
input: ref("")
};
}
});
</script>

View File

@@ -1,3 +1,18 @@
<template>
<p style="text-indent: 2em">{{ $t("message.hsmenu1-3") }}</p>
<div>
<p style="text-indent: 2em">{{ $t("message.hsmenu1-3") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-3",
setup() {
return {
input: ref("")
};
}
});
</script>

View File

@@ -1,3 +1,18 @@
<template>
<p class="app-container">{{ $t("message.hsmenu2") }}</p>
<div class="app-container">
<p>{{ $t("message.hsmenu2") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu2",
setup() {
return {
input: ref("")
};
}
});
</script>

View File

@@ -2,7 +2,7 @@
import { ref } from "vue";
import { storageSession } from "/@/utils/storage";
const auth = ref<Boolean>(storageSession.getItem("info").username || "admin");
const auth = ref<boolean>(storageSession.getItem("info").username || "admin");
function changRole(value) {
storageSession.setItem("info", {

6
src/views/type.ts Normal file
View File

@@ -0,0 +1,6 @@
export type infoType = {
svg?: string;
code?: number;
info?: string;
accessToken?: string;
};

View File

@@ -1,6 +1,4 @@
<script setup lang="ts">
import { ref, shallowRef, computed, onBeforeMount } from "vue";
import { useAppStoreHook } from "/@/store/modules/app";
import {
ReGithub,
ReInfinite,
@@ -8,10 +6,12 @@ import {
ReLine,
ReBar
} from "/@/components/ReCharts/index";
import { useAppStoreHook } from "/@/store/modules/app";
import { ref, shallowRef, computed, onBeforeMount } from "vue";
const date: Date = new Date();
let loading = ref<boolean>(true);
const componentList = shallowRef<ForDataType<undefined>>([]);
const componentList = shallowRef([]);
setTimeout(() => {
loading.value = !loading.value;
@@ -89,7 +89,6 @@ const openDepot = (): void => {
<img
src="https://avatars.githubusercontent.com/u/44761321?s=400&u=30907819abd29bb3779bc247910873e7c7f7c12f&v=4"
title="直达仓库地址"
alt
@click="openDepot"
/>
<span>{{ greetings }}</span>

View File

@@ -16,14 +16,15 @@
"sourceMap": true,
"baseUrl": ".",
"allowJs": false,
"resolveJsonModule": true, // 包含导入的模块。json的扩展
"resolveJsonModule": true,
"lib": ["dom", "esnext"],
"incremental": true,
"paths": {
"/@/*": ["src/*"],
"@build/*": ["build/*"],
"/#/*": ["types/*"]
},
"types": ["node", "vite/client"],
"types": ["node", "vite/client", "element-plus/global"],
"typeRoots": ["./node_modules/@types/", "./types"]
},
"include": [

10
types/global.d.ts vendored
View File

@@ -65,6 +65,8 @@ declare global {
declare interface ViteEnv {
VITE_PORT: number;
VITE_TITLE: string;
VITE_VERSION: string;
VITE_USE_MOCK: boolean;
VITE_USE_PWA: boolean;
VITE_PUBLIC_PATH: string;
@@ -80,6 +82,14 @@ declare global {
VITE_GENERATE_UI: string;
}
declare interface ServerConfigs {
Version?: string;
KeepAlive?: boolean;
Locale?: string;
Layout?: string;
MapConfigure?: any;
}
function parseInt(s: string | number, radix?: number): number;
function parseFloat(string: string | number): number;

2
types/index.d.ts vendored
View File

@@ -29,3 +29,5 @@ declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>;
declare type ForDataType<T> = {
[P in T]?: ForDataType<T[P]>;
};
declare type AnyFunction<T> = (...args: any[]) => T;

View File

@@ -7,7 +7,7 @@ import { createProxy } from "./build/proxy";
import { viteMockServe } from "vite-plugin-mock";
import svgLoader from "vite-svg-loader";
import styleImport from "vite-plugin-style-import";
import ElementPlus from "unplugin-element-plus";
import ElementPlus from "unplugin-element-plus/vite";
const pathResolve = (dir: string): any => {
return resolve(__dirname, ".", dir);
@@ -15,6 +15,7 @@ const pathResolve = (dir: string): any => {
const alias: Record<string, string> = {
"/@": pathResolve("src"),
"@build": pathResolve("build"),
//解决开发环境下的警告 You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler to explicitly replace feature flag globals with boolean literals to get proper tree-shaking in the final bundle.
"vue-i18n": "vue-i18n/dist/vue-i18n.cjs.js"
};

460
yarn.lock
View File

@@ -527,9 +527,9 @@
fastq "^1.6.0"
"@popperjs/core@^2.10.1":
version "2.10.1"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz#728ecd95ab207aab8a9a4e421f0422db329232be"
integrity sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==
version "2.10.2"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
"@rollup/plugin-node-resolve@^13.0.4":
version "13.0.4"
@@ -781,13 +781,13 @@
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-core@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9"
integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg==
"@vue/compiler-core@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.20.tgz#af5a3c5237818835b0d0be837eb5885a8d21c160"
integrity sha512-vcEXlKXoPwBXFP5aUTHN9GTZaDfwCofa9Yu9bbW2C5O/QSa9Esdt7OG4+0RRd3EHEMxUvEdj4RZrd/KpQeiJbA==
dependencies:
"@babel/parser" "^7.15.0"
"@vue/shared" "3.2.19"
"@vue/shared" "3.2.20"
estree-walker "^2.0.2"
source-map "^0.6.1"
@@ -799,25 +799,25 @@
"@vue/compiler-core" "3.2.11"
"@vue/shared" "3.2.11"
"@vue/compiler-dom@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8"
integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw==
"@vue/compiler-dom@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.20.tgz#8e0ef354449c0faf41519b00bfc2045eae01dcb5"
integrity sha512-QnI77ec/JtV7R0YBbcVayYTDCRcI9OCbxiUQK6izVyqQO0658n0zQuoNwe+bYgtqnvGAIqTR3FShTd5y4oOjdg==
dependencies:
"@vue/compiler-core" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-core" "3.2.20"
"@vue/shared" "3.2.20"
"@vue/compiler-sfc@3.2.19", "@vue/compiler-sfc@^3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be"
integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA==
"@vue/compiler-sfc@3.2.20", "@vue/compiler-sfc@^3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.20.tgz#2d7668e76f066c566dd7c09c15c9acce4e876e0a"
integrity sha512-03aZo+6tQKiFLfunHKSPZvdK4Jsn/ftRCyaro8AQIWkuxJbvSosbKK6HTTn+D2c3nPScG155akJoxKENw7rftQ==
dependencies:
"@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.19"
"@vue/compiler-dom" "3.2.19"
"@vue/compiler-ssr" "3.2.19"
"@vue/ref-transform" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-core" "3.2.20"
"@vue/compiler-dom" "3.2.20"
"@vue/compiler-ssr" "3.2.20"
"@vue/ref-transform" "3.2.20"
"@vue/shared" "3.2.20"
estree-walker "^2.0.2"
magic-string "^0.25.7"
postcss "^8.1.10"
@@ -855,19 +855,24 @@
"@vue/compiler-dom" "3.2.11"
"@vue/shared" "3.2.11"
"@vue/compiler-ssr@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c"
integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w==
"@vue/compiler-ssr@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.20.tgz#9cceb6261d9932cb5568202610c1c28f86c5e521"
integrity sha512-rzzVVYivm+EjbfiGQvNeyiYZWzr6Hkej97RZLZvcumacQlnKv9176Xo9rRyeWwFbBlxmtNdrVMslRXtipMXk2w==
dependencies:
"@vue/compiler-dom" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-dom" "3.2.20"
"@vue/shared" "3.2.20"
"@vue/devtools-api@^6.0.0-beta.13", "@vue/devtools-api@^6.0.0-beta.14", "@vue/devtools-api@^6.0.0-beta.15":
"@vue/devtools-api@^6.0.0-beta.13", "@vue/devtools-api@^6.0.0-beta.14":
version "6.0.0-beta.15"
resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
"@vue/devtools-api@^6.0.0-beta.18":
version "6.0.0-beta.18"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.18.tgz#84c0aff9289a57294cb97490811f69e8a0a67f8a"
integrity sha512-56vRhO7nXWWFYTx520BQSDlQH5VYpwy62hFDEqi2yHHEBpEqseOP5WYQusq7BEW3DXSY9E9cfPVR5CFtJbKuMg==
"@vue/eslint-config-prettier@^6.0.0":
version "6.0.0"
resolved "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz#ad5912b308f4ae468458e02a2b05db0b9d246700"
@@ -882,12 +887,12 @@
dependencies:
vue-eslint-parser "^7.0.0"
"@vue/reactivity@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65"
integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA==
"@vue/reactivity@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.20.tgz#81fe1c368e7f20bc0ec1dec1045bbee253582de8"
integrity sha512-nSmoLojUTk+H8HNTAkrUduB4+yIUBK2HPihJo2uXVSH4Spry6oqN6lFzE5zpLK+F27Sja+UqR9R1+/kIOsHV5w==
dependencies:
"@vue/shared" "3.2.19"
"@vue/shared" "3.2.20"
"@vue/ref-transform@3.2.11":
version "3.2.11"
@@ -900,58 +905,58 @@
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/ref-transform@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600"
integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg==
"@vue/ref-transform@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.20.tgz#2a59ec90caf8e5c7336776a0900bff0a8b81c090"
integrity sha512-Y42d3PGlYZ1lXcF3dbd3+qU/C/a3wYEZ949fyOI5ptzkjDWlkfU6vn74fmOjsLjEcjs10BXK2qO99FqQIK2r1Q==
dependencies:
"@babel/parser" "^7.15.0"
"@vue/compiler-core" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-core" "3.2.20"
"@vue/shared" "3.2.20"
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/runtime-core@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3"
integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ==
"@vue/runtime-core@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.20.tgz#8f63e956a3f88fb772541443c45a7701211012cb"
integrity sha512-d1xfUGhZPfiZzAN7SatStD4vRtT8deJSXib2+Cz3x0brjMWKxe32asQc154FF1E2fFgMCHtnfd4A90bQEzV4GQ==
dependencies:
"@vue/reactivity" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/reactivity" "3.2.20"
"@vue/shared" "3.2.20"
"@vue/runtime-dom@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb"
integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A==
"@vue/runtime-dom@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.20.tgz#8aa56ae6c30f9cd4a71ca0e9ec3c4bdc67148d15"
integrity sha512-4TCvZMLhESWCFHFYgqN4QmMA/onnINAlUovhopjlS8ST27G1A8Z0tyxPzLoXLa+b5JrOpbMPheEMPvdKExTJig==
dependencies:
"@vue/runtime-core" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/runtime-core" "3.2.20"
"@vue/shared" "3.2.20"
csstype "^2.6.8"
"@vue/server-renderer@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1"
integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w==
"@vue/server-renderer@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.20.tgz#705e07ae9425132b2b6227d308a51a13f4d4ec81"
integrity sha512-viIbZGep9XabnrRcaxWIi00cOh1x21QYm2upIL5W0zqzTJ54VdTzpI+zi1osNp+VfRQDTHpV2U7H3Kn4ljYJvg==
dependencies:
"@vue/compiler-ssr" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-ssr" "3.2.20"
"@vue/shared" "3.2.20"
"@vue/shared@3.2.11":
version "3.2.11"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.11.tgz#01899f54949caf1ac241de397bd17069632574de"
integrity sha512-ovfXAsSsCvV9JVceWjkqC/7OF5HbgLOtCWjCIosmPGG8lxbPuavhIxRH1dTx4Dg9xLgRTNLvI3pVxG4ItQZekg==
"@vue/shared@3.2.19":
version "3.2.19"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7"
integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew==
"@vue/shared@3.2.20":
version "3.2.20"
resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.2.20.tgz#53746961f731a8ea666e3316271e944238dc31db"
integrity sha512-FbpX+hD5BvXCQerEYO7jtAGHlhAkhTQ4KIV73kmLWNlawWhTiVuQxizgVb0BOkX5oG9cIRZ42EG++d/k/Efp0w==
"@vueuse/core@^6.4.1":
version "6.4.1"
resolved "https://registry.npmjs.org/@vueuse/core/-/core-6.4.1.tgz#21416997a23bfb4924a5082ed6fa959027f80d04"
integrity sha512-FRFeEPVq77gcMZP0mCloJY+lyHJaUQmUMaPp5fBds3fs/BbkAt7HTMMizFKHWDVjbmA20vBOjmC9tTnfD+DdEA==
"@vueuse/core@^6.5.3":
version "6.5.3"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-6.5.3.tgz#15848eaccad18652df4cb4b6ccae7bd7921a0c7e"
integrity sha512-o3CTu4nEqs371sDY5qLBX0r4QOm6GVpm3ApQc2Y+p8OMI2rRGartQo8xRykpUfsyq602A+SVtm/wxIWBkD/KCQ==
dependencies:
"@vueuse/shared" "6.4.1"
"@vueuse/shared" "6.5.3"
vue-demi "*"
"@vueuse/core@~6.1.0":
@@ -969,10 +974,10 @@
dependencies:
vue-demi "*"
"@vueuse/shared@6.4.1":
version "6.4.1"
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-6.4.1.tgz#5bc84be107cead84e11c21d2c57b1e9f2c376975"
integrity sha512-zsaYxxZwACQbMmGg+UBjPUVemi325sDdnnB0mn+PNizE0fVC57B+vbLgdj45NBmr6P4nw6a0Y2rMupebwDWsdw==
"@vueuse/shared@6.5.3":
version "6.5.3"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-6.5.3.tgz#6503fa4bfbf45d0616bacedb8a4bd003f01da73b"
integrity sha512-ChOKu3mECyZeqGJ/gHVm0CaHoZK5/TwNZr1ZM/aqH+RaRNQvC1qkLf1/8PBugzN3yRgC3BtZ/M1kLpGe/BFylw==
dependencies:
vue-demi "*"
@@ -1103,10 +1108,10 @@ astral-regex@^2.0.0:
resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
async-validator@^3.4.0:
version "3.5.2"
resolved "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz#68e866a96824e8b2694ff7a831c1a25c44d5e500"
integrity sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==
async-validator@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.0.3.tgz#c8ecd6b28fc8e18b14be4ec7c704641f999d377d"
integrity sha512-LVoIbJNHPKsO7FMLamo88uxdrvayGkF3vLTMTeiN3CqAbP3qSafLRc6yx3Sq9lHkiEOLNpoA2jwwnfGDdu1SMQ==
autoprefixer@^10.2.4:
version "10.3.4"
@@ -1593,9 +1598,9 @@ dargs@^7.0.0:
resolved "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==
dayjs@^1.10.6, dayjs@^1.10.7:
dayjs@^1.10.7:
version "1.10.7"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
debug@2.6.9:
@@ -1732,11 +1737,6 @@ dot-prop@^5.1.0:
dependencies:
is-obj "^2.0.0"
dotenv@^8.2.0:
version "8.6.0"
resolved "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
downloadjs@1.4.7:
version "1.4.7"
resolved "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz#f69f96f940e0d0553dac291139865a3cd0101e3c"
@@ -1750,13 +1750,13 @@ draggabilly@^2.2.0:
get-size "^2.0.2"
unidragger "^2.3.0"
echarts@^5.1.2:
version "5.2.0"
resolved "https://registry.npmjs.org/echarts/-/echarts-5.2.0.tgz#9f1fbfbf048c15ab630bf0a74525c4c534d6cebc"
integrity sha512-7CrCKGRjFdpLIJ/Yt1gpHeqs5PiCem2GHPdWZPwKl7WSYeZu0Qzm1bcCFe9/b4dfVaL1zlY4JmdzaVwKksVeqg==
echarts@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.2.1.tgz#bd58ec011cd82def4a714e4038ef4b73b8417bc3"
integrity sha512-OJ79b22eqRfbSV8vYmDKmA+XWfNbr0Uk/OafWcFNIGDWti2Uw9A6eVCiJLmqPa9Sk+EWL+t5v26aak0z3gxiZw==
dependencies:
tslib "2.3.0"
zrender "5.2.0"
zrender "5.2.1"
ee-first@1.1.1:
version "1.1.1"
@@ -1768,18 +1768,18 @@ electron-to-chromium@^1.3.830:
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.840.tgz#3f2a1df97015d9b1db5d86a4c6bd4cdb920adcbb"
integrity sha512-yRoUmTLDJnkIJx23xLY7GbSvnmDCq++NSuxHDQ0jiyDJ9YZBUGJcrdUqm+ZwZFzMbCciVzfem2N2AWiHJcWlbw==
element-plus@^1.1.0-beta.16:
version "1.1.0-beta.16"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-1.1.0-beta.16.tgz#4409d9e33d005693f6039f5ed1fe05e301b3170d"
integrity sha512-4BZEldnIfFZs5A/saRqaWE4PwTot4p3YZU7qsDr3ev2zp35pcCL9TtpWMLIvNTMxvxKew0HTDPTk9fAWIZFQrQ==
element-plus@1.1.0-beta.20:
version "1.1.0-beta.20"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-1.1.0-beta.20.tgz#59523c99a88ca4881d899ba8bb81c4a9273ed822"
integrity sha512-5rBrLzfKGz4urSxqKi1tihylyotSswMCKdXpCAJAfRggMjtS1NfqVtrCYEPdjphmP2JHsj8TisDvbRTScRKF0Q==
dependencies:
"@popperjs/core" "^2.10.1"
"@vueuse/core" "~6.1.0"
async-validator "^3.4.0"
async-validator "^4.0.3"
dayjs "^1.10.7"
lodash "^4.17.21"
memoize-one "^5.2.1"
normalize-wheel "^1.0.1"
normalize-wheel-es "^1.1.0"
resize-observer-polyfill "^1.5.1"
element-resize-detector@^1.2.3:
@@ -1835,11 +1835,6 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
es-module-lexer@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.6.0.tgz#e72ab05b7412e62b9be37c37a09bdb6000d706f0"
integrity sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA==
es-module-lexer@^0.7.1:
version "0.7.1"
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz#c2c8e0f46f2df06274cdaf0dd3f3b33e0a0b267d"
@@ -1871,15 +1866,112 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3:
d "^1.0.1"
ext "^1.1.2"
esbuild-android-arm64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz#5178a20d2b7aba741a31c19609f9e67b346996b9"
integrity sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA==
esbuild-darwin-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz#7a3e66c8e1271b650541b25eed65c84f3564a69d"
integrity sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA==
esbuild-darwin-arm64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz#793feca6032b2a57ef291eb9b2d33768d60a49d6"
integrity sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg==
esbuild-freebsd-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz#294aec3c2cf4b41fb6900212fc9c33dd8fbbb4a2"
integrity sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw==
esbuild-freebsd-arm64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz#09fe66c751c12f9b976976b1d83f3de594cb2787"
integrity sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA==
esbuild-linux-32@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz#a9f0793d7bcc9cef4f4ffa4398c525877fba5839"
integrity sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA==
esbuild-linux-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz#c0d0b4c9d62e3bbf8bdf2cece37403aa6d60fc2e"
integrity sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ==
esbuild-linux-arm64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz#1292d97bfa64a08d12728f8a7837bf92776c779b"
integrity sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ==
esbuild-linux-arm@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz#186cd9b8885ac132b9953a4a0afe668168debd10"
integrity sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA==
esbuild-linux-mips64le@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz#42049bf72bc586817b4a51cc9e32148d13e5e807"
integrity sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw==
esbuild-linux-ppc64le@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz#adf1ce2ef2302757c4383887da6ac4dd25be9d4f"
integrity sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q==
esbuild-openbsd-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz#1c8122101898c52a20c8786935cf3eb7a19b83b4"
integrity sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw==
esbuild-sunos-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz#4ec95faa14a60f295fe485bebffefff408739337"
integrity sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ==
esbuild-windows-32@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz#3182c380487b797b04d0ec2c80c2945666869080"
integrity sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg==
esbuild-windows-64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz#b9e995f92d81f433a04f33611e603e82f9232e69"
integrity sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q==
esbuild-windows-arm64@0.13.4:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz#fb239532f07b764d158f4cc787178ef4c6fadb5c"
integrity sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg==
esbuild@0.11.3:
version "0.11.3"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.11.3.tgz#b57165b907be4ffba651f6450538ce8d8c1d5eb0"
integrity sha512-BzVRHcCtFepjS9WcqRjqoIxLqgpK21a8J4Zi4msSGxDxiXVO1IbcqT1KjhdDDnJxKfe7bvzZrvMEX+bVO0Elcw==
esbuild@^0.12.17:
version "0.12.29"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.29.tgz#be602db7c4dc78944a9dbde0d1ea19d36c1f882d"
integrity sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==
esbuild@^0.13.2:
version "0.13.4"
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.13.4.tgz#ce2deb56c4fb360938311cbfc67f8e467bb6841b"
integrity sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg==
optionalDependencies:
esbuild-android-arm64 "0.13.4"
esbuild-darwin-64 "0.13.4"
esbuild-darwin-arm64 "0.13.4"
esbuild-freebsd-64 "0.13.4"
esbuild-freebsd-arm64 "0.13.4"
esbuild-linux-32 "0.13.4"
esbuild-linux-64 "0.13.4"
esbuild-linux-arm "0.13.4"
esbuild-linux-arm64 "0.13.4"
esbuild-linux-mips64le "0.13.4"
esbuild-linux-ppc64le "0.13.4"
esbuild-openbsd-64 "0.13.4"
esbuild-sunos-64 "0.13.4"
esbuild-windows-32 "0.13.4"
esbuild-windows-64 "0.13.4"
esbuild-windows-arm64 "0.13.4"
escalade@^3.1.1:
version "3.1.1"
@@ -2872,7 +2964,7 @@ locate-path@^6.0.0:
lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/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.camelcase@^4.3.0:
@@ -2897,8 +2989,8 @@ lodash.truncate@^4.4.2:
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=
log-symbols@^4.1.0:
version "4.1.0"
@@ -2923,6 +3015,13 @@ longest-streak@^2.0.0:
resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
lowdb@^3.0.0:
version "3.0.0"
resolved "https://registry.nlark.com/lowdb/download/lowdb-3.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flowdb%2Fdownload%2Flowdb-3.0.0.tgz#c10ab4e7eb86f1cbe255e35e60ffb0c6f42049e0"
integrity sha1-wQq05+uG8cviVeNeYP+wxvQgSeA=
dependencies:
steno "^2.1.0"
lower-case@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
@@ -3103,10 +3202,10 @@ minimist@^1.2.0, minimist@^1.2.5:
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mitt@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
mitt@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd"
integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==
mockjs@^1.1.0:
version "1.1.0"
@@ -3146,16 +3245,16 @@ multimatch@^4.0.0:
arrify "^2.0.1"
minimatch "^3.0.4"
nanocolors@^0.1.5:
version "0.1.12"
resolved "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6"
integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==
nanoid@^3.1.23, nanoid@^3.1.25:
nanoid@^3.1.23:
version "3.1.25"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152"
integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==
nanoid@^3.1.28:
version "3.1.29"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz#214fb2d7a33e1a5bef4757b779dfaeb6a4e5aeb4"
integrity sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -3219,10 +3318,10 @@ normalize-selector@^0.2.0:
resolved "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03"
integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=
normalize-wheel@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
integrity sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=
normalize-wheel-es@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.1.0.tgz#db017af1dd5d4c6222c07ae38bc224049d25861e"
integrity sha512-gkcE5xzp8WkSGgu2HItXePGyh3qDOetgPYg0RnjclOIaWTCMB75NTrk0t6KVlbm6ShSikV3ykBFZMiR9GDkvkA==
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
version "4.0.1"
@@ -3417,6 +3516,11 @@ path@^0.12.7:
process "^0.11.1"
util "^0.10.3"
picocolors@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f"
integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3:
version "2.3.0"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
@@ -3427,12 +3531,12 @@ pify@^2.3.0:
resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
pinia@^2.0.0-rc.6:
version "2.0.0-rc.9"
resolved "https://registry.npmjs.org/pinia/-/pinia-2.0.0-rc.9.tgz#ea0812ea28f8197f14767e9b731ae10d3a523803"
integrity sha512-JrFnxKbuyYPEZ6ZS56sBHRzabZj+5xkJj8jxCHGNJ1h2I824QJuLXJVV/3pgkUw0pfXYrRxcO6EiV9+wapSicg==
pinia@2.0.0-rc.10:
version "2.0.0-rc.10"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.0.0-rc.10.tgz#81e823931897a4cf5c53c113d0c0e63b7bba9973"
integrity sha512-WY0KQoHxSBylhGc6aBQKPFfAupYHWpI1QBQKJSyK9btwwMTVQpwCdePgPho+ZoEMl832jb7RwfI5TN1srV5VEA==
dependencies:
"@vue/devtools-api" "^6.0.0-beta.15"
"@vue/devtools-api" "^6.0.0-beta.18"
vue-demi "*"
please-upgrade-node@^3.2.0:
@@ -3583,13 +3687,13 @@ postcss@^8.1.10, postcss@^8.2.6:
nanoid "^3.1.23"
source-map-js "^0.6.2"
postcss@^8.3.6:
version "8.3.7"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.7.tgz#ec88563588c8da8e58e7226f7633b51ae221eeda"
integrity sha512-9SaY7nnyQ63/WittqZYAvkkYPyKxchMKH71UDzeTmWuLSvxTRpeEeABZAzlCi55cuGcoFyoV/amX2BdsafQidQ==
postcss@^8.3.8:
version "8.3.9"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.9.tgz#98754caa06c4ee9eb59cc48bd073bb6bd3437c31"
integrity sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw==
dependencies:
nanocolors "^0.1.5"
nanoid "^3.1.25"
nanoid "^3.1.28"
picocolors "^0.2.1"
source-map-js "^0.6.2"
preact@^10.4.8:
@@ -3792,12 +3896,10 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.19.0, resolve@^1.20.0:
is-core-module "^2.2.0"
path-parse "^1.0.6"
responsive-storage@^1.0.10:
version "1.0.10"
resolved "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.10.tgz#a872d7a1ea4f78f3e77d60ae62910483114cd445"
integrity sha512-M4j7C7/2xAxEfXuwoyt4Xh9N14o0pItsBnMK/BrNOi0mGpxcpDERNrSCPFvVM0avmpi4tliYduqU96ffOT16Ww==
dependencies:
vue "^3.2.19"
responsive-storage@^1.0.11:
version "1.0.11"
resolved "https://registry.npmjs.org/responsive-storage/-/responsive-storage-1.0.11.tgz#35d0c7825a0a3daed6c8ee0228a173f8aadbedd4"
integrity sha512-XY/21b7FKCXwBWGLuxp5KUQOAh8jOTsdfRMz0RVE9P+HhK4oYXKcNESDLxE1mD5MWPg/i+k4SGogro5daMrE9A==
restore-cursor@^3.1.0:
version "3.1.0"
@@ -3819,10 +3921,10 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rollup@^2.38.5:
version "2.57.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz#c1694475eb22e1022477c0f4635fd0ac80713173"
integrity sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==
rollup@^2.57.0:
version "2.58.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-2.58.0.tgz#a643983365e7bf7f5b7c62a8331b983b7c4c67fb"
integrity sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw==
optionalDependencies:
fsevents "~2.3.2"
@@ -4027,6 +4129,11 @@ statuses@~1.5.0:
resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
steno@^2.1.0:
version "2.1.0"
resolved "https://registry.nlark.com/steno/download/steno-2.1.0.tgz#05a9c378ce42ed04f642cda6fcb41787a10e4e33"
integrity sha1-BanDeM5C7QT2Qs2m/LQXh6EOTjM=
string-argv@0.3.1:
version "0.3.1"
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
@@ -4275,7 +4382,7 @@ trough@^1.0.0:
tslib@2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
tslib@^1.8.1, tslib@^1.9.0:
@@ -4344,6 +4451,11 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typescript-cookie@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/typescript-cookie/download/typescript-cookie-1.0.0.tgz#5354bf5d827b98dfe40807bf19b143cdd595a772"
integrity sha1-U1S/XYJ7mN/kCAe/GbFDzdWVp3I=
typescript@^4.4.2:
version "4.4.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
@@ -4409,13 +4521,22 @@ unpipe@~1.0.0:
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
unplugin-element-plus@^0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/unplugin-element-plus/-/unplugin-element-plus-0.0.1.tgz#959d4640253312529e93000aaa7a2078d5543e80"
integrity sha512-5WyuJTE7S6pJV/gK2a6RiGmxEoaNBjJn37tooBYsX9D9CSGamqzIcq+NtBHU0qRkDnx/fpcRcjZh3UXkSLkbuA==
unplugin-element-plus@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/unplugin-element-plus/-/unplugin-element-plus-0.1.0.tgz#eb68721f152a79ebe39a7404cc60cfcd6a8e587b"
integrity sha512-DdNgXlZtarpU6dGzh8WIP5bxLSIWg1qPKHnGvlqOY+RGlljyxe3yULPo6HMAzovdxy+ix4kAijncZSEud72khA==
dependencies:
"@rollup/pluginutils" "^4.1.0"
es-module-lexer "^0.6.0"
es-module-lexer "^0.7.1"
magic-string "^0.25.7"
unplugin "^0.2.7"
unplugin@^0.2.7:
version "0.2.16"
resolved "https://registry.npmjs.org/unplugin/-/unplugin-0.2.16.tgz#6f34e9f5068ca3ec92a36b016f47b5ad8bb875ca"
integrity sha512-KkXatHba0baJszSHW+2e8EQU/5Bz7rYwzYXu8wUeq97tE6K3wvub+7OWSuRv04LttvzNLsJ2jXEyR35gofv74Q==
dependencies:
webpack-virtual-modules "^0.4.3"
upper-case-first@^2.0.2:
version "2.0.2"
@@ -4525,15 +4646,15 @@ vite-svg-loader@^2.2.0:
"@vue/compiler-sfc" "^3.0.11"
svgo "^2.3.0"
vite@^2.5.10:
version "2.5.10"
resolved "https://registry.npmjs.org/vite/-/vite-2.5.10.tgz#c598e3b5a7e1956ffc52eb3b3420d177fc2ed2a5"
integrity sha512-0ObiHTi5AHyXdJcvZ67HMsDgVpjT5RehvVKv6+Q0jFZ7zDI28PF5zK9mYz2avxdA+4iJMdwCz6wnGNnn4WX5Gg==
vite@^2.6.7:
version "2.6.7"
resolved "https://registry.npmjs.org/vite/-/vite-2.6.7.tgz#e15c1d8327950720b5d7c4ec3fb36a5a58ccf7cb"
integrity sha512-ewk//jve9k6vlU8PfJmWUHN8k0YYdw4VaKOMvoQ3nT2Pb6k5OSMKQi4jPOzVH/TlUqMsCrq7IJ80xcuDDVyigg==
dependencies:
esbuild "^0.12.17"
postcss "^8.3.6"
esbuild "^0.13.2"
postcss "^8.3.8"
resolve "^1.20.0"
rollup "^2.38.5"
rollup "^2.57.0"
optionalDependencies:
fsevents "~2.3.2"
@@ -4584,16 +4705,16 @@ vue-types@^4.1.0:
dependencies:
is-plain-object "5.0.0"
vue@^3.2.19:
version "3.2.19"
resolved "https://registry.npmjs.org/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f"
integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA==
vue@^3.2.20:
version "3.2.20"
resolved "https://registry.npmjs.org/vue/-/vue-3.2.20.tgz#940f8aa8bf3e3be78243ca582bad41fcd45ae3e6"
integrity sha512-81JjEP4OGk9oO8+CU0h2nFPGgJBm9mNa3kdCX2k6FuRdrWrC+CNe+tOnuIeTg8EWwQuI+wwdra5Q7vSzp7p4Iw==
dependencies:
"@vue/compiler-dom" "3.2.19"
"@vue/compiler-sfc" "3.2.19"
"@vue/runtime-dom" "3.2.19"
"@vue/server-renderer" "3.2.19"
"@vue/shared" "3.2.19"
"@vue/compiler-dom" "3.2.20"
"@vue/compiler-sfc" "3.2.20"
"@vue/runtime-dom" "3.2.20"
"@vue/server-renderer" "3.2.20"
"@vue/shared" "3.2.20"
vuedraggable@^4.1.0:
version "4.1.0"
@@ -4616,6 +4737,11 @@ wangeditor@^4.7.7:
"@babel/runtime-corejs3" "^7.11.2"
tslib "^2.1.0"
webpack-virtual-modules@^0.4.3:
version "0.4.3"
resolved "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.4.3.tgz#cd597c6d51d5a5ecb473eea1983a58fa8a17ded9"
integrity sha512-5NUqC2JquIL2pBAAo/VfBP6KuGkHIZQXW/lNKupLPfhViwh8wNsu0BObtl09yuKZszeEUfbXz8xhrHvSG16Nqw==
which@^1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@@ -4754,10 +4880,10 @@ yocto-queue@^0.1.0:
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zrender@5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/zrender/-/zrender-5.2.0.tgz#f8abc484ac4a8a51b04c3ccd37beabe1def342cd"
integrity sha512-87v3gvB0lcWy48ObA/DwrhQ95ADMMRhECVrXmHDFCBNvbxHFfEDZtrZh4VmVjLAeFAjimY4PyZ65rbLCivdszA==
zrender@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.2.1.tgz#5f4bbda915ba6d412b0b19dc2431beaad05417bb"
integrity sha512-M3bPGZuyLTNBC6LiNKXJwSCtglMp8XUEqEBG+2MdICDI3d1s500Y4P0CzldQGsqpRVB7fkvf3BKQQRxsEaTlsw==
dependencies:
tslib "2.3.0"