MatchMaster/assets/seven_day_gift/docs/seven-day-gift-maintenance.md

11 KiB
Raw Permalink Blame History

七日活动实现与维护说明

核对日期:2026-09-16。本文以当前工作区代码和资源为准,不代表已发布版本或后端实时配置。测试步骤见 预览与测试说明。

当前流程

  1. HomeScene 的 SevenDayGiftHost 等待 UID,调用 signInActivityInfo 查询活动;UID 未就绪最多按一秒间隔重试十次。
  2. 满足自动展示条件后,以键 sevenDayGift、优先级 10 加入 HomePopupQueue。
  3. 通过主页的 loadHomeBundleWithDependencies("seven_day_gift", 5, ...) 加载分包及依赖,再加载并实例化 prefab/sevenDayGift。
  4. 将查询快照交给活动视图,成功显示后才记录当天已弹。加载或初始化失败不会写已弹记录。
  5. 打开后等待点击,不自动领取。点击当天卡片或弹窗外部,使用快照中当天的奖励执行发奖;成功后更新本地领取状态并播放上浮效果。
  6. 领取后再次点击外部关闭。销毁活动节点,通常下一帧释放活动 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。第七天包含猫奖励且尚未领取时显示,领取后隐藏;装饰节点不参与点击命中。编辑器可直接调整位置、尺寸、颜色和动画。此效果与领取后的上浮动画相互独立。