mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-18 17:46:38 +08:00
feat(projects): 迁移登录完成
This commit is contained in:
parent
f5a36a05cb
commit
b93b80cb4b
@ -1,14 +1,61 @@
|
|||||||
import type { MockMethod } from 'vite-plugin-mock';
|
import type { MockMethod } from 'vite-plugin-mock';
|
||||||
|
|
||||||
|
const token: ApiAuth.Token = {
|
||||||
|
token: '__TEMP_TOKEN__',
|
||||||
|
refreshToken: '__TEMP_REFRESH_TOKEN__'
|
||||||
|
};
|
||||||
|
|
||||||
const apis: MockMethod[] = [
|
const apis: MockMethod[] = [
|
||||||
|
// 获取验证码
|
||||||
{
|
{
|
||||||
url: '/mock/getUser',
|
url: '/mock/getSmsCode',
|
||||||
method: 'get',
|
method: 'post',
|
||||||
response: (): Service.BackendServiceResult => {
|
response: (): Service.BackendServiceResult<boolean> => {
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
message: 'ok',
|
message: 'ok',
|
||||||
data: '测试mock数据'
|
data: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 密码登录
|
||||||
|
{
|
||||||
|
url: '/mock/loginByPwd',
|
||||||
|
method: 'post',
|
||||||
|
response: (): Service.BackendServiceResult<ApiAuth.Token> => {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
message: 'ok',
|
||||||
|
data: token
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 验证码登录
|
||||||
|
{
|
||||||
|
url: '/mock/loginByCode',
|
||||||
|
method: 'post',
|
||||||
|
response: (): Service.BackendServiceResult<ApiAuth.Token> => {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
message: 'ok',
|
||||||
|
data: token
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取用户信息(请求头携带token)
|
||||||
|
{
|
||||||
|
url: '/mock/getUserInfo',
|
||||||
|
method: 'get',
|
||||||
|
response: (): Service.BackendServiceResult<ApiAuth.UserInfo> => {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
message: 'ok',
|
||||||
|
data: {
|
||||||
|
userId: '0',
|
||||||
|
userName: 'Soybean',
|
||||||
|
userPhone: '15170283876',
|
||||||
|
userRole: 'super'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ const routes: AuthRoute.Route[] = [
|
|||||||
|
|
||||||
const routeHome: AuthRoute.RoutePath = '/dashboard/analysis';
|
const routeHome: AuthRoute.RoutePath = '/dashboard/analysis';
|
||||||
|
|
||||||
const data: ApiRoute.ResponseRoute = {
|
const data: ApiRoute.Route = {
|
||||||
routes,
|
routes,
|
||||||
home: routeHome
|
home: routeHome
|
||||||
};
|
};
|
||||||
|
10
package.json
10
package.json
@ -37,13 +37,13 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^16.0.1",
|
"@commitlint/cli": "^16.0.1",
|
||||||
"@commitlint/config-conventional": "^16.0.0",
|
"@commitlint/config-conventional": "^16.0.0",
|
||||||
"@iconify/json": "^1.1.451",
|
"@iconify/json": "^1.1.452",
|
||||||
"@iconify/vue": "^3.1.1",
|
"@iconify/vue": "^3.1.1",
|
||||||
"@types/crypto-js": "^4.1.0",
|
"@types/crypto-js": "^4.1.0",
|
||||||
"@types/node": "^17.0.6",
|
"@types/node": "^17.0.6",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.8.1",
|
"@typescript-eslint/eslint-plugin": "^5.8.1",
|
||||||
"@typescript-eslint/parser": "^5.8.1",
|
"@typescript-eslint/parser": "^5.9.0",
|
||||||
"@vitejs/plugin-vue": "^2.0.1",
|
"@vitejs/plugin-vue": "^2.0.1",
|
||||||
"@vue/eslint-config-prettier": "^7.0.0",
|
"@vue/eslint-config-prettier": "^7.0.0",
|
||||||
"@vue/eslint-config-typescript": "^10.0.0",
|
"@vue/eslint-config-typescript": "^10.0.0",
|
||||||
@ -54,11 +54,11 @@
|
|||||||
"eslint": "^8.6.0",
|
"eslint": "^8.6.0",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.4",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^8.2.0",
|
"eslint-plugin-vue": "^8.2.0",
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"lint-staged": "^12.1.4",
|
"lint-staged": "^12.1.5",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"patch-package": "^6.4.7",
|
"patch-package": "^6.4.7",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"postinstall-postinstall": "^2.1.0",
|
||||||
@ -72,7 +72,7 @@
|
|||||||
"vite-plugin-html": "^2.1.2",
|
"vite-plugin-html": "^2.1.2",
|
||||||
"vite-plugin-mock": "^2.9.6",
|
"vite-plugin-mock": "^2.9.6",
|
||||||
"vite-plugin-windicss": "^1.6.1",
|
"vite-plugin-windicss": "^1.6.1",
|
||||||
"vue-tsc": "^0.30.1",
|
"vue-tsc": "^0.30.2",
|
||||||
"vueuc": "^0.4.19",
|
"vueuc": "^0.4.19",
|
||||||
"windicss": "^3.4.2"
|
"windicss": "^3.4.2"
|
||||||
}
|
}
|
||||||
|
350
pnpm-lock.yaml
350
pnpm-lock.yaml
@ -3,13 +3,13 @@ lockfileVersion: 5.3
|
|||||||
specifiers:
|
specifiers:
|
||||||
'@commitlint/cli': ^16.0.1
|
'@commitlint/cli': ^16.0.1
|
||||||
'@commitlint/config-conventional': ^16.0.0
|
'@commitlint/config-conventional': ^16.0.0
|
||||||
'@iconify/json': ^1.1.451
|
'@iconify/json': ^1.1.452
|
||||||
'@iconify/vue': ^3.1.1
|
'@iconify/vue': ^3.1.1
|
||||||
'@types/crypto-js': ^4.1.0
|
'@types/crypto-js': ^4.1.0
|
||||||
'@types/node': ^17.0.6
|
'@types/node': ^17.0.6
|
||||||
'@types/qs': ^6.9.7
|
'@types/qs': ^6.9.7
|
||||||
'@typescript-eslint/eslint-plugin': ^5.8.1
|
'@typescript-eslint/eslint-plugin': ^5.8.1
|
||||||
'@typescript-eslint/parser': ^5.8.1
|
'@typescript-eslint/parser': ^5.9.0
|
||||||
'@vitejs/plugin-vue': ^2.0.1
|
'@vitejs/plugin-vue': ^2.0.1
|
||||||
'@vue/eslint-config-prettier': ^7.0.0
|
'@vue/eslint-config-prettier': ^7.0.0
|
||||||
'@vue/eslint-config-typescript': ^10.0.0
|
'@vue/eslint-config-typescript': ^10.0.0
|
||||||
@ -25,12 +25,12 @@ specifiers:
|
|||||||
eslint: ^8.6.0
|
eslint: ^8.6.0
|
||||||
eslint-config-airbnb-base: ^15.0.0
|
eslint-config-airbnb-base: ^15.0.0
|
||||||
eslint-config-prettier: ^8.3.0
|
eslint-config-prettier: ^8.3.0
|
||||||
eslint-plugin-import: ^2.25.3
|
eslint-plugin-import: ^2.25.4
|
||||||
eslint-plugin-prettier: ^4.0.0
|
eslint-plugin-prettier: ^4.0.0
|
||||||
eslint-plugin-vue: ^8.2.0
|
eslint-plugin-vue: ^8.2.0
|
||||||
form-data: ^4.0.0
|
form-data: ^4.0.0
|
||||||
husky: ^7.0.4
|
husky: ^7.0.4
|
||||||
lint-staged: ^12.1.4
|
lint-staged: ^12.1.5
|
||||||
lodash-es: ^4.17.21
|
lodash-es: ^4.17.21
|
||||||
mockjs: ^1.1.0
|
mockjs: ^1.1.0
|
||||||
naive-ui: ^2.23.2
|
naive-ui: ^2.23.2
|
||||||
@ -50,7 +50,7 @@ specifiers:
|
|||||||
vite-plugin-windicss: ^1.6.1
|
vite-plugin-windicss: ^1.6.1
|
||||||
vue: ^3.2.26
|
vue: ^3.2.26
|
||||||
vue-router: ^4.0.12
|
vue-router: ^4.0.12
|
||||||
vue-tsc: ^0.30.1
|
vue-tsc: ^0.30.2
|
||||||
vueuc: ^0.4.19
|
vueuc: ^0.4.19
|
||||||
windicss: ^3.4.2
|
windicss: ^3.4.2
|
||||||
|
|
||||||
@ -71,13 +71,13 @@ dependencies:
|
|||||||
devDependencies:
|
devDependencies:
|
||||||
'@commitlint/cli': registry.npmmirror.com/@commitlint/cli/16.0.1_@types+node@17.0.6
|
'@commitlint/cli': registry.npmmirror.com/@commitlint/cli/16.0.1_@types+node@17.0.6
|
||||||
'@commitlint/config-conventional': registry.npmmirror.com/@commitlint/config-conventional/16.0.0
|
'@commitlint/config-conventional': registry.npmmirror.com/@commitlint/config-conventional/16.0.0
|
||||||
'@iconify/json': registry.npmmirror.com/@iconify/json/1.1.451
|
'@iconify/json': registry.npmmirror.com/@iconify/json/1.1.452
|
||||||
'@iconify/vue': registry.npmmirror.com/@iconify/vue/3.1.1_vue@3.2.26
|
'@iconify/vue': registry.npmmirror.com/@iconify/vue/3.1.1_vue@3.2.26
|
||||||
'@types/crypto-js': registry.npmmirror.com/@types/crypto-js/4.1.0
|
'@types/crypto-js': registry.npmmirror.com/@types/crypto-js/4.1.0
|
||||||
'@types/node': registry.npmmirror.com/@types/node/17.0.6
|
'@types/node': registry.npmmirror.com/@types/node/17.0.6
|
||||||
'@types/qs': registry.npmmirror.com/@types/qs/6.9.7
|
'@types/qs': registry.npmmirror.com/@types/qs/6.9.7
|
||||||
'@typescript-eslint/eslint-plugin': registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_13039593e64cd539d0b4c5c2da390958
|
'@typescript-eslint/eslint-plugin': registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_bd2fd93dbcc607ad2f21b784bccfe0c8
|
||||||
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.8.1_eslint@8.6.0+typescript@4.5.4
|
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.9.0_eslint@8.6.0+typescript@4.5.4
|
||||||
'@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/2.0.1_vite@2.7.10+vue@3.2.26
|
'@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/2.0.1_vite@2.7.10+vue@3.2.26
|
||||||
'@vue/eslint-config-prettier': registry.npmmirror.com/@vue/eslint-config-prettier/7.0.0_eslint@8.6.0+prettier@2.5.1
|
'@vue/eslint-config-prettier': registry.npmmirror.com/@vue/eslint-config-prettier/7.0.0_eslint@8.6.0+prettier@2.5.1
|
||||||
'@vue/eslint-config-typescript': registry.npmmirror.com/@vue/eslint-config-typescript/10.0.0_57f850728139557a3a27f1248f77f964
|
'@vue/eslint-config-typescript': registry.npmmirror.com/@vue/eslint-config-typescript/10.0.0_57f850728139557a3a27f1248f77f964
|
||||||
@ -86,13 +86,13 @@ devDependencies:
|
|||||||
cz-conventional-changelog: registry.nlark.com/cz-conventional-changelog/3.3.0_@types+node@17.0.6
|
cz-conventional-changelog: registry.nlark.com/cz-conventional-changelog/3.3.0_@types+node@17.0.6
|
||||||
cz-customizable: registry.npmmirror.com/cz-customizable/6.3.0
|
cz-customizable: registry.npmmirror.com/cz-customizable/6.3.0
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
eslint-config-airbnb-base: registry.npmmirror.com/eslint-config-airbnb-base/15.0.0_b54597effeb7d09a84a334cc3c3dadae
|
eslint-config-airbnb-base: registry.npmmirror.com/eslint-config-airbnb-base/15.0.0_b5a36b8c1535387c8dd00eff7ec6b551
|
||||||
eslint-config-prettier: registry.nlark.com/eslint-config-prettier/8.3.0_eslint@8.6.0
|
eslint-config-prettier: registry.nlark.com/eslint-config-prettier/8.3.0_eslint@8.6.0
|
||||||
eslint-plugin-import: registry.npmmirror.com/eslint-plugin-import/2.25.3_eslint@8.6.0
|
eslint-plugin-import: registry.npmmirror.com/eslint-plugin-import/2.25.4_eslint@8.6.0
|
||||||
eslint-plugin-prettier: registry.npmmirror.com/eslint-plugin-prettier/4.0.0_1c588f61426b1faf18812943f1678311
|
eslint-plugin-prettier: registry.npmmirror.com/eslint-plugin-prettier/4.0.0_1c588f61426b1faf18812943f1678311
|
||||||
eslint-plugin-vue: registry.npmmirror.com/eslint-plugin-vue/8.2.0_eslint@8.6.0
|
eslint-plugin-vue: registry.npmmirror.com/eslint-plugin-vue/8.2.0_eslint@8.6.0
|
||||||
husky: registry.npmmirror.com/husky/7.0.4
|
husky: registry.npmmirror.com/husky/7.0.4
|
||||||
lint-staged: registry.npmmirror.com/lint-staged/12.1.4
|
lint-staged: registry.npmmirror.com/lint-staged/12.1.5
|
||||||
mockjs: registry.npmmirror.com/mockjs/1.1.0
|
mockjs: registry.npmmirror.com/mockjs/1.1.0
|
||||||
patch-package: registry.nlark.com/patch-package/6.4.7
|
patch-package: registry.nlark.com/patch-package/6.4.7
|
||||||
postinstall-postinstall: registry.npmmirror.com/postinstall-postinstall/2.1.0
|
postinstall-postinstall: registry.npmmirror.com/postinstall-postinstall/2.1.0
|
||||||
@ -106,7 +106,7 @@ devDependencies:
|
|||||||
vite-plugin-html: registry.npmmirror.com/vite-plugin-html/2.1.2_vite@2.7.10
|
vite-plugin-html: registry.npmmirror.com/vite-plugin-html/2.1.2_vite@2.7.10
|
||||||
vite-plugin-mock: registry.npmmirror.com/vite-plugin-mock/2.9.6_mockjs@1.1.0+vite@2.7.10
|
vite-plugin-mock: registry.npmmirror.com/vite-plugin-mock/2.9.6_mockjs@1.1.0+vite@2.7.10
|
||||||
vite-plugin-windicss: registry.npmmirror.com/vite-plugin-windicss/1.6.1_vite@2.7.10
|
vite-plugin-windicss: registry.npmmirror.com/vite-plugin-windicss/1.6.1_vite@2.7.10
|
||||||
vue-tsc: registry.npmmirror.com/vue-tsc/0.30.1_typescript@4.5.4
|
vue-tsc: registry.npmmirror.com/vue-tsc/0.30.2_typescript@4.5.4
|
||||||
vueuc: registry.npmmirror.com/vueuc/0.4.19_vue@3.2.26
|
vueuc: registry.npmmirror.com/vueuc/0.4.19_vue@3.2.26
|
||||||
windicss: registry.npmmirror.com/windicss/3.4.2
|
windicss: registry.npmmirror.com/windicss/3.4.2
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dependencies:
|
dependencies:
|
||||||
normalize-path: registry.nlark.com/normalize-path/3.0.0
|
normalize-path: registry.nlark.com/normalize-path/3.0.0
|
||||||
picomatch: registry.nlark.com/picomatch/2.3.0
|
picomatch: registry.npmmirror.com/picomatch/2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/argparse/2.0.1:
|
registry.nlark.com/argparse/2.0.1:
|
||||||
@ -919,7 +919,7 @@ packages:
|
|||||||
version: 0.3.6
|
version: 0.3.6
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: registry.npmmirror.com/debug/3.2.7
|
debug: registry.npmmirror.com/debug/3.2.7
|
||||||
resolve: registry.nlark.com/resolve/1.20.0
|
resolve: registry.npmmirror.com/resolve/1.20.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/eslint-utils/3.0.0_eslint@8.6.0:
|
registry.nlark.com/eslint-utils/3.0.0_eslint@8.6.0:
|
||||||
@ -1675,7 +1675,7 @@ packages:
|
|||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
is-promise: registry.nlark.com/is-promise/2.2.2
|
is-promise: registry.nlark.com/is-promise/2.2.2
|
||||||
promise: registry.nlark.com/promise/7.3.1
|
promise: registry.npmmirror.com/promise/7.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/kind-of/6.0.3:
|
registry.nlark.com/kind-of/6.0.3:
|
||||||
@ -1806,7 +1806,7 @@ packages:
|
|||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
braces: registry.nlark.com/braces/3.0.2
|
braces: registry.nlark.com/braces/3.0.2
|
||||||
picomatch: registry.nlark.com/picomatch/2.3.0
|
picomatch: registry.npmmirror.com/picomatch/2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/mimic-fn/1.2.0:
|
registry.nlark.com/mimic-fn/1.2.0:
|
||||||
@ -1888,7 +1888,7 @@ packages:
|
|||||||
version: 2.5.0
|
version: 2.5.0
|
||||||
dependencies:
|
dependencies:
|
||||||
hosted-git-info: registry.npmmirror.com/hosted-git-info/2.8.9
|
hosted-git-info: registry.npmmirror.com/hosted-git-info/2.8.9
|
||||||
resolve: registry.nlark.com/resolve/1.20.0
|
resolve: registry.npmmirror.com/resolve/1.20.0
|
||||||
semver: registry.nlark.com/semver/5.7.1
|
semver: registry.nlark.com/semver/5.7.1
|
||||||
validate-npm-package-license: registry.nlark.com/validate-npm-package-license/3.0.4
|
validate-npm-package-license: registry.nlark.com/validate-npm-package-license/3.0.4
|
||||||
dev: true
|
dev: true
|
||||||
@ -2186,14 +2186,6 @@ packages:
|
|||||||
fast-diff: registry.nlark.com/fast-diff/1.2.0
|
fast-diff: registry.nlark.com/fast-diff/1.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/promise/7.3.1:
|
|
||||||
resolution: {integrity: sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/promise/download/promise-7.3.1.tgz}
|
|
||||||
name: promise
|
|
||||||
version: 7.3.1
|
|
||||||
dependencies:
|
|
||||||
asap: registry.nlark.com/asap/2.0.6
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
registry.nlark.com/pug-attrs/3.0.0:
|
registry.nlark.com/pug-attrs/3.0.0:
|
||||||
resolution: {integrity: sha1-sQRR4DSBZeMfrRzCPr3dncc0fEE=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/pug-attrs/download/pug-attrs-3.0.0.tgz}
|
resolution: {integrity: sha1-sQRR4DSBZeMfrRzCPr3dncc0fEE=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/pug-attrs/download/pug-attrs-3.0.0.tgz}
|
||||||
name: pug-attrs
|
name: pug-attrs
|
||||||
@ -2228,7 +2220,7 @@ packages:
|
|||||||
jstransformer: registry.nlark.com/jstransformer/1.0.0
|
jstransformer: registry.nlark.com/jstransformer/1.0.0
|
||||||
pug-error: registry.npmmirror.com/pug-error/2.0.0
|
pug-error: registry.npmmirror.com/pug-error/2.0.0
|
||||||
pug-walk: registry.nlark.com/pug-walk/2.0.0
|
pug-walk: registry.nlark.com/pug-walk/2.0.0
|
||||||
resolve: registry.nlark.com/resolve/1.20.0
|
resolve: registry.npmmirror.com/resolve/1.20.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/pug-lexer/5.0.1:
|
registry.nlark.com/pug-lexer/5.0.1:
|
||||||
@ -2288,21 +2280,6 @@ packages:
|
|||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/pug/3.0.2:
|
|
||||||
resolution: {integrity: sha1-81xxBzQ0VOQ7wnrg/3bHMbeOpTU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/pug/download/pug-3.0.2.tgz}
|
|
||||||
name: pug
|
|
||||||
version: 3.0.2
|
|
||||||
dependencies:
|
|
||||||
pug-code-gen: registry.nlark.com/pug-code-gen/3.0.2
|
|
||||||
pug-filters: registry.nlark.com/pug-filters/4.0.0
|
|
||||||
pug-lexer: registry.nlark.com/pug-lexer/5.0.1
|
|
||||||
pug-linker: registry.nlark.com/pug-linker/4.0.0
|
|
||||||
pug-load: registry.nlark.com/pug-load/3.0.0
|
|
||||||
pug-parser: registry.nlark.com/pug-parser/6.0.0
|
|
||||||
pug-runtime: registry.nlark.com/pug-runtime/3.0.1
|
|
||||||
pug-strip-comments: registry.nlark.com/pug-strip-comments/2.0.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
registry.nlark.com/punycode/2.1.1:
|
registry.nlark.com/punycode/2.1.1:
|
||||||
resolution: {integrity: sha1-tYsBCsQMIsVldhbI0sLALHv0eew=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/punycode/download/punycode-2.1.1.tgz}
|
resolution: {integrity: sha1-tYsBCsQMIsVldhbI0sLALHv0eew=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/punycode/download/punycode-2.1.1.tgz}
|
||||||
name: punycode
|
name: punycode
|
||||||
@ -2352,7 +2329,7 @@ packages:
|
|||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
engines: {node: '>=8.10.0'}
|
engines: {node: '>=8.10.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
picomatch: registry.nlark.com/picomatch/2.3.0
|
picomatch: registry.npmmirror.com/picomatch/2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.nlark.com/redent/3.0.0:
|
registry.nlark.com/redent/3.0.0:
|
||||||
@ -3386,10 +3363,10 @@ packages:
|
|||||||
version: 1.2.1
|
version: 1.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@iconify/json/1.1.451:
|
registry.npmmirror.com/@iconify/json/1.1.452:
|
||||||
resolution: {integrity: sha512-A+GgU4xetmBfofDQSBNENRsbZo3vMZTF4pkCxFObWs+y9j/C/oGwJwqiV3yrU9jFecF/MkffBbwNFug8j5EAtw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/json/download/@iconify/json-1.1.451.tgz}
|
resolution: {integrity: sha512-3eUNfCvfap5dE4JUePnul+3wCuWMSqD1zC9oGHqob5FRbJ05tGQ/n0FsL7WthqO5C+dLaMUMNRRG5VRwMzyYfA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/json/download/@iconify/json-1.1.452.tgz}
|
||||||
name: '@iconify/json'
|
name: '@iconify/json'
|
||||||
version: 1.1.451
|
version: 1.1.452
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@iconify/types/1.0.12:
|
registry.npmmirror.com/@iconify/types/1.0.12:
|
||||||
@ -3443,7 +3420,7 @@ packages:
|
|||||||
builtin-modules: registry.nlark.com/builtin-modules/3.2.0
|
builtin-modules: registry.nlark.com/builtin-modules/3.2.0
|
||||||
deepmerge: registry.nlark.com/deepmerge/4.2.2
|
deepmerge: registry.nlark.com/deepmerge/4.2.2
|
||||||
is-module: registry.npmmirror.com/is-module/1.0.0
|
is-module: registry.npmmirror.com/is-module/1.0.0
|
||||||
resolve: registry.nlark.com/resolve/1.20.0
|
resolve: registry.npmmirror.com/resolve/1.20.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@rollup/pluginutils/3.1.0:
|
registry.npmmirror.com/@rollup/pluginutils/3.1.0:
|
||||||
@ -3456,7 +3433,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': registry.npmmirror.com/@types/estree/0.0.39
|
'@types/estree': registry.npmmirror.com/@types/estree/0.0.39
|
||||||
estree-walker: registry.npmmirror.com/estree-walker/1.0.1
|
estree-walker: registry.npmmirror.com/estree-walker/1.0.1
|
||||||
picomatch: registry.nlark.com/picomatch/2.3.0
|
picomatch: registry.npmmirror.com/picomatch/2.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@rollup/pluginutils/4.1.2:
|
registry.npmmirror.com/@rollup/pluginutils/4.1.2:
|
||||||
@ -3594,7 +3571,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/yargs-parser': registry.npmmirror.com/@types/yargs-parser/20.2.1
|
'@types/yargs-parser': registry.npmmirror.com/@types/yargs-parser/20.2.1
|
||||||
|
|
||||||
registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_13039593e64cd539d0b4c5c2da390958:
|
registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_bd2fd93dbcc607ad2f21b784bccfe0c8:
|
||||||
resolution: {integrity: sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-5.8.1.tgz}
|
resolution: {integrity: sha512-wTZ5oEKrKj/8/366qTM366zqhIKAp6NCMweoRONtfuC07OAU9nVI2GZZdqQ1qD30WAAtcPdkH+npDwtRFdp4Rw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/download/@typescript-eslint/eslint-plugin-5.8.1.tgz}
|
||||||
id: registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1
|
id: registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1
|
||||||
name: '@typescript-eslint/eslint-plugin'
|
name: '@typescript-eslint/eslint-plugin'
|
||||||
@ -3609,7 +3586,7 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/experimental-utils': registry.npmmirror.com/@typescript-eslint/experimental-utils/5.8.1_eslint@8.6.0+typescript@4.5.4
|
'@typescript-eslint/experimental-utils': registry.npmmirror.com/@typescript-eslint/experimental-utils/5.8.1_eslint@8.6.0+typescript@4.5.4
|
||||||
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.8.1_eslint@8.6.0+typescript@4.5.4
|
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.9.0_eslint@8.6.0+typescript@4.5.4
|
||||||
'@typescript-eslint/scope-manager': registry.npmmirror.com/@typescript-eslint/scope-manager/5.8.1
|
'@typescript-eslint/scope-manager': registry.npmmirror.com/@typescript-eslint/scope-manager/5.8.1
|
||||||
debug: registry.npmmirror.com/debug/4.3.3
|
debug: registry.npmmirror.com/debug/4.3.3
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
@ -3644,11 +3621,11 @@ packages:
|
|||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@typescript-eslint/parser/5.8.1_eslint@8.6.0+typescript@4.5.4:
|
registry.npmmirror.com/@typescript-eslint/parser/5.9.0_eslint@8.6.0+typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-K1giKHAjHuyB421SoXMXFHHVI4NdNY603uKw92++D3qyxSeYvC10CBJ/GE5Thpo4WTUvu1mmJI2/FFkz38F2Gw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/parser/download/@typescript-eslint/parser-5.8.1.tgz}
|
resolution: {integrity: sha512-/6pOPz8yAxEt4PLzgbFRDpZmHnXCeZgPDrh/1DaVKOjvn/UPMlWhbx/gA96xRi2JxY1kBl2AmwVbyROUqys5xQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/parser/download/@typescript-eslint/parser-5.9.0.tgz}
|
||||||
id: registry.npmmirror.com/@typescript-eslint/parser/5.8.1
|
id: registry.npmmirror.com/@typescript-eslint/parser/5.9.0
|
||||||
name: '@typescript-eslint/parser'
|
name: '@typescript-eslint/parser'
|
||||||
version: 5.8.1
|
version: 5.9.0
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
@ -3657,9 +3634,9 @@ packages:
|
|||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': registry.npmmirror.com/@typescript-eslint/scope-manager/5.8.1
|
'@typescript-eslint/scope-manager': registry.npmmirror.com/@typescript-eslint/scope-manager/5.9.0
|
||||||
'@typescript-eslint/types': registry.npmmirror.com/@typescript-eslint/types/5.8.1
|
'@typescript-eslint/types': registry.npmmirror.com/@typescript-eslint/types/5.9.0
|
||||||
'@typescript-eslint/typescript-estree': registry.npmmirror.com/@typescript-eslint/typescript-estree/5.8.1_typescript@4.5.4
|
'@typescript-eslint/typescript-estree': registry.npmmirror.com/@typescript-eslint/typescript-estree/5.9.0_typescript@4.5.4
|
||||||
debug: registry.npmmirror.com/debug/4.3.3
|
debug: registry.npmmirror.com/debug/4.3.3
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
typescript: registry.npmmirror.com/typescript/4.5.4
|
typescript: registry.npmmirror.com/typescript/4.5.4
|
||||||
@ -3677,6 +3654,16 @@ packages:
|
|||||||
'@typescript-eslint/visitor-keys': registry.npmmirror.com/@typescript-eslint/visitor-keys/5.8.1
|
'@typescript-eslint/visitor-keys': registry.npmmirror.com/@typescript-eslint/visitor-keys/5.8.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/@typescript-eslint/scope-manager/5.9.0:
|
||||||
|
resolution: {integrity: sha512-DKtdIL49Qxk2a8icF6whRk7uThuVz4A6TCXfjdJSwOsf+9ree7vgQWcx0KOyCdk0i9ETX666p4aMhrRhxhUkyg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/scope-manager/download/@typescript-eslint/scope-manager-5.9.0.tgz}
|
||||||
|
name: '@typescript-eslint/scope-manager'
|
||||||
|
version: 5.9.0
|
||||||
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/types': registry.npmmirror.com/@typescript-eslint/types/5.9.0
|
||||||
|
'@typescript-eslint/visitor-keys': registry.npmmirror.com/@typescript-eslint/visitor-keys/5.9.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@typescript-eslint/types/5.8.1:
|
registry.npmmirror.com/@typescript-eslint/types/5.8.1:
|
||||||
resolution: {integrity: sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/types/download/@typescript-eslint/types-5.8.1.tgz}
|
resolution: {integrity: sha512-L/FlWCCgnjKOLefdok90/pqInkomLnAcF9UAzNr+DSqMC3IffzumHTQTrINXhP1gVp9zlHiYYjvozVZDPleLcA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/types/download/@typescript-eslint/types-5.8.1.tgz}
|
||||||
name: '@typescript-eslint/types'
|
name: '@typescript-eslint/types'
|
||||||
@ -3684,6 +3671,13 @@ packages:
|
|||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/@typescript-eslint/types/5.9.0:
|
||||||
|
resolution: {integrity: sha512-mWp6/b56Umo1rwyGCk8fPIzb9Migo8YOniBGPAQDNC6C52SeyNGN4gsVwQTAR+RS2L5xyajON4hOLwAGwPtUwg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/types/download/@typescript-eslint/types-5.9.0.tgz}
|
||||||
|
name: '@typescript-eslint/types'
|
||||||
|
version: 5.9.0
|
||||||
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@typescript-eslint/typescript-estree/5.8.1_typescript@4.5.4:
|
registry.npmmirror.com/@typescript-eslint/typescript-estree/5.8.1_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-5.8.1.tgz}
|
resolution: {integrity: sha512-26lQ8l8tTbG7ri7xEcCFT9ijU5Fk+sx/KRRyyzCv7MQ+rZZlqiDPtMKWLC8P7o+dtCnby4c+OlxuX1tp8WfafQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-5.8.1.tgz}
|
||||||
id: registry.npmmirror.com/@typescript-eslint/typescript-estree/5.8.1
|
id: registry.npmmirror.com/@typescript-eslint/typescript-estree/5.8.1
|
||||||
@ -3708,6 +3702,30 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/@typescript-eslint/typescript-estree/5.9.0_typescript@4.5.4:
|
||||||
|
resolution: {integrity: sha512-kxo3xL2mB7XmiVZcECbaDwYCt3qFXz99tBSuVJR4L/sR7CJ+UNAPrYILILktGj1ppfZ/jNt/cWYbziJUlHl1Pw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-5.9.0.tgz}
|
||||||
|
id: registry.npmmirror.com/@typescript-eslint/typescript-estree/5.9.0
|
||||||
|
name: '@typescript-eslint/typescript-estree'
|
||||||
|
version: 5.9.0
|
||||||
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/types': registry.npmmirror.com/@typescript-eslint/types/5.9.0
|
||||||
|
'@typescript-eslint/visitor-keys': registry.npmmirror.com/@typescript-eslint/visitor-keys/5.9.0
|
||||||
|
debug: registry.npmmirror.com/debug/4.3.3
|
||||||
|
globby: registry.nlark.com/globby/11.0.4
|
||||||
|
is-glob: registry.npmmirror.com/is-glob/4.0.3
|
||||||
|
semver: registry.nlark.com/semver/7.3.5
|
||||||
|
tsutils: registry.nlark.com/tsutils/3.21.0_typescript@4.5.4
|
||||||
|
typescript: registry.npmmirror.com/typescript/4.5.4
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@typescript-eslint/visitor-keys/5.8.1:
|
registry.npmmirror.com/@typescript-eslint/visitor-keys/5.8.1:
|
||||||
resolution: {integrity: sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/visitor-keys/download/@typescript-eslint/visitor-keys-5.8.1.tgz}
|
resolution: {integrity: sha512-SWgiWIwocK6NralrJarPZlWdr0hZnj5GXHIgfdm8hNkyKvpeQuFyLP6YjSIe9kf3YBIfU6OHSZLYkQ+smZwtNg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/visitor-keys/download/@typescript-eslint/visitor-keys-5.8.1.tgz}
|
||||||
name: '@typescript-eslint/visitor-keys'
|
name: '@typescript-eslint/visitor-keys'
|
||||||
@ -3718,6 +3736,16 @@ packages:
|
|||||||
eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/3.1.0
|
eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/3.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/@typescript-eslint/visitor-keys/5.9.0:
|
||||||
|
resolution: {integrity: sha512-6zq0mb7LV0ThExKlecvpfepiB+XEtFv/bzx7/jKSgyXTFD7qjmSu1FoiS0x3OZaiS+UIXpH2vd9O89f02RCtgw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@typescript-eslint/visitor-keys/download/@typescript-eslint/visitor-keys-5.9.0.tgz}
|
||||||
|
name: '@typescript-eslint/visitor-keys'
|
||||||
|
version: 5.9.0
|
||||||
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/types': registry.npmmirror.com/@typescript-eslint/types/5.9.0
|
||||||
|
eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/3.1.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@vitejs/plugin-vue/2.0.1_vite@2.7.10+vue@3.2.26:
|
registry.npmmirror.com/@vitejs/plugin-vue/2.0.1_vite@2.7.10+vue@3.2.26:
|
||||||
resolution: {integrity: sha512-wtdMnGVvys9K8tg+DxowU1ytTrdVveXr3LzdhaKakysgGXyrsfaeds2cDywtvujEASjWOwWL/OgWM+qoeM8Plg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/download/@vitejs/plugin-vue-2.0.1.tgz}
|
resolution: {integrity: sha512-wtdMnGVvys9K8tg+DxowU1ytTrdVveXr3LzdhaKakysgGXyrsfaeds2cDywtvujEASjWOwWL/OgWM+qoeM8Plg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/download/@vitejs/plugin-vue-2.0.1.tgz}
|
||||||
id: registry.npmmirror.com/@vitejs/plugin-vue/2.0.1
|
id: registry.npmmirror.com/@vitejs/plugin-vue/2.0.1
|
||||||
@ -3732,61 +3760,62 @@ packages:
|
|||||||
vue: registry.npmmirror.com/vue/3.2.26
|
vue: registry.npmmirror.com/vue/3.2.26
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/code-gen/0.30.1:
|
registry.npmmirror.com/@volar/code-gen/0.30.2:
|
||||||
resolution: {integrity: sha512-qPT0ZGzLaaUArZ1b5qcso2GAFpgjxsPDRXnq0lgsSOpNO6lXJN5ZcWzFZXYPjMJSV1Rkm0ehK5tSUD+sD+pPWg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/code-gen/download/@volar/code-gen-0.30.1.tgz}
|
resolution: {integrity: sha512-75rlb3rw/O/HiXxrOsVJ8JhEssqtN4dJ0i6oG4kL0udr+QM0TwN0PqaEhoMRyMFV6kBPPSunBBJQ3XNAb0PtGA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/code-gen/download/@volar/code-gen-0.30.2.tgz}
|
||||||
name: '@volar/code-gen'
|
name: '@volar/code-gen'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.1
|
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/html2pug/0.30.1:
|
registry.npmmirror.com/@volar/html2pug/0.30.2:
|
||||||
resolution: {integrity: sha512-ojJPrb4qSLrVNl9LTtdjZ5MFyeHmwJK4OVPTgFc/lyQ94nPS9JHba86SaTwDb2XEgiXBWQVEo12bRr3lW9H2+Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/html2pug/download/@volar/html2pug-0.30.1.tgz}
|
resolution: {integrity: sha512-k/DLGoXALaQgnacP1MoJ77AwnCHlKcsQKJJug8Qdou3+yOrzYjSSEP6uwG8BS0Fv1h4d4JYmlXsxW8gJPGXSQQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/html2pug/download/@volar/html2pug-0.30.2.tgz}
|
||||||
name: '@volar/html2pug'
|
name: '@volar/html2pug'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: registry.nlark.com/domelementtype/2.2.0
|
domelementtype: registry.nlark.com/domelementtype/2.2.0
|
||||||
domhandler: registry.npmmirror.com/domhandler/4.3.0
|
domhandler: registry.npmmirror.com/domhandler/4.3.0
|
||||||
htmlparser2: registry.npmmirror.com/htmlparser2/7.2.0
|
htmlparser2: registry.npmmirror.com/htmlparser2/7.2.0
|
||||||
pug: registry.nlark.com/pug/3.0.2
|
pug: registry.npmmirror.com/pug/3.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/shared/0.30.1:
|
registry.npmmirror.com/@volar/shared/0.30.2:
|
||||||
resolution: {integrity: sha512-6F5yQYeN+gbXAKplxHDvj4Ei+rHCjNhwkfZnGpaSpEU92uSI2vK/HfEdd/zTKdAZpwz0RjliNuFoXLi6umtQ0w==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/shared/download/@volar/shared-0.30.1.tgz}
|
resolution: {integrity: sha512-93Q7i758WjScg4ptvDcpk66r4Paz9StVMH/M5RCsU4/9F5a1xSCUJbkbpwE0zESkVzcuBatDqk79PaZ8TZKqRg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/shared/download/@volar/shared-0.30.2.tgz}
|
||||||
name: '@volar/shared'
|
name: '@volar/shared'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
upath: registry.nlark.com/upath/2.0.1
|
upath: registry.nlark.com/upath/2.0.1
|
||||||
vscode-jsonrpc: registry.npmmirror.com/vscode-jsonrpc/8.0.0-next.4
|
vscode-jsonrpc: registry.npmmirror.com/vscode-jsonrpc/8.0.0-next.4
|
||||||
vscode-uri: registry.npmmirror.com/vscode-uri/3.0.3
|
vscode-uri: registry.npmmirror.com/vscode-uri/3.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/source-map/0.30.1:
|
registry.npmmirror.com/@volar/source-map/0.30.2:
|
||||||
resolution: {integrity: sha512-QGi36KBGHZ4gq81jPSi3W2wRcpso9Apd59AZOv/H98k5hU9zo8wA5hwartZHiybTlT1q/0Yno3agSj+vK2vocw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/source-map/download/@volar/source-map-0.30.1.tgz}
|
resolution: {integrity: sha512-gwa9OiSjUOZWYutJX53m/KDU/zaF0yN3RP2B8J0aMVyT5dE/VaIfknSxPAW5QFC6AT79Ea1HKGtChuSBgqHCfA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/source-map/download/@volar/source-map-0.30.2.tgz}
|
||||||
name: '@volar/source-map'
|
name: '@volar/source-map'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
|
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/transforms/0.30.1:
|
registry.npmmirror.com/@volar/transforms/0.30.2:
|
||||||
resolution: {integrity: sha512-dWFyfQGLoZ8LZI93zud0c5uoCdlkwDBi90G/XaaKfXxkX+3eiJrM0lJ/d1Nc0L04t9mb28I5hpVK68vH90+Tlw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/transforms/download/@volar/transforms-0.30.1.tgz}
|
resolution: {integrity: sha512-bc+55NGlBbMLHkpChqAEgsblYJxjNHiKVMbVUMi52xKa2l9gOWXNbn5WRsHfz4AR+Cq/Zm0AvVJ10ehLQsGsow==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/transforms/download/@volar/transforms-0.30.2.tgz}
|
||||||
name: '@volar/transforms'
|
name: '@volar/transforms'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
vscode-languageserver: registry.npmmirror.com/vscode-languageserver/8.0.0-next.5
|
vscode-languageserver-types: registry.npmmirror.com/vscode-languageserver-types/3.17.0-next.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/@volar/vue-code-gen/0.30.1:
|
registry.npmmirror.com/@volar/vue-code-gen/0.30.2:
|
||||||
resolution: {integrity: sha512-+0egr84YOYLudP6jRXRm+xtAL92GTPaq0U0lsorLTBp/MB14Fap6HMUr/LEeNB5tnND36UQJiUWHM5eTDAAb4Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/vue-code-gen/download/@volar/vue-code-gen-0.30.1.tgz}
|
resolution: {integrity: sha512-kJyVkQFhMvVQ32aDaC6h5DdXG1GJbJjeeAkCnjfCJfMmuYjM5R4QNZHDz1TI0dETgF9vP+kbAukQKNWecHK3qg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@volar/vue-code-gen/download/@volar/vue-code-gen-0.30.2.tgz}
|
||||||
name: '@volar/vue-code-gen'
|
name: '@volar/vue-code-gen'
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.1
|
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.2
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.1
|
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.2
|
||||||
'@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.26
|
'@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.26
|
||||||
'@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.26
|
'@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.26
|
||||||
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.26
|
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.26
|
||||||
@ -3881,8 +3910,8 @@ packages:
|
|||||||
eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
|
||||||
eslint-plugin-vue: ^8.0.1
|
eslint-plugin-vue: ^8.0.1
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_13039593e64cd539d0b4c5c2da390958
|
'@typescript-eslint/eslint-plugin': registry.npmmirror.com/@typescript-eslint/eslint-plugin/5.8.1_bd2fd93dbcc607ad2f21b784bccfe0c8
|
||||||
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.8.1_eslint@8.6.0+typescript@4.5.4
|
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.9.0_eslint@8.6.0+typescript@4.5.4
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
eslint-plugin-vue: registry.npmmirror.com/eslint-plugin-vue/8.2.0_eslint@8.6.0
|
eslint-plugin-vue: registry.npmmirror.com/eslint-plugin-vue/8.2.0_eslint@8.6.0
|
||||||
vue-eslint-parser: registry.npmmirror.com/vue-eslint-parser/8.0.1_eslint@8.6.0
|
vue-eslint-parser: registry.npmmirror.com/vue-eslint-parser/8.0.1_eslint@8.6.0
|
||||||
@ -4766,7 +4795,7 @@ packages:
|
|||||||
esbuild-windows-arm64: registry.npmmirror.com/esbuild-windows-arm64/0.13.15
|
esbuild-windows-arm64: registry.npmmirror.com/esbuild-windows-arm64/0.13.15
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/eslint-config-airbnb-base/15.0.0_b54597effeb7d09a84a334cc3c3dadae:
|
registry.npmmirror.com/eslint-config-airbnb-base/15.0.0_b5a36b8c1535387c8dd00eff7ec6b551:
|
||||||
resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-config-airbnb-base/download/eslint-config-airbnb-base-15.0.0.tgz}
|
resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-config-airbnb-base/download/eslint-config-airbnb-base-15.0.0.tgz}
|
||||||
id: registry.npmmirror.com/eslint-config-airbnb-base/15.0.0
|
id: registry.npmmirror.com/eslint-config-airbnb-base/15.0.0
|
||||||
name: eslint-config-airbnb-base
|
name: eslint-config-airbnb-base
|
||||||
@ -4778,28 +4807,27 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
confusing-browser-globals: registry.npmmirror.com/confusing-browser-globals/1.0.11
|
confusing-browser-globals: registry.npmmirror.com/confusing-browser-globals/1.0.11
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
eslint-plugin-import: registry.npmmirror.com/eslint-plugin-import/2.25.3_eslint@8.6.0
|
eslint-plugin-import: registry.npmmirror.com/eslint-plugin-import/2.25.4_eslint@8.6.0
|
||||||
object.assign: registry.nlark.com/object.assign/4.1.2
|
object.assign: registry.nlark.com/object.assign/4.1.2
|
||||||
object.entries: registry.npmmirror.com/object.entries/1.1.5
|
object.entries: registry.npmmirror.com/object.entries/1.1.5
|
||||||
semver: registry.nlark.com/semver/6.3.0
|
semver: registry.nlark.com/semver/6.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/eslint-module-utils/2.7.1:
|
registry.npmmirror.com/eslint-module-utils/2.7.2:
|
||||||
resolution: {integrity: sha1-tDUAHJ+N1Kt/bQ78rkuWltTCS3w=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-module-utils/download/eslint-module-utils-2.7.1.tgz}
|
resolution: {integrity: sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-module-utils/download/eslint-module-utils-2.7.2.tgz}
|
||||||
name: eslint-module-utils
|
name: eslint-module-utils
|
||||||
version: 2.7.1
|
version: 2.7.2
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: registry.npmmirror.com/debug/3.2.7
|
debug: registry.npmmirror.com/debug/3.2.7
|
||||||
find-up: registry.npmmirror.com/find-up/2.1.0
|
find-up: registry.npmmirror.com/find-up/2.1.0
|
||||||
pkg-dir: registry.npmmirror.com/pkg-dir/2.0.0
|
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/eslint-plugin-import/2.25.3_eslint@8.6.0:
|
registry.npmmirror.com/eslint-plugin-import/2.25.4_eslint@8.6.0:
|
||||||
resolution: {integrity: sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-plugin-import/download/eslint-plugin-import-2.25.3.tgz}
|
resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/eslint-plugin-import/download/eslint-plugin-import-2.25.4.tgz}
|
||||||
id: registry.npmmirror.com/eslint-plugin-import/2.25.3
|
id: registry.npmmirror.com/eslint-plugin-import/2.25.4
|
||||||
name: eslint-plugin-import
|
name: eslint-plugin-import
|
||||||
version: 2.25.3
|
version: 2.25.4
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
||||||
@ -4810,13 +4838,13 @@ packages:
|
|||||||
doctrine: registry.nlark.com/doctrine/2.1.0
|
doctrine: registry.nlark.com/doctrine/2.1.0
|
||||||
eslint: registry.npmmirror.com/eslint/8.6.0
|
eslint: registry.npmmirror.com/eslint/8.6.0
|
||||||
eslint-import-resolver-node: registry.nlark.com/eslint-import-resolver-node/0.3.6
|
eslint-import-resolver-node: registry.nlark.com/eslint-import-resolver-node/0.3.6
|
||||||
eslint-module-utils: registry.npmmirror.com/eslint-module-utils/2.7.1
|
eslint-module-utils: registry.npmmirror.com/eslint-module-utils/2.7.2
|
||||||
has: registry.nlark.com/has/1.0.3
|
has: registry.nlark.com/has/1.0.3
|
||||||
is-core-module: registry.npmmirror.com/is-core-module/2.8.0
|
is-core-module: registry.npmmirror.com/is-core-module/2.8.0
|
||||||
is-glob: registry.npmmirror.com/is-glob/4.0.3
|
is-glob: registry.npmmirror.com/is-glob/4.0.3
|
||||||
minimatch: registry.nlark.com/minimatch/3.0.4
|
minimatch: registry.nlark.com/minimatch/3.0.4
|
||||||
object.values: registry.npmmirror.com/object.values/1.1.5
|
object.values: registry.npmmirror.com/object.values/1.1.5
|
||||||
resolve: registry.nlark.com/resolve/1.20.0
|
resolve: registry.npmmirror.com/resolve/1.20.0
|
||||||
tsconfig-paths: registry.npmmirror.com/tsconfig-paths/3.12.0
|
tsconfig-paths: registry.npmmirror.com/tsconfig-paths/3.12.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@ -5192,7 +5220,7 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/htmlparser2/7.2.0:
|
registry.npmmirror.com/htmlparser2/7.2.0:
|
||||||
resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/htmlparser2/download/htmlparser2-7.2.0.tgz?cache=0&sync_timestamp=1636641904600&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-7.2.0.tgz}
|
resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/htmlparser2/download/htmlparser2-7.2.0.tgz?cache=0&sync_timestamp=1636641716463&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-7.2.0.tgz}
|
||||||
name: htmlparser2
|
name: htmlparser2
|
||||||
version: 7.2.0
|
version: 7.2.0
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5380,10 +5408,10 @@ packages:
|
|||||||
version: 1.2.4
|
version: 1.2.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/lint-staged/12.1.4:
|
registry.npmmirror.com/lint-staged/12.1.5:
|
||||||
resolution: {integrity: sha512-RgDz9nsFsE0/5eL9Vat0AvCuk0+j5mEuzBIVfrRH5FRtt5wibYe8zTjZs2nuqLFrLAGQGYnj8+HJxolcj08i/A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lint-staged/download/lint-staged-12.1.4.tgz}
|
resolution: {integrity: sha512-WyKb+0sNKDTd1LwwAfTBPp0XmdaKkAOEbg4oHE4Kq2+oQVchg/VAcjVQtSqZih1izNsTURjc2EkhG/syRQUXdA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lint-staged/download/lint-staged-12.1.5.tgz}
|
||||||
name: lint-staged
|
name: lint-staged
|
||||||
version: 12.1.4
|
version: 12.1.5
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5599,7 +5627,7 @@ packages:
|
|||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: registry.nlark.com/path-key/3.1.1
|
path-key: registry.npmmirror.com/path-key/3.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/object-inspect/1.12.0:
|
registry.npmmirror.com/object-inspect/1.12.0:
|
||||||
@ -5683,11 +5711,25 @@ packages:
|
|||||||
lines-and-columns: registry.npmmirror.com/lines-and-columns/1.2.4
|
lines-and-columns: registry.npmmirror.com/lines-and-columns/1.2.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/path-key/3.1.1:
|
||||||
|
resolution: {integrity: sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-key/download/path-key-3.1.1.tgz}
|
||||||
|
name: path-key
|
||||||
|
version: 3.1.1
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/picocolors/1.0.0:
|
registry.npmmirror.com/picocolors/1.0.0:
|
||||||
resolution: {integrity: sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picocolors/download/picocolors-1.0.0.tgz}
|
resolution: {integrity: sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picocolors/download/picocolors-1.0.0.tgz}
|
||||||
name: picocolors
|
name: picocolors
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|
||||||
|
registry.npmmirror.com/picomatch/2.3.0:
|
||||||
|
resolution: {integrity: sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picomatch/download/picomatch-2.3.0.tgz}
|
||||||
|
name: picomatch
|
||||||
|
version: 2.3.0
|
||||||
|
engines: {node: '>=8.6'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/pinia/2.0.9_typescript@4.5.4+vue@3.2.26:
|
registry.npmmirror.com/pinia/2.0.9_typescript@4.5.4+vue@3.2.26:
|
||||||
resolution: {integrity: sha512-iuYdxLJKQ07YPyOHYH05wNG9eKWqkP/4y4GE8+RqEYtz5fwHgPA5kr6zQbg/DoEJGnR2XCm1w1vdt6ppzL9ATg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pinia/download/pinia-2.0.9.tgz}
|
resolution: {integrity: sha512-iuYdxLJKQ07YPyOHYH05wNG9eKWqkP/4y4GE8+RqEYtz5fwHgPA5kr6zQbg/DoEJGnR2XCm1w1vdt6ppzL9ATg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pinia/download/pinia-2.0.9.tgz}
|
||||||
id: registry.npmmirror.com/pinia/2.0.9
|
id: registry.npmmirror.com/pinia/2.0.9
|
||||||
@ -5709,15 +5751,6 @@ packages:
|
|||||||
vue-demi: registry.npmmirror.com/vue-demi/0.12.1_vue@3.2.26
|
vue-demi: registry.npmmirror.com/vue-demi/0.12.1_vue@3.2.26
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/pkg-dir/2.0.0:
|
|
||||||
resolution: {integrity: sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pkg-dir/download/pkg-dir-2.0.0.tgz}
|
|
||||||
name: pkg-dir
|
|
||||||
version: 2.0.0
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
dependencies:
|
|
||||||
find-up: registry.npmmirror.com/find-up/2.1.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
registry.npmmirror.com/postcss/8.4.5:
|
registry.npmmirror.com/postcss/8.4.5:
|
||||||
resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/postcss/download/postcss-8.4.5.tgz}
|
resolution: {integrity: sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/postcss/download/postcss-8.4.5.tgz}
|
||||||
name: postcss
|
name: postcss
|
||||||
@ -5761,12 +5794,35 @@ packages:
|
|||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/promise/7.3.1:
|
||||||
|
resolution: {integrity: sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/promise/download/promise-7.3.1.tgz}
|
||||||
|
name: promise
|
||||||
|
version: 7.3.1
|
||||||
|
dependencies:
|
||||||
|
asap: registry.nlark.com/asap/2.0.6
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/pug-error/2.0.0:
|
registry.npmmirror.com/pug-error/2.0.0:
|
||||||
resolution: {integrity: sha1-XGIXPLCcNN4qLOBPF7it/sdNjKU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pug-error/download/pug-error-2.0.0.tgz}
|
resolution: {integrity: sha1-XGIXPLCcNN4qLOBPF7it/sdNjKU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pug-error/download/pug-error-2.0.0.tgz}
|
||||||
name: pug-error
|
name: pug-error
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/pug/3.0.2:
|
||||||
|
resolution: {integrity: sha1-81xxBzQ0VOQ7wnrg/3bHMbeOpTU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/pug/download/pug-3.0.2.tgz}
|
||||||
|
name: pug
|
||||||
|
version: 3.0.2
|
||||||
|
dependencies:
|
||||||
|
pug-code-gen: registry.nlark.com/pug-code-gen/3.0.2
|
||||||
|
pug-filters: registry.nlark.com/pug-filters/4.0.0
|
||||||
|
pug-lexer: registry.nlark.com/pug-lexer/5.0.1
|
||||||
|
pug-linker: registry.nlark.com/pug-linker/4.0.0
|
||||||
|
pug-load: registry.nlark.com/pug-load/3.0.0
|
||||||
|
pug-parser: registry.nlark.com/pug-parser/6.0.0
|
||||||
|
pug-runtime: registry.nlark.com/pug-runtime/3.0.1
|
||||||
|
pug-strip-comments: registry.nlark.com/pug-strip-comments/2.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/qs/6.10.2:
|
registry.npmmirror.com/qs/6.10.2:
|
||||||
resolution: {integrity: sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/qs/download/qs-6.10.2.tgz}
|
resolution: {integrity: sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/qs/download/qs-6.10.2.tgz}
|
||||||
name: qs
|
name: qs
|
||||||
@ -5805,6 +5861,15 @@ packages:
|
|||||||
version: 0.5.6
|
version: 0.5.6
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/resolve/1.20.0:
|
||||||
|
resolution: {integrity: sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve/download/resolve-1.20.0.tgz}
|
||||||
|
name: resolve
|
||||||
|
version: 1.20.0
|
||||||
|
dependencies:
|
||||||
|
is-core-module: registry.npmmirror.com/is-core-module/2.8.0
|
||||||
|
path-parse: registry.nlark.com/path-parse/1.0.7
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/reusify/1.0.4:
|
registry.npmmirror.com/reusify/1.0.4:
|
||||||
resolution: {integrity: sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/reusify/download/reusify-1.0.4.tgz}
|
resolution: {integrity: sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/reusify/download/reusify-1.0.4.tgz}
|
||||||
name: reusify
|
name: reusify
|
||||||
@ -6421,30 +6486,32 @@ packages:
|
|||||||
version: 5.0.0
|
version: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vscode-pug-languageservice/0.30.1:
|
registry.npmmirror.com/vscode-pug-languageservice/0.30.2:
|
||||||
resolution: {integrity: sha512-ytco+lziRQNrpHpI8X+/rhYaX4KUWAnYZHd1f1epu2m+9WoIf9swbk8/slIOeyec1DPg4Y7AS8hTLcEfOfY71g==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-pug-languageservice/download/vscode-pug-languageservice-0.30.1.tgz}
|
resolution: {integrity: sha512-YkrBodqSzNrtLaEIeMnRJAcnqCWysIiOdkzxF6XHuOc+wDvbZ1U4XgxoLvNNjQdzNQIEYKbsLW0ldq5TYphjiA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-pug-languageservice/download/vscode-pug-languageservice-0.30.2.tgz}
|
||||||
name: vscode-pug-languageservice
|
name: vscode-pug-languageservice
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.1
|
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.2
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.1
|
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.2
|
||||||
'@volar/transforms': registry.npmmirror.com/@volar/transforms/0.30.1
|
'@volar/transforms': registry.npmmirror.com/@volar/transforms/0.30.2
|
||||||
pug-lexer: registry.nlark.com/pug-lexer/5.0.1
|
pug-lexer: registry.nlark.com/pug-lexer/5.0.1
|
||||||
pug-parser: registry.nlark.com/pug-parser/6.0.0
|
pug-parser: registry.nlark.com/pug-parser/6.0.0
|
||||||
vscode-languageserver: registry.npmmirror.com/vscode-languageserver/8.0.0-next.5
|
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
||||||
|
vscode-languageserver-types: registry.npmmirror.com/vscode-languageserver-types/3.17.0-next.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vscode-typescript-languageservice/0.30.1:
|
registry.npmmirror.com/vscode-typescript-languageservice/0.30.2:
|
||||||
resolution: {integrity: sha512-7EBJiaLXThlrbm2K5VU+qWPR3z+RtmCFLWiZaNdJYO/E5UFBQiPmO8qXlxcB2x1N7zId2GZoogAbT15oexY2eQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-typescript-languageservice/download/vscode-typescript-languageservice-0.30.1.tgz}
|
resolution: {integrity: sha512-5l+gMfbHTZnJy7V7xdH78ai1ViR/scrIVQT5KFraDWLKTYHjGBkHDZ1E9fF+jbeyEizyy2ayldTQ7kCz8jWqVA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-typescript-languageservice/download/vscode-typescript-languageservice-0.30.2.tgz}
|
||||||
name: vscode-typescript-languageservice
|
name: vscode-typescript-languageservice
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
semver: registry.nlark.com/semver/7.3.5
|
semver: registry.nlark.com/semver/7.3.5
|
||||||
upath: registry.nlark.com/upath/2.0.1
|
upath: registry.nlark.com/upath/2.0.1
|
||||||
vscode-languageserver: registry.npmmirror.com/vscode-languageserver/8.0.0-next.5
|
vscode-languageserver-protocol: registry.npmmirror.com/vscode-languageserver-protocol/3.17.0-next.11
|
||||||
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
||||||
|
vscode-nls: registry.npmmirror.com/vscode-nls/5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vscode-uri/2.1.2:
|
registry.npmmirror.com/vscode-uri/2.1.2:
|
||||||
@ -6459,17 +6526,17 @@ packages:
|
|||||||
version: 3.0.3
|
version: 3.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vscode-vue-languageservice/0.30.1:
|
registry.npmmirror.com/vscode-vue-languageservice/0.30.2:
|
||||||
resolution: {integrity: sha512-l9R5vXkrGY0N4hA2o9ZFBIKL44z7UbHc45YjOmnslGwYL15YXfb7T4quW8VYSWJNRbiFBTNnNLWORIDEcWazBA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-vue-languageservice/download/vscode-vue-languageservice-0.30.1.tgz}
|
resolution: {integrity: sha512-P0g92JmnVkV2zrWhDbT2zxuOUp0X2kMM9VHlrT7ALZq8wAhPOW0B4nhhb9a6jKBh6qqFBDquNeQRvTEZp4NJMA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vscode-vue-languageservice/download/vscode-vue-languageservice-0.30.2.tgz}
|
||||||
name: vscode-vue-languageservice
|
name: vscode-vue-languageservice
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.1
|
'@volar/code-gen': registry.npmmirror.com/@volar/code-gen/0.30.2
|
||||||
'@volar/html2pug': registry.npmmirror.com/@volar/html2pug/0.30.1
|
'@volar/html2pug': registry.npmmirror.com/@volar/html2pug/0.30.2
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.1
|
'@volar/source-map': registry.npmmirror.com/@volar/source-map/0.30.2
|
||||||
'@volar/transforms': registry.npmmirror.com/@volar/transforms/0.30.1
|
'@volar/transforms': registry.npmmirror.com/@volar/transforms/0.30.2
|
||||||
'@volar/vue-code-gen': registry.npmmirror.com/@volar/vue-code-gen/0.30.1
|
'@volar/vue-code-gen': registry.npmmirror.com/@volar/vue-code-gen/0.30.2
|
||||||
'@vscode/emmet-helper': registry.npmmirror.com/@vscode/emmet-helper/2.8.3
|
'@vscode/emmet-helper': registry.npmmirror.com/@vscode/emmet-helper/2.8.3
|
||||||
'@vue/reactivity': registry.npmmirror.com/@vue/reactivity/3.2.26
|
'@vue/reactivity': registry.npmmirror.com/@vue/reactivity/3.2.26
|
||||||
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.26
|
'@vue/shared': registry.npmmirror.com/@vue/shared/3.2.26
|
||||||
@ -6479,9 +6546,10 @@ packages:
|
|||||||
vscode-html-languageservice: registry.npmmirror.com/vscode-html-languageservice/4.2.1
|
vscode-html-languageservice: registry.npmmirror.com/vscode-html-languageservice/4.2.1
|
||||||
vscode-json-languageservice: registry.npmmirror.com/vscode-json-languageservice/4.1.10
|
vscode-json-languageservice: registry.npmmirror.com/vscode-json-languageservice/4.1.10
|
||||||
vscode-languageserver: registry.npmmirror.com/vscode-languageserver/8.0.0-next.5
|
vscode-languageserver: registry.npmmirror.com/vscode-languageserver/8.0.0-next.5
|
||||||
|
vscode-languageserver-protocol: registry.npmmirror.com/vscode-languageserver-protocol/3.17.0-next.11
|
||||||
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
vscode-languageserver-textdocument: registry.npmmirror.com/vscode-languageserver-textdocument/1.0.3
|
||||||
vscode-pug-languageservice: registry.npmmirror.com/vscode-pug-languageservice/0.30.1
|
vscode-pug-languageservice: registry.npmmirror.com/vscode-pug-languageservice/0.30.2
|
||||||
vscode-typescript-languageservice: registry.npmmirror.com/vscode-typescript-languageservice/0.30.1
|
vscode-typescript-languageservice: registry.npmmirror.com/vscode-typescript-languageservice/0.30.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vue-demi/0.12.1_vue@3.2.26:
|
registry.npmmirror.com/vue-demi/0.12.1_vue@3.2.26:
|
||||||
@ -6535,18 +6603,18 @@ packages:
|
|||||||
vue: registry.npmmirror.com/vue/3.2.26
|
vue: registry.npmmirror.com/vue/3.2.26
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/vue-tsc/0.30.1_typescript@4.5.4:
|
registry.npmmirror.com/vue-tsc/0.30.2_typescript@4.5.4:
|
||||||
resolution: {integrity: sha512-AVBPWF70LvuzAt6phaF3U8pg1WmjmZQBfZvkX4Ve9EHTPh4R2JiJnSjf3MQgnx03qF5w0PGkBJ90l12aaLZeKQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-tsc/download/vue-tsc-0.30.1.tgz}
|
resolution: {integrity: sha512-A8KIk5KwQTbSdsrDxwJkFYLPqDJ1zM86w3X8cgpi6rveozKUGDMPt300awEz61sTuBM9fAfUhNRcsWbsJ1I+TQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-tsc/download/vue-tsc-0.30.2.tgz}
|
||||||
id: registry.npmmirror.com/vue-tsc/0.30.1
|
id: registry.npmmirror.com/vue-tsc/0.30.2
|
||||||
name: vue-tsc
|
name: vue-tsc
|
||||||
version: 0.30.1
|
version: 0.30.2
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '*'
|
typescript: '*'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.1
|
'@volar/shared': registry.npmmirror.com/@volar/shared/0.30.2
|
||||||
typescript: registry.npmmirror.com/typescript/4.5.4
|
typescript: registry.npmmirror.com/typescript/4.5.4
|
||||||
vscode-vue-languageservice: registry.npmmirror.com/vscode-vue-languageservice/0.30.1
|
vscode-vue-languageservice: registry.npmmirror.com/vscode-vue-languageservice/0.30.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
registry.npmmirror.com/vue/3.2.26:
|
registry.npmmirror.com/vue/3.2.26:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-config-provider :theme-overrides="theme.naiveThemeOverrides" class="h-full">
|
<n-config-provider :theme="theme.naiveTheme" :theme-overrides="theme.naiveThemeOverrides" class="h-full">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</n-config-provider>
|
</n-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
48
src/components/business/LoginAgreement/index.vue
Normal file
48
src/components/business/LoginAgreement/index.vue
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-full text-14px">
|
||||||
|
<n-checkbox v-model:checked="checked">我已经仔细阅读并接受</n-checkbox>
|
||||||
|
<n-button :text="true" type="primary" @click="handleClickProtocol">《用户协议》</n-button>
|
||||||
|
<n-button :text="true" type="primary" @click="handleClickPolicy">《隐私权政策》</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { NCheckbox, NButton } from 'naive-ui';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** 是否勾选 */
|
||||||
|
value?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: 'update:value', value: boolean): void;
|
||||||
|
/** 点击协议 */
|
||||||
|
(e: 'click-protocol'): void;
|
||||||
|
/** 点击隐私政策 */
|
||||||
|
(e: 'click-policy'): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const checked = computed({
|
||||||
|
get() {
|
||||||
|
return props.value;
|
||||||
|
},
|
||||||
|
set(newValue: boolean) {
|
||||||
|
emit('update:value', newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleClickProtocol() {
|
||||||
|
emit('click-protocol');
|
||||||
|
}
|
||||||
|
function handleClickPolicy() {
|
||||||
|
emit('click-policy');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
3
src/components/business/index.ts
Normal file
3
src/components/business/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import LoginAgreement from './LoginAgreement/index.vue';
|
||||||
|
|
||||||
|
export { LoginAgreement };
|
39
src/components/common/DarkModeSwitch/index.vue
Normal file
39
src/components/common/DarkModeSwitch/index.vue
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<div class="text-18px hover:text-primary cursor-pointer" @click="handleSwitch">
|
||||||
|
<icon-mdi-moon-waning-crescent v-if="darkMode" />
|
||||||
|
<icon-mdi-white-balance-sunny v-else />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** 暗黑模式 */
|
||||||
|
dark?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: 'update:dark', darkMode: boolean): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
dark: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const darkMode = computed({
|
||||||
|
get() {
|
||||||
|
return props.dark;
|
||||||
|
},
|
||||||
|
set(newValue: boolean) {
|
||||||
|
emit('update:dark', newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleSwitch() {
|
||||||
|
darkMode.value = !darkMode.value;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
@ -1,3 +1,4 @@
|
|||||||
import SystemLogo from './SystemLogo/index.vue';
|
import SystemLogo from './SystemLogo/index.vue';
|
||||||
|
import DarkModeSwitch from './DarkModeSwitch/index.vue';
|
||||||
|
|
||||||
export { SystemLogo };
|
export { SystemLogo, DarkModeSwitch };
|
||||||
|
39
src/components/custom/ImageVerify/index.vue
Normal file
39
src/components/custom/ImageVerify/index.vue
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<canvas ref="domRef" width="152" height="40" class="cursor-pointer" @click="getImgCode"></canvas>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { watch } from 'vue';
|
||||||
|
import { useImageVerify } from '@/hooks';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
code?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: 'update:code', code: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
code: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify();
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.code,
|
||||||
|
newValue => {
|
||||||
|
setImgCode(newValue);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(imgCode, newValue => {
|
||||||
|
emit('update:code', newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({ getImgCode });
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
3
src/components/custom/index.ts
Normal file
3
src/components/custom/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import ImageVerify from './ImageVerify/index.vue';
|
||||||
|
|
||||||
|
export { ImageVerify };
|
@ -1 +1,3 @@
|
|||||||
export * from './common';
|
export * from './common';
|
||||||
|
export * from './custom';
|
||||||
|
export * from './business';
|
||||||
|
@ -1 +1,3 @@
|
|||||||
export * from './system';
|
export * from './system';
|
||||||
|
export * from './router';
|
||||||
|
export * from './route';
|
||||||
|
32
src/composables/common/route.ts
Normal file
32
src/composables/common/route.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { unref, computed } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import { router } from '@/router';
|
||||||
|
import { useRouteStore } from '@/store';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由查询参数
|
||||||
|
* @param inSetup - 是否在vue页面/组件的setup里面调用,在axios里面无法使用useRouter和useRoute
|
||||||
|
*/
|
||||||
|
export function useRouteQuery(inSetup: boolean = true) {
|
||||||
|
const { getRouteName } = useRouteStore();
|
||||||
|
|
||||||
|
const route = getRouteInstance(inSetup);
|
||||||
|
|
||||||
|
/** 登录后跳转的地址 */
|
||||||
|
const loginRedirect = computed(() => {
|
||||||
|
let url: string | undefined;
|
||||||
|
if (route.name === getRouteName('login')) {
|
||||||
|
url = (route.query?.redirect as string) || '';
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
loginRedirect
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRouteInstance(inSetup: boolean = true) {
|
||||||
|
const route = inSetup ? useRoute() : unref(router.currentRoute);
|
||||||
|
return route;
|
||||||
|
}
|
90
src/composables/common/router.ts
Normal file
90
src/composables/common/router.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { unref } from 'vue';
|
||||||
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import type { RouteLocationRaw } from 'vue-router';
|
||||||
|
import { router as globalRouter } from '@/router';
|
||||||
|
import { useRouteStore } from '@/store';
|
||||||
|
import { LoginModuleKey } from '@/interface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由跳转
|
||||||
|
* @param inSetup - 是否在vue页面/组件的setup里面调用,在axios里面无法使用useRouter和useRoute
|
||||||
|
*/
|
||||||
|
export function useRouterPush(inSetup: boolean = true) {
|
||||||
|
const { getRouteName } = useRouteStore();
|
||||||
|
|
||||||
|
const router = inSetup ? useRouter() : globalRouter;
|
||||||
|
const route = inSetup ? useRoute() : unref(globalRouter.currentRoute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由跳转
|
||||||
|
* @param to - 需要跳转的路由
|
||||||
|
* @param newTab - 是否在新的浏览器Tab标签打开
|
||||||
|
*/
|
||||||
|
function routerPush(to: RouteLocationRaw, newTab = false) {
|
||||||
|
if (newTab) {
|
||||||
|
const routerData = router.resolve(to);
|
||||||
|
window.open(routerData.href, '_blank');
|
||||||
|
} else {
|
||||||
|
router.push(to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 返回上一级路由 */
|
||||||
|
function routerBack() {
|
||||||
|
router.go(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转首页
|
||||||
|
* @param newTab - 在新的浏览器标签打开
|
||||||
|
*/
|
||||||
|
function toHome(newTab = false) {
|
||||||
|
routerPush(getRouteName('root'), newTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转登录页面
|
||||||
|
* @param loginModule - 展示的登录模块
|
||||||
|
* @param redirectUrl - 重定向地址(登录成功后跳转的地址),默认undefined表示取当前地址为重定向地址
|
||||||
|
*/
|
||||||
|
function toLogin(loginModule?: LoginModuleKey, redirectUrl?: string) {
|
||||||
|
const module: LoginModuleKey = loginModule || 'pwd-login';
|
||||||
|
const routeLocation: RouteLocationRaw = {
|
||||||
|
name: getRouteName('login'),
|
||||||
|
params: { module }
|
||||||
|
};
|
||||||
|
const redirect = redirectUrl || route.fullPath;
|
||||||
|
Object.assign(routeLocation, { query: { redirect } });
|
||||||
|
routerPush(routeLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录页切换其他模块
|
||||||
|
* @param module - 切换后的登录模块
|
||||||
|
*/
|
||||||
|
function toLoginModule(module: LoginModuleKey) {
|
||||||
|
const { query } = route;
|
||||||
|
routerPush({ name: getRouteName('login'), params: { module }, query });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录成功后跳转重定向的地址
|
||||||
|
* @param redirect - 重定向地址
|
||||||
|
*/
|
||||||
|
function toLoginRedirect(redirect?: string) {
|
||||||
|
if (redirect) {
|
||||||
|
routerPush(redirect);
|
||||||
|
} else {
|
||||||
|
toHome();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
routerPush,
|
||||||
|
routerBack,
|
||||||
|
toHome,
|
||||||
|
toLogin,
|
||||||
|
toLoginModule,
|
||||||
|
toLoginRedirect
|
||||||
|
};
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
export * from './service';
|
export * from './service';
|
||||||
|
export * from './regexp';
|
||||||
|
16
src/config/common/regexp.ts
Normal file
16
src/config/common/regexp.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/** 手机号码正则 */
|
||||||
|
export const REGEXP_PHONE =
|
||||||
|
/^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/;
|
||||||
|
|
||||||
|
/** 邮箱正则 */
|
||||||
|
export const REGEXP_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
||||||
|
|
||||||
|
/** 密码正则(密码为8-18位数字/字符/符号的组合) */
|
||||||
|
export const REGEXP_PWD =
|
||||||
|
/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[()])+$)(?!^.*[\u4E00-\u9FA5].*$)([^(0-9a-zA-Z)]|[()]|[a-z]|[A-Z]|[0-9]){8,18}$/;
|
||||||
|
|
||||||
|
/** 6位数字验证码正则 */
|
||||||
|
export const REGEXP_CODE_SIX = /^\d{6}$/;
|
||||||
|
|
||||||
|
/** 4位数字验证码正则 */
|
||||||
|
export const REGEXP_CODE_FOUR = /^\d{4}$/;
|
5
src/hooks/business/index.ts
Normal file
5
src/hooks/business/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import useCountDown from './useCountDown';
|
||||||
|
import useSmsCode from './useSmsCode';
|
||||||
|
import useImageVerify from './useImageVerify';
|
||||||
|
|
||||||
|
export { useCountDown, useSmsCode, useImageVerify };
|
52
src/hooks/business/useCountDown.ts
Normal file
52
src/hooks/business/useCountDown.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { useBoolean } from '../common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 倒计时
|
||||||
|
* @param second - 倒计时的时间(s)
|
||||||
|
*/
|
||||||
|
export default function useCountDown(second: number) {
|
||||||
|
if (second <= 0 && second % 1 !== 0) {
|
||||||
|
throw Error('倒计时的时间应该为一个正整数!');
|
||||||
|
}
|
||||||
|
const { bool: isComplete, setTrue, setFalse } = useBoolean(false);
|
||||||
|
|
||||||
|
const counts = ref(0);
|
||||||
|
const isCounting = computed(() => Boolean(counts.value));
|
||||||
|
|
||||||
|
let intervalId: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始计时
|
||||||
|
* @param updateSecond - 更改初时传入的倒计时时间
|
||||||
|
*/
|
||||||
|
function start(updateSecond: number = second) {
|
||||||
|
if (!counts.value) {
|
||||||
|
setFalse();
|
||||||
|
counts.value = updateSecond;
|
||||||
|
intervalId = setInterval(() => {
|
||||||
|
counts.value -= 1;
|
||||||
|
if (counts.value <= 0) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
setTrue();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止计时
|
||||||
|
*/
|
||||||
|
function stop() {
|
||||||
|
intervalId = clearInterval(intervalId);
|
||||||
|
counts.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
counts,
|
||||||
|
isCounting,
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
isComplete
|
||||||
|
};
|
||||||
|
}
|
85
src/hooks/business/useImageVerify.ts
Normal file
85
src/hooks/business/useImageVerify.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制图形验证码
|
||||||
|
* @param width - 图形宽度
|
||||||
|
* @param height - 图形高度
|
||||||
|
*/
|
||||||
|
export default function useImageVerify(width = 152, height = 40) {
|
||||||
|
const domRef = ref<HTMLCanvasElement>();
|
||||||
|
const imgCode = ref('');
|
||||||
|
|
||||||
|
function setImgCode(code: string) {
|
||||||
|
imgCode.value = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImgCode() {
|
||||||
|
if (!domRef.value) return;
|
||||||
|
imgCode.value = draw(domRef.value, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getImgCode();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
domRef,
|
||||||
|
imgCode,
|
||||||
|
setImgCode,
|
||||||
|
getImgCode
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomNum(min: number, max: number) {
|
||||||
|
const num = Math.floor(Math.random() * (max - min) + min);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomColor(min: number, max: number) {
|
||||||
|
const r = randomNum(min, max);
|
||||||
|
const g = randomNum(min, max);
|
||||||
|
const b = randomNum(min, max);
|
||||||
|
return `rgb(${r},${g},${b})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(dom: HTMLCanvasElement, width: number, height: number) {
|
||||||
|
let imgCode = '';
|
||||||
|
|
||||||
|
const NUMBER_STRING = '0123456789';
|
||||||
|
|
||||||
|
const ctx = dom.getContext('2d');
|
||||||
|
if (!ctx) return imgCode;
|
||||||
|
|
||||||
|
ctx.fillStyle = randomColor(180, 230);
|
||||||
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
for (let i = 0; i < 4; i += 1) {
|
||||||
|
const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
|
||||||
|
imgCode += text;
|
||||||
|
const fontSize = randomNum(18, 41);
|
||||||
|
const deg = randomNum(-30, 30);
|
||||||
|
ctx.font = `${fontSize}px Simhei`;
|
||||||
|
ctx.textBaseline = 'top';
|
||||||
|
ctx.fillStyle = randomColor(80, 150);
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(30 * i + 23, 15);
|
||||||
|
ctx.rotate((deg * Math.PI) / 180);
|
||||||
|
ctx.fillText(text, -15 + 5, -15);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 5; i += 1) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(randomNum(0, width), randomNum(0, height));
|
||||||
|
ctx.lineTo(randomNum(0, width), randomNum(0, height));
|
||||||
|
ctx.strokeStyle = randomColor(180, 230);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
for (let i = 0; i < 41; i += 1) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = randomColor(150, 200);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
return imgCode;
|
||||||
|
}
|
59
src/hooks/business/useSmsCode.ts
Normal file
59
src/hooks/business/useSmsCode.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { computed } from 'vue';
|
||||||
|
import { REGEXP_PHONE } from '@/config';
|
||||||
|
import { fetchSmsCode } from '@/service';
|
||||||
|
import { useLoading } from '../common';
|
||||||
|
import useCountDown from './useCountDown';
|
||||||
|
|
||||||
|
export default function useSmsCode() {
|
||||||
|
const { loading, startLoading, endLoading } = useLoading();
|
||||||
|
const { counts, start, isCounting } = useCountDown(60);
|
||||||
|
const initLabel = '获取验证码';
|
||||||
|
const countingLabel = (second: number) => `${second}秒后重新获取`;
|
||||||
|
const label = computed(() => {
|
||||||
|
let text = initLabel;
|
||||||
|
if (loading.value) {
|
||||||
|
text = '';
|
||||||
|
}
|
||||||
|
if (isCounting.value) {
|
||||||
|
text = countingLabel(counts.value);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 判断手机号码格式是否正确 */
|
||||||
|
function isPhoneValid(phone: string) {
|
||||||
|
let valid = true;
|
||||||
|
if (phone.trim() === '') {
|
||||||
|
window.$message?.error('手机号码不能为空!');
|
||||||
|
valid = false;
|
||||||
|
} else if (!REGEXP_PHONE.test(phone)) {
|
||||||
|
window.$message?.error('手机号码格式错误!');
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取短信验证码
|
||||||
|
* @param phone - 手机号
|
||||||
|
*/
|
||||||
|
async function getSmsCode(phone: string) {
|
||||||
|
const valid = isPhoneValid(phone);
|
||||||
|
if (!valid || loading.value) return;
|
||||||
|
startLoading();
|
||||||
|
const { data } = await fetchSmsCode(phone);
|
||||||
|
if (data) {
|
||||||
|
window.$message?.success('验证码发送成功!');
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
endLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
start,
|
||||||
|
isCounting,
|
||||||
|
getSmsCode,
|
||||||
|
loading
|
||||||
|
};
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
export * from './common';
|
export * from './common';
|
||||||
|
export * from './business';
|
||||||
|
@ -2,5 +2,3 @@ import { EnumLoginModule } from '@/enum';
|
|||||||
|
|
||||||
/** 登录模块 */
|
/** 登录模块 */
|
||||||
export type LoginModuleKey = keyof typeof EnumLoginModule;
|
export type LoginModuleKey = keyof typeof EnumLoginModule;
|
||||||
|
|
||||||
export type LoginModuleRegexp = LoginModuleKey;
|
|
||||||
|
@ -15,7 +15,7 @@ export async function handlePagePermission(
|
|||||||
|
|
||||||
const permissions = to.meta.permissions || [];
|
const permissions = to.meta.permissions || [];
|
||||||
const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
|
const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
|
||||||
const hasPermission = !permissions.length || permissions.includes(auth.role);
|
const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);
|
||||||
|
|
||||||
if (!route.isAddedDynamicRoute) {
|
if (!route.isAddedDynamicRoute) {
|
||||||
// 添加动态路由
|
// 添加动态路由
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// import { getLoginModuleRegExp } from '@/utils';
|
import { getLoginModuleRegExp } from '@/utils';
|
||||||
|
import type { LoginModuleKey } from '@/interface';
|
||||||
|
|
||||||
/** 固定的路由 */
|
/** 固定的路由 */
|
||||||
const constantRoutes: AuthRoute.Route[] = [
|
const constantRoutes: AuthRoute.Route[] = [
|
||||||
@ -12,8 +13,14 @@ const constantRoutes: AuthRoute.Route[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'login',
|
name: 'login',
|
||||||
path: '/login',
|
path: `/login/:module(${getLoginModuleRegExp()})?`,
|
||||||
component: 'blank',
|
component: 'blank',
|
||||||
|
props: route => {
|
||||||
|
const moduleType = (route.params.module as LoginModuleKey) || 'pwd-login';
|
||||||
|
return {
|
||||||
|
module: moduleType
|
||||||
|
};
|
||||||
|
},
|
||||||
meta: {
|
meta: {
|
||||||
title: '登录',
|
title: '登录',
|
||||||
single: true
|
single: true
|
||||||
|
@ -1,15 +1,39 @@
|
|||||||
import { mockRequest } from '../request';
|
import { mockRequest } from '../request';
|
||||||
import { userRoutesMiddleware } from '../middleware';
|
import { userRoutesMiddleware } from '../middleware';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取验证码
|
||||||
|
* @param phone - 手机号
|
||||||
|
* @returns - 返回boolean值表示是否发送成功
|
||||||
|
*/
|
||||||
|
export function fetchSmsCode(phone: string) {
|
||||||
|
return mockRequest.post<boolean>('/getSmsCode', { phone });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
* @param phone - 手机号
|
||||||
|
* @param pwdOrCode - 密码或验证码
|
||||||
|
* @param type - 登录方式: pwd - 密码登录; sms - 验证码登录
|
||||||
|
*/
|
||||||
|
export function fetchLogin(phone: string, pwdOrCode: string, type: 'pwd' | 'sms') {
|
||||||
|
if (type === 'pwd') {
|
||||||
|
return mockRequest.post<ApiAuth.Token>('/loginByPwd', { phone, pwd: pwdOrCode });
|
||||||
|
}
|
||||||
|
return mockRequest.post<ApiAuth.Token>('/loginByCode', { phone, code: pwdOrCode });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取用户信息 */
|
||||||
|
export function fetchUserInfo() {
|
||||||
|
return mockRequest.get<ApiAuth.UserInfo>('/getUserInfo');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户路由数据
|
* 获取用户路由数据
|
||||||
* @param userId - 用户id
|
* @param userId - 用户id
|
||||||
* @description 后端根据用户id查询到对应的角色类型,并将路由筛选出对应角色的路由数据返回前端
|
* @description 后端根据用户id查询到对应的角色类型,并将路由筛选出对应角色的路由数据返回前端
|
||||||
*/
|
*/
|
||||||
export async function fetchUserRoutes(userId: string = 'soybean') {
|
export async function fetchUserRoutes(userId: string = 'soybean') {
|
||||||
const { data } = await mockRequest<ApiRoute.ResponseRoute>(
|
const { data } = await mockRequest.post<ApiRoute.Route>('/getUserRoutes', { userId });
|
||||||
{ url: '/getUserRoutes', method: 'post', data: { userId } },
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return userRoutesMiddleware(data);
|
return userRoutesMiddleware(data);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
import { transformAuthRouteToVueRoute } from '@/utils';
|
import { transformAuthRouteToVueRoute } from '@/utils';
|
||||||
|
|
||||||
export function userRoutesMiddleware(data: ApiRoute.ResponseRoute | null) {
|
export function userRoutesMiddleware(data: ApiRoute.Route | null) {
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = data.routes.map(item => transformAuthRouteToVueRoute(item));
|
const routes: RouteRecordRaw[] = data.routes.map(item => transformAuthRouteToVueRoute(item));
|
||||||
|
@ -6,13 +6,6 @@ import CustomAxiosInstance from './instance';
|
|||||||
|
|
||||||
type RequestMethod = 'get' | 'post' | 'put' | 'delete';
|
type RequestMethod = 'get' | 'post' | 'put' | 'delete';
|
||||||
|
|
||||||
type RequestResultHook<T = any> = {
|
|
||||||
data: Ref<T | null>;
|
|
||||||
error: Ref<Service.RequestError | null>;
|
|
||||||
loading: Ref<boolean>;
|
|
||||||
network: Ref<boolean>;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface RequestParam {
|
interface RequestParam {
|
||||||
url: string;
|
url: string;
|
||||||
method?: RequestMethod;
|
method?: RequestMethod;
|
||||||
@ -20,9 +13,95 @@ interface RequestParam {
|
|||||||
axiosConfig?: AxiosRequestConfig;
|
axiosConfig?: AxiosRequestConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建请求
|
||||||
|
* @param axiosConfig - axios配置
|
||||||
|
*/
|
||||||
export function createRequest(axiosConfig: AxiosRequestConfig) {
|
export function createRequest(axiosConfig: AxiosRequestConfig) {
|
||||||
const customInstance = new CustomAxiosInstance(axiosConfig);
|
const customInstance = new CustomAxiosInstance(axiosConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步promise请求
|
||||||
|
* @param param - 请求参数
|
||||||
|
* - url: 请求地址
|
||||||
|
* - method: 请求方法(默认get)
|
||||||
|
* - data: 请求的body的data
|
||||||
|
* - axiosConfig: axios配置
|
||||||
|
*/
|
||||||
|
async function asyncRequest<T = any>(param: RequestParam): Promise<Service.RequestResult<T>> {
|
||||||
|
const { url } = param;
|
||||||
|
const method = param.method || 'get';
|
||||||
|
const { instance } = customInstance;
|
||||||
|
const res = (await getRequestResponse(
|
||||||
|
instance,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
param.data,
|
||||||
|
param.axiosConfig
|
||||||
|
)) as Service.RequestResult<T>;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function get<T = any>(url: string, config?: AxiosRequestConfig) {
|
||||||
|
return asyncRequest<T>({ url, method: 'get', axiosConfig: config });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param data - 请求的body的data
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
||||||
|
return asyncRequest<T>({ url, method: 'post', data, axiosConfig: config });
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* put请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param data - 请求的body的data
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
||||||
|
return asyncRequest<T>({ url, method: 'put', data, axiosConfig: config });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function handleDelete<T = any>(url: string, config: AxiosRequestConfig) {
|
||||||
|
return asyncRequest<T>({ url, method: 'delete', axiosConfig: config });
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
put,
|
||||||
|
delete: handleDelete
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestResultHook<T = any> = {
|
||||||
|
data: Ref<T | null>;
|
||||||
|
error: Ref<Service.RequestError | null>;
|
||||||
|
loading: Ref<boolean>;
|
||||||
|
network: Ref<boolean>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建hooks请求
|
||||||
|
* @param axiosConfig - axios配置
|
||||||
|
*/
|
||||||
|
export function createHookRequest(axiosConfig: AxiosRequestConfig) {
|
||||||
|
const customInstance = new CustomAxiosInstance(axiosConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hooks请求
|
* hooks请求
|
||||||
* @param param - 请求参数
|
* @param param - 请求参数
|
||||||
@ -30,70 +109,82 @@ export function createRequest(axiosConfig: AxiosRequestConfig) {
|
|||||||
* - method: 请求方法(默认get)
|
* - method: 请求方法(默认get)
|
||||||
* - data: 请求的body的data
|
* - data: 请求的body的data
|
||||||
* - axiosConfig: axios配置
|
* - axiosConfig: axios配置
|
||||||
* @param hookMode - 是否启用hook写法
|
|
||||||
*/
|
*/
|
||||||
function request<T = any>(param: RequestParam, hookMode: true): RequestResultHook<T>;
|
function useRequest<T = any>(param: RequestParam): RequestResultHook<T> {
|
||||||
function request<T = any>(param: RequestParam, hookMode: false): Promise<Service.RequestResult<T>>;
|
const { loading, startLoading, endLoading } = useLoading();
|
||||||
function request<T = any>(
|
const { bool: network, setBool: setNetwork } = useBoolean(window.navigator.onLine);
|
||||||
param: RequestParam,
|
|
||||||
hookMode: boolean
|
startLoading();
|
||||||
): RequestResultHook<T> | Promise<Service.RequestResult<T>> {
|
const data = ref<T | null>(null) as Ref<T | null>;
|
||||||
|
const error = ref<Service.RequestError | null>(null);
|
||||||
|
|
||||||
|
function handleRequestResult(response: any) {
|
||||||
|
const res = response as Service.RequestResult<T>;
|
||||||
|
data.value = res.data;
|
||||||
|
error.value = res.error;
|
||||||
|
endLoading();
|
||||||
|
setNetwork(window.navigator.onLine);
|
||||||
|
}
|
||||||
|
|
||||||
const { url } = param;
|
const { url } = param;
|
||||||
const method = param.method || 'get';
|
const method = param.method || 'get';
|
||||||
const { instance } = customInstance;
|
const { instance } = customInstance;
|
||||||
if (hookMode) {
|
|
||||||
return useRequest(instance, method, url, param.data, param.axiosConfig);
|
getRequestResponse(instance, method, url, param.data, param.axiosConfig).then(handleRequestResult);
|
||||||
}
|
|
||||||
return asyncRequest(instance, method, url, param.data, param.axiosConfig);
|
return {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
loading,
|
||||||
|
network
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return request;
|
/**
|
||||||
}
|
* get请求
|
||||||
|
* @param url - 请求地址
|
||||||
function useRequest<T = any>(
|
* @param config - axios配置
|
||||||
instance: AxiosInstance,
|
*/
|
||||||
method: RequestMethod,
|
function get<T = any>(url: string, config?: AxiosRequestConfig) {
|
||||||
url: string,
|
return useRequest<T>({ url, method: 'get', axiosConfig: config });
|
||||||
bodyData?: any,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): RequestResultHook<T> {
|
|
||||||
const { loading, startLoading, endLoading } = useLoading();
|
|
||||||
const { bool: network, setBool: setNetwork } = useBoolean(window.navigator.onLine);
|
|
||||||
|
|
||||||
startLoading();
|
|
||||||
const data = ref<T | null>(null) as Ref<T | null>;
|
|
||||||
const error = ref<Service.RequestError | null>(null);
|
|
||||||
|
|
||||||
function handleRequestResult(response: any) {
|
|
||||||
const res = response as Service.RequestResult<T>;
|
|
||||||
data.value = res.data;
|
|
||||||
error.value = res.error;
|
|
||||||
endLoading();
|
|
||||||
setNetwork(window.navigator.onLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getRequestResponse(instance, method, url, bodyData, config).then(handleRequestResult);
|
/**
|
||||||
|
* post请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param data - 请求的body的data
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
||||||
|
return useRequest<T>({ url, method: 'post', data, axiosConfig: config });
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* put请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param data - 请求的body的data
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig) {
|
||||||
|
return useRequest<T>({ url, method: 'put', data, axiosConfig: config });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete请求
|
||||||
|
* @param url - 请求地址
|
||||||
|
* @param config - axios配置
|
||||||
|
*/
|
||||||
|
function handleDelete<T = any>(url: string, config: AxiosRequestConfig) {
|
||||||
|
return useRequest<T>({ url, method: 'delete', axiosConfig: config });
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
get,
|
||||||
error,
|
post,
|
||||||
loading,
|
put,
|
||||||
network
|
delete: handleDelete
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function asyncRequest<T = any>(
|
|
||||||
instance: AxiosInstance,
|
|
||||||
method: RequestMethod,
|
|
||||||
url: string,
|
|
||||||
bodyData?: any,
|
|
||||||
config?: AxiosRequestConfig
|
|
||||||
): Promise<Service.RequestResult<T>> {
|
|
||||||
const res = (await getRequestResponse(instance, method, url, bodyData, config)) as Service.RequestResult<T>;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getRequestResponse(
|
async function getRequestResponse(
|
||||||
instance: AxiosInstance,
|
instance: AxiosInstance,
|
||||||
method: RequestMethod,
|
method: RequestMethod,
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { ref, computed, reactive } from 'vue';
|
import { ref, computed, reactive, unref } from 'vue';
|
||||||
import type { Ref, ComputedRef } from 'vue';
|
import type { Ref, ComputedRef } from 'vue';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { getUserInfo, getToken } from '@/utils';
|
import { router as globalRouter } from '@/router';
|
||||||
|
import { useRouterPush, useRouteQuery } from '@/composables';
|
||||||
|
import { useLoading } from '@/hooks';
|
||||||
|
import { fetchLogin, fetchUserInfo } from '@/service';
|
||||||
|
import { getUserInfo, getToken, setUserInfo, setToken, setRefreshToken, clearAuthStorage } from '@/utils';
|
||||||
|
|
||||||
interface AuthStore {
|
interface AuthStore {
|
||||||
/** 用户信息 */
|
/** 用户信息 */
|
||||||
@ -10,21 +14,94 @@ interface AuthStore {
|
|||||||
token: Ref<string>;
|
token: Ref<string>;
|
||||||
/** 是否登录 */
|
/** 是否登录 */
|
||||||
isLogin: ComputedRef<boolean>;
|
isLogin: ComputedRef<boolean>;
|
||||||
/** 用户角色 */
|
/**
|
||||||
role: Ref<Auth.RoleType>;
|
* 重置authStore
|
||||||
|
* 是否需要跳转页面(例如当前页面是需要权限的,登出后需要跳转到登录页面)
|
||||||
|
*/
|
||||||
|
resetAuthStore(pushRoute: boolean): void;
|
||||||
|
/** 登录的加载状态 */
|
||||||
|
loginLoding: Ref<boolean>;
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
* @param phone - 手机号
|
||||||
|
* @param pwdOrCode - 密码或验证码
|
||||||
|
* @param type - 登录方式: pwd - 密码登录; sms - 验证码登录
|
||||||
|
*/
|
||||||
|
login(phone: string, pwdOrCode: string, type: 'pwd' | 'sms'): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth-store', () => {
|
export const useAuthStore = defineStore('auth-store', () => {
|
||||||
|
const { toLogin, toLoginRedirect } = useRouterPush(false);
|
||||||
|
const { loginRedirect } = useRouteQuery(false);
|
||||||
|
const { loading: loginLoding, startLoading: startLoginLoading, endLoading: endLoginLoading } = useLoading();
|
||||||
|
|
||||||
const userInfo: Auth.UserInfo = reactive(getUserInfo());
|
const userInfo: Auth.UserInfo = reactive(getUserInfo());
|
||||||
|
function handleSetUserInfo(data: Auth.UserInfo) {
|
||||||
|
Object.assign(userInfo, data);
|
||||||
|
}
|
||||||
|
|
||||||
const token = ref(getToken());
|
const token = ref(getToken());
|
||||||
|
function handleSetToken(data: string) {
|
||||||
|
token.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
const isLogin = computed(() => Boolean(token.value));
|
const isLogin = computed(() => Boolean(token.value));
|
||||||
const role = ref<Auth.RoleType>('super');
|
|
||||||
|
function resetAuthStore(pushRoute: boolean = true) {
|
||||||
|
const auth = useAuthStore();
|
||||||
|
const route = unref(globalRouter.currentRoute);
|
||||||
|
|
||||||
|
clearAuthStorage();
|
||||||
|
auth.$reset();
|
||||||
|
|
||||||
|
if (pushRoute && route.meta.requiresAuth) {
|
||||||
|
toLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function login(phone: string, pwdOrCode: string, type: 'pwd' | 'sms') {
|
||||||
|
startLoginLoading();
|
||||||
|
const { data } = await fetchLogin(phone, pwdOrCode, type);
|
||||||
|
if (data) {
|
||||||
|
await loginByToken(data);
|
||||||
|
}
|
||||||
|
endLoginLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loginByToken(backendToken: ApiAuth.Token) {
|
||||||
|
// 1.先把token存储到缓存中
|
||||||
|
const { token, refreshToken } = backendToken;
|
||||||
|
setToken(token);
|
||||||
|
setRefreshToken(refreshToken);
|
||||||
|
|
||||||
|
// 2.获取用户信息
|
||||||
|
const { data } = await fetchUserInfo();
|
||||||
|
if (data) {
|
||||||
|
// 成功后把用户信息存储到缓存中
|
||||||
|
setUserInfo(data);
|
||||||
|
handleSetToken(token);
|
||||||
|
handleSetUserInfo(data);
|
||||||
|
// 3. 跳转登录后的地址
|
||||||
|
toLoginRedirect(loginRedirect.value);
|
||||||
|
// 4.登录成功弹出欢迎提示
|
||||||
|
window.$notification?.success({
|
||||||
|
title: '登录成功!',
|
||||||
|
content: `欢迎回来,${userInfo.userName}!`,
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 不成功则重置状态
|
||||||
|
resetAuthStore(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const authStore: AuthStore = {
|
const authStore: AuthStore = {
|
||||||
userInfo,
|
userInfo,
|
||||||
token,
|
token,
|
||||||
isLogin,
|
isLogin,
|
||||||
role
|
resetAuthStore,
|
||||||
|
loginLoding,
|
||||||
|
login
|
||||||
};
|
};
|
||||||
|
|
||||||
return authStore;
|
return authStore;
|
||||||
|
@ -26,7 +26,7 @@ interface RouteStore {
|
|||||||
* 获取路由路径
|
* 获取路由路径
|
||||||
* @description getRouteName 和 getRoutePath 优先使用 getRouteName
|
* @description getRouteName 和 getRoutePath 优先使用 getRouteName
|
||||||
*/
|
*/
|
||||||
getRoutePath(key: AuthRoute.RouteKey): AuthRoute.RoutePath<''> | undefined;
|
getRoutePath(key: AuthRoute.RouteKey): AuthRoute.RoutePath | undefined;
|
||||||
/** 获取路由路径 */
|
/** 获取路由路径 */
|
||||||
getRouteTitle(key: AuthRoute.RouteKey): string | undefined;
|
getRouteTitle(key: AuthRoute.RouteKey): string | undefined;
|
||||||
}
|
}
|
||||||
|
@ -37,3 +37,27 @@ export function getThemeColors(colors: [ColorType, string][]) {
|
|||||||
|
|
||||||
return themeColor;
|
return themeColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** windicss 暗黑模式 */
|
||||||
|
export function handleWindicssDarkMode() {
|
||||||
|
const DARK_CLASS = 'dark';
|
||||||
|
function getHtmlElement() {
|
||||||
|
return document.querySelector('html');
|
||||||
|
}
|
||||||
|
function addDarkClass() {
|
||||||
|
const html = getHtmlElement();
|
||||||
|
if (html) {
|
||||||
|
html.classList.add(DARK_CLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function removeDarkClass() {
|
||||||
|
const html = getHtmlElement();
|
||||||
|
if (html) {
|
||||||
|
html.classList.remove(DARK_CLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
addDarkClass,
|
||||||
|
removeDarkClass
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { ref, computed } from 'vue';
|
import { ref, computed, watch } from 'vue';
|
||||||
import type { Ref, ComputedRef } from 'vue';
|
import type { Ref, ComputedRef } from 'vue';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { useThemeVars } from 'naive-ui';
|
import { useThemeVars, darkTheme, useOsTheme } from 'naive-ui';
|
||||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
import type { GlobalThemeOverrides, GlobalTheme } from 'naive-ui';
|
||||||
import { kebabCase } from 'lodash-es';
|
import { kebabCase } from 'lodash-es';
|
||||||
|
import { useBoolean } from '@/hooks';
|
||||||
import { getColorPalette } from '@/utils';
|
import { getColorPalette } from '@/utils';
|
||||||
import { getThemeColors } from './helpers';
|
import { getThemeColors, handleWindicssDarkMode } from './helpers';
|
||||||
|
|
||||||
interface OtherColor {
|
interface OtherColor {
|
||||||
/** 信息 */
|
/** 信息 */
|
||||||
@ -18,19 +19,31 @@ interface OtherColor {
|
|||||||
error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BuiltInGlobalTheme = Omit<Required<GlobalTheme>, 'InternalSelectMenu' | 'InternalSelection'>;
|
||||||
|
|
||||||
interface ThemeStore {
|
interface ThemeStore {
|
||||||
|
/** 暗黑模式 */
|
||||||
|
darkMode: Ref<boolean>;
|
||||||
|
/** 设置暗黑模式 */
|
||||||
|
setDarkMode(dark: boolean): void;
|
||||||
|
/** 切换/关闭 暗黑模式 */
|
||||||
|
toggleDarkMode(dark: boolean): void;
|
||||||
/** 主题颜色 */
|
/** 主题颜色 */
|
||||||
themeColor: Ref<string>;
|
themeColor: Ref<string>;
|
||||||
/** 其他颜色 */
|
/** 其他颜色 */
|
||||||
otherColor: ComputedRef<OtherColor>;
|
otherColor: ComputedRef<OtherColor>;
|
||||||
/** naiveUI的主题配置 */
|
/** naiveUI的主题配置 */
|
||||||
naiveThemeOverrides: ComputedRef<GlobalThemeOverrides>;
|
naiveThemeOverrides: ComputedRef<GlobalThemeOverrides>;
|
||||||
|
/** naive-ui暗黑主题 */
|
||||||
|
naiveTheme: ComputedRef<BuiltInGlobalTheme | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ThemeVarsKeys = keyof Exclude<GlobalThemeOverrides['common'], undefined>;
|
type ThemeVarsKeys = keyof Exclude<GlobalThemeOverrides['common'], undefined>;
|
||||||
|
|
||||||
export const useThemeStore = defineStore('theme-store', () => {
|
export const useThemeStore = defineStore('theme-store', () => {
|
||||||
const themeVars = useThemeVars();
|
const themeVars = useThemeVars();
|
||||||
|
const { bool: darkMode, setBool: setDarkMode, toggle: toggleDarkMode } = useBoolean();
|
||||||
|
const { addDarkClass, removeDarkClass } = handleWindicssDarkMode();
|
||||||
|
|
||||||
const themeColor = ref('#1890ff');
|
const themeColor = ref('#1890ff');
|
||||||
const otherColor = computed<OtherColor>(() => ({
|
const otherColor = computed<OtherColor>(() => ({
|
||||||
@ -62,6 +75,12 @@ export const useThemeStore = defineStore('theme-store', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** naive-ui暗黑主题 */
|
||||||
|
const naiveTheme = computed(() => (darkMode.value ? darkTheme : undefined));
|
||||||
|
|
||||||
|
/** 操作系统暗黑主题 */
|
||||||
|
const osTheme = useOsTheme();
|
||||||
|
|
||||||
/** 添加css vars至html */
|
/** 添加css vars至html */
|
||||||
function addThemeCssVarsToHtml() {
|
function addThemeCssVarsToHtml() {
|
||||||
if (document.documentElement.style.cssText) return;
|
if (document.documentElement.style.cssText) return;
|
||||||
@ -82,10 +101,40 @@ export const useThemeStore = defineStore('theme-store', () => {
|
|||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
// 监听操作系统主题模式
|
||||||
|
watch(
|
||||||
|
osTheme,
|
||||||
|
newValue => {
|
||||||
|
const isDark = newValue === 'dark';
|
||||||
|
if (isDark) {
|
||||||
|
setDarkMode(true);
|
||||||
|
} else {
|
||||||
|
setDarkMode(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
// 监听主题的暗黑模式
|
||||||
|
watch(
|
||||||
|
() => darkMode.value,
|
||||||
|
newValue => {
|
||||||
|
if (newValue) {
|
||||||
|
addDarkClass();
|
||||||
|
} else {
|
||||||
|
removeDarkClass();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
const themeStore: ThemeStore = {
|
const themeStore: ThemeStore = {
|
||||||
|
darkMode,
|
||||||
|
setDarkMode,
|
||||||
|
toggleDarkMode,
|
||||||
themeColor,
|
themeColor,
|
||||||
otherColor,
|
otherColor,
|
||||||
naiveThemeOverrides
|
naiveThemeOverrides,
|
||||||
|
naiveTheme
|
||||||
};
|
};
|
||||||
|
|
||||||
return themeStore;
|
return themeStore;
|
||||||
|
10
src/typings/api/auth.d.ts
vendored
Normal file
10
src/typings/api/auth.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/** 后端返回的用户权益相关类型 */
|
||||||
|
declare namespace ApiAuth {
|
||||||
|
/** 返回的token和刷新token */
|
||||||
|
interface Token {
|
||||||
|
token: string;
|
||||||
|
refreshToken: string;
|
||||||
|
}
|
||||||
|
/** 返回的用户信息 */
|
||||||
|
type UserInfo = Auth.UserInfo;
|
||||||
|
}
|
2
src/typings/api/route.d.ts
vendored
2
src/typings/api/route.d.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
/** 后端返回的路由相关类型 */
|
/** 后端返回的路由相关类型 */
|
||||||
declare namespace ApiRoute {
|
declare namespace ApiRoute {
|
||||||
/** 后端返回的路由数据类型 */
|
/** 后端返回的路由数据类型 */
|
||||||
interface ResponseRoute {
|
interface Route {
|
||||||
/** 动态路由 */
|
/** 动态路由 */
|
||||||
routes: AuthRoute.Route[];
|
routes: AuthRoute.Route[];
|
||||||
/** 路由首页对应的key */
|
/** 路由首页对应的key */
|
||||||
|
22
src/typings/business/auth.d.ts
vendored
22
src/typings/business/auth.d.ts
vendored
@ -1,15 +1,5 @@
|
|||||||
/** 用户相关模块 */
|
/** 用户相关模块 */
|
||||||
declare namespace Auth {
|
declare namespace Auth {
|
||||||
/** 用户信息 */
|
|
||||||
interface UserInfo {
|
|
||||||
/** 用户id */
|
|
||||||
userId: string;
|
|
||||||
/** 用户名 */
|
|
||||||
userName: string;
|
|
||||||
/** 用户手机号 */
|
|
||||||
userPhone: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户角色类型
|
* 用户角色类型
|
||||||
* - super: 超级管理员
|
* - super: 超级管理员
|
||||||
@ -18,4 +8,16 @@ declare namespace Auth {
|
|||||||
* - visitor: 游客
|
* - visitor: 游客
|
||||||
*/
|
*/
|
||||||
type RoleType = 'super' | 'admin' | 'test' | 'visitor';
|
type RoleType = 'super' | 'admin' | 'test' | 'visitor';
|
||||||
|
|
||||||
|
/** 用户信息 */
|
||||||
|
interface UserInfo {
|
||||||
|
/** 用户id */
|
||||||
|
userId: string;
|
||||||
|
/** 用户名 */
|
||||||
|
userName: string;
|
||||||
|
/** 用户手机号 */
|
||||||
|
userPhone: string;
|
||||||
|
/** 用户角色类型 */
|
||||||
|
userRole: RoleType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
9
src/typings/common/route.d.ts
vendored
9
src/typings/common/route.d.ts
vendored
@ -24,7 +24,7 @@ declare namespace AuthRoute {
|
|||||||
: `/${Key}`;
|
: `/${Key}`;
|
||||||
|
|
||||||
/** 路由路径 */
|
/** 路由路径 */
|
||||||
type RoutePath<Key extends string = string> =
|
type RoutePath<Key extends string = '' | LoginPath> =
|
||||||
| '/'
|
| '/'
|
||||||
| Exclude<KeyToPath<RouteKey>, '/root' | '/redirect'>
|
| Exclude<KeyToPath<RouteKey>, '/root' | '/redirect'>
|
||||||
| Key
|
| Key
|
||||||
@ -65,8 +65,11 @@ declare namespace AuthRoute {
|
|||||||
order?: number;
|
order?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 登录路由路径 */
|
||||||
|
type LoginPath = `/login/:module(${string})?`;
|
||||||
|
|
||||||
/** 单个路由的类型结构(后端返回此类型结构的路由) */
|
/** 单个路由的类型结构(后端返回此类型结构的路由) */
|
||||||
interface Route<T extends string = ''> {
|
interface Route<T extends string = '' | LoginPath> {
|
||||||
/** 路由名称(路由唯一标识) */
|
/** 路由名称(路由唯一标识) */
|
||||||
name: RouteKey;
|
name: RouteKey;
|
||||||
/** 路由路径 */
|
/** 路由路径 */
|
||||||
@ -85,5 +88,7 @@ declare namespace AuthRoute {
|
|||||||
children?: Route[];
|
children?: Route[];
|
||||||
/** 路由描述 */
|
/** 路由描述 */
|
||||||
meta: RouteMeta;
|
meta: RouteMeta;
|
||||||
|
/** 属性 */
|
||||||
|
props?: boolean | Record<string, any> | ((to: any) => Record<string, any>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
src/typings/common/util.d.ts
vendored
2
src/typings/common/util.d.ts
vendored
@ -12,6 +12,4 @@ declare namespace Util {
|
|||||||
type UnionToTuple<T, U = T> = [T] extends [never]
|
type UnionToTuple<T, U = T> = [T] extends [never]
|
||||||
? []
|
? []
|
||||||
: [LastInUnion<T>, ...UnionToTuple<Exclude<U, LastInUnion<T>>>];
|
: [LastInUnion<T>, ...UnionToTuple<Exclude<U, LastInUnion<T>>>];
|
||||||
|
|
||||||
type Inter = UnionToTuple<'1' | '2'>;
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,8 @@ export function getUserInfo() {
|
|||||||
const emptyInfo: Auth.UserInfo = {
|
const emptyInfo: Auth.UserInfo = {
|
||||||
userId: '',
|
userId: '',
|
||||||
userName: '',
|
userName: '',
|
||||||
userPhone: ''
|
userPhone: '',
|
||||||
|
userRole: 'visitor'
|
||||||
};
|
};
|
||||||
const userInfo: Auth.UserInfo = getLocal<Auth.UserInfo>(EnumStorageKey['user-info']) || emptyInfo;
|
const userInfo: Auth.UserInfo = getLocal<Auth.UserInfo>(EnumStorageKey['user-info']) || emptyInfo;
|
||||||
return userInfo;
|
return userInfo;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export * from './typeof';
|
export * from './typeof';
|
||||||
export * from './console';
|
export * from './console';
|
||||||
export * from './color';
|
export * from './color';
|
||||||
|
export * from './number';
|
||||||
export * from './design-pattern';
|
export * from './design-pattern';
|
||||||
|
23
src/utils/common/number.ts
Normal file
23
src/utils/common/number.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 根据数字获取对应的汉字
|
||||||
|
* @param num - 数字(0-10)
|
||||||
|
*/
|
||||||
|
export function getHanByNumber(num: number) {
|
||||||
|
const HAN_STR = '零一二三四五六七八九十';
|
||||||
|
return HAN_STR.charAt(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将总秒数转换成 分:秒
|
||||||
|
* @param seconds - 秒
|
||||||
|
*/
|
||||||
|
export function transformToTimeCountDown(seconds: number) {
|
||||||
|
const SECONDS_A_MINUTE = 60;
|
||||||
|
function fillZero(num: number) {
|
||||||
|
return num.toString().padStart(2, '0');
|
||||||
|
}
|
||||||
|
const minuteNum = Math.floor(seconds / SECONDS_A_MINUTE);
|
||||||
|
const minute = fillZero(minuteNum);
|
||||||
|
const second = fillZero(seconds - minuteNum * SECONDS_A_MINUTE);
|
||||||
|
return `${minute}: ${second}`;
|
||||||
|
}
|
1
src/utils/form/index.ts
Normal file
1
src/utils/form/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './rule';
|
73
src/utils/form/rule.ts
Normal file
73
src/utils/form/rule.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { Ref } from 'vue';
|
||||||
|
import type { FormItemRule } from 'naive-ui';
|
||||||
|
import { REGEXP_PHONE, REGEXP_PWD, REGEXP_CODE_SIX, REGEXP_EMAIL } from '@/config';
|
||||||
|
|
||||||
|
/** 表单规则 */
|
||||||
|
interface CustomFormRules {
|
||||||
|
/** 手机号码 */
|
||||||
|
phone: FormItemRule[];
|
||||||
|
/** 密码 */
|
||||||
|
pwd: FormItemRule[];
|
||||||
|
/** 验证码 */
|
||||||
|
code: FormItemRule[];
|
||||||
|
/** 邮箱 */
|
||||||
|
email: FormItemRule[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单规则 */
|
||||||
|
export const formRules: CustomFormRules = {
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入手机号码' },
|
||||||
|
{ pattern: REGEXP_PHONE, message: '手机号码格式错误', trigger: 'input' }
|
||||||
|
],
|
||||||
|
pwd: [
|
||||||
|
{ required: true, message: '请输入密码' },
|
||||||
|
{ pattern: REGEXP_PWD, message: '密码为8-18位数字/字符/符号,至少2种组合', trigger: 'input' }
|
||||||
|
],
|
||||||
|
code: [
|
||||||
|
{ required: true, message: '请输入验证码' },
|
||||||
|
{ pattern: REGEXP_CODE_SIX, message: '验证码格式错误', trigger: 'input' }
|
||||||
|
],
|
||||||
|
email: [{ pattern: REGEXP_EMAIL, message: '邮箱格式错误', trigger: 'blur' }]
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取确认密码的表单规则 */
|
||||||
|
export function getConfirmPwdRule(pwd: Ref<string>) {
|
||||||
|
const confirmPwdRule: FormItemRule[] = [
|
||||||
|
{ required: true, message: '请输入确认密码' },
|
||||||
|
{
|
||||||
|
validator: (rule, value) => {
|
||||||
|
if (!isBlankString(value) && value !== pwd.value) {
|
||||||
|
return Promise.reject(rule.message);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
message: '输入的值与密码不一致',
|
||||||
|
trigger: 'input'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return confirmPwdRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取图片验证码的表单规则 */
|
||||||
|
export function getImgCodeRule(imgCode: Ref<string>) {
|
||||||
|
const imgCodeRule: FormItemRule[] = [
|
||||||
|
{ required: true, message: '请输入验证码' },
|
||||||
|
{
|
||||||
|
validator: (rule, value) => {
|
||||||
|
if (!isBlankString(value) && value !== imgCode.value) {
|
||||||
|
return Promise.reject(rule.message);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
message: '验证码不正确',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return imgCodeRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 是否为空字符串 */
|
||||||
|
function isBlankString(str: string) {
|
||||||
|
return str.trim() === '';
|
||||||
|
}
|
@ -3,3 +3,4 @@ export * from './storage';
|
|||||||
export * from './service';
|
export * from './service';
|
||||||
export * from './auth';
|
export * from './auth';
|
||||||
export * from './router';
|
export * from './router';
|
||||||
|
export * from './form';
|
||||||
|
@ -40,12 +40,18 @@ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) {
|
|||||||
consoleError('路由组件解析失败: ', item);
|
consoleError('路由组件解析失败: ', item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasProps(item) && !isSingleRoute(item)) {
|
||||||
|
(itemRoute as any).props = item.props;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSingleRoute(item)) {
|
if (isSingleRoute(item)) {
|
||||||
itemRoute.children = [
|
itemRoute.children = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
name: item.name,
|
name: item.name,
|
||||||
component: getViewComponent(item.name)
|
component: getViewComponent(item.name),
|
||||||
|
props: hasProps(item) ? item.props : undefined
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
} else if (hasChildren(item)) {
|
} else if (hasChildren(item)) {
|
||||||
@ -67,6 +73,10 @@ function hasChildren(item: AuthRoute.Route) {
|
|||||||
return Boolean(item.children && item.children.length);
|
return Boolean(item.children && item.children.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasProps(item: AuthRoute.Route) {
|
||||||
|
return Boolean(item.props);
|
||||||
|
}
|
||||||
|
|
||||||
function isSingleRoute(item: AuthRoute.Route) {
|
function isSingleRoute(item: AuthRoute.Route) {
|
||||||
return Boolean(item.meta.single);
|
return Boolean(item.meta.single);
|
||||||
}
|
}
|
||||||
|
61
src/views/system/login/components/BindWechat/index.vue
Normal file
61
src/views/system/login/components/BindWechat/index.vue
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
|
<n-form-item path="phone">
|
||||||
|
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="code">
|
||||||
|
<div class="flex-y-center w-full">
|
||||||
|
<n-input v-model:value="model.code" placeholder="验证码" />
|
||||||
|
<div class="w-18px"></div>
|
||||||
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
|
{{ label }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-space :vertical="true" size="large">
|
||||||
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
||||||
|
</n-space>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { NForm, NFormItem, NInput, NSpace, NButton } from 'naive-ui';
|
||||||
|
import type { FormInst } from 'naive-ui';
|
||||||
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { useSmsCode } from '@/hooks';
|
||||||
|
import { formRules } from '@/utils';
|
||||||
|
|
||||||
|
const { toLoginModule } = useRouterPush();
|
||||||
|
const { label, isCounting, loading: smsLoading, getSmsCode } = useSmsCode();
|
||||||
|
|
||||||
|
const formRef = ref<(HTMLElement & FormInst) | null>(null);
|
||||||
|
const model = reactive({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
imgCode: ''
|
||||||
|
});
|
||||||
|
const rules = {
|
||||||
|
phone: formRules.phone,
|
||||||
|
code: formRules.code
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleSmsCode() {
|
||||||
|
getSmsCode(model.phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(e: MouseEvent) {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
formRef.value.validate(errors => {
|
||||||
|
if (!errors) {
|
||||||
|
window.$message?.success('验证成功');
|
||||||
|
} else {
|
||||||
|
window.$message?.error('验证失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
81
src/views/system/login/components/CodeLogin/index.vue
Normal file
81
src/views/system/login/components/CodeLogin/index.vue
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
|
<n-form-item path="phone">
|
||||||
|
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="code">
|
||||||
|
<div class="flex-y-center w-full">
|
||||||
|
<n-input v-model:value="model.code" placeholder="验证码" />
|
||||||
|
<div class="w-18px"></div>
|
||||||
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
|
{{ label }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="imgCode">
|
||||||
|
<n-input v-model:value="model.imgCode" placeholder="验证码,点击图片刷新" />
|
||||||
|
<div class="pl-8px">
|
||||||
|
<image-verify v-model:code="imgCode" />
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-space :vertical="true" size="large">
|
||||||
|
<n-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
:block="true"
|
||||||
|
:round="true"
|
||||||
|
:loading="auth.loginLoding"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
||||||
|
</n-space>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { NForm, NFormItem, NInput, NSpace, NButton } from 'naive-ui';
|
||||||
|
import type { FormInst } from 'naive-ui';
|
||||||
|
import { ImageVerify } from '@/components';
|
||||||
|
import { useAuthStore } from '@/store';
|
||||||
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { useSmsCode } from '@/hooks';
|
||||||
|
import { formRules, getImgCodeRule } from '@/utils';
|
||||||
|
|
||||||
|
const auth = useAuthStore();
|
||||||
|
const { login } = useAuthStore();
|
||||||
|
const { toLoginModule } = useRouterPush();
|
||||||
|
const { label, isCounting, loading: smsLoading, getSmsCode } = useSmsCode();
|
||||||
|
|
||||||
|
const formRef = ref<(HTMLElement & FormInst) | null>(null);
|
||||||
|
const model = reactive({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
imgCode: ''
|
||||||
|
});
|
||||||
|
const imgCode = ref('');
|
||||||
|
const rules = {
|
||||||
|
phone: formRules.phone,
|
||||||
|
code: formRules.code,
|
||||||
|
imgCode: getImgCodeRule(imgCode)
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleSmsCode() {
|
||||||
|
getSmsCode(model.phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(e: MouseEvent) {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
formRef.value.validate(errors => {
|
||||||
|
if (!errors) {
|
||||||
|
const { phone, code } = model;
|
||||||
|
login(phone, code, 'sms');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="absolute-lt wh-full overflow-hidden">
|
<div class="absolute-lt z-1 wh-full overflow-hidden">
|
||||||
<div class="absolute -right-300px -top-900px">
|
<div class="absolute -right-300px -top-900px">
|
||||||
<corner-top :start-color="lightColor" :end-color="darkColor" />
|
<corner-top :start-color="lightColor" :end-color="darkColor" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<n-space :vertical="true">
|
||||||
|
<n-divider class="!mb-0 text-14px text-[#666]">其他登录方式</n-divider>
|
||||||
|
<div class="flex-center">
|
||||||
|
<n-button :text="true">
|
||||||
|
<icon-mdi-wechat class="text-22px text-[#888] hover:text-[#52BF5E]" />
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { NSpace, NDivider, NButton } from 'naive-ui';
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
@ -0,0 +1,3 @@
|
|||||||
|
import OtherLogin from './OtherLogin.vue';
|
||||||
|
|
||||||
|
export { OtherLogin };
|
75
src/views/system/login/components/PwdLogin/index.vue
Normal file
75
src/views/system/login/components/PwdLogin/index.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
|
<n-form-item path="phone">
|
||||||
|
<n-input v-model:value="model.phone" placeholder="请输入手机号码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="pwd">
|
||||||
|
<n-input v-model:value="model.pwd" type="password" show-password-on="click" placeholder="请输入密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-space :vertical="true" :size="24">
|
||||||
|
<div class="flex-y-center justify-between">
|
||||||
|
<n-checkbox v-model:checked="rememberMe">记住我</n-checkbox>
|
||||||
|
<n-button :text="true">忘记密码?</n-button>
|
||||||
|
</div>
|
||||||
|
<n-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
:block="true"
|
||||||
|
:round="true"
|
||||||
|
:loading="auth.loginLoding"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</n-button>
|
||||||
|
<div class="flex-y-center justify-between">
|
||||||
|
<n-button class="flex-1" :block="true" @click="toLoginModule('code-login')">
|
||||||
|
{{ EnumLoginModule['code-login'] }}
|
||||||
|
</n-button>
|
||||||
|
<div class="w-12px"></div>
|
||||||
|
<n-button class="flex-1" :block="true" @click="toLoginModule('register')">
|
||||||
|
{{ EnumLoginModule.register }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-space>
|
||||||
|
<other-login />
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { NForm, NFormItem, NInput, NSpace, NCheckbox, NButton } from 'naive-ui';
|
||||||
|
import type { FormInst, FormRules } from 'naive-ui';
|
||||||
|
import { EnumLoginModule } from '@/enum';
|
||||||
|
import { useAuthStore } from '@/store';
|
||||||
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { formRules } from '@/utils';
|
||||||
|
import { OtherLogin } from './components';
|
||||||
|
|
||||||
|
const auth = useAuthStore();
|
||||||
|
const { login } = useAuthStore();
|
||||||
|
const { toLoginModule } = useRouterPush();
|
||||||
|
|
||||||
|
const formRef = ref<(HTMLElement & FormInst) | null>(null);
|
||||||
|
const model = reactive({
|
||||||
|
phone: '',
|
||||||
|
pwd: ''
|
||||||
|
});
|
||||||
|
const rules: FormRules = {
|
||||||
|
phone: formRules.phone,
|
||||||
|
pwd: formRules.pwd
|
||||||
|
};
|
||||||
|
const rememberMe = ref(false);
|
||||||
|
|
||||||
|
function handleSubmit(e: MouseEvent) {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
formRef.value.validate(errors => {
|
||||||
|
if (!errors) {
|
||||||
|
const { phone, pwd } = model;
|
||||||
|
login(phone, pwd, 'pwd');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
75
src/views/system/login/components/Register/index.vue
Normal file
75
src/views/system/login/components/Register/index.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
|
<n-form-item path="phone">
|
||||||
|
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="code">
|
||||||
|
<div class="flex-y-center w-full">
|
||||||
|
<n-input v-model:value="model.code" placeholder="验证码" />
|
||||||
|
<div class="w-18px"></div>
|
||||||
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
|
{{ label }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="pwd">
|
||||||
|
<n-input v-model:value="model.pwd" placeholder="密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="confirmPwd">
|
||||||
|
<n-input v-model:value="model.confirmPwd" placeholder="确认密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-space :vertical="true" size="large">
|
||||||
|
<login-agreement v-model:value="agreement" />
|
||||||
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
||||||
|
</n-space>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, toRefs } from 'vue';
|
||||||
|
import { NForm, NFormItem, NInput, NSpace, NButton } from 'naive-ui';
|
||||||
|
import type { FormInst, FormRules } from 'naive-ui';
|
||||||
|
import { LoginAgreement } from '@/components';
|
||||||
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { useSmsCode } from '@/hooks';
|
||||||
|
import { formRules, getConfirmPwdRule } from '@/utils';
|
||||||
|
|
||||||
|
const { toLoginModule } = useRouterPush();
|
||||||
|
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
||||||
|
|
||||||
|
const formRef = ref<(HTMLElement & FormInst) | null>(null);
|
||||||
|
const model = reactive({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
pwd: '',
|
||||||
|
confirmPwd: ''
|
||||||
|
});
|
||||||
|
const rules: FormRules = {
|
||||||
|
phone: formRules.phone,
|
||||||
|
code: formRules.code,
|
||||||
|
pwd: formRules.pwd,
|
||||||
|
confirmPwd: getConfirmPwdRule(toRefs(model).pwd)
|
||||||
|
};
|
||||||
|
|
||||||
|
const agreement = ref(false);
|
||||||
|
|
||||||
|
function handleSmsCode() {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(e: MouseEvent) {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
formRef.value.validate(errors => {
|
||||||
|
if (!errors) {
|
||||||
|
if (!agreement.value) return;
|
||||||
|
window.$message?.success('验证成功');
|
||||||
|
} else {
|
||||||
|
window.$message?.error('验证失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
71
src/views/system/login/components/ResetPwd/index.vue
Normal file
71
src/views/system/login/components/ResetPwd/index.vue
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
|
||||||
|
<n-form-item path="phone">
|
||||||
|
<n-input v-model:value="model.phone" placeholder="手机号码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="code">
|
||||||
|
<div class="flex-y-center w-full">
|
||||||
|
<n-input v-model:value="model.code" placeholder="验证码" />
|
||||||
|
<div class="w-18px"></div>
|
||||||
|
<n-button size="large" :disabled="isCounting" :loading="smsLoading" @click="handleSmsCode">
|
||||||
|
{{ label }}
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="pwd">
|
||||||
|
<n-input v-model:value="model.pwd" placeholder="密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item path="confirmPwd">
|
||||||
|
<n-input v-model:value="model.confirmPwd" placeholder="确认密码" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-space :vertical="true" size="large">
|
||||||
|
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
||||||
|
<n-button size="large" :block="true" :round="true" @click="toLoginModule('pwd-login')">返回</n-button>
|
||||||
|
</n-space>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref, toRefs } from 'vue';
|
||||||
|
import { NForm, NFormItem, NInput, NSpace, NButton, useMessage } from 'naive-ui';
|
||||||
|
import type { FormInst, FormRules } from 'naive-ui';
|
||||||
|
import { useRouterPush } from '@/composables';
|
||||||
|
import { useSmsCode } from '@/hooks';
|
||||||
|
import { formRules, getConfirmPwdRule } from '@/utils';
|
||||||
|
|
||||||
|
const message = useMessage();
|
||||||
|
const { toLoginModule } = useRouterPush();
|
||||||
|
const { label, isCounting, loading: smsLoading, start } = useSmsCode();
|
||||||
|
|
||||||
|
const formRef = ref<(HTMLElement & FormInst) | null>(null);
|
||||||
|
const model = reactive({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
pwd: '',
|
||||||
|
confirmPwd: ''
|
||||||
|
});
|
||||||
|
const rules: FormRules = {
|
||||||
|
phone: formRules.phone,
|
||||||
|
code: formRules.code,
|
||||||
|
pwd: formRules.pwd,
|
||||||
|
confirmPwd: getConfirmPwdRule(toRefs(model).pwd)
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleSmsCode() {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSubmit(e: MouseEvent) {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
formRef.value.validate(errors => {
|
||||||
|
if (!errors) {
|
||||||
|
message.success('验证成功');
|
||||||
|
} else {
|
||||||
|
message.error('验证失败');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
@ -1,3 +1,8 @@
|
|||||||
import LoginBg from './LoginBg/index.vue';
|
import LoginBg from './LoginBg/index.vue';
|
||||||
|
import PwdLogin from './PwdLogin/index.vue';
|
||||||
|
import CodeLogin from './CodeLogin/index.vue';
|
||||||
|
import Register from './Register/index.vue';
|
||||||
|
import ResetPwd from './ResetPwd/index.vue';
|
||||||
|
import BindWechat from './BindWechat/index.vue';
|
||||||
|
|
||||||
export { LoginBg };
|
export { LoginBg, PwdLogin, CodeLogin, Register, ResetPwd, BindWechat };
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative flex-center wh-full" :style="{ backgroundColor: bgColor }">
|
<div class="relative flex-center wh-full" :style="{ backgroundColor: bgColor }">
|
||||||
<n-card :bordered="false" size="large" class="z-20 !w-auto rounded-20px shadow-sm">
|
<dark-mode-switch
|
||||||
|
:dark="theme.darkMode"
|
||||||
|
class="absolute left-48px top-24px z-3 text-20px"
|
||||||
|
@update:dark="setDarkMode"
|
||||||
|
/>
|
||||||
|
<n-card :bordered="false" size="large" class="z-4 !w-auto rounded-20px shadow-sm">
|
||||||
<div class="w-360px">
|
<div class="w-360px">
|
||||||
<header class="flex-y-center justify-between">
|
<header class="flex-y-center justify-between">
|
||||||
<div class="w-70px h-70px rounded-35px overflow-hidden">
|
<div class="w-70px h-70px rounded-35px overflow-hidden">
|
||||||
@ -9,30 +14,70 @@
|
|||||||
<n-gradient-text type="primary" :size="28">{{ title }}</n-gradient-text>
|
<n-gradient-text type="primary" :size="28">{{ title }}</n-gradient-text>
|
||||||
</header>
|
</header>
|
||||||
<main class="pt-24px">
|
<main class="pt-24px">
|
||||||
<h3 class="text-18px text-primary font-medium">登录</h3>
|
<h3 class="text-18px text-primary font-medium">{{ activeModule.label }}</h3>
|
||||||
|
<div class="pt-24px">
|
||||||
|
<transition>
|
||||||
|
<component :is="activeModule.component" />
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
<login-bg :theme-color="theme.themeColor" />
|
<login-bg :theme-color="bgThemeColor" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import type { Component } from 'vue';
|
||||||
import { NCard, NGradientText } from 'naive-ui';
|
import { NCard, NGradientText } from 'naive-ui';
|
||||||
import { SystemLogo } from '@/components';
|
import { EnumLoginModule } from '@/enum';
|
||||||
|
import { SystemLogo, DarkModeSwitch } from '@/components';
|
||||||
import { useThemeStore } from '@/store';
|
import { useThemeStore } from '@/store';
|
||||||
import { useAppInfo } from '@/composables';
|
import { useAppInfo } from '@/composables';
|
||||||
import { mixColor } from '@/utils';
|
import { getColorPalette, mixColor } from '@/utils';
|
||||||
import { LoginBg } from './components';
|
import type { LoginModuleKey } from '@/interface';
|
||||||
|
import { LoginBg, PwdLogin, CodeLogin, Register, ResetPwd, BindWechat } from './components';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** 登录模块分类 */
|
||||||
|
module: LoginModuleKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoginModule {
|
||||||
|
key: LoginModuleKey;
|
||||||
|
label: EnumLoginModule;
|
||||||
|
component: Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
const theme = useThemeStore();
|
const theme = useThemeStore();
|
||||||
|
const { setDarkMode } = useThemeStore();
|
||||||
const { title } = useAppInfo();
|
const { title } = useAppInfo();
|
||||||
|
|
||||||
|
const modules: LoginModule[] = [
|
||||||
|
{ key: 'pwd-login', label: EnumLoginModule['pwd-login'], component: PwdLogin },
|
||||||
|
{ key: 'code-login', label: EnumLoginModule['code-login'], component: CodeLogin },
|
||||||
|
{ key: 'register', label: EnumLoginModule.register, component: Register },
|
||||||
|
{ key: 'reset-pwd', label: EnumLoginModule['reset-pwd'], component: ResetPwd },
|
||||||
|
{ key: 'bind-wechat', label: EnumLoginModule['bind-wechat'], component: BindWechat }
|
||||||
|
];
|
||||||
|
|
||||||
|
const activeModule = computed(() => {
|
||||||
|
const active: LoginModule = { ...modules[0] };
|
||||||
|
const findItem = modules.find(item => item.key === props.module);
|
||||||
|
if (findItem) {
|
||||||
|
Object.assign(active, findItem);
|
||||||
|
}
|
||||||
|
return active;
|
||||||
|
});
|
||||||
|
|
||||||
|
const bgThemeColor = computed(() => (theme.darkMode ? getColorPalette(theme.themeColor, 7) : theme.themeColor));
|
||||||
|
|
||||||
const bgColor = computed(() => {
|
const bgColor = computed(() => {
|
||||||
const COLOR_WHITE = '#ffffff';
|
const COLOR_WHITE = '#ffffff';
|
||||||
const darkMode = false;
|
const ratio = theme.darkMode ? 0.5 : 0.2;
|
||||||
const ratio = darkMode ? 0.6 : 0.2;
|
|
||||||
return mixColor(COLOR_WHITE, theme.themeColor, ratio);
|
return mixColor(COLOR_WHITE, theme.themeColor, ratio);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user