From aa9410b990fba24d954b408496e579ea4796a3f4 Mon Sep 17 00:00:00 2001 From: yml Date: Fri, 22 May 2026 20:38:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E9=99=86=E6=B3=A8=E5=86=8C=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E4=BC=98=E5=8C=96=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/components.d.ts | 34 ++ frontend/package-lock.json | 444 ++++++++++++++++ frontend/package.json | 4 + frontend/src/router/index.ts | 6 + frontend/src/views/mobile/MobileHomeView.vue | 303 ++++++----- frontend/src/views/mobile/MobileLoginView.vue | 486 +++++++++++------ .../src/views/mobile/MobileProfileView.vue | 498 +++++++++++++++--- .../src/views/mobile/MobileRegisterView.vue | 447 ++++++++++++++++ frontend/vite.config.ts | 21 +- 9 files changed, 1864 insertions(+), 379 deletions(-) create mode 100644 frontend/components.d.ts create mode 100644 frontend/src/views/mobile/MobileRegisterView.vue diff --git a/frontend/components.d.ts b/frontend/components.d.ts new file mode 100644 index 0000000..88040b3 --- /dev/null +++ b/frontend/components.d.ts @@ -0,0 +1,34 @@ +/* eslint-disable */ +// @ts-nocheck +// biome-ignore lint: disable +// oxlint-disable +// ------ +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 + +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + VanButton: typeof import('vant/es')['Button'] + VanCell: typeof import('vant/es')['Cell'] + VanCellGroup: typeof import('vant/es')['CellGroup'] + VanCheckbox: typeof import('vant/es')['Checkbox'] + VanDropdownItem: typeof import('vant/es')['DropdownItem'] + VanDropdownMenu: typeof import('vant/es')['DropdownMenu'] + VanEmpty: typeof import('vant/es')['Empty'] + VanField: typeof import('vant/es')['Field'] + VanGrid: typeof import('vant/es')['Grid'] + VanGridItem: typeof import('vant/es')['GridItem'] + VanIcon: typeof import('vant/es')['Icon'] + VanImage: typeof import('vant/es')['Image'] + VanLoading: typeof import('vant/es')['Loading'] + VanNoticeBar: typeof import('vant/es')['NoticeBar'] + VanSearch: typeof import('vant/es')['Search'] + VanTabbar: typeof import('vant/es')['Tabbar'] + VanTabbarItem: typeof import('vant/es')['TabbarItem'] + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e219384..feaec6b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,9 +17,13 @@ }, "devDependencies": { "@types/node": "^24.10.1", + "@vant/auto-import-resolver": "^1.3.0", "@vitejs/plugin-vue": "^6.0.2", "@vue/tsconfig": "^0.8.1", "typescript": "~5.9.3", + "unplugin-auto-import": "^21.0.0", + "unplugin-vue-components": "^32.1.0", + "vant": "^4.9.24", "vite": "^7.2.4", "vue-tsc": "^3.1.5" } @@ -555,12 +559,55 @@ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@popperjs/core": { "name": "@sxzz/popperjs-es", "version": "2.11.8", @@ -1006,6 +1053,30 @@ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", "license": "MIT" }, + "node_modules/@vant/auto-import-resolver": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vant/auto-import-resolver/-/auto-import-resolver-1.3.0.tgz", + "integrity": "sha512-lJyWtCyFizR4bHZvMiNMF3w+WTFTUWAvka1eqTnPK9ticUcKTCOx6qEmHcm8JPb3g1t3GaD2W3MnHkBp/nHamw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vant/popperjs": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz", + "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vant/use": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vant/use/-/use-1.6.0.tgz", + "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.7", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz", @@ -1258,6 +1329,19 @@ "vue": "^3.5.0" } }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1323,6 +1407,22 @@ "node": ">= 0.4" } }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1335,6 +1435,13 @@ "node": ">= 0.8" } }, + "node_modules/confbox": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true, + "license": "MIT" + }, "node_modules/copy-anything": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", @@ -1527,12 +1634,32 @@ "@esbuild/win32-x64": "0.27.7" } }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/exsolve": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", + "dev": true, + "license": "MIT" + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -1730,6 +1857,31 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/local-pkg": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.2.1.tgz", + "integrity": "sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/lodash": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", @@ -1804,6 +1956,38 @@ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1841,6 +2025,17 @@ "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", "license": "BSD-3-Clause" }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -1848,6 +2043,13 @@ "dev": true, "license": "MIT" }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", @@ -1894,6 +2096,18 @@ } } }, + "node_modules/pkg-types": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz", + "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.4", + "exsolve": "^1.0.8", + "pathe": "^2.0.3" + } + }, "node_modules/postcss": { "version": "8.5.15", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", @@ -1931,6 +2145,37 @@ "node": ">=10" } }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -1982,6 +2227,13 @@ "fsevents": "~2.3.2" } }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true, + "license": "MIT" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2000,6 +2252,19 @@ "node": ">=0.10.0" } }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/superjson": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", @@ -2043,6 +2308,13 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -2050,6 +2322,171 @@ "dev": true, "license": "MIT" }, + "node_modules/unimport": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.7.0.tgz", + "integrity": "sha512-njnL6sp8lEA8QQbZrt+52p/g4X0rw3bnGGmUcJnt1jeG8+iiqO779aGz0PirCtydAIVcuTBRlJ52F0u46z309Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.2", + "magic-string": "^0.30.21", + "mlly": "^1.8.0", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "pkg-types": "^2.3.0", + "scule": "^1.3.0", + "strip-literal": "^3.1.0", + "tinyglobby": "^0.2.15", + "unplugin": "^2.3.11", + "unplugin-utils": "^0.3.1" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unimport/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-auto-import": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-21.0.0.tgz", + "integrity": "sha512-vWuC8SwqJmxZFYwPojhOhOXDb5xFhNNcEVb9K/RFkyk/3VnfaOjzitWN7v+8DEKpMjSsY2AEGXNgt6I0yQrhRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "local-pkg": "^1.1.2", + "magic-string": "^0.30.21", + "picomatch": "^4.0.3", + "unimport": "^5.6.0", + "unplugin": "^2.3.11", + "unplugin-utils": "^0.3.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^4.0.0", + "@vueuse/core": "*" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@vueuse/core": { + "optional": true + } + } + }, + "node_modules/unplugin-utils": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz", + "integrity": "sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-vue-components": { + "version": "32.1.0", + "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-32.1.0.tgz", + "integrity": "sha512-YiUkSxuRjab18XFOrX5VsIxXzccrfmHVGsGeJgSgklb829DQmCy9E4vvDUE4tuvZZdxyFJZX0Oc4TPnnxiiMyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^5.0.0", + "local-pkg": "^1.2.0", + "magic-string": "^0.30.21", + "mlly": "^1.8.2", + "obug": "^2.1.1", + "picomatch": "^4.0.4", + "tinyglobby": "^0.2.16", + "unplugin": "^3.0.0", + "unplugin-utils": "^0.3.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^3.2.2 || ^4.0.0", + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/node_modules/unplugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", + "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/vant": { + "version": "4.9.24", + "resolved": "https://registry.npmjs.org/vant/-/vant-4.9.24.tgz", + "integrity": "sha512-tP1A7Vjzv1/B1ljb95Jhv9Q9w6acaaZDJvy6wcKrwGgY0gQZlg+FXLZH/AIKZBE3xvYGDUsv/M7AuGcr/Pqd6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vant/popperjs": "^1.3.0", + "@vant/use": "^1.6.0", + "@vue/shared": "^3.5.31" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vite": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz", @@ -2196,6 +2633,13 @@ "peerDependencies": { "typescript": ">=5.0.0" } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" } } } diff --git a/frontend/package.json b/frontend/package.json index 5c62d9e..7d52b26 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,9 +19,13 @@ }, "devDependencies": { "@types/node": "^24.10.1", + "@vant/auto-import-resolver": "^1.3.0", "@vitejs/plugin-vue": "^6.0.2", "@vue/tsconfig": "^0.8.1", "typescript": "~5.9.3", + "unplugin-auto-import": "^21.0.0", + "unplugin-vue-components": "^32.1.0", + "vant": "^4.9.24", "vite": "^7.2.4", "vue-tsc": "^3.1.5" } diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index ac09f8a..df370f7 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -30,6 +30,12 @@ const router = createRouter({ component: () => import("@/views/mobile/MobileLoginView.vue"), meta: { layout: "blank" }, }, + { + path: "/m/register", + name: "mobile-register", + component: () => import("@/views/mobile/MobileRegisterView.vue"), + meta: { layout: "blank" }, + }, { path: "/m/profile", name: "mobile-profile", diff --git a/frontend/src/views/mobile/MobileHomeView.vue b/frontend/src/views/mobile/MobileHomeView.vue index cb5562b..0aa2b7b 100644 --- a/frontend/src/views/mobile/MobileHomeView.vue +++ b/frontend/src/views/mobile/MobileHomeView.vue @@ -8,7 +8,8 @@ const loading = ref(false); const loadFailed = ref(false); const listings = ref([]); const filterOpen = ref(false); -const activeSort = ref("默认"); +const activeSort = ref(0); +const activeFilter = ref([]); const channels = [ { label: "全部", icon: "🔥" }, @@ -17,8 +18,18 @@ const channels = [ { label: "扫码号", icon: "📱" }, { label: "包夜", icon: "🌙" }, ]; -const sortOptions = ["默认", "价格", "比例", "哈夫币", "筛选"]; -const quickFilters = ["三角洲行动", "安卓/扫码", "高段位", "可包夜"]; +const sortOptions = [ + { text: "默认", value: 0 }, + { text: "价格", value: 1 }, + { text: "比例", value: 2 }, + { text: "哈夫币", value: 3 }, +]; +const quickFilters = [ + { text: "三角洲行动", value: "a" }, + { text: "安卓/扫码", value: "b" }, + { text: "高段位", value: "c" }, + { text: "可包夜", value: "d" }, +]; const fallbackListings: Listing[] = [ { @@ -143,10 +154,13 @@ function formatRatio(item: Listing) { } return `${Math.round(item.haf_coin_amount / item.price_hourly / 10000)}W/元`; } + +const searchValue = ref(""); @@ -282,6 +305,7 @@ function formatRatio(item: Listing) { padding-bottom: 92px; } +/* ========== Hero 区域 ========== */ .mobile-hero { overflow: hidden; border-radius: 0 0 28px 28px; @@ -292,8 +316,7 @@ function formatRatio(item: Listing) { .mobile-topbar, .mobile-brand, .card-title-row, -.card-footer, -.mobile-tabbar { +.card-footer { display: flex; align-items: center; } @@ -337,41 +360,40 @@ function formatRatio(item: Listing) { padding: 7px 12px; } -.mobile-search { - display: flex; - align-items: center; - gap: 8px; +/* ========== van-search 覆盖样式 ========== */ +.home-search { margin-top: 12px; - border-radius: 999px; - background: #ffffff; - padding: 11px 14px; - box-shadow: 0 10px 24px rgba(0, 54, 135, 0.12); + padding: 0; + background: transparent; } -.mobile-search input { - min-width: 0; - flex: 1; - border: 0; - outline: 0; +.home-search :deep(.van-search__content) { + border-radius: 999px; + background: #ffffff; + box-shadow: 0 10px 24px rgba(0, 54, 135, 0.12); + padding: 8px 14px; +} + +.home-search :deep(.van-search__content .van-field__control) { color: #17233d; font-size: 14px; } -.fraud-alert { +/* ========== van-notice-bar 防骗提示 ========== */ +.fraud-notice { margin-top: 12px; border-radius: 12px; background: #ffe27a; color: #5c3b00; - padding: 10px 12px; font-size: 12px; line-height: 1.45; } -.fraud-alert span { - margin-right: 6px; - font-weight: 800; +.fraud-notice :deep(.van-notice-bar__left-icon) { + color: #5c3b00; } +/* ========== Banner ========== */ .mobile-banner { display: flex; justify-content: space-between; @@ -422,46 +444,39 @@ function formatRatio(item: Listing) { transform: rotate(8deg); } +/* ========== Content 区 ========== */ .mobile-content { padding: 14px; } -.channel-strip, -.sort-bar, -.filter-panel { - display: flex; - gap: 8px; - overflow-x: auto; - padding-bottom: 2px; - scrollbar-width: none; +/* ========== van-grid 频道 ========== */ +.channel-grid { + margin-top: 0; } -.channel-strip::-webkit-scrollbar, -.sort-bar::-webkit-scrollbar, -.filter-panel::-webkit-scrollbar { - display: none; -} - -.channel-strip button { - display: grid; - min-width: 72px; - gap: 4px; - flex: 0 0 auto; - place-items: center; - border: 0; - border-radius: 16px; +.channel-grid :deep(.van-grid-item__content) { + padding: 11px 6px; background: #ffffff; - color: #24324a; - padding: 11px 12px; - font-size: 12px; - font-weight: 800; + border-radius: 16px; box-shadow: 0 8px 22px rgba(23, 35, 61, 0.06); } -.channel-strip span { - font-size: 18px; +.channel-grid :deep(.van-grid-item__content--surround::after) { + display: none; } +.channel-icon { + font-size: 22px; + line-height: 1; +} + +.channel-label { + font-size: 12px; + font-weight: 800; + color: #24324a; +} + +/* ========== 数据背书面板 ========== */ .trust-panel { display: grid; grid-template-columns: repeat(3, 1fr); @@ -494,46 +509,38 @@ function formatRatio(item: Listing) { font-size: 11px; } -.sort-bar { - position: sticky; - top: 0; - z-index: 10; +/* ========== van-dropdown-menu 排序筛选 ========== */ +.sort-dropdown { margin: 12px -14px 0; + border-radius: 0; +} + +.sort-dropdown :deep(.van-dropdown-menu__bar) { background: rgba(238, 245, 255, 0.92); - padding: 10px 14px 8px; backdrop-filter: blur(12px); + box-shadow: none; } -.filter-panel { - padding: 8px 0 2px; -} - -.sort-bar button, -.filter-panel button { - flex: 0 0 auto; - border: 0; - border-radius: 999px; - background: #ffffff; - color: #4d5b73; - padding: 9px 12px; +.sort-dropdown :deep(.van-dropdown-menu__title) { font-weight: 800; + color: #4d5b73; + font-size: 14px; } -.sort-bar button.active { - background: #1479ff; - color: #ffffff; +.sort-dropdown :deep(.van-dropdown-menu__title--active) { + color: #1479ff; } -.sort-bar button span { - margin-left: 2px; -} - -.mobile-tip { - margin: 12px 2px; +/* ========== 加载状态 ========== */ +.state-loading { + display: flex; + justify-content: center; + padding: 20px 0; color: #6b7a90; font-size: 13px; } +/* ========== 卡片列表 ========== */ .mobile-list { display: grid; gap: 12px; @@ -655,45 +662,59 @@ function formatRatio(item: Listing) { white-space: nowrap; } -.mobile-tabbar { +/* ========== van-tabbar 底部导航 ========== */ +.home-tabbar { position: fixed; right: 12px; bottom: 12px; left: 12px; z-index: 20; - justify-content: space-around; height: 60px; border-radius: 22px; background: rgba(255, 255, 255, 0.96); box-shadow: 0 16px 36px rgba(23, 35, 61, 0.16); backdrop-filter: blur(14px); + padding: 0; } -.tab-item { +.home-tabbar :deep(.van-tabbar) { + border-radius: 22px; + height: 60px; +} + +.home-tabbar :deep(.van-tabbar-item) { color: #708097; font-size: 12px; font-weight: 800; } -.tab-item.active { +.home-tabbar :deep(.van-tabbar-item--active) { color: #1479ff; } -.publish-tab { - display: grid; - width: 58px; - height: 58px; - place-items: center; - border: 5px solid #eef5ff; - border-radius: 50%; - background: linear-gradient(180deg, #ffb21a, #ff6a00); - color: #ffffff; - font-size: 13px; - font-weight: 900; - transform: translateY(-18px); - box-shadow: 0 10px 24px rgba(255, 106, 0, 0.35); +.home-tabbar :deep(.van-tabbar-item__icon) { + font-size: 20px; } +/* 发布按钮特殊样式 */ +.tabbar-publish :deep(.van-tabbar-item__icon) { + display: grid; + width: 48px; + height: 48px; + place-items: center; + border-radius: 50%; + background: linear-gradient(180deg, #ffb21a, #ff6a00); + color: #ffffff !important; + font-size: 22px; + transform: translateY(-8px); + box-shadow: 0 8px 20px rgba(255, 106, 0, 0.35); +} + +.tabbar-publish :deep(.van-tabbar-item__text) { + color: #ff6a00; +} + +/* ========== 响应式适配 ========== */ @media (min-width: 520px) { .mobile-shell { max-width: 430px; @@ -701,7 +722,7 @@ function formatRatio(item: Listing) { box-shadow: 0 0 0 1px rgba(23, 35, 61, 0.08); } - .mobile-tabbar { + .home-tabbar { right: calc((100vw - 430px) / 2 + 12px); left: calc((100vw - 430px) / 2 + 12px); } diff --git a/frontend/src/views/mobile/MobileLoginView.vue b/frontend/src/views/mobile/MobileLoginView.vue index 0c6f576..c3b967b 100644 --- a/frontend/src/views/mobile/MobileLoginView.vue +++ b/frontend/src/views/mobile/MobileLoginView.vue @@ -1,6 +1,7 @@ diff --git a/frontend/src/views/mobile/MobileRegisterView.vue b/frontend/src/views/mobile/MobileRegisterView.vue new file mode 100644 index 0000000..97bba93 --- /dev/null +++ b/frontend/src/views/mobile/MobileRegisterView.vue @@ -0,0 +1,447 @@ + + + + + diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 0eb375e..9a245b8 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,19 +1,26 @@ -import { fileURLToPath, URL } from 'node:url' +import { fileURLToPath, URL } from "node:url"; -import vue from '@vitejs/plugin-vue' -import { defineConfig } from 'vite' +import vue from "@vitejs/plugin-vue"; +import { defineConfig } from "vite"; +import Components from "unplugin-vue-components/vite"; +import { VantResolver } from "@vant/auto-import-resolver"; export default defineConfig({ - plugins: [vue()], + plugins: [ + vue(), + Components({ + resolvers: [VantResolver()], + }), + ], resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)), + "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, server: { port: 5173, proxy: { - '/api': 'http://127.0.0.1:8080', + "/api": "http://127.0.0.1:8080", }, }, -}) +});