feat: 更换ui组件库,naiveui->element-plus

This commit is contained in:
2026-06-18 09:58:36 +08:00
parent ab9e77669c
commit 33c2b31117
16 changed files with 6192 additions and 528 deletions

View File

@@ -1,5 +1,6 @@
{ {
"enabledPlugins": { "enabledPlugins": {
"frontend-design@claude-plugins-official": true "frontend-design@claude-plugins-official": true,
"context7@claude-plugins-official": true
} }
} }

5
auto-imports.d.ts vendored
View File

@@ -6,8 +6,5 @@
// biome-ignore lint: disable // biome-ignore lint: disable
export {} export {}
declare global { declare global {
const useDialog: typeof import('native-ui').useDialog
const useLoadingBar: typeof import('native-ui').useLoadingBar
const useMessage: typeof import('native-ui').useMessage
const useNotification: typeof import('native-ui').useNotification
} }

60
components.d.ts vendored
View File

@@ -12,26 +12,16 @@ export {}
/* prettier-ignore */ /* prettier-ignore */
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default'] ElAvatar: typeof import('element-plus/es')['ElAvatar']
IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default'] ElBadge: typeof import('element-plus/es')['ElBadge']
IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default'] ElButton: typeof import('element-plus/es')['ElButton']
IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] ElForm: typeof import('element-plus/es')['ElForm']
NAvatar: typeof import('naive-ui')['NAvatar'] ElFormItem: typeof import('element-plus/es')['ElFormItem']
NBadge: typeof import('naive-ui')['NBadge'] ElIcon: typeof import('element-plus/es')['ElIcon']
NButton: typeof import('naive-ui')['NButton'] ElInput: typeof import('element-plus/es')['ElInput']
NCheckbox: typeof import('naive-ui')['NCheckbox'] ElInputOtp: typeof import('element-plus/es')['ElInputOtp']
NConfigProvider: typeof import('naive-ui')['NConfigProvider'] ElPopover: typeof import('element-plus/es')['ElPopover']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NIcon: typeof import('naive-ui')['NIcon']
NInput: typeof import('naive-ui')['NInput']
NInputOtp: typeof import('naive-ui')['NInputOtp']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NPopover: typeof import('naive-ui')['NPopover']
NQrCode: typeof import('naive-ui')['NQrCode']
NSpace: typeof import('naive-ui')['NSpace']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
UserBar: typeof import('./src/components/User/UserBar.vue')['default'] UserBar: typeof import('./src/components/User/UserBar.vue')['default']
@@ -40,26 +30,16 @@ declare module 'vue' {
// For TSX support // For TSX support
declare global { declare global {
const IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default'] const ElAvatar: typeof import('element-plus/es')['ElAvatar']
const IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default'] const ElBadge: typeof import('element-plus/es')['ElBadge']
const IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default'] const ElButton: typeof import('element-plus/es')['ElButton']
const IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default'] const ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
const IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] const ElForm: typeof import('element-plus/es')['ElForm']
const NAvatar: typeof import('naive-ui')['NAvatar'] const ElFormItem: typeof import('element-plus/es')['ElFormItem']
const NBadge: typeof import('naive-ui')['NBadge'] const ElIcon: typeof import('element-plus/es')['ElIcon']
const NButton: typeof import('naive-ui')['NButton'] const ElInput: typeof import('element-plus/es')['ElInput']
const NCheckbox: typeof import('naive-ui')['NCheckbox'] const ElInputOtp: typeof import('element-plus/es')['ElInputOtp']
const NConfigProvider: typeof import('naive-ui')['NConfigProvider'] const ElPopover: typeof import('element-plus/es')['ElPopover']
const NForm: typeof import('naive-ui')['NForm']
const NFormItem: typeof import('naive-ui')['NFormItem']
const NIcon: typeof import('naive-ui')['NIcon']
const NInput: typeof import('naive-ui')['NInput']
const NInputOtp: typeof import('naive-ui')['NInputOtp']
const NMessageProvider: typeof import('naive-ui')['NMessageProvider']
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
const NPopover: typeof import('naive-ui')['NPopover']
const NQrCode: typeof import('naive-ui')['NQrCode']
const NSpace: typeof import('naive-ui')['NSpace']
const RouterLink: typeof import('vue-router')['RouterLink'] const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView'] const RouterView: typeof import('vue-router')['RouterView']
const UserBar: typeof import('./src/components/User/UserBar.vue')['default'] const UserBar: typeof import('./src/components/User/UserBar.vue')['default']

5479
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -13,16 +13,18 @@
}, },
"dependencies": { "dependencies": {
"axios": "^1.17.0", "axios": "^1.17.0",
"naive-ui": "^2.44.1", "element-plus": "^2.14.2",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"pinia-plugin-persistedstate": "^4.7.1", "pinia-plugin-persistedstate": "^4.7.1",
"qrcode": "^1.5.4",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^5.0.4" "vue-router": "^5.0.4"
}, },
"devDependencies": { "devDependencies": {
"@element-plus/icons-vue": "^2.3.2",
"@tsconfig/node24": "^24.0.4", "@tsconfig/node24": "^24.0.4",
"@types/node": "^24.12.2", "@types/node": "^24.12.2",
"@vicons/ionicons5": "^0.13.0", "@types/qrcode": "^1.5.6",
"@vitejs/plugin-vue": "^6.0.6", "@vitejs/plugin-vue": "^6.0.6",
"@vitejs/plugin-vue-jsx": "^5.1.5", "@vitejs/plugin-vue-jsx": "^5.1.5",
"@vue/tsconfig": "^0.9.1", "@vue/tsconfig": "^0.9.1",

491
pnpm-lock.yaml generated
View File

@@ -11,15 +11,18 @@ importers:
axios: axios:
specifier: ^1.17.0 specifier: ^1.17.0
version: 1.17.0 version: 1.17.0
naive-ui: element-plus:
specifier: ^2.44.1 specifier: ^2.14.2
version: 2.44.1(vue@3.5.35(typescript@6.0.3)) version: 2.14.2(vue@3.5.35(typescript@6.0.3))
pinia: pinia:
specifier: ^3.0.4 specifier: ^3.0.4
version: 3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)) version: 3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3))
pinia-plugin-persistedstate: pinia-plugin-persistedstate:
specifier: ^4.7.1 specifier: ^4.7.1
version: 4.7.1(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3))) version: 4.7.1(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))
qrcode:
specifier: ^1.5.4
version: 1.5.4
vue: vue:
specifier: ^3.5.32 specifier: ^3.5.32
version: 3.5.35(typescript@6.0.3) version: 3.5.35(typescript@6.0.3)
@@ -27,15 +30,18 @@ importers:
specifier: ^5.0.4 specifier: ^5.0.4
version: 5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) version: 5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))
devDependencies: devDependencies:
'@element-plus/icons-vue':
specifier: ^2.3.2
version: 2.3.2(vue@3.5.35(typescript@6.0.3))
'@tsconfig/node24': '@tsconfig/node24':
specifier: ^24.0.4 specifier: ^24.0.4
version: 24.0.4 version: 24.0.4
'@types/node': '@types/node':
specifier: ^24.12.2 specifier: ^24.12.2
version: 24.12.4 version: 24.12.4
'@vicons/ionicons5': '@types/qrcode':
specifier: ^0.13.0 specifier: ^1.5.6
version: 0.13.0 version: 1.5.6
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: ^6.0.6 specifier: ^6.0.6
version: 6.0.7(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) version: 6.0.7(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))
@@ -59,7 +65,7 @@ importers:
version: 6.0.3 version: 6.0.3
unplugin-auto-import: unplugin-auto-import:
specifier: ^21.0.0 specifier: ^21.0.0
version: 21.0.0 version: 21.0.0(@vueuse/core@14.3.0(vue@3.5.35(typescript@6.0.3)))
unplugin-vue-components: unplugin-vue-components:
specifier: ^32.1.0 specifier: ^32.1.0
version: 32.1.0(vue@3.5.35(typescript@6.0.3)) version: 32.1.0(vue@3.5.35(typescript@6.0.3))
@@ -239,15 +245,14 @@ packages:
'@bufbuild/protobuf@2.12.0': '@bufbuild/protobuf@2.12.0':
resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==} resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==}
'@css-render/plugin-bem@0.15.14': '@ctrl/tinycolor@4.2.0':
resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==}
peerDependencies: engines: {node: '>=14'}
css-render: ~0.15.14
'@css-render/vue3-ssr@0.15.14': '@element-plus/icons-vue@2.3.2':
resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==}
peerDependencies: peerDependencies:
vue: ^3.0.11 vue: ^3.2.0
'@emnapi/core@1.10.0': '@emnapi/core@1.10.0':
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
@@ -258,8 +263,14 @@ packages:
'@emnapi/wasi-threads@1.2.1': '@emnapi/wasi-threads@1.2.1':
resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
'@emotion/hash@0.8.0': '@floating-ui/core@1.7.5':
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
'@floating-ui/dom@1.7.6':
resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
'@floating-ui/utils@0.2.11':
resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
'@jridgewell/gen-mapping@0.3.13': '@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -277,9 +288,6 @@ packages:
'@jridgewell/trace-mapping@0.3.31': '@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@juggle/resize-observer@3.4.0':
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
'@napi-rs/wasm-runtime@1.1.4': '@napi-rs/wasm-runtime@1.1.4':
resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
peerDependencies: peerDependencies:
@@ -600,6 +608,9 @@ packages:
'@rolldown/pluginutils@1.0.1': '@rolldown/pluginutils@1.0.1':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
'@sxzz/popperjs-es@2.11.8':
resolution: {integrity: sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==}
'@tsconfig/node24@24.0.4': '@tsconfig/node24@24.0.4':
resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==} resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==}
@@ -621,8 +632,11 @@ packages:
'@types/node@24.12.4': '@types/node@24.12.4':
resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
'@vicons/ionicons5@0.13.0': '@types/qrcode@1.5.6':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==} resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
'@types/web-bluetooth@0.0.21':
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
'@vitejs/plugin-vue-jsx@5.1.5': '@vitejs/plugin-vue-jsx@5.1.5':
resolution: {integrity: sha512-jIAsvHOEtWpslLOI2MeElGFxH7M8pM83BU/Tor4RLyiwH0FM4nUW3xdvbw20EeU9wc5IspQwMq225K3CMnJEpA==} resolution: {integrity: sha512-jIAsvHOEtWpslLOI2MeElGFxH7M8pM83BU/Tor4RLyiwH0FM4nUW3xdvbw20EeU9wc5IspQwMq225K3CMnJEpA==}
@@ -754,6 +768,19 @@ packages:
vue: vue:
optional: true optional: true
'@vueuse/core@14.3.0':
resolution: {integrity: sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==}
peerDependencies:
vue: ^3.5.0
'@vueuse/metadata@14.3.0':
resolution: {integrity: sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==}
'@vueuse/shared@14.3.0':
resolution: {integrity: sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==}
peerDependencies:
vue: ^3.5.0
acorn@8.16.0: acorn@8.16.0:
resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
@@ -766,6 +793,14 @@ packages:
alien-signals@3.2.1: alien-signals@3.2.1:
resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.3: ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@@ -815,6 +850,10 @@ packages:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
caniuse-lite@1.0.30001793: caniuse-lite@1.0.30001793:
resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==}
@@ -822,6 +861,16 @@ packages:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
engines: {node: '>= 20.19.0'} engines: {node: '>= 20.19.0'}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colorjs.io@0.5.2: colorjs.io@0.5.2:
resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==} resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==}
@@ -846,22 +895,11 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
css-render@0.15.14:
resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==}
csstype@3.0.11:
resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
csstype@3.2.3: csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
date-fns-tz@3.2.0: dayjs@1.11.21:
resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==}
peerDependencies:
date-fns: ^3.0.0 || ^4.0.0
date-fns@4.4.0:
resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==}
debug@4.4.3: debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
@@ -872,6 +910,10 @@ packages:
supports-color: supports-color:
optional: true optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
default-browser-id@5.0.1: default-browser-id@5.0.1:
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
engines: {node: '>=18'} engines: {node: '>=18'}
@@ -895,6 +937,9 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dunder-proto@1.0.1: dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@@ -902,6 +947,14 @@ packages:
electron-to-chromium@1.5.364: electron-to-chromium@1.5.364:
resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==} resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==}
element-plus@2.14.2:
resolution: {integrity: sha512-eNH9uP3wQoNqieEIHXiNvIVv+zO5sZDU0CAZq5b0zqSN06DD0/V9xIq1R/qm3rw5k3nBTM1JvpxhCfRbaFLzDQ==}
peerDependencies:
vue: ^3.3.7
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
entities@7.0.1: entities@7.0.1:
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
@@ -939,9 +992,6 @@ packages:
estree-walker@3.0.3: estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
evtd@0.2.4:
resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==}
exsolve@1.0.8: exsolve@1.0.8:
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
@@ -954,6 +1004,10 @@ packages:
picomatch: picomatch:
optional: true optional: true
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
follow-redirects@1.16.0: follow-redirects@1.16.0:
resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
engines: {node: '>=4.0'} engines: {node: '>=4.0'}
@@ -979,6 +1033,10 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.3.0: get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@@ -1007,10 +1065,6 @@ packages:
resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
highlight.js@11.11.1:
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
engines: {node: '>=12.0.0'}
hookable@5.5.3: hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
@@ -1030,6 +1084,10 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-glob@4.0.3: is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@@ -1163,9 +1221,20 @@ packages:
resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==}
engines: {node: '>=14'} engines: {node: '>=14'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
lodash-es@4.18.1: lodash-es@4.18.1:
resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
lodash-unified@1.0.3:
resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==}
peerDependencies:
'@types/lodash-es': '*'
lodash: '*'
lodash-es: '*'
lodash@4.18.1: lodash@4.18.1:
resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
@@ -1183,6 +1252,9 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
memoize-one@6.0.0:
resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
memorystream@0.3.1: memorystream@0.3.1:
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
engines: {node: '>= 0.10.0'} engines: {node: '>= 0.10.0'}
@@ -1211,12 +1283,6 @@ packages:
muggle-string@0.4.1: muggle-string@0.4.1:
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
naive-ui@2.44.1:
resolution: {integrity: sha512-reo8Esw0p58liZwbUutC7meW24Xbn3EwNv91zReWKm2W4JPu+zfgJRn/F7aO0BFmvN+h2brA2M5lRvYqLq4kuA==}
engines: {node: '>=20'}
peerDependencies:
vue: ^3.0.0
nanoid@3.3.12: nanoid@3.3.12:
resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -1229,6 +1295,9 @@ packages:
resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
normalize-wheel-es@1.2.0:
resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
npm-normalize-package-bin@4.0.0: npm-normalize-package-bin@4.0.0:
resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
engines: {node: ^18.17.0 || >=20.5.0} engines: {node: ^18.17.0 || >=20.5.0}
@@ -1253,9 +1322,25 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
path-browserify@1.0.1: path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
path-key@3.1.1: path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -1310,6 +1395,10 @@ packages:
pkg-types@2.3.1: pkg-types@2.3.1:
resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==}
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
postcss@8.5.15: postcss@8.5.15:
resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
@@ -1322,6 +1411,11 @@ packages:
resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
engines: {node: '>=10'} engines: {node: '>=10'}
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
quansync@0.2.11: quansync@0.2.11:
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
@@ -1333,6 +1427,13 @@ packages:
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
engines: {node: '>= 20.19.0'} engines: {node: '>= 20.19.0'}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
rfdc@1.4.1: rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
@@ -1473,13 +1574,13 @@ packages:
scule@1.3.0: scule@1.3.0:
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
seemly@0.3.10:
resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==}
semver@6.3.1: semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true hasBin: true
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
shebang-command@2.0.0: shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -1504,6 +1605,14 @@ packages:
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-literal@3.1.0: strip-literal@3.1.0:
resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
@@ -1535,9 +1644,6 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
treemate@0.3.11:
resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==}
tslib@2.8.1: tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -1599,11 +1705,6 @@ packages:
varint@6.0.0: varint@6.0.0:
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
vdirs@0.1.8:
resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==}
peerDependencies:
vue: ^3.0.11
vite-dev-rpc@2.0.0: vite-dev-rpc@2.0.0:
resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==} resolution: {integrity: sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==}
peerDependencies: peerDependencies:
@@ -1678,14 +1779,12 @@ packages:
yaml: yaml:
optional: true optional: true
vooks@0.2.12:
resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==}
peerDependencies:
vue: ^3.0.0
vscode-uri@3.1.0: vscode-uri@3.1.0:
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
vue-component-type-helpers@3.3.5:
resolution: {integrity: sha512-Fe1jyPJoUGpJOYKOri44jduR7My4yYINOMJISuMAbmrs+L5LbIDUc8NTWZYY3EJLK0yPLuCmcd5zoCsE4k2/KA==}
vue-router@5.1.0: vue-router@5.1.0:
resolution: {integrity: sha512-HAbiLzLEHQwxPgvsbOJDAwtavszEgLwri6XfyrsPECIFez8+59xc9LofWVdc/HEaSRT822lJ8H9Ns38VVond5g==} resolution: {integrity: sha512-HAbiLzLEHQwxPgvsbOJDAwtavszEgLwri6XfyrsPECIFez8+59xc9LofWVdc/HEaSRT822lJ8H9Ns38VVond5g==}
peerDependencies: peerDependencies:
@@ -1718,14 +1817,12 @@ packages:
typescript: typescript:
optional: true optional: true
vueuc@0.4.65:
resolution: {integrity: sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==}
peerDependencies:
vue: ^3.0.11
webpack-virtual-modules@0.6.2: webpack-virtual-modules@0.6.2:
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
which@2.0.2: which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@@ -1736,10 +1833,17 @@ packages:
engines: {node: ^18.17.0 || >=20.5.0} engines: {node: ^18.17.0 || >=20.5.0}
hasBin: true hasBin: true
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
wsl-utils@0.3.1: wsl-utils@0.3.1:
resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==}
engines: {node: '>=20'} engines: {node: '>=20'}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
yallist@3.1.1: yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@@ -1748,6 +1852,14 @@ packages:
engines: {node: '>= 14.6'} engines: {node: '>= 14.6'}
hasBin: true hasBin: true
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
snapshots: snapshots:
'@babel/code-frame@7.29.7': '@babel/code-frame@7.29.7':
@@ -1965,11 +2077,9 @@ snapshots:
'@bufbuild/protobuf@2.12.0': {} '@bufbuild/protobuf@2.12.0': {}
'@css-render/plugin-bem@0.15.14(css-render@0.15.14)': '@ctrl/tinycolor@4.2.0': {}
dependencies:
css-render: 0.15.14
'@css-render/vue3-ssr@0.15.14(vue@3.5.35(typescript@6.0.3))': '@element-plus/icons-vue@2.3.2(vue@3.5.35(typescript@6.0.3))':
dependencies: dependencies:
vue: 3.5.35(typescript@6.0.3) vue: 3.5.35(typescript@6.0.3)
@@ -1989,7 +2099,16 @@ snapshots:
tslib: 2.8.1 tslib: 2.8.1
optional: true optional: true
'@emotion/hash@0.8.0': {} '@floating-ui/core@1.7.5':
dependencies:
'@floating-ui/utils': 0.2.11
'@floating-ui/dom@1.7.6':
dependencies:
'@floating-ui/core': 1.7.5
'@floating-ui/utils': 0.2.11
'@floating-ui/utils@0.2.11': {}
'@jridgewell/gen-mapping@0.3.13': '@jridgewell/gen-mapping@0.3.13':
dependencies: dependencies:
@@ -2010,8 +2129,6 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
'@juggle/resize-observer@3.4.0': {}
'@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
dependencies: dependencies:
'@emnapi/core': 1.10.0 '@emnapi/core': 1.10.0
@@ -2192,6 +2309,8 @@ snapshots:
'@rolldown/pluginutils@1.0.1': {} '@rolldown/pluginutils@1.0.1': {}
'@sxzz/popperjs-es@2.11.8': {}
'@tsconfig/node24@24.0.4': {} '@tsconfig/node24@24.0.4': {}
'@tybys/wasm-util@0.10.2': '@tybys/wasm-util@0.10.2':
@@ -2213,7 +2332,11 @@ snapshots:
dependencies: dependencies:
undici-types: 7.16.0 undici-types: 7.16.0
'@vicons/ionicons5@0.13.0': {} '@types/qrcode@1.5.6':
dependencies:
'@types/node': 24.12.4
'@types/web-bluetooth@0.0.21': {}
'@vitejs/plugin-vue-jsx@5.1.5(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': '@vitejs/plugin-vue-jsx@5.1.5(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))':
dependencies: dependencies:
@@ -2419,6 +2542,19 @@ snapshots:
typescript: 6.0.3 typescript: 6.0.3
vue: 3.5.35(typescript@6.0.3) vue: 3.5.35(typescript@6.0.3)
'@vueuse/core@14.3.0(vue@3.5.35(typescript@6.0.3))':
dependencies:
'@types/web-bluetooth': 0.0.21
'@vueuse/metadata': 14.3.0
'@vueuse/shared': 14.3.0(vue@3.5.35(typescript@6.0.3))
vue: 3.5.35(typescript@6.0.3)
'@vueuse/metadata@14.3.0': {}
'@vueuse/shared@14.3.0(vue@3.5.35(typescript@6.0.3))':
dependencies:
vue: 3.5.35(typescript@6.0.3)
acorn@8.16.0: {} acorn@8.16.0: {}
agent-base@6.0.2: agent-base@6.0.2:
@@ -2429,6 +2565,12 @@ snapshots:
alien-signals@3.2.1: {} alien-signals@3.2.1: {}
ansi-regex@5.0.1: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ansi-styles@6.2.3: {} ansi-styles@6.2.3: {}
ansis@4.3.1: {} ansis@4.3.1: {}
@@ -2481,12 +2623,26 @@ snapshots:
es-errors: 1.3.0 es-errors: 1.3.0
function-bind: 1.1.2 function-bind: 1.1.2
camelcase@5.3.1: {}
caniuse-lite@1.0.30001793: {} caniuse-lite@1.0.30001793: {}
chokidar@5.0.0: chokidar@5.0.0:
dependencies: dependencies:
readdirp: 5.0.0 readdirp: 5.0.0
cliui@6.0.0:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
colorjs.io@0.5.2: {} colorjs.io@0.5.2: {}
combined-stream@1.0.8: combined-stream@1.0.8:
@@ -2509,25 +2665,16 @@ snapshots:
shebang-command: 2.0.0 shebang-command: 2.0.0
which: 2.0.2 which: 2.0.2
css-render@0.15.14:
dependencies:
'@emotion/hash': 0.8.0
csstype: 3.0.11
csstype@3.0.11: {}
csstype@3.2.3: {} csstype@3.2.3: {}
date-fns-tz@3.2.0(date-fns@4.4.0): dayjs@1.11.21: {}
dependencies:
date-fns: 4.4.0
date-fns@4.4.0: {}
debug@4.4.3: debug@4.4.3:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
decamelize@1.2.0: {}
default-browser-id@5.0.1: {} default-browser-id@5.0.1: {}
default-browser@5.5.0: default-browser@5.5.0:
@@ -2543,6 +2690,8 @@ snapshots:
detect-libc@2.1.2: {} detect-libc@2.1.2: {}
dijkstrajs@1.0.3: {}
dunder-proto@1.0.1: dunder-proto@1.0.1:
dependencies: dependencies:
call-bind-apply-helpers: 1.0.2 call-bind-apply-helpers: 1.0.2
@@ -2551,6 +2700,27 @@ snapshots:
electron-to-chromium@1.5.364: {} electron-to-chromium@1.5.364: {}
element-plus@2.14.2(vue@3.5.35(typescript@6.0.3)):
dependencies:
'@ctrl/tinycolor': 4.2.0
'@element-plus/icons-vue': 2.3.2(vue@3.5.35(typescript@6.0.3))
'@floating-ui/dom': 1.7.6
'@popperjs/core': '@sxzz/popperjs-es@2.11.8'
'@types/lodash': 4.17.24
'@types/lodash-es': 4.17.12
'@vueuse/core': 14.3.0(vue@3.5.35(typescript@6.0.3))
async-validator: 4.2.5
dayjs: 1.11.21
lodash: 4.18.1
lodash-es: 4.18.1
lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.18.1)(lodash@4.18.1)
memoize-one: 6.0.0
normalize-wheel-es: 1.2.0
vue: 3.5.35(typescript@6.0.3)
vue-component-type-helpers: 3.3.5
emoji-regex@8.0.0: {}
entities@7.0.1: {} entities@7.0.1: {}
error-stack-parser-es@1.0.5: {} error-stack-parser-es@1.0.5: {}
@@ -2580,14 +2750,17 @@ snapshots:
dependencies: dependencies:
'@types/estree': 1.0.9 '@types/estree': 1.0.9
evtd@0.2.4: {}
exsolve@1.0.8: {} exsolve@1.0.8: {}
fdir@6.5.0(picomatch@4.0.4): fdir@6.5.0(picomatch@4.0.4):
optionalDependencies: optionalDependencies:
picomatch: 4.0.4 picomatch: 4.0.4
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
follow-redirects@1.16.0: {} follow-redirects@1.16.0: {}
form-data@4.0.5: form-data@4.0.5:
@@ -2605,6 +2778,8 @@ snapshots:
gensync@1.0.0-beta.2: {} gensync@1.0.0-beta.2: {}
get-caller-file@2.0.5: {}
get-intrinsic@1.3.0: get-intrinsic@1.3.0:
dependencies: dependencies:
call-bind-apply-helpers: 1.0.2 call-bind-apply-helpers: 1.0.2
@@ -2637,8 +2812,6 @@ snapshots:
dependencies: dependencies:
function-bind: 1.1.2 function-bind: 1.1.2
highlight.js@11.11.1: {}
hookable@5.5.3: {} hookable@5.5.3: {}
https-proxy-agent@5.0.1: https-proxy-agent@5.0.1:
@@ -2655,6 +2828,8 @@ snapshots:
is-extglob@2.1.1: is-extglob@2.1.1:
optional: true optional: true
is-fullwidth-code-point@3.0.0: {}
is-glob@4.0.3: is-glob@4.0.3:
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
@@ -2746,8 +2921,18 @@ snapshots:
pkg-types: 2.3.1 pkg-types: 2.3.1
quansync: 0.2.11 quansync: 0.2.11
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
lodash-es@4.18.1: {} lodash-es@4.18.1: {}
lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.18.1)(lodash@4.18.1):
dependencies:
'@types/lodash-es': 4.17.12
lodash: 4.18.1
lodash-es: 4.18.1
lodash@4.18.1: {} lodash@4.18.1: {}
lru-cache@5.1.1: lru-cache@5.1.1:
@@ -2764,6 +2949,8 @@ snapshots:
math-intrinsics@1.1.0: {} math-intrinsics@1.1.0: {}
memoize-one@6.0.0: {}
memorystream@0.3.1: {} memorystream@0.3.1: {}
mime-db@1.52.0: {} mime-db@1.52.0: {}
@@ -2787,28 +2974,6 @@ snapshots:
muggle-string@0.4.1: {} muggle-string@0.4.1: {}
naive-ui@2.44.1(vue@3.5.35(typescript@6.0.3)):
dependencies:
'@css-render/plugin-bem': 0.15.14(css-render@0.15.14)
'@css-render/vue3-ssr': 0.15.14(vue@3.5.35(typescript@6.0.3))
'@types/lodash': 4.17.24
'@types/lodash-es': 4.17.12
async-validator: 4.2.5
css-render: 0.15.14
csstype: 3.2.3
date-fns: 4.4.0
date-fns-tz: 3.2.0(date-fns@4.4.0)
evtd: 0.2.4
highlight.js: 11.11.1
lodash: 4.18.1
lodash-es: 4.18.1
seemly: 0.3.10
treemate: 0.3.11
vdirs: 0.1.8(vue@3.5.35(typescript@6.0.3))
vooks: 0.2.12(vue@3.5.35(typescript@6.0.3))
vue: 3.5.35(typescript@6.0.3)
vueuc: 0.4.65(vue@3.5.35(typescript@6.0.3))
nanoid@3.3.12: {} nanoid@3.3.12: {}
node-addon-api@7.1.1: node-addon-api@7.1.1:
@@ -2816,6 +2981,8 @@ snapshots:
node-releases@2.0.46: {} node-releases@2.0.46: {}
normalize-wheel-es@1.2.0: {}
npm-normalize-package-bin@4.0.0: {} npm-normalize-package-bin@4.0.0: {}
npm-run-all2@8.0.4: npm-run-all2@8.0.4:
@@ -2866,8 +3033,20 @@ snapshots:
'@oxfmt/binding-win32-ia32-msvc': 0.45.0 '@oxfmt/binding-win32-ia32-msvc': 0.45.0
'@oxfmt/binding-win32-x64-msvc': 0.45.0 '@oxfmt/binding-win32-x64-msvc': 0.45.0
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
p-try@2.2.0: {}
path-browserify@1.0.1: {} path-browserify@1.0.1: {}
path-exists@4.0.0: {}
path-key@3.1.1: {} path-key@3.1.1: {}
pathe@2.0.3: {} pathe@2.0.3: {}
@@ -2907,6 +3086,8 @@ snapshots:
exsolve: 1.0.8 exsolve: 1.0.8
pathe: 2.0.3 pathe: 2.0.3
pngjs@5.0.0: {}
postcss@8.5.15: postcss@8.5.15:
dependencies: dependencies:
nanoid: 3.3.12 nanoid: 3.3.12
@@ -2917,6 +3098,12 @@ snapshots:
proxy-from-env@2.1.0: {} proxy-from-env@2.1.0: {}
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
quansync@0.2.11: {} quansync@0.2.11: {}
read-package-json-fast@4.0.0: read-package-json-fast@4.0.0:
@@ -2926,6 +3113,10 @@ snapshots:
readdirp@5.0.0: {} readdirp@5.0.0: {}
require-directory@2.1.1: {}
require-main-filename@2.0.0: {}
rfdc@1.4.1: {} rfdc@1.4.1: {}
rolldown@1.0.3: rolldown@1.0.3:
@@ -3053,10 +3244,10 @@ snapshots:
scule@1.3.0: {} scule@1.3.0: {}
seemly@0.3.10: {}
semver@6.3.1: {} semver@6.3.1: {}
set-blocking@2.0.0: {}
shebang-command@2.0.0: shebang-command@2.0.0:
dependencies: dependencies:
shebang-regex: 3.0.0 shebang-regex: 3.0.0
@@ -3075,6 +3266,16 @@ snapshots:
speakingurl@14.0.1: {} speakingurl@14.0.1: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-literal@3.1.0: strip-literal@3.1.0:
dependencies: dependencies:
js-tokens: 9.0.1 js-tokens: 9.0.1
@@ -3102,8 +3303,6 @@ snapshots:
totalist@3.0.1: {} totalist@3.0.1: {}
treemate@0.3.11: {}
tslib@2.8.1: {} tslib@2.8.1: {}
typescript@6.0.3: {} typescript@6.0.3: {}
@@ -3129,7 +3328,7 @@ snapshots:
unplugin: 2.3.11 unplugin: 2.3.11
unplugin-utils: 0.3.1 unplugin-utils: 0.3.1
unplugin-auto-import@21.0.0: unplugin-auto-import@21.0.0(@vueuse/core@14.3.0(vue@3.5.35(typescript@6.0.3))):
dependencies: dependencies:
local-pkg: 1.2.1 local-pkg: 1.2.1
magic-string: 0.30.21 magic-string: 0.30.21
@@ -3137,6 +3336,8 @@ snapshots:
unimport: 5.7.0 unimport: 5.7.0
unplugin: 2.3.11 unplugin: 2.3.11
unplugin-utils: 0.3.1 unplugin-utils: 0.3.1
optionalDependencies:
'@vueuse/core': 14.3.0(vue@3.5.35(typescript@6.0.3))
unplugin-utils@0.3.1: unplugin-utils@0.3.1:
dependencies: dependencies:
@@ -3177,11 +3378,6 @@ snapshots:
varint@6.0.0: {} varint@6.0.0: {}
vdirs@0.1.8(vue@3.5.35(typescript@6.0.3)):
dependencies:
evtd: 0.2.4
vue: 3.5.35(typescript@6.0.3)
vite-dev-rpc@2.0.0(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0)): vite-dev-rpc@2.0.0(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0)):
dependencies: dependencies:
birpc: 4.0.0 birpc: 4.0.0
@@ -3249,13 +3445,10 @@ snapshots:
sass-embedded: 1.100.0 sass-embedded: 1.100.0
yaml: 2.9.0 yaml: 2.9.0
vooks@0.2.12(vue@3.5.35(typescript@6.0.3)):
dependencies:
evtd: 0.2.4
vue: 3.5.35(typescript@6.0.3)
vscode-uri@3.1.0: {} vscode-uri@3.1.0: {}
vue-component-type-helpers@3.3.5: {}
vue-router@5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)): vue-router@5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)):
dependencies: dependencies:
'@babel/generator': 8.0.0-rc.6 '@babel/generator': 8.0.0-rc.6
@@ -3297,19 +3490,10 @@ snapshots:
optionalDependencies: optionalDependencies:
typescript: 6.0.3 typescript: 6.0.3
vueuc@0.4.65(vue@3.5.35(typescript@6.0.3)):
dependencies:
'@css-render/vue3-ssr': 0.15.14(vue@3.5.35(typescript@6.0.3))
'@juggle/resize-observer': 3.4.0
css-render: 0.15.14
evtd: 0.2.4
seemly: 0.3.10
vdirs: 0.1.8(vue@3.5.35(typescript@6.0.3))
vooks: 0.2.12(vue@3.5.35(typescript@6.0.3))
vue: 3.5.35(typescript@6.0.3)
webpack-virtual-modules@0.6.2: {} webpack-virtual-modules@0.6.2: {}
which-module@2.0.1: {}
which@2.0.2: which@2.0.2:
dependencies: dependencies:
isexe: 2.0.0 isexe: 2.0.0
@@ -3318,11 +3502,38 @@ snapshots:
dependencies: dependencies:
isexe: 3.1.5 isexe: 3.1.5
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wsl-utils@0.3.1: wsl-utils@0.3.1:
dependencies: dependencies:
is-wsl: 3.1.1 is-wsl: 3.1.1
powershell-utils: 0.1.0 powershell-utils: 0.1.0
y18n@4.0.3: {}
yallist@3.1.1: {} yallist@3.1.1: {}
yaml@2.9.0: {} yaml@2.9.0: {}
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs@15.4.1:
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3

