1. 海报

This commit is contained in:
李琦
2026-08-03 10:18:23 +08:00
parent 3b9520eb0f
commit 807adbc6a4
10 changed files with 1155 additions and 21 deletions

View File

@@ -20,9 +20,11 @@
"axios": "^1.6.2",
"echarts": "^6.1.0",
"gsap": "^3.15.0",
"html2canvas": "^1.4.1",
"lucide-vue-next": "^0.507.0",
"motion-v": "^2.3.0",
"pinia": "^2.1.7",
"qrcode": "^1.5.4",
"swiper": "^11.0.5",
"tailwindcss": "^4.1.4",
"vue": "^3.5.13",
@@ -1794,6 +1796,30 @@
"node": ">= 6.0.0"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/ant-design-vue": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz",
@@ -1864,6 +1890,15 @@
"proxy-from-env": "^2.1.0"
}
},
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
@@ -1877,6 +1912,15 @@
"node": ">= 0.4"
}
},
"node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/chokidar": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
@@ -1893,6 +1937,35 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1922,6 +1995,15 @@
"url": "https://opencollective.com/core-js"
}
},
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"license": "MIT",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -1951,6 +2033,15 @@
}
}
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -1969,6 +2060,12 @@
"node": ">=8"
}
},
"node_modules/dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
"license": "MIT"
},
"node_modules/dom-align": {
"version": "1.12.4",
"resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz",
@@ -2005,6 +2102,12 @@
"zrender": "6.1.0"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/enhanced-resolve": {
"version": "5.24.4",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.4.tgz",
@@ -2139,6 +2242,19 @@
}
}
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/follow-redirects": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
@@ -2231,6 +2347,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -2343,6 +2468,19 @@
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
"license": "MIT"
},
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"license": "MIT",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
@@ -2373,6 +2511,15 @@
"node": ">=0.10.0"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -2659,6 +2806,18 @@
"url": "https://opencollective.com/parcel"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lodash": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
@@ -2806,6 +2965,42 @@
"integrity": "sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==",
"license": "MIT"
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/packrup": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/packrup/-/packrup-0.1.2.tgz",
@@ -2815,6 +3010,15 @@
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -2855,6 +3059,15 @@
}
}
},
"node_modules/pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"license": "MIT",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/postcss": {
"version": "8.5.25",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz",
@@ -2892,6 +3105,23 @@
"node": ">=10"
}
},
"node_modules/qrcode": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
"license": "MIT",
"dependencies": {
"dijkstrajs": "^1.0.1",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"bin": {
"qrcode": "bin/qrcode"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
@@ -2906,6 +3136,21 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"license": "ISC"
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
@@ -2986,6 +3231,12 @@
"compute-scroll-into-view": "^1.0.20"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC"
},
"node_modules/shallow-equal": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
@@ -3001,6 +3252,32 @@
"node": ">=0.10.0"
}
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/stylis": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz",
@@ -3045,6 +3322,15 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"license": "MIT",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/throttle-debounce": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
@@ -3091,6 +3377,15 @@
"url": "https://github.com/sponsors/harlan-zw"
}
},
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"license": "MIT",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/vite": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
@@ -3251,6 +3546,67 @@
"loose-envify": "^1.0.0"
}
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"license": "ISC"
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"license": "ISC"
},
"node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"license": "MIT",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"license": "ISC",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/zhead": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/zhead/-/zhead-2.2.4.tgz",

View File

@@ -21,9 +21,11 @@
"axios": "^1.6.2",
"echarts": "^6.1.0",
"gsap": "^3.15.0",
"html2canvas": "^1.4.1",
"lucide-vue-next": "^0.507.0",
"motion-v": "^2.3.0",
"pinia": "^2.1.7",
"qrcode": "^1.5.4",
"swiper": "^11.0.5",
"tailwindcss": "^4.1.4",
"vue": "^3.5.13",

View File

