Compare commits

...

86 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
xiaoaojiao
60b2b56f30 merge 2025-09-15 11:58:34 +08:00
xiaoaojiao
b5ad0ebd12 merge 2025-09-15 11:55:29 +08:00
yixu
450c3b1ccc update 2025-09-15 11:45:50 +08:00
xiaoaojiao
436d9323e7 merge 2025-09-14 23:33:25 +08:00
xiaoaojiao
2ee3758c30 路由二级目录 2025-09-14 23:32:04 +08:00
78 changed files with 3490 additions and 2255 deletions

108
agreement.html Normal file
View File

@@ -0,0 +1,108 @@
<h3 style="font-size:14px;margin-bottom:10px;text-align:center;">泸州老窖会员中心隐私条款</h3>
<h4 style="font-size:14px;margin-bottom:10px;text-align:center;">用户协议与隐私条款</h4>
<p style="font-size:12px;margin-bottom:10px;">尊敬的客户,在您使用我们的服务前,请仔细阅读本协议与隐私条款(以下简称协议)。</p>
<p style="font-size:12px;margin-bottom:10px;">
本协议是您与泸州老窖股份有限公司就泸州老窖会员中心相关事宜共同定立的契约。本协议经您通过点击同意即构成对本协议平等主体有约束力、执行力的法律文件。本协议可由我们不时作出修订,且构成您与我们之间达成的有关会员服务使用、具有约束力的协议。您在本协议修订发布后继续使用泸州老窖会员服务,即视为您已接受了修订。如果您不同意本协议或相关修订,则应立即停止注册程序及使用、享受泸州老窖会员中心服务。
</p>
<p style="font-size:12px;margin-bottom:10px;">
如果您不满十八18周岁或其他无民事行为能力/限制民事行为能力的情形,您应确保与您的父母或监护人共同阅读本协议,以便您的父母或监护人理解并同意本协议的内容。您点击同意本协议或使用泸州老窖会员服务后,即视为您确认本人具有享受泸州老窖会员中心服务、下单购物等相应的权利能力和行为能力,能够独立承担法律责任。若您不具备前述行为相适应的民事行为能力,则您与您父母或监护人应依照法律规定承担因此而导致的一切后果。
</p>
<p style="font-size:12px;margin-bottom:10px;">泸州老窖会员中心保留在法律允许的范围内独自决定拒绝服务、关闭用户账户、清除或编辑内容、取消订单的权利。</p>
<p style="font-size:12px;margin-bottom:10px;"><strong>一、用户协议</strong></p>
<p style="font-size:12px;margin-bottom:10px;">
1泸州老窖会员中心可在加以或不加以通知的情况下随时终止会员计划。从宣布计划终止之日起会员将在规定的时间内继续累积积分并兑换期望的奖励。在泸州老窖宣布计划终止十二个月后无论您在参加计划期间所累积的积分数额如何泸州老窖均有权终止您累积积分和兑换奖励的权利。
</p>
<p style="font-size:12px;margin-bottom:10px;">
2. 泸州老窖会员中心保留在加以或不加以通知的情况下,全权决定添加、修改、删除或以其他方式调整与计划相关的任何规则、程序、条件、优惠或奖励的权利,即使这些修改可能会影响已累积的积分、奖励礼券或其他的具体价值。即泸州老窖会员中心可以做出影响范围不限于如下对象的修改:积分的赚取和兑换规则、奖励积分的使用规则和程序、奖励是否持续提供、奖励类型和特别优惠。
</p>
<p style="font-size:12px;margin-bottom:10px;">
3泸州老窖会员身份将赋予会员赚取积分的权利而积分可参照本协议适用条款兑换奖励。我们将竭诚为会员提供优惠和奖励但若为会员居住国的法律或法规所禁止则将无法提供。</p>
<p style="font-size:12px;margin-bottom:10px;">
4. 若会员以违反本协议适用条款的规定或初衷或任意规定(包括但不限于奖励积分兑换活奖励礼券的使用)的方式使用本计划时,泸州老窖会员中心会保留暂停或终止其会籍的权利。此外,泸州老窖会员中心也保留权利,若怀疑会员有以下行为,可自行全权判断并终止其会籍:
</p>
<p style="font-size:12px;margin-bottom:10px;">a违反相关法律、法规或条例的行为</p>
<p style="font-size:12px;margin-bottom:10px;">b违背或违反本协议的适用条款</p>
<p style="font-size:12px;margin-bottom:10px;">c任何欺诈或不诚实的行为、盗窃或与会员账户相关包括但不限于奖励兑换、礼券使用或其他会员礼遇的不当或不道德行为
由于以上原因导致会籍终止,可能会导致所有的已累计积分丢失,且对应礼券和礼遇、等级被取消。除终止会籍外,泸州老窖会员中心还有权视必要程度,采取适当的行政和法律措施,包括但不限于刑事诉讼。</p>
<p style="font-size:12px;margin-bottom:10px;">
5、在未经泸州老窖会员中心许可的情况下不可对任何泸州老窖会员的积分、奖励礼券或泸州老窖会员中心的其他礼遇进行销售和交易。任何被泸州老窖单方面确认的任何以违反本协议适用条款的方式转让、销售或分配的积分、礼券或礼遇均可能会被没收或取消。
</p>
<p style="font-size:12px;margin-bottom:10px;"><strong>二、隐私条款</strong></p>
<p style="font-size:12px;margin-bottom:10px;">1. 用户许可</p>
<p style="font-size:12px;margin-bottom:10px;">1.1  我们允许您在本协议范围内享有个人的、非排他性的、不可转让的使用泸州老窖会员中心的权利。但您不得有以下行为:</p>
<p style="font-size:12px;margin-bottom:10px;">
1.1.1 以任何方式出售、转让、分发、修改或传播泸州老窖会员中心或与泸州老窖会员中心有关的文字、图片、音乐、条形码、视频、数据、超链接、展示及其他内容(“内容”);</p>
<p style="font-size:12px;margin-bottom:10px;">1.1.2 储存或发送淫秽、诽谤、暴力或者其他非法资料;</p>
<p style="font-size:12px;margin-bottom:10px;">1.1.3 储存或发送包含软件病毒或其他有害的计算机的程序资料;</p>
<p style="font-size:12px;margin-bottom:10px;">1.1.4 利用服务或泸州老窖会员中心小程序进行违法犯罪活动;</p>
<p style="font-size:12px;margin-bottom:10px;">
<p style="font-size:12px;margin-bottom:10px;">1.1.5 利用服务或泸州老窖会员中心小程序侵犯他人合法权益;</p>
<p style="font-size:12px;margin-bottom:10px;">1.1.6 利用服务或泸州老窖会员中心小程序影响网络的正常运行;</p>
<p style="font-size:12px;margin-bottom:10px;">1.1.7 损害泸州老窖会员中心小程序数据的完整性或性能。</p>
<p style="font-size:12px;margin-bottom:10px;">本用户许可同样适用于泸州老窖会员服务的任何更新、补充或替代产品,但相关更新、补充或替代产品中有相反规定的除外。</p>
<p style="font-size:12px;margin-bottom:10px;">本用户许可同样适用于泸州老窖会员服务的任何更新、补充或替代产品,但相关更新、补充或替代产品中有相反规定的除外。</p>
<p style="font-size:12px;margin-bottom:10px;">2. 注册账号、密码及安全性</p>
<p style="font-size:12px;margin-bottom:10px;">2.1 注册资格 您承诺:您具有完全民事权利能力和兴文能力或不具有完全民事权利能力和行为能力但经您的法定代理人同意并由其代理注册泸州老窖会员服务。
</p>
<p style="font-size:12px;margin-bottom:10px;">2.2 注册流程:您同意根据泸州老窖会员注册页面的要求提供手机号码并通过认证程序注册账号,或者通过微信授权快速注册账号。您将对账号安全负全部责任。
</p>
<p style="font-size:12px;margin-bottom:10px;">2.3 您成功注册后,您同意接受我们发送的与泸州老窖会员管理、运营相关的微信订阅号/微信服务号/或微信服务信息/或电子邮件/或短消息。</p>
<p style="font-size:12px;margin-bottom:10px;">
2.4 注册成功后,您有权根据泸州老窖会员中心相关页面公示的服务规则获取泸州老窖的相关自安息、发送订单、授权我们通过您指定的账户划扣服务费用并享受其他相关服务。</p>
<p style="font-size:12px;margin-bottom:10px;">2.5 您若发现任何非法使用用户账号或存在安全漏洞的情况,请立即反馈给我们。</p>
<p style="font-size:12px;margin-bottom:10px;">3. 用户信息保护</p>
<p style="font-size:12px;margin-bottom:10px;">
3.1 您同意向泸州老窖会员中心提供某些信息包括但不限于身份识别信息、平台操作信息、位置信息、支付信息、个人信用信息以及其他根据我们的产品和需要而手机的您的个人信息(“用户信息”)。</p>
<p style="font-size:12px;margin-bottom:10px;">3.2 您同意向我们传输用户信息,并授权我们在泸州老窖会员功能所需的范围内以本协议所述的目的记录、处理及存储上述用户信息。</p>
<p style="font-size:12px;margin-bottom:10px;">3.3 我们通过以下方式收集、分享、使用您的用户信息:</p>
<p style="font-size:12px;margin-bottom:10px;">
3.3.1 为了向您提供更加便捷、人性化的服务,我们可能需要您提供一些个人信息,包括:姓名、地址、电话号码等个人资料。为了保证您能够享受更好的服务,您需要及时更新上述注册资料,否则我们可能因为您资料不准确而无法提供服务。</p>
<p style="font-size:12px;margin-bottom:10px;">3.3.2 如果您将泸州老窖会员中心与您第三方支付平台的账户关联,您需要授权我们通过您指定的账户划扣服务费。</p>
<p style="font-size:12px;margin-bottom:10px;">3.3.3 为了向您提供更便捷的售前服务(如查询附近门店)以及售后服务等,泸州老窖会员中心小程序将会使用、保存您的位置信息、交易信息、操作信息等。
</p>
<p style="font-size:12px;margin-bottom:10px;">3.3.4 为了改进服务质量,我们会向您征集反馈意见,包括您参与的问卷调查、在线意见反馈、客户投诉等。</p>
<p style="font-size:12px;margin-bottom:10px;">3.3.5 以其他方式收集用户信息。</p>
<p style="font-size:12px;margin-bottom:10px;">
3.4 除手机号码外,您的头像、姓名、性别、生日、邮箱等信息均为选填信息,您可以选择是否填写。如您填写上述信息,我们也仅会从为您提供更好的服务的角度使用上述信息。</p>
<p style="font-size:12px;margin-bottom:10px;">
3.5 我们将采取技术措施和其他必要措施,确保用户信息安全,防止在本服务中收集的用户信息泄露。在发生前述情形或我们发现存在前述情形的可能时将及时采取措施补救。</p>
<p style="font-size:12px;margin-bottom:10px;">3.6 我们承诺未经过您的同意不将您的个人信息任意披露。但在以下情形下,我们将无法做出前述保证并披露您的相关信息。这些情形包括但不限于:</p>
<p style="font-size:12px;margin-bottom:10px;">
3.6.1 为了您的服务、交易顺利完成,我们不得不把您的某些用户信息,如您的姓名、电话、配送地址等提供给相关服务方,以便于他们及时与您取得联系,提供服务;</p>
<p style="font-size:12px;margin-bottom:10px;">
3.6.2 当您在泸州老窖会员中心小程序的行为违反服务条款,或可能损害他人权益或导致他人遭受损害,只要我们相信披露您的用户信息是为了辨识、联络或采取法律行动所必须的行动时;</p>
<p style="font-size:12px;margin-bottom:10px;">3.6.3 根据法律法规规定必须披露或公开的用户信息;</p>
<p style="font-size:12px;margin-bottom:10px;">3.6.4 有权机关依法执行公务,要求提供特定用户信息;</p>
<p style="font-size:12px;margin-bottom:10px;">3.6.5 您与我们及合作单位之间就用户信息的使用公开达成约定,我们因此向合作单位公开用户信息;</p>
<p style="font-size:12px;margin-bottom:10px;">3.6.6 任何由于黑客攻击电脑病毒侵入或其他不可抗力事件导致用户信息的泄露。</p>
<p style="font-size:12px;margin-bottom:10px;">3.7 您同意我们在以下事项中使用用户信息:</p>
<p style="font-size:12px;margin-bottom:10px;">3.7.1 向您及时发送重要的通知,如软件更新、本协议条款变更;</p>
<p style="font-size:12px;margin-bottom:10px;">3.7.2 进行审计数据分析和研究等,以改进产品服务及与用户之间的沟通;</p>
<p style="font-size:12px;margin-bottom:10px;">3.7.3 依照本协议约定,我们管理、审查用户信息及采取处理的措施;</p>
<p style="font-size:12px;margin-bottom:10px;">3.7.4 适用法律法规规定的其他事项。</p>
<p style="font-size:12px;margin-bottom:10px;">除上述事项外,未取得您事先同意,我们不会将用户信息用于其他任何用途。</p>
<p style="font-size:12px;margin-bottom:10px;">4. 责任</p>
<p style="font-size:12px;margin-bottom:10px;">
4.1 我们向您提供的预定信息仅供您参考并不构成保证。我们将在合理的范围内尽力保证该等信息准确但无法保证其中没有任何错误。由于会员中心小程序的功能受到客观技术条件的影响您理解并同意小程序在起使用过程中发生暂时中断是正常的现象。我们不能保证小程序的功能不会发生中断或不出现差错也不能保证CRM的网站或服务器不存在病毒或其他有害成分。
</p>
<p style="font-size:12px;margin-bottom:10px;">4.2 您通过小程序请求的产品和服务质量有泸州老窖负责控制和监督。</p>
<p style="font-size:12px;margin-bottom:10px;">4.3 我们将不承担任何基于不可抗力等非人为因素给您造成的损失。不可抗力包括但不限于:</p>
<p style="font-size:12px;margin-bottom:10px;">4.3.1 大雾、雷雨、沙尘、道路积雪、结冰、低能见度等危及行车安全的恶劣气象条件;</p>
<p style="font-size:12px;margin-bottom:10px;">4.3.2 洪涝、台风、冰雹、暴雪、地震、山地崩塌、滑坡、泥石流、海啸等自然灾害;</p>
<p style="font-size:12px;margin-bottom:10px;">4.3.3 公安机关交通部门在集会游行、大型运动会、道路桥梁建设、救灾抢险等情形下实施的交通管制等措施;</p>
<p style="font-size:12px;margin-bottom:10px;">4.3.4 黑客攻击、电信部门技术调整导致之重大影响、因政府管制二造成之暂时关闭、病毒侵袭等事件。</p>
<p style="font-size:12px;margin-bottom:10px;">4.4 我们对于您的以下行为引起的直接、间接、偶然及继起的损害不负责任:</p>
<p style="font-size:12px;margin-bottom:10px;">4.4.1 不正当使用服务;</p>
<p style="font-size:12px;margin-bottom:10px;">4.4.2 故意隐瞒重要信息;</p>
<p style="font-size:12px;margin-bottom:10px;">4.4.3 传送的信息不符合规定等。</p>
<p style="font-size:12px;margin-bottom:10px;">4.5 在适用法律允许的最大范围内,在任何情况下,</p>
<p style="font-size:12px;margin-bottom:10px;">a.我们均不就小程序的使用对用户承担责任;</p>
<p style="font-size:12px;margin-bottom:10px;">b.不就任何间接的、特殊的、偶然的、附随的或惩罚性的损害对您承担责任,包括但不限于商誉损失、利润损失、用户信息丢失、失窃</p>
<p style="font-size:12px;margin-bottom:10px;">5. 知识产权</p>
<p style="font-size:12px;margin-bottom:10px;">
泸州老窖标识以及与泸州老窖会员相关的其他泸州老窖商标、服务标志、图像和标识均为泸州老窖的商标或注册商标。与泸州老窖会员相关的其他商标、服务标志、图像和标识为其各自所有人的商标。未经泸州老窖或相关商标持有人的事先书面许可,用户不得全部或部门复制、模仿或使用泸州老窖标志或第三方标志。小程序和内容受到与著作权、商标、专利、商业秘密及其他专有权利相关的国际条约、法律、法规、行政规章等规定的保护,您可在泸州老窖或内容所有人授权的情况下使用包含数字信息的安全组件。
</p>
<p style="font-size:12px;margin-bottom:10px;">6. 合约期限及变更、终止:我们和您订立的这份协议是无固定期间协议。</p>
<p style="font-size:12px;margin-bottom:10px;">7. 其他</p>
<p style="font-size:12px;margin-bottom:10px;">7.1 本用户协议部分条款或附件无效或终止的,我们有权根据其他情况选择是否继续履行其他条款。</p>
<p style="font-size:12px;margin-bottom:40px;">7.2 本协议适用中国法律。本协议履行中发生的任何争议,由泸州老窖股份有限公司所在地人民法院管辖。</p>