View File

@@ -1,35 +1,11 @@
<template> <template>
<NConfigProvider <ElConfigProvider :locale="zhCn">
:locale="zhCN"
:date-locale="dateZhCN"
:theme="lightTheme"
:theme-overrides="themeOverrides"
class="app-wrapper"
>
<NNotificationProvider>
<NMessageProvider>
<router-view /> <router-view />
</NMessageProvider> </ElConfigProvider>
</NNotificationProvider>
</NConfigProvider>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { RouterView } from 'vue-router' import { RouterView } from 'vue-router'
import { zhCN, dateZhCN, lightTheme, useThemeVars, type GlobalThemeOverrides } from 'naive-ui' import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
const themeOverrides: GlobalThemeOverrides = {
common: {
primaryColor: '#2080F0',
primaryColorHover: '#4098fc',
primaryColorPressed: '#1060c9',
primaryColorSuppl: '#4098fc'
}
}
</script> </script>
<style scoped>
.app-wrapper {
height: 100%;
}
</style>

View File

@@ -1,10 +1,7 @@
import { createDiscreteApi } from 'naive-ui' import { ElMessage } from 'element-plus'
import { eventBus, AppEvents } from '@/utils' import { eventBus, AppEvents } from '@/utils'
import type { RequestErrorEvent } from './types' import type { RequestErrorEvent } from './types'
/** 离散式 API可在组件外使用 */
const { message } = createDiscreteApi(['message'])
/** /**
* 注册请求错误 UI 展示 * 注册请求错误 UI 展示
* *
@@ -13,5 +10,5 @@ const { message } = createDiscreteApi(['message'])
*/ */
eventBus.on(AppEvents.REQUEST_ERROR, (payload: unknown) => { eventBus.on(AppEvents.REQUEST_ERROR, (payload: unknown) => {
const { message: errorMessage } = payload as RequestErrorEvent const { message: errorMessage } = payload as RequestErrorEvent
message.error(errorMessage) ElMessage.error(errorMessage)
}) })

