11 KiB
七日活动实现与维护说明
核对日期:2026-09-16。本文以当前工作区代码和资源为准,不代表已发布版本或后端实时配置。测试步骤见 预览与测试说明。
当前流程
HomeScene的SevenDayGiftHost等待 UID,调用signInActivityInfo查询活动;UID 未就绪最多按一秒间隔重试十次。- 满足自动展示条件后,以键
sevenDayGift、优先级10加入HomePopupQueue。 - 通过主页的
loadHomeBundleWithDependencies("seven_day_gift", 5, ...)加载分包及依赖,再加载并实例化prefab/sevenDayGift。 - 将查询快照交给活动视图,成功显示后才记录当天已弹。加载或初始化失败不会写已弹记录。
- 打开后等待点击,不自动领取。点击当天卡片或弹窗外部,使用快照中当天的奖励执行发奖;成功后更新本地领取状态并播放上浮效果。
- 领取后再次点击外部关闭。销毁活动节点,通常下一帧释放活动 Bundle;宿主销毁时立即释放。独立测试服的测试入口存在时保留 Bundle,退出主页时一并释放。
没有手动入口或关闭按钮。代码中的 autoClaim 是保留的旧参数名,目前表示自动展示来源,不代表自动领取。
自动展示条件
- 存在
activityId,且triggerReached为真。 status不是expired或completed。- 时间可解析时要求
serverNow < endAt;当前代码遇到不可解析时间不会因此阻止展示。 canClaim为真,todayClaimed为假,当前账号、活动、服务器日期尚未成功显示过。
触发等级、开始时间和期限由后端决定;前端不硬编码 23 关或 14 天,也不单独检查 startAt 是否已经到达。
自动弹窗记录键为 seven_day_gift_auto_open_v1:<uid>:<activityId>,值为 UTC+8 自然日编号字符串;缺少有效服务器时间时使用设备时间。已弹记录不代表已领取,领取失败不会清除该记录。
主页进入和回到前台会查询。弹窗加载中或显示中不重复查询;Cocos CC_PREVIEW 环境不会自动查询或自动打开活动。
文件职责
以下路径均相对于项目根目录。
| 文件 | 职责 |
|---|---|
assets/Script/seven_day_gift/SevenDayGiftHost.ts |
展示条件、主页队列、分包加载与释放 |
assets/Script/seven_day_gift/SevenDayGiftBootstrapApi.ts |
主包活动查询 |
assets/seven_day_gift/SevenDayGift.ts |
预制体节点绑定、数据刷新、点击和动画调用 |
assets/seven_day_gift/SevenDayGiftRuntime.ts |
领取流程、Loading、状态更新 |
assets/seven_day_gift/SevenDayGiftApi.ts |
数据类型、猫皮肤与道具保存接口 |
assets/seven_day_gift/SevenDayGiftReward.ts |
本地资产增加、同步及成功记录防重 |
assets/seven_day_gift/prefab/sevenDayGift.prefab |
面板最终布局 |
assets/seven_day_gift/texture/reward_numbers_medium/ |
数字、乘号、加号、分钟图片 |
assets/seven_day_gift/SevenDayHitTest.ts、SevenDayHitMasks.ts |
透明区域点击判定及离线命中数据 |
assets/reward_claim_effect/RewardClaimEffect.ts |
独立领取上浮特效 |
assets/Script/ActivityPopupAnimator.ts |
面板开关动画 |
assets/home_popup_queue/HomePopupQueue.ts |
主页活动弹窗协调 |
assets/seven_day_gift/test/SevenDayTest.ts、SevenDayTest.prefab |
独立测试服白字入口、接口字段查看、当前账号活动缓存清理 |
主包宿主通过接口调用活动组件,不静态导入活动实现。维护时保留资源 .meta 和 UUID,避免场景直接引用活动资源而破坏按需加载。
预制体与美术维护
面板共 85 个节点,奖励节点全部存放在预制体中。运行时不创建或销毁面板奖励节点,只更新图片、数量字位和状态,播放动画。
sevenDayGift
├─ mask
└─ panel
├─ header
└─ cards
└─ giftDay1 … giftDay7
├─ dayLabel
├─ rewardItems
│ └─ rewardItem0 / rewardItem1
│ └─ amount
│ └─ digit0 … 实际需要的字位
├─ claimedOverlay
└─ claimedBadge
默认展示第 1 天可领取。仅 claimedOverlay 和 claimedBadge 默认未激活,领取后显示。备用布局、额外字位、文字兜底、旧关闭按钮、提示和重复标题文字均已删除。
当前编辑器展示值与容量
下表是预制体默认展示和测试基线,不是服务端奖励配置的证明。实际发奖仍以接口 rewards 为准。
| 天数 | 默认展示 | 奖励槽位数 | 各奖励数量字位数 |
|---|---|---|---|
| 1 | 无限体力 15 分钟 | 1 | 3 |
| 2 | 锤子 ×1 | 1 | 2 |
| 3 | 无限体力 30 分钟 | 1 | 3 |
| 4 | 冻结 ×1、魔法棒 ×1 | 2 | 2、2 |
| 5 | 金币 600 | 1 | 3 |
| 6 | 锤子 ×1、冻结 ×1 | 2 | 2、2 |
| 7 | 无限体力 60 分钟、猫皮肤 ×1 | 2 | 3、2 |
“分钟”整张图片占一个字位,乘号也占一个字位。猫的发奖编号由接口 itemId 指定;面板当前使用绑定的固定猫图片。
当前视觉规格
- “分钟”按数字的可见高度等比放大,不按较小的原始贴图尺寸显示。
- 同一卡片内各奖励的数量排在同一水平线上;此前按各图标底边定位导致高低不齐。
- 所有面板数量相对调整前放大 15%,数量容器高度为 29.9。
- 第七天爱心相对调整前放大 10%、左移 6px。
- 当前可领取卡片为黄色并播放 1~1.04 倍呼吸缩放;第七天使用专用底图。猫在可领取或已领取时显示正常图,否则显示锁定图。
直接在预制体调整 rewardItem* 的位置、尺寸及 amount 的整体位置;这些值不会被数据刷新重设。数量字位内部尺寸和间距仍由 refreshAmount() 按容器宽高更新,日期描边颜色、卡片底图和状态仍受脚本控制。
增加奖励项、调整奖励顺序或改变类型时,必须同步检查固定槽位、图片比例及位置。增加数量位数时,需添加连续命名的 digitN Sprite 节点。超出槽位的奖励不会显示,但发奖逻辑仍消费完整接口数组;字位不足、缺图或小数数量会隐藏该数量并警告,不显示文字兜底,不可把显示限制当作发奖限制。
面板预制体与领取特效是两套展示:RewardClaimEffect 仍动态创建临时特效节点,并保留它自身的数量绘制逻辑。此次分钟等高、15% 数量放大及无文字兜底针对面板,不代表特效已同步采用这些规格。
接口与发奖
主包向 signInActivityInfo 提交 UID,公共 Utils.POST 补充 token 等公共参数。仅 code === 1 且 data 为有效对象时消费结果;data: false 不展示活动。活动查询和分包资产保存接口均有 5.5 秒超时保护。
| 快照字段 | 用途 |
|---|---|
activityId、startAt |
活动识别、本次领取记录 |
serverNow、endAt、status |
日期及展示条件 |
triggerLevel、triggerReached |
后端触发信息;实际展示判断使用后者 |
canClaim、todayClaimed、nextRewardDay |
当天领取资格和目标天数 |
claimedCount、rewards[].claimed |
已领进度 |
rewards[].day、rewards[].items |
按天查找奖励,不能假定天数组顺序 |
奖励项包括 type、count(兼容旧字段 amount)和猫皮肤 itemId。无限体力原值为秒,仅显示时除以 60。
没有独立活动领取请求:从查询快照取出 nextRewardDay 对应的 items,执行以下资产更新。
| 奖励 | 当前实现 |
|---|---|
| 金币 | GameTool.changeCoin() |
| 锤子、冻结、魔法棒 | 增加本地总量,再经 userProp 保存总量 |
| 无限体力 | GameTool.setUserPowerTime(seconds, "seven_day_gift"),刷新主页体力显示 |
| 猫皮肤 | setCatArr 保存 itemId,更新猫列表 |
成功后本地标记当天已领取,设置 canClaim=false、todayClaimed=true;第七天标记活动完成,再播放特效。领取 Loading 有 7 秒兜底;失败允许在当前弹窗重试。
防重与当前边界
成功记录存放在 seven_day_gift_processed_claims_v1,按 UID 和 JSON.stringify([activityId, startAt, nextRewardDay]) 生成的领取标识区分。只有整体同步成功后才写记录;同一设备的成功记录可阻止重复发奖,不能代替后端跨设备幂等。
当前先增加本地资产,再等待部分保存接口。若道具或猫保存失败,前面已经增加的资产没有事务回滚,重试可能再次累加。金币、体力路径也不等同于逐项确认服务端最终到账。测试需覆盖部分失败,不应把“可重试”描述为“不会重复增加”。
如果后端查询本身已直接增加资产,当前客户端累加方式需与后端重新确认,避免重复发奖。视图和 Runtime 不独立定时检查过期;展示后的过期边界仍需要接口约定和真实环境验证。
当前环境配置
assets/Script/module/Pay/Utils.ts 当前配置:
httpip:https://q6rvwvtnga.sealoshzh.site/testHttpip:https://q6rvwvtnga.sealoshzh.site/,与正式地址相同。- 旧测试地址
https://sor779u2w8.sealoshzh.site/仅为注释。
开发版、体验版选择 testHttpip,正式版及其他情况选择 httpip。因此当前不能把开发版/体验版称为独立测试服;真实领取前应确认目标地址和测试账号。本次文档整理不修改服务器配置,也未请求线上接口。
测试入口由 SevenDayGiftBootstrapApi.getTestEnvironment() 统一门禁:仅开发版/体验版且测试、正式地址不同源时显示,每次按钮操作再次校验。测试脚本和预制体位于本包 test/ 目录,主包仅按路径加载。当前配置下入口隐藏,未擅自恢复旧测试地址。具体操作见测试文档。
排查与修改入口
| 现象 | 检查位置 |
|---|---|
| 主页不弹 | 是否 CC_PREVIEW、UID、接口响应、展示条件、当天已弹记录、主页队列是否有其他窗口 |
| 分包或预制体加载失败 | 主页依赖加载器、Bundle 名、Prefab 路径和 SevenDayGift 组件 |
| 编辑器与运行图标位置不同 | 是否重新导入/构建、是否修改了当前实际使用的奖励槽位、是否处于动画中 |
| 数量消失或奖励少显示 | 控制台容量警告、字位数、图片绑定、后端项数及顺序 |
| 点透明区域行为异常 | SevenDayHitTest 与贴图对应的命中数据 |
| 发奖失败或资产重复 | 保存接口响应、成功记录、部分失败重试路径 |
当前宿主仍有展示判断和打开日志,不能描述为“仅有异常日志”。重新打包需先经 Cocos 构建,再到微信开发者工具验证,单点微信编译不会更新 Cocos 资源。
第七天小猫光效
小猫背后的 catGlow 已固化在预制体中,使用本包独立复制的 exture/catAnimation3.png,不引用扭蛋包资源。CatRewardGlow.anim 循环播放(视图刷新时显式确保启动,重复刷新不重播):6 秒旋转一圈、2 秒明暗呼吸,金色,480×480,透明度 170~255。第七天包含猫奖励且尚未领取时显示,领取后隐藏;装饰节点不参与点击命中。编辑器可直接调整位置、尺寸、颜色和动画。此效果与领取后的上浮动画相互独立。