接口调试
This commit is contained in:
parent
11c05de565
commit
de6dfb5e20
@ -18,6 +18,21 @@ export default defineConfigWithVueTs(
|
||||
|
||||
...pluginVue.configs['flat/essential'],
|
||||
vueTsConfigs.recommended,
|
||||
{
|
||||
rules: {
|
||||
// 1. 强制 Vue 文件内标签块的顺序
|
||||
'vue/block-order': [
|
||||
'error',
|
||||
{
|
||||
order: ['template', 'script', 'style'],
|
||||
},
|
||||
],
|
||||
// 2. 自动关闭单单词组件名检查(根据需要可选)
|
||||
'vue/multi-word-component-names': 'off',
|
||||
// 3. 可以在这里添加更多 TypeScript 或 Vue 的自定义校验
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
},
|
||||
},
|
||||
|
||||
skipFormatting,
|
||||
)
|
||||
|
||||
@ -7,10 +7,10 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"dev": "vite --mode dev",
|
||||
"build:test": "vite build --mode test",
|
||||
"build:prod": "vite build --mode pord",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build",
|
||||
"lint": "eslint . --fix --cache",
|
||||
"format": "prettier --write --experimental-cli src/"
|
||||
@ -18,8 +18,10 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"@vueuse/core": "^14.1.0",
|
||||
"axios": "^1.13.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"lucide-vue-next": "^0.562.0",
|
||||
"reka-ui": "^2.7.0",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
|
||||
198
pnpm-lock.yaml
generated
198
pnpm-lock.yaml
generated
@ -14,12 +14,18 @@ importers:
|
||||
'@vueuse/core':
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0(vue@3.5.26(typescript@5.9.3))
|
||||
axios:
|
||||
specifier: ^1.13.2
|
||||
version: 1.13.2
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
crypto-js:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
lucide-vue-next:
|
||||
specifier: ^0.562.0
|
||||
version: 0.562.0(vue@3.5.26(typescript@5.9.3))
|
||||
@ -957,6 +963,12 @@ packages:
|
||||
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.13.2:
|
||||
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
@ -989,6 +1001,10 @@ packages:
|
||||
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1014,6 +1030,10 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
commander@7.2.0:
|
||||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||
engines: {node: '>= 10'}
|
||||
@ -1032,6 +1052,9 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
|
||||
css-select@5.2.2:
|
||||
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
|
||||
|
||||
@ -1086,6 +1109,10 @@ packages:
|
||||
defu@6.1.4:
|
||||
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1103,6 +1130,10 @@ packages:
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
electron-to-chromium@1.5.267:
|
||||
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
|
||||
|
||||
@ -1121,6 +1152,22 @@ packages:
|
||||
error-stack-parser-es@1.0.5:
|
||||
resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
esbuild@0.27.2:
|
||||
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
|
||||
engines: {node: '>=18'}
|
||||
@ -1260,15 +1307,39 @@ packages:
|
||||
flatted@3.3.3:
|
||||
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
||||
|
||||
follow-redirects@1.15.11:
|
||||
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
form-data@4.0.5:
|
||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -1281,6 +1352,10 @@ packages:
|
||||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
@ -1288,6 +1363,18 @@ packages:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
@ -1476,6 +1563,10 @@ packages:
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
mdn-data@2.0.28:
|
||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||
|
||||
@ -1494,6 +1585,14 @@ packages:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
@ -1674,6 +1773,9 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
@ -2862,6 +2964,16 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.13.2:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11
|
||||
form-data: 4.0.5
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
baseline-browser-mapping@2.9.11: {}
|
||||
@ -2895,6 +3007,11 @@ snapshots:
|
||||
dependencies:
|
||||
run-applescript: 7.1.0
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
callsites@3.1.0: {}
|
||||
|
||||
caniuse-lite@1.0.30001761: {}
|
||||
@ -2916,6 +3033,10 @@ snapshots:
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@7.2.0: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@ -2932,6 +3053,8 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
crypto-js@4.2.0: {}
|
||||
|
||||
css-select@5.2.2:
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
@ -2977,6 +3100,8 @@ snapshots:
|
||||
|
||||
defu@6.1.4: {}
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
@ -2997,6 +3122,12 @@ snapshots:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
electron-to-chromium@1.5.267: {}
|
||||
|
||||
enhanced-resolve@5.18.4:
|
||||
@ -3010,6 +3141,21 @@ snapshots:
|
||||
|
||||
error-stack-parser-es@1.0.5: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
esbuild@0.27.2:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.27.2
|
||||
@ -3183,11 +3329,41 @@ snapshots:
|
||||
|
||||
flatted@3.3.3: {}
|
||||
|
||||
follow-redirects@1.15.11: {}
|
||||
|
||||
form-data@4.0.5:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
function-bind: 1.1.2
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
glob-parent@5.1.2:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
@ -3198,10 +3374,22 @@ snapshots:
|
||||
|
||||
globals@14.0.0: {}
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
ignore@5.3.2: {}
|
||||
@ -3337,6 +3525,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
mdn-data@2.0.28: {}
|
||||
|
||||
mdn-data@2.0.30: {}
|
||||
@ -3350,6 +3540,12 @@ snapshots:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
@ -3462,6 +3658,8 @@ snapshots:
|
||||
|
||||
prettier@3.7.4: {}
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
@ -7,7 +7,7 @@ import ArrowIcon from './arrow-icon2.svg?component'
|
||||
const faqList = ref([
|
||||
{
|
||||
id: 1,
|
||||
question: '登陆公共 Apple ID 时,出现“双重验证”提示,且要求输入验证码怎么办?',
|
||||
question: '登录公共 Apple ID 时,出现“双重验证”提示,且要求输入验证码怎么办?',
|
||||
answer:
|
||||
'这是由于有其他用户没有按照教程操作,将公共 Apple ID 绑定手机号码,开启了双重验证所导致。\n\n解决办法:请您先清除浏览器缓存,再刷新本页面,获取新的公共 Apple ID,接着请按照教程一步一步操作。',
|
||||
},
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
</div>
|
||||
<div v-show="activeIndex === 1">
|
||||
<div class="pt-[34px] pb-[15px] text-center font-[900]">
|
||||
登陆海外 Apple ID 后再点击下方下载按钮
|
||||
登录海外 Apple ID 后再点击下方下载按钮
|
||||
</div>
|
||||
</div>
|
||||
<!-- tab2 -->
|
||||
|
||||
62
src/pages/Home/components/CodeSentTip.vue
Normal file
62
src/pages/Home/components/CodeSentTip.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
<div
|
||||
v-if="visible"
|
||||
class="!pointer-events-auto fixed inset-0 z-[100] flex items-center justify-center p-4"
|
||||
>
|
||||
<div
|
||||
class="backdrop-blur-[2px z-[110]] absolute inset-0 bg-black/40"
|
||||
@click.stop="hide"
|
||||
></div>
|
||||
|
||||
<div
|
||||
class="relative z-10 w-full max-w-[280px] rounded-[40px] border border-white/10 bg-[#999999] p-8 shadow-2xl"
|
||||
@click.stop
|
||||
>
|
||||
<div class="space-y-2 text-black">
|
||||
<h3 class="flex items-start text-lg font-black"><span class="mr-1">*</span>重要提示</h3>
|
||||
<p class="text-[15px] leading-relaxed font-bold tracking-tight">
|
||||
验证邮件已发送至邮箱,如无法找到,请检查垃圾邮件箱或营销邮件箱。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onBeforeUnmount } from 'vue'
|
||||
|
||||
const visible = ref(false)
|
||||
const timer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const show = () => {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
const hide = () => {
|
||||
console.log('hide')
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
// 组件卸载前清除计时器防止内存泄漏
|
||||
onBeforeUnmount(() => {
|
||||
if (timer) clearTimeout(timer)
|
||||
})
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
</style>
|
||||
@ -1,31 +1,3 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { toast } from 'vue-sonner'
|
||||
|
||||
const email = ref('')
|
||||
const code = ref('')
|
||||
const countdown = ref(0)
|
||||
|
||||
const handleGetCode = () => {
|
||||
if (!email.value) {
|
||||
toast('请输入邮箱')
|
||||
return
|
||||
}
|
||||
// 模拟倒计时逻辑
|
||||
countdown.value = 60
|
||||
const timer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) clearInterval(timer)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const handleLogin = () => {
|
||||
console.log('登录提交', { email: email.value, code: code.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-6 text-black">
|
||||
<div class="overflow-hidden rounded-[20px] bg-[#78788029] px-4">
|
||||
@ -62,6 +34,7 @@ const handleLogin = () => {
|
||||
<div class="flex gap-4 pt-2">
|
||||
<Button
|
||||
variant="secondary"
|
||||
@click="emit('close')"
|
||||
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#D1D1D1] text-lg font-medium text-[#757575] hover:bg-[#C1C1C1]"
|
||||
>
|
||||
取消
|
||||
@ -70,12 +43,44 @@ const handleLogin = () => {
|
||||
@click="handleLogin"
|
||||
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#A8FF53] text-lg font-medium text-black hover:bg-[#96E64A]"
|
||||
>
|
||||
登陆/注册
|
||||
登录/注册
|
||||
</Button>
|
||||
</div>
|
||||
<CodeSentTip ref="CodeSentTipRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { toast } from 'vue-sonner'
|
||||
import CodeSentTip from '@/pages/Home/components/CodeSentTip.vue'
|
||||
const CodeSentTipRef = ref(null)
|
||||
const email = ref('')
|
||||
const code = ref('')
|
||||
const countdown = ref(0)
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
const handleGetCode = () => {
|
||||
if (!email.value) {
|
||||
toast('请输入邮箱')
|
||||
return
|
||||
}
|
||||
CodeSentTipRef.value.show()
|
||||
// 模拟倒计时逻辑
|
||||
countdown.value = 60
|
||||
const timer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) clearInterval(timer)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const handleLogin = () => {
|
||||
console.log('登录提交', { email: email.value, code: code.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 移除 Shadcn Input 的默认边框阴影,保持纯净感 */
|
||||
input:focus {
|
||||
|
||||
@ -7,12 +7,12 @@
|
||||
:showCloseButton="false"
|
||||
>
|
||||
<DialogHeader class="py-2 pl-2">
|
||||
<DialogTitle class="text-left">登陆Hi快帐户</DialogTitle>
|
||||
<DialogTitle class="text-left">登录Hi快帐户</DialogTitle>
|
||||
<DialogDescription class="text-left text-base text-black">
|
||||
如使用新邮箱地址,将自动为您创建Hi快帐户
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<LoginForm />
|
||||
<LoginForm @close="isOpen = false" />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
@ -28,7 +28,7 @@ import {
|
||||
} from '@/components/ui/dialog'
|
||||
import LoginForm from './LoginForm.vue'
|
||||
|
||||
const isOpen = ref(true)
|
||||
const isOpen = ref(false)
|
||||
|
||||
const setOpen = (value: boolean) => {
|
||||
isOpen.value = value
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
@click="openLoginModal"
|
||||
class="flex h-[48px] items-center rounded-full bg-[#70C877] px-6 text-sm font-bold backdrop-blur-md transition hover:bg-white/30"
|
||||
>
|
||||
登陆 / 注册
|
||||
登录 / 注册
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
@ -49,7 +49,7 @@
|
||||
<div class="md:w-1/2">
|
||||
<div class="mb-[20px] ml-[42px]">
|
||||
<h2 class="mb-2 text-5xl font-black italic md:text-7xl">
|
||||
<img :src="Logo" alt="Hi快VPN" class="h-[34px] w-auto" />
|
||||
<Logo />
|
||||
</h2>
|
||||
<p class="font-600 text-3xl md:text-4xl">网在我在, 网快我快</p>
|
||||
</div>
|
||||
|
||||
@ -1,33 +1,3 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import PlanCard from '@/components/user-center/PlanCard.vue'
|
||||
import DeviceList from '@/components/user-center/DeviceList.vue'
|
||||
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
// --- Mock Data ---
|
||||
const devices = [
|
||||
{ id: '1', name: 'XXX的 MacBook Pro 15-inch', type: 'desktop' as const, deviceId: '87654321' },
|
||||
{ id: '2', name: 'XXX的 iPhone 15 Pro Max', type: 'mobile' as const, deviceId: '12345678' },
|
||||
]
|
||||
|
||||
const plans = [
|
||||
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
|
||||
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
|
||||
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
|
||||
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
|
||||
]
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
const currentPlanIndex = ref(3)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Main Neon Green Card -->
|
||||
<div class="pt-[35px]">
|
||||
@ -67,6 +37,37 @@ const currentPlanIndex = ref(3)
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import PlanCard from '@/components/user-center/PlanCard.vue'
|
||||
import DeviceList from '@/components/user-center/DeviceList.vue'
|
||||
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import request from '@/utils/request'
|
||||
// --- Mock Data ---
|
||||
const devices = [
|
||||
{ id: '1', name: 'XXX的 MacBook Pro 15-inch', type: 'desktop' as const, deviceId: '87654321' },
|
||||
{ id: '2', name: 'XXX的 iPhone 15 Pro Max', type: 'mobile' as const, deviceId: '12345678' },
|
||||
]
|
||||
|
||||
const plans = [
|
||||
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
|
||||
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
|
||||
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
|
||||
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
|
||||
]
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
const currentPlanIndex = ref(3)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Simplified layout font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');
|
||||
|
||||
@ -1,19 +1,3 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import MobileLayout from './MobileLayout/index.vue'
|
||||
import Logo from '@/pages/Home/logo.svg?component'
|
||||
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-black text-black">
|
||||
<!-- Full Width Header -->
|
||||
@ -41,6 +25,44 @@ const handlePlanSelect = (id: string) => {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import MobileLayout from './MobileLayout/index.vue'
|
||||
import Logo from '@/pages/Home/logo.svg?component'
|
||||
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
|
||||
import request from '@/utils/request'
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
|
||||
const devices = ref([])
|
||||
function init() {
|
||||
// 设备列表
|
||||
request.get('/public/user/devices').then((res) => {
|
||||
devices.value = res.list
|
||||
})
|
||||
// 订阅详情
|
||||
request.get('/public/subscribe/list').then((res) => {
|
||||
console.log(222, res.list)
|
||||
})
|
||||
// 获取支付方式
|
||||
request.get('/public/payment/methods').then((res) => {
|
||||
console.log(33, res)
|
||||
})
|
||||
// 订阅列表
|
||||
request.get('/public/subscribe/list').then((res) => {
|
||||
console.log(44, res)
|
||||
})
|
||||
}
|
||||
init()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Simplified layout font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');
|
||||
|
||||
75
src/utils/request/HiAesUtil.ts
Normal file
75
src/utils/request/HiAesUtil.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
/**
|
||||
* HiAesUtil - AES-256-CBC 加密工具类
|
||||
* 逻辑与 Dart 版本保持 100% 同步
|
||||
*/
|
||||
export class HiAesUtil {
|
||||
/**
|
||||
* 生成 32 字节密钥 (SHA-256)
|
||||
*/
|
||||
static _generateKey(keyStr) {
|
||||
return CryptoJS.SHA256(keyStr)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 16 字节 IV
|
||||
* 逻辑: SHA-256(MD5(nonce) + keyStr) -> 取前16字节
|
||||
*/
|
||||
static _generateIv(nonce, keyStr) {
|
||||
// 1. MD5 处理 nonce
|
||||
const md5Hash = CryptoJS.MD5(nonce)
|
||||
// 2. 转为 16 进制字符串
|
||||
const md5Hex = md5Hash.toString(CryptoJS.enc.Hex)
|
||||
// 3. 拼接 md5Hex + keyStr 并做 SHA-256
|
||||
const finalHash = CryptoJS.SHA256(md5Hex + keyStr)
|
||||
|
||||
// 4. 重要:截取前 16 字节 (128位)
|
||||
// CryptoJS 的 WordArray 由 32 位整数组成,16 字节即前 4 个 words
|
||||
const iv = CryptoJS.lib.WordArray.create(finalHash.words.slice(0, 4), 16)
|
||||
return iv
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
* @param {string} plainText - 明文
|
||||
* @param {string} keyStr - 密钥
|
||||
*/
|
||||
static encryptData(plainText, keyStr) {
|
||||
// 生成 ISO8601 时间戳 (与 Dart DateTime.now().toIso8601String() 对应)
|
||||
const nonce = new Date().toISOString()
|
||||
|
||||
const key = this._generateKey(keyStr)
|
||||
const iv = this._generateIv(nonce, keyStr)
|
||||
|
||||
const encrypted = CryptoJS.AES.encrypt(plainText, key, {
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
})
|
||||
|
||||
return {
|
||||
data: encrypted.toString(), // Base64 字符串
|
||||
time: nonce,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
* @param {string} encryptedData - Base64 加密字符串
|
||||
* @param {string} nonce - 时间戳
|
||||
* @param {string} keyStr - 密钥
|
||||
*/
|
||||
static decryptData(encryptedData, nonce, keyStr) {
|
||||
const key = this._generateKey(keyStr)
|
||||
const iv = this._generateIv(nonce, keyStr)
|
||||
|
||||
const decrypted = CryptoJS.AES.decrypt(encryptedData, key, {
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
})
|
||||
|
||||
return decrypted.toString(CryptoJS.enc.Utf8)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user