View File

@@ -1,12 +1,12 @@
<template> <template>
<div class="user-bar"> <div class="user-bar">
<div class="container"> <div class="container">
<n-popover trigger="click"> <el-popover trigger="click" :width="260">
<template #trigger> <template #reference>
<div class="user-info"> <div class="user-info">
<n-badge dot :offset="[-7, 29]" color="#008000"> <el-badge is-dot :offset="[-7, 29]" class="user-badge">
<n-avatar round src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg" /> <el-avatar shape="circle" src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg" />
</n-badge> </el-badge>
<div class="user-name"> <div class="user-name">
<div class="user-title">MarchGlow</div> <div class="user-title">MarchGlow</div>
<div class="user-state">在线</div> <div class="user-state">在线</div>
@@ -14,17 +14,17 @@
</div> </div>
</template> </template>
<span>I wish they all could be California girls</span> <span>I wish they all could be California girls</span>
</n-popover> </el-popover>
<div class="feature"> <div class="feature">
<n-icon color="#fff" :size="26"><SettingsSharp /></n-icon> <el-icon color="#fff" :size="26"><Setting /></el-icon>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { SettingsSharp } from '@vicons/ionicons5' import { Setting } from '@element-plus/icons-vue'
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@@ -36,11 +36,15 @@ import { SettingsSharp } from '@vicons/ionicons5'
align-items: center; align-items: center;
} }
:deep(.n-badge .n-badge-sup) { .user-badge :deep(.el-badge__content) {
width: 12px; width: 12px;
height: 12px; height: 12px;
} }
.user-badge :deep(.el-badge__content.is-dot) {
background-color: #008000;
}
.container { .container {
display: flex; display: flex;
flex: 1; flex: 1;

View File

@@ -6,27 +6,22 @@
<RouterView v-slot="{ Component, route }"> <RouterView v-slot="{ Component, route }">
<Transition appear mode="out-in" name="slide-right"> <Transition appear mode="out-in" name="slide-right">
<KeepAlive :include="['Login']"> <KeepAlive :include="['Login']">
<component <component :is="Component" :key="route.fullPath" class="auth-layout__content" />
:is="Component"
:key="route.fullPath"
class="auth-layout__content"
/>
</KeepAlive> </KeepAlive>
</Transition> </Transition>
</RouterView> </RouterView>
<div class="auth-layout__footer"> <div class="auth-layout__footer">
<span style="color: #71717a">Copyright © 2024</span> <span style="color: #71717a">Copyright © 2024</span>
<a href="javascript:void(0)" class="auth-layout__footer-link" style="color: #2080f0">MarchGlow</a> <a href="javascript:void(0)" class="auth-layout__footer-link" style="color: #2080f0"
>MarchGlow</a
>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts"></script>
import { useThemeVars } from 'naive-ui'
const themeVars = useThemeVars()
</script>
<style scoped> <style scoped>
.auth-layout { .auth-layout {
@@ -54,7 +49,7 @@ const themeVars = useThemeVars()
background: linear-gradient( background: linear-gradient(
154deg, 154deg,
#07070915 30%, #07070915 30%,
color-mix(in srgb, v-bind(themeVars.primaryColor) 30%, transparent) 48%, color-mix(in srgb, var(--el-color-primary) 30%, transparent) 48%,
#07070915 64% #07070915 64%
); );
filter: blur(100px); filter: blur(100px);
@@ -94,7 +89,6 @@ const themeVars = useThemeVars()
} }
.auth-layout__content { .auth-layout__content {
margin-top: 24px;
width: 100%; width: 100%;
} }

View File

@@ -1,4 +1,5 @@
import './assets/style' import './assets/style'
import 'element-plus/dist/index.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import { initPinia } from './stores' import { initPinia } from './stores'

View File

@@ -6,56 +6,66 @@
<span style="color: #71717a">登录账号以进入对战</span> <span style="color: #71717a">登录账号以进入对战</span>
</p> </p>
</div> </div>
<n-form <el-form
ref="formRef" ref="formRef"
:model="loginModel" :model="loginModel"
:rules="rules" :rules="rules"
:show-label="false" hide-required-asterisk
class="login-wrapper__form" class="login-wrapper__form"
> >
<n-form-item path="username"> <el-form-item prop="username">
<n-input v-model:value="loginModel.username" placeholder="请输入账号" :maxlength="20" /> <el-input
</n-form-item> size="large"
<n-form-item path="password"> v-model="loginModel.username"
<n-input placeholder="请输入账号"
v-model:value="loginModel.password" :maxlength="20"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginModel.password"
size="large"
type="password" type="password"
show-password-on="click" show-password
placeholder="密码" placeholder="密码"
:maxlength="20" :maxlength="20"
/> />
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<div class="login-wrapper__actions"> <div class="login-wrapper__actions">
<n-checkbox v-model:checked="rememberAccount">记住账号</n-checkbox> <el-checkbox v-model="rememberAccount">记住账号</el-checkbox>
<a href="javascript:void(0)" style="color: #2080f0">忘记密码</a> <a href="javascript:void(0)" style="color: #2080f0">忘记密码</a>
</div> </div>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<n-button :loading="loading" style="width: 100%" type="primary" @click="userLoginFun" <el-button :loading="loading" style="width: 100%" type="primary" @click="userLoginFun"
>登录 >登录
</n-button> </el-button>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<div class="login-wrapper__quick-btns"> <div class="login-wrapper__quick-btns">
<n-button class="login-wrapper__quick-btn" @click="router.push('/auth/phone-login')"> 手机登录 </n-button> <el-button class="login-wrapper__quick-btn" @click="router.push('/auth/phone-login')">
<n-button class="login-wrapper__quick-btn" @click="router.push('/auth/qrcode-login')"> 扫码登录 </n-button> 手机登录
</el-button>
<el-button class="login-wrapper__quick-btn" @click="router.push('/auth/qrcode-login')">
扫码登录
</el-button>
</div> </div>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<div class="login-wrapper__register-link"> <div class="login-wrapper__register-link">
<span>没有账号</span> <span>没有账号</span>
<router-link to="/auth/register" style="color: #2080f0">创建账号</router-link> <router-link to="/auth/register" style="color: #2080f0">创建账号</router-link>
</div> </div>
</n-form-item> </el-form-item>
</n-form> </el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, useTemplateRef, onMounted } from 'vue' import { reactive, ref, useTemplateRef, onMounted } from 'vue'
import type { FormItemRule, FormRules, FormInst } from 'naive-ui' import type { FormRules, FormInstance } from 'element-plus'
import { useMessage } from 'naive-ui' import { ElMessage } from 'element-plus'
import { useAccountStore } from '@/stores' import { useAccountStore } from '@/stores'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
@@ -65,8 +75,7 @@ const REMEMBER_KEY = 'login_remembered_username'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const accountStore = useAccountStore() const accountStore = useAccountStore()
const message = useMessage() const formRef = useTemplateRef<FormInstance>('formRef')
const formRef = useTemplateRef<FormInst>('formRef')
const loginModel = reactive({ const loginModel = reactive({
username: '', username: '',
password: '' password: ''
@@ -84,43 +93,39 @@ onMounted(() => {
} }
}) })
const rules: FormRules = { /** 账号验证规则 */
username: [ const validateUsername = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
{
required: true,
trigger: ['blur'],
validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入登陆账号') callback(new Error('请输入登陆账号'))
} else if (value.length < 2) { } else if (value.length < 2) {
return new Error('账号长度不能小于2位') callback(new Error('账号长度不能小于2位'))
} else if (value.length > 20) { } else if (value.length > 20) {
return new Error('账号长度不能大于20位') callback(new Error('账号长度不能大于20位'))
} else if (!/^[A-Za-z][A-Za-z0-9]*$/.test(value)) { } else if (!/^[A-Za-z][A-Za-z0-9]*$/.test(value)) {
return new Error('账号以字母开头,只能包含字母和数字') callback(new Error('账号以字母开头,只能包含字母和数字'))
} else {
callback()
} }
return true }
}
} /** 密码验证规则 */
], const validatePassword = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
password: [
{
required: true,
trigger: ['blur'],
validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入密码') callback(new Error('请输入密码'))
} else if (value.length < 8) { } else if (value.length < 8) {
return new Error('密码长度不能小于8位') callback(new Error('密码长度不能小于8位'))
} else if (value.length > 20) { } else if (value.length > 20) {
return new Error('密码长度不能大于20位') callback(new Error('密码长度不能大于20位'))
} else if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(value)) { } else if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(value)) {
return new Error('密码必须包含大小写字母和数字') callback(new Error('密码必须包含大小写字母和数字'))
} else {
callback()
} }
return true }
}
} const rules: FormRules = {
] username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePassword }]
} }
/** /**
@@ -147,16 +152,16 @@ function getErrorMessage(error: unknown): string {
/** 用户登录 */ /** 用户登录 */
const userLoginFun = () => { const userLoginFun = () => {
formRef.value?.validate(async (errors) => { formRef.value?.validate((valid: boolean) => {
if (errors) return if (!valid) return
loading.value = true loading.value = true
try { accountStore
await accountStore.login({ .login({
username: loginModel.username, username: loginModel.username,
password: loginModel.password password: loginModel.password
}) })
.then(() => {
// 记住账号:将用户名存入 localStorage // 记住账号:将用户名存入 localStorage
if (rememberAccount.value) { if (rememberAccount.value) {
localStorage.setItem(REMEMBER_KEY, loginModel.username) localStorage.setItem(REMEMBER_KEY, loginModel.username)
@@ -164,15 +169,17 @@ const userLoginFun = () => {
localStorage.removeItem(REMEMBER_KEY) localStorage.removeItem(REMEMBER_KEY)
} }
message.success('登录成功') ElMessage.success('登录成功')
// 跳转到目标页面(有 redirect 参数则优先跳回原页面,否则去首页) // 跳转到目标页面(有 redirect 参数则优先跳回原页面,否则去首页)
const redirectPath = (route.query.redirect as string) || '/' const redirectPath = (route.query.redirect as string) || '/'
router.push(redirectPath) router.push(redirectPath)
} catch (error: unknown) { })
message.error(getErrorMessage(error)) .catch((error: unknown) => {
} finally { ElMessage.error(getErrorMessage(error))
})
.finally(() => {
loading.value = false loading.value = false
} })
}) })
} }
</script> </script>
@@ -204,7 +211,7 @@ const userLoginFun = () => {
.login-wrapper__form { .login-wrapper__form {
width: 100%; width: 100%;
margin-top: 40px; margin-top: 20px;
} }
.login-wrapper__actions { .login-wrapper__actions {

View File

@@ -6,112 +6,106 @@
<span style="color: #71717a">请输入手机号码登录账号以进入对战</span> <span style="color: #71717a">请输入手机号码登录账号以进入对战</span>
</p> </p>
</div> </div>
<n-form <el-form
ref="formRef" ref="formRef"
:model="loginModel" :model="loginModel"
:rules="rules" :rules="rules"
:show-label="false" hide-required-asterisk
class="phone-login-wrapper__form" class="phone-login-wrapper__form"
> >
<n-form-item path="phoneNumber"> <el-form-item prop="phoneNumber">
<n-input v-model:value="loginModel.phoneNumber" placeholder="手机号码" :maxlength="20" /> <el-input
</n-form-item> size="large"
<n-form-item path="code"> v-model="loginModel.phoneNumber"
<div class="phone-login-wrapper__code-row"> placeholder="手机号码"
<n-input-otp :maxlength="11"
block
v-model:value="loginModel.code"
:allow-input="onlyAllowNumber"
style="gap: 0; flex: 2"
/> />
<n-button style="flex: 1" @click="getPhoneCodeFun">获取验证码</n-button> </el-form-item>
<el-form-item prop="code">
<div class="phone-login-wrapper__code-row">
<el-input-otp
v-model="loginModel.code"
:length="6"
:formatter="onlyAllowNumber"
style="flex: 2; --el-input-otp-gap: 0"
>
<template #separator></template>
</el-input-otp>
<el-button style="flex: 1" @click="getPhoneCodeFun">获取验证码</el-button>
</div> </div>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<n-button :loading="loading" style="width: 100%" type="primary" @click="phoneLoginFun" <el-button :loading="loading" style="width: 100%" type="primary" @click="phoneLoginFun"
>登录 >登录
</n-button> </el-button>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<div class="phone-login-wrapper__back-row"> <div class="phone-login-wrapper__back-row">
<n-button class="phone-login-wrapper__back-btn" @click="router.push('/auth/login')"> 返回 </n-button> <el-button class="phone-login-wrapper__back-btn" @click="router.push('/auth/login')">
返回
</el-button>
</div> </div>
</n-form-item> </el-form-item>
</n-form> </el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, useTemplateRef } from 'vue' import { reactive, ref, useTemplateRef } from 'vue'
import type { FormItemRule, FormRules, FormInst } from 'naive-ui' import type { FormRules, FormInstance } from 'element-plus'
import { useAccountStore } from '@/stores' import { useAccountStore } from '@/stores'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
const accountStore = useAccountStore() const accountStore = useAccountStore()
const formRef = useTemplateRef<FormInst>('formRef') const formRef = useTemplateRef<FormInstance>('formRef')
const loginModel = reactive({ const loginModel = reactive({
phoneNumber: '', phoneNumber: '',
code: [] code: ''
}) })
const loading = ref(false) const loading = ref(false)
const onlyAllowNumber = (value: string) => !value || /^\d+$/.test(value) /** 仅允许输入数字字符 */
const rules: FormRules = { const onlyAllowNumber = (value: string) => value.replace(/\D/g, '')
phoneNumber: [
{ /** 手机号验证规则 */
key: 'phoneNumber', const validatePhoneNumber = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
required: true,
trigger: ['blur'],
validator: (rule: FormItemRule, value: string) => {
if (!/^1[3-9]\d{9}$/.test(value)) { if (!/^1[3-9]\d{9}$/.test(value)) {
return new Error('请输入手机号码') callback(new Error('请输入正确的手机号码'))
} else {
callback()
} }
return true }
/** 验证码验证规则 */
const validateCode = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
if (!value || value.length !== 6) {
callback(new Error('请输入6位验证码'))
} else {
callback()
} }
} }
],
code: [ const rules: FormRules = {
{ phoneNumber: [{ required: true, trigger: 'blur', validator: validatePhoneNumber }],
key: 'code', code: [{ required: true, trigger: 'blur', validator: validateCode }]
required: true,
trigger: ['blur'],
validator: (_, value: string[] | null) => {
if (value === null) {
return new Error('请输入验证码')
}
if (value.filter(Boolean).length !== 6) {
return new Error('请输入验证码')
}
return true
}
}
]
} }
const getPhoneCodeFun = () => { const getPhoneCodeFun = () => {
formRef.value?.validate( formRef.value?.validateField('phoneNumber', (valid: boolean) => {
(errors) => { if (valid) {
if (!errors) {
console.log('获取验证码成功') console.log('获取验证码成功')
// TODO 获取验证码方法 // TODO 获取验证码方法
} }
}, })
(rule) => {
if (rule.key === 'phoneNumber') {
return true
}
return false
}
)
} }
const phoneLoginFun = () => { const phoneLoginFun = () => {
formRef.value?.validate((errors) => { formRef.value?.validate((valid: boolean) => {
if (!errors) { if (valid) {
loading.value = true loading.value = true
console.log('登录成功') console.log('登录成功')
// TODO 登录方法 // TODO 登录方法
accountStore.token = '123456' accountStore.accessToken = '123456'
setTimeout(() => { setTimeout(() => {
loading.value = false loading.value = false
}, 1000) }, 1000)
@@ -147,7 +141,7 @@ const phoneLoginFun = () => {
.phone-login-wrapper__form { .phone-login-wrapper__form {
width: 100%; width: 100%;
margin-top: 40px; margin-top: 20px;
} }
.phone-login-wrapper__code-row { .phone-login-wrapper__code-row {

View File

@@ -6,30 +6,42 @@
<span style="color: #71717a">请用手机扫描二维码登录</span> <span style="color: #71717a">请用手机扫描二维码登录</span>
</p> </p>
</div> </div>
<n-form :show-label="false" class="qrcode-login-wrapper__form"> <el-form hide-required-asterisk class="qrcode-login-wrapper__form">
<n-form-item> <el-form-item>
<n-space vertical style="align-items: center; flex: 1"> <div class="qrcode-login-wrapper__qrcode-area">
<n-qr-code v-model:value="qrcode" :size="180" /> <canvas ref="qrcodeCanvas" width="180" height="180"></canvas>
<p>扫码后点击 '确认'即可完成登录</p> <p>扫码后点击 '确认'即可完成登录</p>
</n-space>
</n-form-item>
<n-form-item>
<div class="qrcode-login-wrapper__back-row">
<n-button class="qrcode-login-wrapper__back-btn" @click="router.push('/auth/login')"> 返回 </n-button>
</div> </div>
</n-form-item> </el-form-item>
</n-form> <el-form-item>
<div class="qrcode-login-wrapper__back-row">
<el-button class="qrcode-login-wrapper__back-btn" @click="router.push('/auth/login')">
返回
</el-button>
</div>
</el-form-item>
</el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref, useTemplateRef, onMounted } from 'vue'
import { useAccountStore } from '@/stores' import QRCode from 'qrcode'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
const accountStore = useAccountStore() const qrcodeCanvas = useTemplateRef<HTMLCanvasElement>('qrcodeCanvas')
const qrcode = ref('') /** 二维码内容TODO: 替换为实际登录凭证) */
const qrcodeValue = ref('https://example.com/login-qrcode')
onMounted(async () => {
if (qrcodeCanvas.value) {
await QRCode.toCanvas(qrcodeCanvas.value, qrcodeValue.value, {
width: 180,
margin: 2
})
}
})
</script> </script>
<style scoped> <style scoped>
@@ -59,7 +71,14 @@ const qrcode = ref('')
.qrcode-login-wrapper__form { .qrcode-login-wrapper__form {
width: 100%; width: 100%;
margin-top: 40px; margin-top: 20px;
}
.qrcode-login-wrapper__qrcode-area {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
} }
.qrcode-login-wrapper__back-row { .qrcode-login-wrapper__back-row {

View File

@@ -6,31 +6,33 @@
<span style="color: #71717a">创建账号进入对战</span> <span style="color: #71717a">创建账号进入对战</span>
</p> </p>
</div> </div>
<n-form <el-form
ref="formRef" ref="formRef"
:model="registerModel" :model="registerModel"
:rules="rules" :rules="rules"
:show-label="false" hide-required-asterisk
class="register-wrapper__form" class="register-wrapper__form"
> >
<n-form-item path="username"> <el-form-item prop="username">
<n-input v-model:value="registerModel.username" placeholder="请输入账号" :maxlength="20" /> <el-input
</n-form-item> size="large"
<n-form-item path="password"> v-model="registerModel.username"
placeholder="请输入账号"
:maxlength="20"
/>
</el-form-item>
<el-form-item prop="password">
<div class="register-wrapper__password-group"> <div class="register-wrapper__password-group">
<n-input <el-input
v-model:value="registerModel.password" v-model="registerModel.password"
size="large"
type="password" type="password"
show-password-on="click" show-password
placeholder="密码" placeholder="密码"
:maxlength="20" :maxlength="20"
/> />
<div class="register-wrapper__strength-bars"> <div class="register-wrapper__strength-bars">
<div <div v-for="level in 5" :key="level" class="register-wrapper__strength-bar-track">
v-for="level in 5"
:key="level"
class="register-wrapper__strength-bar-track"
>
<div <div
class="register-wrapper__strength-bar-fill" class="register-wrapper__strength-bar-fill"
:style="{ width: securityLevel >= level ? '100%' : '0' }" :style="{ width: securityLevel >= level ? '100%' : '0' }"
@@ -41,47 +43,48 @@
使用 8 个或更多字符混合大小写字母数字 使用 8 个或更多字符混合大小写字母数字
</p> </p>
</div> </div>
</n-form-item> </el-form-item>
<n-form-item path="confirmPassword"> <el-form-item prop="confirmPassword">
<n-input <el-input
v-model:value="registerModel.confirmPassword" v-model="registerModel.confirmPassword"
size="large"
type="password" type="password"
show-password-on="click" show-password
placeholder="确认密码" placeholder="确认密码"
:maxlength="20" :maxlength="20"
/> />
</n-form-item> </el-form-item>
<n-form-item path="agreement"> <el-form-item prop="agreement">
<div class="register-wrapper__agreement"> <div class="register-wrapper__agreement">
<n-checkbox v-model:checked="registerModel.agreement">我同意</n-checkbox> <el-checkbox v-model="registerModel.agreement">我同意</el-checkbox>
<a href="javascript:void(0)" style="color: #2080f0">隐私政策 & 条款</a> <a href="javascript:void(0)" style="color: #2080f0">隐私政策 & 条款</a>
</div> </div>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<n-button :loading="loading" style="width: 100%" type="primary" @click="userRegisterFun" <el-button :loading="loading" style="width: 100%" type="primary" @click="userRegisterFun"
>注册 >注册
</n-button> </el-button>
</n-form-item> </el-form-item>
<n-form-item> <el-form-item>
<div class="register-wrapper__login-link"> <div class="register-wrapper__login-link">
<span>已经有账号了</span> <span>已经有账号了</span>
<router-link to="/auth/login" style="color: #2080f0">去登录</router-link> <router-link to="/auth/login" style="color: #2080f0">去登录</router-link>
</div> </div>
</n-form-item> </el-form-item>
</n-form> </el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, useTemplateRef, watch } from 'vue' import { reactive, ref, useTemplateRef, watch } from 'vue'
import { type FormInst, type FormItemRule, type FormRules, useMessage } from 'naive-ui' import type { FormRules, FormInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import { useAccountStore } from '@/stores' import { useAccountStore } from '@/stores'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
const accountStore = useAccountStore() const accountStore = useAccountStore()
const message = useMessage() const formRef = useTemplateRef<FormInstance>('formRef')
const formRef = useTemplateRef<FormInst>('formRef')
const registerModel = reactive({ const registerModel = reactive({
username: '', username: '',
password: '', password: '',
@@ -116,70 +119,65 @@ const checkPasswordStrength = (password: string) => {
securityLevel.value = strength securityLevel.value = strength
} }
const rules: FormRules = { /** 账号验证规则 */
username: [ const validateUsername = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
{
required: true,
trigger: ['blur'],
validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入登陆账号') callback(new Error('请输入登陆账号'))
} else if (value.length < 2) { } else if (value.length < 2) {
return new Error('账号长度不能小于2位') callback(new Error('账号长度不能小于2位'))
} else if (value.length > 20) { } else if (value.length > 20) {
return new Error('账号长度不能大于20位') callback(new Error('账号长度不能大于20位'))
} else if (!/^[A-Za-z][A-Za-z0-9]*$/.test(value)) { } else if (!/^[A-Za-z][A-Za-z0-9]*$/.test(value)) {
return new Error('账号以字母开头,只能包含字母和数字') callback(new Error('账号以字母开头,只能包含字母和数字'))
} else {
callback()
} }
return true }
}
} /** 密码验证规则 */
], const validatePassword = (_rule: unknown, value: string, callback: (error?: Error) => void) => {
password: [
{
required: true,
trigger: ['blur'],
validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请输入密码') callback(new Error('请输入密码'))
} else if (value.length < 8) { } else if (value.length < 8) {
return new Error('密码长度不能小于8位') callback(new Error('密码长度不能小于8位'))
} else if (value.length > 20) { } else if (value.length > 20) {
return new Error('密码长度不能大于20位') callback(new Error('密码长度不能大于20位'))
} else if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(value)) { } else if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/.test(value)) {
return new Error('密码必须包含大小写字母和数字') callback(new Error('密码必须包含大小写字母和数字'))
} else {
callback()
} }
return true }
}
} /** 确认密码验证规则 */
], const validateConfirmPassword = (
confirmPassword: [ _rule: unknown,
{ value: string,
required: true, callback: (error?: Error) => void
trigger: ['blur'], ) => {
validator: (_rule: FormItemRule, value: string) => {
if (!value) { if (!value) {
return new Error('请再次输入密码') callback(new Error('请再次输入密码'))
} else if (registerModel.password !== value) {
callback(new Error('密码不一致'))
} else {
callback()
} }
if (registerModel.password !== value) { }
return new Error('密码不一致')
} /** 协议同意验证规则 */
return true const validateAgreement = (_rule: unknown, value: boolean, callback: (error?: Error) => void) => {
}
}
],
agreement: [
{
required: true,
trigger: 'change',
validator: (_rule: FormItemRule, value: boolean) => {
if (!value) { if (!value) {
return new Error('请勾选同意协议') callback(new Error('请勾选同意协议'))
} else {
callback()
} }
return true }
}
} const rules: FormRules = {
] username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePassword }],
confirmPassword: [{ required: true, trigger: 'blur', validator: validateConfirmPassword }],
agreement: [{ required: true, trigger: 'change', validator: validateAgreement }]
} }
/** /**
@@ -205,24 +203,26 @@ function getErrorMessage(error: unknown): string {
/** 用户注册 */ /** 用户注册 */
const userRegisterFun = () => { const userRegisterFun = () => {
formRef.value?.validate(async (errors) => { formRef.value?.validate((valid: boolean) => {
if (errors) return if (!valid) return
loading.value = true loading.value = true
try { accountStore
await accountStore.register({ .register({
username: registerModel.username, username: registerModel.username,
password: registerModel.password password: registerModel.password
}) })
.then(() => {
message.success('注册成功') ElMessage.success('注册成功')
// 注册成功后跳转首页 // 注册成功后跳转首页
router.push('/') router.push('/')
} catch (error: unknown) { })
message.error(getErrorMessage(error)) .catch((error: unknown) => {
} finally { ElMessage.error(getErrorMessage(error))
})
.finally(() => {
loading.value = false loading.value = false
} })
}) })
} }
</script> </script>
@@ -254,7 +254,7 @@ const userRegisterFun = () => {
.register-wrapper__form { .register-wrapper__form {
width: 100%; width: 100%;
margin-top: 40px; margin-top: 20px;
} }
.register-wrapper__password-group { .register-wrapper__password-group {
@@ -291,6 +291,8 @@ const userRegisterFun = () => {
.register-wrapper__password-hint { .register-wrapper__password-hint {
font-size: 12px; font-size: 12px;
margin-top: 8px; margin-top: 8px;
margin-bottom: 0;
line-height: normal;
} }
.register-wrapper__agreement { .register-wrapper__agreement {

View File

@@ -6,7 +6,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools' import vueDevTools from 'vite-plugin-vue-devtools'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Components from 'unplugin-vue-components/vite' import Components from 'unplugin-vue-components/vite'
// https://vite.dev/config/ // https://vite.dev/config/
@@ -16,10 +16,10 @@ export default defineConfig({
vueJsx(), vueJsx(),
vueDevTools(), vueDevTools(),
AutoImport({ AutoImport({
imports: [{ 'native-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar'] }] resolvers: [ElementPlusResolver()]
}), }),
Components({ Components({
resolvers: [NaiveUiResolver()] resolvers: [ElementPlusResolver()]
}) })
], ],
resolve: { resolve: {