View File

@@ -9,7 +9,7 @@
<meta content="telephone=no,email=no" name=format-detection>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui" />
<title>basecode</title>
<title>Ai在一起 金饼送给你</title>
<script>
const isWeixinPlatform = /MicroMessenger/i.test(window.navigator.userAgent) || window.__wxjs_environment === 'miniprogram'
if (isWeixinPlatform) {
@@ -34,7 +34,7 @@
const org_id = getParam("org_id")
const code = getParam("code")
const appid = "wx718c4a40911b7837"
const host = "https://huodong2.lzlj.com/iceSip/"
const host = "https://huodong2.lzlj.com/faceFamily/"
if (isWeixinPlatform && !isLogin && !code) {
let url = encodeURIComponent(host)
@@ -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-size: 10% 10%;
}
.preload {
display: none;
}
</style>
<link rel="stylesheet" href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.6.16/weui.min.css">
</head>
<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>
<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>
@@ -84,7 +94,7 @@
window.onload = async function () {
if (/MicroMessenger/i.test(window.navigator.userAgent)) {
try {
const response = await fetch(`https://huodong2.lzlj.com/api/iceSip/wechat/jssdk`, {
const response = await fetch(`https://huodong2.lzlj.com/api/faceFamily/wechat/jssdk`, {
method: "POST",
headers: new Headers({
'Content-Type': 'application/json',
@@ -109,8 +119,8 @@
const shareData = {
title: document.title,
desc: document.title,
link: "https://huodong2.lzlj.com/iceSip/",
imgUrl: "https://huodong2.lzlj.com/iceSip/share.webp"
link: "https://huodong2.lzlj.com/faceFamily/",
imgUrl: "https://huodong2.lzlj.com/faceFamily/share.webp"
}
wx.updateAppMessageShareData({
title: shareData.title, // 分享标题
@@ -135,7 +145,7 @@
var _hmt = _hmt || [];
(function () {
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];
s.parentNode.insertBefore(hm, s);
})();

View File

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

60
pnpm-lock.yaml generated
View File

@@ -17,6 +17,9 @@ importers:
element-plus:
specifier: ^2.11.1
version: 2.11.1(vue@3.5.20)
face-api.js:
specifier: ^0.22.2
version: 0.22.2
gsap:
specifier: ^3.13.0
version: 3.13.0
@@ -506,6 +509,10 @@ packages:
'@sxzz/popperjs-es@2.11.7':
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':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
@@ -515,9 +522,21 @@ packages:
'@types/lodash@4.17.20':
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':
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':
resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -729,6 +748,9 @@ packages:
resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==}
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:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -878,6 +900,10 @@ packages:
engines: {node: ^18 || >=20}
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:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
@@ -975,6 +1001,9 @@ packages:
resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
engines: {node: '>=18'}
seedrandom@2.4.3:
resolution: {integrity: sha512-2CkZ9Wn2dS4mMUWQaXLsOAfGD+irMlLEeSP3cMxpGbgyOOzJGFa+MWCOMTOCMyZinHRPxyOj/S/C57li/1to6Q==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -1030,6 +1059,9 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
unicorn-magic@0.3.0:
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
engines: {node: '>=18'}
@@ -1568,6 +1600,15 @@ snapshots:
'@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/lodash-es@4.17.12':
@@ -1576,8 +1617,16 @@ snapshots:
'@types/lodash@4.17.20': {}
'@types/offscreencanvas@2019.3.0': {}
'@types/seedrandom@2.4.27': {}
'@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)':
dependencies:
'@babel/core': 7.28.3
@@ -1877,6 +1926,11 @@ snapshots:
strip-final-newline: 4.0.0
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):
optionalDependencies:
picomatch: 4.0.3
@@ -1976,6 +2030,8 @@ snapshots:
nanoid@5.1.5: {}
node-fetch@2.1.2: {}
node-releases@2.0.19: {}
normalize-wheel-es@1.2.0: {}
@@ -2075,6 +2131,8 @@ snapshots:
run-applescript@7.0.0: {}
seedrandom@2.4.3: {}
semver@6.3.1: {}
set-blocking@2.0.0: {}
@@ -2120,6 +2178,8 @@ snapshots:
totalist@3.0.1: {}
tslib@1.14.1: {}
unicorn-magic@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

@@ -80,11 +80,11 @@ const handleLoginSuccess = async () => {
await initUserGameInfos(true, true)
}
if (isLogin()) {
handleLoginSuccess()
} else {
userStatus(handleLoginSuccess)
}
// if (isLogin()) {
// handleLoginSuccess()
// } else {
// userStatus(handleLoginSuccess)
// }
const getUserLottery = async () => {
const result = await Request("lottery", { pool: "all" }, "GET")
if (result.res.status === 200) {
@@ -140,7 +140,7 @@ globalToastEvent.on(ToastType.SHOW_ADDRESS, (id) => {
<Address :show="addressShow" :prizeId="activePrizeId" @address-submit="handleAddressSubmitAfter"
@address-close="addressShow = false"></Address>
<Ad :show="adShow" @close="adShow = false"></Ad>
<Lottery :show="lotteryShow" @close="lotteryShow = false"></Lottery>
<!-- <Lottery :show="lotteryShow" @close="lotteryShow = false"></Lottery> -->
</template>
<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>
import ModalTransition from "./ModalTransition.vue"
import { ref } from "vue"
import { isWeixinPlatform, miniJumpToScene, getMiniPageBtnHack } from "../libs/utils"
import { isWeixinPlatform, miniJumpToActive, getMiniPageBtnHack } from "../libs/utils"
const props = defineProps({
show: false,
})
const emit = defineEmits(['close'])
const adHtml = ref('')
//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 = () => {
if (!isWeixinPlatform()) {
weui.alert("请前往「泸州老窖会员中心」小程序进行查询")
}else{
miniJumpToActive()
}
}
</script>
<style scoped>
<style>
.ad-wrapper {
position: relative;
width: 100vw;
@@ -48,7 +50,13 @@ const adGoto = () => {
background-size: 100%;
}
.close {
.btn-ad wx-open-launch-weapp#launch-btn{
width: 100%;
height: 100%;
display: block !important;
}
.ad .close {
position: absolute;
width: 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 MyPhoto from './MyPhoto.vue'
import PhotoSquare from './PhotoSquare.vue'
import { loadFaceApiModels, validateFaceInImage } from "../libs/faceValidator.js"
defineProps({
show: true
})
onMounted(() => {
onMounted(async () => {
await loadFaceApiModels()
})
import { ElMessage } from 'element-plus';
import { Plus } from '@element-plus/icons-vue';
import { tr } from "element-plus/es/locales.mjs"
const router = useRouter();
// 上传前的校验
const beforeUpload = (file) => {
// 基础格式校验
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
ElMessage.error('只能上传JPG或PNG格式的图片!');
return false;
}
const isLt2M = file.size / 1024 / 1024 < 2;
const isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) {
ElMessage.error('图片大小不能超过2MB!');
ElMessage.error('图片大小不能超过10MB!');
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 filename = url.split('/').pop();
const matchedTemplate = faceTemplate.find(template => template.name === filename);
const matchedTemplate = faceTemplate.find(template => filename.includes(template.name));
if (!matchedTemplate) {
console.error(`No template found for filename: ${filename}`);
return null;
@@ -113,8 +157,20 @@ const clearUploadFile = (index) => {
if (uploadRefs.value[index]) {
uploadRefs.value[index].clearFiles();
uploadItems.value[index].imageUrl = '';
uploadedFiles.splice(index, 1);
// 获取 templateFaceID
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);
}
}
};
@@ -128,6 +184,10 @@ const displayScanImg = ref(false);
const disableScanAnimation = ref(false);
const generateImage = async (options) => {
console.log(uploadedFiles);
if (uploadedFiles.length === 0) {
weui.alert("请上传头像照片!")
return false;
}
globalStore.generateStatus = true;
displayScanImg.value = true;
const urlParams = new URLSearchParams(window.location.search);
@@ -156,7 +216,7 @@ const generateImage = async (options) => {
try {
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',
headers: {
'Content-Type': 'application/json',
@@ -165,53 +225,59 @@ const generateImage = async (options) => {
},
body: JSON.stringify(formData)
});
const mergeData = await mergeResponse.json();
globalStore.mergeId = mergeData.merge_id;
const navigateToSynthesizedResults = () => {
router.push({
name: 'synthesizedResults'
})
}
let index = 0
const max = 4;
const Timer = setInterval(()=>{
if (index >= max) {
loading.hide();
clearInterval(Timer)
} else {
index++
mergeFetch(index)
const data = await response.json()
if (response.status == 200 || response.status == 201) {
globalStore.mergeId = data.merge_id;
const navigateToSynthesizedResults = () => {
router.push({
name: 'synthesizedResults'
})
}
}, 1000)
const mergeFetch = async (index)=> {
const statusRes = await Request(`face/merge/${mergeData.merge_id}/status`, {}, 'GET', false)
if (statusRes.res.status === 200) {
if (statusRes.json.status === 'success') {
displayMyPhotoBtn.value = false;
let index = 0
const max = 4;
const Timer = setInterval(()=>{
if (index >= max) {
loading.hide();
clearInterval(Timer)
navigateToSynthesizedResults();
globalStore.result_url = statusRes.json.result_url;
} else {
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 {
if (index === 4) {
disableScanAnimation.value = true;
displayMyPhotoBtn.value = true;
}
}
} else {
if (index === 4) {
disableScanAnimation.value = true;
displayMyPhotoBtn.value = true;
}
}
} else {
ElMessage.error(data.message);
loading.hide();
}
} catch (error) {
console.error('Merge API error:', error);
loading.hide();
}
}
@@ -274,22 +340,22 @@ const buttonUploadedPosition = (index) => {
const ADJUSTMENT_CONFIG = {
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: {
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: {
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: {
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: {
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:{
1:6, 2:7, 3:6, 4:5, 5:6, 6:4
1:12, 2:14, 3:12, 4:10, 5:12, 6:8
}
};
@@ -299,7 +365,7 @@ const buttonUploadedPosition = (index) => {
}
return {
top:`${adjustedTop}%`,
top:`${adjustedTop}vw`,
left :pos.left ,
"--item-width" :pos.width
};
@@ -324,12 +390,14 @@ const imagePosition = (index) => {
return {
top : pos.top,
left : pos.left,
width: pos.width
width: pos.width,
height: pos.width
};
};
// 自定义上传方法
const customUpload = async (options) => {
const loading = weui.loading()
const { file, data, onProgress, onSuccess, onError } = options
try {
@@ -344,15 +412,22 @@ const customUpload = async (options) => {
},
body: formData
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
.then(async response => {
const data = await response.json()
if (response.status == 200 || response.status == 201) {
loading.hide();
onSuccess(data);
} else {
ElMessage.error(data.message);
loading.hide();
}
})
.catch((error) => {
console.error('Error:', error);
loading.hide();
console.error('Error:', error);
});
} catch (error) {
loading.hide();
onError(error)
throw error
}
@@ -378,14 +453,16 @@ const showPhotoSquare = () => {
isPhotoSquareVisible.value = true;
};
import imgLoading from '../assets/images/generate-img-loading-bg.webp'
import generateImg from '../assets/images/generate-img-bg.webp'
</script>
<template>
<div :show="show">
<div :show="show" class="main">
<div class="home-wrapper" :style="{
backgroundImage: displayScanModel
? 'url(src/assets/images/generate-img-loading-bg.webp)'
: 'url(src/assets/images/generate-img-bg.webp)'
? `url(${imgLoading})`
: `url(${generateImg})`
}">
<div class="scene-item item-1">
<img src="../assets/images/back-btn.webp" @click="goBack" alt="后退">
@@ -441,12 +518,13 @@ const showPhotoSquare = () => {
<!-- 图片预览 -->
<div v-if="item.imageUrl" class="preview-container" :style="{ pointerEvents: displayMyPhotoBtn ? 'none' : 'auto' }">
<img
:src="item.imageUrl"
alt="预览图"
class="preview-image upload-btn"
:style="imagePosition(index + 1)"
/>
<div class="preview-image upload-btn" :style="imagePosition(index + 1)">
<img
:src="item.imageUrl"
alt="预览图"
class="pre-img"
/>
</div>
<button @click.stop.prevent="clearUploadFile(index)" :style="buttonUploadedPosition(index + 1)" style="position: absolute;">
<div :style="{ width: buttonUploadedPosition(index + 1)['--item-width'] }" >
<img src="../assets/images/img-uploaded.webp" class="delete-btn upload-img-wrapper" alt="删除图片">
@@ -471,6 +549,17 @@ const showPhotoSquare = () => {
</template>
<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 {
width: 100%;
position: absolute;
@@ -568,16 +657,16 @@ const showPhotoSquare = () => {
outline: none !important;
}
.home-wrapper {
width: 100%;
height: 92vh;
background-size: cover;
width: 100vw;
height: 200vw;
background-size: 100%;
background-repeat: no-repeat;
margin-top: -8vw;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
min-height: -webkit-fill-available;
}
.img-from-template {
width: 75vw;
@@ -632,7 +721,7 @@ const showPhotoSquare = () => {
}
.item-4 {
width: 72vw;
top: 23.5%;
top: 48vw;
pointer-events: none;
}
.item-5 {

View File

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

View File

@@ -1,55 +1,222 @@
<script setup>
import { ref, computed, watch, onMounted } from "vue"
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 PhotoSquare from './PhotoSquare.vue'
import globalToastEvent, { ToastType } from '../globalToastEvent';
import { globalStore } from "../globalstore.js";
import Login from '../components/Login.vue'
import { isWeixin, isLogin, getParam, Storage, Request } from "../libs/utils"
import Lottery from '../components/Lottery.vue';
defineProps({
const props = defineProps({
show: true
})
const isMusicOn = ref(false);
const audioElement = ref(null);
onMounted(() => {
audioElement.value = new Audio(faceFamily);
tryAutoPlay();
})
const videoElement = ref(null);
const videoLoaded = ref(false);
const videoError = ref(false);
const lotteryShow = ref(false)
const lotteryType = ref("draw")
const lotteryNoticeData = ref(null)
// 尝试自动播放
const tryAutoPlay = () => {
// 先加载音频
audioElement.value.load();
// 尝试播放
const playPromise = audioElement.value.play();
if (playPromise !== undefined) {
playPromise.then(() => {
// 自动播放成功
// 初始化全局音频实例
const initGlobalAudio = () => {
if (!globalStore.globalAudio) {
globalStore.globalAudio = new Audio(bgm);
globalStore.globalAudio.loop = true; // 设置循环播放
globalStore.globalAudio.preload = 'auto';
// 监听音频事件
globalStore.globalAudio.addEventListener('play', () => {
isMusicOn.value = true;
console.log("自动播放成功");
})
.catch(error => {
// 自动播放被阻止
console.log("自动播放被阻止,需要用户交互:", error);
});
globalStore.globalAudio.addEventListener('pause', () => {
isMusicOn.value = false;
});
globalStore.globalAudio.addEventListener('ended', () => {
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 = () => {
isMusicOn.value = !isMusicOn.value;
if (!isMusicOn.value) {
audioElement.value.pause();
} else {
audioElement.value.play().catch(error => {
console.log("播放失败:", error);
});
if (!audioElement.value) {
initGlobalAudio();
}
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 = () => {
@@ -62,14 +229,18 @@ const handleRule = () => {
globalToastEvent.emit(ToastType.SHOW_RULE)
}
const handleLottery = () => {
if (globalStore.draw_chances <= 0) {
return weui.alert("还没有抽奖机会,快去参加活动吧")
};
lotteryType.value = 'draw'
lotteryNoticeData.value = null
globalToastEvent.emit(ToastType.SHOW_LOTTERY)
if (globalStore.draw_chances <= 0) return;
globalStore.reducerDrawChances();
}
const router = useRouter();
const navigateSelectTemplatePage = () => {
if (globalStore.game_chances <= 0) return;
if (globalStore.game_chances <= 0) return weui.alert('去做任务获得更多参与次数吧');
globalStore.reducerGameChances();
router.push({
name: 'selectTemplateV2'
@@ -81,20 +252,20 @@ const myPhotoValue = route.query.myPhotoValue;
const isMyPhotoVisible = ref(false);
const isPhotoSquareVisible = ref(false);
const showMyPhoto = () => {
const showMyPhoto = () => {
isMyPhotoVisible.value = true;
isPhotoSquareVisible.value = false;
}
const showPhotoSquare=()=>{
const showPhotoSquare = () => {
isMyPhotoVisible.value = false;
isPhotoSquareVisible.value = true;
}
watch(() => myPhotoValue, async (newVal) => {
console.log(newVal)
if (!newVal) {
return
}
isMyPhotoVisible.value = true;
}, { immediate: true })
@@ -130,7 +301,7 @@ const initUserGameInfos = async (refresh_official, refresh_cap_scan) => {
if (result.res.status === 200) {
globalStore.draw_chances = result.json.draw_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.cap_scan = result.json.cap_scan
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)
}
}
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 () => {
console.log("已登录")
loginShow.value = false
await initUserGameInfos(true, true)
await getNotice()
}
if (isLogin()) {
@@ -156,19 +335,70 @@ if (isLogin()) {
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>
<template>
<div :show="show">
<div :show="show" class="main">
<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 }">
<img src="../assets/images/lottery.webp" alt="抽奖">
<div class="lottery-main">
<p class="lottery-value">{{ globalStore.draw_chances }}</p>
</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="立即参与">
<div class="join-main">
<p class="join-value">{{ globalStore.game_chances }}</p>
@@ -204,29 +434,80 @@ if (isLogin()) {
<MyPhoto @go-photo-square="showPhotoSquare" v-model:show="isMyPhotoVisible" />
<PhotoSquare @go-my-photo="showMyPhoto" v-model:show="isPhotoSquareVisible" />
<Login :show="loginShow" @login-success="handleLoginSuccess" />
<Lottery :show="lotteryShow" @close="lotteryShow = false" :type="lotteryType" :data="lotteryNoticeData"></Lottery>
<Popup v-model:show="isPopupVisible" />
</template>
<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 {
width: 100%;
height: 92vh;
background-image: url('../assets/images/home-bg.webp');
background-size: cover;
background-repeat: no-repeat;
width: 100vw;
height: 200vw;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
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 {
position: absolute;
position: fixed;
cursor: pointer;
transition: all 0.4s ease;
overflow: hidden;
border: 3px solid transparent;
animation: float 4s ease-in-out infinite;
}
@@ -243,7 +524,7 @@ if (isLogin()) {
.item-1 {
width: 21vw;
bottom: 0;
bottom: 5vw;
left: 0;
animation-delay: 0s;
}
@@ -255,75 +536,78 @@ if (isLogin()) {
width: 4vw;
height: 3.5vw;
position: absolute;
top: 1.5vw;
right: 6.6vw;
top: 1.7vw;
right: 7.3vw;
color: #fff;
}
.lottery-main .lottery-value {
font-size: 10px;
font-size: 4vw;
}
.item-2 {
width: 48vw;
bottom: 0;
bottom: 5vw;
animation-delay: 0s;
}
.join-main {
position: absolute;
top: 3.4vw;
right: 2.6vw;
width: 7vw;
line-height: 7vw;
text-align: left;
right: -3.5vw;
width: 13vw;
}
.join-main .join-value {
margin: 0;
color: white;
text-stroke: 4px #ff0000;
-webkit-text-stroke: 1px #ff0000;
font-size: 24px;
text-shadow: -1px -1px 0 #ff0000, 1px -1px 0 #ff0000, -1px 1px 0 #ff0000, 1px 1px 0 #ff0000, 0 0 2px #ff0000;
font-size: 5.4vw;
font-weight: 900;
}
.item-3 {
width: 21vw;
bottom: 0;
bottom: 5vw;
right: 0;
animation-delay: 0s;
}
.item-4 {
width: 11vw;
top: 1.5%;
right: 1.5%;
animation-delay: 0s;
}
.item-5 {
width: 11vw;
top: 1.5%;
right: 1.5%;
animation-delay: 0s;
}
.item-6 {
width: 14.5vw;
top: 8%;
right: 0;
animation-delay: 0s;
}
.item-7 {
width: 14.5vw;
top: 13.5%;
right: 0;
animation-delay: 0s;
}
.item-8 {
width: 11vw;
bottom: 32%;
right: 1%;
animation-delay: 0s;
}
.item-9 {
width: 11vw;
bottom: 23%;

View File

@@ -5,16 +5,18 @@
<div class="guangyun" ref="guangyunRef"></div>
<div class="lottery-scene" ref="sceneRef">
<div class="lottery-card" ref="cardRef">
<div class="lottery-face">
<img :src="lotteryFaceUrl" alt="">
</div>
<div class="lottery-prize">
<div class="lottery-title" ref="titleRef"></div>
<div class="lottery-image" :class="activePrizeData.prize_code"></div>
<div class="lottery-name">{{ activePrizeData.name }}</div>
<div class="lottery-title" :class="props.type === 'notice' && 'notice'" ref="titleRef"
v-show="activePrizeData.prize_code !== 'NO'"></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="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>
@@ -32,15 +34,14 @@ import ModalTransition from "./ModalTransition.vue"
import confetti from "canvas-confetti";
import { Request, Sleep } from "../libs/utils"
import { globalStore } from "@/globalstore";
//TODO: globalStore.result_url 这里这张图要用用户分享那张图
// import lotteryFace from "../assets/images/haibao-cover.webp"
import getUserPicture from "../libs/getUserPicture";
const lotteryFace = globalStore.result_url;
const lotteryFaceUrl = ref(lotteryFace)
// const lotteryFaceUrl = ref('')
const cardRef = ref(null)
const sceneRef = ref(null)
const guangRef = ref(null)
const guangyunRef = ref(null)
const lotteryImageRef = ref(null)
const titleRef = ref(null)
const activePrizeData = ref({})
const btngroupShow = ref(false)
@@ -48,14 +49,13 @@ const btngroupShow = ref(false)
gsap.registerPlugin()
const props = defineProps({
show: false,
type: "draw",
data: null
})
const emit = defineEmits(['close'])
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 shakeTimeline = null
let PRIZEDATA = null
const closeThis = () => {
@@ -67,9 +67,15 @@ const handleBtnMore = () => {
closeThis()
globalToastEvent.emit(ToastType.SHOW_AD)
}
const handleLotteryAction = () => {
const readNotice = async () => {
await Request(`notice/read`, { id: activePrizeData.value.noticeId })
}
const handleLotteryAction = async () => {
//实物
closeThis()
if (props.type !== 'draw') {
await readNotice()
}
if (activePrizeData.value.coupon_type === 'scene') {
globalToastEvent.emit(ToastType.SHOW_ADDRESS, activePrizeData.value.id)
}
@@ -97,17 +103,10 @@ const initAnimateStyle = () => {
});
}
// 创建一个时间线,添加关键帧,并循环
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(lotteryImageRef.value, { scale: 0 })
gsap.set(guangyunRef.value, { scale: 0, opacity: 1 })
gsap.set(titleRef.value, { scaleY: 0 })
gsap.set(sceneRef.value, { scale: .5 })
gsap.set(sceneRef.value, { scale: .2 })
gsap.set(cardRef.value, { rotateY: 0 })
btngroupShow.value = false
}
@@ -117,25 +116,66 @@ watch(() => props.show, async (newVal) => {
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: 延时测试,上限删掉
// await Sleep(2000)
// await Sleep(20000)
shakeTimeline.pause()
const lottteryResult = await Request("lottery/draw", { pool: 'game', consume_type: 'points' })
// TODO: 测试数据
// const lottteryResult = {
// lottteryResult = {
// res: { status: 200 },
// json: {
// id: 0,
// code: "HEIGAI_42_GPJ_500ML",
// prize_code: 'HEIGAI_42_GPJ_500ML',
// code: "xxx",
// prize_code: 'xxx',
// coupon_type: "scene",
// name: "泸州老窖的一瓶酒"
// }
// }
loading.hide()
if (lottteryResult.res.status !== 200) {
emit('close')
return
@@ -160,26 +200,23 @@ watch(() => props.show, async (newVal) => {
}
});
prizeshowTime.to(sceneRef.value, {
duration: .4,
scale: .2,
})
prizeshowTime.to(sceneRef.value, {
duration: 1,
prizeshowTime.to([sceneRef.value], {
duration: 2.5,
scale: 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, {
duration: 1.5,
scale: 2,
}, "-=1")
prizeshowTime.to(cardRef.value, {
rotateY: 180 * 3,
duration: 1,
}, "-=1.4")
prizeshowTime.to(titleRef.value, {
scaleY: 1,
ease: "elastic.out(1,0.3)"
@@ -209,12 +246,49 @@ watch(() => props.show, async (newVal) => {
})
onUnmounted(() => {
shakeTimeline = null
gsapCtx && gsapCtx.revert()
})
</script>
<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,
.guangyun {
position: absolute;
@@ -243,7 +317,7 @@ onUnmounted(() => {
position: absolute;
top: 24vw;
left: 50%;
transform: translateX(-50%);
transform: translateX(-50%) !important;
width: 65.462963vw;
height: 19.907407vw;
background-image: url("../assets/images/lottery-title.webp");
@@ -251,12 +325,40 @@ onUnmounted(() => {
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 {
position: absolute;
bottom: 18vw;
text-align: center;
width: 100%;
font-size: 6vw;
width: 80%;
left: 10%;
font-size: 4.3vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 700;
color: rgb(255, 255, 255);
text-shadow:
@@ -272,7 +374,7 @@ onUnmounted(() => {
bottom: -24vw;
width: 100%;
display: flex;
justify-content: space-between;
justify-content: space-evenly;
}
.btn-more {
@@ -299,6 +401,7 @@ onUnmounted(() => {
background-position: center bottom;
background-repeat: no-repeat;
background-size: auto 100%;
background-origin: 50% 100%;
}
.lottery-image.HEIGAI_42_GPJ_500ML {
@@ -342,12 +445,10 @@ onUnmounted(() => {
position: absolute;
width: 100%;
height: 100%;
transform-style: preserve-3d;
top: -14vw;
}
.lottery-card.flip {
transform: rotateY(180deg);
}
.lottery-face {
position: absolute;
@@ -372,8 +473,6 @@ onUnmounted(() => {
background-image: url("../assets/images/prize-bg.webp");
background-repeat: no-repeat;
background-size: 100%;
backface-visibility: hidden;
transform: rotateY(180deg);
}
.close {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,15 +7,16 @@ import globalToastEvent, { ToastType } from '../globalToastEvent';
import { Storage, generateQR } from "../libs/utils";
import Haibao from "@/libs/haibao";
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 Lottery from '../components/Lottery.vue';
defineProps({
show: true
})
const isPopupVisible = ref(false);
const lotteryShow = ref(false)
const chartsBattle = ()=> {
globalStore.chartsBattle = true;
@@ -70,7 +71,7 @@ const handleHaibao = async () => {
});
}
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(haibaoCoverBorder, 0, 0)
haibaoCover.draw('destination-in').then(() => {
@@ -79,13 +80,14 @@ const handleHaibao = async () => {
const haibaoSave = new Haibao(1080, 2160)
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(qrcode, 115, 1875)
haibaoSave.add(url, 64, 250)
haibaoSave.add(qrcode, 127, 1860)
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 => {
haibaoUrl.value = url
// haibaoUrl.value = url
haibaoUrl.value = globalStore.result_url;
loading.hide()
}).catch(err => {
console.log(err)
@@ -108,10 +110,19 @@ const handleHaibao = async () => {
// return userPictureVal;
// }
// };
globalToastEvent.on(ToastType.SHOW_LOTTERY, () => {
lotteryShow.value = true
})
const handleBtnMore = () => {
globalToastEvent.emit(ToastType.SHOW_AD)
}
</script>
<template>
<div>
<div class="main">
<div class="home-wrapper">
<div class="scene-item item-1">
<img src="../assets/images/go-home-btn.webp" @click="navigateToHome" alt="回到首页">
@@ -127,10 +138,14 @@ const handleHaibao = async () => {
</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="参与打榜">
</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">
<img src="../assets/images/instant-win.webp" alt="立即抽奖">
</div>
@@ -138,6 +153,7 @@ const handleHaibao = async () => {
</div>
<Popup v-model:show="isPopupVisible" />
<Lottery :show="lotteryShow" @close="lotteryShow = false" data="null" type="draw"></Lottery>
</template>
<style scoped>
@@ -171,20 +187,16 @@ const handleHaibao = async () => {
}
.fullsection {
position: fixed;
top: 25vw;
position: absolute;
top: 40vw;
left: 0;
width: 100%;
height: 100%;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
/* background-color: rgba(0, 0, 0, .7); */
}
.haibao {
position: relative;
top: -25vw;
width: 70vw;
height: 119.444444vw;
background-image: url("../assets/images/haibao-cover.webp");
@@ -216,10 +228,12 @@ const handleHaibao = async () => {
top: initial;
transform: translate3d(-50%,0,0);
}
.main {
height: 100%;
overflow-y: auto;
}
.home-wrapper {
width: 100%;
height: 92vh;
width: 100vw;
background-image: url('../assets/images/img-result-bg.webp');
background-size: cover;
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-scan" :class="globalStore.cap_scan >= globalStore.MAX_CAP_SCAN && 'has'"
@click="handleScan($event)"></div>
<div class="btn-share" :class="globalStore.invitees >= globalStore.MAX_INVITE_DAILY && 'has'"
@click="openHaibao($event)"></div>
<div class="btn-share" @click="openHaibao($event)"></div>
</div>
<div class="close" @click="$emit('close')"></div>
</div>
@@ -29,16 +28,19 @@
<script setup>
import { ref, computed } from "vue"
import { globalStore } from "@/globalstore";
import globalToastEvent, { ToastType } from "../globalToastEvent"
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 bg from "../assets/images/haibao-bg.webp"
import mask from "../assets/images/haibao-mask.webp"
import haibaoCoverBorder from "../assets/images/haibao-cover.webp"
import haibaoCoverBorderNoTitle from "../assets/images/haibao-cover-no-title.webp"
const props = defineProps({
show: false,
})
let mergeId = ''
const emit = defineEmits(['close', 'open'])
const shareShow = ref(false)
const qiweiShow = ref(false)
@@ -54,9 +56,7 @@ const handleHaibao = async () => {
return
}
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('https://lzlj123.oss-cn-shanghai.aliyuncs.com/face-merged/20250914/face-merge-5c90bb95-d1d2-479a-a13b-ada7ba8e7152.jpg')
const infos = Storage.get("userinfos")
const haibaoCover = new Haibao(951, 1607)
@@ -66,15 +66,23 @@ const handleHaibao = async () => {
haibaoCover.draw('destination-in').then(() => {
haibaoCover.generate({ mimeType: 'image/png' }).then(async (url) => {
userHaibaoUrl.value = url
})
})
const haibaoSave = new Haibao(1080, 2160)
const qrcode = await generateQR(`fromid=${infos.invite_code}&org_id=${infos.org_id}`, 200, 200)
haibaoSave.add(url, 62, 350)
haibaoSave.add(bg, 0, 0)
haibaoSave.add(qrcode, 115, 1875)
haibaoSave.draw().then(() => {
haibaoSave.text(infos.nickname, haibaoSave.canvas.width / 2, 200, { font: 'bold 50px Arial', color: '#ffee6f' })
haibaoSave.generate({ mimeType: 'image/png' }).then(url => {
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=${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
loading.hide()
}).catch(err => {
@@ -112,17 +120,54 @@ const openQiwei = (e) => {
qiweiShow.value = true
}
const openHaibao = (e) => {
const target = e.currentTarget
const openHaibao = async (e) => {
const target = e.currentTarget
if (target.classList.contains("has")) {
return
}
if (!globalStore.result_url) {
return weui.alert("请先参与活动合成图片并打榜!")
}
haibaoShow.value = true
handleHaibao()
const url = new URL('https://huodong2.lzlj.com/api/faceFamily/face/square');
url.searchParams.append('my_only', '1');
url.searchParams.append('page', '1');
url.searchParams.append('per_page', '100');
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 target = e.currentTarget

View File

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

View File

@@ -1,6 +1,10 @@
import { reactive } from "vue"
export const globalStore = reactive({
first_share_today:false,
globalAudio: null,
userMutedMusic: false, // 用户是否手动静音了音乐
isFirstVisitHomePage: true, // 是否首次访问首页
select_template: '',
people_count: 0,
draw_chances: 0,
@@ -11,7 +15,6 @@ export const globalStore = reactive({
generateStatus: false,
generateImgTemplates: [],
chartsBattle: false,
invitees: 0,
followed_official: false,
cap_scan: 0,
game_chances_view_recipes: 0,
@@ -33,7 +36,4 @@ export const globalStore = reactive({
lotteryAdd () {
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 = () => {
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 = () => {
wx.miniProgram.navigateTo({
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}`
} else {
Storage.clear()
weui.alert("错误的请求")
window.location.reload()
return
weui.alert("登录失效,请重新登录")
// window.location.reload()
}
}
@@ -192,94 +194,8 @@ export const Request = async (url, data, type, noloading, noerror) => {
return { res: response, json: result }
} else if (response.status == 401) {
Storage.clear()
weui.alert("错误的请求")
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()
weui.alert("登录失效,请重新登录")
// window.location.reload()
return
} else {
if (!noerror) {

View File

@@ -2,7 +2,7 @@ import { createRouter, createWebHistory } from 'vue-router'
import routes from './routes' // 导入路由定义
const router = createRouter({
history: createWebHistory(),
history: createWebHistory('/faceFamily/'),
routes
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,216 +1,265 @@
import shenxian_bg from '../assets/images/generate/template/shenxian/shenxian_bg.webp'
import shenxian_1 from '../assets/images/generate/template/shenxian/shenxian_1.webp'
import shenxian_2 from '../assets/images/generate/template/shenxian/shenxian_2.webp'
import shenxian_3 from '../assets/images/generate/template/shenxian/shenxian_3.webp'
import shenxian_4 from '../assets/images/generate/template/shenxian/shenxian_4.webp'
import shenxian_5 from '../assets/images/generate/template/shenxian/shenxian_5.webp'
import shenxian_6 from '../assets/images/generate/template/shenxian/shenxian_6.webp'
import xianxia_bg from '../assets/images/generate/template/xianxia/xianxia_bg.webp'
import xianxia_1 from '../assets/images/generate/template/xianxia/xianxia_1.webp'
import xianxia_2 from '../assets/images/generate/template/xianxia/xianxia_2.webp'
import xianxia_3 from '../assets/images/generate/template/xianxia/xianxia_3.webp'
import xianxia_4 from '../assets/images/generate/template/xianxia/xianxia_4.webp'
import xianxia_5 from '../assets/images/generate/template/xianxia/xianxia_5.webp'
import xianxia_6 from '../assets/images/generate/template/xianxia/xianxia_6.webp'
import fugu_bg from '../assets/images/generate/template/fugu/fugu_bg.webp'
import fugu_1 from '../assets/images/generate/template/fugu/fugu_1.webp'
import fugu_2 from '../assets/images/generate/template/fugu/fugu_2.webp'
import fugu_3 from '../assets/images/generate/template/fugu/fugu_3.webp'
import fugu_4 from '../assets/images/generate/template/fugu/fugu_4.webp'
import fugu_5 from '../assets/images/generate/template/fugu/fugu_5.webp'
import fugu_6 from '../assets/images/generate/template/fugu/fugu_6.webp'
import xinzhongshi_bg from '../assets/images/generate/template/xinzhongshi/xinzhongshi_bg.webp'
import xinzhongshi_1 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_1.webp'
import xinzhongshi_2 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_2.webp'
import xinzhongshi_3 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_3.webp'
import xinzhongshi_4 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_4.webp'
import xinzhongshi_5 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_5.webp'
import xinzhongshi_6 from '../assets/images/generate/template/xinzhongshi/xinzhongshi_6.webp'
import luying_bg from '../assets/images/generate/template/luying/luying_bg.webp'
import luying_1 from '../assets/images/generate/template/luying/luying_1.webp'
import luying_2 from '../assets/images/generate/template/luying/luying_2.webp'
import luying_3 from '../assets/images/generate/template/luying/luying_3.webp'
import luying_4 from '../assets/images/generate/template/luying/luying_4.webp'
import luying_5 from '../assets/images/generate/template/luying/luying_5.webp'
import luying_6 from '../assets/images/generate/template/luying/luying_6.webp'
import paidui_bg from '../assets/images/generate/template/paidui/paidui_bg.webp'
import paidui_1 from '../assets/images/generate/template/paidui/paidui_1.webp'
import paidui_2 from '../assets/images/generate/template/paidui/paidui_2.webp'
import paidui_3 from '../assets/images/generate/template/paidui/paidui_3.webp'
import paidui_4 from '../assets/images/generate/template/paidui/paidui_4.webp'
import paidui_5 from '../assets/images/generate/template/paidui/paidui_5.webp'
import paidui_6 from '../assets/images/generate/template/paidui/paidui_6.webp'
const imageBackground = [
{
id: 1,
titleImgUrl: 'src/assets/images/generate/template/shenxian/shenxian_bg.webp',
titleImgUrl: shenxian_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_1.webp',
imgUrl: shenxian_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_2.webp',
imgUrl: shenxian_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_3.webp',
imgUrl: shenxian_3,
peopleCount: 2
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_4.webp',
imgUrl: shenxian_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_5.webp',
imgUrl: shenxian_5,
peopleCount: 4
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/shenxian/shenxian_6.webp',
imgUrl: shenxian_6,
peopleCount: 5
}
]
},
{
id: 2,
titleImgUrl: 'src/assets/images/generate/template/xianxia/xianxia_bg.webp',
titleImgUrl: xianxia_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_1.webp',
imgUrl: xianxia_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_2.webp',
imgUrl: xianxia_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_3.webp',
imgUrl: xianxia_3,
peopleCount: 3
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_4.webp',
imgUrl: xianxia_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_5.webp',
imgUrl: xianxia_5,
peopleCount: 4
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/xianxia/xianxia_6.webp',
imgUrl: xianxia_6,
peopleCount: 5
}
]
},
{
id: 3,
titleImgUrl: 'src/assets/images/generate/template/fugu/fugu_bg.webp',
titleImgUrl: fugu_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_1.webp',
imgUrl: fugu_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_2.webp',
imgUrl: fugu_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_3.webp',
imgUrl: fugu_3,
peopleCount: 2
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_4.webp',
imgUrl: fugu_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_5.webp',
imgUrl: fugu_5,
peopleCount: 4
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/fugu/fugu_6.webp',
imgUrl: fugu_6,
peopleCount: 5
}
]
},
{
id: 4,
titleImgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_bg.webp',
titleImgUrl: xinzhongshi_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_1.webp',
imgUrl: xinzhongshi_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_2.webp',
imgUrl: xinzhongshi_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_3.webp',
imgUrl: xinzhongshi_3,
peopleCount: 2
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_4.webp',
imgUrl: xinzhongshi_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_5.webp',
imgUrl: xinzhongshi_5,
peopleCount: 4
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/xinzhongshi/xinzhongshi_6.webp',
imgUrl: xinzhongshi_6,
peopleCount: 5
}
]
},
{
id: 5,
titleImgUrl: 'src/assets/images/generate/template/luying/luying_bg.webp',
titleImgUrl: luying_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/luying/luying_1.webp',
imgUrl: luying_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/luying/luying_2.webp',
imgUrl: luying_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/luying/luying_3.webp',
imgUrl: luying_3,
peopleCount: 2
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/luying/luying_4.webp',
imgUrl: luying_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/luying/luying_5.webp',
imgUrl: luying_5,
peopleCount: 4
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/luying/luying_6.webp',
imgUrl: luying_6,
peopleCount: 5
}
]
},
{
id: 6,
titleImgUrl: 'src/assets/images/generate/template/paidui/paidui_bg.webp',
titleImgUrl: paidui_bg,
children: [
{
id: 1,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_1.webp',
imgUrl: paidui_1,
peopleCount: 2
},
{
id: 2,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_2.webp',
imgUrl: paidui_2,
peopleCount: 2
},
{
id: 3,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_3.webp',
imgUrl: paidui_3,
peopleCount: 2
},
{
id: 4,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_4.webp',
imgUrl: paidui_4,
peopleCount: 3
},
{
id: 5,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_5.webp',
imgUrl: paidui_5,
peopleCount: 3
},
{
id: 6,
imgUrl: 'src/assets/images/generate/template/paidui/paidui_6.webp',
imgUrl: paidui_6,
peopleCount: 5
}
]

View File

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

View File

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

View File

@@ -6,7 +6,7 @@ import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
// base: 'https://huodong2.lzlj.com/faceFamily/',
base: process.env.NODE_ENV === 'production' ? 'https://huodong2.lzlj.com/faceFamily/' : '/faceFamily/',
plugins: [
vue({
template: {