mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-24 20:36:37 +08:00
Merge branch 'honghuangdc:main' into main
This commit is contained in:
commit
5efd1dbec4
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,6 +30,5 @@ stats.html
|
||||
*.sw?
|
||||
|
||||
/src/typings/components.d.ts
|
||||
/src/typings/router-page.d.ts
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
15
index.html
15
index.html
@ -3,25 +3,12 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/resource/loading.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title><%= appName %></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="loading-container">
|
||||
<div id="loadingLogo" class="loading-svg"></div>
|
||||
<div class="loading-spin__container">
|
||||
<div class="loading-spin">
|
||||
<div class="left-0 top-0 loading-spin-item"></div>
|
||||
<div class="left-0 bottom-0 loading-spin-item loading-delay-500"></div>
|
||||
<div class="right-0 top-0 loading-spin-item loading-delay-1000"></div>
|
||||
<div class="right-0 bottom-0 loading-spin-item loading-delay-1500"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loading-title"><%= appTitle %></div>
|
||||
</div>
|
||||
<script src="/resource/loading.js"></script>
|
||||
<div id="appLoading"></div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
@ -81,11 +81,11 @@
|
||||
"vue-router": "^4.1.6",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"wangeditor": "^4.7.15",
|
||||
"xgplayer": "^2.32.1"
|
||||
"xgplayer": "^2.32.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@amap/amap-jsapi-types": "^0.0.10",
|
||||
"@iconify/json": "^2.1.136",
|
||||
"@iconify/json": "^2.1.139",
|
||||
"@iconify/vue": "^4.0.0",
|
||||
"@soybeanjs/router-page": "1.0.3",
|
||||
"@types/bmapgl": "^0.0.5",
|
||||
@ -107,7 +107,7 @@
|
||||
"esno": "^0.16.3",
|
||||
"husky": "^8.0.2",
|
||||
"mockjs": "^1.1.0",
|
||||
"npm-check-updates": "^16.3.25",
|
||||
"npm-check-updates": "^16.4.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "^5.8.3",
|
||||
"sass": "^1.56.1",
|
||||
@ -117,7 +117,7 @@
|
||||
"unplugin-vue-components": "0.22.9",
|
||||
"unplugin-vue-macros": "^0.16.3",
|
||||
"utility-types": "^3.10.0",
|
||||
"vite": "^3.2.3",
|
||||
"vite": "^3.2.4",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
|
124
pnpm-lock.yaml
124
pnpm-lock.yaml
@ -10,7 +10,7 @@ specifiers:
|
||||
'@antv/data-set': ^0.11.8
|
||||
'@antv/g2': ^4.2.8
|
||||
'@better-scroll/core': ^2.5.0
|
||||
'@iconify/json': ^2.1.136
|
||||
'@iconify/json': ^2.1.139
|
||||
'@iconify/vue': ^4.0.0
|
||||
'@soybeanjs/router-page': 1.0.3
|
||||
'@soybeanjs/vue-admin-layout': ^1.1.1
|
||||
@ -44,7 +44,7 @@ specifiers:
|
||||
lodash-es: ^4.17.21
|
||||
mockjs: ^1.1.0
|
||||
naive-ui: 2.33.5
|
||||
npm-check-updates: ^16.3.25
|
||||
npm-check-updates: ^16.4.1
|
||||
pinia: ^2.0.23
|
||||
print-js: ^1.6.0
|
||||
qs: ^6.11.0
|
||||
@ -60,7 +60,7 @@ specifiers:
|
||||
unplugin-vue-macros: ^0.16.3
|
||||
utility-types: ^3.10.0
|
||||
vditor: ^3.8.18
|
||||
vite: ^3.2.3
|
||||
vite: ^3.2.4
|
||||
vite-plugin-compression: ^0.5.1
|
||||
vite-plugin-html: ^3.2.0
|
||||
vite-plugin-mock: ^2.9.6
|
||||
@ -73,7 +73,7 @@ specifiers:
|
||||
vue-tsc: ^1.0.9
|
||||
vuedraggable: ^4.1.0
|
||||
wangeditor: ^4.7.15
|
||||
xgplayer: ^2.32.1
|
||||
xgplayer: ^2.32.2
|
||||
zx: ^7.1.1
|
||||
|
||||
dependencies:
|
||||
@ -103,11 +103,11 @@ dependencies:
|
||||
vue-router: 4.1.6_vue@3.2.45
|
||||
vuedraggable: 4.1.0_vue@3.2.45
|
||||
wangeditor: 4.7.15
|
||||
xgplayer: 2.32.1
|
||||
xgplayer: 2.32.2
|
||||
|
||||
devDependencies:
|
||||
'@amap/amap-jsapi-types': 0.0.10
|
||||
'@iconify/json': 2.1.136
|
||||
'@iconify/json': 2.1.139
|
||||
'@iconify/vue': 4.0.0_vue@3.2.45
|
||||
'@soybeanjs/router-page': 1.0.3
|
||||
'@types/bmapgl': 0.0.5
|
||||
@ -116,9 +116,9 @@ devDependencies:
|
||||
'@types/qs': 6.9.7
|
||||
'@types/ua-parser-js': 0.7.36
|
||||
'@unocss/preset-uno': 0.46.5
|
||||
'@unocss/vite': 0.46.5_rollup@2.79.1+vite@3.2.3
|
||||
'@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.45
|
||||
'@vitejs/plugin-vue-jsx': 2.1.1_vite@3.2.3+vue@3.2.45
|
||||
'@unocss/vite': 0.46.5_rollup@2.79.1+vite@3.2.4
|
||||
'@vitejs/plugin-vue': 3.2.0_vite@3.2.4+vue@3.2.45
|
||||
'@vitejs/plugin-vue-jsx': 2.1.1_vite@3.2.4+vue@3.2.45
|
||||
commitlint: 17.2.0
|
||||
conventional-changelog: 3.1.25
|
||||
cross-env: 7.0.3
|
||||
@ -129,7 +129,7 @@ devDependencies:
|
||||
esno: 0.16.3
|
||||
husky: 8.0.2
|
||||
mockjs: 1.1.0_3y7clh66jsbznbjsqlxuh6722u
|
||||
npm-check-updates: 16.3.25
|
||||
npm-check-updates: 16.4.1
|
||||
rimraf: 3.0.2
|
||||
rollup-plugin-visualizer: 5.8.3_rollup@2.79.1
|
||||
sass: 1.56.1
|
||||
@ -137,15 +137,15 @@ devDependencies:
|
||||
typescript: 4.8.4
|
||||
unplugin-icons: 0.14.13
|
||||
unplugin-vue-components: 0.22.9_rollup@2.79.1+vue@3.2.45
|
||||
unplugin-vue-macros: 0.16.3_mtjmd4d7yri6vok5vdb7foxsoq
|
||||
unplugin-vue-macros: 0.16.3_wngx4xzvqgttz6r2laqlxyas2u
|
||||
utility-types: 3.10.0
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite-plugin-compression: 0.5.1_vite@3.2.3
|
||||
vite-plugin-html: 3.2.0_vite@3.2.3
|
||||
vite-plugin-mock: 2.9.6_qj5sox3st75utfpfnxdchh4ucq
|
||||
vite-plugin-progress: 0.0.6_vite@3.2.3
|
||||
vite-plugin-pwa: 0.13.3_jklrv2undatkozcsn24zow6xuu
|
||||
vite-plugin-svg-icons: 2.0.1_vite@3.2.3
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
vite-plugin-compression: 0.5.1_vite@3.2.4
|
||||
vite-plugin-html: 3.2.0_vite@3.2.4
|
||||
vite-plugin-mock: 2.9.6_55m5mhr4n72hhmialh5t5h2xye
|
||||
vite-plugin-progress: 0.0.6_vite@3.2.4
|
||||
vite-plugin-pwa: 0.13.3_ncfuj3sngaz4xbo7yyj2tfhvju
|
||||
vite-plugin-svg-icons: 2.0.1_vite@3.2.4
|
||||
vue-tsc: 1.0.9_typescript@4.8.4
|
||||
zx: 7.1.1
|
||||
|
||||
@ -1637,11 +1637,11 @@ packages:
|
||||
'@types/node': 14.18.33
|
||||
chalk: 4.1.2
|
||||
cosmiconfig: 7.1.0
|
||||
cosmiconfig-typescript-loader: 4.2.0_zhrz2lclwdmp54iaqottwiuipu
|
||||
cosmiconfig-typescript-loader: 4.2.0_qoh33be55smklb2oyrgdyddh4a
|
||||
lodash: 4.17.21
|
||||
resolve-from: 5.0.0
|
||||
ts-node: 10.9.1_cbe7ovvae6zqfnmtgctpgpys54
|
||||
typescript: 4.8.4
|
||||
typescript: 4.9.3
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- '@swc/wasm'
|
||||
@ -1833,8 +1833,8 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@iconify/json/2.1.136:
|
||||
resolution: {integrity: sha512-tO5hV+yXn87+OCQqiVzis6i4YQiRX4044ZjubP6GmbeclE6tsypK+by/tXjbm90GTX0jhsOJ6YLzWl3szivywg==}
|
||||
/@iconify/json/2.1.139:
|
||||
resolution: {integrity: sha512-H/DQ/yVgdUk4x4hU696fy0mZOkvLQaR6REQU/okFLgaiIFOS+EWw6GV5JDSKbbkh0YVaxUrAUaqB8XTSFVrFeA==}
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 0.3.9
|
||||
@ -2569,7 +2569,7 @@ packages:
|
||||
css-tree: 2.2.1
|
||||
dev: true
|
||||
|
||||
/@unocss/vite/0.46.5_rollup@2.79.1+vite@3.2.3:
|
||||
/@unocss/vite/0.46.5_rollup@2.79.1+vite@3.2.4:
|
||||
resolution: {integrity: sha512-/auNcS1L3PjwAA3U/i9scJf2Zx3kkgCdKiXyfetjws4ddAnVE+LrDmIKbbdSUiWFoq9W2QOPpOPpV2xips2gmg==}
|
||||
peerDependencies:
|
||||
vite: ^2.9.0 || ^3.0.0-0
|
||||
@ -2582,12 +2582,12 @@ packages:
|
||||
'@unocss/scope': 0.46.5
|
||||
'@unocss/transformer-directives': 0.46.5
|
||||
magic-string: 0.26.7
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-vue-jsx/2.1.1_vite@3.2.3+vue@3.2.45:
|
||||
/@vitejs/plugin-vue-jsx/2.1.1_vite@3.2.4+vue@3.2.45:
|
||||
resolution: {integrity: sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -2597,20 +2597,20 @@ packages:
|
||||
'@babel/core': 7.20.2
|
||||
'@babel/plugin-transform-typescript': 7.20.2_@babel+core@7.20.2
|
||||
'@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.20.2
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
vue: 3.2.45
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-vue/3.2.0_vite@3.2.3+vue@3.2.45:
|
||||
/@vitejs/plugin-vue/3.2.0_vite@3.2.4+vue@3.2.45:
|
||||
resolution: {integrity: sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
vite: ^3.0.0
|
||||
vue: ^3.2.25
|
||||
dependencies:
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
vue: 3.2.45
|
||||
dev: true
|
||||
|
||||
@ -2742,16 +2742,16 @@ packages:
|
||||
unplugin: 0.10.2
|
||||
dev: true
|
||||
|
||||
/@vue-macros/named-template/0.0.5_pwzry6ifamiyy66hle7uchcfiy:
|
||||
/@vue-macros/named-template/0.0.5_2aqiuug577r2uhg7pi2e2y3u2a:
|
||||
resolution: {integrity: sha512-bZRUljNyvOOqeE9dyqXvKPQCLUCcPt1EkThmXqSbxagV29ohyviF8+CCs/8OdmNygLTBIChjP8DexQ3nUIFzUg==}
|
||||
engines: {node: '>=14.19.0'}
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
'@vitejs/plugin-vue': 3.2.0_vite@3.2.3+vue@3.2.45
|
||||
'@vitejs/plugin-vue': 3.2.0_vite@3.2.4+vue@3.2.45
|
||||
'@vue-macros/common': 0.13.3
|
||||
'@vue/compiler-dom': 3.2.45
|
||||
unplugin: 0.10.2
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.3
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.4
|
||||
transitivePeerDependencies:
|
||||
- esbuild
|
||||
- rollup
|
||||
@ -2760,14 +2760,14 @@ packages:
|
||||
- webpack
|
||||
dev: true
|
||||
|
||||
/@vue-macros/setup-component/0.12.7_rollup@2.79.1+vite@3.2.3:
|
||||
/@vue-macros/setup-component/0.12.7_rollup@2.79.1+vite@3.2.4:
|
||||
resolution: {integrity: sha512-L0WkJgw0QDwZh4tOjjKIDR0DMIybiOunsaxVqkJjicTb2YaiRUSLq4Wadl8Ttrsd0IEfI51CSlg7Sx0/dKLrlQ==}
|
||||
engines: {node: '>=14.19.0'}
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 4.2.1
|
||||
'@vue-macros/common': 0.13.3
|
||||
unplugin: 0.10.2
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.3
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.4
|
||||
transitivePeerDependencies:
|
||||
- esbuild
|
||||
- rollup
|
||||
@ -4006,7 +4006,7 @@ packages:
|
||||
vary: 1.1.2
|
||||
dev: true
|
||||
|
||||
/cosmiconfig-typescript-loader/4.2.0_zhrz2lclwdmp54iaqottwiuipu:
|
||||
/cosmiconfig-typescript-loader/4.2.0_qoh33be55smklb2oyrgdyddh4a:
|
||||
resolution: {integrity: sha512-NkANeMnaHrlaSSlpKGyvn2R4rqUDeE/9E5YHx+b4nwo0R8dZyAqcih8/gxpCZvqWP9Vf6xuLpMSzSgdVEIM78g==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
peerDependencies:
|
||||
@ -4018,7 +4018,7 @@ packages:
|
||||
'@types/node': 14.18.33
|
||||
cosmiconfig: 7.1.0
|
||||
ts-node: 10.9.1_cbe7ovvae6zqfnmtgctpgpys54
|
||||
typescript: 4.8.4
|
||||
typescript: 4.9.3
|
||||
dev: true
|
||||
|
||||
/cosmiconfig/7.1.0:
|
||||
@ -7820,8 +7820,8 @@ packages:
|
||||
npm-normalize-package-bin: 3.0.0
|
||||
dev: true
|
||||
|
||||
/npm-check-updates/16.3.25:
|
||||
resolution: {integrity: sha512-zrjx6P7LGHYS5e3TNuSqkWQc9m1KLjJIxFERGANN+xEY826NQYG08RwucUD9nRxIlRE9PsGCcMsJJTYJu1DHbA==}
|
||||
/npm-check-updates/16.4.1:
|
||||
resolution: {integrity: sha512-g0Uf1kCw0p5boutvu5E4htsjYEDuFT9LxYHYFLldAzWs5012jVikEH1Wdae68xedu4twF4EVbKcs83+G2nGnQg==}
|
||||
engines: {node: '>=14.14'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@ -10396,6 +10396,12 @@ packages:
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
|
||||
/typescript/4.9.3:
|
||||
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ua-parser-js/1.0.32:
|
||||
resolution: {integrity: sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==}
|
||||
dev: false
|
||||
@ -10595,7 +10601,7 @@ packages:
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: true
|
||||
|
||||
/unplugin-combine/0.2.8_rollup@2.79.1+vite@3.2.3:
|
||||
/unplugin-combine/0.2.8_rollup@2.79.1+vite@3.2.4:
|
||||
resolution: {integrity: sha512-Z38AC/TEjXbVyZ5HjVqo+lADj0/dcfwWC0Z4y0LNhybJzJQwmcMxm+ZsqHY3faauj4YigmlRMdptR5JEW9RuLg==}
|
||||
engines: {node: '>=14.19.0'}
|
||||
peerDependencies:
|
||||
@ -10616,7 +10622,7 @@ packages:
|
||||
'@antfu/utils': 0.6.3
|
||||
rollup: 2.79.1
|
||||
unplugin: 0.10.2
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
dev: true
|
||||
|
||||
/unplugin-icons/0.14.13:
|
||||
@ -10683,7 +10689,7 @@ packages:
|
||||
unplugin: 0.10.2
|
||||
dev: true
|
||||
|
||||
/unplugin-vue-macros/0.16.3_mtjmd4d7yri6vok5vdb7foxsoq:
|
||||
/unplugin-vue-macros/0.16.3_wngx4xzvqgttz6r2laqlxyas2u:
|
||||
resolution: {integrity: sha512-ADdDS5EjHRZ2esEHSNBw7CS7QLWpqvNJIW0H5EqKgSvtQ+2Hnb8IeRVT0f4mR+wyQvl/ZrlpTs1GvZdsh8eSlw==}
|
||||
engines: {node: '>=14.19.0'}
|
||||
peerDependencies:
|
||||
@ -10696,12 +10702,12 @@ packages:
|
||||
'@vue-macros/define-render': 0.13.8_vue@3.2.45
|
||||
'@vue-macros/define-slots': 0.0.5_vue@3.2.45
|
||||
'@vue-macros/hoist-static': 0.12.7
|
||||
'@vue-macros/named-template': 0.0.5_pwzry6ifamiyy66hle7uchcfiy
|
||||
'@vue-macros/setup-component': 0.12.7_rollup@2.79.1+vite@3.2.3
|
||||
'@vue-macros/named-template': 0.0.5_2aqiuug577r2uhg7pi2e2y3u2a
|
||||
'@vue-macros/setup-component': 0.12.7_rollup@2.79.1+vite@3.2.4
|
||||
'@vue-macros/setup-sfc': 0.12.7
|
||||
'@vue-macros/short-emits': 0.12.8
|
||||
local-pkg: 0.4.2
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.3
|
||||
unplugin-combine: 0.2.8_rollup@2.79.1+vite@3.2.4
|
||||
unplugin-vue-define-options: 0.12.7
|
||||
vue: 3.2.45
|
||||
transitivePeerDependencies:
|
||||
@ -10862,7 +10868,7 @@ packages:
|
||||
vfile-message: 2.0.4
|
||||
dev: true
|
||||
|
||||
/vite-plugin-compression/0.5.1_vite@3.2.3:
|
||||
/vite-plugin-compression/0.5.1_vite@3.2.4:
|
||||
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
@ -10870,12 +10876,12 @@ packages:
|
||||
chalk: 4.1.2
|
||||
debug: 4.3.4
|
||||
fs-extra: 10.1.0
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-html/3.2.0_vite@3.2.3:
|
||||
/vite-plugin-html/3.2.0_vite@3.2.4:
|
||||
resolution: {integrity: sha512-2VLCeDiHmV/BqqNn5h2V+4280KRgQzCFN47cst3WiNK848klESPQnzuC3okH5XHtgwHH/6s1Ho/YV6yIO0pgoQ==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
@ -10892,10 +10898,10 @@ packages:
|
||||
html-minifier-terser: 6.1.0
|
||||
node-html-parser: 5.4.2
|
||||
pathe: 0.2.0
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
dev: true
|
||||
|
||||
/vite-plugin-mock/2.9.6_qj5sox3st75utfpfnxdchh4ucq:
|
||||
/vite-plugin-mock/2.9.6_55m5mhr4n72hhmialh5t5h2xye:
|
||||
resolution: {integrity: sha512-/Rm59oPppe/ncbkSrUuAxIQihlI2YcBmnbR4ST1RA2VzM1C0tEQc1KlbQvnUGhXECAGTaQN2JyasiwXP6EtKgg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
peerDependencies:
|
||||
@ -10912,13 +10918,13 @@ packages:
|
||||
fast-glob: 3.2.12
|
||||
mockjs: 1.1.0_3y7clh66jsbznbjsqlxuh6722u
|
||||
path-to-regexp: 6.2.1
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-progress/0.0.6_vite@3.2.3:
|
||||
/vite-plugin-progress/0.0.6_vite@3.2.4:
|
||||
resolution: {integrity: sha512-pIK2TVEY4XFGrz10CQDdEufBBCDaV0geRHfXV3abGTBr+OF9O0Zmd3ZDrHJXDv4Rl3qAQP4BTCuPYQ3XqstmqA==}
|
||||
engines: {node: '>=14', pnpm: '>=7.0.0'}
|
||||
peerDependencies:
|
||||
@ -10927,10 +10933,10 @@ packages:
|
||||
picocolors: 1.0.0
|
||||
progress: 2.0.3
|
||||
rd: 2.0.1
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
dev: true
|
||||
|
||||
/vite-plugin-pwa/0.13.3_jklrv2undatkozcsn24zow6xuu:
|
||||
/vite-plugin-pwa/0.13.3_ncfuj3sngaz4xbo7yyj2tfhvju:
|
||||
resolution: {integrity: sha512-cjWXpZ7slAY14OKz7M8XdgTIi9wjf6OD6NkhiMAc+ogxnbUrecUwLdRtfGPCPsN2ftut5gaN1jTghb11p6IQAA==}
|
||||
peerDependencies:
|
||||
vite: ^3.1.0
|
||||
@ -10942,14 +10948,14 @@ packages:
|
||||
fast-glob: 3.2.12
|
||||
pretty-bytes: 6.0.0
|
||||
rollup: 2.79.1
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
workbox-build: 6.5.4
|
||||
workbox-window: 6.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-svg-icons/2.0.1_vite@3.2.3:
|
||||
/vite-plugin-svg-icons/2.0.1_vite@3.2.4:
|
||||
resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==}
|
||||
peerDependencies:
|
||||
vite: '>=2.0.0'
|
||||
@ -10962,13 +10968,13 @@ packages:
|
||||
pathe: 0.2.0
|
||||
svg-baker: 1.7.0
|
||||
svgo: 2.8.0
|
||||
vite: 3.2.3_ajklay5k626t46b6fyghkbup3i
|
||||
vite: 3.2.4_ajklay5k626t46b6fyghkbup3i
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite/3.2.3_ajklay5k626t46b6fyghkbup3i:
|
||||
resolution: {integrity: sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==}
|
||||
/vite/3.2.4_ajklay5k626t46b6fyghkbup3i:
|
||||
resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -11427,8 +11433,8 @@ packages:
|
||||
generate-source-map: 0.0.5
|
||||
dev: false
|
||||
|
||||
/xgplayer/2.32.1:
|
||||
resolution: {integrity: sha512-jUs6108INqnzEn3DTGre6pHW3KroM2w0VKuJNEvOIkoD2oUB+MW5ZZ0PsIwijX/oQRpmvq422CUgo4uqXVidEQ==}
|
||||
/xgplayer/2.32.2:
|
||||
resolution: {integrity: sha512-VWK8Hp5K3Fs5YoHadpyCw2zwuiOimRjkPo2PSJZPYKj59VNnL9oLruZp6cy86LHoAgWELRIQj6Nmw5SkQNByWQ==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
chalk: 2.4.2
|
||||
|
@ -1,91 +0,0 @@
|
||||
.loading-container {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-svg {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.loading-spin__container {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin: 36px 0;
|
||||
}
|
||||
|
||||
.loading-spin {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
animation: loadingSpin 1s linear infinite;
|
||||
}
|
||||
|
||||
.left-0 {
|
||||
left: 0;
|
||||
}
|
||||
.right-0 {
|
||||
right: 0;
|
||||
}
|
||||
.top-0 {
|
||||
top: 0;
|
||||
}
|
||||
.bottom-0 {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.loading-spin-item {
|
||||
position: absolute;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 8px;
|
||||
-webkit-animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes loadingSpin {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loadingPulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-delay-500 {
|
||||
-webkit-animation-delay: 500ms;
|
||||
animation-delay: 500ms;
|
||||
}
|
||||
.loading-delay-1000 {
|
||||
-webkit-animation-delay: 1000ms;
|
||||
animation-delay: 1000ms;
|
||||
}
|
||||
.loading-delay-1500 {
|
||||
-webkit-animation-delay: 1500ms;
|
||||
animation-delay: 1500ms;
|
||||
}
|
||||
|
||||
.loading-title {
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
color: #646464;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* 初始化加载效果的svg格式logo
|
||||
* @param {string} id - 元素id
|
||||
*/
|
||||
function initSvgLogo(id) {
|
||||
const svgStr = `<svg width="128px" height="128px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
|
||||
y="0px" viewBox="0 0 158.9 158.9" style="enable-background:new 0 0 158.9 158.9;" xml:space="preserve">
|
||||
<path style="fill:none" d="M0,158.9C0,106.3,0,53.7,0,1.1C0,0.2,0.2,0,1.1,0c52.2,0,104.5,0,156.7,0c0.9,0,1.1,0.2,1.1,1.1
|
||||
c0,52.2,0,104.5,0,156.7c0,0.9-0.2,1.1-1.1,1.1C105.2,158.8,52.6,158.8,0,158.9z" />
|
||||
<path style="fill:currentColor" d="M81.3,55.9c-0.1-11.7-2.9-22.5-9.4-32.4c-1-1.5-2.1-2.9-2.5-4.7c-0.7-3.4,0.9-6.9,4-8.6c3-1.7,6.8-1.2,9.3,1.2
|
||||
c2.4,2.6,4.4,5.6,5.9,8.8c4.7,8.9,7.6,18.6,8.4,28.6c1,12.5-0.7,25-5.2,36.7c-0.9,2.5-1.9,4.9-3,7.3c-0.3,0.4-0.3,1,0,1.4
|
||||
c9.6,13.3,21.8,23,37.8,27.2c6.4,1.7,13.1,2.3,19.7,1.6c4.2-0.4,7.9,2.7,8.4,6.9c0.7,4.3-2.3,8.3-6.6,9c0,0,0,0-0.1,0
|
||||
c-7.7,0.9-15.5,0.5-23-1.3c-13.9-3.1-26.7-10-36.9-19.9c-4.4-4.2-8.4-8.8-11.9-13.7c-0.5-0.8-1.4-1.2-2.3-1.1
|
||||
c-9.5,0.7-18.8,3.3-27.4,7.6c-11.6,6-20.7,14.6-26.4,26.4c-0.7,1.9-2,3.5-3.7,4.7c-2.9,1.7-6.6,1.5-9.2-0.7c-2.8-2.2-3.8-6-2.4-9.3
|
||||
c2.2-5.2,5.1-10.1,8.7-14.5c12.2-15.4,28.2-24.6,47.3-28.6c4-0.8,8.1-1.4,12.2-1.6c0.5,0,1-0.3,1.2-0.8c3.3-7.1,5.5-14.6,6.5-22.3
|
||||
C81.1,61.2,81.3,58.6,81.3,55.9z" />
|
||||
<path style="fill:currentColor" d="M136.3,108.3c-3.8-0.5-7.6-1.4-11.1-2.9c-7.7-2.8-14.4-7.5-19.7-13.8c-2.9-3.3-2.5-8.4,0.8-11.3
|
||||
c1.4-1.2,3.1-1.9,4.9-1.9c2.5-0.1,5,1,6.5,2.9c4.9,5.6,11.6,9.4,18.9,10.8c1.5,0.2,3.1,0.6,4.5,1.2c3.2,1.8,4.8,5.6,3.8,9.2
|
||||
C144,106.1,140.8,108.4,136.3,108.3z" />
|
||||
<path style="fill:currentColor" d="M55.7,33.3c3,0.2,5.6,2.2,6.6,5c2.2,5.4,3.4,11.2,3.6,17c0.3,5.9-0.6,11.7-2.5,17.3c-2,5.8-8.2,7.8-12.9,4.2
|
||||
c-2.6-2.2-3.6-5.8-2.4-9c1.4-4,1.9-8.2,1.7-12.4c-0.2-3.8-1-7.5-2.4-11C45.3,38.9,49.2,33.3,55.7,33.3z" />
|
||||
<path style="fill:currentColor" d="M77.9,126.6c0,3.9-2.8,7.2-6.7,7.9c-7.8,1.5-14.8,5.9-19.7,12.2c-2.7,3.5-7.6,4.2-11.2,1.6
|
||||
c-3.6-2.6-4.3-7.6-1.7-11.2c0.1-0.1,0.2-0.3,0.3-0.4c4.1-5.2,9.3-9.6,15.1-12.8c4.4-2.5,9.1-4.2,14-5.1
|
||||
C73.3,117.7,77.9,121.3,77.9,126.6z" />
|
||||
</svg>`;
|
||||
const appEl = document.querySelector(id);
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = svgStr;
|
||||
if (appEl) {
|
||||
appEl.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
function addThemeColorCssVars() {
|
||||
const key = '__THEME_COLOR__';
|
||||
const defaultColor = '#1890ff';
|
||||
const themeColor = window.localStorage.getItem(key) || defaultColor;
|
||||
const cssVars = `--primary-color: ${themeColor}`;
|
||||
document.documentElement.style.cssText = cssVars;
|
||||
}
|
||||
|
||||
addThemeColorCssVars();
|
||||
|
||||
initSvgLogo('#loadingLogo');
|
41
src/components/common/AppLoading.vue
Normal file
41
src/components/common/AppLoading.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="fixed-center flex-col">
|
||||
<system-logo class="text-128px text-primary" />
|
||||
<div class="w-56px h-56px my-36px">
|
||||
<div class="relative h-full animate-spin">
|
||||
<div
|
||||
v-for="(item, index) in lodingClasses"
|
||||
:key="index"
|
||||
class="absolute w-16px h-16px bg-primary rounded-8px animate-pulse"
|
||||
:class="item"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="text-28px font-500 text-#646464">{{ title }}</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppInfo } from '@/composables';
|
||||
import { localStg } from '@/utils';
|
||||
|
||||
const { title } = useAppInfo();
|
||||
|
||||
const lodingClasses = [
|
||||
'left-0 top-0',
|
||||
'left-0 bottom-0 animate-delay-500',
|
||||
'right-0 top-0 animate-delay-1000',
|
||||
'right-0 bottom-0 animate-delay-1500'
|
||||
];
|
||||
|
||||
function addThemeColorCssVars() {
|
||||
const defaultColor = '#1890ff';
|
||||
const themeColor = localStg.get('themeColor') || defaultColor;
|
||||
const cssVars = `--primary-color: ${themeColor}`;
|
||||
document.documentElement.style.cssText = cssVars;
|
||||
}
|
||||
|
||||
addThemeColorCssVars();
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
@ -5,22 +5,6 @@ export enum EnumContentType {
|
||||
formData = 'multipart/form-data'
|
||||
}
|
||||
|
||||
/** 缓存的key */
|
||||
export enum EnumStorageKey {
|
||||
/** 主题颜色 */
|
||||
'theme-color' = '__THEME_COLOR__',
|
||||
/** 用户token */
|
||||
'token' = '__TOKEN__',
|
||||
/** 用户刷新token */
|
||||
'refresh-token' = '__REFRESH_TOKEN__',
|
||||
/** 用户信息 */
|
||||
'user-info' = '__USER_INFO__',
|
||||
/** 主题配置 */
|
||||
'theme-settings' = '__THEME_SETTINGS__',
|
||||
/** 多页签路由信息 */
|
||||
'multi-tab-routes' = '__MULTI_TAB_ROUTES__'
|
||||
}
|
||||
|
||||
/** 数据类型 */
|
||||
export enum EnumDataType {
|
||||
number = '[object Number]',
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import AppLoading from './components/common/AppLoading.vue';
|
||||
import { setupDirectives } from './directives';
|
||||
import { setupRouter } from './router';
|
||||
import { setupAssets } from './plugins';
|
||||
@ -10,6 +11,11 @@ async function setupApp() {
|
||||
// import assets: js、css
|
||||
setupAssets();
|
||||
|
||||
// app loading
|
||||
const appLoading = createApp(AppLoading);
|
||||
|
||||
appLoading.mount('#appLoading');
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// store plugin: pinia
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
||||
import { routeName } from '@/router';
|
||||
import { useRouteStore } from '@/store';
|
||||
import { getToken } from '@/utils';
|
||||
import { localStg } from '@/utils';
|
||||
|
||||
/**
|
||||
* 动态路由
|
||||
@ -12,7 +12,7 @@ export async function createDynamicRouteGuard(
|
||||
next: NavigationGuardNext
|
||||
) {
|
||||
const route = useRouteStore();
|
||||
const isLogin = Boolean(getToken());
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
|
||||
// 初始化权限路由
|
||||
if (!route.isInitAuthRoute) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
|
||||
import { routeName } from '@/router';
|
||||
import { useAuthStore } from '@/store';
|
||||
import { exeStrategyActions, getToken } from '@/utils';
|
||||
import { exeStrategyActions, localStg } from '@/utils';
|
||||
import { createDynamicRouteGuard } from './dynamic';
|
||||
|
||||
/** 处理路由页面的权限 */
|
||||
@ -22,7 +22,7 @@ export async function createPermissionGuard(
|
||||
}
|
||||
|
||||
const auth = useAuthStore();
|
||||
const isLogin = Boolean(getToken());
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
const permissions = to.meta.permissions || [];
|
||||
const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
|
||||
const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
import { useAuthStore } from '@/store';
|
||||
import { getRefreshToken, setRefreshToken, setToken } from '@/utils';
|
||||
import { localStg } from '@/utils';
|
||||
import { fetchUpdateToken } from '../api';
|
||||
|
||||
/**
|
||||
@ -9,11 +9,12 @@ import { fetchUpdateToken } from '../api';
|
||||
*/
|
||||
export async function handleRefreshToken(axiosConfig: AxiosRequestConfig) {
|
||||
const { resetAuthStore } = useAuthStore();
|
||||
const refreshToken = getRefreshToken();
|
||||
const refreshToken = localStg.get('refreshToken') || '';
|
||||
const { data } = await fetchUpdateToken(refreshToken);
|
||||
if (data) {
|
||||
setToken(data.token);
|
||||
setRefreshToken(data.refreshToken);
|
||||
localStg.set('token', data.token);
|
||||
localStg.set('refreshToken', data.refreshToken);
|
||||
|
||||
const config = { ...axiosConfig };
|
||||
if (config.headers) {
|
||||
config.headers.Authorization = data.token;
|
||||
|
@ -2,7 +2,7 @@ import axios from 'axios';
|
||||
import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||
import { REFRESH_TOKEN_CODE } from '@/config';
|
||||
import {
|
||||
getToken,
|
||||
localStg,
|
||||
handleAxiosError,
|
||||
handleBackendError,
|
||||
handleResponseError,
|
||||
@ -49,7 +49,7 @@ export default class CustomAxiosInstance {
|
||||
const contentType = handleConfig.headers['Content-Type'] as string;
|
||||
handleConfig.data = await transformRequestData(handleConfig.data, contentType);
|
||||
// 设置token
|
||||
handleConfig.headers.Authorization = getToken();
|
||||
handleConfig.headers.Authorization = localStg.get('token') || '';
|
||||
}
|
||||
return handleConfig;
|
||||
},
|
||||
|
25
src/store/modules/auth/helpers.ts
Normal file
25
src/store/modules/auth/helpers.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { localStg } from '@/utils';
|
||||
|
||||
/** 获取token */
|
||||
export function getToken() {
|
||||
return localStg.get('token') || '';
|
||||
}
|
||||
|
||||
/** 获取用户信息 */
|
||||
export function getUserInfo() {
|
||||
const emptyInfo: Auth.UserInfo = {
|
||||
userId: '',
|
||||
userName: '',
|
||||
userRole: 'user'
|
||||
};
|
||||
const userInfo: Auth.UserInfo = localStg.get('userInfo') || emptyInfo;
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/** 去除用户相关缓存 */
|
||||
export function clearAuthStorage() {
|
||||
localStg.remove('token');
|
||||
localStg.remove('refreshToken');
|
||||
localStg.remove('userInfo');
|
||||
}
|
@ -3,9 +3,10 @@ import { defineStore } from 'pinia';
|
||||
import { router } from '@/router';
|
||||
import { fetchLogin, fetchUserInfo } from '@/service';
|
||||
import { useRouterPush } from '@/composables';
|
||||
import { clearAuthStorage, getToken, getUserInfo, setRefreshToken, setToken, setUserInfo } from '@/utils';
|
||||
import { localStg } from '@/utils';
|
||||
import { useTabStore } from '../tab';
|
||||
import { useRouteStore } from '../route';
|
||||
import { getToken, getUserInfo, clearAuthStorage } from './helpers';
|
||||
|
||||
interface AuthState {
|
||||
/** 用户信息 */
|
||||
@ -81,14 +82,14 @@ export const useAuthStore = defineStore('auth-store', {
|
||||
|
||||
// 先把token存储到缓存中(后面接口的请求头需要token)
|
||||
const { token, refreshToken } = backendToken;
|
||||
setToken(token);
|
||||
setRefreshToken(refreshToken);
|
||||
localStg.set('token', token);
|
||||
localStg.set('refreshToken', refreshToken);
|
||||
|
||||
// 获取用户信息
|
||||
const { data } = await fetchUserInfo();
|
||||
if (data) {
|
||||
// 成功后把用户信息存储到缓存中
|
||||
setUserInfo(data);
|
||||
localStg.set('userInfo', data);
|
||||
|
||||
// 更新状态
|
||||
this.userInfo = data;
|
||||
|
@ -2,10 +2,10 @@ import { defineStore } from 'pinia';
|
||||
import { ROOT_ROUTE, constantRoutes, router, routes as staticRoutes } from '@/router';
|
||||
import { fetchUserRoutes } from '@/service';
|
||||
import {
|
||||
localStg,
|
||||
filterAuthRoutesByUserPermission,
|
||||
getCacheRoutes,
|
||||
getConstantRouteNames,
|
||||
getUserInfo,
|
||||
transformAuthRouteToVueRoutes,
|
||||
transformAuthRouteToVueRoute,
|
||||
transformAuthRouteToMenu,
|
||||
@ -106,7 +106,12 @@ export const useRouteStore = defineStore('route-store', {
|
||||
},
|
||||
/** 初始化动态路由 */
|
||||
async initDynamicRoute() {
|
||||
const { userId } = getUserInfo();
|
||||
const { userId } = localStg.get('userInfo') || {};
|
||||
|
||||
if (!userId) {
|
||||
throw new Error('userId 不能为空!');
|
||||
}
|
||||
|
||||
const { data } = await fetchUserRoutes(userId);
|
||||
if (data) {
|
||||
this.routeHomeName = data.home;
|
||||
@ -123,9 +128,6 @@ export const useRouteStore = defineStore('route-store', {
|
||||
/** 初始化权限路由 */
|
||||
async initAuthRoute() {
|
||||
const { initHomeTab } = useTabStore();
|
||||
const { userId } = getUserInfo();
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const isDynamicRoute = this.authRouteMode === 'dynamic';
|
||||
if (isDynamicRoute) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import type { RouteLocationNormalizedLoaded, RouteRecordNormalized } from 'vue-router';
|
||||
import { EnumStorageKey } from '@/enum';
|
||||
import { getLocal, setLocal } from '@/utils';
|
||||
import { localStg } from '@/utils';
|
||||
|
||||
/**
|
||||
* 根据vue路由获取tab路由
|
||||
@ -58,15 +57,10 @@ function hasFullPath(
|
||||
return Boolean((route as RouteLocationNormalizedLoaded).fullPath);
|
||||
}
|
||||
|
||||
/** 缓存多页签数据 */
|
||||
export function setTabRoutes(data: App.GlobalTabRoute[]) {
|
||||
setLocal(EnumStorageKey['multi-tab-routes'], data);
|
||||
}
|
||||
|
||||
/** 获取缓存的多页签数据 */
|
||||
export function getTabRoutes() {
|
||||
const routes: App.GlobalTabRoute[] = [];
|
||||
const data = getLocal<App.GlobalTabRoute[]>(EnumStorageKey['multi-tab-routes']);
|
||||
const data = localStg.get('multiTabRoutes');
|
||||
if (data) {
|
||||
const defaultTabRoutes = data.map(item => ({
|
||||
...item,
|
||||
@ -82,5 +76,5 @@ export function getTabRoutes() {
|
||||
|
||||
/** 清空多页签数据 */
|
||||
export function clearTabRoutes() {
|
||||
setTabRoutes([]);
|
||||
localStg.set('multiTabRoutes', []);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { RouteLocationNormalizedLoaded, Router } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useRouterPush } from '@/composables';
|
||||
import { localStg } from '@/utils';
|
||||
import { useThemeStore } from '../theme';
|
||||
import {
|
||||
clearTabRoutes,
|
||||
@ -8,8 +9,7 @@ import {
|
||||
getIndexInTabRoutesByRouteName,
|
||||
getTabRouteByVueRoute,
|
||||
getTabRoutes,
|
||||
isInTabRoutes,
|
||||
setTabRoutes
|
||||
isInTabRoutes
|
||||
} from './helpers';
|
||||
|
||||
interface TabState {
|
||||
@ -52,7 +52,7 @@ export const useTabStore = defineStore('tab-store', {
|
||||
},
|
||||
/** 缓存页签路由数据 */
|
||||
cacheTabRoutes() {
|
||||
setTabRoutes(this.tabs);
|
||||
localStg.set('multiTabRoutes', this.tabs);
|
||||
},
|
||||
/**
|
||||
* 设置当前路由对应的页签为激活状态
|
||||
|
@ -1,19 +1,18 @@
|
||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { themeSetting } from '@/settings';
|
||||
import { EnumStorageKey } from '@/enum';
|
||||
import { addColorAlpha, getColorPalette, getLocal, getThemeColor, removeLocal, setLocal } from '@/utils';
|
||||
import { localStg, addColorAlpha, getColorPalette } from '@/utils';
|
||||
|
||||
/** 初始化主题配置 */
|
||||
export function initThemeSettings() {
|
||||
const isProd = import.meta.env.PROD;
|
||||
// 生产环境才缓存主题配置,本地开发实时调整配置更改配置的json
|
||||
const storageSettings = getThemeSettings();
|
||||
const storageSettings = localStg.get('themeSettings');
|
||||
if (isProd && storageSettings) {
|
||||
return storageSettings;
|
||||
}
|
||||
|
||||
const themeColor = getThemeColor() || themeSetting.themeColor;
|
||||
const themeColor = localStg.get('themeColor') || themeSetting.themeColor;
|
||||
const info = themeSetting.isCustomizeInfoColor ? themeSetting.otherColor.info : getColorPalette(themeColor, 7);
|
||||
const otherColor = { ...themeSetting.otherColor, info };
|
||||
const setting = cloneDeep({ ...themeSetting, themeColor, otherColor });
|
||||
@ -78,18 +77,3 @@ export function getNaiveThemeOverrides(colors: Record<ColorType, string>): Globa
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取缓存中的主题配置 */
|
||||
function getThemeSettings() {
|
||||
return getLocal<Theme.Setting>(EnumStorageKey['theme-settings']);
|
||||
}
|
||||
|
||||
/** 获取缓存中的主题配置 */
|
||||
export function setThemeSettings(settings: Theme.Setting) {
|
||||
return setLocal(EnumStorageKey['theme-settings'], settings);
|
||||
}
|
||||
|
||||
/** 清除缓存配置 */
|
||||
export function clearThemeSettings() {
|
||||
removeLocal(EnumStorageKey['theme-settings']);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { darkTheme } from 'naive-ui';
|
||||
import { clearThemeSettings, getNaiveThemeOverrides, initThemeSettings, setThemeSettings } from './helpers';
|
||||
import { localStg } from '@/utils';
|
||||
import { getNaiveThemeOverrides, initThemeSettings } from './helpers';
|
||||
|
||||
type ThemeState = Theme.Setting;
|
||||
|
||||
@ -24,14 +25,14 @@ export const useThemeStore = defineStore('theme-store', {
|
||||
actions: {
|
||||
/** 重置theme状态 */
|
||||
resetThemeStore() {
|
||||
clearThemeSettings();
|
||||
localStg.remove('themeSettings');
|
||||
this.$reset();
|
||||
},
|
||||
/** 缓存主题配置 */
|
||||
cacheThemeSettings() {
|
||||
const isProd = import.meta.env.PROD;
|
||||
if (isProd) {
|
||||
setThemeSettings(this.$state);
|
||||
localStg.set('themeSettings', this.$state);
|
||||
}
|
||||
},
|
||||
/** 设置暗黑模式 */
|
||||
|
@ -3,7 +3,7 @@ import { useOsTheme } from 'naive-ui';
|
||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
||||
import { useElementSize } from '@vueuse/core';
|
||||
import { kebabCase } from 'lodash-es';
|
||||
import { setThemeColor } from '@/utils';
|
||||
import { localStg } from '@/utils';
|
||||
import { useThemeStore } from '../modules';
|
||||
|
||||
/** 订阅theme store */
|
||||
@ -17,7 +17,7 @@ export default function subscribeThemeStore() {
|
||||
const stopThemeColor = watch(
|
||||
() => theme.themeColor,
|
||||
newValue => {
|
||||
setThemeColor(newValue);
|
||||
localStg.set('themeColor', newValue);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
67
src/typings/router-page.d.ts
vendored
Normal file
67
src/typings/router-page.d.ts
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
declare namespace RouterPage {
|
||||
/** 根路由 */
|
||||
type RootRouteKey = 'root';
|
||||
|
||||
/** 未找到路由(捕获无效路径的路由) */
|
||||
type NotFoundRouteKey = 'not-found';
|
||||
|
||||
/** 页面路由 */
|
||||
type RouteKey =
|
||||
| '403'
|
||||
| '404'
|
||||
| '500'
|
||||
| 'about'
|
||||
| 'auth-demo'
|
||||
| 'auth-demo_permission'
|
||||
| 'auth-demo_super'
|
||||
| 'component'
|
||||
| 'component_button'
|
||||
| 'component_card'
|
||||
| 'component_table'
|
||||
| 'constant-page'
|
||||
| 'dashboard'
|
||||
| 'dashboard_analysis'
|
||||
| 'dashboard_workbench'
|
||||
| 'document'
|
||||
| 'document_naive'
|
||||
| 'document_project'
|
||||
| 'document_project-link'
|
||||
| 'document_vite'
|
||||
| 'document_vue'
|
||||
| 'exception'
|
||||
| 'exception_403'
|
||||
| 'exception_404'
|
||||
| 'exception_500'
|
||||
| 'function'
|
||||
| 'function_tab'
|
||||
| 'function_tab-detail'
|
||||
| 'function_tab-multi-detail'
|
||||
| 'login'
|
||||
| 'management'
|
||||
| 'management_auth'
|
||||
| 'management_role'
|
||||
| 'management_route'
|
||||
| 'management_user'
|
||||
| 'multi-menu'
|
||||
| 'multi-menu_first'
|
||||
| 'multi-menu_first_second'
|
||||
| 'multi-menu_first_second-new'
|
||||
| 'multi-menu_first_second-new_third'
|
||||
| 'not-found'
|
||||
| 'plugin'
|
||||
| 'plugin_charts'
|
||||
| 'plugin_charts_antv'
|
||||
| 'plugin_charts_echarts'
|
||||
| 'plugin_copy'
|
||||
| 'plugin_editor'
|
||||
| 'plugin_editor_markdown'
|
||||
| 'plugin_editor_quill'
|
||||
| 'plugin_icon'
|
||||
| 'plugin_map'
|
||||
| 'plugin_print'
|
||||
| 'plugin_swiper'
|
||||
| 'plugin_video';
|
||||
|
||||
/** 最后一级路由(该级路有对应的vue文件) */
|
||||
type LastDegreeRouteKey = Extract<RouteKey, '403' | '404' | '500' | 'about' | 'auth-demo_permission' | 'auth-demo_super' | 'component_button' | 'component_card' | 'component_table' | 'constant-page' | 'dashboard_analysis' | 'dashboard_workbench' | 'document_naive' | 'document_project' | 'document_project-link' | 'document_vite' | 'document_vue' | 'exception_403' | 'exception_404' | 'exception_500' | 'function_tab' | 'function_tab-detail' | 'function_tab-multi-detail' | 'login' | 'management_auth' | 'management_role' | 'management_route' | 'management_user' | 'multi-menu_first_second' | 'multi-menu_first_second-new_third' | 'not-found' | 'plugin_charts_antv' | 'plugin_charts_echarts' | 'plugin_copy' | 'plugin_editor_markdown' | 'plugin_editor_quill' | 'plugin_icon' | 'plugin_map' | 'plugin_print' | 'plugin_swiper' | 'plugin_video'>
|
||||
}
|
22
src/typings/storage.d.ts
vendored
Normal file
22
src/typings/storage.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
declare namespace StorageInterface {
|
||||
/** localStorage的存储数据的类型 */
|
||||
interface Session {
|
||||
demoKey: string;
|
||||
}
|
||||
|
||||
/** localStorage的存储数据的类型 */
|
||||
interface Local {
|
||||
/** 主题颜色 */
|
||||
themeColor: string;
|
||||
/** 用户token */
|
||||
token: string;
|
||||
/** 用户刷新token */
|
||||
refreshToken: string;
|
||||
/** 用户信息 */
|
||||
userInfo: Auth.UserInfo;
|
||||
/** 主题配置 */
|
||||
themeSettings: Theme.Setting;
|
||||
/** 多页签路由信息 */
|
||||
multiTabRoutes: App.GlobalTabRoute[];
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './user';
|
@ -1,60 +0,0 @@
|
||||
import { EnumStorageKey } from '@/enum';
|
||||
import { getLocal, removeLocal, setLocal } from '../storage';
|
||||
|
||||
/** 设置token */
|
||||
export function setToken(token: string) {
|
||||
setLocal(EnumStorageKey.token, token);
|
||||
}
|
||||
|
||||
/** 获取token */
|
||||
export function getToken() {
|
||||
return getLocal<string>(EnumStorageKey.token) || '';
|
||||
}
|
||||
|
||||
/** 去除token */
|
||||
export function removeToken() {
|
||||
removeLocal(EnumStorageKey.token);
|
||||
}
|
||||
|
||||
/** 获取refresh token */
|
||||
export function getRefreshToken() {
|
||||
return getLocal<string>(EnumStorageKey['refresh-token']) || '';
|
||||
}
|
||||
|
||||
/** 设置refresh token */
|
||||
export function setRefreshToken(token: string) {
|
||||
setLocal(EnumStorageKey['refresh-token'], token);
|
||||
}
|
||||
|
||||
/** 去除refresh token */
|
||||
export function removeRefreshToken() {
|
||||
removeLocal(EnumStorageKey['refresh-token']);
|
||||
}
|
||||
|
||||
/** 获取用户信息 */
|
||||
export function getUserInfo() {
|
||||
const emptyInfo: Auth.UserInfo = {
|
||||
userId: '',
|
||||
userName: '',
|
||||
userRole: 'user'
|
||||
};
|
||||
const userInfo: Auth.UserInfo = getLocal<Auth.UserInfo>(EnumStorageKey['user-info']) || emptyInfo;
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/** 设置用户信息 */
|
||||
export function setUserInfo(userInfo: Auth.UserInfo) {
|
||||
setLocal(EnumStorageKey['user-info'], userInfo);
|
||||
}
|
||||
|
||||
/** 去除用户信息 */
|
||||
export function removeUserInfo() {
|
||||
removeLocal(EnumStorageKey['user-info']);
|
||||
}
|
||||
|
||||
/** 去除用户相关缓存 */
|
||||
export function clearAuthStorage() {
|
||||
removeToken();
|
||||
removeRefreshToken();
|
||||
removeUserInfo();
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
export * from './typeof';
|
||||
export * from './color';
|
||||
export * from './number';
|
||||
export * from './object';
|
||||
export * from './pattern';
|
||||
export * from './theme';
|
||||
|
@ -1,4 +0,0 @@
|
||||
/** 设置对象数据 */
|
||||
export function objectAssign<T extends Record<string, any>>(target: T, source: Partial<T>) {
|
||||
Object.assign(target, source);
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { EnumStorageKey } from '@/enum';
|
||||
|
||||
/**
|
||||
* 缓存主题颜色
|
||||
* @param color
|
||||
*/
|
||||
export function setThemeColor(color: string) {
|
||||
window.localStorage.setItem(EnumStorageKey['theme-color'], color);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存的主题颜色
|
||||
*/
|
||||
export function getThemeColor() {
|
||||
return window.localStorage.getItem(EnumStorageKey['theme-color']);
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
export * from './common';
|
||||
export * from './storage';
|
||||
export * from './service';
|
||||
export * from './auth';
|
||||
export * from './router';
|
||||
export * from './form';
|
||||
|
@ -1,45 +1,57 @@
|
||||
import { decrypto, encrypto } from '../crypto';
|
||||
|
||||
interface StorageData {
|
||||
value: unknown;
|
||||
interface StorageData<T> {
|
||||
value: T;
|
||||
expire: number | null;
|
||||
}
|
||||
|
||||
/** 默认缓存期限为7天 */
|
||||
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
||||
function createLocalStorage<T extends StorageInterface.Local = StorageInterface.Local>() {
|
||||
/** 默认缓存期限为7天 */
|
||||
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
||||
|
||||
export function setLocal(key: string, value: unknown, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
const storageData: StorageData = { value, expire: expire !== null ? new Date().getTime() + expire * 1000 : null };
|
||||
const json = encrypto(storageData);
|
||||
window.localStorage.setItem(key, json);
|
||||
}
|
||||
function set<K extends keyof T>(key: K, value: T[K], expire: number | null = DEFAULT_CACHE_TIME) {
|
||||
const storageData: StorageData<T[K]> = {
|
||||
value,
|
||||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null
|
||||
};
|
||||
const json = encrypto(storageData);
|
||||
window.localStorage.setItem(key as string, json);
|
||||
}
|
||||
|
||||
export function getLocal<T>(key: string) {
|
||||
const json = window.localStorage.getItem(key);
|
||||
if (json) {
|
||||
let storageData: StorageData | null = null;
|
||||
try {
|
||||
storageData = decrypto(json);
|
||||
} catch {
|
||||
// 防止解析失败
|
||||
}
|
||||
if (storageData) {
|
||||
const { value, expire } = storageData;
|
||||
// 在有效期内直接返回
|
||||
if (expire === null || expire >= Date.now()) {
|
||||
return value as T;
|
||||
function get<K extends keyof T>(key: K) {
|
||||
const json = window.localStorage.getItem(key as string);
|
||||
if (json) {
|
||||
let storageData: StorageData<T[K]> | null = null;
|
||||
try {
|
||||
storageData = decrypto(json);
|
||||
} catch {
|
||||
// 防止解析失败
|
||||
}
|
||||
if (storageData) {
|
||||
const { value, expire } = storageData;
|
||||
// 在有效期内直接返回
|
||||
if (expire === null || expire >= Date.now()) {
|
||||
return value as T[K];
|
||||
}
|
||||
}
|
||||
remove(key);
|
||||
return null;
|
||||
}
|
||||
removeLocal(key);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
function remove(key: keyof T) {
|
||||
window.localStorage.removeItem(key as string);
|
||||
}
|
||||
function clear() {
|
||||
window.localStorage.clear();
|
||||
}
|
||||
|
||||
return {
|
||||
set,
|
||||
get,
|
||||
remove,
|
||||
clear
|
||||
};
|
||||
}
|
||||
|
||||
export function removeLocal(key: string) {
|
||||
window.localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
export function clearLocal() {
|
||||
window.localStorage.clear();
|
||||
}
|
||||
export const localStg = createLocalStorage();
|
||||
|
@ -25,3 +25,37 @@ export function removeSession(key: string) {
|
||||
export function clearSession() {
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
|
||||
function createSessionStorage<T extends StorageInterface.Session = StorageInterface.Session>() {
|
||||
function set<K extends keyof T>(key: K, value: T[K]) {
|
||||
const json = encrypto(value);
|
||||
sessionStorage.setItem(key as string, json);
|
||||
}
|
||||
function get<K extends keyof T>(key: K) {
|
||||
const json = sessionStorage.getItem(key as string);
|
||||
let data: T[K] | null = null;
|
||||
if (json) {
|
||||
try {
|
||||
data = decrypto(json);
|
||||
} catch {
|
||||
// 防止解析失败
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
function remove(key: keyof T) {
|
||||
window.sessionStorage.removeItem(key as string);
|
||||
}
|
||||
function clear() {
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
|
||||
return {
|
||||
set,
|
||||
get,
|
||||
remove,
|
||||
clear
|
||||
};
|
||||
}
|
||||
|
||||
export const sessionStg = createSessionStorage();
|
||||
|
Loading…
Reference in New Issue
Block a user