@@ -44,6 +44,9 @@ importers:
gsap:
specifier: ^3.15.0
version: 3.15.0
html2canvas:
specifier: ^1.4.1
version: 1.4.1
lucide-vue-next:
specifier: ^0.507.0
version: 0.507.0(vue@3.5.40)
@@ -53,6 +56,9 @@ importers:
pinia:
specifier: ^2.1.7
version: 2.3.1(vue@3.5.40)
qrcode:
specifier: ^1.5.4
version: 1.5.4
swiper:
specifier: ^11.0.5
version: 11.2.10
@@ -715,6 +721,14 @@ packages:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
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'}
ant-design-vue@4.2.6:
resolution: {integrity: sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==}
engines: {node: '>=12.22.0'}
@@ -733,14 +747,32 @@ packages:
axios@1.18.1:
resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==}
base64-arraybuffer@1.0.2:
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
engines: {node: '>= 0.6.0'}
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
chokidar@5.0.0:
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
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==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -751,6 +783,9 @@ packages:
core-js@3.49.0:
resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==}
css-line-break@2.1.0:
resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
@@ -766,6 +801,10 @@ packages:
supports-color:
optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
@@ -774,6 +813,9 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dom-align@1.12.4:
resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==}
@@ -787,6 +829,9 @@ packages:
echarts@6.1.0:
resolution: {integrity: sha512-q0yaFPggC9FUdsWH4blavRWFmxdrIodbkoKNAjJudAI6CA9gNPxHtV2RcZNEepZVlk4yvBYkOkbk6HIVpIyHZA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
enhanced-resolve@5.24.4:
resolution: {integrity: sha512-GVoi+ICHocoOIU7qVVM48wOJziRsqrsyqlI0Ce0LdowRn6v3bcH2zUa9kp85ncx0nwIb9/HOCOLS3fdThDG/XQ==}
engines: {node: '>=10.13.0'}
@@ -828,6 +873,10 @@ packages:
picomatch:
optional: true
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
follow-redirects@1.16.0:
resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
engines: {node: '>=4.0'}
@@ -863,6 +912,10 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
@@ -899,6 +952,10 @@ packages:
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
html2canvas@1.4.1:
resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
engines: {node: '>=8.0.0'}
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
@@ -910,6 +967,10 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
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:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -999,6 +1060,10 @@ packages:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
lodash-es@4.18.1:
resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
@@ -1059,9 +1124,25 @@ packages:
omit.js@2.0.2:
resolution: {integrity: sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==}
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'}
packrup@0.1.2:
resolution: {integrity: sha512-ZcKU7zrr5GlonoS9cxxrb5HVswGnyj6jQvwFBa6p5VFw7G71VAHcUKL5wyZSU/ECtPM/9gacWxy2KFQKt1gMNA==}
path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -1078,6 +1159,10 @@ packages:
typescript:
optional: true
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
postcss@8.5.24:
resolution: {integrity: sha512-8RyVklq0owXUTa4xlpzu4l9AaVKIdQvAcOHZWaMh98HgySsUtxRVf/chRe3dsSLqb6i40BzGRzEUddRaI+9TSw==}
engines: {node: ^10 || ^12 || >=14}
@@ -1086,10 +1171,22 @@ packages:
resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
engines: {node: '>=10'}
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
readdirp@5.0.0:
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
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==}
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
@@ -1106,6 +1203,9 @@ packages:
scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
shallow-equal@1.2.1:
resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
@@ -1113,6 +1213,14 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
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'}
stylis@4.4.0:
resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==}
@@ -1127,6 +1235,9 @@ packages:
resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
engines: {node: '>=6'}
text-segmentation@1.0.3:
resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
throttle-debounce@5.0.2:
resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==}
engines: {node: '>=12.22'}
@@ -1144,6 +1255,9 @@ packages:
unhead@1.11.20:
resolution: {integrity: sha512-3AsNQC0pjwlLqEYHLjtichGWankK8yqmocReITecmpB1H0aOabeESueyy+8X1gyJx4ftZVwo9hqQ4O3fPWffCA==}
utrie@1.0.2:
resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
vite@6.4.3:
resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -1217,6 +1331,24 @@ packages:
warning@4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
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'}
zhead@2.2.4:
resolution: {integrity: sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==}
@@ -1701,6 +1833,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
ansi-regex@5.0.1: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
ant-design-vue@4.2.6(vue@3.5.40):
dependencies:
'@ant-design/colors': 6.0.0
@@ -1743,15 +1881,31 @@ snapshots:
- debug
- supports-color
base64-arraybuffer@1.0.2: {}
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
camelcase@5.3.1: {}
chokidar@5.0.0:
dependencies:
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: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@@ -1760,6 +1914,10 @@ snapshots:
core-js@3.49.0: {}
css-line-break@2.1.0:
dependencies:
utrie: 1.0.2
csstype@3.2.3: {}
dayjs@1.11.21: {}
@@ -1768,10 +1926,14 @@ snapshots:
dependencies:
ms: 2.1.3
decamelize@1.2.0: {}
delayed-stream@1.0.0: {}
detect-libc@2.1.2: {}
dijkstrajs@1.0.3: {}
dom-align@1.12.4: {}
dom-scroll-into-view@2.0.1: {}
@@ -1787,6 +1949,8 @@ snapshots:
tslib: 2.3.0
zrender: 6.1.0
emoji-regex@8.0.0: {}
enhanced-resolve@5.24.4:
dependencies:
graceful-fs: 4.2.11
@@ -1844,6 +2008,11 @@ snapshots:
optionalDependencies:
picomatch: 4.0.5
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
follow-redirects@1.16.0(debug@4.4.3):
optionalDependencies:
debug: 4.4.3
@@ -1867,6 +2036,8 @@ snapshots:
function-bind@1.1.2: {}
get-caller-file@2.0.5: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -1905,6 +2076,11 @@ snapshots:
hookable@5.5.3: {}
html2canvas@1.4.1:
dependencies:
css-line-break: 2.1.0
text-segmentation: 1.0.3
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
@@ -1917,6 +2093,8 @@ snapshots:
is-extglob@2.1.1:
optional: true
is-fullwidth-code-point@3.0.0: {}
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -1977,6 +2155,10 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
lodash-es@4.18.1: {}
lodash@4.18.1: {}
@@ -2031,8 +2213,20 @@ snapshots:
omit.js@2.0.2: {}
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: {}
packrup@0.1.2: {}
path-exists@4.0.0: {}
picocolors@1.1.1: {}
picomatch@4.0.5: {}
@@ -2045,6 +2239,8 @@ snapshots:
transitivePeerDependencies:
- '@vue/composition-api'
pngjs@5.0.0: {}
postcss@8.5.24:
dependencies:
nanoid: 3.3.16
@@ -2053,8 +2249,18 @@ snapshots:
proxy-from-env@2.1.0: {}
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
readdirp@5.0.0: {}
require-directory@2.1.1: {}
require-main-filename@2.0.0: {}
resize-observer-polyfill@1.5.1: {}
rollup@4.62.3:
@@ -2100,10 +2306,22 @@ snapshots:
dependencies:
compute-scroll-into-view: 1.0.20
set-blocking@2.0.0: {}
shallow-equal@1.2.1: {}
source-map-js@1.2.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
stylis@4.4.0: {}
swiper@11.2.10: {}
@@ -2112,6 +2330,10 @@ snapshots:
tapable@2.3.3: {}
text-segmentation@1.0.3:
dependencies:
utrie: 1.0.2
throttle-debounce@5.0.2: {}
tinyglobby@0.2.17:
@@ -2130,6 +2352,10 @@ snapshots:
'@unhead/shared': 1.11.20
hookable: 5.5.3
utrie@1.0.2:
dependencies:
base64-arraybuffer: 1.0.2
vite@6.4.3(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.102.0):
dependencies:
esbuild: 0.25.12
@@ -2170,6 +2396,35 @@ snapshots:
dependencies:
loose-envify: 1.4.0
which-module@2.0.1: {}
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
y18n@4.0.3: {}
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
zhead@2.2.4: {}
zrender@6.1.0:

View File

@@ -0,0 +1,113 @@
<template>
<div class="fq" :class="{ 'fq--compact': compact }">
<div class="fq-title">扫码观喜</div>
<div class="fq-frame">
<span class="fq-corner fq-tl"></span>
<span class="fq-corner fq-tr"></span>
<span class="fq-corner fq-bl"></span>
<span class="fq-corner fq-br"></span>
<canvas ref="canvasRef" class="fq-canvas"></canvas>
</div>
<div v-if="!compact" class="fq-hint">手机扫码打开本页</div>
</div>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import { renderFestiveQr } from '@/composables/renderFestiveQr'
const props = defineProps({
url: { type: String, required: true },
size: { type: Number, default: 148 },
compact: { type: Boolean, default: false },
centerImg: { type: String, default: '' },
})
const canvasRef = ref(null)
async function render() {
if (!canvasRef.value || !props.url) return
const width = props.compact ? Math.min(props.size, 112) : props.size
await renderFestiveQr(canvasRef.value, props.url, {
size: width,
centerImg: props.centerImg,
})
}
onMounted(render)
watch(() => [props.url, props.size, props.compact, props.centerImg], render)
</script>
<style scoped>
.fq {
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
padding: 14px 16px 12px;
background:
radial-gradient(circle at 50% 0%, rgba(240, 215, 140, 0.25), transparent 55%),
linear-gradient(180deg, #9b0000, #6e0000);
border: 1.5px solid #d4af37;
border-radius: 12px;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
color: #f0d78c;
min-width: 200px;
}
.fq--compact {
min-width: 0;
padding: 8px 10px 8px;
border-radius: 10px;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32);
}
.fq--compact .fq-title {
font-size: 12px;
letter-spacing: 0.35em;
padding-left: 0.35em;
margin-bottom: 8px;
}
.fq--compact .fq-frame { padding: 8px; }
.fq--compact .fq-corner { font-size: 10px; }
.fq-title {
font-size: 15px;
letter-spacing: 0.45em;
padding-left: 0.45em;
font-weight: 600;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
margin-bottom: 10px;
line-height: 1.2;
flex-shrink: 0;
}
.fq-frame {
position: relative;
padding: 14px;
background: linear-gradient(145deg, #fff8e7, #f7e7c3);
border: 2px solid #d4af37;
border-radius: 10px;
box-shadow: inset 0 0 0 1px rgba(155, 0, 0, 0.12);
}
.fq-corner {
position: absolute;
font-size: 12px;
font-weight: 700;
color: #c41e3a;
line-height: 1;
opacity: 0.9;
z-index: 1;
pointer-events: none;
}
.fq-tl { top: 3px; left: 4px; }
.fq-tr { top: 3px; right: 4px; }
.fq-bl { bottom: 3px; left: 4px; }
.fq-br { bottom: 3px; right: 4px; }
.fq-canvas {
display: block;
border-radius: 4px;
}
.fq-hint {
margin-top: 8px;
font-size: 11px;
letter-spacing: 0.18em;
color: rgba(240, 215, 140, 0.85);
}
</style>

View File

@@ -10,6 +10,13 @@ export const POSTER_TEMPLATES = [
{ value: 'split', label: '左图右文', desc: '竖排书法 + 右侧宴席信息' },
]
/** 手机端布局仅影响窄屏PC 仍按模板本身版式 */
export const MOBILE_LAYOUTS = [
{ value: 'auto', label: '自动布局', desc: '按屏幕宽度自动切换(当前默认)' },
{ value: 'portrait', label: '竖向展示', desc: '手机端强制上下排布' },
{ value: 'landscape', label: '横屏展示', desc: '手机端强制左右分栏' },
]
/** 解析为 1 | 2无法识别返回 0 */
export function resolvePosterSide(input) {
if (input === 1 || input === '1') return 1
@@ -29,8 +36,11 @@ function baseFields(side) {
return {
side: resolvePosterSide(side) || 1,
template: 'classic',
mobileLayout: 'auto',
enabled: true,
heroImg: '',
/** 二维码中心图;空则显示圆圈大囍 */
qrCenterImg: '',
title: '婚礼邀请函',
footer: '—诚挚邀请 ♥ 恭请光临—',
loadingEffect: 'redSeal',
@@ -157,6 +167,9 @@ export function normalizePosterConfig(raw, side = 1) {
const template = POSTER_TEMPLATES.some((t) => t.value === loaded.template)
? loaded.template
: base.template
const mobileLayout = MOBILE_LAYOUTS.some((t) => t.value === loaded.mobileLayout)
? loaded.mobileLayout
: base.mobileLayout
const groomName = loaded.groomName || loaded.sonName || base.groomName
const brideName = loaded.brideName || loaded.daughterInLawName || base.brideName
@@ -166,6 +179,7 @@ export function normalizePosterConfig(raw, side = 1) {
...loaded,
side: s,
template,
mobileLayout,
lines: lines.length ? lines : base.lines,
groomName,
brideName,
@@ -179,6 +193,7 @@ export function normalizePosterConfig(raw, side = 1) {
: base.enterEffect,
invitePath: loaded.invitePath || '/',
inviteButtonText: loaded.inviteButtonText || base.inviteButtonText,
qrCenterImg: loaded.qrCenterImg || '',
verticalSlogan: loaded.verticalSlogan || base.verticalSlogan,
subSlogan1: loaded.subSlogan1 || base.subSlogan1,
subSlogan2: loaded.subSlogan2 || base.subSlogan2,

View File

@@ -0,0 +1,83 @@
import QRCode from 'qrcode'
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image()
img.crossOrigin = 'anonymous'
img.onload = () => resolve(img)
img.onerror = reject
img.src = src
})
}
/** 在 canvas 上绘制喜庆二维码,中心为配置图或圆圈大囍 */
export async function renderFestiveQr(canvas, url, options = {}) {
const size = options.size || 148
const centerImg = String(options.centerImg || '').trim()
await QRCode.toCanvas(canvas, url, {
width: size,
margin: 1,
color: {
dark: '#8b0000',
light: '#fff8e7',
},
errorCorrectionLevel: 'H',
})
const ctx = canvas.getContext('2d')
if (!ctx) return
const w = canvas.width
const h = canvas.height
const cx = w / 2
const cy = h / 2
const diameter = Math.round(Math.min(w, h) * 0.3)
const r = diameter / 2
const ring = Math.max(2, Math.round(w * 0.012))
ctx.save()
// 外圈底
ctx.beginPath()
ctx.arc(cx, cy, r + ring, 0, Math.PI * 2)
ctx.fillStyle = '#fff8e7'
ctx.fill()
ctx.strokeStyle = '#c41e3a'
ctx.lineWidth = ring
ctx.stroke()
let drewImg = false
if (centerImg) {
try {
const img = await loadImage(centerImg)
ctx.beginPath()
ctx.arc(cx, cy, r - 0.5, 0, Math.PI * 2)
ctx.clip()
const side = (r - 0.5) * 2
const scale = Math.max(side / img.width, side / img.height)
const dw = img.width * scale
const dh = img.height * scale
ctx.drawImage(img, cx - dw / 2, cy - dh / 2, dw, dh)
drewImg = true
} catch {
drewImg = false
}
}
if (!drewImg) {
ctx.beginPath()
ctx.arc(cx, cy, r - 0.5, 0, Math.PI * 2)
ctx.fillStyle = 'rgba(255, 248, 231, 0.96)'
ctx.fill()
ctx.strokeStyle = '#c41e3a'
ctx.lineWidth = Math.max(1.5, ring * 0.7)
ctx.stroke()
ctx.fillStyle = '#c41e3a'
ctx.font = `700 ${Math.round(r * 1.45)}px "Noto Serif SC","Source Han Serif SC","Songti SC",serif`
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.fillText('囍', cx, cy + r * 0.04)
}
ctx.restore()
}

View File

@@ -438,6 +438,16 @@
{{ POSTER_TEMPLATES.find(t => t.value === posterCfg.template)?.desc }}
</div>
</a-form-item>
<a-form-item label="手机端布局">
<a-radio-group v-model:value="posterCfg.mobileLayout">
<a-radio-button v-for="t in MOBILE_LAYOUTS" :key="t.value" :value="t.value">
{{ t.label }}
</a-radio-button>
</a-radio-group>
<div class="text-[11px] text-[#8A8680] mt-1">
{{ MOBILE_LAYOUTS.find(t => t.value === posterCfg.mobileLayout)?.desc }}仅窄屏生效PC 不受影响
</div>
</a-form-item>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<a-form-item label="启用海报页">
<a-switch v-model:checked="posterCfg.enabled" />
@@ -467,6 +477,15 @@
<a-form-item :label="posterCfg.template === 'split' ? '左侧照片' : '顶部照片'">
<image-field v-model="posterCfg.heroImg" label="海报图片" @pick="setPosterHero" :uploading="uploading" />
</a-form-item>
<a-form-item label="二维码中心图">
<image-field
v-model="posterCfg.qrCenterImg"
label="中心图(可选)"
@pick="setPosterQrCenter"
:uploading="uploading"
/>
<div class="text-xs text-stone-500 mt-1">不配置时二维码中心为圆圈大</div>
</a-form-item>
<!-- classic 字段 -->
<template v-if="posterCfg.template === 'classic'">
@@ -890,7 +909,7 @@ import { resolveDanmakuSwatch } from '@/utils/danmakuColors'
import { getSlotResizeSpecs, resizeSlotToFile, probeResizedMeta, metaHasFileSize } from '@/composables/resizeImage'
import {
defaultPosterBundle, normalizePosterBundle, normalizePosterConfig,
LOADING_EFFECTS, ENTER_EFFECTS, POSTER_SIDES, POSTER_TEMPLATES, sideKey,
LOADING_EFFECTS, ENTER_EFFECTS, POSTER_SIDES, POSTER_TEMPLATES, MOBILE_LAYOUTS, sideKey,
} from '@/composables/posterDefaults'
echarts.use([PieChart, TooltipComponent, LegendComponent, CanvasRenderer])
@@ -969,6 +988,11 @@ function setPosterHero(url) {
if (!posterBundle[side]) posterBundle[side] = normalizePosterConfig(null, side)
posterBundle[side].heroImg = url
}
function setPosterQrCenter(url) {
const side = sideKey(posterSideTab.value)
if (!posterBundle[side]) posterBundle[side] = normalizePosterConfig(null, side)
posterBundle[side].qrCenterImg = url
}
const currentPhotoIndex = computed(() => Math.min(Number(activePhotoTab.value) || 0, Math.max(cfg.photoPages.length - 1, 0)))
const isConfigTab = computed(() => CONFIG_SECTIONS.includes(activeTab.value))
const visitPagination = computed(() => ({

View File

@@ -60,20 +60,37 @@
<div class="hb-enter-veil"></div>
</div>
<template v-if="cfg.enabled && (phase === 'content' || phase === 'enter')">
<ClassicPoster
v-if="cfg.template === 'classic'"
:cfg="cfg"
:ready="contentVisible && phase === 'content'"
@invite="goInvite"
/>
<SplitPoster
v-else
:cfg="cfg"
:ready="contentVisible && phase === 'content'"
@invite="goInvite"
/>
</template>
<div
v-if="cfg.enabled && (phase === 'content' || phase === 'enter')"
class="hb-main"
>
<div class="hb-poster-wrap">
<ClassicPoster
v-if="cfg.template === 'classic'"
:cfg="cfg"
:ready="contentVisible && phase === 'content'"
@invite="goInvite"
/>
<SplitPoster
v-else
:cfg="cfg"
:ready="contentVisible && phase === 'content'"
@invite="goInvite"
/>
</div>
</div>
<!-- PC右下角固定不占版心空间保存时会把二维码打进海报图 -->
<aside
v-if="isPc && phase === 'content' && contentVisible && cfg.enabled"
class="hb-pc-tools"
>
<button type="button" class="hb-save-btn" :disabled="savingImg" @click="savePosterImage">
<i class="fa-solid fa-download"></i>
{{ savingImg ? '生成中…' : '保存海报' }}
</button>
<FestiveQrCard :url="pageUrl" :size="112" :center-img="cfg.qrCenterImg" compact />
</aside>
<div v-if="!cfg.enabled && phase === 'content'" class="hb-disabled">
<p>海报暂未开放</p>
@@ -85,10 +102,13 @@
<script setup>
import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import html2canvas from 'html2canvas'
import { getPosterConfig } from '@/api/wedding'
import { normalizePosterConfig, resolvePosterSide } from '@/composables/posterDefaults'
import { renderFestiveQr } from '@/composables/renderFestiveQr'
import ClassicPoster from '@/views/hb/templates/ClassicPoster.vue'
import SplitPoster from '@/views/hb/templates/SplitPoster.vue'
import FestiveQrCard from '@/components/FestiveQrCard.vue'
const route = useRoute()
const router = useRouter()
@@ -97,6 +117,9 @@ const cfg = reactive(normalizePosterConfig(null, posterSide.value))
const phase = ref('loading')
const enterLeaving = ref(false)
const contentVisible = ref(false)
const savingImg = ref(false)
const isPc = ref(false)
const pageUrl = computed(() => (typeof window !== 'undefined' ? window.location.href : ''))
let timers = []
function later(fn, ms) {
@@ -105,12 +128,94 @@ function later(fn, ms) {
return id
}
function refreshPc() {
isPc.value = window.matchMedia('(min-width: 900px)').matches
}
function goInvite() {
const path = cfg.invitePath || '/'
if (path.startsWith('http')) window.location.href = path
else router.push(path)
}
async function mountCaptureQr(host) {
const isSplit = host.classList.contains('sp-card')
const target = isSplit
? (host.querySelector('.sp-left') || host)
: (host.querySelector('.hb-inner') || host)
const qrSize = isSplit ? 64 : 88
const badge = document.createElement('div')
badge.setAttribute('data-hb-capture-qr', '')
badge.className = isSplit ? 'hb-cq--split' : 'hb-cq--classic'
badge.innerHTML = `
<div class="hb-cq-title">扫码观喜</div>
<div class="hb-cq-frame">
<span class="hb-cq-c hb-cq-tl">囍</span>
<span class="hb-cq-c hb-cq-tr">囍</span>
<span class="hb-cq-c hb-cq-bl">囍</span>
<span class="hb-cq-c hb-cq-br">囍</span>
<canvas></canvas>
</div>
`
if (!isSplit) {
target.classList.add('hb-inner--capturing')
} else if (getComputedStyle(target).position === 'static') {
target.style.position = 'relative'
}
// 保存时先藏按钮,避免进图、也避免占位
const hiddenCtas = []
host.querySelectorAll('[data-html2canvas-ignore]').forEach((node) => {
hiddenCtas.push([node, node.style.display])
node.style.display = 'none'
})
target.appendChild(badge)
const qrCanvas = badge.querySelector('canvas')
await renderFestiveQr(qrCanvas, pageUrl.value, {
size: qrSize,
centerImg: cfg.qrCenterImg,
})
await new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)))
return () => {
badge.remove()
target.classList.remove('hb-inner--capturing')
hiddenCtas.forEach(([node, display]) => {
node.style.display = display
})
}
}
async function savePosterImage() {
const el = document.querySelector('[data-poster-capture]')
if (!el) return
savingImg.value = true
let cleanup = null
try {
cleanup = await mountCaptureQr(el)
const canvas = await html2canvas(el, {
useCORS: true,
allowTaint: true,
backgroundColor: '#7a0000',
scale: Math.min(2, window.devicePixelRatio || 2),
ignoreElements: (node) => !!node?.hasAttribute?.('data-html2canvas-ignore'),
})
const a = document.createElement('a')
a.download = `婚礼海报-${cfg.side === 2 ? '女方' : '男方'}-${Date.now()}.png`
a.href = canvas.toDataURL('image/png')
a.click()
} catch (e) {
console.error(e)
window.alert('保存失败,请稍后重试(跨域图片可能导致无法导出)')
} finally {
cleanup?.()
savingImg.value = false
}
}
async function runSequence() {
const loadMs = cfg.loadingEffect === 'fade' ? 700 : 1100
await new Promise((r) => later(r, loadMs))
@@ -135,6 +240,8 @@ async function runSequence() {
}
onMounted(async () => {
refreshPc()
window.addEventListener('resize', refreshPc, { passive: true })
const side = posterSide.value
try {
const res = await getPosterConfig(side)
@@ -148,6 +255,7 @@ onMounted(async () => {
onUnmounted(() => {
timers.forEach(clearTimeout)
timers = []
window.removeEventListener('resize', refreshPc)
})
</script>
@@ -175,6 +283,54 @@ onUnmounted(() => {
overflow-x: hidden;
font-family: "Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", serif;
}
.hb-main {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
max-width: 960px;
}
.hb-poster-wrap {
display: flex;
justify-content: center;
min-width: 0;
width: 100%;
}
.hb-pc-tools {
position: fixed;
right: 20px;
bottom: 20px;
z-index: 25;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
pointer-events: none;
}
.hb-pc-tools > * { pointer-events: auto; }
.hb-save-btn {
appearance: none;
border: 1.5px solid #d4af37;
background: linear-gradient(180deg, rgba(212, 175, 55, 0.45), rgba(155, 0, 0, 0.72));
color: #f0d78c;
padding: 10px 16px;
border-radius: 999px;
letter-spacing: 0.2em;
font-size: 13px;
cursor: pointer;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
backdrop-filter: blur(6px);
}
.hb-save-btn:disabled { opacity: 0.65; cursor: wait; }
.hb-save-btn:not(:disabled):hover {
filter: brightness(1.08);
}
.hb-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.hb-bg-decor { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.hb-bg-xi {
@@ -262,3 +418,85 @@ onUnmounted(() => {
@keyframes hb-swing { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes hb-twinkle { 0%, 100% { opacity: 0.25; transform: scale(0.7); } 50% { opacity: 1; transform: scale(1.25); } }
</style>
<!-- 保存截图时注入的喜庆二维码 Vue 节点需全局样式 -->
<style>
[data-hb-capture-qr] {
z-index: 30;
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
padding: 8px 10px;
background:
radial-gradient(circle at 50% 0%, rgba(240, 215, 140, 0.28), transparent 55%),
linear-gradient(180deg, #9b0000, #6e0000);
border: 1.5px solid #d4af37;
border-radius: 10px;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
color: #f0d78c;
pointer-events: none;
font-family: "Noto Serif SC", "Source Han Serif SC", "Songti SC", "STSong", serif;
}
/* 左图右文:贴在左图右下角,更小 */
[data-hb-capture-qr].hb-cq--split {
position: absolute;
right: 8px;
bottom: 8px;
padding: 5px 6px;
border-radius: 8px;
}
[data-hb-capture-qr].hb-cq--split .hb-cq-title {
font-size: 9px;
letter-spacing: 0.22em;
padding-left: 0.22em;
margin-bottom: 6px;
}
[data-hb-capture-qr].hb-cq--split .hb-cq-frame { padding: 5px; border-radius: 6px; }
[data-hb-capture-qr].hb-cq--split .hb-cq-c { font-size: 8px; }
/* 经典竖版:置于最底部,随容器增高 */
[data-hb-capture-qr].hb-cq--classic {
position: relative;
margin: 36px auto 8px;
flex-shrink: 0;
z-index: 5;
}
.hb-inner--capturing {
min-height: min(940px, calc(100dvh + 100px)) !important;
padding-bottom: 20px !important;
overflow: visible !important;
}
[data-hb-capture-qr] .hb-cq-title {
font-size: 11px;
letter-spacing: 0.35em;
padding-left: 0.35em;
font-weight: 600;
margin-bottom: 8px;
line-height: 1.2;
flex-shrink: 0;
}
[data-hb-capture-qr] .hb-cq-frame {
position: relative;
padding: 8px;
background: linear-gradient(145deg, #fff8e7, #f7e7c3);
border: 2px solid #d4af37;
border-radius: 8px;
}
[data-hb-capture-qr] .hb-cq-c {
position: absolute;
font-size: 10px;
font-weight: 700;
color: #c41e3a;
line-height: 1;
z-index: 1;
pointer-events: none;
}
[data-hb-capture-qr] .hb-cq-tl { top: 2px; left: 3px; }
[data-hb-capture-qr] .hb-cq-tr { top: 2px; right: 3px; }
[data-hb-capture-qr] .hb-cq-bl { bottom: 2px; left: 3px; }
[data-hb-capture-qr] .hb-cq-br { bottom: 2px; right: 3px; }
[data-hb-capture-qr] canvas {
display: block;
border-radius: 3px;
}
</style>

View File

@@ -1,6 +1,9 @@
<template>
<div class="hb-stage" :class="{ 'is-visible': ready }">
<div class="hb-frame">
<div
class="hb-stage"
:class="[{ 'is-visible': ready }, `hb-m-${cfg.mobileLayout || 'auto'}`]"
>
<div class="hb-frame" data-poster-capture>
<div class="hb-frame-ornament hb-frame-ornament-tl" aria-hidden="true">
<svg viewBox="0 0 48 48"><use href="#hb-icon-corner" /></svg>
</div>
@@ -116,7 +119,11 @@
/>
</div>
<div v-if="cfg.showInviteButton && stage >= 6" class="hb-cta is-show">
<div
v-if="cfg.showInviteButton && stage >= 6"
class="hb-cta is-show"
data-html2canvas-ignore
>
<button type="button" class="hb-cta-btn" @click="$emit('invite')">
{{ cfg.inviteButtonText }}
</button>
@@ -193,6 +200,12 @@ watch(
opacity: 1;
transform: translateY(0) scale(1);
}
@media (max-width: 719px) {
.hb-m-portrait { width: min(420px, 100%); }
.hb-m-landscape { width: min(100%, 640px); }
.hb-m-landscape .hb-inner { min-height: min(520px, 78dvh); }
.hb-m-landscape .hb-title { font-size: clamp(24px, 7vw, 34px); }
}
.hb-frame {
position: relative;
border: 1.5px solid var(--hb-gold);

View File

@@ -1,6 +1,12 @@
<template>
<div class="sp" :class="{ 'is-visible': ready }">
<div class="sp-card">
<div
class="sp"
:class="[
{ 'is-visible': ready },
`sp-m-${cfg.mobileLayout || 'auto'}`,
]"
>
<div class="sp-card" data-poster-capture>
<section class="sp-left">
<div class="sp-photo" :class="{ 'is-show': stage >= 1 }">
<img v-if="cfg.heroImg" :src="cfg.heroImg" alt="" />
@@ -91,7 +97,11 @@
<span class="sp-heart"></span>
</div>
<div v-if="cfg.showInviteButton && stage >= 6" class="sp-cta">
<div
v-if="cfg.showInviteButton && stage >= 6"
class="sp-cta"
data-html2canvas-ignore
>
<button type="button" class="sp-cta-btn" @click="$emit('invite')">
{{ cfg.inviteButtonText }}
</button>
@@ -174,6 +184,7 @@ watch(
.sp.is-visible { opacity: 1; transform: none; }
.sp-card {
position: relative;
display: flex;
flex-direction: column;
border: 1.5px solid var(--hb-gold);
@@ -184,6 +195,30 @@ watch(
background: #8b0000;
}
/* 手机端:自动 = 上下;竖向强制上下;横屏强制左右 */
@media (max-width: 719px) {
.sp-m-auto .sp-card,
.sp-m-portrait .sp-card {
flex-direction: column;
}
.sp-m-auto .sp-left,
.sp-m-portrait .sp-left {
width: 100%;
}
.sp-m-landscape .sp-card {
flex-direction: row;
min-height: min(420px, 70dvh);
}
.sp-m-landscape .sp-left { width: 44%; min-height: 0; }
.sp-m-landscape .sp-right { width: 56%; padding: 12px 10px; }
.sp-m-landscape .sp-slogan { font-size: clamp(22px, 6vw, 32px); }
.sp-m-landscape .sp-xi-top { font-size: 32px; }
.sp-m-landscape .sp-name { font-size: 14px; }
.sp-m-landscape .sp-line { font-size: 11px; }
.sp-m-landscape .sp-greeting { font-size: 12px; }
.sp-m-landscape .sp-photo { min-height: 100%; }
}
@media (min-width: 720px) {
.sp-card { flex-direction: row; min-height: min(560px, calc(100dvh - 40px)); }
.sp-left { width: 46%; }