Showing
48 changed files
with
2994 additions
and
87 deletions
.env.development
0 → 100644
.env.production
0 → 100644
1 | import path from 'path' | 1 | import path from 'path' |
2 | +import { BuildOptions } from 'vite' | ||
2 | export const OUTPUT_DIR = 'dist' | 3 | export const OUTPUT_DIR = 'dist' |
3 | 4 | ||
4 | // monaco-editor 路径 | 5 | // monaco-editor 路径 |
@@ -11,12 +12,12 @@ export const chunkSizeWarningLimit = 2000 | @@ -11,12 +12,12 @@ export const chunkSizeWarningLimit = 2000 | ||
11 | export const brotliSize = false | 12 | export const brotliSize = false |
12 | 13 | ||
13 | // 分包 | 14 | // 分包 |
14 | -export const rollupOptions = { | 15 | +export const rollupOptions: BuildOptions['rollupOptions'] = { |
15 | output: { | 16 | output: { |
16 | chunkFileNames: 'static/js/[name]-[hash].js', | 17 | chunkFileNames: 'static/js/[name]-[hash].js', |
17 | entryFileNames: 'static/js/[name]-[hash].js', | 18 | entryFileNames: 'static/js/[name]-[hash].js', |
18 | assetFileNames: (chunkInfo) => { | 19 | assetFileNames: (chunkInfo) => { |
19 | - if(['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) { | 20 | + if (['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name!))) { |
20 | return `static/[ext]/[name].[ext]` | 21 | return `static/[ext]/[name].[ext]` |
21 | } | 22 | } |
22 | return `static/[ext]/[name]-[hash].[ext]` | 23 | return `static/[ext]/[name]-[hash].[ext]` |
build/external/globConfig/const.ts
0 → 100644
build/external/globConfig/getGlobConfigName.ts
renamed from
build/getConfigFileName.ts
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | * Get the configuration file variable name | 2 | * Get the configuration file variable name |
3 | * @param env | 3 | * @param env |
4 | */ | 4 | */ |
5 | -export const getConfigFileName = (env: Record<string, any>) => { | 5 | +export const getGlobalConfigName = (env: Record<string, any>) => { |
6 | return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` | 6 | return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` |
7 | .toUpperCase() | 7 | .toUpperCase() |
8 | .replace(/\s/g, ''); | 8 | .replace(/\s/g, ''); |
build/external/globConfig/index.ts
0 → 100644
1 | +import { getRootPath } from "../utils"; | ||
2 | +import { writeFileSync } from "fs"; | ||
3 | +import { Plugin } from "vite"; | ||
4 | +import { GLOB_CONFIG_FILE_NAME } from "./const"; | ||
5 | +import { getGlobalConfigName } from "./getGlobConfigName"; | ||
6 | + | ||
7 | +export function GenerateBuildConfig(viteEnv: Record<string, any>) { | ||
8 | + return { | ||
9 | + name: 'vite-plugin-generate-global-config', | ||
10 | + apply: 'build', | ||
11 | + enforce: 'post', | ||
12 | + closeBundle() { | ||
13 | + | ||
14 | + function createConfig({ config, configName, configFileName }: { configName: string, config: Record<string, any>, configFileName?: string } = { configName: '', config: {} }) { | ||
15 | + try { | ||
16 | + const windowConf = `window.${configName}`; | ||
17 | + // Ensure that the variable will not be modified | ||
18 | + const configStr = `${windowConf}=${JSON.stringify(config)}; | ||
19 | + Object.freeze(${windowConf}); | ||
20 | + Object.defineProperty(window, "${configName}", { | ||
21 | + configurable: false, | ||
22 | + writable: false, | ||
23 | + }); | ||
24 | + `.replace(/\s/g, ''); | ||
25 | + | ||
26 | + writeFileSync(getRootPath(`dist/${configFileName}`), configStr, { encoding: 'utf-8' }) | ||
27 | + } catch (error) { | ||
28 | + | ||
29 | + } | ||
30 | + } | ||
31 | + | ||
32 | + const configName = getGlobalConfigName(viteEnv as ImportMetaEnv) | ||
33 | + | ||
34 | + createConfig({ config: viteEnv, configFileName: GLOB_CONFIG_FILE_NAME, configName }) | ||
35 | + | ||
36 | + } | ||
37 | + } as Plugin | ||
38 | +} | ||
39 | + |
build/external/globConfig/useGlobSetting.ts
0 → 100644
1 | +import { getGlobalConfigName } from "./getGlobConfigName"; | ||
2 | + | ||
3 | + | ||
4 | +export function getAppEnvConfig() { | ||
5 | + const ENV_NAME = getGlobalConfigName(import.meta.env); | ||
6 | + | ||
7 | + const ENV = (import.meta.env.DEV | ||
8 | + ? // Get the global configuration (the configuration will be extracted independently when packaging) | ||
9 | + (import.meta.env as unknown as GlobEnvConfig) | ||
10 | + : window[ENV_NAME as any]) as unknown as GlobEnvConfig; | ||
11 | + const { | ||
12 | + VITE_GLOB_APP_TITLE, | ||
13 | + VITE_GLOB_APP_SHORT_NAME, | ||
14 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
15 | + } = ENV; | ||
16 | + | ||
17 | + if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { | ||
18 | + console.warn( | ||
19 | + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` | ||
20 | + ); | ||
21 | + } | ||
22 | + | ||
23 | + return { | ||
24 | + VITE_GLOB_APP_TITLE, | ||
25 | + VITE_GLOB_APP_SHORT_NAME, | ||
26 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
27 | + }; | ||
28 | +} | ||
29 | + | ||
30 | +export const useGlobSetting = (): Readonly<GlobConfig> => { | ||
31 | + const { | ||
32 | + VITE_GLOB_APP_TITLE, | ||
33 | + VITE_GLOB_APP_SHORT_NAME, | ||
34 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
35 | + } = getAppEnvConfig(); | ||
36 | + | ||
37 | + if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { | ||
38 | + console.warn( | ||
39 | + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` | ||
40 | + ); | ||
41 | + } | ||
42 | + | ||
43 | + // Take global configuration | ||
44 | + const glob: Readonly<GlobConfig> = { | ||
45 | + title: VITE_GLOB_APP_TITLE, | ||
46 | + securityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
47 | + }; | ||
48 | + | ||
49 | + return glob as Readonly<GlobConfig>; | ||
50 | +}; |
build/external/utils.ts
0 → 100644
1 | +import { resolve } from "path" | ||
2 | + | ||
3 | +export function parseEnv(env: ImportMetaEnv) { | ||
4 | + const res: Record<string, any> = {} | ||
5 | + | ||
6 | + for (const envName of Object.keys(env)) { | ||
7 | + let value = env[envName] | ||
8 | + | ||
9 | + // parese to boolean | ||
10 | + value = value === 'true' ? true : value === 'false' ? false : value | ||
11 | + | ||
12 | + if (envName === 'VITE_GLOB_PROXY') { | ||
13 | + try { | ||
14 | + value = JSON.parse(value) | ||
15 | + } catch (error) { | ||
16 | + value = '' | ||
17 | + } | ||
18 | + } | ||
19 | + | ||
20 | + res[envName] = value | ||
21 | + | ||
22 | + if (typeof value === 'string') { | ||
23 | + process.env[envName] = value | ||
24 | + } else if (typeof value === 'object') { | ||
25 | + process.env[envName] === JSON.stringify(value) | ||
26 | + } | ||
27 | + | ||
28 | + } | ||
29 | + | ||
30 | + return res | ||
31 | +} | ||
32 | + | ||
33 | +export function getEnvConfig(match = 'VITE_GLOB_',) { | ||
34 | + | ||
35 | +} | ||
36 | + | ||
37 | +export function getRootPath(...dir: string[]) { | ||
38 | + return resolve(process.cwd(), ...dir); | ||
39 | +} |
build/external/vite/html.ts
0 → 100644
1 | +import { createHtmlPlugin } from 'vite-plugin-html' | ||
2 | + | ||
3 | +const GLOB_CONFIG_FILE_NAME = '_app.config.js' | ||
4 | + | ||
5 | +export function configHtmlPlugin(env: ImportMetaEnv, isBuild: boolean) { | ||
6 | + const { VITE_GLOB_APP_TITLE, VITE_GLOB_CONTENT_SECURITY_POLICY, VITE_GLOB_PUBLIC_PATH } = env | ||
7 | + const getAppConfigSrc = () => { | ||
8 | + const path = VITE_GLOB_PUBLIC_PATH.endsWith('/') ? VITE_GLOB_PUBLIC_PATH : `${VITE_GLOB_PUBLIC_PATH}` | ||
9 | + return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${Date.now()}` | ||
10 | + } | ||
11 | + | ||
12 | + const htmlPlugin = createHtmlPlugin({ | ||
13 | + minify: isBuild, | ||
14 | + inject: { | ||
15 | + data: { | ||
16 | + title: VITE_GLOB_APP_TITLE, | ||
17 | + contentSecurityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY ? `<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />` : '' | ||
18 | + }, | ||
19 | + tags: isBuild ? [ | ||
20 | + { | ||
21 | + tag: 'script', | ||
22 | + attrs: { src: getAppConfigSrc() } | ||
23 | + } | ||
24 | + ] : [] | ||
25 | + } | ||
26 | + }) | ||
27 | + | ||
28 | + return htmlPlugin | ||
29 | +} |
build/external/vite/proxy.ts
0 → 100644
1 | +import { ProxyOptions } from "vite" | ||
2 | + | ||
3 | +export const createProxy = (viteEnv: ImportMetaEnv) => { | ||
4 | + const { VITE_GLOB_PROXY } = viteEnv | ||
5 | + const httpsReg = /^https:\/\//; | ||
6 | + const res: Record<string, ProxyOptions> = {} | ||
7 | + | ||
8 | + for (const [prefix, target] of VITE_GLOB_PROXY) { | ||
9 | + const isHttps = httpsReg.test(prefix) | ||
10 | + | ||
11 | + res[prefix] = { | ||
12 | + target, | ||
13 | + changeOrigin: true, | ||
14 | + ws: true, | ||
15 | + rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), | ||
16 | + ...(isHttps ? { secure: false } : {}) | ||
17 | + } | ||
18 | + } | ||
19 | + | ||
20 | + return res | ||
21 | +} |
@@ -31,10 +31,12 @@ | @@ -31,10 +31,12 @@ | ||
31 | "gsap": "^3.11.3", | 31 | "gsap": "^3.11.3", |
32 | "highlight.js": "^11.5.0", | 32 | "highlight.js": "^11.5.0", |
33 | "html2canvas": "^1.4.1", | 33 | "html2canvas": "^1.4.1", |
34 | + "jwt-decode": "^3.1.2", | ||
34 | "keymaster": "^1.6.2", | 35 | "keymaster": "^1.6.2", |
35 | "monaco-editor": "^0.33.0", | 36 | "monaco-editor": "^0.33.0", |
36 | "naive-ui": "2.34.3", | 37 | "naive-ui": "2.34.3", |
37 | "pinia": "^2.0.13", | 38 | "pinia": "^2.0.13", |
39 | + "qs": "^6.11.0", | ||
38 | "screenfull": "^6.0.1", | 40 | "screenfull": "^6.0.1", |
39 | "three": "^0.145.0", | 41 | "three": "^0.145.0", |
40 | "vue": "^3.2.31", | 42 | "vue": "^3.2.31", |
@@ -49,6 +51,7 @@ | @@ -49,6 +51,7 @@ | ||
49 | "@commitlint/cli": "^17.0.2", | 51 | "@commitlint/cli": "^17.0.2", |
50 | "@commitlint/config-conventional": "^17.0.2", | 52 | "@commitlint/config-conventional": "^17.0.2", |
51 | "@types/node": "^16.11.26", | 53 | "@types/node": "^16.11.26", |
54 | + "@types/qs": "^6.9.7", | ||
52 | "@types/three": "^0.144.0", | 55 | "@types/three": "^0.144.0", |
53 | "@typescript-eslint/eslint-plugin": "^5.18.0", | 56 | "@typescript-eslint/eslint-plugin": "^5.18.0", |
54 | "@typescript-eslint/parser": "^5.18.0", | 57 | "@typescript-eslint/parser": "^5.18.0", |
@@ -76,6 +79,7 @@ | @@ -76,6 +79,7 @@ | ||
76 | "typescript": "4.6.3", | 79 | "typescript": "4.6.3", |
77 | "vite": "2.9.9", | 80 | "vite": "2.9.9", |
78 | "vite-plugin-compression": "^0.5.1", | 81 | "vite-plugin-compression": "^0.5.1", |
82 | + "vite-plugin-html": "^3.2.0", | ||
79 | "vite-plugin-importer": "^0.2.5", | 83 | "vite-plugin-importer": "^0.2.5", |
80 | "vite-plugin-mock": "^2.9.6", | 84 | "vite-plugin-mock": "^2.9.6", |
81 | "vite-plugin-monaco-editor": "^1.1.0", | 85 | "vite-plugin-monaco-editor": "^1.1.0", |
@@ -10,6 +10,7 @@ specifiers: | @@ -10,6 +10,7 @@ specifiers: | ||
10 | '@types/keymaster': ^1.6.30 | 10 | '@types/keymaster': ^1.6.30 |
11 | '@types/lodash': ^4.14.184 | 11 | '@types/lodash': ^4.14.184 |
12 | '@types/node': ^16.11.26 | 12 | '@types/node': ^16.11.26 |
13 | + '@types/qs': ^6.9.7 | ||
13 | '@types/three': ^0.144.0 | 14 | '@types/three': ^0.144.0 |
14 | '@typescript-eslint/eslint-plugin': ^5.18.0 | 15 | '@typescript-eslint/eslint-plugin': ^5.18.0 |
15 | '@typescript-eslint/parser': ^5.18.0 | 16 | '@typescript-eslint/parser': ^5.18.0 |
@@ -39,6 +40,7 @@ specifiers: | @@ -39,6 +40,7 @@ specifiers: | ||
39 | highlight.js: ^11.5.0 | 40 | highlight.js: ^11.5.0 |
40 | html2canvas: ^1.4.1 | 41 | html2canvas: ^1.4.1 |
41 | husky: ^8.0.1 | 42 | husky: ^8.0.1 |
43 | + jwt-decode: ^3.1.2 | ||
42 | keymaster: ^1.6.2 | 44 | keymaster: ^1.6.2 |
43 | lodash: ~4.17.21 | 45 | lodash: ~4.17.21 |
44 | mockjs: ^1.1.0 | 46 | mockjs: ^1.1.0 |
@@ -47,6 +49,7 @@ specifiers: | @@ -47,6 +49,7 @@ specifiers: | ||
47 | pinia: ^2.0.13 | 49 | pinia: ^2.0.13 |
48 | plop: ^3.0.5 | 50 | plop: ^3.0.5 |
49 | prettier: ^2.6.2 | 51 | prettier: ^2.6.2 |
52 | + qs: ^6.11.0 | ||
50 | sass: ^1.49.11 | 53 | sass: ^1.49.11 |
51 | sass-loader: ^12.6.0 | 54 | sass-loader: ^12.6.0 |
52 | screenfull: ^6.0.1 | 55 | screenfull: ^6.0.1 |
@@ -54,6 +57,7 @@ specifiers: | @@ -54,6 +57,7 @@ specifiers: | ||
54 | typescript: 4.6.3 | 57 | typescript: 4.6.3 |
55 | vite: 2.9.9 | 58 | vite: 2.9.9 |
56 | vite-plugin-compression: ^0.5.1 | 59 | vite-plugin-compression: ^0.5.1 |
60 | + vite-plugin-html: ^3.2.0 | ||
57 | vite-plugin-importer: ^0.2.5 | 61 | vite-plugin-importer: ^0.2.5 |
58 | vite-plugin-mock: ^2.9.6 | 62 | vite-plugin-mock: ^2.9.6 |
59 | vite-plugin-monaco-editor: ^1.1.0 | 63 | vite-plugin-monaco-editor: ^1.1.0 |
@@ -85,10 +89,12 @@ dependencies: | @@ -85,10 +89,12 @@ dependencies: | ||
85 | gsap: 3.11.3 | 89 | gsap: 3.11.3 |
86 | highlight.js: 11.5.1 | 90 | highlight.js: 11.5.1 |
87 | html2canvas: 1.4.1 | 91 | html2canvas: 1.4.1 |
92 | + jwt-decode: 3.1.2 | ||
88 | keymaster: 1.6.2 | 93 | keymaster: 1.6.2 |
89 | monaco-editor: 0.33.0 | 94 | monaco-editor: 0.33.0 |
90 | naive-ui: 2.34.3_vue@3.2.37 | 95 | naive-ui: 2.34.3_vue@3.2.37 |
91 | pinia: 2.0.14_ub5l46u3nefphax5x2tezui4oq | 96 | pinia: 2.0.14_ub5l46u3nefphax5x2tezui4oq |
97 | + qs: 6.11.0 | ||
92 | screenfull: 6.0.1 | 98 | screenfull: 6.0.1 |
93 | three: 0.145.0 | 99 | three: 0.145.0 |
94 | vue: 3.2.37 | 100 | vue: 3.2.37 |
@@ -103,6 +109,7 @@ devDependencies: | @@ -103,6 +109,7 @@ devDependencies: | ||
103 | '@commitlint/cli': 17.0.2 | 109 | '@commitlint/cli': 17.0.2 |
104 | '@commitlint/config-conventional': 17.0.2 | 110 | '@commitlint/config-conventional': 17.0.2 |
105 | '@types/node': 16.11.40 | 111 | '@types/node': 16.11.40 |
112 | + '@types/qs': 6.9.7 | ||
106 | '@types/three': 0.144.0 | 113 | '@types/three': 0.144.0 |
107 | '@typescript-eslint/eslint-plugin': 5.28.0_evi7yu7wunhzwb24olrfvzynny | 114 | '@typescript-eslint/eslint-plugin': 5.28.0_evi7yu7wunhzwb24olrfvzynny |
108 | '@typescript-eslint/parser': 5.28.0_sfmgizikprcxt7r54j7cnzjamu | 115 | '@typescript-eslint/parser': 5.28.0_sfmgizikprcxt7r54j7cnzjamu |
@@ -130,6 +137,7 @@ devDependencies: | @@ -130,6 +137,7 @@ devDependencies: | ||
130 | typescript: 4.6.3 | 137 | typescript: 4.6.3 |
131 | vite: 2.9.9_sass@1.52.3 | 138 | vite: 2.9.9_sass@1.52.3 |
132 | vite-plugin-compression: 0.5.1_vite@2.9.9 | 139 | vite-plugin-compression: 0.5.1_vite@2.9.9 |
140 | + vite-plugin-html: 3.2.0_vite@2.9.9 | ||
133 | vite-plugin-importer: 0.2.5 | 141 | vite-plugin-importer: 0.2.5 |
134 | vite-plugin-mock: 2.9.6_mockjs@1.1.0+vite@2.9.9 | 142 | vite-plugin-mock: 2.9.6_mockjs@1.1.0+vite@2.9.9 |
135 | vite-plugin-monaco-editor: 1.1.0_monaco-editor@0.33.0 | 143 | vite-plugin-monaco-editor: 1.1.0_monaco-editor@0.33.0 |
@@ -745,6 +753,13 @@ packages: | @@ -745,6 +753,13 @@ packages: | ||
745 | engines: {node: '>=6.0.0'} | 753 | engines: {node: '>=6.0.0'} |
746 | dev: true | 754 | dev: true |
747 | 755 | ||
756 | + /@jridgewell/source-map/0.3.2: | ||
757 | + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} | ||
758 | + dependencies: | ||
759 | + '@jridgewell/gen-mapping': 0.3.1 | ||
760 | + '@jridgewell/trace-mapping': 0.3.13 | ||
761 | + dev: true | ||
762 | + | ||
748 | /@jridgewell/sourcemap-codec/1.4.13: | 763 | /@jridgewell/sourcemap-codec/1.4.13: |
749 | resolution: {integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==} | 764 | resolution: {integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==} |
750 | dev: true | 765 | dev: true |
@@ -928,6 +943,10 @@ packages: | @@ -928,6 +943,10 @@ packages: | ||
928 | resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} | 943 | resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} |
929 | dev: true | 944 | dev: true |
930 | 945 | ||
946 | + /@types/qs/6.9.7: | ||
947 | + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} | ||
948 | + dev: true | ||
949 | + | ||
931 | /@types/resolve/1.17.1: | 950 | /@types/resolve/1.17.1: |
932 | resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} | 951 | resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} |
933 | dependencies: | 952 | dependencies: |
@@ -1237,7 +1256,6 @@ packages: | @@ -1237,7 +1256,6 @@ packages: | ||
1237 | dependencies: | 1256 | dependencies: |
1238 | '@vue/reactivity': 3.2.37 | 1257 | '@vue/reactivity': 3.2.37 |
1239 | '@vue/shared': 3.2.37 | 1258 | '@vue/shared': 3.2.37 |
1240 | - dev: false | ||
1241 | 1259 | ||
1242 | /@vue/runtime-dom/3.2.37: | 1260 | /@vue/runtime-dom/3.2.37: |
1243 | resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} | 1261 | resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} |
@@ -1245,7 +1263,6 @@ packages: | @@ -1245,7 +1263,6 @@ packages: | ||
1245 | '@vue/runtime-core': 3.2.37 | 1263 | '@vue/runtime-core': 3.2.37 |
1246 | '@vue/shared': 3.2.37 | 1264 | '@vue/shared': 3.2.37 |
1247 | csstype: 2.6.20 | 1265 | csstype: 2.6.20 |
1248 | - dev: false | ||
1249 | 1266 | ||
1250 | /@vue/server-renderer/3.2.37_vue@3.2.37: | 1267 | /@vue/server-renderer/3.2.37_vue@3.2.37: |
1251 | resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} | 1268 | resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} |
@@ -1255,7 +1272,6 @@ packages: | @@ -1255,7 +1272,6 @@ packages: | ||
1255 | '@vue/compiler-ssr': 3.2.37 | 1272 | '@vue/compiler-ssr': 3.2.37 |
1256 | '@vue/shared': 3.2.37 | 1273 | '@vue/shared': 3.2.37 |
1257 | vue: 3.2.37 | 1274 | vue: 3.2.37 |
1258 | - dev: false | ||
1259 | 1275 | ||
1260 | /@vue/shared/3.2.37: | 1276 | /@vue/shared/3.2.37: |
1261 | resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} | 1277 | resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} |
@@ -1449,6 +1465,10 @@ packages: | @@ -1449,6 +1465,10 @@ packages: | ||
1449 | resolution: {integrity: sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA==} | 1465 | resolution: {integrity: sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA==} |
1450 | dev: false | 1466 | dev: false |
1451 | 1467 | ||
1468 | + /async/3.2.4: | ||
1469 | + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} | ||
1470 | + dev: true | ||
1471 | + | ||
1452 | /asynckit/0.4.0: | 1472 | /asynckit/0.4.0: |
1453 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} | 1473 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} |
1454 | dev: false | 1474 | dev: false |
@@ -1520,6 +1540,12 @@ packages: | @@ -1520,6 +1540,12 @@ packages: | ||
1520 | concat-map: 0.0.1 | 1540 | concat-map: 0.0.1 |
1521 | dev: true | 1541 | dev: true |
1522 | 1542 | ||
1543 | + /brace-expansion/2.0.1: | ||
1544 | + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} | ||
1545 | + dependencies: | ||
1546 | + balanced-match: 1.0.2 | ||
1547 | + dev: true | ||
1548 | + | ||
1523 | /braces/3.0.2: | 1549 | /braces/3.0.2: |
1524 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} | 1550 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} |
1525 | engines: {node: '>=8'} | 1551 | engines: {node: '>=8'} |
@@ -1539,6 +1565,10 @@ packages: | @@ -1539,6 +1565,10 @@ packages: | ||
1539 | picocolors: 1.0.0 | 1565 | picocolors: 1.0.0 |
1540 | dev: true | 1566 | dev: true |
1541 | 1567 | ||
1568 | + /buffer-from/1.1.2: | ||
1569 | + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} | ||
1570 | + dev: true | ||
1571 | + | ||
1542 | /buffer/5.7.1: | 1572 | /buffer/5.7.1: |
1543 | resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} | 1573 | resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} |
1544 | dependencies: | 1574 | dependencies: |
@@ -1563,7 +1593,6 @@ packages: | @@ -1563,7 +1593,6 @@ packages: | ||
1563 | dependencies: | 1593 | dependencies: |
1564 | function-bind: 1.1.1 | 1594 | function-bind: 1.1.1 |
1565 | get-intrinsic: 1.1.2 | 1595 | get-intrinsic: 1.1.2 |
1566 | - dev: true | ||
1567 | 1596 | ||
1568 | /callsites/3.1.0: | 1597 | /callsites/3.1.0: |
1569 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} | 1598 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} |
@@ -1672,6 +1701,13 @@ packages: | @@ -1672,6 +1701,13 @@ packages: | ||
1672 | fsevents: 2.3.2 | 1701 | fsevents: 2.3.2 |
1673 | dev: true | 1702 | dev: true |
1674 | 1703 | ||
1704 | + /clean-css/5.3.2: | ||
1705 | + resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} | ||
1706 | + engines: {node: '>= 10.0'} | ||
1707 | + dependencies: | ||
1708 | + source-map: 0.6.1 | ||
1709 | + dev: true | ||
1710 | + | ||
1675 | /clean-stack/2.2.0: | 1711 | /clean-stack/2.2.0: |
1676 | resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} | 1712 | resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} |
1677 | engines: {node: '>=6'} | 1713 | engines: {node: '>=6'} |
@@ -1748,6 +1784,10 @@ packages: | @@ -1748,6 +1784,10 @@ packages: | ||
1748 | color-string: 1.9.1 | 1784 | color-string: 1.9.1 |
1749 | dev: false | 1785 | dev: false |
1750 | 1786 | ||
1787 | + /colorette/2.0.19: | ||
1788 | + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} | ||
1789 | + dev: true | ||
1790 | + | ||
1751 | /combined-stream/1.0.8: | 1791 | /combined-stream/1.0.8: |
1752 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} | 1792 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} |
1753 | engines: {node: '>= 0.8'} | 1793 | engines: {node: '>= 0.8'} |
@@ -1755,6 +1795,15 @@ packages: | @@ -1755,6 +1795,15 @@ packages: | ||
1755 | delayed-stream: 1.0.0 | 1795 | delayed-stream: 1.0.0 |
1756 | dev: false | 1796 | dev: false |
1757 | 1797 | ||
1798 | + /commander/2.20.3: | ||
1799 | + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} | ||
1800 | + dev: true | ||
1801 | + | ||
1802 | + /commander/8.3.0: | ||
1803 | + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} | ||
1804 | + engines: {node: '>= 12'} | ||
1805 | + dev: true | ||
1806 | + | ||
1758 | /commander/9.3.0: | 1807 | /commander/9.3.0: |
1759 | resolution: {integrity: sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==} | 1808 | resolution: {integrity: sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==} |
1760 | engines: {node: ^12.20.0 || >=14} | 1809 | engines: {node: ^12.20.0 || >=14} |
@@ -1783,6 +1832,11 @@ packages: | @@ -1783,6 +1832,11 @@ packages: | ||
1783 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} | 1832 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} |
1784 | dev: true | 1833 | dev: true |
1785 | 1834 | ||
1835 | + /connect-history-api-fallback/1.6.0: | ||
1836 | + resolution: {integrity: sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==} | ||
1837 | + engines: {node: '>=0.8'} | ||
1838 | + dev: true | ||
1839 | + | ||
1786 | /connect/3.7.0: | 1840 | /connect/3.7.0: |
1787 | resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} | 1841 | resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} |
1788 | engines: {node: '>= 0.10.0'} | 1842 | engines: {node: '>= 0.10.0'} |
@@ -1795,6 +1849,10 @@ packages: | @@ -1795,6 +1849,10 @@ packages: | ||
1795 | - supports-color | 1849 | - supports-color |
1796 | dev: true | 1850 | dev: true |
1797 | 1851 | ||
1852 | + /consola/2.15.3: | ||
1853 | + resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} | ||
1854 | + dev: true | ||
1855 | + | ||
1798 | /constant-case/3.0.4: | 1856 | /constant-case/3.0.4: |
1799 | resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} | 1857 | resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} |
1800 | dependencies: | 1858 | dependencies: |
@@ -1832,8 +1890,8 @@ packages: | @@ -1832,8 +1890,8 @@ packages: | ||
1832 | engines: {node: '>=10'} | 1890 | engines: {node: '>=10'} |
1833 | hasBin: true | 1891 | hasBin: true |
1834 | dependencies: | 1892 | dependencies: |
1835 | - is-text-path: 1.0.1 | ||
1836 | JSONStream: 1.3.5 | 1893 | JSONStream: 1.3.5 |
1894 | + is-text-path: 1.0.1 | ||
1837 | lodash: 4.17.21 | 1895 | lodash: 4.17.21 |
1838 | meow: 8.1.2 | 1896 | meow: 8.1.2 |
1839 | split2: 3.2.2 | 1897 | split2: 3.2.2 |
@@ -1904,6 +1962,21 @@ packages: | @@ -1904,6 +1962,21 @@ packages: | ||
1904 | csstype: 3.0.11 | 1962 | csstype: 3.0.11 |
1905 | dev: false | 1963 | dev: false |
1906 | 1964 | ||
1965 | + /css-select/4.3.0: | ||
1966 | + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} | ||
1967 | + dependencies: | ||
1968 | + boolbase: 1.0.0 | ||
1969 | + css-what: 6.1.0 | ||
1970 | + domhandler: 4.3.1 | ||
1971 | + domutils: 2.8.0 | ||
1972 | + nth-check: 2.1.1 | ||
1973 | + dev: true | ||
1974 | + | ||
1975 | + /css-what/6.1.0: | ||
1976 | + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} | ||
1977 | + engines: {node: '>= 6'} | ||
1978 | + dev: true | ||
1979 | + | ||
1907 | /cssesc/3.0.0: | 1980 | /cssesc/3.0.0: |
1908 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} | 1981 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} |
1909 | engines: {node: '>=4'} | 1982 | engines: {node: '>=4'} |
@@ -1912,7 +1985,6 @@ packages: | @@ -1912,7 +1985,6 @@ packages: | ||
1912 | 1985 | ||
1913 | /csstype/2.6.20: | 1986 | /csstype/2.6.20: |
1914 | resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} | 1987 | resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} |
1915 | - dev: false | ||
1916 | 1988 | ||
1917 | /csstype/3.0.11: | 1989 | /csstype/3.0.11: |
1918 | resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} | 1990 | resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} |
@@ -2112,6 +2184,16 @@ packages: | @@ -2112,6 +2184,16 @@ packages: | ||
2112 | is-obj: 2.0.0 | 2184 | is-obj: 2.0.0 |
2113 | dev: true | 2185 | dev: true |
2114 | 2186 | ||
2187 | + /dotenv-expand/8.0.3: | ||
2188 | + resolution: {integrity: sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==} | ||
2189 | + engines: {node: '>=12'} | ||
2190 | + dev: true | ||
2191 | + | ||
2192 | + /dotenv/16.0.3: | ||
2193 | + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} | ||
2194 | + engines: {node: '>=12'} | ||
2195 | + dev: true | ||
2196 | + | ||
2115 | /echarts-liquidfill/3.1.0_echarts@5.3.3: | 2197 | /echarts-liquidfill/3.1.0_echarts@5.3.3: |
2116 | resolution: {integrity: sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==} | 2198 | resolution: {integrity: sha512-5Dlqs/jTsdTUAsd+K5LPLLTgrbbNORUSBQyk8PSy1Mg2zgHDWm83FmvA4s0ooNepCJojFYRITTQ4GU1UUSKYLw==} |
2117 | peerDependencies: | 2199 | peerDependencies: |
@@ -2137,12 +2219,19 @@ packages: | @@ -2137,12 +2219,19 @@ packages: | ||
2137 | dependencies: | 2219 | dependencies: |
2138 | tslib: 2.3.0 | 2220 | tslib: 2.3.0 |
2139 | zrender: 5.3.2 | 2221 | zrender: 5.3.2 |
2140 | - dev: true | ||
2141 | 2222 | ||
2142 | /ee-first/1.1.1: | 2223 | /ee-first/1.1.1: |
2143 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} | 2224 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} |
2144 | dev: true | 2225 | dev: true |
2145 | 2226 | ||
2227 | + /ejs/3.1.8: | ||
2228 | + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} | ||
2229 | + engines: {node: '>=0.10.0'} | ||
2230 | + hasBin: true | ||
2231 | + dependencies: | ||
2232 | + jake: 10.8.5 | ||
2233 | + dev: true | ||
2234 | + | ||
2146 | /electron-to-chromium/1.4.155: | 2235 | /electron-to-chromium/1.4.155: |
2147 | resolution: {integrity: sha512-niPzKBSYPG06gxLKO0c2kEmgdRMTtIbNrBlvD31Ld8Q57b/K0218U4j8u/OOt25XE1eFOn47FcmQVdx9R1qqxA==} | 2236 | resolution: {integrity: sha512-niPzKBSYPG06gxLKO0c2kEmgdRMTtIbNrBlvD31Ld8Q57b/K0218U4j8u/OOt25XE1eFOn47FcmQVdx9R1qqxA==} |
2148 | dev: true | 2237 | dev: true |
@@ -2775,6 +2864,12 @@ packages: | @@ -2775,6 +2864,12 @@ packages: | ||
2775 | flat-cache: 3.0.4 | 2864 | flat-cache: 3.0.4 |
2776 | dev: true | 2865 | dev: true |
2777 | 2866 | ||
2867 | + /filelist/1.0.4: | ||
2868 | + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} | ||
2869 | + dependencies: | ||
2870 | + minimatch: 5.1.6 | ||
2871 | + dev: true | ||
2872 | + | ||
2778 | /fill-range/7.0.1: | 2873 | /fill-range/7.0.1: |
2779 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} | 2874 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} |
2780 | engines: {node: '>=8'} | 2875 | engines: {node: '>=8'} |
@@ -2912,7 +3007,6 @@ packages: | @@ -2912,7 +3007,6 @@ packages: | ||
2912 | 3007 | ||
2913 | /function-bind/1.1.1: | 3008 | /function-bind/1.1.1: |
2914 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} | 3009 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} |
2915 | - dev: true | ||
2916 | 3010 | ||
2917 | /function.prototype.name/1.1.5: | 3011 | /function.prototype.name/1.1.5: |
2918 | resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} | 3012 | resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} |
@@ -2948,7 +3042,6 @@ packages: | @@ -2948,7 +3042,6 @@ packages: | ||
2948 | function-bind: 1.1.1 | 3042 | function-bind: 1.1.1 |
2949 | has: 1.0.3 | 3043 | has: 1.0.3 |
2950 | has-symbols: 1.0.3 | 3044 | has-symbols: 1.0.3 |
2951 | - dev: true | ||
2952 | 3045 | ||
2953 | /get-stream/6.0.1: | 3046 | /get-stream/6.0.1: |
2954 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} | 3047 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} |
@@ -3111,7 +3204,6 @@ packages: | @@ -3111,7 +3204,6 @@ packages: | ||
3111 | /has-symbols/1.0.3: | 3204 | /has-symbols/1.0.3: |
3112 | resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} | 3205 | resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} |
3113 | engines: {node: '>= 0.4'} | 3206 | engines: {node: '>= 0.4'} |
3114 | - dev: true | ||
3115 | 3207 | ||
3116 | /has-tostringtag/1.0.0: | 3208 | /has-tostringtag/1.0.0: |
3117 | resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} | 3209 | resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} |
@@ -3125,12 +3217,16 @@ packages: | @@ -3125,12 +3217,16 @@ packages: | ||
3125 | engines: {node: '>= 0.4.0'} | 3217 | engines: {node: '>= 0.4.0'} |
3126 | dependencies: | 3218 | dependencies: |
3127 | function-bind: 1.1.1 | 3219 | function-bind: 1.1.1 |
3128 | - dev: true | ||
3129 | 3220 | ||
3130 | /hash-sum/2.0.0: | 3221 | /hash-sum/2.0.0: |
3131 | resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} | 3222 | resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} |
3132 | dev: true | 3223 | dev: true |
3133 | 3224 | ||
3225 | + /he/1.2.0: | ||
3226 | + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} | ||
3227 | + hasBin: true | ||
3228 | + dev: true | ||
3229 | + | ||
3134 | /header-case/2.0.4: | 3230 | /header-case/2.0.4: |
3135 | resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} | 3231 | resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} |
3136 | dependencies: | 3232 | dependencies: |
@@ -3161,6 +3257,20 @@ packages: | @@ -3161,6 +3257,20 @@ packages: | ||
3161 | lru-cache: 6.0.0 | 3257 | lru-cache: 6.0.0 |
3162 | dev: true | 3258 | dev: true |
3163 | 3259 | ||
3260 | + /html-minifier-terser/6.1.0: | ||
3261 | + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} | ||
3262 | + engines: {node: '>=12'} | ||
3263 | + hasBin: true | ||
3264 | + dependencies: | ||
3265 | + camel-case: 4.1.2 | ||
3266 | + clean-css: 5.3.2 | ||
3267 | + commander: 8.3.0 | ||
3268 | + he: 1.2.0 | ||
3269 | + param-case: 3.0.4 | ||
3270 | + relateurl: 0.2.7 | ||
3271 | + terser: 5.16.4 | ||
3272 | + dev: true | ||
3273 | + | ||
3164 | /html-tags/3.2.0: | 3274 | /html-tags/3.2.0: |
3165 | resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} | 3275 | resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} |
3166 | engines: {node: '>=8'} | 3276 | engines: {node: '>=8'} |
@@ -3517,6 +3627,17 @@ packages: | @@ -3517,6 +3627,17 @@ packages: | ||
3517 | engines: {node: '>=0.10.0'} | 3627 | engines: {node: '>=0.10.0'} |
3518 | dev: true | 3628 | dev: true |
3519 | 3629 | ||
3630 | + /jake/10.8.5: | ||
3631 | + resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} | ||
3632 | + engines: {node: '>=10'} | ||
3633 | + hasBin: true | ||
3634 | + dependencies: | ||
3635 | + async: 3.2.4 | ||
3636 | + chalk: 4.1.2 | ||
3637 | + filelist: 1.0.4 | ||
3638 | + minimatch: 3.1.2 | ||
3639 | + dev: true | ||
3640 | + | ||
3520 | /js-stringify/1.0.2: | 3641 | /js-stringify/1.0.2: |
3521 | resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} | 3642 | resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} |
3522 | dev: true | 3643 | dev: true |
@@ -3591,6 +3712,10 @@ packages: | @@ -3591,6 +3712,10 @@ packages: | ||
3591 | promise: 7.3.1 | 3712 | promise: 7.3.1 |
3592 | dev: true | 3713 | dev: true |
3593 | 3714 | ||
3715 | + /jwt-decode/3.1.2: | ||
3716 | + resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} | ||
3717 | + dev: false | ||
3718 | + | ||
3594 | /keymaster/1.6.2: | 3719 | /keymaster/1.6.2: |
3595 | resolution: {integrity: sha512-OvA/AALN8IDKKkTk2Z+bDrzs/SQao4lo/QPbwSdDvm+frxfiYiYCSn1aHFUypJY3SruAO1y/c771agBmTXqUtg==} | 3720 | resolution: {integrity: sha512-OvA/AALN8IDKKkTk2Z+bDrzs/SQao4lo/QPbwSdDvm+frxfiYiYCSn1aHFUypJY3SruAO1y/c771agBmTXqUtg==} |
3596 | dev: false | 3721 | dev: false |
@@ -3790,6 +3915,13 @@ packages: | @@ -3790,6 +3915,13 @@ packages: | ||
3790 | brace-expansion: 1.1.11 | 3915 | brace-expansion: 1.1.11 |
3791 | dev: true | 3916 | dev: true |
3792 | 3917 | ||
3918 | + /minimatch/5.1.6: | ||
3919 | + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} | ||
3920 | + engines: {node: '>=10'} | ||
3921 | + dependencies: | ||
3922 | + brace-expansion: 2.0.1 | ||
3923 | + dev: true | ||
3924 | + | ||
3793 | /minimist-options/4.1.0: | 3925 | /minimist-options/4.1.0: |
3794 | resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} | 3926 | resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} |
3795 | engines: {node: '>= 6'} | 3927 | engines: {node: '>= 6'} |
@@ -3818,7 +3950,6 @@ packages: | @@ -3818,7 +3950,6 @@ packages: | ||
3818 | 3950 | ||
3819 | /monaco-editor/0.33.0: | 3951 | /monaco-editor/0.33.0: |
3820 | resolution: {integrity: sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==} | 3952 | resolution: {integrity: sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==} |
3821 | - dev: false | ||
3822 | 3953 | ||
3823 | /ms/2.0.0: | 3954 | /ms/2.0.0: |
3824 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} | 3955 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} |
@@ -3882,6 +4013,13 @@ packages: | @@ -3882,6 +4013,13 @@ packages: | ||
3882 | tslib: 2.4.0 | 4013 | tslib: 2.4.0 |
3883 | dev: true | 4014 | dev: true |
3884 | 4015 | ||
4016 | + /node-html-parser/5.4.2: | ||
4017 | + resolution: {integrity: sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==} | ||
4018 | + dependencies: | ||
4019 | + css-select: 4.3.0 | ||
4020 | + he: 1.2.0 | ||
4021 | + dev: true | ||
4022 | + | ||
3885 | /node-plop/0.31.0: | 4023 | /node-plop/0.31.0: |
3886 | resolution: {integrity: sha512-aKLPxiBoFTNUovvtK8j/Whc4PZREkYx6htw2HJPiU8wYquXmN8pkd9B3xlFo6AJ4ZlzFsQSf/NXR5xET8EqRYw==} | 4024 | resolution: {integrity: sha512-aKLPxiBoFTNUovvtK8j/Whc4PZREkYx6htw2HJPiU8wYquXmN8pkd9B3xlFo6AJ4ZlzFsQSf/NXR5xET8EqRYw==} |
3887 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} | 4025 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} |
@@ -3949,7 +4087,6 @@ packages: | @@ -3949,7 +4087,6 @@ packages: | ||
3949 | 4087 | ||
3950 | /object-inspect/1.12.2: | 4088 | /object-inspect/1.12.2: |
3951 | resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} | 4089 | resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} |
3952 | - dev: true | ||
3953 | 4090 | ||
3954 | /object-keys/1.1.1: | 4091 | /object-keys/1.1.1: |
3955 | resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} | 4092 | resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} |
@@ -4228,6 +4365,10 @@ packages: | @@ -4228,6 +4365,10 @@ packages: | ||
4228 | engines: {node: '>=8'} | 4365 | engines: {node: '>=8'} |
4229 | dev: true | 4366 | dev: true |
4230 | 4367 | ||
4368 | + /pathe/0.2.0: | ||
4369 | + resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} | ||
4370 | + dev: true | ||
4371 | + | ||
4231 | /picocolors/1.0.0: | 4372 | /picocolors/1.0.0: |
4232 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} | 4373 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} |
4233 | 4374 | ||
@@ -4410,6 +4551,13 @@ packages: | @@ -4410,6 +4551,13 @@ packages: | ||
4410 | engines: {node: '>=0.6.0', teleport: '>=0.2.0'} | 4551 | engines: {node: '>=0.6.0', teleport: '>=0.2.0'} |
4411 | dev: true | 4552 | dev: true |
4412 | 4553 | ||
4554 | + /qs/6.11.0: | ||
4555 | + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} | ||
4556 | + engines: {node: '>=0.6'} | ||
4557 | + dependencies: | ||
4558 | + side-channel: 1.0.4 | ||
4559 | + dev: false | ||
4560 | + | ||
4413 | /queue-microtask/1.2.3: | 4561 | /queue-microtask/1.2.3: |
4414 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} | 4562 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} |
4415 | dev: true | 4563 | dev: true |
@@ -4487,6 +4635,11 @@ packages: | @@ -4487,6 +4635,11 @@ packages: | ||
4487 | engines: {node: '>=8'} | 4635 | engines: {node: '>=8'} |
4488 | dev: true | 4636 | dev: true |
4489 | 4637 | ||
4638 | + /relateurl/0.2.7: | ||
4639 | + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} | ||
4640 | + engines: {node: '>= 0.10'} | ||
4641 | + dev: true | ||
4642 | + | ||
4490 | /request-light/0.5.8: | 4643 | /request-light/0.5.8: |
4491 | resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} | 4644 | resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} |
4492 | dev: true | 4645 | dev: true |
@@ -4686,7 +4839,6 @@ packages: | @@ -4686,7 +4839,6 @@ packages: | ||
4686 | call-bind: 1.0.2 | 4839 | call-bind: 1.0.2 |
4687 | get-intrinsic: 1.1.2 | 4840 | get-intrinsic: 1.1.2 |
4688 | object-inspect: 1.12.2 | 4841 | object-inspect: 1.12.2 |
4689 | - dev: true | ||
4690 | 4842 | ||
4691 | /signal-exit/3.0.7: | 4843 | /signal-exit/3.0.7: |
4692 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} | 4844 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} |
@@ -4723,6 +4875,13 @@ packages: | @@ -4723,6 +4875,13 @@ packages: | ||
4723 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} | 4875 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} |
4724 | engines: {node: '>=0.10.0'} | 4876 | engines: {node: '>=0.10.0'} |
4725 | 4877 | ||
4878 | + /source-map-support/0.5.21: | ||
4879 | + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} | ||
4880 | + dependencies: | ||
4881 | + buffer-from: 1.1.2 | ||
4882 | + source-map: 0.6.1 | ||
4883 | + dev: true | ||
4884 | + | ||
4726 | /source-map/0.6.1: | 4885 | /source-map/0.6.1: |
4727 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} | 4886 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} |
4728 | engines: {node: '>=0.10.0'} | 4887 | engines: {node: '>=0.10.0'} |
@@ -4853,6 +5012,17 @@ packages: | @@ -4853,6 +5012,17 @@ packages: | ||
4853 | resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} | 5012 | resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} |
4854 | dev: true | 5013 | dev: true |
4855 | 5014 | ||
5015 | + /terser/5.16.4: | ||
5016 | + resolution: {integrity: sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==} | ||
5017 | + engines: {node: '>=10'} | ||
5018 | + hasBin: true | ||
5019 | + dependencies: | ||
5020 | + '@jridgewell/source-map': 0.3.2 | ||
5021 | + acorn: 8.7.1 | ||
5022 | + commander: 2.20.3 | ||
5023 | + source-map-support: 0.5.21 | ||
5024 | + dev: true | ||
5025 | + | ||
4856 | /text-extensions/1.9.0: | 5026 | /text-extensions/1.9.0: |
4857 | resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} | 5027 | resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} |
4858 | engines: {node: '>=0.10'} | 5028 | engines: {node: '>=0.10'} |
@@ -4965,7 +5135,6 @@ packages: | @@ -4965,7 +5135,6 @@ packages: | ||
4965 | 5135 | ||
4966 | /tslib/2.3.0: | 5136 | /tslib/2.3.0: |
4967 | resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} | 5137 | resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} |
4968 | - dev: true | ||
4969 | 5138 | ||
4970 | /tslib/2.4.0: | 5139 | /tslib/2.4.0: |
4971 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} | 5140 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} |
@@ -5017,7 +5186,6 @@ packages: | @@ -5017,7 +5186,6 @@ packages: | ||
5017 | resolution: {integrity: sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==} | 5186 | resolution: {integrity: sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==} |
5018 | engines: {node: '>=4.2.0'} | 5187 | engines: {node: '>=4.2.0'} |
5019 | hasBin: true | 5188 | hasBin: true |
5020 | - dev: true | ||
5021 | 5189 | ||
5022 | /typescript/4.7.3: | 5190 | /typescript/4.7.3: |
5023 | resolution: {integrity: sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==} | 5191 | resolution: {integrity: sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==} |
@@ -5137,6 +5305,26 @@ packages: | @@ -5137,6 +5305,26 @@ packages: | ||
5137 | - supports-color | 5305 | - supports-color |
5138 | dev: true | 5306 | dev: true |
5139 | 5307 | ||
5308 | + /vite-plugin-html/3.2.0_vite@2.9.9: | ||
5309 | + resolution: {integrity: sha512-2VLCeDiHmV/BqqNn5h2V+4280KRgQzCFN47cst3WiNK848klESPQnzuC3okH5XHtgwHH/6s1Ho/YV6yIO0pgoQ==} | ||
5310 | + peerDependencies: | ||
5311 | + vite: '>=2.0.0' | ||
5312 | + dependencies: | ||
5313 | + '@rollup/pluginutils': 4.2.1 | ||
5314 | + colorette: 2.0.19 | ||
5315 | + connect-history-api-fallback: 1.6.0 | ||
5316 | + consola: 2.15.3 | ||
5317 | + dotenv: 16.0.3 | ||
5318 | + dotenv-expand: 8.0.3 | ||
5319 | + ejs: 3.1.8 | ||
5320 | + fast-glob: 3.2.11 | ||
5321 | + fs-extra: 10.1.0 | ||
5322 | + html-minifier-terser: 6.1.0 | ||
5323 | + node-html-parser: 5.4.2 | ||
5324 | + pathe: 0.2.0 | ||
5325 | + vite: 2.9.9_sass@1.52.3 | ||
5326 | + dev: true | ||
5327 | + | ||
5140 | /vite-plugin-importer/0.2.5: | 5328 | /vite-plugin-importer/0.2.5: |
5141 | resolution: {integrity: sha512-6OtqJmVwnfw8+B4OIh7pIdXs+jLkN7g5PIqmZdpgrMYjIFMiZrcMB1zlyUQSTokKGC90KwXviO/lq1hcUBUG3Q==} | 5329 | resolution: {integrity: sha512-6OtqJmVwnfw8+B4OIh7pIdXs+jLkN7g5PIqmZdpgrMYjIFMiZrcMB1zlyUQSTokKGC90KwXviO/lq1hcUBUG3Q==} |
5142 | dependencies: | 5330 | dependencies: |
@@ -5437,7 +5625,6 @@ packages: | @@ -5437,7 +5625,6 @@ packages: | ||
5437 | '@vue/runtime-dom': 3.2.37 | 5625 | '@vue/runtime-dom': 3.2.37 |
5438 | '@vue/server-renderer': 3.2.37_vue@3.2.37 | 5626 | '@vue/server-renderer': 3.2.37_vue@3.2.37 |
5439 | '@vue/shared': 3.2.37 | 5627 | '@vue/shared': 3.2.37 |
5440 | - dev: false | ||
5441 | 5628 | ||
5442 | /vue3-lazyload/0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae: | 5629 | /vue3-lazyload/0.2.5-beta_2yymnzrok6eda47acnj2yjm3ae: |
5443 | resolution: {integrity: sha512-GVhJfL9Hcu+AvWsYmUwODivvt+gzpT0ztgAzZaUduoiTaGCv/qzhr0VwAQXfjGF3XFYFyOJsHlAi3/WE0P8XTQ==} | 5630 | resolution: {integrity: sha512-GVhJfL9Hcu+AvWsYmUwODivvt+gzpT0ztgAzZaUduoiTaGCv/qzhr0VwAQXfjGF3XFYFyOJsHlAi3/WE0P8XTQ==} |
@@ -5603,4 +5790,3 @@ packages: | @@ -5603,4 +5790,3 @@ packages: | ||
5603 | resolution: {integrity: sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==} | 5790 | resolution: {integrity: sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==} |
5604 | dependencies: | 5791 | dependencies: |
5605 | tslib: 2.3.0 | 5792 | tslib: 2.3.0 |
5606 | - dev: true |
src/api/external/sys/model/jwtModel.ts
0 → 100644
src/api/external/sys/model/userModel.ts
0 → 100644
1 | +/** | ||
2 | + * @description: Login interface parameters | ||
3 | + */ | ||
4 | +export interface LoginParams { | ||
5 | + username: string; | ||
6 | + password: string; | ||
7 | +} | ||
8 | +export interface SmsLoginParams { | ||
9 | + phoneNumber: string; | ||
10 | + code: string; | ||
11 | +} | ||
12 | +export interface RefreshTokenParams { | ||
13 | + refreshToken: string; | ||
14 | +} | ||
15 | + | ||
16 | +export interface RoleInfo { | ||
17 | + roleName: string; | ||
18 | + value: string; | ||
19 | +} | ||
20 | + | ||
21 | +/** | ||
22 | + * @description: Login interface return value | ||
23 | + */ | ||
24 | +export interface LoginResultModel { | ||
25 | + token: string; | ||
26 | + refreshToken: string; | ||
27 | +} | ||
28 | + | ||
29 | +/** | ||
30 | + * @description: Get user information return value | ||
31 | + */ | ||
32 | +export interface GetUserInfoModel { | ||
33 | + roles: RoleInfo[]; | ||
34 | + // 用户id | ||
35 | + userId: string | number; | ||
36 | + // 用户名 | ||
37 | + username: string; | ||
38 | + // 真实名字 | ||
39 | + realName: string; | ||
40 | + // 头像 | ||
41 | + avatar: string; | ||
42 | + // 介绍 | ||
43 | + desc?: string; | ||
44 | +} | ||
45 | +export interface UserInfoModel { | ||
46 | + userId: string | number; | ||
47 | + username: string; | ||
48 | + realName: string; | ||
49 | + avatar: string; | ||
50 | + tenantCode: string; | ||
51 | + tenantName: string; | ||
52 | + roles: string[]; | ||
53 | + plainRoles?: PlainRoleInfo[]; | ||
54 | +} | ||
55 | + | ||
56 | +export interface PlainRoleInfo { | ||
57 | + roleName: string; | ||
58 | + roleId: string; | ||
59 | +} |
src/api/external/sys/user.ts
0 → 100644
1 | +import { defHttp } from '@/utils/external/http/axios'; | ||
2 | +import { | ||
3 | + LoginParams, | ||
4 | + LoginResultModel, | ||
5 | + GetUserInfoModel, | ||
6 | + UserInfoModel, | ||
7 | + RefreshTokenParams, | ||
8 | + SmsLoginParams, | ||
9 | +} from './model/userModel'; | ||
10 | + | ||
11 | +import type { ErrorMessageMode } from '/#/external/axios'; | ||
12 | + | ||
13 | +enum Api { | ||
14 | + Login = '/auth/login', | ||
15 | + SmsCodeLogin = '/auth/code/login', | ||
16 | + Logout = '/logout', | ||
17 | + GetUserInfo = '/user', | ||
18 | + GetMyInfo = '/user/me/info', | ||
19 | + GetPermCode = '/role/me/permissions', | ||
20 | + RefreshToken = '/auth/token', | ||
21 | + SendLoginSmsCode = '/noauth/send_login_code/', | ||
22 | + ResetCode = '/noauth/reset_code/', | ||
23 | + ResetPassword = '/noauth/reset/', | ||
24 | +} | ||
25 | + | ||
26 | +/** | ||
27 | + * @description: user login api | ||
28 | + */ | ||
29 | +export function loginApi(params: LoginParams, mode: ErrorMessageMode = 'modal') { | ||
30 | + return defHttp.post<LoginResultModel>( | ||
31 | + { | ||
32 | + url: Api.Login, | ||
33 | + params, | ||
34 | + }, | ||
35 | + { | ||
36 | + errorMessageMode: mode, | ||
37 | + joinPrefix: false, | ||
38 | + } | ||
39 | + ); | ||
40 | +} | ||
41 | +export function getMyInfo() { | ||
42 | + return defHttp.get<UserInfoModel>({ url: Api.GetMyInfo }); | ||
43 | +} | ||
44 | +/** | ||
45 | + * @description: getUserInfo | ||
46 | + */ | ||
47 | +export function getUserInfo() { | ||
48 | + return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }); | ||
49 | +} | ||
50 | + | ||
51 | +export function getPermCode() { | ||
52 | + return defHttp.get<string[]>({ url: Api.GetPermCode }); | ||
53 | +} | ||
54 | +export async function SendLoginSmsCode(phoneNumber: string) { | ||
55 | + return await defHttp.post<boolean>({ url: Api.SendLoginSmsCode + phoneNumber }); | ||
56 | +} | ||
57 | +export function doLogout() { | ||
58 | + // return defHttp.get({ url: Api.Logout }); | ||
59 | +} | ||
60 | +export function doRefreshToken(params: RefreshTokenParams) { | ||
61 | + return defHttp.post<LoginResultModel>( | ||
62 | + { | ||
63 | + url: Api.RefreshToken, | ||
64 | + params, | ||
65 | + }, | ||
66 | + { | ||
67 | + joinPrefix: false, | ||
68 | + } | ||
69 | + ); | ||
70 | +} | ||
71 | +export function smsCodeLoginApi(params: SmsLoginParams, mode: ErrorMessageMode = 'modal') { | ||
72 | + return defHttp.post<LoginResultModel>( | ||
73 | + { | ||
74 | + url: Api.SmsCodeLogin, | ||
75 | + params, | ||
76 | + }, | ||
77 | + { | ||
78 | + errorMessageMode: mode, | ||
79 | + } | ||
80 | + ); | ||
81 | +} | ||
82 | + | ||
83 | +export const getUserToken = (id: string) => { | ||
84 | + return defHttp.get<Record<'token' | 'refreshToken', string>>({ | ||
85 | + url: `/third/login/id/${id}`, | ||
86 | + }); | ||
87 | +}; |
src/enums/external/cacheEnum.ts
0 → 100644
1 | +// token key | ||
2 | +export const TOKEN_KEY = 'TOKEN__'; | ||
3 | + | ||
4 | +export const JWT_TOKEN_KEY = 'JWT_TOKEN'; | ||
5 | + | ||
6 | +export const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN'; | ||
7 | + | ||
8 | +export const LOCALE_KEY = 'LOCALE__'; | ||
9 | + | ||
10 | +// user info key | ||
11 | +export const USER_INFO_KEY = 'USER__INFO__'; | ||
12 | + | ||
13 | +// role info key | ||
14 | +export const ROLES_KEY = 'ROLES__KEY'; | ||
15 | + | ||
16 | +// project config key | ||
17 | +export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__'; | ||
18 | + | ||
19 | +// lock info | ||
20 | +export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'; | ||
21 | + | ||
22 | +export const MULTIPLE_TABS_KEY = 'MULTIPLE_TABS__KEY__'; | ||
23 | + | ||
24 | +export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE__'; | ||
25 | + | ||
26 | +// base global local key | ||
27 | +export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'; | ||
28 | + | ||
29 | +// base global session key | ||
30 | +export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY__'; | ||
31 | + | ||
32 | +export const PLATFORM = 'PLATFORM'; | ||
33 | + | ||
34 | +export const MENU_LIST = 'MENU_LIST'; | ||
35 | +export enum CacheTypeEnum { | ||
36 | + SESSION, | ||
37 | + LOCAL, | ||
38 | +} |
src/enums/external/httpEnum.ts
0 → 100644
1 | +/** | ||
2 | + * @description: Request result set | ||
3 | + */ | ||
4 | +export enum ResultEnum { | ||
5 | + SUCCESS = 0, | ||
6 | + ERROR = 1, | ||
7 | + TIMEOUT = 401, | ||
8 | + TYPE = 'success', | ||
9 | +} | ||
10 | + | ||
11 | +/** | ||
12 | + * @description: request method | ||
13 | + */ | ||
14 | +export enum RequestEnum { | ||
15 | + GET = 'GET', | ||
16 | + POST = 'POST', | ||
17 | + PUT = 'PUT', | ||
18 | + DELETE = 'DELETE', | ||
19 | +} | ||
20 | + | ||
21 | +/** | ||
22 | + * @description: contentTyp | ||
23 | + */ | ||
24 | +export enum ContentTypeEnum { | ||
25 | + // json | ||
26 | + JSON = 'application/json;charset=UTF-8', | ||
27 | + // form-data qs | ||
28 | + FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8', | ||
29 | + // form-data upload | ||
30 | + FORM_DATA = 'multipart/form-data;charset=UTF-8', | ||
31 | +} |
src/enums/external/pageEnum.ts
0 → 100644
1 | +export const PageEnum = { | ||
2 | + SYSTEM_PASSWORD: '/system/changePassword', | ||
3 | + // basic login path | ||
4 | + BASE_LOGIN: '/login', | ||
5 | + // basic home path | ||
6 | + // BASE_HOME: isDolang.value == '/dashboard/workbench' ? '/dashboard/workbench' : isDolang.value, | ||
7 | + BASE_HOME: '/dashboard/workbench', | ||
8 | + // error page path | ||
9 | + ERROR_PAGE: '/exception', | ||
10 | + // error log page path | ||
11 | + ERROR_LOG_PAGE: '/error-log/list', | ||
12 | + //消息配置 | ||
13 | + MESSAGE_CONFIG: '/message/config', | ||
14 | + //设备配置 | ||
15 | + DEVICE_PROFILE: '/product/profiles', | ||
16 | + DEVICE_LIST: '/device/list', | ||
17 | +}; |
src/enums/external/roleEnum.ts
0 → 100644
1 | +export enum RoleEnum { | ||
2 | + SYS_ADMIN = 'SYS_ADMIN', | ||
3 | + PLATFORM_ADMIN = 'PLATFORM_ADMIN', | ||
4 | + TENANT_ADMIN = 'TENANT_ADMIN', | ||
5 | + CUSTOMER_USER = 'CUSTOMER_USER', | ||
6 | +} | ||
7 | + | ||
8 | +export function isAdmin(role: string) { | ||
9 | + if (role === RoleEnum.SYS_ADMIN || role === RoleEnum.PLATFORM_ADMIN) { | ||
10 | + return true; | ||
11 | + } else if (role === RoleEnum.TENANT_ADMIN || role === RoleEnum.CUSTOMER_USER) { | ||
12 | + return false; | ||
13 | + } | ||
14 | +} | ||
15 | +// 按钮级权限控制,只针对客户 | ||
16 | +export function authBtn(role: string): boolean { | ||
17 | + return role !== RoleEnum.CUSTOMER_USER | ||
18 | +} |
src/hooks/external/setting/index.ts
0 → 100644
1 | +import type { GlobConfig } from '/#/external/config'; | ||
2 | +import { getAppEnvConfig } from '@/utils/external/env'; | ||
3 | + | ||
4 | +export const useGlobSetting = (): Readonly<GlobConfig> => { | ||
5 | + const { | ||
6 | + VITE_GLOB_APP_TITLE, | ||
7 | + VITE_GLOB_API_URL, | ||
8 | + VITE_GLOB_APP_SHORT_NAME, | ||
9 | + VITE_GLOB_API_URL_PREFIX, | ||
10 | + VITE_GLOB_UPLOAD_URL, | ||
11 | + VITE_GLOB_CONFIGURATION, | ||
12 | + VITE_GLOB_WEB_SOCKET, | ||
13 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
14 | + VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME, | ||
15 | + VITE_GLOB_ALARM_NOTIFY_DURATION, | ||
16 | + } = getAppEnvConfig(); | ||
17 | + | ||
18 | + if (!/[a-zA-Z_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { | ||
19 | + console.warn( | ||
20 | + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` | ||
21 | + ); | ||
22 | + } | ||
23 | + | ||
24 | + // Take global configuration | ||
25 | + const glob: Readonly<GlobConfig> = { | ||
26 | + title: VITE_GLOB_APP_TITLE, | ||
27 | + apiUrl: VITE_GLOB_API_URL, | ||
28 | + shortName: VITE_GLOB_APP_SHORT_NAME, | ||
29 | + urlPrefix: VITE_GLOB_API_URL_PREFIX, | ||
30 | + uploadUrl: VITE_GLOB_UPLOAD_URL, | ||
31 | + configurationPrefix: VITE_GLOB_CONFIGURATION, | ||
32 | + socketUrl: VITE_GLOB_WEB_SOCKET, | ||
33 | + securityPolicy: VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
34 | + alarmNotifyDuration: VITE_GLOB_ALARM_NOTIFY_DURATION, | ||
35 | + alarmPollingInterval: VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME, | ||
36 | + }; | ||
37 | + return glob as Readonly<GlobConfig>; | ||
38 | +}; |
src/hooks/external/useMessage.ts
0 → 100644
src/settings/external/encryptionSetting.ts
0 → 100644
1 | +import { isDevMode } from '@/utils/external/env'; | ||
2 | + | ||
3 | +// System default cache time, in seconds | ||
4 | +export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7; | ||
5 | + | ||
6 | +// aes encryption key | ||
7 | +export const cacheCipher = { | ||
8 | + key: '_11111000001111@', | ||
9 | + iv: '@11111000001111_', | ||
10 | +}; | ||
11 | + | ||
12 | +// Whether the system cache is encrypted using aes | ||
13 | +export const enableStorageEncryption = !isDevMode(); |
src/settings/external/projectSetting.ts
0 → 100644
1 | +import type { ProjectConfig } from '/#/external/config'; | ||
2 | +import { CacheTypeEnum } from '@/enums/external/cacheEnum'; | ||
3 | + | ||
4 | + | ||
5 | +// ! You need to clear the browser cache after the change | ||
6 | +const setting: Partial<ProjectConfig> = { | ||
7 | + // Whether to show the configuration button | ||
8 | + showSettingButton: true, | ||
9 | + | ||
10 | + // Whether to show the theme switch button | ||
11 | + showDarkModeToggle: true, | ||
12 | + | ||
13 | + // Website gray mode, open for possible mourning dates | ||
14 | + grayMode: false, | ||
15 | + | ||
16 | + // Color Weakness Mode | ||
17 | + colorWeak: false, | ||
18 | + | ||
19 | + // Whether to cancel the menu, the top, the multi-tab page display, for possible embedded in other systems | ||
20 | + fullContent: false, | ||
21 | + | ||
22 | + | ||
23 | + // Whether to display the logo | ||
24 | + showLogo: true, | ||
25 | + | ||
26 | + // Whether to show footer | ||
27 | + showFooter: false, | ||
28 | + | ||
29 | + // Whether to enable KeepAlive cache is best to close during development, otherwise the cache needs to be cleared every time | ||
30 | + openKeepAlive: true, | ||
31 | + | ||
32 | + // Automatic screen lock time, 0 does not lock the screen. Unit minute default 0 | ||
33 | + lockTime: 0, | ||
34 | + | ||
35 | + // Whether to show breadcrumbs | ||
36 | + showBreadCrumb: false, | ||
37 | + | ||
38 | + // Whether to show the breadcrumb icon | ||
39 | + showBreadCrumbIcon: false, | ||
40 | + | ||
41 | + // Use error-handler-plugin | ||
42 | + useErrorHandle: false, | ||
43 | + | ||
44 | + // Whether to open back to top | ||
45 | + useOpenBackTop: true, | ||
46 | + | ||
47 | + // Is it possible to embed iframe pages | ||
48 | + canEmbedIFramePage: true, | ||
49 | + | ||
50 | + // Whether to delete unclosed messages and notify when switching the interface | ||
51 | + closeMessageOnSwitch: true, | ||
52 | + | ||
53 | + // Whether to cancel the http request that has been sent but not responded when switching the interface. | ||
54 | + // If it is enabled, I want to overwrite a single interface. Can be set in a separate interface | ||
55 | + removeAllHttpPending: false, | ||
56 | +}; | ||
57 | + | ||
58 | +export default setting; |
src/store/external/module/user.ts
0 → 100644
1 | +import type { UserInfo, UserUpdateInfo } from '/#/external/store'; | ||
2 | +import type { ErrorMessageMode } from '/#/external/axios'; | ||
3 | +import { defineStore } from 'pinia'; | ||
4 | +import { pinia as store } from '@/store'; | ||
5 | +import { RoleEnum } from '@/enums/external/roleEnum'; | ||
6 | +import { PageEnum } from '@/enums/external/pageEnum'; | ||
7 | +import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, USER_INFO_KEY } from '@/enums/external/cacheEnum'; | ||
8 | +import { getAuthCache, setAuthCache } from '@/utils/external/auth'; | ||
9 | +import { | ||
10 | + LoginParams, | ||
11 | + LoginResultModel, | ||
12 | + RefreshTokenParams, | ||
13 | + SmsLoginParams, | ||
14 | +} from '@/api/external/sys/model/userModel'; | ||
15 | +import { doRefreshToken, loginApi } from '@/api/external/sys/user'; | ||
16 | +import router from '@/router'; | ||
17 | +import { createLocalStorage } from '@/utils/external/cache'; | ||
18 | +import { useI18n } from 'vue-i18n'; | ||
19 | +import { useDialog } from 'naive-ui'; | ||
20 | + | ||
21 | +interface UserState { | ||
22 | + platInfo: any; | ||
23 | + enterPriseInfo: any; | ||
24 | + userInfo: Nullable<UserInfo>; | ||
25 | + userUpdateInfo?: Nullable<UserUpdateInfo>; | ||
26 | + token?: string; | ||
27 | + roleList: RoleEnum[]; | ||
28 | + sessionTimeout?: boolean; | ||
29 | + lastUpdateTime: number; | ||
30 | + jwtToken?: string; | ||
31 | + refreshToken?: string; | ||
32 | + outTarget?: string; | ||
33 | +} | ||
34 | + | ||
35 | +const storage = createLocalStorage(); | ||
36 | +export const useUserStore = defineStore({ | ||
37 | + id: 'app-user', | ||
38 | + state: (): UserState => ({ | ||
39 | + //平台信息 | ||
40 | + platInfo: storage.get('platformInfo') || null, | ||
41 | + enterPriseInfo: storage.get('enterPriseInfo') || null, | ||
42 | + | ||
43 | + // user info | ||
44 | + userInfo: null, | ||
45 | + userUpdateInfo: null, | ||
46 | + // token | ||
47 | + jwtToken: undefined, | ||
48 | + //refresh Token | ||
49 | + refreshToken: undefined, | ||
50 | + // roleList | ||
51 | + roleList: [], | ||
52 | + // Whether the login expired | ||
53 | + sessionTimeout: false, | ||
54 | + // Last fetch time | ||
55 | + lastUpdateTime: 0, | ||
56 | + }), | ||
57 | + | ||
58 | + getters: { | ||
59 | + getPlatInfo(): any { | ||
60 | + return this.platInfo; | ||
61 | + }, | ||
62 | + getUserInfo(): UserInfo { | ||
63 | + return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {}; | ||
64 | + }, | ||
65 | + | ||
66 | + getUserUpdateInfo(): UserUpdateInfo { | ||
67 | + return this.userUpdateInfo || {}; | ||
68 | + }, | ||
69 | + getJwtToken(): string { | ||
70 | + return this.jwtToken || getAuthCache<string>(JWT_TOKEN_KEY); | ||
71 | + }, | ||
72 | + getRefreshToken(): string { | ||
73 | + return this.refreshToken || getAuthCache<string>(REFRESH_TOKEN_KEY); | ||
74 | + }, | ||
75 | + getRoleList(): RoleEnum[] { | ||
76 | + return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY); | ||
77 | + }, | ||
78 | + getSessionTimeout(): boolean { | ||
79 | + return !!this.sessionTimeout; | ||
80 | + }, | ||
81 | + getLastUpdateTime(): number { | ||
82 | + return this.lastUpdateTime; | ||
83 | + }, | ||
84 | + }, | ||
85 | + actions: { | ||
86 | + setPlatInfo(platInfo: any) { | ||
87 | + this.platInfo = platInfo; | ||
88 | + }, | ||
89 | + setEnterPriseInfo(enterPriseInfo: any) { | ||
90 | + this.enterPriseInfo = enterPriseInfo; | ||
91 | + }, | ||
92 | + | ||
93 | + storeToken(jwtToken: string, refreshToken: string) { | ||
94 | + this.jwtToken = jwtToken; | ||
95 | + this.refreshToken = refreshToken; | ||
96 | + setAuthCache(JWT_TOKEN_KEY, jwtToken); | ||
97 | + setAuthCache(REFRESH_TOKEN_KEY, refreshToken); | ||
98 | + }, | ||
99 | + setToken(info: string | undefined) { | ||
100 | + this.jwtToken = info; | ||
101 | + setAuthCache(JWT_TOKEN_KEY, info); | ||
102 | + }, | ||
103 | + setRoleList(roleList: RoleEnum[]) { | ||
104 | + this.roleList = roleList; | ||
105 | + setAuthCache(ROLES_KEY, roleList); | ||
106 | + }, | ||
107 | + setUserInfo(info: UserInfo | null) { | ||
108 | + this.userInfo = info; | ||
109 | + this.lastUpdateTime = new Date().getTime(); | ||
110 | + setAuthCache(USER_INFO_KEY, info); | ||
111 | + }, | ||
112 | + setUserUpdateInfo(info: UserUpdateInfo) { | ||
113 | + this.userUpdateInfo = info; | ||
114 | + }, | ||
115 | + setSessionTimeout(flag: boolean) { | ||
116 | + this.sessionTimeout = flag; | ||
117 | + }, | ||
118 | + resetState() { | ||
119 | + this.userInfo = null; | ||
120 | + this.token = ''; | ||
121 | + this.roleList = []; | ||
122 | + this.sessionTimeout = false; | ||
123 | + }, | ||
124 | + /** | ||
125 | + * @description: login | ||
126 | + */ | ||
127 | + async login( | ||
128 | + params: LoginParams & { | ||
129 | + goHome?: boolean; | ||
130 | + mode?: ErrorMessageMode; | ||
131 | + } | ||
132 | + ) { | ||
133 | + try { | ||
134 | + const { goHome = true, mode, ...loginParams } = params; | ||
135 | + const data = await loginApi(loginParams, mode); | ||
136 | + } catch (error) { | ||
137 | + return Promise.reject(error); | ||
138 | + } | ||
139 | + }, | ||
140 | + async process(data: LoginResultModel, goHome?: boolean) { | ||
141 | + | ||
142 | + }, | ||
143 | + async smsCodelogin( | ||
144 | + params: SmsLoginParams & { | ||
145 | + goHome?: boolean; | ||
146 | + mode?: ErrorMessageMode; | ||
147 | + } | ||
148 | + ) { | ||
149 | + | ||
150 | + }, | ||
151 | + async getMyUserInfoAction() { | ||
152 | + | ||
153 | + }, | ||
154 | + /** | ||
155 | + * @description: logout | ||
156 | + */ | ||
157 | + async logout(goLogin = false) { | ||
158 | + this.setToken(undefined); | ||
159 | + this.setSessionTimeout(false); | ||
160 | + setAuthCache(REFRESH_TOKEN_KEY, undefined); | ||
161 | + this.setUserInfo(null); | ||
162 | + goLogin && router.push(PageEnum.BASE_LOGIN); | ||
163 | + window.localStorage.clear(); | ||
164 | + window.localStorage.removeItem('updateUserInfo'); | ||
165 | + }, | ||
166 | + | ||
167 | + async doRefresh() { | ||
168 | + try { | ||
169 | + const req = { refreshToken: this.refreshToken } as RefreshTokenParams; | ||
170 | + const data = await doRefreshToken(req); | ||
171 | + const { token, refreshToken } = data; | ||
172 | + this.storeToken(token, refreshToken); | ||
173 | + } catch (error) { | ||
174 | + this.logout(); | ||
175 | + } | ||
176 | + }, | ||
177 | + | ||
178 | + /** | ||
179 | + * @description: Confirm before logging out | ||
180 | + */ | ||
181 | + confirmLoginOut() { | ||
182 | + const { warning } = useDialog(); | ||
183 | + const { t } = useI18n(); | ||
184 | + warning({ | ||
185 | + type: 'warning', | ||
186 | + title: '温馨提醒', | ||
187 | + content: '是否确认退出系统?', | ||
188 | + onPositiveClick: async () => { | ||
189 | + await this.logout(true); | ||
190 | + }, | ||
191 | + }); | ||
192 | + }, | ||
193 | + }, | ||
194 | +}); | ||
195 | + | ||
196 | +// Need to be used outside the setup | ||
197 | +export function useUserStoreWithOut() { | ||
198 | + return useUserStore(store); | ||
199 | +} |
src/utils/external/auth/index.ts
0 → 100644
1 | +import { Persistent, BasicKeys } from '@/utils/external/cache/persistent'; | ||
2 | +import { CacheTypeEnum } from '@/enums/external/cacheEnum'; | ||
3 | +import projectSetting from '@/settings/external/projectSetting'; | ||
4 | +import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum'; | ||
5 | + | ||
6 | +const { permissionCacheType } = projectSetting; | ||
7 | +const isLocal = permissionCacheType === CacheTypeEnum.LOCAL; | ||
8 | + | ||
9 | +export function getAuthCache<T>(key: BasicKeys) { | ||
10 | + const fn = isLocal ? Persistent.getLocal : Persistent.getSession; | ||
11 | + return fn(key) as T; | ||
12 | +} | ||
13 | + | ||
14 | +export function setAuthCache(key: BasicKeys, value: any) { | ||
15 | + const fn = isLocal ? Persistent.setLocal : Persistent.setSession; | ||
16 | + return fn(key, value, true); | ||
17 | +} | ||
18 | + | ||
19 | +export function clearAuthCache(immediate = true) { | ||
20 | + const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession; | ||
21 | + return fn(immediate); | ||
22 | +} | ||
23 | +export function getJwtToken() { | ||
24 | + return getAuthCache(JWT_TOKEN_KEY); | ||
25 | +} | ||
26 | +export function getRefreshToken() { | ||
27 | + return getAuthCache(REFRESH_TOKEN_KEY); | ||
28 | +} |
src/utils/external/cache/index.ts
0 → 100644
1 | +import { getStorageShortName } from '@/utils/external/env'; | ||
2 | +import { createStorage as create, CreateStorageParams } from './storageCache'; | ||
3 | +import { enableStorageEncryption, DEFAULT_CACHE_TIME } from '@/settings/external/encryptionSetting'; | ||
4 | + | ||
5 | + | ||
6 | +export type Options = Partial<CreateStorageParams>; | ||
7 | + | ||
8 | +const createOptions = (storage: Storage, options: Options = {}): Options => { | ||
9 | + return { | ||
10 | + // No encryption in debug mode | ||
11 | + hasEncrypt: enableStorageEncryption, | ||
12 | + storage, | ||
13 | + prefixKey: getStorageShortName(), | ||
14 | + ...options, | ||
15 | + }; | ||
16 | +}; | ||
17 | + | ||
18 | +export const WebStorage = create(createOptions(sessionStorage)); | ||
19 | + | ||
20 | +export const createStorage = (storage: Storage = sessionStorage, options: Options = {}) => { | ||
21 | + return create(createOptions(storage, options)); | ||
22 | +}; | ||
23 | + | ||
24 | +export const createSessionStorage = (options: Options = {}) => { | ||
25 | + return createStorage(sessionStorage, { ...options, timeout: DEFAULT_CACHE_TIME }); | ||
26 | +}; | ||
27 | + | ||
28 | +export const createLocalStorage = (options: Options = {}) => { | ||
29 | + return createStorage(localStorage, { ...options, timeout: DEFAULT_CACHE_TIME }); | ||
30 | +}; | ||
31 | + | ||
32 | +export default WebStorage; |
src/utils/external/cache/memory.ts
0 → 100644
1 | +export interface Cache<V = any> { | ||
2 | + value?: V; | ||
3 | + timeoutId?: ReturnType<typeof setTimeout>; | ||
4 | + time?: number; | ||
5 | + alive?: number; | ||
6 | +} | ||
7 | + | ||
8 | +const NOT_ALIVE = 0; | ||
9 | + | ||
10 | +export class Memory<T = any, V = any> { | ||
11 | + private cache: { [key in keyof T]?: Cache<V> } = {}; | ||
12 | + private alive: number; | ||
13 | + | ||
14 | + constructor(alive = NOT_ALIVE) { | ||
15 | + // Unit second | ||
16 | + this.alive = alive * 1000; | ||
17 | + } | ||
18 | + | ||
19 | + get getCache() { | ||
20 | + return this.cache; | ||
21 | + } | ||
22 | + | ||
23 | + setCache(cache: { [key in keyof T]?: Cache<V> }) { | ||
24 | + this.cache = cache; | ||
25 | + } | ||
26 | + | ||
27 | + // get<K extends keyof T>(key: K) { | ||
28 | + // const item = this.getItem(key); | ||
29 | + // const time = item?.time; | ||
30 | + // if (!isNullOrUnDef(time) && time < new Date().getTime()) { | ||
31 | + // this.remove(key); | ||
32 | + // } | ||
33 | + // return item?.value ?? undefined; | ||
34 | + // } | ||
35 | + | ||
36 | + get<K extends keyof T>(key: K) { | ||
37 | + return this.cache[key]; | ||
38 | + } | ||
39 | + | ||
40 | + set<K extends keyof T>(key: K, value: V, expires?: number) { | ||
41 | + let item = this.get(key); | ||
42 | + | ||
43 | + if (!expires || (expires as number) <= 0) { | ||
44 | + expires = this.alive; | ||
45 | + } | ||
46 | + if (item) { | ||
47 | + if (item.timeoutId) { | ||
48 | + clearTimeout(item.timeoutId); | ||
49 | + item.timeoutId = undefined; | ||
50 | + } | ||
51 | + item.value = value; | ||
52 | + } else { | ||
53 | + item = { value, alive: expires }; | ||
54 | + this.cache[key] = item; | ||
55 | + } | ||
56 | + | ||
57 | + if (!expires) { | ||
58 | + return value; | ||
59 | + } | ||
60 | + const now = new Date().getTime(); | ||
61 | + item.time = now + this.alive; | ||
62 | + item.timeoutId = setTimeout( | ||
63 | + () => { | ||
64 | + this.remove(key); | ||
65 | + }, | ||
66 | + expires > now ? expires - now : expires | ||
67 | + ); | ||
68 | + | ||
69 | + return value; | ||
70 | + } | ||
71 | + | ||
72 | + remove<K extends keyof T>(key: K) { | ||
73 | + const item = this.get(key); | ||
74 | + Reflect.deleteProperty(this.cache, key); | ||
75 | + if (item) { | ||
76 | + clearTimeout(item.timeoutId!); | ||
77 | + return item.value; | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + resetCache(cache: { [K in keyof T]: Cache }) { | ||
82 | + Object.keys(cache).forEach((key) => { | ||
83 | + const k = key as any as keyof T; | ||
84 | + const item = cache[k]; | ||
85 | + if (item && item.time) { | ||
86 | + const now = new Date().getTime(); | ||
87 | + const expire = item.time; | ||
88 | + if (expire > now) { | ||
89 | + this.set(k, item.value, expire); | ||
90 | + } | ||
91 | + } | ||
92 | + }); | ||
93 | + } | ||
94 | + | ||
95 | + clear() { | ||
96 | + Object.keys(this.cache).forEach((key) => { | ||
97 | + const item: Cache<V> = this.cache[key as keyof T]!; | ||
98 | + item.timeoutId && clearTimeout(item.timeoutId); | ||
99 | + }); | ||
100 | + this.cache = {}; | ||
101 | + } | ||
102 | +} |
src/utils/external/cache/persistent.ts
0 → 100644
1 | +import type { LockInfo, UserInfo } from '/#/external/store'; | ||
2 | +import type { ProjectConfig } from '/#/external/config'; | ||
3 | +import type { RouteLocationNormalized } from 'vue-router'; | ||
4 | + | ||
5 | +import { createLocalStorage, createSessionStorage } from '@/utils/external/cache'; | ||
6 | +import { Memory } from './memory'; | ||
7 | +import { | ||
8 | + PLATFORM, | ||
9 | + TOKEN_KEY, | ||
10 | + JWT_TOKEN_KEY, | ||
11 | + REFRESH_TOKEN_KEY, | ||
12 | + USER_INFO_KEY, | ||
13 | + ROLES_KEY, | ||
14 | + LOCK_INFO_KEY, | ||
15 | + PROJ_CFG_KEY, | ||
16 | + APP_LOCAL_CACHE_KEY, | ||
17 | + APP_SESSION_CACHE_KEY, | ||
18 | + MULTIPLE_TABS_KEY, | ||
19 | + MENU_LIST, | ||
20 | +} from '@/enums/external/cacheEnum'; | ||
21 | +import { DEFAULT_CACHE_TIME } from '@/settings/external/encryptionSetting'; | ||
22 | +import { toRaw } from 'vue'; | ||
23 | +import omit from 'lodash/omit'; | ||
24 | +import pick from 'lodash/pick'; | ||
25 | + | ||
26 | +interface BasicStore { | ||
27 | + [PLATFORM]: Object; | ||
28 | + [TOKEN_KEY]: string | number | null | undefined; | ||
29 | + [JWT_TOKEN_KEY]: string | number | null | undefined; | ||
30 | + [REFRESH_TOKEN_KEY]: string | number | null | undefined; | ||
31 | + [USER_INFO_KEY]: UserInfo; | ||
32 | + [ROLES_KEY]: string[]; | ||
33 | + [LOCK_INFO_KEY]: LockInfo; | ||
34 | + [PROJ_CFG_KEY]: ProjectConfig; | ||
35 | + [MULTIPLE_TABS_KEY]: RouteLocationNormalized[]; | ||
36 | + [MENU_LIST]: any[]; | ||
37 | +} | ||
38 | + | ||
39 | +type LocalStore = BasicStore; | ||
40 | + | ||
41 | +type SessionStore = BasicStore; | ||
42 | + | ||
43 | +export type BasicKeys = keyof BasicStore; | ||
44 | +type LocalKeys = keyof LocalStore; | ||
45 | +type SessionKeys = keyof SessionStore; | ||
46 | + | ||
47 | +const ls = createLocalStorage(); | ||
48 | +const ss = createSessionStorage(); | ||
49 | + | ||
50 | +const localMemory = new Memory(DEFAULT_CACHE_TIME); | ||
51 | +const sessionMemory = new Memory(DEFAULT_CACHE_TIME); | ||
52 | + | ||
53 | +function initPersistentMemory() { | ||
54 | + const localCache = ls.get(APP_LOCAL_CACHE_KEY); | ||
55 | + const sessionCache = ss.get(APP_SESSION_CACHE_KEY); | ||
56 | + localCache && localMemory.resetCache(localCache); | ||
57 | + sessionCache && sessionMemory.resetCache(sessionCache); | ||
58 | +} | ||
59 | + | ||
60 | +export class Persistent { | ||
61 | + static getLocal<T>(key: LocalKeys) { | ||
62 | + return localMemory.get(key)?.value as Nullable<T>; | ||
63 | + } | ||
64 | + | ||
65 | + static setLocal(key: LocalKeys, value: LocalStore[LocalKeys], immediate = false): void { | ||
66 | + localMemory.set(key, toRaw(value)); | ||
67 | + immediate && ls.set(APP_LOCAL_CACHE_KEY, localMemory.getCache); | ||
68 | + } | ||
69 | + | ||
70 | + static removeLocal(key: LocalKeys, immediate = false): void { | ||
71 | + localMemory.remove(key); | ||
72 | + immediate && ls.set(APP_LOCAL_CACHE_KEY, localMemory.getCache); | ||
73 | + } | ||
74 | + | ||
75 | + static clearLocal(immediate = false): void { | ||
76 | + localMemory.clear(); | ||
77 | + immediate && ls.clear(); | ||
78 | + } | ||
79 | + | ||
80 | + static getSession<T>(key: SessionKeys) { | ||
81 | + return sessionMemory.get(key)?.value as Nullable<T>; | ||
82 | + } | ||
83 | + | ||
84 | + static setSession(key: SessionKeys, value: SessionStore[SessionKeys], immediate = false): void { | ||
85 | + sessionMemory.set(key, toRaw(value)); | ||
86 | + immediate && ss.set(APP_SESSION_CACHE_KEY, sessionMemory.getCache); | ||
87 | + } | ||
88 | + | ||
89 | + static removeSession(key: SessionKeys, immediate = false): void { | ||
90 | + sessionMemory.remove(key); | ||
91 | + immediate && ss.set(APP_SESSION_CACHE_KEY, sessionMemory.getCache); | ||
92 | + } | ||
93 | + static clearSession(immediate = false): void { | ||
94 | + sessionMemory.clear(); | ||
95 | + immediate && ss.clear(); | ||
96 | + } | ||
97 | + | ||
98 | + static clearAll(immediate = false) { | ||
99 | + sessionMemory.clear(); | ||
100 | + localMemory.clear(); | ||
101 | + if (immediate) { | ||
102 | + ls.clear(); | ||
103 | + ss.clear(); | ||
104 | + } | ||
105 | + } | ||
106 | +} | ||
107 | + | ||
108 | +window.addEventListener('beforeunload', function () { | ||
109 | + // TOKEN_KEY 在登录或注销时已经写入到storage了,此处为了解决同时打开多个窗口时token不同步的问题 | ||
110 | + // LOCK_INFO_KEY 在锁屏和解锁时写入,此处也不应修改 | ||
111 | + ls.set(APP_LOCAL_CACHE_KEY, { | ||
112 | + ...omit(localMemory.getCache, LOCK_INFO_KEY), | ||
113 | + ...pick(ls.get(APP_LOCAL_CACHE_KEY), [ | ||
114 | + TOKEN_KEY, | ||
115 | + JWT_TOKEN_KEY, | ||
116 | + REFRESH_TOKEN_KEY, | ||
117 | + USER_INFO_KEY, | ||
118 | + LOCK_INFO_KEY, | ||
119 | + ROLES_KEY, | ||
120 | + ]), | ||
121 | + }); | ||
122 | + ss.set(APP_SESSION_CACHE_KEY, { | ||
123 | + ...omit(sessionMemory.getCache, LOCK_INFO_KEY), | ||
124 | + ...pick(ss.get(APP_SESSION_CACHE_KEY), [ | ||
125 | + TOKEN_KEY, | ||
126 | + JWT_TOKEN_KEY, | ||
127 | + REFRESH_TOKEN_KEY, | ||
128 | + USER_INFO_KEY, | ||
129 | + LOCK_INFO_KEY, | ||
130 | + ROLES_KEY, | ||
131 | + ]), | ||
132 | + }); | ||
133 | +}); | ||
134 | + | ||
135 | +function storageChange(e: any) { | ||
136 | + const { key, newValue, oldValue } = e; | ||
137 | + | ||
138 | + if (!key) { | ||
139 | + Persistent.clearAll(); | ||
140 | + return; | ||
141 | + } | ||
142 | + | ||
143 | + if (!!newValue && !!oldValue) { | ||
144 | + if (APP_LOCAL_CACHE_KEY === key) { | ||
145 | + Persistent.clearLocal(); | ||
146 | + } | ||
147 | + if (APP_SESSION_CACHE_KEY === key) { | ||
148 | + Persistent.clearSession(); | ||
149 | + } | ||
150 | + } | ||
151 | +} | ||
152 | + | ||
153 | +window.addEventListener('storage', storageChange); | ||
154 | + | ||
155 | +initPersistentMemory(); |
src/utils/external/cache/storageCache.ts
0 → 100644
1 | +import { cacheCipher } from '@/settings/external/encryptionSetting'; | ||
2 | + | ||
3 | +import type { EncryptionParams } from '@/utils/external/cipher'; | ||
4 | + | ||
5 | +import { AesEncryption } from '@/utils/external/cipher'; | ||
6 | + | ||
7 | +import { isNullOrUnDef } from '@/utils/external/is'; | ||
8 | + | ||
9 | +export interface CreateStorageParams extends EncryptionParams { | ||
10 | + prefixKey: string; | ||
11 | + storage: Storage; | ||
12 | + hasEncrypt: boolean; | ||
13 | + timeout?: Nullable<number>; | ||
14 | +} | ||
15 | +export const createStorage = ({ | ||
16 | + prefixKey = '', | ||
17 | + storage = sessionStorage, | ||
18 | + key = cacheCipher.key, | ||
19 | + iv = cacheCipher.iv, | ||
20 | + timeout = null, | ||
21 | + hasEncrypt = true, | ||
22 | +}: Partial<CreateStorageParams> = {}) => { | ||
23 | + if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) { | ||
24 | + throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!'); | ||
25 | + } | ||
26 | + | ||
27 | + const encryption = new AesEncryption({ key, iv }); | ||
28 | + | ||
29 | + /** | ||
30 | + *Cache class | ||
31 | + *Construction parameters can be passed into sessionStorage, localStorage, | ||
32 | + * @class Cache | ||
33 | + * @example | ||
34 | + */ | ||
35 | + const WebStorage = class WebStorage { | ||
36 | + private storage: Storage; | ||
37 | + private prefixKey?: string; | ||
38 | + private encryption: AesEncryption; | ||
39 | + private hasEncrypt: boolean; | ||
40 | + /** | ||
41 | + * | ||
42 | + * @param {*} storage | ||
43 | + */ | ||
44 | + constructor() { | ||
45 | + this.storage = storage; | ||
46 | + this.prefixKey = prefixKey; | ||
47 | + this.encryption = encryption; | ||
48 | + this.hasEncrypt = hasEncrypt; | ||
49 | + } | ||
50 | + | ||
51 | + private getKey(key: string) { | ||
52 | + return `${this.prefixKey}${key}`.toUpperCase(); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * | ||
57 | + * Set cache | ||
58 | + * @param {string} key | ||
59 | + * @param {*} value | ||
60 | + * @expire Expiration time in seconds | ||
61 | + * @memberof Cache | ||
62 | + */ | ||
63 | + set(key: string, value: any, expire: number | null = timeout) { | ||
64 | + const stringData = JSON.stringify({ | ||
65 | + value, | ||
66 | + time: Date.now(), | ||
67 | + expire: !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null, | ||
68 | + }); | ||
69 | + const stringifyValue = this.hasEncrypt | ||
70 | + ? this.encryption.encryptByAES(stringData) | ||
71 | + : stringData; | ||
72 | + this.storage.setItem(this.getKey(key), stringifyValue); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + *Read cache | ||
77 | + * @param {string} key | ||
78 | + * @memberof Cache | ||
79 | + */ | ||
80 | + get(key: string, def: any = null): any { | ||
81 | + const val = this.storage.getItem(this.getKey(key)); | ||
82 | + if (!val) return def; | ||
83 | + | ||
84 | + try { | ||
85 | + const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val; | ||
86 | + const data = JSON.parse(decVal); | ||
87 | + const { value, expire } = data; | ||
88 | + if (isNullOrUnDef(expire) || expire >= new Date().getTime()) { | ||
89 | + return value; | ||
90 | + } | ||
91 | + this.remove(key); | ||
92 | + } catch (e) { | ||
93 | + return def; | ||
94 | + } | ||
95 | + } | ||
96 | + | ||
97 | + /** | ||
98 | + * Delete cache based on key | ||
99 | + * @param {string} key | ||
100 | + * @memberof Cache | ||
101 | + */ | ||
102 | + remove(key: string) { | ||
103 | + this.storage.removeItem(this.getKey(key)); | ||
104 | + } | ||
105 | + | ||
106 | + /** | ||
107 | + * Delete all caches of this instance | ||
108 | + */ | ||
109 | + clear(): void { | ||
110 | + this.storage.clear(); | ||
111 | + } | ||
112 | + }; | ||
113 | + return new WebStorage(); | ||
114 | +}; |
src/utils/external/cipher.ts
0 → 100644
1 | +import { encrypt, decrypt } from 'crypto-js/aes'; | ||
2 | +import { parse } from 'crypto-js/enc-utf8'; | ||
3 | +import pkcs7 from 'crypto-js/pad-pkcs7'; | ||
4 | +import ECB from 'crypto-js/mode-ecb'; | ||
5 | +import md5 from 'crypto-js/md5'; | ||
6 | +import UTF8 from 'crypto-js/enc-utf8'; | ||
7 | +import Base64 from 'crypto-js/enc-base64'; | ||
8 | + | ||
9 | +export interface EncryptionParams { | ||
10 | + key: string; | ||
11 | + iv: string; | ||
12 | +} | ||
13 | + | ||
14 | +export class AesEncryption { | ||
15 | + private key; | ||
16 | + private iv; | ||
17 | + | ||
18 | + constructor(opt: Partial<EncryptionParams> = {}) { | ||
19 | + const { key, iv } = opt; | ||
20 | + if (key) { | ||
21 | + this.key = parse(key); | ||
22 | + } | ||
23 | + if (iv) { | ||
24 | + this.iv = parse(iv); | ||
25 | + } | ||
26 | + } | ||
27 | + | ||
28 | + get getOptions() { | ||
29 | + return { | ||
30 | + mode: ECB, | ||
31 | + padding: pkcs7, | ||
32 | + iv: this.iv, | ||
33 | + }; | ||
34 | + } | ||
35 | + | ||
36 | + encryptByAES(cipherText: string) { | ||
37 | + return encrypt(cipherText, this.key!, this.getOptions).toString(); | ||
38 | + } | ||
39 | + | ||
40 | + decryptByAES(cipherText: string) { | ||
41 | + return decrypt(cipherText, this.key!, this.getOptions).toString(UTF8); | ||
42 | + } | ||
43 | +} | ||
44 | + | ||
45 | +export function encryptByBase64(cipherText: string) { | ||
46 | + return UTF8.parse(cipherText).toString(Base64); | ||
47 | +} | ||
48 | + | ||
49 | +export function decodeByBase64(cipherText: string) { | ||
50 | + return Base64.parse(cipherText).toString(UTF8); | ||
51 | +} | ||
52 | + | ||
53 | +export function encryptByMd5(password: string) { | ||
54 | + return md5(password).toString(); | ||
55 | +} |
src/utils/external/env/index.ts
0 → 100644
1 | +import type { GlobEnvConfig } from '/#/external/config'; | ||
2 | + | ||
3 | +import pkg from '../../../../package.json'; | ||
4 | +import { getGlobalConfigName } from 'build/external/globConfig/getGlobConfigName'; | ||
5 | + | ||
6 | +export function getCommonStoragePrefix() { | ||
7 | + const { VITE_GLOB_APP_SHORT_NAME } = getAppEnvConfig(); | ||
8 | + return `${VITE_GLOB_APP_SHORT_NAME}__${getEnv()}`.toUpperCase(); | ||
9 | +} | ||
10 | + | ||
11 | +// Generate cache key according to version | ||
12 | +export function getStorageShortName() { | ||
13 | + return `${getCommonStoragePrefix()}${`__${pkg.version}`}__`.toUpperCase(); | ||
14 | +} | ||
15 | + | ||
16 | +export function getAppEnvConfig() { | ||
17 | + const ENV_NAME = getGlobalConfigName(import.meta.env); | ||
18 | + | ||
19 | + const ENV = (import.meta.env.DEV | ||
20 | + ? // Get the global configuration (the configuration will be extracted independently when packaging) | ||
21 | + (import.meta.env as unknown as GlobEnvConfig) | ||
22 | + : window[ENV_NAME as any]) as unknown as GlobEnvConfig; | ||
23 | + const { | ||
24 | + VITE_GLOB_APP_TITLE, | ||
25 | + VITE_GLOB_API_URL, | ||
26 | + VITE_GLOB_APP_SHORT_NAME, | ||
27 | + VITE_GLOB_API_URL_PREFIX, | ||
28 | + VITE_GLOB_UPLOAD_URL, | ||
29 | + VITE_GLOB_CONFIGURATION, | ||
30 | + VITE_GLOB_WEB_SOCKET, | ||
31 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
32 | + VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME, | ||
33 | + VITE_GLOB_ALARM_NOTIFY_DURATION, | ||
34 | + } = ENV; | ||
35 | + | ||
36 | + if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { | ||
37 | + console.warn( | ||
38 | + `VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.` | ||
39 | + ); | ||
40 | + } | ||
41 | + | ||
42 | + return { | ||
43 | + VITE_GLOB_APP_TITLE, | ||
44 | + VITE_GLOB_API_URL, | ||
45 | + VITE_GLOB_APP_SHORT_NAME, | ||
46 | + VITE_GLOB_API_URL_PREFIX, | ||
47 | + VITE_GLOB_UPLOAD_URL, | ||
48 | + VITE_GLOB_CONFIGURATION, | ||
49 | + VITE_GLOB_WEB_SOCKET, | ||
50 | + VITE_GLOB_CONTENT_SECURITY_POLICY, | ||
51 | + VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME, | ||
52 | + VITE_GLOB_ALARM_NOTIFY_DURATION, | ||
53 | + }; | ||
54 | +} | ||
55 | + | ||
56 | +/** | ||
57 | + * @description: Development mode | ||
58 | + */ | ||
59 | +export const devMode = 'development'; | ||
60 | + | ||
61 | +/** | ||
62 | + * @description: Production mode | ||
63 | + */ | ||
64 | +export const prodMode = 'production'; | ||
65 | + | ||
66 | +/** | ||
67 | + * @description: Get environment variables | ||
68 | + * @returns: | ||
69 | + * @example: | ||
70 | + */ | ||
71 | +export function getEnv(): string { | ||
72 | + return import.meta.env.MODE; | ||
73 | +} | ||
74 | + | ||
75 | +/** | ||
76 | + * @description: Is it a development mode | ||
77 | + * @returns: | ||
78 | + * @example: | ||
79 | + */ | ||
80 | +export function isDevMode(): boolean { | ||
81 | + return import.meta.env.DEV; | ||
82 | +} | ||
83 | + | ||
84 | +/** | ||
85 | + * @description: Is it a production mode | ||
86 | + * @returns: | ||
87 | + * @example: | ||
88 | + */ | ||
89 | +export function isProdMode(): boolean { | ||
90 | + return import.meta.env.PROD; | ||
91 | +} |
src/utils/external/http/axios/Axios.ts
0 → 100644
1 | +import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, AxiosError } from 'axios'; | ||
2 | +import type { CreateAxiosOptions } from './axiosTransform'; | ||
3 | +import axios from 'axios'; | ||
4 | +import qs from 'qs'; | ||
5 | +import { AxiosCanceler } from './axiosCancel'; | ||
6 | +import jwt_decode from 'jwt-decode'; | ||
7 | +import { RequestOptions, Result, UploadFileParams } from '/#/external/axios'; | ||
8 | +import { JwtModel } from '@/api/external/sys/model/jwtModel'; | ||
9 | +import { isFunction } from '@/utils/external/is' | ||
10 | +import { ContentTypeEnum, RequestEnum } from '@/enums/external/httpEnum'; | ||
11 | +import omit from 'lodash/omit'; | ||
12 | +import cloneDeep from 'lodash/cloneDeep'; | ||
13 | +import { useUserStore } from '@/store/external/module/user'; | ||
14 | + | ||
15 | +export * from './axiosTransform'; | ||
16 | + | ||
17 | +/** | ||
18 | + * @description: axios module | ||
19 | + */ | ||
20 | +export class VAxios { | ||
21 | + private axiosInstance: AxiosInstance; | ||
22 | + private readonly options: CreateAxiosOptions; | ||
23 | + private waitingQueue: any[]; | ||
24 | + private refreshing = false; | ||
25 | + | ||
26 | + constructor(options: CreateAxiosOptions) { | ||
27 | + this.options = options; | ||
28 | + this.axiosInstance = axios.create(options); | ||
29 | + this.setupInterceptors(); | ||
30 | + this.waitingQueue = []; | ||
31 | + } | ||
32 | + | ||
33 | + /** | ||
34 | + * @description: Create axios instance | ||
35 | + */ | ||
36 | + private createAxios(config: CreateAxiosOptions): void { | ||
37 | + this.axiosInstance = axios.create(config); | ||
38 | + } | ||
39 | + | ||
40 | + private getTransform() { | ||
41 | + const { transform } = this.options; | ||
42 | + return transform; | ||
43 | + } | ||
44 | + | ||
45 | + getAxios(): AxiosInstance { | ||
46 | + return this.axiosInstance; | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * @description: Reconfigure axios | ||
51 | + */ | ||
52 | + configAxios(config: CreateAxiosOptions) { | ||
53 | + if (!this.axiosInstance) { | ||
54 | + return; | ||
55 | + } | ||
56 | + this.createAxios(config); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * @description: Set general header | ||
61 | + */ | ||
62 | + setHeader(headers: any): void { | ||
63 | + if (!this.axiosInstance) { | ||
64 | + return; | ||
65 | + } | ||
66 | + Object.assign(this.axiosInstance.defaults.headers, headers); | ||
67 | + } | ||
68 | + /** | ||
69 | + * JWT 自动刷新 | ||
70 | + * @description: 自动刷新token | ||
71 | + */ | ||
72 | + private isNeedTokenURL(url: string, arr = ['/auth/login', '/auth/token']) { | ||
73 | + return !arr.some((val) => url.indexOf(val) > -1); | ||
74 | + } | ||
75 | + | ||
76 | + /** | ||
77 | + * | ||
78 | + * @returns | ||
79 | + */ | ||
80 | + private refreshTokenBeforeReq(doRefreshTokenApi: () => Promise<unknown>): Promise<unknown> { | ||
81 | + // 创建一个未完成的promise,把改变状态的resolve方法交给请求token结束后执行 | ||
82 | + const promise = new Promise((resolve) => { | ||
83 | + // 等待队列放的是一个回调函数,来延迟resolve的执行,以此控制promise状态的改变 | ||
84 | + this.waitingQueue.push(() => resolve(null)); | ||
85 | + }); | ||
86 | + if (!this.refreshing) { | ||
87 | + this.refreshing = true; | ||
88 | + // 模拟请求刷新Token接口,当接口返回数据时执行then方法 TODO 添加catch捕获异常 | ||
89 | + doRefreshTokenApi().then(() => { | ||
90 | + this.refreshing = false; | ||
91 | + this.waitingQueue.forEach((cb) => cb()); | ||
92 | + this.waitingQueue.length = 0; | ||
93 | + }); | ||
94 | + } | ||
95 | + return promise; | ||
96 | + } | ||
97 | + /** | ||
98 | + * @description: Interceptor configuration | ||
99 | + */ | ||
100 | + private setupInterceptors() { | ||
101 | + const transform = this.getTransform(); | ||
102 | + if (!transform) { | ||
103 | + return; | ||
104 | + } | ||
105 | + const { | ||
106 | + requestInterceptors, | ||
107 | + requestInterceptorsCatch, | ||
108 | + responseInterceptors, | ||
109 | + responseInterceptorsCatch, | ||
110 | + } = transform; | ||
111 | + | ||
112 | + const axiosCanceler = new AxiosCanceler(); | ||
113 | + | ||
114 | + // Request interceptor configuration processing | ||
115 | + this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => { | ||
116 | + // If cancel repeat request is turned on, then cancel repeat request is prohibited | ||
117 | + const userStore = useUserStore(); | ||
118 | + if (userStore && userStore.jwtToken) { | ||
119 | + try { | ||
120 | + const res = jwt_decode(userStore.jwtToken) as JwtModel; | ||
121 | + const currentTime = new Date().getTime() / 1000; | ||
122 | + if (currentTime >= res.exp && this.isNeedTokenURL(config.url!)) { | ||
123 | + await this.refreshTokenBeforeReq(userStore.doRefresh); | ||
124 | + } | ||
125 | + } catch (error) { | ||
126 | + userStore.logout(); | ||
127 | + } | ||
128 | + } | ||
129 | + const { | ||
130 | + headers: { ignoreCancelToken } = {}, | ||
131 | + } = config; | ||
132 | + | ||
133 | + const ignoreCancel = | ||
134 | + ignoreCancelToken !== undefined | ||
135 | + ? ignoreCancelToken | ||
136 | + : this.options.requestOptions?.ignoreCancelToken; | ||
137 | + | ||
138 | + !ignoreCancel && axiosCanceler.addPending(config); | ||
139 | + if (requestInterceptors && isFunction(requestInterceptors)) { | ||
140 | + config = requestInterceptors(config, this.options); | ||
141 | + } | ||
142 | + return config; | ||
143 | + }, undefined); | ||
144 | + | ||
145 | + // Request interceptor error capture | ||
146 | + requestInterceptorsCatch && | ||
147 | + isFunction(requestInterceptorsCatch) && | ||
148 | + this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch); | ||
149 | + | ||
150 | + // Response result interceptor processing | ||
151 | + this.axiosInstance.interceptors.response.use((res: AxiosResponse<any>) => { | ||
152 | + res && axiosCanceler.removePending(res.config); | ||
153 | + if (responseInterceptors && isFunction(responseInterceptors)) { | ||
154 | + res = responseInterceptors(res); | ||
155 | + } | ||
156 | + return res; | ||
157 | + }, undefined); | ||
158 | + | ||
159 | + // Response result interceptor error capture | ||
160 | + responseInterceptorsCatch && | ||
161 | + isFunction(responseInterceptorsCatch) && | ||
162 | + this.axiosInstance.interceptors.response.use(undefined, responseInterceptorsCatch); | ||
163 | + } | ||
164 | + | ||
165 | + /** | ||
166 | + * @description: File Upload | ||
167 | + */ | ||
168 | + uploadFile<T = any>(config: AxiosRequestConfig, params: UploadFileParams) { | ||
169 | + const formData = new window.FormData(); | ||
170 | + | ||
171 | + if (params.data) { | ||
172 | + Object.keys(params.data).forEach((key) => { | ||
173 | + if (!params.data) return; | ||
174 | + const value = params.data[key]; | ||
175 | + if (Array.isArray(value)) { | ||
176 | + value.forEach((item) => { | ||
177 | + formData.append(`${key}[]`, item); | ||
178 | + }); | ||
179 | + return; | ||
180 | + } | ||
181 | + | ||
182 | + formData.append(key, params.data[key]); | ||
183 | + }); | ||
184 | + } | ||
185 | + formData.append(params.name || 'file', params.file, params.filename); | ||
186 | + const customParams = omit(params, 'file', 'filename', 'file'); | ||
187 | + | ||
188 | + Object.keys(customParams).forEach((key) => { | ||
189 | + formData.append(key, customParams[key]); | ||
190 | + }); | ||
191 | + | ||
192 | + return this.axiosInstance.request<T>({ | ||
193 | + ...config, | ||
194 | + method: 'POST', | ||
195 | + data: formData, | ||
196 | + headers: { | ||
197 | + 'Content-type': ContentTypeEnum.FORM_DATA, | ||
198 | + ignoreCancelToken: true, | ||
199 | + }, | ||
200 | + }); | ||
201 | + } | ||
202 | + | ||
203 | + // support form-data | ||
204 | + supportFormData(config: AxiosRequestConfig) { | ||
205 | + const headers = config.headers || this.options.headers; | ||
206 | + const contentType = headers?.['Content-Type'] || headers?.['content-type']; | ||
207 | + | ||
208 | + if ( | ||
209 | + contentType !== ContentTypeEnum.FORM_URLENCODED || | ||
210 | + !Reflect.has(config, 'data') || | ||
211 | + config.method?.toUpperCase() === RequestEnum.GET | ||
212 | + ) { | ||
213 | + return config; | ||
214 | + } | ||
215 | + | ||
216 | + return { | ||
217 | + ...config, | ||
218 | + data: qs.stringify(config.data, { arrayFormat: 'brackets' }), | ||
219 | + }; | ||
220 | + } | ||
221 | + | ||
222 | + get<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> { | ||
223 | + return this.request({ ...config, method: 'GET' }, options); | ||
224 | + } | ||
225 | + | ||
226 | + post<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> { | ||
227 | + return this.request({ ...config, method: 'POST' }, options); | ||
228 | + } | ||
229 | + | ||
230 | + put<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> { | ||
231 | + return this.request({ ...config, method: 'PUT' }, options); | ||
232 | + } | ||
233 | + | ||
234 | + delete<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> { | ||
235 | + return this.request({ ...config, method: 'DELETE' }, options); | ||
236 | + } | ||
237 | + | ||
238 | + request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> { | ||
239 | + let conf: CreateAxiosOptions = cloneDeep(config); | ||
240 | + const transform = this.getTransform(); | ||
241 | + | ||
242 | + const { requestOptions } = this.options; | ||
243 | + | ||
244 | + const opt: RequestOptions = Object.assign({}, requestOptions, options); | ||
245 | + | ||
246 | + const { beforeRequestHook, requestCatchHook, transformRequestHook } = transform || {}; | ||
247 | + if (beforeRequestHook && isFunction(beforeRequestHook)) { | ||
248 | + conf = beforeRequestHook(conf, opt); | ||
249 | + } | ||
250 | + conf.requestOptions = opt; | ||
251 | + | ||
252 | + conf = this.supportFormData(conf); | ||
253 | + | ||
254 | + return new Promise((resolve, reject) => { | ||
255 | + this.axiosInstance | ||
256 | + .request<any, AxiosResponse<Result>>(conf) | ||
257 | + .then((res: AxiosResponse<Result>) => { | ||
258 | + if (transformRequestHook && isFunction(transformRequestHook)) { | ||
259 | + try { | ||
260 | + const ret = transformRequestHook(res, opt); | ||
261 | + resolve(ret); | ||
262 | + } catch (err) { | ||
263 | + reject(err || new Error('request error!')); | ||
264 | + } | ||
265 | + return; | ||
266 | + } | ||
267 | + resolve(res as unknown as Promise<T>); | ||
268 | + }) | ||
269 | + .catch((e: Error | AxiosError) => { | ||
270 | + if (requestCatchHook && isFunction(requestCatchHook)) { | ||
271 | + reject(requestCatchHook(e, opt)); | ||
272 | + return; | ||
273 | + } | ||
274 | + if (axios.isAxiosError(e)) { | ||
275 | + // rewrite error message from axios in here | ||
276 | + } | ||
277 | + reject(e); | ||
278 | + }); | ||
279 | + }); | ||
280 | + } | ||
281 | +} |
src/utils/external/http/axios/axiosCancel.ts
0 → 100644
1 | +import type { AxiosRequestConfig, Canceler } from 'axios'; | ||
2 | +import axios from 'axios'; | ||
3 | +import { isFunction } from '@/utils/external/is'; | ||
4 | + | ||
5 | +// Used to store the identification and cancellation function of each request | ||
6 | +let pendingMap = new Map<string, Canceler>(); | ||
7 | + | ||
8 | +export const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&'); | ||
9 | + | ||
10 | +export class AxiosCanceler { | ||
11 | + /** | ||
12 | + * Add request | ||
13 | + * @param {Object} config | ||
14 | + */ | ||
15 | + addPending(config: AxiosRequestConfig) { | ||
16 | + this.removePending(config); | ||
17 | + const url = getPendingUrl(config); | ||
18 | + config.cancelToken = | ||
19 | + config.cancelToken || | ||
20 | + new axios.CancelToken((cancel) => { | ||
21 | + if (!pendingMap.has(url)) { | ||
22 | + // If there is no current request in pending, add it | ||
23 | + pendingMap.set(url, cancel); | ||
24 | + } | ||
25 | + }); | ||
26 | + } | ||
27 | + | ||
28 | + /** | ||
29 | + * @description: Clear all pending | ||
30 | + */ | ||
31 | + removeAllPending() { | ||
32 | + pendingMap.forEach((cancel) => { | ||
33 | + cancel && isFunction(cancel) && cancel(); | ||
34 | + }); | ||
35 | + pendingMap.clear(); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Removal request | ||
40 | + * @param {Object} config | ||
41 | + */ | ||
42 | + removePending(config: AxiosRequestConfig) { | ||
43 | + const url = getPendingUrl(config); | ||
44 | + | ||
45 | + if (pendingMap.has(url)) { | ||
46 | + // If there is a current request identifier in pending, | ||
47 | + // the current request needs to be cancelled and removed | ||
48 | + const cancel = pendingMap.get(url); | ||
49 | + cancel && cancel(url); | ||
50 | + pendingMap.delete(url); | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * @description: reset | ||
56 | + */ | ||
57 | + reset(): void { | ||
58 | + pendingMap = new Map<string, Canceler>(); | ||
59 | + } | ||
60 | +} |
1 | +/** | ||
2 | + * Data processing class, can be configured according to the project | ||
3 | + */ | ||
4 | +import type { AxiosRequestConfig, AxiosResponse } from 'axios'; | ||
5 | +import type { RequestOptions, Result } from '/#/external/axios'; | ||
6 | + | ||
7 | +export interface CreateAxiosOptions extends AxiosRequestConfig { | ||
8 | + authenticationScheme?: string; | ||
9 | + urlPrefix?: string; | ||
10 | + transform?: AxiosTransform; | ||
11 | + requestOptions?: RequestOptions; | ||
12 | +} | ||
13 | + | ||
14 | +export abstract class AxiosTransform { | ||
15 | + /** | ||
16 | + * @description: Process configuration before request | ||
17 | + * @description: Process configuration before request | ||
18 | + */ | ||
19 | + beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig; | ||
20 | + | ||
21 | + /** | ||
22 | + * @description: Request successfully processed | ||
23 | + */ | ||
24 | + transformRequestHook?: (res: AxiosResponse<Result>, options: RequestOptions) => any; | ||
25 | + | ||
26 | + /** | ||
27 | + * @description: 请求失败处理 | ||
28 | + */ | ||
29 | + requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>; | ||
30 | + | ||
31 | + /** | ||
32 | + * @description: 请求之前的拦截器 | ||
33 | + */ | ||
34 | + requestInterceptors?: ( | ||
35 | + config: AxiosRequestConfig, | ||
36 | + options: CreateAxiosOptions | ||
37 | + ) => AxiosRequestConfig; | ||
38 | + | ||
39 | + /** | ||
40 | + * @description: 请求之后的拦截器 | ||
41 | + */ | ||
42 | + responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>; | ||
43 | + | ||
44 | + /** | ||
45 | + * @description: 请求之前的拦截器错误处理 | ||
46 | + */ | ||
47 | + requestInterceptorsCatch?: (error: Error) => void; | ||
48 | + | ||
49 | + /** | ||
50 | + * @description: 请求之后的拦截器错误处理 | ||
51 | + */ | ||
52 | + responseInterceptorsCatch?: (error: Error) => void; | ||
53 | +} |
src/utils/external/http/axios/checkStatus.ts
0 → 100644
1 | +import type { ErrorMessageMode } from '/#/external/axios'; | ||
2 | +import { useUserStoreWithOut } from '@/store/external/module/user'; | ||
3 | +import { useI18n } from 'vue-i18n'; | ||
4 | +import { useMessage } from 'naive-ui'; | ||
5 | + | ||
6 | +const { error } = useMessage() | ||
7 | +export function checkStatus( | ||
8 | + status: number, | ||
9 | + msg: string, | ||
10 | + errorMessageMode: ErrorMessageMode = 'message' | ||
11 | +): void { | ||
12 | + const { t } = useI18n(); | ||
13 | + const userStore = useUserStoreWithOut(); | ||
14 | + let errMessage = msg; | ||
15 | + switch (status) { | ||
16 | + case 400: | ||
17 | + errMessage = `${msg}`; | ||
18 | + break; | ||
19 | + // 401: Not logged in | ||
20 | + // Jump to the login page if not logged in, and carry the path of the current page | ||
21 | + // Return to the current page after successful login. This step needs to be operated on the login page. | ||
22 | + case 401: | ||
23 | + errMessage = ''; | ||
24 | + userStore.logout() | ||
25 | + break; | ||
26 | + case 403: | ||
27 | + errMessage = '未授权'; | ||
28 | + break; | ||
29 | + // 404请求不存在 | ||
30 | + case 404: | ||
31 | + errMessage = '未找到该资源!'; | ||
32 | + break; | ||
33 | + case 405: | ||
34 | + errMessage = '网络请求错误,请求方法未允许!'; | ||
35 | + break; | ||
36 | + case 408: | ||
37 | + errMessage = '网络请求超时!'; | ||
38 | + break; | ||
39 | + case 500: | ||
40 | + errMessage = '服务器错误,请联系管理员!'; | ||
41 | + break; | ||
42 | + case 501: | ||
43 | + errMessage = '网络未实现!'; | ||
44 | + break; | ||
45 | + case 502: | ||
46 | + errMessage = '网络错误!'; | ||
47 | + break; | ||
48 | + case 503: | ||
49 | + errMessage = '服务不可用,服务器暂时过载或维护!'; | ||
50 | + break; | ||
51 | + case 504: | ||
52 | + errMessage = '网络超时!'; | ||
53 | + break; | ||
54 | + case 505: | ||
55 | + errMessage = 'http版本不支持该请求!'; | ||
56 | + break; | ||
57 | + default: | ||
58 | + } | ||
59 | + if (errMessage) { | ||
60 | + if (errorMessageMode === 'message') { | ||
61 | + error(errMessage); | ||
62 | + } | ||
63 | + } | ||
64 | +} |
src/utils/external/http/axios/helper.ts
0 → 100644
1 | +import { isObject, isString } from '@/utils/external/is'; | ||
2 | + | ||
3 | +const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm'; | ||
4 | + | ||
5 | +export function joinTimestamp<T extends boolean>( | ||
6 | + join: boolean, | ||
7 | + restful: T | ||
8 | +): T extends true ? string : object; | ||
9 | + | ||
10 | +export function joinTimestamp(join: boolean, restful = false): string | object { | ||
11 | + if (!join) { | ||
12 | + return restful ? '' : {}; | ||
13 | + } | ||
14 | + const now = new Date().getTime(); | ||
15 | + if (restful) { | ||
16 | + return `?_t=${now}`; | ||
17 | + } | ||
18 | + return { _t: now }; | ||
19 | +} | ||
20 | + | ||
21 | +/** | ||
22 | + * @description: Format request parameter time | ||
23 | + */ | ||
24 | +export function formatRequestDate(params: Recordable) { | ||
25 | + if (Object.prototype.toString.call(params) !== '[object Object]') { | ||
26 | + return; | ||
27 | + } | ||
28 | + | ||
29 | + for (const key in params) { | ||
30 | + if (params[key] && params[key]._isAMomentObject) { | ||
31 | + params[key] = params[key].format(DATE_TIME_FORMAT); | ||
32 | + } | ||
33 | + if (isString(key)) { | ||
34 | + const value = params[key]; | ||
35 | + if (value) { | ||
36 | + try { | ||
37 | + params[key] = isString(value) ? value.trim() : value; | ||
38 | + } catch (error) { | ||
39 | + throw new Error(error as string); | ||
40 | + } | ||
41 | + } | ||
42 | + } | ||
43 | + if (isObject(params[key])) { | ||
44 | + formatRequestDate(params[key]); | ||
45 | + } | ||
46 | + } | ||
47 | +} |
src/utils/external/http/axios/index.ts
0 → 100644
1 | +// axios配置 可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动 | ||
2 | +// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged | ||
3 | + | ||
4 | +import type { AxiosResponse } from 'axios'; | ||
5 | +import type { RequestOptions, Result } from '/#/external/axios'; | ||
6 | +import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform'; | ||
7 | +import { VAxios } from './Axios'; | ||
8 | +import { checkStatus } from './checkStatus'; | ||
9 | +import { useGlobSetting } from '@/hooks/external/setting'; | ||
10 | +import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum'; | ||
11 | +import { isString } from '@/utils/external/is'; | ||
12 | +import { getJwtToken } from '@/utils/external/auth'; | ||
13 | +import { setObjToUrlParams, deepMerge } from '@/utils/external'; | ||
14 | +import { joinTimestamp, formatRequestDate } from './helper'; | ||
15 | +import { PageEnum } from '@/enums/external/pageEnum'; | ||
16 | +import router from '@/router'; | ||
17 | +import { useDialog } from 'naive-ui'; | ||
18 | + | ||
19 | +const globSetting = useGlobSetting(); | ||
20 | +const urlPrefix = globSetting.urlPrefix; | ||
21 | + | ||
22 | +const { success, error } = useDialog() | ||
23 | +/** | ||
24 | + * @description: 数据处理,方便区分多种处理方式 | ||
25 | + */ | ||
26 | +const transform: AxiosTransform = { | ||
27 | + /** | ||
28 | + * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误 | ||
29 | + */ | ||
30 | + transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => { | ||
31 | + const { isReturnNativeResponse } = options; | ||
32 | + // 是否返回原生响应头 比如:需要获取响应头时使用该属性 | ||
33 | + if (isReturnNativeResponse) { | ||
34 | + return res; | ||
35 | + } | ||
36 | + return res.data; | ||
37 | + }, | ||
38 | + | ||
39 | + // 请求之前处理config | ||
40 | + beforeRequestHook: (config, options) => { | ||
41 | + const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options; | ||
42 | + | ||
43 | + if (joinPrefix) { | ||
44 | + config.url = `${urlPrefix}${config.url}`; | ||
45 | + } | ||
46 | + | ||
47 | + if (apiUrl && isString(apiUrl)) { | ||
48 | + config.url = `${apiUrl}${config.url}`; | ||
49 | + } | ||
50 | + const params = config.params || {}; | ||
51 | + const data = config.data || false; | ||
52 | + formatDate && data && !isString(data) && formatRequestDate(data); | ||
53 | + if (config.method?.toUpperCase() === RequestEnum.GET) { | ||
54 | + if (!isString(params)) { | ||
55 | + // 给 get 请求加上时间戳参数,避免从缓存中拿数据。 | ||
56 | + config.params = Object.assign(params || {}, joinTimestamp(joinTime, false)); | ||
57 | + } else { | ||
58 | + // 兼容restful风格 | ||
59 | + config.url = config.url + params + `${joinTimestamp(joinTime, true)}`; | ||
60 | + config.params = undefined; | ||
61 | + } | ||
62 | + } else { | ||
63 | + if (!isString(params)) { | ||
64 | + formatDate && formatRequestDate(params); | ||
65 | + if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) { | ||
66 | + config.data = data; | ||
67 | + config.params = params; | ||
68 | + } else { | ||
69 | + // 非GET请求如果没有提供data,则将params视为data | ||
70 | + config.data = params; | ||
71 | + config.params = undefined; | ||
72 | + } | ||
73 | + if (joinParamsToUrl) { | ||
74 | + config.url = setObjToUrlParams( | ||
75 | + config.url as string, | ||
76 | + Object.assign({}, config.params, config.data) | ||
77 | + ); | ||
78 | + } | ||
79 | + } else { | ||
80 | + // 兼容restful风格 | ||
81 | + config.url = config.url + params; | ||
82 | + config.params = undefined; | ||
83 | + } | ||
84 | + } | ||
85 | + return config; | ||
86 | + }, | ||
87 | + | ||
88 | + /** | ||
89 | + * @description: 请求拦截器处理 | ||
90 | + */ | ||
91 | + requestInterceptors: (config, options) => { | ||
92 | + // 请求之前处理config | ||
93 | + const token = getJwtToken(); | ||
94 | + if (token && (config as Recordable)?.requestOptions?.withToken !== false) { | ||
95 | + // jwt token | ||
96 | + config.headers!['X-Authorization'] = options.authenticationScheme | ||
97 | + ? `${options.authenticationScheme} ${token}` | ||
98 | + : token as string; | ||
99 | + } | ||
100 | + return config; | ||
101 | + }, | ||
102 | + | ||
103 | + /** | ||
104 | + * @description: 响应拦截器处理 | ||
105 | + */ | ||
106 | + responseInterceptors: (res: AxiosResponse<any>) => { | ||
107 | + return res; | ||
108 | + }, | ||
109 | + | ||
110 | + /** | ||
111 | + * @description: 响应错误处理 | ||
112 | + */ | ||
113 | + responseInterceptorsCatch: (error: any) => { | ||
114 | + | ||
115 | + const { response, code, message, config } = error || {}; | ||
116 | + | ||
117 | + const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'; | ||
118 | + const errorMsgIsObj = typeof response?.data === 'object'; | ||
119 | + const msg: string = errorMsgIsObj | ||
120 | + ? response?.data?.message || response?.data?.msg | ||
121 | + : response?.data; | ||
122 | + const err: string = error?.toString?.() ?? ''; | ||
123 | + let errMessage = ''; | ||
124 | + try { | ||
125 | + if (response?.data?.status == '401' || response?.data?.message == '"Authentication failed"') { | ||
126 | + window.localStorage.clear(); | ||
127 | + window.sessionStorage.clear(); | ||
128 | + router.push(PageEnum.BASE_HOME); | ||
129 | + } | ||
130 | + if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) { | ||
131 | + errMessage = '接口请求超时,请刷新页面重试!' | ||
132 | + } | ||
133 | + if (err?.includes('Network Error')) { | ||
134 | + errMessage = '网络异常,请检查您的网络连接时候正常!' | ||
135 | + } | ||
136 | + | ||
137 | + if (errMessage) { | ||
138 | + if (errorMessageMode === 'modal') { | ||
139 | + error({ title: '错误提示', content: errMessage }) | ||
140 | + } else if (errorMessageMode === 'message') { | ||
141 | + error({ title: '错误提示', content: errMessage }) | ||
142 | + } | ||
143 | + return Promise.reject(error); | ||
144 | + } | ||
145 | + } catch (error: any) { | ||
146 | + throw new Error(error); | ||
147 | + } | ||
148 | + checkStatus(error?.response?.status, msg, errorMessageMode); | ||
149 | + return Promise.reject(response.data); | ||
150 | + }, | ||
151 | +}; | ||
152 | + | ||
153 | +function createAxios(opt?: Partial<CreateAxiosOptions>) { | ||
154 | + return new VAxios( | ||
155 | + deepMerge( | ||
156 | + { | ||
157 | + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes | ||
158 | + // authentication schemes,e.g: Bearer | ||
159 | + // authenticationScheme: 'Bearer', | ||
160 | + authenticationScheme: 'Bearer', | ||
161 | + timeout: 10 * 1000, | ||
162 | + // 基础接口地址 | ||
163 | + // baseURL: globSetting.apiUrl, | ||
164 | + // 接口可能会有通用的地址部分,可以统一抽取出来 | ||
165 | + urlPrefix: urlPrefix, | ||
166 | + headers: { 'Content-Type': ContentTypeEnum.JSON }, | ||
167 | + // 如果是form-data格式 | ||
168 | + // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED }, | ||
169 | + // 数据处理方式 | ||
170 | + transform, | ||
171 | + // 配置项,下面的选项都可以在独立的接口请求中覆盖 | ||
172 | + requestOptions: { | ||
173 | + // 默认将prefix 添加到url | ||
174 | + joinPrefix: true, | ||
175 | + // 是否返回原生响应头 比如:需要获取响应头时使用该属性 | ||
176 | + isReturnNativeResponse: false, | ||
177 | + // 需要对返回数据进行处理 | ||
178 | + isTransformResponse: true, | ||
179 | + // post请求的时候添加参数到url | ||
180 | + joinParamsToUrl: false, | ||
181 | + // 格式化提交参数时间 | ||
182 | + formatDate: true, | ||
183 | + // 消息提示类型 | ||
184 | + errorMessageMode: 'message', | ||
185 | + // 接口地址 | ||
186 | + apiUrl: globSetting.apiUrl, | ||
187 | + // 是否加入时间戳 | ||
188 | + joinTime: true, | ||
189 | + // 忽略重复请求 | ||
190 | + ignoreCancelToken: true, | ||
191 | + // 是否携带token | ||
192 | + withToken: true, | ||
193 | + }, | ||
194 | + }, | ||
195 | + opt || {} | ||
196 | + ) | ||
197 | + ); | ||
198 | +} | ||
199 | +export const defHttp = createAxios(); | ||
200 | + | ||
201 | +// other api url | ||
202 | +export const otherHttp = createAxios({ | ||
203 | + requestOptions: { | ||
204 | + apiUrl: 'xxx', | ||
205 | + }, | ||
206 | +}); |
src/utils/external/index.ts
0 → 100644
1 | +import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'; | ||
2 | +import type { App, Component, Plugin } from 'vue'; | ||
3 | + | ||
4 | +import { unref } from 'vue'; | ||
5 | +import { isObject } from '@/utils/external/is'; | ||
6 | + | ||
7 | +export const noop = () => { }; | ||
8 | + | ||
9 | +/** | ||
10 | + * @description: Set ui mount node | ||
11 | + */ | ||
12 | +export function getPopupContainer(node?: HTMLElement): HTMLElement { | ||
13 | + return (node?.parentNode as HTMLElement) ?? document.body; | ||
14 | +} | ||
15 | + | ||
16 | +/** | ||
17 | + * Add the object as a parameter to the URL | ||
18 | + * @param baseUrl url | ||
19 | + * @param obj | ||
20 | + * @returns {string} | ||
21 | + * eg: | ||
22 | + * let obj = {a: '3', b: '4'} | ||
23 | + * setObjToUrlParams('www.baidu.com', obj) | ||
24 | + * ==>www.baidu.com?a=3&b=4 | ||
25 | + */ | ||
26 | +export function setObjToUrlParams(baseUrl: string, obj: any): string { | ||
27 | + let parameters = ''; | ||
28 | + for (const key in obj) { | ||
29 | + parameters += key + '=' + encodeURIComponent(obj[key]) + '&'; | ||
30 | + } | ||
31 | + parameters = parameters.replace(/&$/, ''); | ||
32 | + return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters; | ||
33 | +} | ||
34 | + | ||
35 | +export function deepMerge<T = any>(src: any = {}, target: any = {}): T { | ||
36 | + let key: string; | ||
37 | + for (key in target) { | ||
38 | + src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key]); | ||
39 | + } | ||
40 | + return src; | ||
41 | +} | ||
42 | + | ||
43 | +export function openWindow( | ||
44 | + url: string, | ||
45 | + opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean } | ||
46 | +) { | ||
47 | + const { target = '__blank', noopener = true, noreferrer = true } = opt || {}; | ||
48 | + const feature: string[] = []; | ||
49 | + | ||
50 | + noopener && feature.push('noopener=yes'); | ||
51 | + noreferrer && feature.push('noreferrer=yes'); | ||
52 | + | ||
53 | + window.open(url, target, feature.join(',')); | ||
54 | +} | ||
55 | + | ||
56 | +// dynamic use hook props | ||
57 | +export function getDynamicProps<T extends Recordable, U>(props: T): Partial<U> { | ||
58 | + const ret: Recordable = {}; | ||
59 | + | ||
60 | + Object.keys(props).map((key) => { | ||
61 | + ret[key] = unref((props as Recordable)[key]); | ||
62 | + }); | ||
63 | + | ||
64 | + return ret as Partial<U>; | ||
65 | +} | ||
66 | + | ||
67 | +export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized { | ||
68 | + if (!route) return route; | ||
69 | + const { matched, ...opt } = route; | ||
70 | + return { | ||
71 | + ...opt, | ||
72 | + matched: (matched | ||
73 | + ? matched.map((item) => ({ | ||
74 | + meta: item.meta, | ||
75 | + name: item.name, | ||
76 | + path: item.path, | ||
77 | + })) | ||
78 | + : undefined) as RouteRecordNormalized[], | ||
79 | + }; | ||
80 | +} | ||
81 | + | ||
82 | +export const withInstall = <T extends Component>(component: T, alias?: string) => { | ||
83 | + const comp = component as any; | ||
84 | + comp.install = (app: App) => { | ||
85 | + app.component(comp.name || comp.displayName, component); | ||
86 | + if (alias) { | ||
87 | + app.config.globalProperties[alias] = component; | ||
88 | + } | ||
89 | + }; | ||
90 | + return component as T & Plugin; | ||
91 | +}; |
src/utils/external/is.ts
0 → 100644
1 | +const toString = Object.prototype.toString; | ||
2 | + | ||
3 | +export function is(val: unknown, type: string) { | ||
4 | + return toString.call(val) === `[object ${type}]`; | ||
5 | +} | ||
6 | + | ||
7 | +export function isDef<T = unknown>(val?: T): val is T { | ||
8 | + return typeof val !== 'undefined'; | ||
9 | +} | ||
10 | + | ||
11 | +export function isUnDef<T = unknown>(val?: T): val is T { | ||
12 | + return !isDef(val); | ||
13 | +} | ||
14 | + | ||
15 | +export function isObject(val: any): val is Record<any, any> { | ||
16 | + return val !== null && is(val, 'Object'); | ||
17 | +} | ||
18 | + | ||
19 | +export function isEmpty<T = unknown>(val: T): val is T { | ||
20 | + if (isArray(val) || isString(val)) { | ||
21 | + return val.length === 0; | ||
22 | + } | ||
23 | + | ||
24 | + if (val instanceof Map || val instanceof Set) { | ||
25 | + return val.size === 0; | ||
26 | + } | ||
27 | + | ||
28 | + if (isObject(val)) { | ||
29 | + return Object.keys(val).length === 0; | ||
30 | + } | ||
31 | + | ||
32 | + return false; | ||
33 | +} | ||
34 | + | ||
35 | +export function isDate(val: unknown): val is Date { | ||
36 | + return is(val, 'Date'); | ||
37 | +} | ||
38 | + | ||
39 | +export function isNull(val: unknown): val is null { | ||
40 | + return val === null; | ||
41 | +} | ||
42 | + | ||
43 | +export function isNullAndUnDef(val: unknown): val is null | undefined { | ||
44 | + return isUnDef(val) && isNull(val); | ||
45 | +} | ||
46 | + | ||
47 | +export function isNullOrUnDef(val: unknown): val is null | undefined { | ||
48 | + return isUnDef(val) || isNull(val); | ||
49 | +} | ||
50 | + | ||
51 | +export function isNumber(val: unknown): val is number { | ||
52 | + return is(val, 'Number'); | ||
53 | +} | ||
54 | + | ||
55 | +export function isPromise<T = any>(val: unknown): val is Promise<T> { | ||
56 | + return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch); | ||
57 | +} | ||
58 | + | ||
59 | +export function isString(val: unknown): val is string { | ||
60 | + return is(val, 'String'); | ||
61 | +} | ||
62 | + | ||
63 | +export function isFunction(val: unknown): val is Function { | ||
64 | + return typeof val === 'function'; | ||
65 | +} | ||
66 | + | ||
67 | +export function isBoolean(val: unknown): val is boolean { | ||
68 | + return is(val, 'Boolean'); | ||
69 | +} | ||
70 | + | ||
71 | +export function isRegExp(val: unknown): val is RegExp { | ||
72 | + return is(val, 'RegExp'); | ||
73 | +} | ||
74 | + | ||
75 | +export function isArray(val: any): val is Array<any> { | ||
76 | + return val && Array.isArray(val); | ||
77 | +} | ||
78 | + | ||
79 | +export function isWindow(val: any): val is Window { | ||
80 | + return typeof window !== 'undefined' && is(val, 'Window'); | ||
81 | +} | ||
82 | + | ||
83 | +export function isElement(val: unknown): val is Element { | ||
84 | + return isObject(val) && !!val.tagName; | ||
85 | +} | ||
86 | + | ||
87 | +export function isMap(val: unknown): val is Map<any, any> { | ||
88 | + return is(val, 'Map'); | ||
89 | +} | ||
90 | + | ||
91 | +export const isServer = typeof window === 'undefined'; | ||
92 | + | ||
93 | +export const isClient = !isServer; | ||
94 | + | ||
95 | +export function isUrl(path: string): boolean { | ||
96 | + const reg = | ||
97 | + /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; | ||
98 | + return reg.test(path); | ||
99 | +} |
@@ -20,6 +20,6 @@ | @@ -20,6 +20,6 @@ | ||
20 | // "strictNullChecks": true, //不允许使用null | 20 | // "strictNullChecks": true, //不允许使用null |
21 | "noImplicitThis": true //不允许往this上面挂属性 | 21 | "noImplicitThis": true //不允许往this上面挂属性 |
22 | }, | 22 | }, |
23 | - "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*"], | 23 | + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*", "build/**/*"], |
24 | "exclude": ["node_modules", "dist", "**/*.js"] | 24 | "exclude": ["node_modules", "dist", "**/*.js"] |
25 | } | 25 | } |
types/external/axios.d.ts
0 → 100644
1 | +export type ErrorMessageMode = 'none' | 'modal' | 'message' | undefined; | ||
2 | + | ||
3 | +export interface RequestOptions { | ||
4 | + // Splicing request parameters to url | ||
5 | + joinParamsToUrl?: boolean; | ||
6 | + // Format request parameter time | ||
7 | + formatDate?: boolean; | ||
8 | + // Whether to process the request result | ||
9 | + isTransformResponse?: boolean; | ||
10 | + // Whether to return native response headers | ||
11 | + // For example: use this attribute when you need to get the response headers | ||
12 | + isReturnNativeResponse?: boolean; | ||
13 | + // Whether to join url | ||
14 | + joinPrefix?: boolean; | ||
15 | + // Interface address, use the default apiUrl if you leave it blank | ||
16 | + apiUrl?: string; | ||
17 | + // Error message prompt type | ||
18 | + errorMessageMode?: ErrorMessageMode; | ||
19 | + // Whether to add a timestamp | ||
20 | + joinTime?: boolean; | ||
21 | + ignoreCancelToken?: boolean; | ||
22 | + // Whether to send token in header | ||
23 | + withToken?: boolean; | ||
24 | +} | ||
25 | + | ||
26 | +export interface Result<T = any> { | ||
27 | + code: number; | ||
28 | + type: 'success' | 'error' | 'warning'; | ||
29 | + message: string; | ||
30 | + result: T; | ||
31 | +} | ||
32 | + | ||
33 | +// multipart/form-data: upload file | ||
34 | +export interface UploadFileParams { | ||
35 | + // Other parameters | ||
36 | + data?: Recordable; | ||
37 | + // File parameter interface field name | ||
38 | + name?: string; | ||
39 | + // file name | ||
40 | + file: File | Blob; | ||
41 | + // file name | ||
42 | + filename?: string; | ||
43 | + [key: string]: any; | ||
44 | +} | ||
45 | + | ||
46 | +export interface PaginationResult<T = Recordable> { | ||
47 | + items: T[]; | ||
48 | + total: number; | ||
49 | +} |
types/external/config.d.ts
0 → 100644
1 | +import { MenuTypeEnum, MenuModeEnum, TriggerEnum, MixSidebarTriggerEnum } from '/@/enums/menuEnum'; | ||
2 | +import { | ||
3 | + ContentEnum, | ||
4 | + PermissionModeEnum, | ||
5 | + ThemeEnum, | ||
6 | + RouterTransitionEnum, | ||
7 | + SettingButtonPositionEnum, | ||
8 | + SessionTimeoutProcessingEnum, | ||
9 | +} from '/@/enums/appEnum'; | ||
10 | + | ||
11 | +import { CacheTypeEnum } from '/@/enums/cacheEnum'; | ||
12 | + | ||
13 | +export type LocaleType = 'zh_CN' | 'en' | 'ru' | 'ja' | 'ko'; | ||
14 | + | ||
15 | +export interface MenuSetting { | ||
16 | + bgColor: string; | ||
17 | + fixed: boolean; | ||
18 | + collapsed: boolean; | ||
19 | + canDrag: boolean; | ||
20 | + show: boolean; | ||
21 | + hidden: boolean; | ||
22 | + split: boolean; | ||
23 | + menuWidth: number; | ||
24 | + mode: MenuModeEnum; | ||
25 | + type: MenuTypeEnum; | ||
26 | + theme: ThemeEnum; | ||
27 | + topMenuAlign: 'start' | 'center' | 'end'; | ||
28 | + trigger: TriggerEnum; | ||
29 | + accordion: boolean; | ||
30 | + closeMixSidebarOnChange: boolean; | ||
31 | + collapsedShowTitle: boolean; | ||
32 | + mixSideTrigger: MixSidebarTriggerEnum; | ||
33 | + mixSideFixed: boolean; | ||
34 | +} | ||
35 | + | ||
36 | +export interface MultiTabsSetting { | ||
37 | + cache: boolean; | ||
38 | + show: boolean; | ||
39 | + showQuick: boolean; | ||
40 | + canDrag: boolean; | ||
41 | + showRedo: boolean; | ||
42 | + showFold: boolean; | ||
43 | +} | ||
44 | + | ||
45 | +export interface HeaderSetting { | ||
46 | + bgColor: string; | ||
47 | + fixed: boolean; | ||
48 | + show: boolean; | ||
49 | + theme: ThemeEnum; | ||
50 | + // Turn on full screen | ||
51 | + showFullScreen: boolean; | ||
52 | + // Whether to show the lock screen | ||
53 | + useLockPage: boolean; | ||
54 | + // Show document button | ||
55 | + showDoc: boolean; | ||
56 | + // Show message center button | ||
57 | + showNotice: boolean; | ||
58 | + showSearch: boolean; | ||
59 | +} | ||
60 | + | ||
61 | +export interface LocaleSetting { | ||
62 | + showPicker: boolean; | ||
63 | + // Current language | ||
64 | + locale: LocaleType; | ||
65 | + // default language | ||
66 | + fallback: LocaleType; | ||
67 | + // available Locales | ||
68 | + availableLocales: LocaleType[]; | ||
69 | +} | ||
70 | + | ||
71 | +export interface TransitionSetting { | ||
72 | + // Whether to open the page switching animation | ||
73 | + enable: boolean; | ||
74 | + // Route basic switching animation | ||
75 | + basicTransition: RouterTransitionEnum; | ||
76 | + // Whether to open page switching loading | ||
77 | + openPageLoading: boolean; | ||
78 | + // Whether to open the top progress bar | ||
79 | + openNProgress: boolean; | ||
80 | +} | ||
81 | + | ||
82 | +export interface ProjectConfig { | ||
83 | + // Storage location of permission related information | ||
84 | + permissionCacheType: CacheTypeEnum; | ||
85 | + // Whether to show the configuration button | ||
86 | + showSettingButton: boolean; | ||
87 | + // Whether to show the theme switch button | ||
88 | + showDarkModeToggle: boolean; | ||
89 | + // Configure where the button is displayed | ||
90 | + settingButtonPosition: SettingButtonPositionEnum; | ||
91 | + // Permission mode | ||
92 | + permissionMode: PermissionModeEnum; | ||
93 | + // Session timeout processing | ||
94 | + sessionTimeoutProcessing: SessionTimeoutProcessingEnum; | ||
95 | + // Website gray mode, open for possible mourning dates | ||
96 | + grayMode: boolean; | ||
97 | + // Whether to turn on the color weak mode | ||
98 | + colorWeak: boolean; | ||
99 | + // Theme color | ||
100 | + themeColor: string; | ||
101 | + | ||
102 | + // The main interface is displayed in full screen, the menu is not displayed, and the top | ||
103 | + fullContent: boolean; | ||
104 | + // content width | ||
105 | + contentMode: ContentEnum; | ||
106 | + // Whether to display the logo | ||
107 | + showLogo: boolean; | ||
108 | + // Whether to show the global footer | ||
109 | + showFooter: boolean; | ||
110 | + // menuType: MenuTypeEnum; | ||
111 | + headerSetting: HeaderSetting; | ||
112 | + // menuSetting | ||
113 | + menuSetting: MenuSetting; | ||
114 | + // Multi-tab settings | ||
115 | + multiTabsSetting: MultiTabsSetting; | ||
116 | + // Animation configuration | ||
117 | + transitionSetting: TransitionSetting; | ||
118 | + // pageLayout whether to enable keep-alive | ||
119 | + openKeepAlive: boolean; | ||
120 | + // Lock screen time | ||
121 | + lockTime: number; | ||
122 | + // Show breadcrumbs | ||
123 | + showBreadCrumb: boolean; | ||
124 | + // Show breadcrumb icon | ||
125 | + showBreadCrumbIcon: boolean; | ||
126 | + // Use error-handler-plugin | ||
127 | + useErrorHandle: boolean; | ||
128 | + // Whether to open back to top | ||
129 | + useOpenBackTop: boolean; | ||
130 | + // Is it possible to embed iframe pages | ||
131 | + canEmbedIFramePage: boolean; | ||
132 | + // Whether to delete unclosed messages and notify when switching the interface | ||
133 | + closeMessageOnSwitch: boolean; | ||
134 | + // Whether to cancel the http request that has been sent but not responded when switching the interface. | ||
135 | + removeAllHttpPending: boolean; | ||
136 | +} | ||
137 | + | ||
138 | +export interface GlobConfig { | ||
139 | + // Site title | ||
140 | + title: string; | ||
141 | + // Service interface url | ||
142 | + apiUrl: string; | ||
143 | + // Upload url | ||
144 | + uploadUrl?: string; | ||
145 | + // Service interface url prefix | ||
146 | + urlPrefix?: string; | ||
147 | + // Project abbreviation | ||
148 | + shortName: string; | ||
149 | + // configuration center proxy prefix | ||
150 | + configurationPrefix: string; | ||
151 | + // socket url | ||
152 | + socketUrl: string; | ||
153 | + // alarm notify alarm duration | ||
154 | + alarmNotifyDuration: string; | ||
155 | + // alarm notify polling interval | ||
156 | + alarmPollingInterval: string; | ||
157 | + // upgrade your http policy to https | ||
158 | + securityPolicy: string; | ||
159 | +} | ||
160 | +export interface GlobEnvConfig { | ||
161 | + // Site title | ||
162 | + VITE_GLOB_APP_TITLE: string; | ||
163 | + // Service interface url | ||
164 | + VITE_GLOB_API_URL: string; | ||
165 | + // Service interface url prefix | ||
166 | + VITE_GLOB_API_URL_PREFIX?: string; | ||
167 | + // Project abbreviation | ||
168 | + VITE_GLOB_APP_SHORT_NAME: string; | ||
169 | + // Upload url | ||
170 | + VITE_GLOB_UPLOAD_URL?: string; | ||
171 | + // configuration | ||
172 | + VITE_GLOB_CONFIGURATION: string; | ||
173 | + // socket | ||
174 | + VITE_GLOB_WEB_SOCKET: string; | ||
175 | + // force transform http to https | ||
176 | + VITE_GLOB_CONTENT_SECURITY_POLICY: string; | ||
177 | + // notify polling interval time | ||
178 | + VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME: string; | ||
179 | + // notify duration | ||
180 | + VITE_GLOB_ALARM_NOTIFY_DURATION: string; | ||
181 | +} |
types/external/global.d.ts
0 → 100644
1 | +import type { | ||
2 | + ComponentRenderProxy, | ||
3 | + VNode, | ||
4 | + VNodeChild, | ||
5 | + ComponentPublicInstance, | ||
6 | + FunctionalComponent, | ||
7 | + PropType as VuePropType, | ||
8 | +} from 'vue'; | ||
9 | + | ||
10 | +declare global { | ||
11 | + const __APP_INFO__: { | ||
12 | + pkg: { | ||
13 | + name: string; | ||
14 | + version: string; | ||
15 | + dependencies: Recordable<string>; | ||
16 | + devDependencies: Recordable<string>; | ||
17 | + }; | ||
18 | + lastBuildTime: string; | ||
19 | + }; | ||
20 | + // declare interface Window { | ||
21 | + // // Global vue app instance | ||
22 | + // __APP__: App<Element>; | ||
23 | + // } | ||
24 | + | ||
25 | + // vue | ||
26 | + declare type PropType<T> = VuePropType<T>; | ||
27 | + declare type VueNode = VNodeChild | JSX.Element; | ||
28 | + | ||
29 | + export type Writable<T> = { | ||
30 | + -readonly [P in keyof T]: T[P]; | ||
31 | + }; | ||
32 | + | ||
33 | + declare type Nullable<T> = T | null; | ||
34 | + declare type NonNullable<T> = T extends null | undefined ? never : T; | ||
35 | + declare type Recordable<T = any> = Record<string, T>; | ||
36 | + declare type ReadonlyRecordable<T = any> = { | ||
37 | + readonly [key: string]: T; | ||
38 | + }; | ||
39 | + declare type Indexable<T = any> = { | ||
40 | + [key: string]: T; | ||
41 | + }; | ||
42 | + declare type DeepPartial<T> = { | ||
43 | + [P in keyof T]?: DeepPartial<T[P]>; | ||
44 | + }; | ||
45 | + declare type TimeoutHandle = ReturnType<typeof setTimeout>; | ||
46 | + declare type IntervalHandle = ReturnType<typeof setInterval>; | ||
47 | + | ||
48 | + declare interface ChangeEvent extends Event { | ||
49 | + target: HTMLInputElement; | ||
50 | + } | ||
51 | + | ||
52 | + declare interface WheelEvent { | ||
53 | + path?: EventTarget[]; | ||
54 | + } | ||
55 | + interface ImportMetaEnv extends ViteEnv { | ||
56 | + __: unknown; | ||
57 | + } | ||
58 | + | ||
59 | + declare interface ViteEnv { | ||
60 | + VITE_PORT: number; | ||
61 | + VITE_GLOB_USE_MOCK: boolean; | ||
62 | + VITE_USE_PWA: boolean; | ||
63 | + VITE_GLOB_PUBLIC_PATH: string; | ||
64 | + VITE_PROXY: [string, string][]; | ||
65 | + VITE_GLOB_APP_TITLE: string; | ||
66 | + VITE_GLOB_APP_SHORT_NAME: string; | ||
67 | + VITE_USE_CDN: boolean; | ||
68 | + VITE_GLOB_DROP_CONSOLE: boolean; | ||
69 | + VITE_GLOB_BUILD_COMPRESS: 'gzip' | 'brotli' | 'none'; | ||
70 | + VITE_GLOB_BUILD_COMPRESS_DELETE_ORIGIN_FILE: boolean; | ||
71 | + VITE_LEGACY: boolean; | ||
72 | + VITE_GLOB_USE_IMAGEMIN: boolean; | ||
73 | + VITE_GENERATE_UI: string; | ||
74 | + VITE_GLOB_CONTENT_SECURITY_POLICY: boolean; | ||
75 | + VITE_GLOB_ALARM_NOTIFY_POLLING_INTERVAL_TIME: number; | ||
76 | + VITE_GLOB_ALARM_NOTIFY_DURATION: number; | ||
77 | + } | ||
78 | + | ||
79 | + declare function parseInt(s: string | number, radix?: number): number; | ||
80 | + | ||
81 | + declare function parseFloat(string: string | number): number; | ||
82 | + | ||
83 | + namespace JSX { | ||
84 | + // tslint:disable no-empty-interface | ||
85 | + type Element = VNode; | ||
86 | + // tslint:disable no-empty-interface | ||
87 | + type ElementClass = ComponentRenderProxy; | ||
88 | + interface ElementAttributesProperty { | ||
89 | + $props: any; | ||
90 | + } | ||
91 | + interface IntrinsicElements { | ||
92 | + [elem: string]: any; | ||
93 | + } | ||
94 | + interface IntrinsicAttributes { | ||
95 | + [elem: string]: any; | ||
96 | + } | ||
97 | + } | ||
98 | +} | ||
99 | + | ||
100 | +declare module 'vue' { | ||
101 | + export type JSXComponent<Props = any> = | ||
102 | + | { new (): ComponentPublicInstance<Props> } | ||
103 | + | FunctionalComponent<Props>; | ||
104 | +} |
types/external/index.d.ts
0 → 100644
1 | +declare interface Fn<T = any, R = T> { | ||
2 | + (...arg: T[]): R; | ||
3 | +} | ||
4 | + | ||
5 | +declare interface PromiseFn<T = any, R = T> { | ||
6 | + (...arg: T[]): Promise<R>; | ||
7 | +} | ||
8 | + | ||
9 | +declare type RefType<T> = T | null; | ||
10 | + | ||
11 | +declare type LabelValueOptions = { | ||
12 | + label: string; | ||
13 | + value: any; | ||
14 | + [key: string]: string | number | boolean; | ||
15 | +}[]; | ||
16 | + | ||
17 | +declare type EmitType = (event: string, ...args: any[]) => void; | ||
18 | + | ||
19 | +declare type TargetContext = '_self' | '_blank'; | ||
20 | + | ||
21 | +declare interface ComponentElRef<T extends HTMLElement = HTMLDivElement> { | ||
22 | + $el: T; | ||
23 | +} | ||
24 | + | ||
25 | +declare type ComponentRef<T extends HTMLElement = HTMLDivElement> = ComponentElRef<T> | null; | ||
26 | + | ||
27 | +declare type ElRef<T extends HTMLElement = HTMLDivElement> = Nullable<T>; |
types/external/store.d.ts
0 → 100644
1 | +import { ErrorTypeEnum } from '/@/enums/exceptionEnum'; | ||
2 | +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; | ||
3 | +import { PlainRoleInfo } from '/@/api/sys/model/userModel'; | ||
4 | + | ||
5 | +// Lock screen information | ||
6 | +export interface LockInfo { | ||
7 | + // Password required | ||
8 | + pwd?: string | undefined; | ||
9 | + // Is it locked? | ||
10 | + isLock?: boolean; | ||
11 | +} | ||
12 | + | ||
13 | +// Error-log information | ||
14 | +export interface ErrorLogInfo { | ||
15 | + // Type of error | ||
16 | + type: ErrorTypeEnum; | ||
17 | + // Error file | ||
18 | + file: string; | ||
19 | + // Error name | ||
20 | + name?: string; | ||
21 | + // Error message | ||
22 | + message: string; | ||
23 | + // Error stack | ||
24 | + stack?: string; | ||
25 | + // Error detail | ||
26 | + detail: string; | ||
27 | + // Error url | ||
28 | + url: string; | ||
29 | + // Error time | ||
30 | + time?: string; | ||
31 | +} | ||
32 | + | ||
33 | +export interface UserInfo { | ||
34 | + userId?: string | number; | ||
35 | + username?: string; | ||
36 | + realName?: string; | ||
37 | + avatar?: string; | ||
38 | + homePath?: string; | ||
39 | + tenantCode?: string; | ||
40 | + tenantName?: string; | ||
41 | + roles?: string[]; | ||
42 | + plainRoles?: PlainRoleInfo[]; | ||
43 | + phoneNumber?: string; | ||
44 | + email?: string; | ||
45 | +} | ||
46 | + | ||
47 | +export interface BeforeMiniState { | ||
48 | + menuCollapsed?: boolean; | ||
49 | + menuSplit?: boolean; | ||
50 | + menuMode?: MenuModeEnum; | ||
51 | + menuType?: MenuTypeEnum; | ||
52 | +} | ||
53 | + | ||
54 | +export interface UserUpdateInfo { | ||
55 | + activateToken?: string; | ||
56 | + avatar?: string; | ||
57 | + createTime?: string; | ||
58 | + creator?: string; | ||
59 | + email?: string; | ||
60 | + enabled?: true; | ||
61 | + hasPassword?: false; | ||
62 | + id?: string; | ||
63 | + level?: 2; | ||
64 | + password?: string; | ||
65 | + phoneNumber?: string; | ||
66 | + realName?: string; | ||
67 | + tenantId?: string; | ||
68 | + updateTime?: string; | ||
69 | + updater?: string; | ||
70 | + username?: string; | ||
71 | +} |
1 | /// <reference types="vite/client" /> | 1 | /// <reference types="vite/client" /> |
2 | 2 | ||
3 | -interface ImportMetaEnv { | 3 | + |
4 | +declare interface GlobEnvConfig { | ||
4 | // 标题 | 5 | // 标题 |
5 | VITE_GLOB_APP_TITLE: string; | 6 | VITE_GLOB_APP_TITLE: string; |
7 | + // 公共路径 | ||
8 | + VITE_GLOB_PUBLIC_PATH: string | ||
9 | + // 代理地址 | ||
10 | + VITE_GLOB_PROXY: [string, string][] | ||
11 | + // 内容安全协议 | ||
12 | + VITE_GLOB_CONTENT_SECURITY_POLICY: boolean | ||
13 | + | ||
14 | + VITE_GLOB_APP_SHORT_NAME: string | ||
15 | +} | ||
16 | + | ||
17 | + | ||
18 | +declare type GlobConfig = { | ||
19 | + | ||
20 | +} | ||
21 | + | ||
22 | +declare interface ViteEnv extends GlobEnvConfig { | ||
6 | // 端口 | 23 | // 端口 |
7 | VITE_DEV_PORT: string; | 24 | VITE_DEV_PORT: string; |
8 | // 开发地址 | 25 | // 开发地址 |
9 | VITE_DEV_PATH: string | 26 | VITE_DEV_PATH: string |
10 | // 生产地址 | 27 | // 生产地址 |
11 | VITE_PRO_PATH: string | 28 | VITE_PRO_PATH: string |
12 | -} | ||
29 | +} | ||
30 | + | ||
31 | +interface ImportMetaEnv extends ViteEnv { | ||
32 | +} | ||
33 | + |
1 | -import { defineConfig } from 'vite' | 1 | +import { defineConfig, loadEnv } from 'vite' |
2 | import vue from '@vitejs/plugin-vue' | 2 | import vue from '@vitejs/plugin-vue' |
3 | import { resolve } from 'path' | 3 | import { resolve } from 'path' |
4 | import { OUTPUT_DIR, brotliSize, chunkSizeWarningLimit, terserOptions, rollupOptions } from './build/constant' | 4 | import { OUTPUT_DIR, brotliSize, chunkSizeWarningLimit, terserOptions, rollupOptions } from './build/constant' |
5 | import viteCompression from 'vite-plugin-compression' | 5 | import viteCompression from 'vite-plugin-compression' |
6 | import { viteMockServe } from 'vite-plugin-mock' | 6 | import { viteMockServe } from 'vite-plugin-mock' |
7 | import monacoEditorPlugin from 'vite-plugin-monaco-editor' | 7 | import monacoEditorPlugin from 'vite-plugin-monaco-editor' |
8 | +import { createProxy } from './build/external/vite/proxy' | ||
9 | +import { parseEnv } from './build/external/utils' | ||
10 | +import { GenerateBuildConfig } from './build/external/globConfig' | ||
8 | 11 | ||
9 | function pathResolve(dir: string) { | 12 | function pathResolve(dir: string) { |
10 | return resolve(process.cwd(), '.', dir) | 13 | return resolve(process.cwd(), '.', dir) |
11 | } | 14 | } |
12 | 15 | ||
13 | -export default defineConfig({ | ||
14 | - base: '/', | ||
15 | - // 路径重定向 | ||
16 | - resolve: { | ||
17 | - alias: [ | ||
18 | - { | ||
19 | - find: /\/#\//, | ||
20 | - replacement: pathResolve('types') | ||
21 | - }, | ||
22 | - { | ||
23 | - find: '@', | ||
24 | - replacement: pathResolve('src') | ||
25 | - }, | ||
26 | - { | ||
27 | - find: 'vue-i18n', | ||
28 | - replacement: 'vue-i18n/dist/vue-i18n.cjs.js', //解决i8n警告 | 16 | +export default defineConfig(({ mode, command }) => { |
17 | + | ||
18 | + const root = process.cwd() | ||
19 | + | ||
20 | + const env = loadEnv(mode, root) | ||
21 | + | ||
22 | + const viteEnv = parseEnv(env) | ||
23 | + | ||
24 | + const isBuild = command === 'build' | ||
25 | + | ||
26 | + return { | ||
27 | + base: '/', | ||
28 | + // 路径重定向 | ||
29 | + resolve: { | ||
30 | + alias: [ | ||
31 | + { | ||
32 | + find: /\/#\//, | ||
33 | + replacement: pathResolve('types') | ||
34 | + }, | ||
35 | + { | ||
36 | + find: '@', | ||
37 | + replacement: pathResolve('src') | ||
38 | + }, | ||
39 | + { | ||
40 | + find: 'vue-i18n', | ||
41 | + replacement: 'vue-i18n/dist/vue-i18n.cjs.js', //解决i8n警告 | ||
42 | + } | ||
43 | + ], | ||
44 | + dedupe: ['vue'] | ||
45 | + }, | ||
46 | + // 全局 css 注册 | ||
47 | + css: { | ||
48 | + preprocessorOptions: { | ||
49 | + scss: { | ||
50 | + javascriptEnabled: true, | ||
51 | + additionalData: `@import "src/styles/common/style.scss";` | ||
52 | + } | ||
29 | } | 53 | } |
54 | + }, | ||
55 | + plugins: [ | ||
56 | + vue(), | ||
57 | + monacoEditorPlugin({ | ||
58 | + languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html'] | ||
59 | + }), | ||
60 | + viteMockServe({ | ||
61 | + mockPath: '/src/api/mock', | ||
62 | + // 开发打包开关 | ||
63 | + localEnabled: true, | ||
64 | + // 生产打包开关 | ||
65 | + prodEnabled: true, | ||
66 | + // 打开后,可以读取 ts 文件模块。 请注意,打开后将无法监视.js 文件 | ||
67 | + supportTs: true, | ||
68 | + // 监视文件更改 | ||
69 | + watchFiles: true | ||
70 | + }), | ||
71 | + // 压缩 | ||
72 | + viteCompression({ | ||
73 | + verbose: true, | ||
74 | + disable: false, | ||
75 | + threshold: 10240, | ||
76 | + algorithm: 'gzip', | ||
77 | + ext: '.gz' | ||
78 | + }), | ||
79 | + GenerateBuildConfig(viteEnv) | ||
30 | ], | 80 | ], |
31 | - dedupe: ['vue'] | ||
32 | - }, | ||
33 | - // 全局 css 注册 | ||
34 | - css: { | ||
35 | - preprocessorOptions: { | ||
36 | - scss: { | ||
37 | - javascriptEnabled: true, | ||
38 | - additionalData: `@import "src/styles/common/style.scss";` | ||
39 | - } | 81 | + build: { |
82 | + target: 'es2015', | ||
83 | + outDir: OUTPUT_DIR, | ||
84 | + // minify: 'terser', // 如果需要用terser混淆,可打开这两行 | ||
85 | + // terserOptions: terserOptions, | ||
86 | + rollupOptions: rollupOptions, | ||
87 | + brotliSize: brotliSize, | ||
88 | + chunkSizeWarningLimit: chunkSizeWarningLimit | ||
89 | + }, | ||
90 | + server: { | ||
91 | + proxy: createProxy(viteEnv) | ||
40 | } | 92 | } |
41 | - }, | ||
42 | - plugins: [ | ||
43 | - vue(), | ||
44 | - monacoEditorPlugin({ | ||
45 | - languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html'] | ||
46 | - }), | ||
47 | - viteMockServe({ | ||
48 | - mockPath: '/src/api/mock', | ||
49 | - // 开发打包开关 | ||
50 | - localEnabled: true, | ||
51 | - // 生产打包开关 | ||
52 | - prodEnabled: true, | ||
53 | - // 打开后,可以读取 ts 文件模块。 请注意,打开后将无法监视.js 文件 | ||
54 | - supportTs: true, | ||
55 | - // 监视文件更改 | ||
56 | - watchFiles: true | ||
57 | - }), | ||
58 | - // 压缩 | ||
59 | - viteCompression({ | ||
60 | - verbose: true, | ||
61 | - disable: false, | ||
62 | - threshold: 10240, | ||
63 | - algorithm: 'gzip', | ||
64 | - ext: '.gz' | ||
65 | - }) | ||
66 | - ], | ||
67 | - build: { | ||
68 | - target: 'es2015', | ||
69 | - outDir: OUTPUT_DIR, | ||
70 | - // minify: 'terser', // 如果需要用terser混淆,可打开这两行 | ||
71 | - // terserOptions: terserOptions, | ||
72 | - rollupOptions: rollupOptions, | ||
73 | - brotliSize: brotliSize, | ||
74 | - chunkSizeWarningLimit: chunkSizeWarningLimit | ||
75 | } | 93 | } |
76 | -}) | 94 | +} |
95 | +) |