Compare commits

...

81 Commits

Author SHA1 Message Date
yixu
e195570435 update 2025-10-03 21:25:49 +08:00
yixu
f9a8716262 update 2025-09-30 21:04:01 +08:00
xiaoaojiao
b86d973303 update 2025-09-29 20:36:46 +08:00
xiaoaojiao
6d631e9883 update 2025-09-29 12:26:25 +08:00
yixu
b3b6ca0bfb update 2025-09-29 12:19:53 +08:00
yixu
1b30ced5cf update 2025-09-28 20:44:33 +08:00
yixu
75d73ad086 update 2025-09-28 16:00:01 +08:00
yixu
f540bb6898 update 2025-09-28 12:20:13 +08:00
xiaoaojiao
783c8a0322 update 2025-09-28 10:46:55 +08:00
xiaoaojiao
d24041a04a update 2025-09-28 10:34:14 +08:00
xiaoaojiao
20fc5f5f85 修改海报位置 2025-09-28 09:48:05 +08:00
yixu
7af856992f update 2025-09-26 17:24:13 +08:00
yixu
b03849d8a1 update 2025-09-26 16:02:39 +08:00
xiaoaojiao
014196ffa0 还原抽奖 2025-09-24 13:55:09 +08:00
xiaoaojiao
2ee6172498 添加排名奖励 2025-09-23 19:33:14 +08:00
yixu
1a8a9d9fd4 update 2025-09-23 18:08:57 +08:00
xiaoaojiao
795ec1d267 merge 2025-09-23 17:49:42 +08:00
xiaoaojiao
5d118abf40 merge 2025-09-23 17:44:11 +08:00
yixu
493ad9c2df update 2025-09-23 17:16:53 +08:00
yixu
0ca1bc5ec7 update 2025-09-23 16:42:45 +08:00
xiaoaojiao
b0d2c9ed1a merge 2025-09-23 16:12:34 +08:00
xiaoaojiao
c402cbc74c merge 2025-09-23 15:49:34 +08:00
xiaoaojiao
a9f8371d0a merge 2025-09-23 15:48:50 +08:00
yixu
414d2ae8b0 update 2025-09-23 15:46:46 +08:00
yixu
90558bb56b update 2025-09-23 15:28:34 +08:00
xiaoaojiao
5ba3ea7560 抽奖修改 2025-09-23 15:00:58 +08:00
xiaoaojiao
3adbe7dfff Merge branch 'master' of http://git.jietuozhidao.com/liuxiang/faceFamilySource 2025-09-23 14:19:02 +08:00
xiaoaojiao
24339e6db0 抽奖效果修改 2025-09-23 14:18:51 +08:00
yixu
1e4244b92d update 2025-09-23 13:10:15 +08:00
yixu
465ac8b15f update 2025-09-23 11:44:49 +08:00
yixu
83a577c29b update 2025-09-22 20:00:08 +08:00
yixu
50e1dc2139 update 2025-09-22 17:36:39 +08:00
xiaoaojiao
dbe781c402 分享增加合成次数 2025-09-19 22:20:26 +08:00
yixu
865a2929b9 update 2025-09-19 21:09:27 +08:00
yixu
a77f622997 update 2025-09-19 20:10:19 +08:00
yixu
d556750b9d update 2025-09-19 18:08:40 +08:00
yixu
e7bf1cb2d2 update 2025-09-19 17:52:58 +08:00
yixu
e911372e20 update 2025-09-19 17:46:37 +08:00
yixu
18043471b5 update 2025-09-19 15:26:39 +08:00
yixu
0354cf289d update 2025-09-19 13:12:03 +08:00
xiaoaojiao
a84770b4c3 merge 2025-09-19 10:37:26 +08:00
xiaoaojiao
7033502a01 merge 2025-09-19 10:11:37 +08:00
xiaoaojiao
756832f300 merge 2025-09-19 10:09:49 +08:00
yixu
3b1860e5af update 2025-09-19 07:06:29 +08:00
yixu
f92985b783 fix 2025-09-18 22:42:37 +08:00
yixu
6cc707cc2e fix 2025-09-18 22:18:04 +08:00
xiaoaojiao
23c2c88530 share update 2025-09-18 22:06:35 +08:00
xiaoaojiao
ebcc16086a 优化 2025-09-18 21:57:49 +08:00
yixu
7f22f7a0c7 fix 2025-09-18 21:47:31 +08:00
xiaoaojiao
31b5e048cc Merge branch 'master' of http://git.jietuozhidao.com/liuxiang/faceFamilySource
No changes 11
2025-09-18 21:39:29 +08:00
yixu
260b9f4d08 fix 2025-09-18 21:36:25 +08:00
yixu
936cf0a8e5 fix 2025-09-18 21:28:21 +08:00
yixu
67865139d3 fix 2025-09-18 21:21:52 +08:00
yixu
a9dc9cda79 fix 2025-09-18 20:58:24 +08:00
xiaoaojiao
438bf9eecf 首次合成次数 2025-09-18 17:27:03 +08:00
xiaoaojiao
5f63d4bd1a 优化图片加载 2025-09-18 00:00:13 +08:00
yixu
3d75028615 update 2025-09-17 22:53:05 +08:00
yixu
c5728347e0 update 2025-09-17 22:22:14 +08:00
yixu
097050e5df update 2025-09-17 22:09:32 +08:00
xiaoaojiao
1b89cc367b 修改抽奖动画 2025-09-17 16:38:42 +08:00
yixu
427bdfc0ed update 2025-09-17 15:05:05 +08:00
yixu
4ec6306841 update 2025-09-17 14:51:31 +08:00
xiaoaojiao
50401c0427 merge 2025-09-16 20:49:48 +08:00
yixu
42c6610229 update 2025-09-16 17:19:31 +08:00
yixu
44e9e099b2 update 2025-09-16 16:52:25 +08:00
yixu
9ac7d56e88 update 2025-09-16 16:21:41 +08:00
yixu
c68b99abd5 update 2025-09-16 14:14:43 +08:00
yixu
99795f2913 update 2025-09-16 14:08:20 +08:00
yixu
1b9584393a update 2025-09-16 13:56:43 +08:00
yixu
67a9330fda update 2025-09-16 09:47:46 +08:00
yixu
9de77817b5 update 2025-09-15 20:10:18 +08:00
yixu
dd773f03c0 update 2025-09-15 19:30:25 +08:00
yixu
e9d3c17262 update 2025-09-15 17:24:55 +08:00
yixu
74ea2e77ca update 2025-09-15 17:18:28 +08:00
yixu
c158f92829 update 2025-09-15 16:51:19 +08:00
xiaoaojiao
4c8051e45c todolist 合成照片 2025-09-15 16:22:43 +08:00
yixu
0dd0c10ca4 update 2025-09-15 16:13:57 +08:00
yixu
eeeebb8be8 update 2025-09-15 15:42:50 +08:00
yixu
718997a7f0 update 2025-09-15 14:33:33 +08:00
yixu
f5f9d7c1a1 update 2025-09-15 14:28:19 +08:00
xiaoaojiao
5957191ac0 merge 2025-09-15 11:59:00 +08:00
75 changed files with 3272 additions and 2247 deletions

View File

@@ -9,7 +9,7 @@
<meta content="telephone=no,email=no" name=format-detection> <meta content="telephone=no,email=no" name=format-detection>
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui" /> content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui" />
<title>AI合成全家福迎中秋金饼</title> <title>Ai在一起 金饼送给你</title>
<script> <script>
const isWeixinPlatform = /MicroMessenger/i.test(window.navigator.userAgent) || window.__wxjs_environment === 'miniprogram' const isWeixinPlatform = /MicroMessenger/i.test(window.navigator.userAgent) || window.__wxjs_environment === 'miniprogram'
if (isWeixinPlatform) { if (isWeixinPlatform) {
@@ -71,11 +71,21 @@
background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23ededed' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23ededed' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23ededed' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3CanimateTransform attributeName='transform' begin='0s' dur='1s' type='rotate' values='0 40 40;360 40 40' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E%0A") no-repeat center center; background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23ededed' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23ededed' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23ededed' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23ededed' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3CanimateTransform attributeName='transform' begin='0s' dur='1s' type='rotate' values='0 40 40;360 40 40' repeatCount='indefinite'/%3E%3C/g%3E%3C/svg%3E%0A") no-repeat center center;
background-size: 10% 10%; background-size: 10% 10%;
} }
.preload {
display: none;
}
</style> </style>
<link rel="stylesheet" href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.6.16/weui.min.css"> <link rel="stylesheet" href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.6.16/weui.min.css">
</head> </head>
<body> <body>
<div class="preload">
<img src="./src/assets/images/generate/select-template-bg.webp" alt="">
<img src="./src/assets/images/generate/generate-img-bg.webp" alt="">
<img src="./src/assets/images/generate/photo-squarev2.webp" alt="">
<img src="./src/assets/images/generate/my-photov2.webp" alt="">
</div>
<div id="app"></div> <div id="app"></div>
<script type="text/javascript" src="https://res2.wx.qq.com/open/js/jweixin-1.6.2.js"></script> <script type="text/javascript" src="https://res2.wx.qq.com/open/js/jweixin-1.6.2.js"></script>
<script type="text/javascript" src="https://res.wx.qq.com/t/wx_fed/weui.js/res/1.2.19/weui.min.js"></script> <script type="text/javascript" src="https://res.wx.qq.com/t/wx_fed/weui.js/res/1.2.19/weui.min.js"></script>
@@ -135,7 +145,7 @@
var _hmt = _hmt || []; var _hmt = _hmt || [];
(function () { (function () {
var hm = document.createElement("script"); var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?71eeb5d8fcd3c242670077b6398b3a0d"; hm.src = "https://hm.baidu.com/hm.js?eea1d73562644a65f05fa3b1c04c3894";
var s = document.getElementsByTagName("script")[0]; var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s); s.parentNode.insertBefore(hm, s);
})(); })();

View File

@@ -12,6 +12,7 @@
"@element-plus/icons-vue": "^2.3.2", "@element-plus/icons-vue": "^2.3.2",
"canvas-confetti": "^1.9.3", "canvas-confetti": "^1.9.3",
"element-plus": "^2.11.1", "element-plus": "^2.11.1",
"face-api.js": "^0.22.2",
"gsap": "^3.13.0", "gsap": "^3.13.0",
"howler": "^2.2.4", "howler": "^2.2.4",
"mitt": "^3.0.1", "mitt": "^3.0.1",

71
pnpm-lock.yaml generated
View File

@@ -17,6 +17,9 @@ importers:
element-plus: element-plus:
specifier: ^2.11.1 specifier: ^2.11.1
version: 2.11.1(vue@3.5.20) version: 2.11.1(vue@3.5.20)
face-api.js:
specifier: ^0.22.2
version: 0.22.2
gsap: gsap:
specifier: ^3.13.0 specifier: ^3.13.0
version: 3.13.0 version: 3.13.0
@@ -425,67 +428,56 @@ packages:
resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.50.0': '@rollup/rollup-linux-arm-musleabihf@4.50.0':
resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==} resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.50.0': '@rollup/rollup-linux-arm64-gnu@4.50.0':
resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.50.0': '@rollup/rollup-linux-arm64-musl@4.50.0':
resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==} resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.50.0': '@rollup/rollup-linux-loongarch64-gnu@4.50.0':
resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-gnu@4.50.0': '@rollup/rollup-linux-ppc64-gnu@4.50.0':
resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.50.0': '@rollup/rollup-linux-riscv64-gnu@4.50.0':
resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.50.0': '@rollup/rollup-linux-riscv64-musl@4.50.0':
resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.50.0': '@rollup/rollup-linux-s390x-gnu@4.50.0':
resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.50.0': '@rollup/rollup-linux-x64-gnu@4.50.0':
resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==} resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.50.0': '@rollup/rollup-linux-x64-musl@4.50.0':
resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==} resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl]
'@rollup/rollup-openharmony-arm64@4.50.0': '@rollup/rollup-openharmony-arm64@4.50.0':
resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==}
@@ -517,6 +509,10 @@ packages:
'@sxzz/popperjs-es@2.11.7': '@sxzz/popperjs-es@2.11.7':
resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
'@tensorflow/tfjs-core@1.7.0':
resolution: {integrity: sha512-uwQdiklNjqBnHPeseOdG0sGxrI3+d6lybaKu2+ou3ajVeKdPEwpWbgqA6iHjq1iylnOGkgkbbnQ6r2lwkiIIHw==}
engines: {yarn: '>= 1.3.2'}
'@types/estree@1.0.8': '@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
@@ -526,9 +522,21 @@ packages:
'@types/lodash@4.17.20': '@types/lodash@4.17.20':
resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==}
'@types/offscreencanvas@2019.3.0':
resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==}
'@types/seedrandom@2.4.27':
resolution: {integrity: sha512-YvMLqFak/7rt//lPBtEHv3M4sRNA+HGxrhFZ+DQs9K2IkYJbNwVIb8avtJfhDiuaUBX/AW0jnjv48FV8h3u9bQ==}
'@types/web-bluetooth@0.0.16': '@types/web-bluetooth@0.0.16':
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
'@types/webgl-ext@0.0.30':
resolution: {integrity: sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==}
'@types/webgl2@0.0.4':
resolution: {integrity: sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==}
'@vitejs/plugin-vue-jsx@3.1.0': '@vitejs/plugin-vue-jsx@3.1.0':
resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==} resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
@@ -740,6 +748,9 @@ packages:
resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==}
engines: {node: ^18.19.0 || >=20.5.0} engines: {node: ^18.19.0 || >=20.5.0}
face-api.js@0.22.2:
resolution: {integrity: sha512-9Bbv/yaBRTKCXjiDqzryeKhYxmgSjJ7ukvOvEBy6krA0Ah/vNBlsf7iBNfJljWiPA8Tys1/MnB3lyP2Hfmsuyw==}
fdir@6.5.0: fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
@@ -889,6 +900,10 @@ packages:
engines: {node: ^18 || >=20} engines: {node: ^18 || >=20}
hasBin: true hasBin: true
node-fetch@2.1.2:
resolution: {integrity: sha512-IHLHYskTc2arMYsHZH82PVX8CSKT5lzb7AXeyO06QnjGDKtkv+pv3mEki6S7reB/x1QPo+YPxQRNEVgR5V/w3Q==}
engines: {node: 4.x || >=6.0.0}
node-releases@2.0.19: node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
@@ -986,6 +1001,9 @@ packages:
resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
engines: {node: '>=18'} engines: {node: '>=18'}
seedrandom@2.4.3:
resolution: {integrity: sha512-2CkZ9Wn2dS4mMUWQaXLsOAfGD+irMlLEeSP3cMxpGbgyOOzJGFa+MWCOMTOCMyZinHRPxyOj/S/C57li/1to6Q==}
semver@6.3.1: semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true hasBin: true
@@ -1041,6 +1059,9 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
unicorn-magic@0.3.0: unicorn-magic@0.3.0:
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
engines: {node: '>=18'} engines: {node: '>=18'}
@@ -1579,6 +1600,15 @@ snapshots:
'@sxzz/popperjs-es@2.11.7': {} '@sxzz/popperjs-es@2.11.7': {}
'@tensorflow/tfjs-core@1.7.0':
dependencies:
'@types/offscreencanvas': 2019.3.0
'@types/seedrandom': 2.4.27
'@types/webgl-ext': 0.0.30
'@types/webgl2': 0.0.4
node-fetch: 2.1.2
seedrandom: 2.4.3
'@types/estree@1.0.8': {} '@types/estree@1.0.8': {}
'@types/lodash-es@4.17.12': '@types/lodash-es@4.17.12':
@@ -1587,8 +1617,16 @@ snapshots:
'@types/lodash@4.17.20': {} '@types/lodash@4.17.20': {}
'@types/offscreencanvas@2019.3.0': {}
'@types/seedrandom@2.4.27': {}
'@types/web-bluetooth@0.0.16': {} '@types/web-bluetooth@0.0.16': {}
'@types/webgl-ext@0.0.30': {}
'@types/webgl2@0.0.4': {}
'@vitejs/plugin-vue-jsx@3.1.0(vite@7.1.3)(vue@3.5.20)': '@vitejs/plugin-vue-jsx@3.1.0(vite@7.1.3)(vue@3.5.20)':
dependencies: dependencies:
'@babel/core': 7.28.3 '@babel/core': 7.28.3
@@ -1888,6 +1926,11 @@ snapshots:
strip-final-newline: 4.0.0 strip-final-newline: 4.0.0
yoctocolors: 2.1.2 yoctocolors: 2.1.2
face-api.js@0.22.2:
dependencies:
'@tensorflow/tfjs-core': 1.7.0
tslib: 1.14.1
fdir@6.5.0(picomatch@4.0.3): fdir@6.5.0(picomatch@4.0.3):
optionalDependencies: optionalDependencies:
picomatch: 4.0.3 picomatch: 4.0.3
@@ -1987,6 +2030,8 @@ snapshots:
nanoid@5.1.5: {} nanoid@5.1.5: {}
node-fetch@2.1.2: {}
node-releases@2.0.19: {} node-releases@2.0.19: {}
normalize-wheel-es@1.2.0: {} normalize-wheel-es@1.2.0: {}
@@ -2086,6 +2131,8 @@ snapshots:
run-applescript@7.0.0: {} run-applescript@7.0.0: {}
seedrandom@2.4.3: {}
semver@6.3.1: {} semver@6.3.1: {}
set-blocking@2.0.0: {} set-blocking@2.0.0: {}
@@ -2131,6 +2178,8 @@ snapshots:
totalist@3.0.1: {} totalist@3.0.1: {}
tslib@1.14.1: {}
unicorn-magic@0.3.0: {} unicorn-magic@0.3.0: {}
unplugin-utils@0.3.0: unplugin-utils@0.3.0:

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1 @@
[{"weights":[{"name":"conv0/filters","shape":[3,3,3,16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009007044399485869,"min":-1.2069439495311063}},{"name":"conv0/bias","shape":[16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005263455241334205,"min":-0.9211046672334858}},{"name":"conv1/depthwise_filter","shape":[3,3,16,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004001977630690033,"min":-0.5042491814669441}},{"name":"conv1/pointwise_filter","shape":[1,1,16,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013836609615999109,"min":-1.411334180831909}},{"name":"conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0015159862590771096,"min":-0.30926119685173037}},{"name":"conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002666276225856706,"min":-0.317286870876948}},{"name":"conv2/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015265831292844286,"min":-1.6792414422128714}},{"name":"conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0020280554598453,"min":-0.37113414915168985}},{"name":"conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006100742489683862,"min":-0.8907084034938438}},{"name":"conv3/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016276211832083907,"min":-2.0508026908425725}},{"name":"conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394414279975143,"min":-0.7637432129944072}},{"name":"conv4/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006716050119961009,"min":-0.8059260143953211}},{"name":"conv4/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021875603993733724,"min":-2.8875797271728514}},{"name":"conv4/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0041141652009066415,"min":-0.8187188749804216}},{"name":"conv5/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008423839597141042,"min":-0.9013508368940915}},{"name":"conv5/pointwise_filter","shape":[1,1,256,512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.030007277283014035,"min":-3.8709387695088107}},{"name":"conv5/bias","shape":[512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008402082966823203,"min":-1.4871686851277068}},{"name":"conv8/filters","shape":[1,1,512,25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.028336129469030042,"min":-4.675461362389957}},{"name":"conv8/bias","shape":[25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002268134028303857,"min":-0.41053225912299807}}],"paths":["tiny_face_detector_model-shard1"]}]

View File

@@ -140,7 +140,7 @@ globalToastEvent.on(ToastType.SHOW_ADDRESS, (id) => {
<Address :show="addressShow" :prizeId="activePrizeId" @address-submit="handleAddressSubmitAfter" <Address :show="addressShow" :prizeId="activePrizeId" @address-submit="handleAddressSubmitAfter"
@address-close="addressShow = false"></Address> @address-close="addressShow = false"></Address>
<Ad :show="adShow" @close="adShow = false"></Ad> <Ad :show="adShow" @close="adShow = false"></Ad>
<Lottery :show="lotteryShow" @close="lotteryShow = false"></Lottery> <!-- <Lottery :show="lotteryShow" @close="lotteryShow = false"></Lottery> -->
</template> </template>
<style scoped> <style scoped>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/assets/images/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

View File

@@ -10,23 +10,25 @@
<script setup> <script setup>
import ModalTransition from "./ModalTransition.vue" import ModalTransition from "./ModalTransition.vue"
import { ref } from "vue" import { ref } from "vue"
import { isWeixinPlatform, miniJumpToScene, getMiniPageBtnHack } from "../libs/utils" import { isWeixinPlatform, miniJumpToActive, getMiniPageBtnHack } from "../libs/utils"
const props = defineProps({ const props = defineProps({
show: false, show: false,
}) })
const emit = defineEmits(['close']) const emit = defineEmits(['close'])
const adHtml = ref('') const adHtml = ref('')
//TODO: 这个地址后面要改的 //TODO: 这个地址后面要改的
adHtml.value = getMiniPageBtnHack("/pages/unify/unify?orgId=200282401019674482&targetUrl=%2Fpages%2Fcoupon%2Fcoupons-list") adHtml.value = getMiniPageBtnHack("/pages/retail-act/landing-page/ordinary?id=897432916524553363&orgId=200282401019674482&programId=84796583983972352")
const adGoto = () => { const adGoto = () => {
if (!isWeixinPlatform()) { if (!isWeixinPlatform()) {
weui.alert("请前往「泸州老窖会员中心」小程序进行查询") weui.alert("请前往「泸州老窖会员中心」小程序进行查询")
}else{
miniJumpToActive()
} }
} }
</script> </script>
<style scoped> <style>
.ad-wrapper { .ad-wrapper {
position: relative; position: relative;
width: 100vw; width: 100vw;
@@ -48,7 +50,13 @@ const adGoto = () => {
background-size: 100%; background-size: 100%;
} }
.close { .btn-ad wx-open-launch-weapp#launch-btn{
width: 100%;
height: 100%;
display: block !important;
}
.ad .close {
position: absolute; position: absolute;
width: 8.148148vw; width: 8.148148vw;
height: 8.148148vw; height: 8.148148vw;

View File

@@ -8,36 +8,80 @@ import { globalStore } from "../globalstore.js";
import faceTemplate from "../static/ali_face_template.js"; import faceTemplate from "../static/ali_face_template.js";
import MyPhoto from './MyPhoto.vue' import MyPhoto from './MyPhoto.vue'
import PhotoSquare from './PhotoSquare.vue' import PhotoSquare from './PhotoSquare.vue'
import { loadFaceApiModels, validateFaceInImage } from "../libs/faceValidator.js"
defineProps({ defineProps({
show: true show: true
}) })
onMounted(() => { onMounted(async () => {
await loadFaceApiModels()
}) })
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue'; import { Plus } from '@element-plus/icons-vue';
import { tr } from "element-plus/es/locales.mjs" import { tr } from "element-plus/es/locales.mjs"
const router = useRouter(); const router = useRouter();
// 上传前的校验 // 上传前的校验
const beforeUpload = (file) => { const beforeUpload = (file) => {
// 基础格式校验
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) { if (!isJpgOrPng) {
ElMessage.error('只能上传JPG或PNG格式的图片!'); ElMessage.error('只能上传JPG或PNG格式的图片!');
return false; return false;
} }
const isLt2M = file.size / 1024 / 1024 < 2;
const isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) { if (!isLt2M) {
ElMessage.error('图片大小不能超过2MB!'); ElMessage.error('图片大小不能超过10MB!');
return false; return false;
} }
return true;
return new Promise(async (resolve) => {
const loadingInstance = ElMessage({
message: '正在验证人脸...',
type: 'info',
duration: 0,
showClose: false
});
try {
const faceValidationResult = await validateFaceInImage(file);
loadingInstance.close();
if (!faceValidationResult.success) {
ElMessage({
message: faceValidationResult.message,
type: 'error',
duration: 4000
});
resolve(false);
} else {
ElMessage({
message: faceValidationResult.message,
type: 'success',
duration: 2000
});
resolve(true);
}
} catch (error) {
loadingInstance.close();
console.error('人脸验证出错:', error);
ElMessage({
message: '人脸验证失败,请重试',
type: 'error',
duration: 3000
});
resolve(false);
}
});
}; };
const getTemplateIdsFromUrl = (response, url, index)=> { const getTemplateIdsFromUrl = (response, url, index)=> {
const filename = url.split('/').pop(); const filename = url.split('/').pop();
const matchedTemplate = faceTemplate.find(template => template.name === filename); const matchedTemplate = faceTemplate.find(template => filename.includes(template.name));
if (!matchedTemplate) { if (!matchedTemplate) {
console.error(`No template found for filename: ${filename}`); console.error(`No template found for filename: ${filename}`);
return null; return null;
@@ -113,8 +157,20 @@ const clearUploadFile = (index) => {
if (uploadRefs.value[index]) { if (uploadRefs.value[index]) {
uploadRefs.value[index].clearFiles(); uploadRefs.value[index].clearFiles();
uploadItems.value[index].imageUrl = ''; uploadItems.value[index].imageUrl = '';
// 获取 templateFaceID
uploadedFiles.splice(index, 1); const ids = getTemplateIdsFromUrl(
uploadedFiles[index]?.templateIds,
globalStore.select_template,
index
);
if (!ids || !ids.templateFaceID) return;
// 通过 templateFaceID 定位并删除
const removeIdx = uploadedFiles.findIndex(
file => file.templateIds?.templateFaceID === ids.templateFaceID
);
if (removeIdx !== -1) {
uploadedFiles.splice(removeIdx, 1);
}
} }
}; };
@@ -160,7 +216,7 @@ const generateImage = async (options) => {
try { try {
const loading = weui.loading(); const loading = weui.loading();
const mergeResponse = await fetch('https://huodong2.lzlj.com/api/faceFamily/face/merge', { const response = await fetch('https://huodong2.lzlj.com/api/faceFamily/face/merge', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -169,53 +225,59 @@ const generateImage = async (options) => {
}, },
body: JSON.stringify(formData) body: JSON.stringify(formData)
}); });
const mergeData = await mergeResponse.json(); const data = await response.json()
globalStore.mergeId = mergeData.merge_id; if (response.status == 200 || response.status == 201) {
const navigateToSynthesizedResults = () => { globalStore.mergeId = data.merge_id;
router.push({ const navigateToSynthesizedResults = () => {
name: 'synthesizedResults' router.push({
}) name: 'synthesizedResults'
} })
let index = 0
const max = 4;
const Timer = setInterval(()=>{
if (index >= max) {
loading.hide();
clearInterval(Timer)
} else {
index++
mergeFetch(index)
} }
}, 1000)
let index = 0
const mergeFetch = async (index)=> { const max = 4;
const statusRes = await Request(`face/merge/${mergeData.merge_id}/status`, {}, 'GET', false) const Timer = setInterval(()=>{
if (index >= max) {
if (statusRes.res.status === 200) {
if (statusRes.json.status === 'success') {
displayMyPhotoBtn.value = false;
loading.hide(); loading.hide();
clearInterval(Timer) clearInterval(Timer)
navigateToSynthesizedResults(); } else {
globalStore.result_url = statusRes.json.result_url; index++
mergeFetch(index)
}
}, 1000)
const mergeFetch = async (index)=> {
const statusRes = await Request(`face/merge/${data.merge_id}/status`, {}, 'GET', true)
if (statusRes.res.status === 200) {
if (statusRes.json.status === 'success') {
displayMyPhotoBtn.value = false;
loading.hide();
clearInterval(Timer)
navigateToSynthesizedResults();
globalStore.result_url = statusRes.json.result_url;
} else {
if (index === 4) {
disableScanAnimation.value = true;
displayMyPhotoBtn.value = true;
}
}
} else { } else {
if (index === 4) { if (index === 4) {
disableScanAnimation.value = true; disableScanAnimation.value = true;
displayMyPhotoBtn.value = true; displayMyPhotoBtn.value = true;
} }
} }
} else {
if (index === 4) {
disableScanAnimation.value = true;
displayMyPhotoBtn.value = true;
}
} }
} else {
ElMessage.error(data.message);
loading.hide();
} }
} catch (error) { } catch (error) {
console.error('Merge API error:', error); console.error('Merge API error:', error);
loading.hide();
} }
} }
@@ -278,22 +340,22 @@ const buttonUploadedPosition = (index) => {
const ADJUSTMENT_CONFIG = { const ADJUSTMENT_CONFIG = {
shenxian: { shenxian: {
1:8, 2:6, 3:6, 4:5, 5:5, 6:4 1:16, 2:12, 3:12, 4:10, 5:10, 6:8
}, },
xianxia: { xianxia: {
1:8, 2:6, 3:6, 4:5, 5:5, 6:4 1:11, 2:12, 3:12, 4:10, 5:10, 6:8
}, },
fugu: { fugu: {
1:6, 2:7, 3:7, 4:5, 5:5, 6:4 1:12, 2:14, 3:14, 4:10, 5:10, 6:8
}, },
xinzhongshi: { xinzhongshi: {
1:6, 2:7, 3:4, 4:5, 5:3, 6:4 1:12, 2:14, 3:8, 4:10, 5:6, 6:8
}, },
luying: { luying: {
1:6, 2:7, 3:4, 4:5, 5:3, 6:4 1:12, 2:14, 3:8, 4:10, 5:6, 6:8
}, },
paidui:{ paidui:{
1:6, 2:7, 3:6, 4:5, 5:6, 6:4 1:12, 2:14, 3:12, 4:10, 5:12, 6:8
} }
}; };
@@ -303,7 +365,7 @@ const buttonUploadedPosition = (index) => {
} }
return { return {
top:`${adjustedTop}%`, top:`${adjustedTop}vw`,
left :pos.left , left :pos.left ,
"--item-width" :pos.width "--item-width" :pos.width
}; };
@@ -328,12 +390,14 @@ const imagePosition = (index) => {
return { return {
top : pos.top, top : pos.top,
left : pos.left, left : pos.left,
width: pos.width width: pos.width,
height: pos.width
}; };
}; };
// 自定义上传方法 // 自定义上传方法
const customUpload = async (options) => { const customUpload = async (options) => {
const loading = weui.loading()
const { file, data, onProgress, onSuccess, onError } = options const { file, data, onProgress, onSuccess, onError } = options
try { try {
@@ -348,15 +412,22 @@ const customUpload = async (options) => {
}, },
body: formData body: formData
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
console.log('Success:', data); if (response.status == 200 || response.status == 201) {
loading.hide();
onSuccess(data); onSuccess(data);
} else {
ElMessage.error(data.message);
loading.hide();
}
}) })
.catch((error) => { .catch((error) => {
console.error('Error:', error); loading.hide();
console.error('Error:', error);
}); });
} catch (error) { } catch (error) {
loading.hide();
onError(error) onError(error)
throw error throw error
} }
@@ -387,7 +458,7 @@ import generateImg from '../assets/images/generate-img-bg.webp'
</script> </script>
<template> <template>
<div :show="show"> <div :show="show" class="main">
<div class="home-wrapper" :style="{ <div class="home-wrapper" :style="{
backgroundImage: displayScanModel backgroundImage: displayScanModel
? `url(${imgLoading})` ? `url(${imgLoading})`
@@ -447,12 +518,13 @@ import generateImg from '../assets/images/generate-img-bg.webp'
<!-- 图片预览 --> <!-- 图片预览 -->
<div v-if="item.imageUrl" class="preview-container" :style="{ pointerEvents: displayMyPhotoBtn ? 'none' : 'auto' }"> <div v-if="item.imageUrl" class="preview-container" :style="{ pointerEvents: displayMyPhotoBtn ? 'none' : 'auto' }">
<img <div class="preview-image upload-btn" :style="imagePosition(index + 1)">
:src="item.imageUrl" <img
alt="预览图" :src="item.imageUrl"
class="preview-image upload-btn" alt="预览图"
:style="imagePosition(index + 1)" class="pre-img"
/> />
</div>
<button @click.stop.prevent="clearUploadFile(index)" :style="buttonUploadedPosition(index + 1)" style="position: absolute;"> <button @click.stop.prevent="clearUploadFile(index)" :style="buttonUploadedPosition(index + 1)" style="position: absolute;">
<div :style="{ width: buttonUploadedPosition(index + 1)['--item-width'] }" > <div :style="{ width: buttonUploadedPosition(index + 1)['--item-width'] }" >
<img src="../assets/images/img-uploaded.webp" class="delete-btn upload-img-wrapper" alt="删除图片"> <img src="../assets/images/img-uploaded.webp" class="delete-btn upload-img-wrapper" alt="删除图片">
@@ -477,6 +549,17 @@ import generateImg from '../assets/images/generate-img-bg.webp'
</template> </template>
<style scoped> <style scoped>
.pre-img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
object-position: top;
}
.main {
height: 100%;
overflow-y: auto;
}
.moving-image { .moving-image {
width: 100%; width: 100%;
position: absolute; position: absolute;
@@ -574,16 +657,16 @@ import generateImg from '../assets/images/generate-img-bg.webp'
outline: none !important; outline: none !important;
} }
.home-wrapper { .home-wrapper {
width: 100%; width: 100vw;
height: 92vh; height: 200vw;
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
margin-top: -8vw;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available;
} }
.img-from-template { .img-from-template {
width: 75vw; width: 75vw;
@@ -638,7 +721,7 @@ import generateImg from '../assets/images/generate-img-bg.webp'
} }
.item-4 { .item-4 {
width: 72vw; width: 72vw;
top: 23.5%; top: 48vw;
pointer-events: none; pointer-events: none;
} }
.item-5 { .item-5 {

View File

@@ -40,17 +40,19 @@ const closeTodoList = () => {
<style scoped> <style scoped>
.home-wrapper { .home-wrapper {
width: 100%; width: 100vw;
height: 92vh; height: 100vh;
min-height: 100vh;
background-image: url('../assets/images/generate-img-confirm.webp'); background-image: url('../assets/images/generate-img-confirm.webp');
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center bottom; /* 从底部开始显示,上方可截断 */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: flex-end; /* 内容向底部对齐 */
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available; overflow: hidden; /* 隐藏溢出的上方内容 */
} }
.scene-item { .scene-item {
@@ -60,6 +62,7 @@ const closeTodoList = () => {
overflow: hidden; overflow: hidden;
border: 3px solid transparent; border: 3px solid transparent;
animation: float 4s ease-in-out infinite; animation: float 4s ease-in-out infinite;
z-index: 10;
} }
.scene-item:hover { .scene-item:hover {
@@ -75,14 +78,16 @@ const closeTodoList = () => {
.item-1 { .item-1 {
width: 10vw; width: 10vw;
top: 15%; bottom: 160vw;
right: 4%; right: 4%;
animation-delay: 0s; animation-delay: 0s;
} }
.item-2 { .item-2 {
width: 47vw; width: 47vw;
bottom: 5vw; bottom: max(5vh, 5vw);
left: 50%;
transform: translateX(-50%);
animation-delay: 0s; animation-delay: 0s;
} }
</style> </style>

View File

@@ -1,55 +1,222 @@
<script setup> <script setup>
import { ref, computed, watch, onMounted } from "vue" import { ref, computed, watch, onMounted } from "vue"
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import faceFamily from "../assets/audio/faceFamily.mp3" import bgm from "../assets/audio/bgm.mp3"
import backgroundVideo from "../assets/video/1_stab_chf3_rhea1.mp4"
import MyPhoto from './MyPhoto.vue' import MyPhoto from './MyPhoto.vue'
import PhotoSquare from './PhotoSquare.vue' import PhotoSquare from './PhotoSquare.vue'
import globalToastEvent, { ToastType } from '../globalToastEvent'; import globalToastEvent, { ToastType } from '../globalToastEvent';
import { globalStore } from "../globalstore.js"; import { globalStore } from "../globalstore.js";
import Login from '../components/Login.vue' import Login from '../components/Login.vue'
import { isWeixin, isLogin, getParam, Storage, Request } from "../libs/utils" import { isWeixin, isLogin, getParam, Storage, Request } from "../libs/utils"
import Lottery from '../components/Lottery.vue';
defineProps({ const props = defineProps({
show: true show: true
}) })
const isMusicOn = ref(false); const isMusicOn = ref(false);
const audioElement = ref(null); const audioElement = ref(null);
onMounted(() => { const videoElement = ref(null);
audioElement.value = new Audio(faceFamily); const videoLoaded = ref(false);
tryAutoPlay(); const videoError = ref(false);
}) const lotteryShow = ref(false)
const lotteryType = ref("draw")
const lotteryNoticeData = ref(null)
// 尝试自动播放 // 初始化全局音频实例
const tryAutoPlay = () => { const initGlobalAudio = () => {
// 先加载音频 if (!globalStore.globalAudio) {
audioElement.value.load(); globalStore.globalAudio = new Audio(bgm);
// 尝试播放 globalStore.globalAudio.loop = true; // 设置循环播放
const playPromise = audioElement.value.play(); globalStore.globalAudio.preload = 'auto';
if (playPromise !== undefined) {
playPromise.then(() => { // 监听音频事件
// 自动播放成功 globalStore.globalAudio.addEventListener('play', () => {
isMusicOn.value = true; isMusicOn.value = true;
console.log("自动播放成功"); });
})
.catch(error => { globalStore.globalAudio.addEventListener('pause', () => {
// 自动播放被阻止 isMusicOn.value = false;
console.log("自动播放被阻止,需要用户交互:", error); });
globalStore.globalAudio.addEventListener('ended', () => {
isMusicOn.value = false; isMusicOn.value = false;
audioElement.value.pause();
}); });
} }
audioElement.value = globalStore.globalAudio;
// 同步当前音乐状态
isMusicOn.value = !globalStore.globalAudio.paused;
};
onMounted(() => {
initGlobalAudio();
initVideo();
checkAndPlayAudio();
})
// 检查并播放音频
const checkAndPlayAudio = () => {
if (!audioElement.value) return;
// 如果用户曾经手动静音,则不自动播放
if (globalStore.userMutedMusic) {
console.log('用户曾经手动静音,不自动播放音乐');
isMusicOn.value = false;
return;
}
// 检查音频是否已在播放
if (!audioElement.value.paused) {
console.log('音频已在播放,跳过重复播放');
isMusicOn.value = true;
return;
}
// 只在首次访问或音乐没有被用户手动静音时才尝试自动播放
if (globalStore.isFirstVisitHomePage || !globalStore.userMutedMusic) {
const playPromise = audioElement.value.play();
if (playPromise !== undefined) {
playPromise.then(() => {
// 自动播放成功
isMusicOn.value = true;
globalStore.isFirstVisitHomePage = false;
console.log('自动播放成功');
})
.catch(error => {
// 自动播放被阻止
console.log('自动播放被阻止,需要用户交互:', error);
isMusicOn.value = false;
audioElement.value.pause();
});
}
} else {
// 非首次访问且用户没有手动静音,但音乐当前暂停,则保持暂停状态
isMusicOn.value = false;
}
};
// 初始化视频
const initVideo = () => {
document.addEventListener('WeixinJSBridgeReady',()=>{
videoElement.value && videoElement.value.play()
})
setTimeout(() => {
if (videoElement.value) {
const video = videoElement.value;
// 移动设备视频优化设置
video.muted = true;
video.loop = true;
video.autoplay = true;
video.playsInline = true;
video.setAttribute('webkit-playsinline', 'true');
video.setAttribute('playsinline', 'true');
video.setAttribute('x5-video-player-type', 'h5');
video.setAttribute('x5-video-player-fullscreen', 'false');
// 移动设备特殊处理
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (isMobile) {
video.preload = 'metadata'; // 移动设备使用较小的预加载
// 尝试在用户交互后播放
const playVideo = () => {
video.play().then(() => {
console.log('移动设备视频播放成功');
videoLoaded.value = true;
}).catch(error => {
console.log('移动设备视频播放失败:', error);
videoError.value = true;
});
};
// 在用户点击时尝试播放视频
document.addEventListener('touchstart', playVideo, { once: true });
document.addEventListener('click', playVideo, { once: true });
}
// 按钮交互触发视频播放(用于 iOS 等严格的自动播放限制)
const buttons = document.querySelectorAll('.scene-item');
buttons.forEach(button => {
button.addEventListener('click', () => {
if (video.paused && !videoError.value) {
video.play().catch(error => {
console.log('点击后视频播放失败:', error);
});
}
}, { once: true });
});
// 监听视频事件
video.addEventListener('loadedmetadata', () => {
console.log('视频元数据加载完成');
if (!isMobile) {
video.play().catch(error => {
console.log('PC设备视频自动播放失败:', error);
videoError.value = true;
});
}
});
video.addEventListener('canplay', () => {
videoLoaded.value = true;
videoError.value = false;
});
}
}, 200);
}; };
// 播放/暂停切换 // 播放/暂停切换
const toggleMusicState = () => { const toggleMusicState = () => {
isMusicOn.value = !isMusicOn.value; if (!audioElement.value) {
if (!isMusicOn.value) { initGlobalAudio();
audioElement.value.pause();
} else {
audioElement.value.play().catch(error => {
console.log("播放失败:", error);
});
} }
if (isMusicOn.value) {
// 当前在播放,用户点击静音
audioElement.value.pause();
globalStore.userMutedMusic = true; // 记录用户手动静音
isMusicOn.value = false;
console.log('用户手动静音音乐');
} else {
// 当前暂停,用户点击播放
const playPromise = audioElement.value.play();
if (playPromise !== undefined) {
playPromise.then(() => {
globalStore.userMutedMusic = false; // 用户重新开启音乐,清除静音标记
isMusicOn.value = true;
console.log('用户手动开启音乐');
})
.catch(error => {
console.log('播放失败:', error);
isMusicOn.value = false;
});
}
}
};
// 视频事件处理
const onVideoLoadStart = () => {
console.log('视频开始加载');
};
const onVideoCanPlay = () => {
console.log('视频可以播放');
videoLoaded.value = true;
videoError.value = false;
};
const onVideoLoaded = () => {
console.log('视频数据加载完成');
videoLoaded.value = true;
};
const onVideoError = (event) => {
console.error('视频加载错误:', event);
videoError.value = true;
videoLoaded.value = false;
}; };
const navigateTodoList = () => { const navigateTodoList = () => {
@@ -62,14 +229,18 @@ const handleRule = () => {
globalToastEvent.emit(ToastType.SHOW_RULE) globalToastEvent.emit(ToastType.SHOW_RULE)
} }
const handleLottery = () => { const handleLottery = () => {
if (globalStore.draw_chances <= 0) {
return weui.alert("还没有抽奖机会,快去参加活动吧")
};
lotteryType.value = 'draw'
lotteryNoticeData.value = null
globalToastEvent.emit(ToastType.SHOW_LOTTERY) globalToastEvent.emit(ToastType.SHOW_LOTTERY)
if (globalStore.draw_chances <= 0) return;
globalStore.reducerDrawChances();
} }
const router = useRouter(); const router = useRouter();
const navigateSelectTemplatePage = () => { const navigateSelectTemplatePage = () => {
if (globalStore.game_chances <= 0) return; if (globalStore.game_chances <= 0) return weui.alert('去做任务获得更多参与次数吧');
globalStore.reducerGameChances(); globalStore.reducerGameChances();
router.push({ router.push({
name: 'selectTemplateV2' name: 'selectTemplateV2'
@@ -81,11 +252,11 @@ const myPhotoValue = route.query.myPhotoValue;
const isMyPhotoVisible = ref(false); const isMyPhotoVisible = ref(false);
const isPhotoSquareVisible = ref(false); const isPhotoSquareVisible = ref(false);
const showMyPhoto = () => { const showMyPhoto = () => {
isMyPhotoVisible.value = true; isMyPhotoVisible.value = true;
isPhotoSquareVisible.value = false; isPhotoSquareVisible.value = false;
} }
const showPhotoSquare=()=>{ const showPhotoSquare = () => {
isMyPhotoVisible.value = false; isMyPhotoVisible.value = false;
isPhotoSquareVisible.value = true; isPhotoSquareVisible.value = true;
} }
@@ -94,7 +265,7 @@ watch(() => myPhotoValue, async (newVal) => {
if (!newVal) { if (!newVal) {
return return
} }
isMyPhotoVisible.value = true; isMyPhotoVisible.value = true;
}, { immediate: true }) }, { immediate: true })
@@ -130,7 +301,7 @@ const initUserGameInfos = async (refresh_official, refresh_cap_scan) => {
if (result.res.status === 200) { if (result.res.status === 200) {
globalStore.draw_chances = result.json.draw_chances globalStore.draw_chances = result.json.draw_chances
globalStore.game_chances = result.json.game_chances globalStore.game_chances = result.json.game_chances
globalStore.invitees = result.json.invitees globalStore.first_share_today = result.json.first_share_today
globalStore.followed_official = result.json.followed_official globalStore.followed_official = result.json.followed_official
globalStore.cap_scan = result.json.cap_scan globalStore.cap_scan = result.json.cap_scan
globalStore.game_chances_view_recipes = result.json.game_chances_view_recipes globalStore.game_chances_view_recipes = result.json.game_chances_view_recipes
@@ -142,12 +313,20 @@ const initUserGameInfos = async (refresh_official, refresh_cap_scan) => {
globalToastEvent.emit(ToastType.MOUNTED) globalToastEvent.emit(ToastType.MOUNTED)
} }
} }
const getNotice = async () => {
const result = await Request('notice/latest', {}, "GET")
if (result.json.notification) {
lotteryType.value = 'notice'
lotteryNoticeData.value = result.json.notification
lotteryShow.value = true
}
}
const handleLoginSuccess = async () => { const handleLoginSuccess = async () => {
console.log("已登录") console.log("已登录")
loginShow.value = false loginShow.value = false
await initUserGameInfos(true, true) await initUserGameInfos(true, true)
await getNotice()
} }
if (isLogin()) { if (isLogin()) {
@@ -156,19 +335,70 @@ if (isLogin()) {
userStatus(handleLoginSuccess) userStatus(handleLoginSuccess)
} }
let mergeId = '';
const urlParams = new URLSearchParams(window.location.search);
mergeId = urlParams.get('merge_id');
watch(() => mergeId, async (newVal) => {
if (!newVal) {
return
}
if (newVal) {
isPhotoSquareVisible.value = true;
}
}, { immediate: true })
globalToastEvent.on(ToastType.SHOW_LOTTERY, async () => {
// await initUserGameInfos(false, false);
lotteryShow.value = true
})
globalToastEvent.on(ToastType.INFO_UPDATE, async () => {
initUserGameInfos(false, false)
})
watch(() => lotteryShow.value, async (newVal) => {
initUserGameInfos(true, true);
}, { immediate: true })
import Popup from './Popup.vue'
const isPopupVisible = ref(false);
const navigatePopupPage = () => {
isPopupVisible.value = true;
}
</script> </script>
<template> <template>
<div :show="show"> <div :show="show" class="main">
<div class="home-wrapper"> <div class="home-wrapper">
<!-- 视频背景 -->
<video ref="videoElement" class="background-video" :src="backgroundVideo" autoplay loop muted playsinline
webkit-playsinline preload="metadata" x5-video-player-type="h5" x5-video-player-fullscreen="false"
x5-video-orientation="portraint" @loadstart="onVideoLoadStart" @canplay="onVideoCanPlay" @error="onVideoError"
@loadeddata="onVideoLoaded">
<!-- 为不支持视频的设备提供 fallback -->
<p style="display: none;">您的浏览器不支持视频播放</p>
</video>
<div class="scene-item logo">
<img src="../assets/images/logo.webp" alt="logo">
</div>
<div class="scene-item slogan">
<img src="../assets/images/slogan.webp" alt="slogan">
</div>
<div class="scene-item home-title">
<img src="../assets/images/home-title.webp" alt="slogan">
</div>
<!-- fallback 背景图当视频无法加载时显示 -->
<div v-if="videoError || !videoLoaded" class="fallback-background"></div>
<div class="scene-item item-1" @click="handleLottery" :class="{ 'disabled': globalStore.draw_chances <= 0 }"> <div class="scene-item item-1" @click="handleLottery" :class="{ 'disabled': globalStore.draw_chances <= 0 }">
<img src="../assets/images/lottery.webp" alt="抽奖"> <img src="../assets/images/lottery.webp" alt="抽奖">
<div class="lottery-main"> <div class="lottery-main">
<p class="lottery-value">{{ globalStore.draw_chances }}</p> <p class="lottery-value">{{ globalStore.draw_chances }}</p>
</div> </div>
</div> </div>
<div class="scene-item item-2" @click="navigateSelectTemplatePage" :class="{ 'disabled': globalStore.game_chances <= 0 }"> <div class="scene-item item-2" @click="navigatePopupPage">
<img src="../assets/images/join.webp" alt="立即参与"> <img src="../assets/images/join.webp" alt="立即参与">
<div class="join-main"> <div class="join-main">
<p class="join-value">{{ globalStore.game_chances }}</p> <p class="join-value">{{ globalStore.game_chances }}</p>
@@ -204,29 +434,80 @@ if (isLogin()) {
<MyPhoto @go-photo-square="showPhotoSquare" v-model:show="isMyPhotoVisible" /> <MyPhoto @go-photo-square="showPhotoSquare" v-model:show="isMyPhotoVisible" />
<PhotoSquare @go-my-photo="showMyPhoto" v-model:show="isPhotoSquareVisible" /> <PhotoSquare @go-my-photo="showMyPhoto" v-model:show="isPhotoSquareVisible" />
<Login :show="loginShow" @login-success="handleLoginSuccess" /> <Login :show="loginShow" @login-success="handleLoginSuccess" />
<Lottery :show="lotteryShow" @close="lotteryShow = false" :type="lotteryType" :data="lotteryNoticeData"></Lottery>
<Popup v-model:show="isPopupVisible" />
</template> </template>
<style scoped> <style scoped>
.logo {
top: 4vw;
width: 24vw;
left: 4vw;
}
.slogan {
top: 20vw;
width: 76vw;
}
.home-title {
width: 72vw;
top: 144vw;
}
.main {
height: 100%;
overflow-y: auto;
}
.home-wrapper { .home-wrapper {
width: 100%; width: 100vw;
height: 92vh; height: 200vw;
background-image: url('../assets/images/home-bg.webp');
background-size: cover;
background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available; min-height: -webkit-fill-available;
overflow: hidden;
/* 防止视频溢出 */
}
/* 视频背景样式 */
.background-video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
/* 保持视频比例并填满容器 */
z-index: 0;
/* 置于最底层 */
pointer-events: none;
/* 禁止视频交互,避免影响按钮点击 */
}
/* fallback 背景图 */
.fallback-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('../assets/images/home-bg.webp');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
z-index: -1;
/* 置于视频下方 */
} }
.scene-item { .scene-item {
position: absolute; position: fixed;
cursor: pointer; cursor: pointer;
transition: all 0.4s ease; transition: all 0.4s ease;
overflow: hidden; overflow: hidden;
border: 3px solid transparent;
animation: float 4s ease-in-out infinite; animation: float 4s ease-in-out infinite;
} }
@@ -243,7 +524,7 @@ if (isLogin()) {
.item-1 { .item-1 {
width: 21vw; width: 21vw;
bottom: 0; bottom: 5vw;
left: 0; left: 0;
animation-delay: 0s; animation-delay: 0s;
} }
@@ -255,75 +536,78 @@ if (isLogin()) {
width: 4vw; width: 4vw;
height: 3.5vw; height: 3.5vw;
position: absolute; position: absolute;
top: 1.5vw; top: 1.7vw;
right: 6.6vw; right: 7.3vw;
color: #fff; color: #fff;
} }
.lottery-main .lottery-value { .lottery-main .lottery-value {
font-size: 10px; font-size: 4vw;
} }
.item-2 { .item-2 {
width: 48vw; width: 48vw;
bottom: 0; bottom: 5vw;
animation-delay: 0s; animation-delay: 0s;
} }
.join-main { .join-main {
position: absolute; position: absolute;
top: 3.4vw; top: 3.4vw;
right: 2.6vw; right: -3.5vw;
width: 7vw; width: 13vw;
line-height: 7vw;
text-align: left;
} }
.join-main .join-value { .join-main .join-value {
margin: 0; margin: 0;
color: white; color: white;
text-stroke: 4px #ff0000; text-shadow: -1px -1px 0 #ff0000, 1px -1px 0 #ff0000, -1px 1px 0 #ff0000, 1px 1px 0 #ff0000, 0 0 2px #ff0000;
-webkit-text-stroke: 1px #ff0000; font-size: 5.4vw;
font-size: 24px;
font-weight: 900; font-weight: 900;
} }
.item-3 { .item-3 {
width: 21vw; width: 21vw;
bottom: 0; bottom: 5vw;
right: 0; right: 0;
animation-delay: 0s; animation-delay: 0s;
} }
.item-4 { .item-4 {
width: 11vw; width: 11vw;
top: 1.5%; top: 1.5%;
right: 1.5%; right: 1.5%;
animation-delay: 0s; animation-delay: 0s;
} }
.item-5 { .item-5 {
width: 11vw; width: 11vw;
top: 1.5%; top: 1.5%;
right: 1.5%; right: 1.5%;
animation-delay: 0s; animation-delay: 0s;
} }
.item-6 { .item-6 {
width: 14.5vw; width: 14.5vw;
top: 8%; top: 8%;
right: 0; right: 0;
animation-delay: 0s; animation-delay: 0s;
} }
.item-7 { .item-7 {
width: 14.5vw; width: 14.5vw;
top: 13.5%; top: 13.5%;
right: 0; right: 0;
animation-delay: 0s; animation-delay: 0s;
} }
.item-8 { .item-8 {
width: 11vw; width: 11vw;
bottom: 32%; bottom: 32%;
right: 1%; right: 1%;
animation-delay: 0s; animation-delay: 0s;
} }
.item-9 { .item-9 {
width: 11vw; width: 11vw;
bottom: 23%; bottom: 23%;

View File

@@ -5,16 +5,18 @@
<div class="guangyun" ref="guangyunRef"></div> <div class="guangyun" ref="guangyunRef"></div>
<div class="lottery-scene" ref="sceneRef"> <div class="lottery-scene" ref="sceneRef">
<div class="lottery-card" ref="cardRef"> <div class="lottery-card" ref="cardRef">
<div class="lottery-face">
<img :src="lotteryFaceUrl" alt="">
</div>
<div class="lottery-prize"> <div class="lottery-prize">
<div class="lottery-title" ref="titleRef"></div> <div class="lottery-title" :class="props.type === 'notice' && 'notice'" ref="titleRef"
<div class="lottery-image" :class="activePrizeData.prize_code"></div> v-show="activePrizeData.prize_code !== 'NO'"></div>
<div class="lottery-name">{{ activePrizeData.name }}</div> <div class="lottery-desc" v-show="props.type === 'notice'">
在刚刚结束的打榜活动中成功斩获<br /><strong>[{{ activePrizeData.rank }}]</strong>
</div>
<div class="lottery-image" :class="'USER_' + activePrizeData.prize_code" ref="lotteryImageRef"></div>
<div class="lottery-name" v-show="activePrizeData.prize_code !== 'NO'">{{ activePrizeData.prize_name }}
</div>
<div class="lottery-btngroup" v-show="btngroupShow"> <div class="lottery-btngroup" v-show="btngroupShow">
<div class="btn-more" @click="handleBtnMore"></div> <div class="btn-more" @click="handleBtnMore"></div>
<div class="btn-kaixin" @click="handleLotteryAction"></div> <div class="btn-kaixin" @click="handleLotteryAction" v-if="activePrizeData.prize_code !== 'NO'"></div>
</div> </div>
</div> </div>
</div> </div>
@@ -32,15 +34,14 @@ import ModalTransition from "./ModalTransition.vue"
import confetti from "canvas-confetti"; import confetti from "canvas-confetti";
import { Request, Sleep } from "../libs/utils" import { Request, Sleep } from "../libs/utils"
import { globalStore } from "@/globalstore"; import { globalStore } from "@/globalstore";
//TODO: globalStore.result_url 这里这张图要用用户分享那张图 import getUserPicture from "../libs/getUserPicture";
// import lotteryFace from "../assets/images/haibao-cover.webp"
const lotteryFace = globalStore.result_url; // const lotteryFaceUrl = ref('')
const lotteryFaceUrl = ref(lotteryFace)
const cardRef = ref(null) const cardRef = ref(null)
const sceneRef = ref(null) const sceneRef = ref(null)
const guangRef = ref(null) const guangRef = ref(null)
const guangyunRef = ref(null) const guangyunRef = ref(null)
const lotteryImageRef = ref(null)
const titleRef = ref(null) const titleRef = ref(null)
const activePrizeData = ref({}) const activePrizeData = ref({})
const btngroupShow = ref(false) const btngroupShow = ref(false)
@@ -48,14 +49,13 @@ const btngroupShow = ref(false)
gsap.registerPlugin() gsap.registerPlugin()
const props = defineProps({ const props = defineProps({
show: false, show: false,
type: "draw",
data: null
}) })
const emit = defineEmits(['close']) const emit = defineEmits(['close'])
let interval = null let interval = null
const PRIZE_LIST = ['TJGJ', 'XINCHUN_WEIZUN', 'TEQU_JL_52_60Y_100ML_2', 'LZLJ_TEQU_LZH_52_100ML_2', 'HEIGAI_42_GPJ_500ML', 'DZCZ', 'DZSCZ', '66_POINTS', 'NO']
let gsapCtx = null let gsapCtx = null
let shakeTimeline = null
let PRIZEDATA = null let PRIZEDATA = null
const closeThis = () => { const closeThis = () => {
@@ -67,9 +67,15 @@ const handleBtnMore = () => {
closeThis() closeThis()
globalToastEvent.emit(ToastType.SHOW_AD) globalToastEvent.emit(ToastType.SHOW_AD)
} }
const handleLotteryAction = () => { const readNotice = async () => {
await Request(`notice/read`, { id: activePrizeData.value.noticeId })
}
const handleLotteryAction = async () => {
//实物 //实物
closeThis() closeThis()
if (props.type !== 'draw') {
await readNotice()
}
if (activePrizeData.value.coupon_type === 'scene') { if (activePrizeData.value.coupon_type === 'scene') {
globalToastEvent.emit(ToastType.SHOW_ADDRESS, activePrizeData.value.id) globalToastEvent.emit(ToastType.SHOW_ADDRESS, activePrizeData.value.id)
} }
@@ -97,17 +103,10 @@ const initAnimateStyle = () => {
}); });
} }
// 创建一个时间线,添加关键帧,并循环 gsap.set(lotteryImageRef.value, { scale: 0 })
shakeTimeline = gsap.timeline({ repeat: -1, paused: true });
shakeTimeline.to(cardRef.value, { duration: 0, x: 0, y: 0 }); // 初始位置
keyframes.forEach(keyframe => {
shakeTimeline.to(cardRef.value, keyframe);
});
shakeTimeline.to(cardRef.value, { duration: 0.1, x: 0, y: 0 })
gsap.set(guangyunRef.value, { scale: 0, opacity: 1 }) gsap.set(guangyunRef.value, { scale: 0, opacity: 1 })
gsap.set(titleRef.value, { scaleY: 0 }) gsap.set(titleRef.value, { scaleY: 0 })
gsap.set(sceneRef.value, { scale: .5 }) gsap.set(sceneRef.value, { scale: .2 })
gsap.set(cardRef.value, { rotateY: 0 }) gsap.set(cardRef.value, { rotateY: 0 })
btngroupShow.value = false btngroupShow.value = false
} }
@@ -117,25 +116,66 @@ watch(() => props.show, async (newVal) => {
return return
} }
shakeTimeline.play() const loading = weui.loading()
let lottteryResult = null
if (props.type === 'draw') {
lottteryResult = await Request("lottery/draw", { pool: 'game', consume_type: 'points' })
// 监听请求失败,关闭组件
if (!lottteryResult || !lottteryResult.res || (lottteryResult.res.status !== 200 && lottteryResult.res.status !== 201)) {
emit('close')
loading.hide()
return
}
} else {
if (!props.data) {
weui.alert("获取排名奖励出错,请刷新页面重试")
emit('close')
loading.hide()
return
}
lottteryResult = {
res: { status: 200 },
json: {
noticeId: props.data.id,
id: props.data.data.prize.id,
prize_code: props.data.data.prize.prize_code,
prize_name: props.data.data.prize.name,
coupon_type: props.data.data.prize.scene,
rank: props.data.data.rank
}
}
}
// const userPicture = await getUserPicture()
// const preimg = async() => {
// new Promise((resolve) => {
// const img = new Image()
// img.onload = () => resolve(img)
// img.src = userPicture
// })
// }
// await preimg()
// lotteryFaceUrl.value = userPicture
//TODO: 延时测试,上限删掉 //TODO: 延时测试,上限删掉
// await Sleep(2000) // await Sleep(20000)
shakeTimeline.pause()
const lottteryResult = await Request("lottery/draw", { pool: 'game', consume_type: 'points' })
// TODO: 测试数据 // TODO: 测试数据
// const lottteryResult = { // lottteryResult = {
// res: { status: 200 }, // res: { status: 200 },
// json: { // json: {
// id: 0, // id: 0,
// code: "HEIGAI_42_GPJ_500ML", // code: "xxx",
// prize_code: 'HEIGAI_42_GPJ_500ML', // prize_code: 'xxx',
// coupon_type: "scene", // coupon_type: "scene",
// name: "泸州老窖的一瓶酒" // name: "泸州老窖的一瓶酒"
// } // }
// } // }
loading.hide()
if (lottteryResult.res.status !== 200) { if (lottteryResult.res.status !== 200) {
emit('close') emit('close')
return return
@@ -160,26 +200,23 @@ watch(() => props.show, async (newVal) => {
} }
}); });
prizeshowTime.to(sceneRef.value, {
duration: .4, prizeshowTime.to([sceneRef.value], {
scale: .2, duration: 2.5,
})
prizeshowTime.to(sceneRef.value, {
duration: 1,
scale: 1, scale: 1,
opacity: 1, opacity: 1,
ease: "power4.out" ease: "power4.inOut"
}) })
prizeshowTime.to(lotteryImageRef.value, {
duration: 1,
scale: 1,
ease: "power4.inOut"
}, "-=1.5")
prizeshowTime.to(guangyunRef.value, { prizeshowTime.to(guangyunRef.value, {
duration: 1.5, duration: 1.5,
scale: 2, scale: 2,
}, "-=1") }, "-=1")
prizeshowTime.to(cardRef.value, {
rotateY: 180 * 3,
duration: 1,
}, "-=1.4")
prizeshowTime.to(titleRef.value, { prizeshowTime.to(titleRef.value, {
scaleY: 1, scaleY: 1,
ease: "elastic.out(1,0.3)" ease: "elastic.out(1,0.3)"
@@ -209,12 +246,49 @@ watch(() => props.show, async (newVal) => {
}) })
onUnmounted(() => { onUnmounted(() => {
shakeTimeline = null
gsapCtx && gsapCtx.revert() gsapCtx && gsapCtx.revert()
}) })
</script> </script>
<style scoped> <style scoped>
.lottery-image.USER_LZ_ZQ_DZJ {
background-image: url("../assets/images/USER_LZ_ZQ_DZJ.webp");
}
.lottery-image.USER_HG_42_GPJ_500ML {
background-image: url("../assets/images/USER_HG_42_GPJ_500ML.webp");
}
.lottery-image.USER_QLL_MH {
background-image: url("../assets/images/USER_QLL_MH.webp");
}
.lottery-image.USER_DZSKSJ {
background-image: url("../assets/images/USER_DZSKSJ.webp");
}
.lottery-image.USER_LZ_ZQ_DZJ_LJW {
background-image: url("../assets/images/USER_LZ_ZQ_DZJ_LJW.webp");
}
.lottery-image.USER_NO {
background-size: 60% auto;
background-position: center center;
background-image: url("../assets/images/USER_NO.webp");
}
.lottery-image.USER_LZ_XS_SPZ_30ML {
background-image: url("../assets/images/USER_LZ_XS_SPZ_30ML.webp");
}
.lottery-image.USER_LZ_DZ_JBGJ {
background-image: url("../assets/images/USER_LZ_DZ_JBGJ.webp");
}
.lottery-image.USER_LZ_DZ_JBGJ_LZ_ZQ_DZJ {
background-image: url("../assets/images/USER_LZ_DZ_JBGJ_LZ_ZQ_DZJ.webp");
}
.guang, .guang,
.guangyun { .guangyun {
position: absolute; position: absolute;
@@ -243,7 +317,7 @@ onUnmounted(() => {
position: absolute; position: absolute;
top: 24vw; top: 24vw;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%) !important;
width: 65.462963vw; width: 65.462963vw;
height: 19.907407vw; height: 19.907407vw;
background-image: url("../assets/images/lottery-title.webp"); background-image: url("../assets/images/lottery-title.webp");
@@ -251,12 +325,40 @@ onUnmounted(() => {
background-size: 100%; background-size: 100%;
} }
.lottery-title.notice {
width: 39.259259vw;
height: 7.12963vw;
background-image: url("../assets/images/notice-title.webp");
}
.lottery-desc {
position: absolute;
top: 32vw;
left: 50%;
transform: translateX(-50%) !important;
width: 81vw;
font-size: 5vw;
font-weight: 700;
text-align: center;
color: rgb(255, 255, 255);
text-shadow:
0 0 0.37037vw #ff0000,
0 0 0.740741vw #ff0000,
0 0 1.111111vw #ff0000,
0.092593vw 0.092593vw 0 #ff0000,
-0.092593vw -0.092593vw 0 #ff0000;
}
.lottery-name { .lottery-name {
position: absolute; position: absolute;
bottom: 18vw; bottom: 18vw;
text-align: center; text-align: center;
width: 100%; width: 80%;
font-size: 6vw; left: 10%;
font-size: 4.3vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 700; font-weight: 700;
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
text-shadow: text-shadow:
@@ -272,7 +374,7 @@ onUnmounted(() => {
bottom: -24vw; bottom: -24vw;
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-evenly;
} }
.btn-more { .btn-more {
@@ -299,6 +401,7 @@ onUnmounted(() => {
background-position: center bottom; background-position: center bottom;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: auto 100%; background-size: auto 100%;
background-origin: 50% 100%;
} }
.lottery-image.HEIGAI_42_GPJ_500ML { .lottery-image.HEIGAI_42_GPJ_500ML {
@@ -342,12 +445,10 @@ onUnmounted(() => {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
transform-style: preserve-3d;
top: -14vw;
} }
.lottery-card.flip {
transform: rotateY(180deg);
}
.lottery-face { .lottery-face {
position: absolute; position: absolute;
@@ -372,8 +473,6 @@ onUnmounted(() => {
background-image: url("../assets/images/prize-bg.webp"); background-image: url("../assets/images/prize-bg.webp");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100%; background-size: 100%;
backface-visibility: hidden;
transform: rotateY(180deg);
} }
.close { .close {

View File

@@ -21,7 +21,7 @@ const goBack = () => {
const imageList = ref([]) const imageList = ref([])
const displayZhuli = ref(false); const displayZhuli = ref(false);
const fetchImages = async () => { const fetchImages = async () => {
try { try {
const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square'); const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square');
url.searchParams.append('my_only', '1'); url.searchParams.append('my_only', '1');
@@ -34,27 +34,65 @@ const fetchImages = async () => {
} }
}) })
const data = await response.json() const data = await response.json()
console.log('Success:', data) if (response.status == 200 || response.status == 201) {
images.value = data.data; // 只保留 status=processing 或 result_url 不为空的记录
const foundItem = data.data.find(item => item.is_public === true); images.value = data.data.filter(item => item.status === 'processing' || item.result_url);
if (foundItem) { // 测试数据
globalStore.result_url = foundItem.result_url; // images.value = [
displayZhuli.value = true; // {
} else { // "id": 186,
displayZhuli.value = false; // "status": "success",
} // "error_message": null,
imageList.value = data; // "is_public": false,
// "result_url": "https:\/\/lzlj123.oss-cn-shanghai.aliyuncs.com\/face-merged\/20250919\/face-merge-717b50c3-9c38-4713-929a-49d072b90ab6.jpg",
const hasPublicImage = images.value.some(item => item.is_public); // "likes_count": 0,
if (hasPublicImage) { // "created_at": "2025-09-19T04:30:26.000000Z",
globalStore.chartsBattle = true; // "user_name": "\u4f9d\u65ed"
const publicIndex = images.value.findIndex(item => item.is_public); // },
if (publicIndex !== -1) { // {
activeBorders.value = activeBorders.value.map((_, index) => index === publicIndex); // "id": 155,
// "status": "success",
// "error_message": null,
// "is_public": false,
// "result_url": "https:\/\/lzlj123.oss-cn-shanghai.aliyuncs.com\/face-merged\/20250917\/face-merge-1d2ddf63-b029-48f8-b0b7-de7643dbd184.jpg",
// "likes_count": 0,
// "created_at": "2025-09-17T13:37:08.000000Z",
// "user_name": "\u4f9d\u65ed"
// },
// {
// "id": 156,
// "status": "success",
// "error_message": null,
// "is_public": false,
// "result_url": "https:\/\/lzlj123.oss-cn-shanghai.aliyuncs.com\/face-merged\/20250917\/face-merge-eda32a25-4244-4041-8db8-25aeb41f5a2f.jpg",
// "likes_count": 2,
// "created_at": "2025-09-17T13:40:49.000000Z",
// "user_name": "\u4f9d\u65ed"
// }
// ]
const foundItem = images.value.find(item => item.is_public === true);
if (foundItem) {
globalStore.result_url = foundItem.result_url;
globalStore.mergeId = foundItem.id
displayZhuli.value = true;
} else {
displayZhuli.value = false;
} }
imageList.value = images.value;
const hasPublicImage = images.value.some(item => item.is_public);
if (hasPublicImage) {
globalStore.chartsBattle = true;
const publicIndex = images.value.findIndex(item => item.is_public);
if (publicIndex !== -1) {
activeBorders.value = activeBorders.value.map((_, index) => index === publicIndex);
}
}
} else {
ElMessage.error(data.message);
} }
} catch (error) { } catch (error) {
console.error('Error:', error) console.error('Error:', error)
} }
} }
@@ -68,23 +106,27 @@ watch(() => props.show, async (newVal) => {
// 图片数据 // 图片数据
const images = ref([]); const images = ref([]);
import defaultBorderImage from '../assets/images/my-photo-border.webp'; import defaultBorderImage from '../assets/images/my-photo-border.webp';
import activeBorderImage from '../assets/images/my-photo-selected-border.webp'; import activeBorderImage from '../assets/images/my-photo-selected-border.webp';
import inActiveBorderImage from '../assets/images/no-btn.webp';
const activeBorders = ref(images.value.map(() => false)); const activeBorders = ref(images.value.map(() => false));
let mergeId = '';
// 切换边框状态 // 切换边框状态
const toggleBorder = (item, index) => { const toggleBorder = (item, index) => {
activeBorders.value = activeBorders.value.map(() => false); activeBorders.value = activeBorders.value.map(() => false);
// 如果没有打榜点击切换图片时把当前背景图赋值给globalStore.result_url做为最新的背景图 // 如果没有打榜点击切换图片时把当前背景图赋值给globalStore.result_url做为最新的背景图
globalStore.result_url = item.result_url; globalStore.result_url = item.result_url;
activeBorders.value[index] = true; activeBorders.value[index] = true;
mergeId = item.id; globalStore.mergeId = item.id;
}; };
const handleDabangClick = () => { const handleDabangClick = () => {
fetch(`https://huodong2.lzlj.com/api/faceFamily/face/publish/${mergeId}`, { if (!globalStore.mergeId) {
weui.alert("请先合成照片!")
return false;
}
fetch(`https://huodong2.lzlj.com/api/faceFamily/face/publish/${globalStore.mergeId}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -93,19 +135,21 @@ const handleDabangClick = () => {
}, },
body: {} body: {}
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
ElMessage.success('打榜成功!'); if (response.status == 200 || response.status == 201) {
displayZhuli.value = true; ElMessage.success('打榜成功!');
console.log('Success:', data); displayZhuli.value = true;
globalStore.chartsBattle = true; globalStore.chartsBattle = true;
return { success: true, data }; return { success: true, data };
}) } else {
.catch((error) => { ElMessage.error(data.message);
ElMessage.success('打榜失败!'); }
console.error('Error:', error); })
return { success: false, error }; .catch((error) => {
}); ElMessage.error('打榜失败!');
return { success: false, error };
});
}; };
const handleZhuliClick = () => { const handleZhuliClick = () => {
@@ -113,33 +157,47 @@ const handleZhuliClick = () => {
console.log('助力被点击'); console.log('助力被点击');
}; };
const downloadGenerateImg = (item) => {
openHaibao(item);
console.log('下载被点击');
}
import haibaoCoverBorderNoTitle from "../assets/images/haibao-cover-no-title.webp"
import haibaoCoverBorderSuccess from "../assets/images/haibao-cover-sucess.webp";
import failedImg from '../assets/images/failed.webp'; import failedImg from '../assets/images/failed.webp';
const getGenerateImgStatus = async (item)=> { import processingImg from '../assets/images/processing.webp';
const getGenerateImgStatus = async (item) => {
const loading = weui.loading()
fetch(`https://huodong2.lzlj.com/api/faceFamily/face/merge/${item.id}/status`, { fetch(`https://huodong2.lzlj.com/api/faceFamily/face/merge/${item.id}/status`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Authorization': `Bearer ${Storage.get("userinfos").api_token}` 'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
} }
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
console.log('Success:', data); loading.hide();
if (data.status = 'failed') { if (response.status == 200 || response.status == 201) {
item.result_url = failedImg; if (data.status = 'failed') {
} else if (data.status = 'success') { item.result_url = failedImg;
item.result_url = data.result_url; } else if (data.status = 'success') {
item.result_url = data.result_url;
}
} else {
ElMessage.error(data.message);
} }
}) })
.catch((error) => { .catch((error) => {
console.error('Error:', error); loading.hide();
}); ElMessage.error('获取状态失败!');
});
} }
const getBackgroundImage = (item) => { const getBackgroundImage = (item) => {
if (item.result_url) { if (item.result_url) {
return item.result_url; return `${item.result_url}?x-oss-process=image/resize,w_400/format,webp/quality,q_80`;
} else { } else {
return item.result_url = failedImg; return item.result_url = processing;
} }
}; };
@@ -149,7 +207,7 @@ import Haibao from "@/libs/haibao";
import mask from "../assets/images/haibao-mask.webp"; import mask from "../assets/images/haibao-mask.webp";
import haibaoCoverBorder from "../assets/images/haibao-cover.webp"; import haibaoCoverBorder from "../assets/images/haibao-cover.webp";
import bg from "../assets/images/haibao-bg.webp" import bg from "../assets/images/haibao-bg.webp"
const loadImage = (src)=> { const loadImage = (src) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const img = new Image(); const img = new Image();
img.crossOrigin = "Anonymous"; img.crossOrigin = "Anonymous";
@@ -166,50 +224,94 @@ const userhaibaoCover = computed(() => {
return { backgroundImage: `url(${userHaibaoUrl.value})` } return { backgroundImage: `url(${userHaibaoUrl.value})` }
}) })
const openHaibao = (e) => { const openHaibao = (item) => {
haibaoShow.value = true haibaoShow.value = true
handleHaibao() handleHaibao(item)
} }
const handleHaibao = async () => { const handleHaibao = async (item) => {
if (haibaoUrl.value) {
return
}
const loading = weui.loading() const loading = weui.loading()
const infos = Storage.get("userinfos") const infos = Storage.get("userinfos")
const haibaoCover = new Haibao(951, 1607) const haibaoCover = new Haibao(951, 1607)
const userPicture = await loadImage(globalStore.result_url) let userPicture = '';
haibaoCover.add(userPicture, 0, 50, 951, 1698) if (item && item.result_url) {
haibaoCover.add(mask, 10, 100) userPicture = await loadImage(item.result_url)
haibaoCover.add(haibaoCoverBorder, 0, 0) haibaoCover.add(userPicture, 0, 50, 951, 1698)
haibaoCover.draw('destination-in').then(() => { haibaoCover.add(mask, 10, 100)
haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => { haibaoCover.add(haibaoCoverBorderSuccess, 0, 0)
userHaibaoUrl.value = url haibaoCover.draw('destination-in').then(() => {
haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => {
userHaibaoUrl.value = url
const haibaoSave = new Haibao(1080, 2160) const haibaoSave = new Haibao(1080, 2160)
const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${infos.merge_id}`, 200, 200) const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${globalStore.mergeId}`, 200, 200)
haibaoSave.add(url, 62, 350) haibaoSave.add(bg, 0, 0)
haibaoSave.add(bg, 0, 0) haibaoSave.add(url, 64, 250)
haibaoSave.add(qrcode, 115, 1875) haibaoSave.add(qrcode, 127, 1860)
haibaoSave.draw().then(() => { haibaoSave.draw().then(() => {
haibaoSave.text(infos.nickname, haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#ffee6f' }) haibaoSave.text(infos.nickname + '的全家福', haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#fcf2b3' })
haibaoSave.generate({ mimeType: 'image/png' }).then(url => { haibaoSave.generate({ mimeType: 'image/png' }).then(url => {
haibaoUrl.value = url if (item && item.result_url) {
loading.hide() haibaoUrl.value = item.result_url
}
loading.hide()
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
})
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
weui.alert("海报生成失败,请重新生成") weui.alert("海报生成失败,请重新生成")
loading.hide() loading.hide()
}) })
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
}) })
}) })
}) } else {
userPicture = await loadImage(globalStore.result_url)
const haibaoCoverNoTitleBorder = new Haibao(951, 1607)
haibaoCoverNoTitleBorder.add(userPicture, 0, 50, 951, 1698)
haibaoCoverNoTitleBorder.add(mask, 10, 100)
haibaoCoverNoTitleBorder.add(haibaoCoverBorder, 0, 0)
haibaoCoverNoTitleBorder.draw('destination-in').then(() => {
haibaoCoverNoTitleBorder.generate({ mimeType: 'image/png' }).then(async (url) => {
userHaibaoUrl.value = url
})
})
if (!globalStore.first_share_today) {
Request(`face/share/${globalStore.mergeId}`)
}
const haibaoCoverNoTitle = new Haibao(951, 1607)
haibaoCoverNoTitle.add(userPicture, 0, 50, 951, 1698)
haibaoCoverNoTitle.add(mask, 10, 100)
haibaoCoverNoTitle.add(haibaoCoverBorderNoTitle, 0, 0)
haibaoCoverNoTitle.draw('destination-in').then(() => {
haibaoCoverNoTitle.generate({ mimeType: 'image/png' }).then(async (url) => {
const haibaoSaveNoTitle = new Haibao(1080, 2160)
const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${globalStore.mergeId}`, 200, 200)
haibaoSaveNoTitle.add(bg, 0, 0)
haibaoSaveNoTitle.add(url, 64, 250)
haibaoSaveNoTitle.add(qrcode, 127, 1860)
haibaoSaveNoTitle.draw().then(() => {
haibaoSaveNoTitle.text(infos.nickname + '的全家福', haibaoSaveNoTitle.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#fcf2b3' })
haibaoSaveNoTitle.generate({ mimeType: 'image/png' }).then(url => {
haibaoUrl.value = url
loading.hide()
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
})
}).catch(err => {
console.log(err)
weui.alert("海报生成失败,请重新生成")
loading.hide()
})
})
})
}
} }
const markers = ref([]); const markers = ref([]);
@@ -217,6 +319,19 @@ markers.value = [
{ x: 0, y: 32, width: 50, height: 14 } { x: 0, y: 32, width: 50, height: 14 }
]; ];
const getBorder = (item, index) => {
if (globalStore.chartsBattle && index !== 0) {
return inActiveBorderImage;
} else {
if ((activeBorders.value[index] || (globalStore.chartsBattle && item.is_public))) {
return activeBorderImage;
} else {
return defaultBorderImage;
}
}
}
</script> </script>
<template> <template>
@@ -226,18 +341,14 @@ markers.value = [
<img src="../assets/images/close-btn.webp" alt="关闭按钮"> <img src="../assets/images/close-btn.webp" alt="关闭按钮">
</div> </div>
<div v-for="(marker, index) in markers" <div v-for="(marker, index) in markers" :key="index" class="marker" :style="{
:key="index" left: marker.x + 'vw',
class="marker" top: marker.y + 'vw',
:style="{ width: marker.width + 'vw',
left: marker.x + 'vw', height: marker.height + 'vw'
top: marker.y + 'vw', }" @click.stop="$emit('go-photo-square')">
width: marker.width + 'vw',
height: marker.height + 'vw'
}"
@click.stop="$emit('go-photo-square')">
</div> </div>
<!-- <p class="my-photo-desc">只能选一张照片打榜每周一打榜成绩清零 可重新选择照片参与打榜</p> --> <p class="my-photo-desc">位会员只能选一张照片参与打榜点赞前30名即可获得中秋精美礼品速速邀请好友为你点赞吧</p>
<div class="image-gallery"> <div class="image-gallery">
<!-- <RecycleScroller <!-- <RecycleScroller
class="scroller" class="scroller"
@@ -263,28 +374,21 @@ markers.value = [
</div> </div>
</div> </div>
</RecycleScroller> --> </RecycleScroller> -->
<div <div v-for="(item, index) in images" :key="index" class="image-wrapper">
v-for="(item, index) in images" <div class="image-container mask-background" @click="downloadGenerateImg(item)" :style="{ backgroundImage: `url(${getBackgroundImage(item)})` }">
:key="index" </div>
class="image-wrapper" <img v-if="item.status === 'processing'" @click.stop="getGenerateImgStatus(item)"
> src="../assets/images/refresh-btn.webp" class="refresh-btn" alt="刷新">
<div class="image-container mask-background" <img :src="getBorder(item, index)" class="border-image" alt="border"
:style="{ backgroundImage: `url(${getBackgroundImage(item)})` }" @click.stop="downloadGenerateImg(item)"
>
</div>
<img v-if="item.status === 'progressing'" @click="getGenerateImgStatus(item)" src="../assets/images/refresh-btn.webp" class="refresh-btn" alt="刷新">
<img
:src="(activeBorders[index] || (globalStore.chartsBattle && item.is_public))
? activeBorderImage : defaultBorderImage"
class="border-image"
alt="border"
@click="!globalStore.chartsBattle && toggleBorder(item, index)"
/> />
<div class="mask-overlay"
@click="(!globalStore.chartsBattle && item.result_url !== processingImg) && toggleBorder(item, index)"></div>
</div> </div>
</div> </div>
<div class="scene-item item-2"> <div class="scene-item item-2">
<img v-if="displayZhuli" @click="handleZhuliClick()" src="../assets/images/zhuli.webp" alt="助力" > <img v-if="displayZhuli" @click="handleZhuliClick()" src="../assets/images/zhuli.webp" alt="助力">
<img v-if="!displayZhuli" @click="handleDabangClick()" src="../assets/images/dabang.webp" alt="打榜" > <img v-if="!displayZhuli" @click="handleDabangClick()" src="../assets/images/dabang.webp" alt="打榜">
</div> </div>
<div class="fullsection" v-show="haibaoShow"> <div class="fullsection" v-show="haibaoShow">
@@ -299,17 +403,30 @@ markers.value = [
</template> </template>
<style scoped> <style scoped>
/* 蒙版样式 */
.mask-overlay {
position: absolute;
bottom: 0;
left: 14vw;
width: 10vw;
height: 8vw;
z-index: 2;
cursor: pointer;
}
.scroller { .scroller {
height: 124vw; height: 124vw;
overflow-y: auto; overflow-y: auto;
} }
.list-item { .list-item {
height: 2vw; height: 2vw;
line-height: 50px; line-height: 50px;
} }
.marker { .marker {
position: absolute; position: absolute;
} }
.fullsection { .fullsection {
position: fixed; position: fixed;
top: 0; top: 0;
@@ -354,43 +471,59 @@ markers.value = [
width: 87vw; width: 87vw;
top: 48vw; top: 48vw;
text-align: center; text-align: center;
color: #855211 color: #855211;
font-size: 3.6vw;
} }
.download-btn {
width: 12.6vw;
position: absolute;
bottom: 7vw;
right: 3vw;
cursor: pointer;
}
.refresh-btn { .refresh-btn {
width: 12vw; width: 12vw;
position: absolute; position: absolute;
top: 12%; top: 7vw;
right: 8%; right: 3vw;
cursor: pointer; cursor: pointer;
z-index: 9; z-index: 13;
} }
.image-wrapper { .image-wrapper {
position: relative; position: relative;
margin-bottom: 0;
float: left;
margin-right: 2vw; margin-right: 2vw;
margin-left: 2vw; margin-left: 2vw;
width: 38vw;
height: 59vw;
} }
.border-image { .border-image {
position: absolute; position: absolute;
width: 40vw; width: 40vw;
top: 1.6333vh; top: 2.8vw;
left: -0.4vw; left: -0.8vw;
} }
.image-gallery { .image-gallery {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
display: block;
width: 84vw; width: 84vw;
height: 57vh; height: 57vh;
position: absolute; position: relative;
top: 26%; display: flex;
flex-flow: row;
flex-wrap: wrap;
top: 26vw;
padding-bottom: 22vw;
} }
.image-container { .image-container {
width: 38vw; width: 38vw;
height: 56vw; height: 59vw;
top: 2.2vw; top: 0;
margin-bottom: 3vw; margin-bottom: 3vw;
background-image: url('../assets/images/test.webp'); background-image: url('../assets/images/test.webp');
background-size: cover; background-size: cover;
@@ -401,7 +534,6 @@ markers.value = [
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available; min-height: -webkit-fill-available;
position: relative;
cursor: pointer; cursor: pointer;
} }
@@ -424,7 +556,7 @@ markers.value = [
width: 100%; width: 100%;
height: 92vh; height: 92vh;
background-image: url('../assets/images/my-photov2.webp'); background-image: url('../assets/images/my-photov2.webp');
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -433,6 +565,7 @@ markers.value = [
position: relative; position: relative;
min-height: -webkit-fill-available; min-height: -webkit-fill-available;
} }
.scene-item { .scene-item {
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
@@ -446,6 +579,7 @@ markers.value = [
.scene-item:hover { .scene-item:hover {
transform: scale(1.05); transform: scale(1.05);
} }
.btn-login { .btn-login {
text-align: center; text-align: center;
border-radius: 1vw; border-radius: 1vw;
@@ -455,22 +589,26 @@ markers.value = [
color: #fff; color: #fff;
position: relative; position: relative;
} }
.item-1 { .item-1 {
top: 9%; top: 9%;
width: 10vw; width: 10vw;
right: 4%; right: 4%;
} }
.item-3 { .item-3 {
top: 16.3vh; top: 16.3vh;
width: 32vw; width: 32vw;
position: absolute; position: absolute;
left: 11vw; left: 11vw;
} }
.item-2 { .item-2 {
position: fixed; position: fixed;
width: 100%; width: 100%;
bottom: 0; bottom: 0;
} }
.scene-item img { .scene-item img {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@@ -2,7 +2,7 @@
import { ref, onMounted, computed, watch } from "vue" import { ref, onMounted, computed, watch } from "vue"
import { Request, Storage } from "../libs/utils" import { Request, Storage } from "../libs/utils"
import ModalTransition from "./ModalTransition.vue" import ModalTransition from "./ModalTransition.vue"
import { useRouter } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { RecycleScroller } from "vue-virtual-scroller"; import { RecycleScroller } from "vue-virtual-scroller";
import "vue-virtual-scroller/dist/vue-virtual-scroller.css"; import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
@@ -11,26 +11,26 @@ const props = defineProps({
show: false show: false
}) })
watch(() => props.show, async (newVal) => { const disableInviteHelp = ref(false);
if (!newVal) {
return
}
fetchImages();
})
const emit = defineEmits(['go-my-photo', 'update:show']); const emit = defineEmits(['go-my-photo', 'update:show']);
const router = useRouter(); const router = useRouter();
const route = useRoute();
const goBack = () => { const goBack = () => {
emit('update:show', false); emit('update:show', false);
// 清除URL中的查询参数
if (Object.keys(route.query).length > 0) {
router.replace({ path: route.path, query: {} });
}
}; };
const username = ref(); const username = ref();
const likesCount = ref(); const likesCount = ref();
const userImg = ref(); const userImg = ref();
const ranking = ref(); const ranking = ref();
const displayMyPublishPhoto = ref(false);
const fetchImages = async () => { const fetchImages = async () => {
disableInviteHelp.value = false;
try { try {
const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square'); const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square');
url.searchParams.append('my_only', '0'); url.searchParams.append('my_only', '0');
@@ -42,80 +42,174 @@ const fetchImages = async () => {
} }
}) })
const data = await response.json() const data = await response.json()
console.log('Success:', data) if (response.status == 200 || response.status == 201) {
images.value = data.data console.log('Success:', data)
username.value = data.my_published_photo.user_name; images.value = data.data
likesCount.value = data.my_published_photo.likes_count; if (data.my_published_photo) {
userImg.value = data.my_published_photo.result_url; displayMyPublishPhoto.value = true;
ranking.value = data.my_published_photo.ranking; username.value = data.my_published_photo.user_name;
likesCount.value = data.my_published_photo.likes_count;
userImg.value = data.my_published_photo.avatar;
ranking.value = data.my_published_photo.ranking;
} else {
displayMyPublishPhoto.value = false;
}
} else {
ElMessage.error(data.message);
emit('update:show', false);
}
} catch (error) { } catch (error) {
console.error('Error:', error) console.error('Error:', error)
} }
} }
// 图片数据 watch(() => props.show, async (newVal) => {
const images = ref([]);
const disableInviteHelp = ref(false);
const userinfos = Storage.get("userinfos")
// TODO 需要测试邀请进来的情况
const mergeId = ref();
const rankingInvite = ref(0);
const nameInvite = ref('');
const linkCountInvite = ref(0);
const urlParams = new URLSearchParams(window.location.search);
mergeId.value = urlParams.get('merge_id');
watch(() => mergeId, async (newVal) => {
if (!newVal) { if (!newVal) {
return return
} }
if (newVal.value) { fetchImages();
getInviteInfo(); }, {immediate: true})
}
})
const getInviteInfo = ()=> { // 图片数据与分页
const urlParams = new URLSearchParams(window.location.search); const images = ref([]);
mergeId.value = urlParams.get('merge_id'); const page = ref(1);
fetch(`https://huodong2.lzlj.com/api/faceFamily/face/merge/${mergeId.value}`, { const perPage = 20;
const loading = ref(false);
const finished = ref(false);
const loadMoreImages = async () => {
if (loading.value || finished.value) return;
loading.value = true;
try {
const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square');
url.searchParams.append('my_only', '0');
url.searchParams.append('page', page.value);
url.searchParams.append('per_page', perPage);
const response = await fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
}
});
const data = await response.json();
if (response.status == 200 || response.status == 201) {
if (data.data.length < perPage) finished.value = true;
images.value.push(...data.data);
page.value++;
if (data.my_published_photo) {
displayMyPublishPhoto.value = true;
username.value = data.my_published_photo.user_name;
likesCount.value = data.my_published_photo.likes_count;
userImg.value = data.my_published_photo.avatar;
ranking.value = data.my_published_photo.ranking;
} else {
displayMyPublishPhoto.value = false;
}
} else {
ElMessage.error(data.message);
emit('update:show', false);
}
} catch (error) {
console.error('Error:', error);
}
loading.value = false;
};
const handleScroll = (e) => {
const el = e.target;
if (el.scrollHeight - el.scrollTop - el.clientHeight < 100) {
loadMoreImages();
}
};
watch(() => props.show, async (newVal) => {
if (!newVal) return;
// 重置分页
images.value = [];
page.value = 1;
finished.value = false;
await loadMoreImages();
}, {immediate: true});
const userinfos = Storage.get("userinfos")
let mergeId = '';
let inviteCode = '';
const rankingInvite = ref(0);
const nameInvite = ref('');
const linkCountInvite = ref(0);
const backgroundImageForInvite = ref('');
const urlParams = new URLSearchParams(window.location.search);
mergeId = urlParams.get('merge_id');
inviteCode = urlParams.get('fromid');
const getInviteInfo = ()=> {
disableInviteHelp.value = true;
fetch(`https://huodong2.lzlj.com/api/faceFamily/face/merge/${mergeId}`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Authorization': `Bearer ${Storage.get("userinfos").api_token}` 'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
} }
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
rankingInvite.value = data.ranking; if (response.status == 200 || response.status == 201) {
nameInvite.value = data.user_name; rankingInvite.value = data.ranking;
linkCountInvite.value = data.likes_count; nameInvite.value = data.user_name;
linkCountInvite.value = data.likes_count;
backgroundImageForInvite.value = data.result_url;
} else {
ElMessage.error(data.message);
// emit('update:show', false);
}
}) })
.catch((error) => { .catch((error) => {
ElMessage.success('点赞失败!'); ElMessage.error('分享进入页面失败!');
console.error('Error:', error); emit('update:show', false);
}); });
} }
watch(() => mergeId, async (newVal) => {
if (!newVal) {
return
}
if (newVal) {
if (inviteCode === userinfos.invite_code) {
weui.alert("不可以给自己点赞哦!");
return false;
}
getInviteInfo();
}
}, {immediate: true})
const displayInviteHelpBtn = ref(true);
const inviteHelp = ()=> { const inviteHelp = ()=> {
const formData = { const formData = {
invite_code: userinfos.invite_code, invite_code: inviteCode,
merge_id: '' merge_id: mergeId
} }
fetch('https://huodong2.lzlj.com/api/faceFamily/face/like', { fetch('https://huodong2.lzlj.com/api/faceFamily/face/like', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json',
Accept: "application/json",
'Authorization': `Bearer ${Storage.get("userinfos").api_token}` 'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
}, },
body: JSON.stringify(formData) body: JSON.stringify(formData)
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
disableInviteHelp.value = true; if (response.status == 200 || response.status == 201) {
ElMessage.success('点赞成功!'); displayInviteHelpBtn.value = false;
ElMessage.success('点赞成功!');
} else {
ElMessage.error(data.message);
}
}) })
.catch((error) => { .catch((error) => {
ElMessage.success('点赞失败!'); ElMessage.error('点赞失败!');
console.error('Error:', error); console.error('Error:', error);
}); });
} }
@@ -128,6 +222,12 @@ markers.value = [
{ x: 50, y: 32, width: 50, height: 14 } { x: 50, y: 32, width: 50, height: 14 }
]; ];
const getBackgroundImage = (item) => {
if (item.result_url) {
return `${item.result_url}?x-oss-process=image/resize,w_400/format,webp/quality,q_80`;
}
};
</script> </script>
<template> <template>
@@ -148,83 +248,59 @@ markers.value = [
}" }"
@click.stop="$emit('go-my-photo')"> @click.stop="$emit('go-my-photo')">
</div> </div>
<p class="my-photo-desc">打榜活动截止至10月3日23:59:59结束中奖信息将于10月4日早10点推送至获奖会员</p>
<div v-if="!disableInviteHelp" class="image-gallery "> <div v-if="!disableInviteHelp" class="image-gallery scroller" @scroll="handleScroll">
<RecycleScroller <div
class="scroller"
:items="images"
:item-size="8"
key-field="id"
v-slot="{ item, index }"
>
<div class="image-wrapper">
<div class="image-container mask-background">
</div>
<img
src="../assets/images/zpgc-border.webp"
class="border-image"
alt="border"
/>
<div class="list-item">
<div class="flex-container-detail">
<div class="left-group">
<p class="photo-number">{{ (index + 1).toString().padStart(3, '0') }}</p>
<p class="photo-name">{{ item.user_name }}</p>
</div>
<p class="right-item photo-name" style="padding-left: 3vw;">{{ item.likes_count }}</p>
</div>
</div>
</div>
</RecycleScroller>
<!-- <div
v-for="(item, index) in images" v-for="(item, index) in images"
:key="index" :key="item.id || index"
class="image-wrapper" class="image-wrapper"
> >
<div class="image-container mask-background"> <div class="image-container mask-background"
:style="{ backgroundImage: `url(${getBackgroundImage(item)})` }">
</div> </div>
<img <img
src="../assets/images/zpgc-border.webp" src="../assets/images/zpgc-border.webp"
class="border-image" class="border-image"
alt="border" alt="border"
/> />
<div class="flex-container-detail"> <div class="list-item">
<div class="left-group"> <div class="flex-container-detail">
<p class="photo-number">{{ (index + 1).toString().padStart(3, '0') }}</p> <div class="photo-number">{{ (index + 1).toString().padStart(3, '0') }}</div>
<p class="photo-name">{{ item.user_name }}</p> <div class="photo-name">{{ item.user_name }}</div>
<div class="right-item photo-name">{{ item.likes_count }}</div>
</div> </div>
<p class="right-item photo-name" style="padding-left: 3vw;">{{ item.likes_count }}</p>
</div> </div>
</div> --> </div>
<div v-if="loading" style="text-align:center;padding:10px;color:#999;">加载中...</div>
<div v-if="finished && images.length === 0" style="text-align:center;padding:10px;color:#999;">暂无数据</div>
</div> </div>
<div v-if="!disableInviteHelp" class="fixed-background-container"> <div v-if="!disableInviteHelp && displayMyPublishPhoto" class="fixed-background-container">
<div class="flex-container"> <div class="flex-container">
<div class="left-group"> <div class="left-group">
<p class="photo-number">{{ ranking }}</p> <p class="photo-number">{{ ranking }}</p>
<img :src="userImg" class="user-img" alt="我的照片"> <img :src="userImg" class="user-img" alt="">
<p class="photo-name bold">{{ username }}</p> <p class="photo-name-square bold">{{ username }}</p>
</div> </div>
<p class="right-item photo-name bold" style="padding-left: 3vw;">{{ likesCount }}</p> <p class="right-item photo-name bold" style="padding-left: 3vw;">{{ likesCount }}</p>
</div> </div>
</div> </div>
<div v-if="disableInviteHelp"> <div v-if="disableInviteHelp" class="share-main">
<div class="image-gallery-share"> <div class="image-gallery-share">
<div class="image-wrapper-share"> <div class="image-wrapper-share">
<div class="image-container-share mask-background"> <div class="image-container-share mask-background"
:style="{ backgroundImage: `url(${backgroundImageForInvite})` }">
</div> </div>
<img src="../assets/images/zpgc-border.webp" class="border-image-share" alt="border" /> <img src="../assets/images/zpgc-border.webp" class="border-image-share" alt="border" />
<div class="flex-container-detail-invite"> <div class="flex-container-detail-invite">
<div class="left-group-left"> <div class="photo-number">{{ rankingInvite }}</div>
<p class="photo-number">111</p> <div class="photo-name-invite">{{ nameInvite }}</div>
<p class="photo-name">222</p> <div class="link-count-invite">{{ linkCountInvite }}</div>
</div>
<p class="right-item photo-name" style="padding-left: 3vw;">333</p>
</div> </div>
</div> </div>
</div> </div>
<div class="ranking-title" @click="inviteHelp"> <div v-if="displayInviteHelpBtn" class="ranking-title" @click="inviteHelp">
<img src="/src/assets/images/dianzan.webp" alt="点赞"> <img src="/src/assets/images/dianzan.webp" alt="点赞">
</div> </div>
</div> </div>
@@ -233,23 +309,64 @@ markers.value = [
</template> </template>
<style scoped> <style scoped>
.share-main {
display: flex;
flex-flow: column;
align-items: center;
}
.my-photo-desc {
position: absolute;
width: 87vw;
top: 48vw;
text-align: center;
color: #855211;
font-size: 3.6vw;
}
.scroller { .scroller {
height: 124vw; height: 124vw;
overflow-y: auto; overflow-y: auto;
} }
.list-item { .list-item {
height: 8vw; position: relative;
line-height: 50px;
} }
.marker { .marker {
position: absolute; position: absolute;
} }
.flex-container-detail-invite { .flex-container-detail-invite {
display: flex;
flex-flow: row;
justify-content: center;
position: relative; position: relative;
top: -8vw; display: flex;
justify-content: space-around;
align-items: center;
height: 11vw;
bottom: 10.5vw;
font-size: 3vw;
width: 100%;
padding: 0px 13vw;
}
.photo-name-square {
min-width: 14vw;
max-width: 40vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #93551f;
}
.photo-name-invite {
min-width: 14vw;
max-width: 30vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #93551f;
}
.link-count-invite {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #93551f;
padding-left: 2vw;
margin-left: auto;
flex-shrink: 0;
} }
.left-group-left { .left-group-left {
display: flex; display: flex;
@@ -260,70 +377,70 @@ markers.value = [
.ranking-title { .ranking-title {
width: 48vw; width: 48vw;
position: absolute; position: absolute;
bottom: 20vw; bottom: 2vw;
left: 27vw; left: 27vw;
} }
.ranking-title img { .ranking-title img {
width: 100%; width: 100%;
} }
.image-gallery-share {
margin: 0 auto;
position: relative;
overflow-y: auto;
display: block;
width: 84vw;
height: 57vh;
top: 16%;
}
.image-wrapper-share { .image-wrapper-share {
position: relative; position: relative;
margin-bottom: -10vw; width: 69vw;
float: left; height: 57vw;
margin-left: 4vw; margin-top: 12vw;
} }
.image-container-share { .image-container-share {
width: 77vw; width: 68vw;
height: 43vh; height: 81vw;
background-image: url(/src/assets/images/test.webp); background-image: url(/src/assets/images/test.webp);
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
min-height: -webkit-fill-available;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
background-position: center;
} }
.border-image-share { .border-image-share {
position: absolute; position: absolute;
width: 72vw; width: 63vw;
top: -0.5vw; top: -0.8vw;
left: 2.6vw; left: 3vw;
} }
.bold { .bold {
font-weight: bold; font-weight: bold;
} }
.photo-number { .photo-number {
color: red; color: red;
flex-shrink: 0;
padding-right: 2vw;
} }
.photo-name { .photo-name {
min-width: 14vw;
max-width: 19vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #93551f; color: #93551f;
} }
.flex-container-detail { .flex-container-detail {
position: relative; position: absolute;
display: flex; display: flex;
justify-content: center; justify-content: space-around;
align-items: center; align-items: center;
height: 3vh; bottom: 5vw;
top: -11vw; font-size: 3vw;
font-size: 11px; width: 100%;
padding: 0 4vw;
left: 2vw;
} }
.flex-container { .flex-container {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
height: 8vh; height: 100%;
padding: 0 6vw; padding: 0 6vw;
} }
@@ -339,7 +456,9 @@ markers.value = [
} }
.left-group p, .right-item { .left-group p, .right-item {
margin: 0; padding-left: 0.3vw;
margin-left: auto;
flex-shrink: 0;
} }
.fixed-background-container { .fixed-background-container {
background-image: url('../assets/images/paiming-border.webp'); background-image: url('../assets/images/paiming-border.webp');
@@ -347,38 +466,41 @@ markers.value = [
bottom: 1vh; bottom: 1vh;
left: 5vw; left: 5vw;
width: 90vw; width: 90vw;
height: 8vh; height: 17vw;
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: bottom center; background-position: bottom center;
} }
.image-wrapper { .image-wrapper {
position: relative; position: relative;
margin-bottom: -10vw;
float: left;
margin-right: 2vw; margin-right: 2vw;
margin-left: 2vw; margin-left: 2vw;
width: 38vw;
height: 59vw;
} }
.border-image { .border-image {
position: absolute; position: absolute;
width: 40vw; width: 40vw;
top: 1.6333vh; top: 2.8vw;
left: -0.4vw; left: -0.8vw;
} }
.image-gallery { .image-gallery {
overflow-y: auto; overflow-y: auto;
display: block; overflow-x: hidden;
width: 84vw; width: 84vw;
height: 57vh; height: 57vh;
position: absolute; position: relative;
top: 28%; display: flex;
flex-flow: row;
flex-wrap: wrap;
top: 26vw;
padding-bottom: 12vw;
} }
.image-container { .image-container {
width: 38vw; width: 38vw;
height: 28vh;
background-image: url('../assets/images/test.webp'); background-image: url('../assets/images/test.webp');
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -24,18 +24,22 @@ const confirmBtn = () => {
}, },
body: {} body: {}
}) })
.then(response => response.json()) .then(async response => {
.then(data => { const data = await response.json()
if (data.message === '您已经有一张发布的照片,不能再次发布') { if (response.status == 200 || response.status == 201) {
weui.alert('您已经有一张发布的照片,不能再次发布') if (data.message === '您已经有一张发布的照片,不能再次发布') {
return weui.alert('您已经有一张发布的照片,不能再次发布')
return
}
ElMessage.success('打榜成功!');
console.log('Success:', data);
return { success: true, data };
} else {
ElMessage.error(data.message);
} }
ElMessage.success('打榜成功!');
console.log('Success:', data);
return { success: true, data };
}) })
.catch((error) => { .catch((error) => {
ElMessage.success('打榜失败!'); ElMessage.error('打榜失败!');
return { success: false, error }; return { success: false, error };
}); });
emit('update:show', false); emit('update:show', false);
@@ -48,12 +52,12 @@ const confirmBtn = () => {
<div class="home-bg"> <div class="home-bg">
<div class="popup-bg"> <div class="popup-bg">
<div class="scene-item item-1"> <div class="scene-item item-1">
<img src="../assets/images/confirm.webp" @click="confirmBtn" alt="确认"> <img src="../assets/images/confirm.webp" @click="cancelBtn" alt="确认">
</div> </div>
<p class="message">温馨提示每位用户只能选择一张合影参与打榜一经确认在打榜期间将无法更换</p> <p class="message">活动已结束</p>
<div class="scene-item item-2"> <!-- <div class="scene-item item-2">
<img src="../assets/images/cancel.webp" @click="cancelBtn" alt="取消"> <img src="../assets/images/cancel.webp" @click="cancelBtn" alt="取消">
</div> </div> -->
</div> </div>
</div> </div>
</ModalTransition> </ModalTransition>
@@ -62,7 +66,7 @@ const confirmBtn = () => {
<style scoped> <style scoped>
.home-bg { .home-bg {
position: absolute; position: absolute;
top: 72vw; top: 60vw;
left: 12vw; left: 12vw;
} }
.message { .message {
@@ -70,19 +74,19 @@ const confirmBtn = () => {
position: absolute; position: absolute;
top: 42%; top: 42%;
color: #774107; color: #774107;
text-align: center;
} }
.popup-bg { .popup-bg {
width: 77vw; width: 77vw;
height: 60vw; height: 60vw;
background-image: url('../assets/images/popup.webp'); background-image: url('../assets/images/popup.webp');
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available;
} }
.scene-item { .scene-item {
position: absolute; position: absolute;
@@ -109,7 +113,6 @@ const confirmBtn = () => {
.item-1 { .item-1 {
top: 50vw; top: 50vw;
width: 40vw; width: 40vw;
right: 0;
} }
.item-2 { .item-2 {
top: 50vw; top: 50vw;

View File

@@ -59,7 +59,7 @@ const handleItemBtn = (id, event) => {
} }
</script> </script>
<style scoped> <style>
.prizelist { .prizelist {
position: relative; position: relative;
width: 100vw; width: 100vw;
@@ -111,7 +111,7 @@ const handleItemBtn = (id, event) => {
flex: 1; flex: 1;
display: flex; display: flex;
font-weight: 700; font-weight: 700;
color: #09431d; color: #48260a;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
@@ -139,38 +139,54 @@ const handleItemBtn = (id, event) => {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100%; background-size: 100%;
} }
wx-open-launch-weapp{
width: 100%;
height: 100%;
}
.btn-goto wx-open-launch-weapp {
display: block;
}
wx-open-launch-weapp, wx-open-launch-weapp,
.btn-goto.noaddress wx-open-launch-weapp { .btn-goto.noaddress wx-open-launch-weapp {
display: none; display: none;
} }
.btn-goto wx-open-launch-weapp {
display: block;
}
.btn-goto.noaddress { .btn-goto.noaddress {
background-image: url("../assets/images/btn-address.webp"); background-image: url("../assets/images/btn-address.webp");
} }
.prizelist-cover.USER_TJGJ { .prizelist-cover.USER_LZ_ZQ_DZJ {
background-image: url("../assets/images/USER_TJGJ.webp"); background-image: url("../assets/images/generate/USER_LZ_ZQ_DZJ.webp");
} }
.prizelist-cover.USER_XINCHUN_WEIZUN { .prizelist-cover.USER_HG_42_GPJ_500ML {
background-image: url("../assets/images/USER_XINCHUN_WEIZUN.webp"); background-image: url("../assets/images/USER_HG_42_GPJ_500ML.webp");
} }
.prizelist-cover.USER_TEQU_JL_52_60Y_100ML_2 { .prizelist-cover.USER_QLL_MH {
background-image: url("../assets/images/USER_TEQU_JL_52_60Y_100ML_2.webp"); background-image: url("../assets/images/USER_QLL_MH.webp");
} }
.prizelist-cover.USER_LZLJ_TEQU_LZH_52_100ML_2 { .prizelist-cover.USER_DZSKSJ {
background-image: url("../assets/images/USER_LZLJ_TEQU_LZH_52_100ML_2.webp"); background-image: url("../assets/images/generate/USER_DZSKSJ.webp");
} }
.prizelist-cover.USER_HEIGAI_42_GPJ_500ML { .prizelist-cover.USER_LZ_ZQ_DZJ_LJW {
background-image: url("../assets/images/USER_HEIGAI_42_GPJ_500ML.webp"); background-image: url("../assets/images/USER_LZ_ZQ_DZJ_LJW.webp");
}
.prizelist-cover.USER_LZ_XS_SPZ_30ML {
background-image: url("../assets/images/generate/USER_LZ_XS_SPZ_30ML.webp");
}
.prizelist-cover.USER_LZ_DZ_JBGJ {
background-image: url("../assets/images/USER_LZ_DZ_JBGJ.webp");
}
.prizelist-cover.USER_LZ_DZ_JBGJ_LZ_ZQ_DZJ {
background-image: url("../assets/images/generate/USER_LZ_DZ_JBGJ_LZ_ZQ_DZJ.webp");
} }
.prizelist-cover.USER_DZCZ { .prizelist-cover.USER_DZCZ {

View File

@@ -2,11 +2,11 @@
<ModalTransition class="rule" :show="show"> <ModalTransition class="rule" :show="show">
<div class="rule-wrapper"> <div class="rule-wrapper">
<div class="rule-content"> <div class="rule-content">
<!-- <img src="../assets/images/rule-1.webp" alt=""> <img src="../assets/images/rule-1.webp" alt="">
<img src="../assets/images/rule-2.webp" alt=""> <img src="../assets/images/rule-2.webp" alt="">
<img src="../assets/images/rule-3.webp" alt=""> <img src="../assets/images/rule-3.webp" alt="">
<img src="../assets/images/rule-4.webp" alt=""> <img src="../assets/images/rule-4.webp" alt="">
<img src="../assets/images/rule-5.webp" alt=""> --> <img src="../assets/images/rule-5.webp" alt="">
</div> </div>
<div class="close" @click="emit('close')"></div> <div class="close" @click="emit('close')"></div>
</div> </div>
@@ -26,7 +26,7 @@ const emit = defineEmits(['close'])
.rule-wrapper { .rule-wrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: 175.740741vw; height: 182vw;
background-image: url("../assets/images/rule-bg.webp"); background-image: url("../assets/images/rule-bg.webp");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100%; background-size: 100%;

View File

@@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, onMounted } from "vue" import { ref, onMounted, watch } from "vue"
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import imageBackground from '../static/imageBackground.js'; import imageBackground from '../static/imageBackground.js';
import { globalStore } from "../globalstore.js"; import { globalStore } from "../globalstore.js";
@@ -13,12 +13,25 @@ onMounted(() => {
}) })
const router = useRouter(); const router = useRouter();
const navigateTodoList = () => { const navigateBack = () => {
router.push({ router.push({
name: 'home' name: 'home'
}) })
} }
const imageUrl = ref(globalStore.select_template);
const goToHomePage = (item) => {
if (!item) {
router.push({
name: 'home'
});
}
}
watch(imageUrl, (item) => {
goToHomePage(item)
}, { immediate: true })
const displayedImages = ref([]); const displayedImages = ref([]);
const goToGenerateImgPage = (item) => { const goToGenerateImgPage = (item) => {
globalStore.people_count = item.peopleCount; globalStore.people_count = item.peopleCount;
@@ -61,10 +74,10 @@ const handleNavClick = (event) => {
</script> </script>
<template> <template>
<div :show="show"> <div :show="show" class="main">
<div class="home-wrapper"> <div class="home-wrapper">
<div class="scene-item item-1"> <div class="scene-item item-1" @click="navigateBack">
<img src="../assets/images/back-btn.webp" @click="navigateTodoList" alt="后退"> <img src="../assets/images/back-btn.webp" alt="后退">
</div> </div>
<!-- 显示当前选中的背景图片 --> <!-- 显示当前选中的背景图片 -->
@@ -118,10 +131,11 @@ const handleNavClick = (event) => {
.nav-container { .nav-container {
position: relative; position: relative;
top: 21vw;
} }
.nav-image-wrapper { .nav-image-wrapper {
top: 24vw; top: 0;
opacity: 0; opacity: 0;
position: relative; position: relative;
display: inline-block; display: inline-block;
@@ -165,24 +179,28 @@ const handleNavClick = (event) => {
} }
.mask-image { .mask-image {
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
position: relative; position: relative;
width: 39vw; width: 39vw;
height: 52vw; height: 52vw;
} }
.border-img { .border-img {
width: 39.5vw; width: 39.7vw;
height: 54vw; height: 54.4vw;
position: absolute; position: absolute;
top: -0.5vw; top: -0.7vw;
left: 0; left: -0.1vw;
}
.main {
height: 100%;
overflow-y: auto;
} }
.home-wrapper { .home-wrapper {
width: 100%; width: 100vw;
height: 92vh; height: 200vw;
background-image: url('../assets/images/generate/select-template-bg.webp'); background-image: url('../assets/images/generate/select-template-bg.webp');
background-size: cover; background-size: 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -190,6 +208,7 @@ const handleNavClick = (event) => {
align-items: center; align-items: center;
position: relative; position: relative;
min-height: -webkit-fill-available; min-height: -webkit-fill-available;
margin-top: -4vw;
} }
.scene-item { .scene-item {

View File

@@ -7,15 +7,16 @@ import globalToastEvent, { ToastType } from '../globalToastEvent';
import { Storage, generateQR } from "../libs/utils"; import { Storage, generateQR } from "../libs/utils";
import Haibao from "@/libs/haibao"; import Haibao from "@/libs/haibao";
import mask from "../assets/images/haibao-mask.webp"; import mask from "../assets/images/haibao-mask.webp";
import haibaoCoverBorder from "../assets/images/haibao-cover.webp"; import haibaoCoverBorder from "../assets/images/haibao-cover-sucess.webp";
import bg from "../assets/images/haibao-bg.webp" import bg from "../assets/images/haibao-bg.webp"
import Lottery from '../components/Lottery.vue';
defineProps({ defineProps({
show: true show: true
}) })
const isPopupVisible = ref(false); const isPopupVisible = ref(false);
const lotteryShow = ref(false)
const chartsBattle = ()=> { const chartsBattle = ()=> {
globalStore.chartsBattle = true; globalStore.chartsBattle = true;
@@ -70,7 +71,7 @@ const handleHaibao = async () => {
}); });
} }
const userPicture = await loadImage(globalStore.result_url) const userPicture = await loadImage(globalStore.result_url)
haibaoCover.add(userPicture, 0, 0) haibaoCover.add(userPicture, 0, 50, 951, 1698)
haibaoCover.add(mask, 10, 100) haibaoCover.add(mask, 10, 100)
haibaoCover.add(haibaoCoverBorder, 0, 0) haibaoCover.add(haibaoCoverBorder, 0, 0)
haibaoCover.draw('destination-in').then(() => { haibaoCover.draw('destination-in').then(() => {
@@ -79,13 +80,14 @@ const handleHaibao = async () => {
const haibaoSave = new Haibao(1080, 2160) const haibaoSave = new Haibao(1080, 2160)
const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${infos.merge_id}`, 200, 200) const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${infos.merge_id}`, 200, 200)
haibaoSave.add(url, 62, 350)
haibaoSave.add(bg, 0, 0) haibaoSave.add(bg, 0, 0)
haibaoSave.add(qrcode, 115, 1875) haibaoSave.add(url, 64, 250)
haibaoSave.add(qrcode, 127, 1860)
haibaoSave.draw().then(() => { haibaoSave.draw().then(() => {
haibaoSave.text(infos.nickname, haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#ffee6f' }) haibaoSave.text(infos.nickname + '的全家福', haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#fcf2b3' })
haibaoSave.generate({ mimeType: 'image/png' }).then(url => { haibaoSave.generate({ mimeType: 'image/png' }).then(url => {
haibaoUrl.value = url // haibaoUrl.value = url
haibaoUrl.value = globalStore.result_url;
loading.hide() loading.hide()
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
@@ -108,10 +110,19 @@ const handleHaibao = async () => {
// return userPictureVal; // return userPictureVal;
// } // }
// }; // };
globalToastEvent.on(ToastType.SHOW_LOTTERY, () => {
lotteryShow.value = true
})
const handleBtnMore = () => {
globalToastEvent.emit(ToastType.SHOW_AD)
}
</script> </script>
<template> <template>
<div> <div class="main">
<div class="home-wrapper"> <div class="home-wrapper">
<div class="scene-item item-1"> <div class="scene-item item-1">
<img src="../assets/images/go-home-btn.webp" @click="navigateToHome" alt="回到首页"> <img src="../assets/images/go-home-btn.webp" @click="navigateToHome" alt="回到首页">
@@ -127,10 +138,14 @@ const handleHaibao = async () => {
</div> </div>
</div> </div>
<div class="scene-item item-2"> <div v-if="!globalStore.chartsBattle" class="scene-item item-2">
<img src="../assets/images/charts-battle.webp" @click="chartsBattle" alt="参与打榜"> <img src="../assets/images/charts-battle.webp" @click="chartsBattle" alt="参与打榜">
</div> </div>
<div v-if="globalStore.chartsBattle" class="scene-item item-2">
<img src="../assets/images/btn-more.webp" @click="handleBtnMore" alt="更多金喜">
</div>
<div class="scene-item item-3" @click="handleLottery"> <div class="scene-item item-3" @click="handleLottery">
<img src="../assets/images/instant-win.webp" alt="立即抽奖"> <img src="../assets/images/instant-win.webp" alt="立即抽奖">
</div> </div>
@@ -138,6 +153,7 @@ const handleHaibao = async () => {
</div> </div>
<Popup v-model:show="isPopupVisible" /> <Popup v-model:show="isPopupVisible" />
<Lottery :show="lotteryShow" @close="lotteryShow = false" data="null" type="draw"></Lottery>
</template> </template>
<style scoped> <style scoped>
@@ -171,20 +187,16 @@ const handleHaibao = async () => {
} }
.fullsection { .fullsection {
position: fixed; position: absolute;
top: 25vw; top: 40vw;
left: 0; left: 0;
width: 100%; width: 100vw;
height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
/* background-color: rgba(0, 0, 0, .7); */
} }
.haibao { .haibao {
position: relative;
top: -25vw;
width: 70vw; width: 70vw;
height: 119.444444vw; height: 119.444444vw;
background-image: url("../assets/images/haibao-cover.webp"); background-image: url("../assets/images/haibao-cover.webp");
@@ -216,10 +228,12 @@ const handleHaibao = async () => {
top: initial; top: initial;
transform: translate3d(-50%,0,0); transform: translate3d(-50%,0,0);
} }
.main {
height: 100%;
overflow-y: auto;
}
.home-wrapper { .home-wrapper {
width: 100%; width: 100vw;
height: 92vh;
background-image: url('../assets/images/img-result-bg.webp'); background-image: url('../assets/images/img-result-bg.webp');
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@@ -5,8 +5,7 @@
<div class="btn-qiwei" :class="globalStore.followed_official && 'has'" @click="openQiwei($event)"></div> <div class="btn-qiwei" :class="globalStore.followed_official && 'has'" @click="openQiwei($event)"></div>
<div class="btn-scan" :class="globalStore.cap_scan >= globalStore.MAX_CAP_SCAN && 'has'" <div class="btn-scan" :class="globalStore.cap_scan >= globalStore.MAX_CAP_SCAN && 'has'"
@click="handleScan($event)"></div> @click="handleScan($event)"></div>
<div class="btn-share" :class="globalStore.invitees >= globalStore.MAX_INVITE_DAILY && 'has'" <div class="btn-share" @click="openHaibao($event)"></div>
@click="openHaibao($event)"></div>
</div> </div>
<div class="close" @click="$emit('close')"></div> <div class="close" @click="$emit('close')"></div>
</div> </div>
@@ -29,16 +28,19 @@
<script setup> <script setup>
import { ref, computed } from "vue" import { ref, computed } from "vue"
import { globalStore } from "@/globalstore"; import { globalStore } from "@/globalstore";
import globalToastEvent, { ToastType } from "../globalToastEvent"
import ModalTransition from "./ModalTransition.vue" import ModalTransition from "./ModalTransition.vue"
import { Storage, generateQR, isWeixin, isMiniPage } from "../libs/utils" import { Storage, generateQR, isWeixin, isMiniPage, Request } from "../libs/utils"
import Haibao from "@/libs/haibao" import Haibao from "@/libs/haibao"
import bg from "../assets/images/haibao-bg.webp" import bg from "../assets/images/haibao-bg.webp"
import mask from "../assets/images/haibao-mask.webp" import mask from "../assets/images/haibao-mask.webp"
import haibaoCoverBorder from "../assets/images/haibao-cover.webp" import haibaoCoverBorder from "../assets/images/haibao-cover.webp"
import haibaoCoverBorderNoTitle from "../assets/images/haibao-cover-no-title.webp"
const props = defineProps({ const props = defineProps({
show: false, show: false,
}) })
let mergeId = ''
const emit = defineEmits(['close', 'open']) const emit = defineEmits(['close', 'open'])
const shareShow = ref(false) const shareShow = ref(false)
const qiweiShow = ref(false) const qiweiShow = ref(false)
@@ -54,9 +56,7 @@ const handleHaibao = async () => {
return return
} }
const loading = weui.loading() const loading = weui.loading()
// let userPicture = 'https://lzlj123.oss-cn-shanghai.aliyuncs.com/face-merged/20250914/face-merge-5c90bb95-d1d2-479a-a13b-ada7ba8e7152.jpg'
let userPicture = await loadImage(globalStore.result_url) let userPicture = await loadImage(globalStore.result_url)
// let userPicture = await loadImage('https://lzlj123.oss-cn-shanghai.aliyuncs.com/face-merged/20250914/face-merge-5c90bb95-d1d2-479a-a13b-ada7ba8e7152.jpg')
const infos = Storage.get("userinfos") const infos = Storage.get("userinfos")
const haibaoCover = new Haibao(951, 1607) const haibaoCover = new Haibao(951, 1607)
@@ -66,15 +66,23 @@ const handleHaibao = async () => {
haibaoCover.draw('destination-in').then(() => { haibaoCover.draw('destination-in').then(() => {
haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => { haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => {
userHaibaoUrl.value = url userHaibaoUrl.value = url
})
})
const haibaoSave = new Haibao(1080, 2160) const haibaoCoverNoTitle = new Haibao(951, 1607)
const qrcode = await generateQR(`fromid=${infos.invite_code}&org_id=${infos.org_id}`, 200, 200) haibaoCoverNoTitle.add(userPicture, 0, 50, 951, 1698)
haibaoSave.add(url, 62, 350) haibaoCoverNoTitle.add(mask, 10, 100)
haibaoSave.add(bg, 0, 0) haibaoCoverNoTitle.add(haibaoCoverBorderNoTitle, 0, 0)
haibaoSave.add(qrcode, 115, 1875) haibaoCoverNoTitle.draw('destination-in').then(() => {
haibaoSave.draw().then(() => { haibaoCoverNoTitle.generate({ mimeType: 'image/png' }).then(async (url) => {
haibaoSave.text(infos.nickname, haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#ffee6f' }) const haibaoSaveNoTitle = new Haibao(1080, 2160)
haibaoSave.generate({ mimeType: 'image/png' }).then(url => { const qrcode = await generateQR(`fromid=${infos.invite_code}&merge_id=${mergeId}`, 220, 220)
haibaoSaveNoTitle.add(bg, 0, 0)
haibaoSaveNoTitle.add(url, 64, 250)
haibaoSaveNoTitle.add(qrcode, 118, 1849)
haibaoSaveNoTitle.draw().then(() => {
haibaoSaveNoTitle.text(infos.nickname + '的全家福', haibaoSaveNoTitle.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#fcf2b3' })
haibaoSaveNoTitle.generate({ mimeType: 'image/png' }).then(url => {
haibaoUrl.value = url haibaoUrl.value = url
loading.hide() loading.hide()
}).catch(err => { }).catch(err => {
@@ -112,17 +120,54 @@ const openQiwei = (e) => {
qiweiShow.value = true qiweiShow.value = true
} }
const openHaibao = (e) => {
const target = e.currentTarget
const openHaibao = async (e) => {
const target = e.currentTarget
if (target.classList.contains("has")) { if (target.classList.contains("has")) {
return return
} }
if (!globalStore.result_url) { const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square');
return weui.alert("请先参与活动合成图片并打榜!") url.searchParams.append('my_only', '1');
} url.searchParams.append('page', '1');
haibaoShow.value = true url.searchParams.append('per_page', '100');
handleHaibao() const loading = weui.loading()
fetch(url.toString(), {
method: 'GET',
headers: {
'Authorization': `Bearer ${Storage.get("userinfos").api_token}`
}
})
.then(async response => {
const data = await response.json()
if (response.status == 200 || response.status == 201) {
loading.hide()
const foundItem = data.data.find(item => item.is_public === true);
if (foundItem) {
globalStore.result_url = foundItem.result_url;
mergeId = foundItem.id;
haibaoShow.value = true
if (!globalStore.first_share_today) {
const shareOk = await Request(`face/share/${mergeId}`)
if (shareOk.res.status === 200) {
globalStore.first_share_today = true
globalToastEvent.emit(ToastType.INFO_UPDATE)
}
}
handleHaibao()
} else {
return weui.alert("请先参与活动合成图片并打榜!")
}
return { success: true, data };
} else {
loading.hide()
ElMessage.error(data.message);
}
})
.catch((error) => {
loading.hide()
return { success: false, error };
});
} }
const openPeifang = (e) => { const openPeifang = (e) => {
const target = e.currentTarget const target = e.currentTarget

View File

@@ -6,9 +6,10 @@ export const ToastType = {
SHOW_RULE: "show_rule", SHOW_RULE: "show_rule",
SHOW_PRIZELIST: "show_prizelist", SHOW_PRIZELIST: "show_prizelist",
SHOW_LOTTERY: "show_lottery", SHOW_LOTTERY: "show_lottery",
SHOW_AD:"show_ad", SHOW_AD: "show_ad",
SHOW_ADDRESS:"show_address", SHOW_ADDRESS: "show_address",
MOUNTED: "mounted" MOUNTED: "mounted",
INFO_UPDATE: "info_update"
}; };
export default globalToastEvent; export default globalToastEvent;

View File

@@ -1,6 +1,10 @@
import { reactive } from "vue" import { reactive } from "vue"
export const globalStore = reactive({ export const globalStore = reactive({
first_share_today:false,
globalAudio: null,
userMutedMusic: false, // 用户是否手动静音了音乐
isFirstVisitHomePage: true, // 是否首次访问首页
select_template: '', select_template: '',
people_count: 0, people_count: 0,
draw_chances: 0, draw_chances: 0,
@@ -11,7 +15,6 @@ export const globalStore = reactive({
generateStatus: false, generateStatus: false,
generateImgTemplates: [], generateImgTemplates: [],
chartsBattle: false, chartsBattle: false,
invitees: 0,
followed_official: false, followed_official: false,
cap_scan: 0, cap_scan: 0,
game_chances_view_recipes: 0, game_chances_view_recipes: 0,
@@ -33,7 +36,4 @@ export const globalStore = reactive({
lotteryAdd () { lotteryAdd () {
this.lotteryCount++ this.lotteryCount++
}, },
updateViewRecipesCount () {
this.game_chances_view_recipes = this.game_chances_view_recipes >= this.MAX_VIEW_RECIPES_DAILY ? this.MAX_VIEW_RECIPES_DAILY : this.game_chances_view_recipes + 1
}
}) })

204
src/libs/faceValidator.js Normal file
View File

@@ -0,0 +1,204 @@
import * as faceapi from 'face-api.js'
// 模型加载状态
let modelsLoaded = false
/**
* 加载 face-api.js 模型
*/
export async function loadFaceApiModels() {
if (modelsLoaded) {
console.log('Face API 模型已经加载过了')
return true
}
try {
console.log('开始加载 Face API 模型...')
// 获取基础路径,处理 vite 的 base 配置
const basePath = import.meta.env.BASE_URL || '/'
const modelsPath = basePath.endsWith('/') ? basePath + 'models' : basePath + '/models'
console.log('模型加载路径:', modelsPath)
// 加载必需的模型
await Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri(modelsPath),
faceapi.nets.faceLandmark68Net.loadFromUri(modelsPath),
faceapi.nets.faceRecognitionNet.loadFromUri(modelsPath)
])
console.log('Face API 模型加载完成')
modelsLoaded = true
return true
} catch (error) {
console.error('Face API 模型加载失败:', error)
}
}
/**
* 检查模型是否已加载
*/
export function areModelsLoaded() {
return modelsLoaded
}
/**
* 验证图片中的人脸
* @param {File} file - 图片文件
* @returns {Promise<Object>} - 验证结果
*/
export async function validateFaceInImage(file) {
// 如果模型未加载,先加载模型
if (!modelsLoaded) {
const loaded = await loadFaceApiModels()
if (!loaded) {
return {
success: false,
message: '人脸识别模型加载失败,请刷新页面重试'
}
}
}
return new Promise((resolve) => {
const img = new Image()
img.onload = async () => {
try {
console.log('开始进行人脸检测...')
// 使用 TinyFaceDetector 进行人脸检测
const detections = await faceapi
.detectAllFaces(img, new faceapi.TinyFaceDetectorOptions({
inputSize: 416,
scoreThreshold: 0.3
}))
.withFaceLandmarks()
console.log(`检测到 ${detections.length} 张人脸`)
// 检查是否检测到人脸
if (detections.length === 0) {
resolve({
success: false,
message: '未检测到人脸,请上传包含清晰人脸的图片'
})
return
}
// 检查是否只有一张人脸
if (detections.length > 1) {
resolve({
success: false,
message: '检测到多张人脸,请上传只包含一张人脸的图片'
})
return
}
const detection = detections[0]
const confidence = detection.detection.score
console.log('人脸检测置信度:', confidence)
// 检查置信度是否足够高
const minConfidence = 0.3 // 降低到 0.6 以提高通过率
if (confidence < minConfidence) {
resolve({
success: false,
message: `人脸清晰度不够(置信度: ${(confidence * 100).toFixed(1)}%),请上传更清晰的人脸图片`
})
return
}
// 检查人脸大小(相对于图片尺寸)
const faceBox = detection.detection.box
const imageArea = img.naturalWidth * img.naturalHeight
const faceArea = faceBox.width * faceBox.height
const faceRatio = faceArea / imageArea
console.log('人脸占图片比例:', (faceRatio * 100).toFixed(2) + '%')
const minFaceRatio = 0.01 // 降低到 1.5% 以提高通过率
if (faceRatio < minFaceRatio) {
resolve({
success: false,
message: '人脸在图片中占比太小,请上传人脸更大更清晰的图片'
})
return
}
// 检查人脸角度(通过关键点判断)
if (detection.landmarks) {
const landmarks = detection.landmarks
const leftEye = landmarks.getLeftEye()
const rightEye = landmarks.getRightEye()
// 计算眼睛之间的角度来判断人脸是否正面
if (leftEye.length > 0 && rightEye.length > 0) {
const leftEyeCenter = leftEye[0]
const rightEyeCenter = rightEye[3]
const eyeAngle = Math.abs(
Math.atan2(
rightEyeCenter.y - leftEyeCenter.y,
rightEyeCenter.x - leftEyeCenter.x
) * 180 / Math.PI
)
console.log('人脸角度:', eyeAngle.toFixed(1) + '度')
const maxAngle = 30 // 放宽到 20 度
if (eyeAngle > maxAngle) {
resolve({
success: false,
message: '请上传正面人脸照片,避免侧脸或过度倾斜的角度'
})
return
}
}
}
// 所有验证通过
resolve({
success: true,
message: `人脸验证通过(置信度: ${(confidence * 100).toFixed(1)}%`,
confidence: confidence,
faceRatio: faceRatio,
faceBox: {
x: faceBox.x,
y: faceBox.y,
width: faceBox.width,
height: faceBox.height
}
})
} catch (error) {
console.error('人脸检测过程中出错:', error)
resolve({
success: false,
message: '人脸检测失败,请重试或更换图片'
})
}
}
img.onerror = () => {
resolve({
success: false,
message: '图片加载失败,请检查图片格式'
})
}
// 加载图片
const reader = new FileReader()
reader.onload = (e) => {
img.src = e.target.result
}
reader.onerror = () => {
resolve({
success: false,
message: '图片读取失败,请重试'
})
}
reader.readAsDataURL(file)
})
}

View File

@@ -0,0 +1,29 @@
import { globalStore } from "@/globalstore";
import { generateQR, Request } from "../libs/utils"
import Haibao from "@/libs/haibao"
import mask from "../assets/images/haibao-mask.webp"
import haibaoCoverBorder from "../assets/images/haibao-cover.webp"
export default async () => {
let userUrl = globalStore.result_url
if (!userUrl) {
const result = await Request('face/square', { my_only: 1, page: 1, per_page: 100 }, "GET", true)
if (result.res.status === 200) {
const dataHit = result.json.data.find(v => v.is_public)
if (!dataHit) {
return weui.alert("请先去参与打榜")
}
userUrl = dataHit.result_url
}
}
const haibaoCover = new Haibao(951, 1607)
haibaoCover.add(userUrl, 0, 50, 951, 1698)
haibaoCover.add(mask, 10, 100)
haibaoCover.add(haibaoCoverBorder, 0, 0)
await haibaoCover.draw('destination-in');
return await haibaoCover.generate({ mimeType: 'image/png' });
}

View File

@@ -99,6 +99,9 @@ export const getMiniPageBtnHack = (url) => {
export const miniJumpToScene = () => { export const miniJumpToScene = () => {
wx.miniProgram.navigateTo({ url: '/pages/unify/unify?orgId=200282401019674482&targetUrl=%2Fpages%2Fretail%2Forder%2Forder-list%3Ftab%3DAll%26topTab%3D1' }) wx.miniProgram.navigateTo({ url: '/pages/unify/unify?orgId=200282401019674482&targetUrl=%2Fpages%2Fretail%2Forder%2Forder-list%3Ftab%3DAll%26topTab%3D1' })
} }
export const miniJumpToActive = () => {
wx.miniProgram.navigateTo({ url: '/pages/retail-act/landing-page/ordinary?id=897432916524553363&orgId=200282401019674482&programId=84796583983972352' })
}
export const miniJumpToCouopon = () => { export const miniJumpToCouopon = () => {
wx.miniProgram.navigateTo({ wx.miniProgram.navigateTo({
url: '/pages/unify/unify?orgId=200282401019674482&targetUrl=%2Fpages%2Fcoupon%2Fcoupons-list' url: '/pages/unify/unify?orgId=200282401019674482&targetUrl=%2Fpages%2Fcoupon%2Fcoupons-list'
@@ -139,9 +142,8 @@ export const Request = async (url, data, type, noloading, noerror) => {
headers.Authorization = `Bearer ${Storage.get("userinfos").api_token}` headers.Authorization = `Bearer ${Storage.get("userinfos").api_token}`
} else { } else {
Storage.clear() Storage.clear()
weui.alert("错误的请求") weui.alert("登录失效,请重新登录")
window.location.reload() // window.location.reload()
return
} }
} }
@@ -192,94 +194,8 @@ export const Request = async (url, data, type, noloading, noerror) => {
return { res: response, json: result } return { res: response, json: result }
} else if (response.status == 401) { } else if (response.status == 401) {
Storage.clear() Storage.clear()
weui.alert("错误的请求") weui.alert("登录失效,请重新登录")
window.location.reload() // window.location.reload()
return
} else {
if (!noerror) {
weui.alert(message)
}
return { res: response, json: result }
}
} catch (error) {
if (!noerror) {
weui.alert(message)
}
loading && loading.hide()
}
}
export const RequestImg = async (url, data, type, noloading, noerror) => {
let headers = {
'Content-Type': 'multipart/form-data',
Accept: "application/json",
"Source": "faceFamily",
'App-Channel': getUserBrowersName(),
refer: document.referrer,
blackbox: Storage.get("blackbox") ? Storage.get("blackbox") : false
}
if (url != "sms/sendCode" && url != "sms/authPhone" && url != "wechat/login" && url != "wechat/jssdk") {
if (isLogin()) {
headers.Authorization = `Bearer ${Storage.get("userinfos").api_token}`
} else {
Storage.clear()
weui.alert("错误的请求")
window.location.reload()
return
}
}
if (isBaseLogin() && url == "sms/authPhone") {
headers.Authorization = `Bearer ${Storage.get("userinfos").api_token}`
}
let loading = false
if (!noloading) {
loading = weui.loading()
}
let message = "请求失败,请重试"
let fetchData = {
method: type || 'POST',
headers: new Headers(headers),
}
if (fetchData.method == "POST") {
fetchData.body = JSON.stringify(data)
}
let requrl = 'https://huodong2.lzlj.com/api/faceFamily/upload/image'
if (type === "GET") {
let paramArr = []
Object.keys(data).forEach(v => {
paramArr.push(`${v}=${data[v]}`)
})
requrl = paramArr.length === 0 ? `${requrl}` : `${requrl}?${paramArr.join("&")}`
}
try {
const response = await fetch(`${requrl}`, fetchData)
const result = await response.json()
message = result.message || message
if (getParam("debug")) {
console.log("url:", url)
console.log("data:", data)
console.log(response)
console.log(result)
}
loading && loading.hide()
if (response.status == 200 || response.status == 201) {
return { res: response, json: result }
} else if (response.status == 401) {
Storage.clear()
weui.alert("错误的请求")
window.location.reload()
return return
} else { } else {
if (!noerror) { if (!noerror) {

File diff suppressed because it is too large Load Diff

View File

@@ -50,7 +50,6 @@ import paidui_6 from '../assets/images/generate/template/paidui/paidui_6.webp'
const imageBackground = [ const imageBackground = [
{ {
id: 1, id: 1,
<<<<<<< HEAD
titleImgUrl: shenxian_bg, titleImgUrl: shenxian_bg,
children: [ children: [
{ {
@@ -60,31 +59,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: shenxian_2, imgUrl: shenxian_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: shenxian_3, imgUrl: shenxian_3,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: shenxian_4, imgUrl: shenxian_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: shenxian_5, imgUrl: shenxian_5,
peopleCount: 4 peopleCount: 4
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: shenxian_6, imgUrl: shenxian_6,
peopleCount: 5 peopleCount: 5
} }
@@ -92,7 +86,6 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
titleImgUrl: xianxia_bg, titleImgUrl: xianxia_bg,
children: [ children: [
{ {
@@ -102,31 +95,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: xianxia_2, imgUrl: xianxia_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: xianxia_3, imgUrl: xianxia_3,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: xianxia_4, imgUrl: xianxia_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: xianxia_5, imgUrl: xianxia_5,
peopleCount: 4 peopleCount: 4
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: xianxia_6, imgUrl: xianxia_6,
peopleCount: 5 peopleCount: 5
} }
@@ -134,7 +122,6 @@ const imageBackground = [
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
titleImgUrl: fugu_bg, titleImgUrl: fugu_bg,
children: [ children: [
{ {
@@ -144,31 +131,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: fugu_2, imgUrl: fugu_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: fugu_3, imgUrl: fugu_3,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: fugu_4, imgUrl: fugu_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: fugu_5, imgUrl: fugu_5,
peopleCount: 4 peopleCount: 4
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: fugu_6, imgUrl: fugu_6,
peopleCount: 5 peopleCount: 5
} }
@@ -176,7 +158,6 @@ const imageBackground = [
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
titleImgUrl: xinzhongshi_bg, titleImgUrl: xinzhongshi_bg,
children: [ children: [
{ {
@@ -186,31 +167,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: xinzhongshi_2, imgUrl: xinzhongshi_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: xinzhongshi_3, imgUrl: xinzhongshi_3,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: xinzhongshi_4, imgUrl: xinzhongshi_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: xinzhongshi_5, imgUrl: xinzhongshi_5,
peopleCount: 4 peopleCount: 4
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: xinzhongshi_6, imgUrl: xinzhongshi_6,
peopleCount: 5 peopleCount: 5
} }
@@ -218,7 +194,6 @@ const imageBackground = [
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
titleImgUrl: luying_bg, titleImgUrl: luying_bg,
children: [ children: [
{ {
@@ -228,31 +203,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: luying_2, imgUrl: luying_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: luying_3, imgUrl: luying_3,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: luying_4, imgUrl: luying_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: luying_5, imgUrl: luying_5,
peopleCount: 4 peopleCount: 4
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: luying_6, imgUrl: luying_6,
peopleCount: 5 peopleCount: 5
} }
@@ -260,7 +230,6 @@ const imageBackground = [
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
titleImgUrl: paidui_bg, titleImgUrl: paidui_bg,
children: [ children: [
{ {
@@ -270,31 +239,26 @@ const imageBackground = [
}, },
{ {
id: 2, id: 2,
<<<<<<< HEAD
imgUrl: paidui_2, imgUrl: paidui_2,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 3, id: 3,
<<<<<<< HEAD
imgUrl: paidui_3, imgUrl: paidui_3,
peopleCount: 2 peopleCount: 2
}, },
{ {
id: 4, id: 4,
<<<<<<< HEAD
imgUrl: paidui_4, imgUrl: paidui_4,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 5, id: 5,
<<<<<<< HEAD
imgUrl: paidui_5, imgUrl: paidui_5,
peopleCount: 3 peopleCount: 3
}, },
{ {
id: 6, id: 6,
<<<<<<< HEAD
imgUrl: paidui_6, imgUrl: paidui_6,
peopleCount: 5 peopleCount: 5
} }

View File

@@ -2,109 +2,109 @@ const imagePositionMaps = {
shenxian: { shenxian: {
1: { 1: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '38%', left: '38vw',
width: '55px' width: '13vw'
}, },
{ {
top: '56%', top: '114vw',
left: '57%', left: '57vw',
width: '55px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '43%', top: '86vw',
left: '39%', left: '39vw',
width: '55px' width: '13vw'
}, },
{ {
top: '56%', top: '114vw',
left: '60%', left: '60vw',
width: '55px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '49%', top: '98vw',
left: '30%', left: '30vw',
width: '55px' width: '13vw'
}, },
{ {
top: '47%', top: '95vw',
left: '53%', left: '53vw',
width: '55px' width: '13vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '40%', top: '80vw',
left: '31%', left: '31vw',
width: '50px' width: '11vw'
}, },
{ {
top: '36%', top: '72vw',
left: '61%', left: '61vw',
width: '50px' width: '11vw'
}, },
{ {
top: '62%', top: '124vw',
left: '40%', left: '40vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '39%', top: '76vw',
left: '32%', left: '32vw',
width: '44px' width: '10vw'
}, },
{ {
top: '36%', top: '72vw',
left: '54%', left: '54vw',
width: '44px' width: '10vw'
}, },
{ {
top: '60%', top: '118vw',
left: '43%', left: '43vw',
width: '44px' width: '10vw'
}, },
{ {
top: '55%', top: '107vw',
left: '68%', left: '68vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '42%', top: '84vw',
left: '26%', left: '26vw',
width: '40px' width: '8vw'
}, },
{ {
top: '39%', top: '76vw',
left: '43%', left: '43vw',
width: '40px' width: '8vw'
}, },
{ {
top: '39%', top: '76vw',
left: '59%', left: '59vw',
width: '40px' width: '8vw'
}, },
{ {
top: '44%', top: '88vw',
left: '68%', left: '68vw',
width: '40px' width: '8vw'
}, },
{ {
top: '53%', top: '106vw',
left: '41%', left: '41vw',
width: '40px' width: '8vw'
} }
] ]
}, },
@@ -112,114 +112,114 @@ const imagePositionMaps = {
xianxia: { xianxia: {
1: { 1: {
positions: [{ positions: [{
top: '46%', top: '93vw',
left: '33%', left: '33vw',
width: '55px' width: '13vw'
}, },
{ {
top: '46%', top: '93vw',
left: '61%', left: '61vw',
width: '55px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '37%', left: '37vw',
width: '55px' width: '13vw'
}, },
{ {
top: '55%', top: '110vw',
left: '55%', left: '55vw',
width: '55px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '40%', top: '80vw',
left: '34%', left: '34vw',
width: '55px' width: '13vw'
}, },
{ {
top: '44%', top: '88vw',
left: '57%', left: '57vw',
width: '55px' width: '13vw'
}, },
{ {
top: '61%', top: '123vw',
left: '38%', left: '38vw',
width: '55px' width: '13vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '43%', top: '86vw',
left: '37%', left: '37vw',
width: '50px' width: '11vw'
}, },
{ {
top: '45%', top: '90vw',
left: '58%', left: '58vw',
width: '50px' width: '11vw'
}, },
{ {
top: '61%', top: '123vw',
left: '42%', left: '42vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '43%', top: '86vw',
left: '28%', left: '28vw',
width: '44px' width: '10vw'
}, },
{ {
top: '41%', top: '83vw',
left: '55%', left: '55vw',
width: '44px' width: '10vw'
}, },
{ {
top: '55%', top: '110vw',
left: '46%', left: '46vw',
width: '44px' width: '10vw'
}, },
{ {
top: '47%', top: '95vw',
left: '68%', left: '68vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '42%', top: '84vw',
left: '35%', left: '35vw',
width: '40px' width: '8vw'
}, },
{ {
top: '37%', top: '74vw',
left: '53%', left: '53vw',
width: '40px' width: '8vw'
}, },
{ {
top: '40%', top: '80vw',
left: '71%', left: '71vw',
width: '40px' width: '8vw'
}, },
{ {
top: '52%', top: '103vw',
left: '27%', left: '27vw',
width: '40px' width: '8vw'
}, },
{ {
top: '55%', top: '110vw',
left: '54%', left: '54vw',
width: '40px' width: '8vw'
} }
] ]
}, },
@@ -227,109 +227,109 @@ const imagePositionMaps = {
fugu: { fugu: {
1: { 1: {
positions: [{ positions: [{
top: '35%', top: '71vw',
left: '39%', left: '39vw',
width: '55px' width: '13vw'
}, },
{ {
top: '41%', top: '83vw',
left: '56%', left: '56vw',
width: '55px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '45%', top: '90vw',
left: '34%', left: '34vw',
width: '55px' width: '13vw'
}, },
{ {
top: '45%', top: '90vw',
left: '53%', left: '53vw',
width: '55px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '43%', top: '86vw',
left: '40%', left: '40vw',
width: '55px' width: '13vw'
}, },
{ {
top: '51%', top: '103vw',
left: '61%', left: '61vw',
width: '55px' width: '13vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '46%', top: '93vw',
left: '29%', left: '29vw',
width: '50px' width: '11vw'
}, },
{ {
top: '36%', top: '72vw',
left: '55%', left: '55vw',
width: '50px' width: '11vw'
}, },
{ {
top: '646%', top: '93vw',
left: '69%', left: '69vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '34%', top: '69vw',
left: '35%', left: '35vw',
width: '44px' width: '10vw'
}, },
{ {
top: '38%', top: '77vw',
left: '54%', left: '54vw',
width: '44px' width: '10vw'
}, },
{ {
top: '49%', top: '98vw',
left: '32%', left: '32vw',
width: '44px' width: '10vw'
}, },
{ {
top: '53%', top: '106vw',
left: '59%', left: '59vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '33%', top: '65vw',
left: '49%', left: '49vw',
width: '40px' width: '8vw'
}, },
{ {
top: '36%', top: '72vw',
left: '70%', left: '70vw',
width: '40px' width: '8vw'
}, },
{ {
top: '49%', top: '98vw',
left: '34%', left: '34vw',
width: '40px' width: '8vw'
}, },
{ {
top: '50%', top: '101vw',
left: '49%', left: '49vw',
width: '40px' width: '8vw'
}, },
{ {
top: '56%', top: '114vw',
left: '62%', left: '62vw',
width: '40px' width: '8vw'
} }
] ]
}, },
@@ -337,109 +337,109 @@ const imagePositionMaps = {
xinzhongshi: { xinzhongshi: {
1: { 1: {
positions: [{ positions: [{
top: '51%', top: '103vw',
left: '31%', left: '31vw',
width: '60px' width: '13vw'
}, },
{ {
top: '46%', top: '93vw',
left: '48%', left: '48vw',
width: '60px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '58%', top: '118vw',
left: '29%', left: '29vw',
width: '60px' width: '13vw'
}, },
{ {
top: '39%', top: '76vw',
left: '47%', left: '47vw',
width: '60px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '45.5%', top: '94vw',
left: '34%', left: '34vw',
width: '40px' width: '8vw'
}, },
{ {
top: '47.5%', top: '97vw',
left: '59.5%', left: '59.5vw',
width: '40px' width: '8vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '39%', top: '76vw',
left: '37.5%', left: '37.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '42.5%', top: '86vw',
left: '59%', left: '59vw',
width: '50px' width: '11vw'
}, },
{ {
top: '59%', top: '120vw',
left: '50%', left: '50vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '40.5%', top: '83vw',
left: '46%', left: '46vw',
width: '44px' width: '10vw'
}, },
{ {
top: '41%', top: '83vw',
left: '66%', left: '66vw',
width: '44px' width: '10vw'
}, },
{ {
top: '47.5%', top: '95vw',
left: '30.5%', left: '30.5vw',
width: '44px' width: '10vw'
}, },
{ {
top: '53%', top: '106vw',
left: '59%', left: '59vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '26%', left: '26vw',
width: '36px' width: '8vw'
}, },
{ {
top: '41%', top: '83vw',
left: '47.6%', left: '47.6vw',
width: '36px' width: '8vw'
}, },
{ {
top: '52.5%', top: '107vw',
left: '26.4%', left: '26.4vw',
width: '36px' width: '8vw'
}, },
{ {
top: '58%', top: '118vw',
left: '44.5%', left: '44.5vw',
width: '36px' width: '8vw'
}, },
{ {
top: '49%', top: '98vw',
left: '67%', left: '67vw',
width: '36px' width: '8vw'
} }
] ]
}, },
@@ -447,109 +447,109 @@ const imagePositionMaps = {
luying: { luying: {
1: { 1: {
positions: [{ positions: [{
top: '49%', top: '99vw',
left: '33%', left: '33vw',
width: '60px' width: '13vw'
}, },
{ {
top: '53%', top: '106vw',
left: '50%', left: '50vw',
width: '60px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '48%', top: '99vw',
left: '33%', left: '33vw',
width: '60px' width: '13vw'
}, },
{ {
top: '57%', top: '115vw',
left: '58%', left: '58vw',
width: '60px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '53%', top: '106vw',
left: '39%', left: '39vw',
width: '60px' width: '13vw'
}, },
{ {
top: '53.5%', top: '109vw',
left: '57.2%', left: '57.2vw',
width: '60px' width: '13vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '45%', top: '90vw',
left: '29.5%', left: '29.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '44.5%', top: '90vw',
left: '57.6%', left: '57.6vw',
width: '50px' width: '11vw'
}, },
{ {
top: '53.4%', top: '110vw',
left: '45%', left: '45vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '49.7%', top: '100vw',
left: '24%', left: '24vw',
width: '44px' width: '10vw'
}, },
{ {
top: '47%', top: '95vw',
left: '61%', left: '61vw',
width: '44px' width: '10vw'
}, },
{ {
top: '57%', top: '115vw',
left: '34.5%', left: '34.5vw',
width: '44px' width: '10vw'
}, },
{ {
top: '55%', top: '110vw',
left: '49%', left: '49vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '42%', left: '42vw',
width: '40px' width: '8vw'
}, },
{ {
top: '43%', top: '86vw',
left: '63.6%', left: '63.6vw',
width: '40px' width: '8vw'
}, },
{ {
top: '50.5%', top: '103vw',
left: '28%', left: '28vw',
width: '40px' width: '8vw'
}, },
{ {
top: '51.4%', top: '105vw',
left: '51%', left: '52vw',
width: '40px' width: '8vw'
}, },
{ {
top: '57.5%', top: '118vw',
left: '68%', left: '70vw',
width: '40px' width: '8vw'
} }
] ]
}, },
@@ -557,104 +557,104 @@ const imagePositionMaps = {
paidui: { paidui: {
1: { 1: {
positions: [{ positions: [{
top: '46%', top: '93vw',
left: '31%', left: '31vw',
width: '60px' width: '13vw'
}, },
{ {
top: '42%', top: '84vw',
left: '48%', left: '48vw',
width: '60px' width: '13vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '49%', top: '98vw',
left: '35%', left: '35vw',
width: '60px' width: '13vw'
}, },
{ {
top: '48%', top: '99vw',
left: '54%', left: '54vw',
width: '60px' width: '13vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '57%', top: '115vw',
left: '30%', left: '30vw',
width: '50px' width: '11vw'
}, },
{ {
top: '41%', top: '83vw',
left: '51.2%', left: '51.2vw',
width: '50px' width: '11vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '37.5%', left: '37.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '44.4%', top: '89vw',
left: '64.6%', left: '64.6vw',
width: '50px' width: '11vw'
}, },
{ {
top: '56.4%', top: '116vw',
left: '48%', left: '48vw',
width: '50px' width: '11vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '43.7%', top: '88vw',
left: '29%', left: '29vw',
width: '44px' width: '10vw'
}, },
{ {
top: '40%', top: '80vw',
left: '44%', left: '44vw',
width: '44px' width: '10vw'
}, },
{ {
top: '46%', top: '93vw',
left: '64.5%', left: '64.5vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '38%', top: '77vw',
left: '28%', left: '28vw',
width: '40px' width: '8vw'
}, },
{ {
top: '40%', top: '80vw',
left: '56.6%', left: '56.6vw',
width: '40px' width: '8vw'
}, },
{ {
top: '49.5%', top: '101vw',
left: '37%', left: '37vw',
width: '40px' width: '8vw'
}, },
{ {
top: '52%', top: '106vw',
left: '53%', left: '53vw',
width: '40px' width: '8vw'
}, },
{ {
top: '53.5%', top: '108vw',
left: '71.2%', left: '72vw',
width: '40px' width: '8vw'
} }
] ]
}, },

View File

@@ -2,109 +2,109 @@ const positionMaps = {
shenxian: { shenxian: {
1: { 1: {
positions: [{ positions: [{
top: '37%', top: '74vw',
left: '36%', left: '36vw',
width: '76px' width: '18vw'
}, },
{ {
top: '52%', top: '105vw',
left: '55%', left: '55vw',
width: '76px' width: '18vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '38%', top: '75vw',
left: '38%', left: '38vw',
width: '70px' width: '16vw'
}, },
{ {
top: '51%', top: '102vw',
left: '58%', left: '58vw',
width: '70px' width: '16vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '43%', top: '86vw',
left: '28%', left: '28vw',
width: '72px' width: '17vw'
}, },
{ {
top: '41%', top: '83vw',
left: '51%', left: '51vw',
width: '72px' width: '17vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '35%', top: '70vw',
left: '30%', left: '30vw',
width: '60px' width: '14vw'
}, },
{ {
top: '31%', top: '62vw',
left: '59%', left: '59vw',
width: '60px' width: '14vw'
}, },
{ {
top: '57%', top: '114vw',
left: '38%', left: '38vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '34%', top: '68vw',
left: '30%', left: '30vw',
width: '58px' width: '13vw'
}, },
{ {
top: '31%', top: '62vw',
left: '52%', left: '52vw',
width: '58px' width: '13vw'
}, },
{ {
top: '55%', top: '110vw',
left: '41%', left: '41vw',
width: '58px' width: '13vw'
}, },
{ {
top: '50%', top: '99vw',
left: '66%', left: '66vw',
width: '58px' width: '13vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '38%', top: '76vw',
left: '25%', left: '25vw',
width: '50px' width: '11vw'
}, },
{ {
top: '35%', top: '70vw',
left: '42%', left: '42vw',
width: '50px' width: '11vw'
}, },
{ {
top: '35%', top: '70vw',
left: '57%', left: '57.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '40%', top: '80vw',
left: '67%', left: '67vw',
width: '50px' width: '11vw'
}, },
{ {
top: '49%', top: '99vw',
left: '40%', left: '40.5vw',
width: '50px' width: '11vw'
} }
] ]
}, },
@@ -112,114 +112,114 @@ const positionMaps = {
xianxia: { xianxia: {
1: { 1: {
positions: [{ positions: [{
top: '42%', top: '83vw',
left: '31%', left: '33vw',
width: '76px' width: '14vw'
}, },
{ {
top: '41%', top: '81vw',
left: '58%', left: '59vw',
width: '76px' width: '14vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '36%', top: '72vw',
left: '36%', left: '36vw',
width: '70px' width: '16vw'
}, },
{ {
top: '50%', top: '99vw',
left: '54%', left: '54vw',
width: '70px' width: '16vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '34%', top: '68vw',
left: '32%', left: '32vw',
width: '72px' width: '17vw'
}, },
{ {
top: '38%', top: '75vw',
left: '55%', left: '55vw',
width: '72px' width: '17vw'
}, },
{ {
top: '55%', top: '110vw',
left: '36%', left: '36vw',
width: '72px' width: '17vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '38%', top: '75vw',
left: '36%', left: '36vw',
width: '60px' width: '14vw'
}, },
{ {
top: '40%', top: '80vw',
left: '57%', left: '57vw',
width: '60px' width: '14vw'
}, },
{ {
top: '56%', top: '111vw',
left: '41%', left: '41vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '39%', top: '78vw',
left: '27%', left: '27vw',
width: '58px' width: '13vw'
}, },
{ {
top: '36%', top: '72vw',
left: '53%', left: '53vw',
width: '58px' width: '13vw'
}, },
{ {
top: '50%', top: '101vw',
left: '44%', left: '45vw',
width: '58px' width: '13vw'
}, },
{ {
top: '43%', top: '86vw',
left: '67%', left: '68vw',
width: '58px' width: '13vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '38%', top: '75vw',
left: '34%', left: '34vw',
width: '50px' width: '11vw'
}, },
{ {
top: '33%', top: '66vw',
left: '51.6%', left: '52.4vw',
width: '50px' width: '11vw'
}, },
{ {
top: '36%', top: '72vw',
left: '69%', left: '70vw',
width: '50px' width: '11vw'
}, },
{ {
top: '48%', top: '95vw',
left: '26%', left: '27vw',
width: '50px' width: '11vw'
}, },
{ {
top: '51%', top: '102vw',
left: '53%', left: '53vw',
width: '50px' width: '11vw'
} }
] ]
}, },
@@ -227,109 +227,109 @@ const positionMaps = {
fugu: { fugu: {
1: { 1: {
positions: [{ positions: [{
top: '30%', top: '60vw',
left: '38%', left: '38vw',
width: '70px' width: '16vw'
}, },
{ {
top: '36%', top: '72vw',
left: '54%', left: '54vw',
width: '70px' width: '16vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '40%', top: '80vw',
left: '32%', left: '32vw',
width: '74px' width: '17vw'
}, },
{ {
top: '40%', top: '80vw',
left: '51%', left: '51vw',
width: '74px' width: '17vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '39%', top: '79vw',
left: '39%', left: '39vw',
width: '72px' width: '17vw'
}, },
{ {
top: '46%', top: '92vw',
left: '59%', left: '59vw',
width: '72px' width: '17vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '28%', left: '28vw',
width: '60px' width: '14vw'
}, },
{ {
top: '31%', top: '62vw',
left: '54%', left: '54vw',
width: '60px' width: '14vw'
}, },
{ {
top: '41%', top: '83vw',
left: '68%', left: '68vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '30%', top: '60vw',
left: '33%', left: '34vw',
width: '58px' width: '13vw'
}, },
{ {
top: '34%', top: '68vw',
left: '52%', left: '53vw',
width: '58px' width: '13vw'
}, },
{ {
top: '45%', top: '90vw',
left: '30.5%', left: '30.5vw',
width: '58px' width: '13vw'
}, },
{ {
top: '48.5%', top: '98vw',
left: '57%', left: '57vw',
width: '58px' width: '13vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '29%', top: '59vw',
left: '48%', left: '48.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '32%', top: '64vw',
left: '68.6%', left: '69.6vw',
width: '50px' width: '11vw'
}, },
{ {
top: '44.5%', top: '89vw',
left: '33%', left: '33.5vw',
width: '50px' width: '11vw'
}, },
{ {
top: '46.2%', top: '93vw',
left: '47.4%', left: '48vw',
width: '50px' width: '11vw'
}, },
{ {
top: '52%', top: '105vw',
left: '61%', left: '61.5vw',
width: '50px' width: '11vw'
} }
] ]
}, },
@@ -337,109 +337,109 @@ const positionMaps = {
xinzhongshi: { xinzhongshi: {
1: { 1: {
positions: [{ positions: [{
top: '46%', top: '92vw',
left: '31%', left: '31vw',
width: '70px' width: '16vw'
}, },
{ {
top: '41%', top: '83vw',
left: '47%', left: '47vw',
width: '70px' width: '16vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '53%', top: '107vw',
left: '28%', left: '28vw',
width: '74px' width: '17vw'
}, },
{ {
top: '34%', top: '68vw',
left: '45%', left: '45vw',
width: '74px' width: '17vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '42%', top: '85vw',
left: '34%', left: '34vw',
width: '48px' width: '12vw'
}, },
{ {
top: '43.5%', top: '88vw',
left: '58.5%', left: '58.5vw',
width: '48px' width: '12vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '34%', top: '68vw',
left: '36.5%', left: '36.5vw',
width: '60px' width: '14vw'
}, },
{ {
top: '37.5%', top: '76vw',
left: '58%', left: '58vw',
width: '60px' width: '14vw'
}, },
{ {
top: '54%', top: '109vw',
left: '49%', left: '49vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '37%', top: '74vw',
left: '47%', left: '47vw',
width: '44px' width: '10vw'
}, },
{ {
top: '36.5%', top: '73vw',
left: '66%', left: '66vw',
width: '44px' width: '10vw'
}, },
{ {
top: '43%', top: '86vw',
left: '30.5%', left: '30.5vw',
width: '44px' width: '10vw'
}, },
{ {
top: '49%', top: '99vw',
left: '59%', left: '59vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '38%', top: '75vw',
left: '25%', left: '25vw',
width: '48px' width: '12vw'
}, },
{ {
top: '37%', top: '74vw',
left: '46.6%', left: '46.6vw',
width: '48px' width: '12vw'
}, },
{ {
top: '48.5%', top: '98vw',
left: '25%', left: '25vw',
width: '48px' width: '12vw'
}, },
{ {
top: '54%', top: '109vw',
left: '43%', left: '43vw',
width: '48px' width: '12vw'
}, },
{ {
top: '45%', top: '90vw',
left: '65%', left: '65vw',
width: '48px' width: '12vw'
} }
] ]
}, },
@@ -447,109 +447,109 @@ const positionMaps = {
luying: { luying: {
1: { 1: {
positions: [{ positions: [{
top: '44%', top: '89vw',
left: '33%', left: '33vw',
width: '70px' width: '16vw'
}, },
{ {
top: '48%', top: '96vw',
left: '49%', left: '49vw',
width: '70px' width: '16vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '43.5%', top: '88vw',
left: '32%', left: '33vw',
width: '74px' width: '17vw'
}, },
{ {
top: '52%', top: '104vw',
left: '57%', left: '58vw',
width: '74px' width: '17vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '45%', top: '90vw',
left: '38%', left: '38vw',
width: '74px' width: '17vw'
}, },
{ {
top: '45.5%', top: '91vw',
left: '55.5%', left: '55.5vw',
width: '74px' width: '17vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '40%', top: '80vw',
left: '28.5%', left: '28.5vw',
width: '60px' width: '14vw'
}, },
{ {
top: '39.5%', top: '79vw',
left: '56%', left: '56vw',
width: '60px' width: '14vw'
}, },
{ {
top: '49%', top: '99vw',
left: '44%', left: '44vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '45.7%', top: '91vw',
left: '24%', left: '24vw',
width: '44px' width: '10vw'
}, },
{ {
top: '43%', top: '86vw',
left: '61%', left: '61vw',
width: '44px' width: '10vw'
}, },
{ {
top: '53%', top: '107vw',
left: '34.5%', left: '34.5vw',
width: '44px' width: '10vw'
}, },
{ {
top: '51%', top: '102vw',
left: '49%', left: '49.5vw',
width: '44px' width: '10vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '37.5%', top: '76vw',
left: '42%', left: '42vw',
width: '48px' width: '12vw'
}, },
{ {
top: '39%', top: '79vw',
left: '62.6%', left: '62.6vw',
width: '48px' width: '12vw'
}, },
{ {
top: '46.5%', top: '93vw',
left: '27%', left: '27vw',
width: '48px' width: '12vw'
}, },
{ {
top: '47.4%', top: '95vw',
left: '50%', left: '50vw',
width: '48px' width: '12vw'
}, },
{ {
top: '53.5%', top: '108vw',
left: '67%', left: '68vw',
width: '48px' width: '12vw'
} }
] ]
}, },
@@ -557,104 +557,104 @@ const positionMaps = {
paidui: { paidui: {
1: { 1: {
positions: [{ positions: [{
top: '41%', top: '83vw',
left: '31%', left: '31vw',
width: '70px' width: '16vw'
}, },
{ {
top: '37%', top: '74vw',
left: '47%', left: '47vw',
width: '70px' width: '16vw'
} }
] ]
}, },
2: { 2: {
positions: [{ positions: [{
top: '44%', top: '89vw',
left: '34%', left: '34vw',
width: '74px' width: '17vw'
}, },
{ {
top: '43.5%', top: '88vw',
left: '52%', left: '52vw',
width: '74px' width: '17vw'
} }
] ]
}, },
3: { 3: {
positions: [{ positions: [{
top: '51%', top: '102vw',
left: '29%', left: '29vw',
width: '60px' width: '14vw'
}, },
{ {
top: '35.2%', top: '71vw',
left: '49.5%', left: '49.5vw',
width: '60px' width: '14vw'
} }
] ]
}, },
4: { 4: {
positions: [{ positions: [{
top: '36%', top: '72vw',
left: '36.5%', left: '36.5vw',
width: '60px' width: '14vw'
}, },
{ {
top: '39.5%', top: '79vw',
left: '54%', left: '54vw',
width: '60px' width: '14vw'
}, },
{ {
top: '52%', top: '105vw',
left: '47%', left: '47vw',
width: '60px' width: '14vw'
} }
] ]
}, },
5: { 5: {
positions: [{ positions: [{
top: '40%', top: '80vw',
left: '27.5%', left: '27.5vw',
width: '60px' width: '14vw'
}, },
{ {
top: '36.5%', top: '73vw',
left: '42%', left: '42vw',
width: '60px' width: '14vw'
}, },
{ {
top: '42%', top: '85vw',
left: '62.5%', left: '62.5vw',
width: '60px' width: '14vw'
} }
] ]
}, },
6: { 6: {
positions: [{ positions: [{
top: '35%', top: '70vw',
left: '28%', left: '28vw',
width: '46px' width: '11vw'
}, },
{ {
top: '37%', top: '74vw',
left: '55.6%', left: '55.6vw',
width: '46px' width: '11vw'
}, },
{ {
top: '46.5%', top: '93vw',
left: '36%', left: '36vw',
width: '46px' width: '11vw'
}, },
{ {
top: '48.5%', top: '98vw',
left: '52%', left: '52vw',
width: '46px' width: '11vw'
}, },
{ {
top: '50%', top: '99vw',
left: '71%', left: '71vw',
width: '46px' width: '11vw'
} }
] ]
}, },