> 当前交互更新:七日弹窗无关闭按钮;首次外部点击与卡片领取一致,只领取当前奖励,后一次外部点击再关闭。领取及效果期间禁止重复操作。奖励改用 `assets/reward_claim_effect/RewardClaimEffect.ts` 上浮效果;下文旧版自动领取、关闭按钮和公共奖励动画说明仅作历史记录,测试以 `testSeven-local-preview.md` 为准。 # 七日好礼活动实现与维护说明 本文记录 `feature/seven_day_gift` 分支从 `main` 拉出后完成的七日签到活动相关改动,供后续开发、联调、测试和上线维护使用。 记录日期:2026-09-04 基线提交:`6b56b88284e1bb864241530a23aa3376ce0faf3e` 开发分支:`feature/seven_day_gift` > 重要:记录时该分支相对 `main` 没有新的已提交 commit,功能改动仍在工作区。本文描述的是“当前工作区相对 `main`”的实际差异,不代表这些文件已经提交或合并。 ## 1. 功能目标 本次增加一个由后端控制状态的七日好礼活动,主要规则如下: - 玩家主线达到活动触发条件后,在主页自动弹出七日活动,不再显示手动入口按钮。 - 当前约定的触发等级为 23,但前端不自行计算触发结果,以后端返回的 `triggerReached` 为准。 - 活动有效期由后端的 `startAt`、`endAt` 和 `status` 控制;当前产品约定是 14 天内领取 7 天奖励。 - 每个服务器自然日最多领取一次,具体是否可领取以后端 `canClaim` 为准。 - 当天有奖励可领且当天没有自动弹过时,进入主页自动打开并自动领取当天奖励。 - 自动领取结束(成功或失败)后才开放关闭按钮;失败时可点击当天卡片重试。 - 当天领取后关闭页面,即销毁活动实例并释放 Bundle;第二天满足条件时重新加载。 - 开发版和体验版使用测试服务器;正式版使用正式服务器。 - 上线代码不包含测试面板、接口反馈、模拟日期或测试资产注入功能。 ## 2. 总体结构 七日活动采用“主包轻量宿主 + 活动 Bundle”的结构。主包只负责首次状态查询、自动弹出判断和 Bundle 生命周期;活动 UI、领取和发奖代码均放入 `seven_day_gift` Bundle: ```text HomeScene └─ Canvas/sevenDayGift 主包中的轻量宿主节点 ├─ SevenDayGiftHost Bundle 加载与释放 └─ SevenDayGiftBootstrapApi 首次状态查询 seven_day_gift Bundle ├─ prefab/sevenDayGift.prefab 活动弹窗 ├─ SevenDayGift + SevenDayGiftRuntime UI 与业务流程 ├─ SevenDayGiftApi + SevenDayGiftReward 完整接口与发奖 └─ texture/* 活动图片 ``` 核心调用链: ```text 进入 HomeScene / 小游戏回到前台 ↓ SevenDayGiftHost.queryActivity(true) ↓ signInActivityInfo ↓ 判断活动是否可见、当天是否可领取 ↓ 满足 canClaim 且当天未弹过 → 自动打开活动 自动弹窗完成后自动领取当天卡片 ↓ 使用本次查询的 nextRewardDay 对应 items ↓ SevenDayGiftReward.grant ↓ 更新本地资产并同步相关资产接口 ↓ 打开项目公共奖励动画 ↓ 在当前快照上更新已领取状态,不重复查询 ``` ## 3. 新增文件 ### 3.1 主包引导层 `assets/Script/seven_day_gift/SevenDayGiftHost.ts` 挂载在 `HomeScene` 的 `sevenDayGift` 节点上,只负责: - 进入主页时查询活动。 - 监听 `cc.game.EVENT_SHOW`,从后台回到前台时重新查询活动。 - 判断是否需要自动弹出。 - 按需加载 `seven_day_gift` Bundle 和 `prefab/sevenDayGift`。 - 弹窗关闭后销毁实例,并在下一帧执行 `bundle.releaseAll()` 和 `cc.assetManager.removeBundle()`。 `assets/Script/seven_day_gift/SevenDayGiftBootstrapApi.ts` 是主包中的最小查询接口,只包含 `signInActivityInfo`、UID 获取、服务器选择、超时和基础日志。它不能引用 Bundle 内的完整 API、Reward、Prefab 或调试脚本,否则这些代码会被重新打进主包。 #### 活动可见条件 `isActivityVisible()` 当前要求: - 返回了 `activityId`。 - `triggerReached === true`。 - `status` 不是 `expired`。 - `status` 不是 `completed`。 - `serverNow < endAt`。 前端没有直接检查 `startAt`,正常情况下应由后端通过 `status` 保证活动尚未开始时不返回可见状态。 #### 自动弹出条件 `shouldAutoOpen()` 当前要求: - 活动处于可见状态。 - 后端返回 `canClaim === true`。 - 本地没有当前用户、当前活动、当天的自动弹出记录。 本地记录键: ```text seven_day_gift_auto_open_v1:: ``` 值为根据 `serverNow` 计算出的东八区自然日编号。自动弹出前先写记录,再执行 `show()`,防止同一运行过程重复触发。 以下操作不会自动清除该记录: - 修改服务器关卡等级。 - 将等级从 23 改回 22 后再次通关。 - 重新请求活动接口。 - 关闭活动但不领取。 清除微信缓存、更换设备、更换 UID 或更换 `activityId`,会允许再次自动弹出。 #### 查询时机 - `HomeScene` 中宿主组件执行 `onLoad()`。 - 小游戏触发 `cc.game.EVENT_SHOW`,并且宿主仍位于当前主页场景。 七日活动宿主不在关卡场景中,因此玩家在关卡里达到触发等级时不会立即弹窗;返回主页后才查询和判断。 #### 加载与释放 - 点击领取时,加载动画最长兜底 7 秒。 - 七日 API 自身的请求超时是 5.5 秒。 - 自动后台查询不主动显示 Loading,避免进入主页时无条件遮挡界面。 - 各微信环境都只有命中自动弹出条件时才加载 Bundle。 - Cocos 编辑器预览不主动请求活动,也不加载 Bundle;联调应使用微信开发版或体验版。 - 节点先销毁,Bundle 在下一帧释放,避免在组件销毁回调尚未结束时回收其脚本和资源。 ### 3.2 `assets/seven_day_gift/SevenDayGift.ts` 活动弹窗视图组件,负责: - 缓存 7 张奖励卡片。 - 根据接口数据刷新卡片底图、日期、奖励图标和领取状态。 - 仅允许点击 `nextRewardDay` 对应且 `canClaim` 为真的卡片。 - 防止领取过程中重复点击。 - 活动打开和关闭时播放缩放、透明度动画。 - 当前可领取卡片播放轻微循环缩放提示。 - 自动领取期间隐藏关闭按钮并禁止遮罩关闭;领取回调结束后才允许关闭。 UI 约定: - 图片统一保持 `cc.Color.WHITE`,不对原图进行额外染色。 - 活动卡片底部状态文字节点被隐藏,不显示“点击领取/未解锁”等附加文字。 - 单奖励和多奖励使用相同的大图标尺寸。 - 多奖励从左到右排列并允许部分重叠,但按卡片可用宽度计算间距,避免越界。 - 卡片只显示道具图片,不显示奖励名称或数量文字。 - 第 7 天猫皮肤在未解锁时使用隐藏猫图片,解锁后使用正常猫图片。 ### 3.3 `assets/seven_day_gift/SevenDayGiftApi.ts` 七日活动接口封装和 TypeScript 数据契约,负责: - 活动查询由主包 `SevenDayGiftBootstrapApi` 调用 `signInActivityInfo`,Bundle 内不再请求活动接口。 - 保存猫皮肤:`setCatArr`。 - 保存普通道具:`userProp`。 - 5.5 秒没有回调时返回统一超时结果,迟到回调不再重复执行业务回调。 UID 优先读取: ```text cc.fx.StorageMessage.getStorage("uid") ``` 并同步回 `cc.fx.GameConfig.GM_INFO.uid`。如果发现 UID 改变,应先检查登录流程和本地 `uid` 缓存,而不是只看七日活动脚本。 ### 3.4 `assets/seven_day_gift/SevenDayGiftReward.ts` 将后端奖励转换成项目现有资产操作,支持以下类型: | 后端类型 | 前端处理 | | --- | --- | | `coin` | `cc.fx.GameTool.changeCoin()` | | `hammer` | 增加 `GM_INFO.hammerAmount`,保存 `prop`,通过 `SevenDayGiftApi.saveProps()` 同步 `/userProp` | | `freeze` | 增加 `GM_INFO.freezeAmount`,保存 `prop`,通过 `SevenDayGiftApi.saveProps()` 同步 `/userProp` | | `magic_wand` | 增加 `GM_INFO.magicAmount`,保存 `prop`,通过 `SevenDayGiftApi.saveProps()` 同步 `/userProp` | | `infinite_health` | 调用 `setUserPowerTime(seconds, "seven_day_gift")` | | `cat_skin` | 使用 `itemId` 调用 `setCatArr?action=save` | 奖励数量兼容: ```ts const rewardAmount = item.count !== undefined ? item.count : item.amount; ``` 即优先读取 `count`,旧接口使用 `amount` 时仍能正常发奖。卡片虽然不显示数量文字,发奖逻辑仍必须保留此兼容,除非后端已确认所有环境和历史数据都统一完成迁移。 领取幂等记录保存在: ```text seven_day_gift_processed_claims_v1 ``` 记录键为 `:`;这里的 `claimId` 是前端用 `[activityId, startAt, nextRewardDay]` 序列化生成的本地同步标识,接口不需要返回该字段。同一个 `claimId` 在同一设备上再次处理时直接视为成功,不重复增加资产。 注意:这个记录是客户端本地幂等保护,不能代替服务端活动领取的幂等校验。清缓存或换设备后本地记录会消失,后端仍必须保证同一用户、同一天、同一领取不能重复发放。 ### 3.5 `assets/seven_day_gift/SevenDayGiftRuntime.ts` Bundle 内的活动业务控制器,只有 Bundle 加载后才进入内存,负责: - 直接消费主页查询结果中的当日奖励,交给 `SevenDayGiftReward` 同步本地资产及对应资产接口。 - 更新当前快照的领取状态、调用项目公共奖励动画;不再发起额外活动请求。 - 管理主页 Loading、错误提示和领取失败后的重试状态。 - 销毁时清理 Loading 和运行状态。 旧的 `SevenDayHomeEntryLayout.ts` 和主页入口 Prefab 已删除;七日活动不再参与主页入口排序,也不会改动商城、排行榜等既有入口的位置或透明度。 ### 3.6 Prefab 和图片资源 新增: - `assets/seven_day_gift/prefab/sevenDayGift.prefab`:七日活动主弹窗。 - `assets/seven_day_gift/texture/*.png`:活动面板、卡片、标题、猫、道具和已领取标记等图片。 所有 Cocos 资源必须连同对应 `.meta` 文件提交,不能只提交 PNG、Prefab 或 TypeScript 文件。`.meta` 中的 UUID 是场景和 Prefab 引用资源的依据。 ### 3.7 `assets/Script/ActivityPopupAnimator.ts` 公共活动弹窗动画工具,七日活动通过 `popupAnimation` 选择动画类型。该脚本属于主包是因为 Bundle 内弹窗需要引用它;它不包含活动数据、测试入口或网络逻辑。 ## 4. 接口契约 ### 4.1 查询活动 `signInActivityInfo` 请求: ```json { "uid": "用户UID" } ``` 主要返回字段: | 字段 | 含义 | | --- | --- | | `serverNow` | 服务器当前时间,支持毫秒、秒级数值或可解析日期字符串 | | `activityId` | 活动标识,同时用于自动弹出本地键 | | `status` | 当前状态,前端明确识别 `active`、`completed`、`expired` | | `triggerLevel` | 后端配置的触发等级,仅展示/诊断 | | `triggerReached` | 后端最终触发判断;是否允许自动弹出依赖此字段 | | `startAt` | 活动开始时间,当前前端不直接校验 | | `endAt` | 活动结束时间,活动可见性判断会校验 | | `claimedCount` | 已领取天数 | | `todayClaimed` | 当天是否已领取 | | `canClaim` | 当前是否允许领取,同时控制自动弹窗和卡片领取 | | `nextRewardDay` | 下一次应该领取第几天 | | `rewards` | 7 天奖励数组及每项 `claimed` 状态 | 活动自动弹窗要求活动处于可见状态、`canClaim === true` 且当天未弹过。当前版本没有手动入口。 ### 4.2 查询结果直接驱动领取 不再使用独立领取接口。`signInActivityInfo` 的请求携带 uid,由公共 POST 层补 token,不传 gameName。未达到 23 关时 `code: 1, data: false`,主页不弹窗。 达到条件后,使用查询响应中的 `nextRewardDay` 在 `rewards` 中找到对应 `day` 的 `items`。自动弹窗动画结束后同步这些奖励,完成后本地更新 claimed、claimedCount、todayClaimed、canClaim 和第七天 completed 状态,再播放公共奖励动画。领取过程不重新请求活动接口。 每天自动弹窗记录按 UID、活动 ID 和服务器 UTC+8 日期隔离。同步失败允许在当前弹窗点击当天卡片重试,但不清除当天已弹记录;关闭后当天不会再次自动弹出。弹窗打开期间切回前台不重复查询。 当前沿用客户端增加资产并调用资产保存接口的方式;查询响应必须是可消费的领取快照。后端若已经直接增加资产,必须改为读取资产最终值,不能再使用客户端累加。服务器需要维护跨日进度和幂等;前端不会把自己计算的 claimedCount 写回活动接口。 ### 4.3 当前奖励配置 当前已联调的后端数据为: | 天数 | 奖励 | | ---: | --- | | 1 | 无限体力 900 秒(15 分钟) | | 2 | 锤子 ×1 | | 3 | 无限体力 1800 秒(30 分钟) | | 4 | 冻结 ×1、魔法棒 ×1 | | 5 | 金币 ×600 | | 6 | 锤子 ×1、冻结 ×1(策划调整:删除魔法棒,服务端待同步确认) | | 7 | 无限体力 3600 秒(1 小时)、猫皮肤 `itemId=12` ×1 | 正式奖励完全以服务端 `rewards` 为准,前端不再维护模拟奖励配置。 ## 5. 环境和服务器路由 服务器地址定义在 `assets/Script/module/Pay/Utils.ts`: ```text 正式服务器:https://q6rvwvtnga.sealoshzh.site/ 测试服务器:https://sor779u2w8.sealoshzh.site/ ``` 路由规则: | `envVersion` | 项目识别 | 使用地址 | | --- | --- | --- | | `develop` | 开发版 | 测试服务器 | | `trial` | 体验版 | 测试服务器 | | `release` | 正式版 | 正式服务器 | | 其他/未知 | 未知版本 | 正式服务器兜底 | 因此正常发布流程不需要上线前手工把 `testHttpip` 改成正式地址。体验版继续访问测试服,正式发布后自动切换正式服。 正式上线前必须同时确认: - 微信后台已经配置正式请求域名。 - 开发/体验测试需要的测试域名也已配置。 - 两个服务器部署了兼容的数据结构和对应接口。 - 正式服的活动配置、奖励、触发等级、活动期限已经检查。 ## 6. 对主项目原有文件的修改 ### 6.1 `assets/Scene/HomeScene.fire` 语义上的新增内容只有 `Canvas/sevenDayGift` 活动宿主节点,并挂载主包中的 `SevenDayGiftHost`。场景不再序列化引用活动 Prefab;宿主通过 Bundle 名和资源路径动态加载,避免 Prefab 依赖把整个活动反向带入主包。 由于 Cocos 场景文件使用数组 `__id__` 交叉引用,插入节点后大量后续编号发生位移,Git 会显示上千行机械差异。评审时应重点确认新增节点、父节点、组件和 UUID 引用,不应把所有 `__id__` 位移误判成业务改动。 ### 6.2 `assets/Script/JiaZai.ts` 每日任务数据增加空字段保护: - `levelPass`、`share`、`useEnergy`、`useProp` 缺失时建立默认对象。 - 后端任务数据不完整时只更新实际存在的字段。 这属于联调期间为避免每日任务接口变化导致主页 `checkTasks()` 崩溃而增加的兼容,不是七日活动核心逻辑,但主页如果在这里抛异常,会连带影响七日活动初始化和测试。七日活动已删除入口,不再修改主页入口渐隐列表。 ### 6.3 `assets/Script/GameManager.ts` 登录返回的 `data.data.task` 同时兼容: - JSON 字符串。 - 已经解析好的对象。 - 缺少部分任务字段。 - 无法解析的异常字符串。 原实现无条件 `JSON.parse()`,后端改为对象或返回异常结构时会抛错;现在使用类型判断和 `try/catch`,只覆盖实际存在的任务字段。 ### 6.4 `assets/Script/module/Pay/Utils.ts` 修改内容: - 恢复独立测试服务器 `testHttpip`。 - `POST()` 根据微信环境选择 `testHttpip` 或 `httpip`。 - 每日任务保存和领取结果增加空字段保护。 这项环境路由是七日活动安全测试和上线的关键。不要为了临时联调再次把 `testHttpip` 指向正式服,否则开发版和体验版会修改正式用户数据。 ### 6.5 `assets/Script/Reward.ts` 项目公共奖励弹窗原来只支持 Prefab 中预先存在的固定图标节点。本次增加 `getOrCreateRewardIcon()`: - 优先查找 `icon/` 现有节点。 - 找不到节点但调用方传入 `spriteFrame` 时,运行时创建 Sprite 节点。 - 找不到节点且没有 `spriteFrame` 时打印警告,不让空引用直接崩溃。 - `cat_skin` 使用 1.1 缩放。 七日活动把 `magic_wand` 转为公共奖励弹窗原有名称 `magic`;猫皮肤则额外传入活动中的 `catArt` SpriteFrame。 ### 6.6 `build-templates` 记录时 `build-templates` 相对 `main` 没有差异,不属于本次七日活动功能改动。后续排查 `game.json`、`project.config.json` 或分包模板问题时,应单独检查负责人提供的模板版本,不要把模板问题和七日活动脚本混为一谈。 ## 7. 日志和排查方式 上线版本只保留超时、领取失败、资产同步失败和缺失资源等异常日志,不再打印完整请求参数及响应。联调时使用微信开发者工具 Network 面板,并结合后端日志确认接口: ```text signInActivityInfo userCoin / userProp / userPower / setCatArr ``` 常见问题排查: | 现象 | 优先检查 | | --- | --- | | 达到 23 关但没有自动弹 | `signInActivityInfo` 的 `activityId`、`triggerReached`、`status`、`endAt`、`canClaim`;再查服务器 `levelAmount` 和本地当天自动弹记录 | | 每次回主页都重复弹 | 是否每次清缓存;UID/activityId 是否变化;自动弹出本地记录是否被其他逻辑清除 | | 卡片不能领取 | `canClaim`、`nextRewardDay`、当前卡片 `claimed`;查看 `signInActivityInfo` 返回及资产同步错误 | | 奖励数量为 0 | 后端是否返回 `count` 或 `amount`;值是否能转换为数字 | | 猫皮肤动画不显示 | `Reward.ts` 是否收到 `spriteFrame`;活动猫图片 UUID 是否有效 | | 猫皮肤没有保存 | 查看 `setCatArr` 的请求、`itemId` 和返回内容 | | 微信报合法域名错误 | 微信后台 request 合法域名是否包含当前环境服务器域名 | | 活动测试 UID 变化 | 登录接口、本地 `uid` 缓存、`GM_INFO.uid` 是否被其他流程重写 | ## 8. 正确测试流程 ### 8.1 UI 验收 测试代码已从上线分支删除。请由后端准备不同活动进度的测试 UID,在微信开发版或体验版依次验证: - 第 1~7 天布局。 - 单奖励和多奖励的图片大小与重叠,确认不显示数量文字。 - 今日已领取状态。 - 七天完成状态。 - 活动过期状态。 - 自动弹出、自动领取、领取期间禁止关闭和领取后关闭。 - 公共奖励动画。 前端不再提供模拟日期、清除自动弹出记录或增加资产按钮。 ### 8.2 完整测试服流程 准备干净测试 UID:服务器等级 22,并且没有七日活动记录。 1. 22 级进入主页,确认没有自动弹窗。 2. 通关并让服务器等级变成 23。 3. 返回主页,确认自动弹一次并自动发起领取。 4. 自动领取完成前确认关闭按钮不可用,完成后可以关闭。 5. 再进主页或切前后台,确认当天不重复自动弹。 6. 确认领取接口、Loading、奖励动画和资产变化。 7. 重启游戏,确认资产持久化。 8. 当天重复点击领取,确认后端不重复发放。 9. 由后端推进测试日期或重置测试活动,完成第 2~7 天验证。 10. 领满后确认不再弹出。 11. 使用另一条未领满记录推进到 `endAt` 之后,确认不再弹出。 12. 使用一个等级大于 23 且没有活动记录的老玩家 UID,验证补触发逻辑。 修改服务器等级不会删除已经创建的活动记录,也不会清除本地自动弹出记录。要重新测试“22 → 23 首次触发”,必须使用新 UID,或者让后端删除该 UID 的活动记录,并同时清除本地自动弹出记录。 ### 8.3 异常测试 - 断网进入主页。 - 查询接口超时后恢复网络。 - 领取时连续快速点击。 - 领取响应返回后立即杀进程。 - 第 7 天保存猫皮肤时断网。 - 切后台后重新进入。 - 清缓存后重新登录。 - 同一设备切换两个 UID。 - 后端缺少部分每日任务字段时主页不崩溃。 其中“后端已经确认领取,但客户端资产同步尚未完成时退出”是需要重点关注的边界。当前流程消费 `signInActivityInfo` 返回的奖励快照,再更新金币、道具、无限体力和猫皮肤;服务端必须提供可查询、可重试且幂等的最终结果,不能只依赖本地领取标记。 ## 9. 上线流程 1. 整理工作区,只保留确认需要的业务改动。 2. 把七日活动目录和所有对应 `.meta` 纳入 Git。 3. 提交功能分支。 4. 获取并合并最新 `main`。 5. 冲突解决后重新执行测试服完整流程。 6. 合并到发布分支或 `main`。 7. 从确定的发布 commit 做一次干净微信小游戏构建。 8. 微信开发者工具确认无新增红色业务错误、分包正确、请求域名正常。 9. 上传开发版本并设置体验版。 10. Android、iOS 真机测试,确认体验版仍访问测试服务器。 11. 后端确认正式接口和活动配置已部署。 12. 提交审核;审核通过后发布。 13. 如果后台支持灰度,优先灰度并观察活动查询、领取、重复领取拦截和猫皮肤保存错误率。 正式发布后需用正式环境测试账号做最小冒烟验证: - 页面上不存在“7日测试”和“接口反馈”按钮。 - `signInActivityInfo` 请求正式服务器。 - 达标且可领取用户当天自动弹出一次并自动领取。 - 一次领取可以完整到账。 - 领取后状态和资产重登仍一致。 ## 10. 后续修改指南 ### 10.1 修改触发等级或活动期限 触发等级和期限应优先修改后端配置。前端只消费: - `triggerLevel` - `triggerReached` - `startAt` - `endAt` - `status` 前端没有触发等级和期限的本地模拟配置。 ### 10.2 修改奖励数量 修改后端 `rewards` 配置。保持 `count` 为首选字段,并继续兼容 `amount`。 ### 10.3 增加新的奖励类型 至少检查以下位置: 1. `SevenDayRewardItem.type` 类型声明。 2. `SevenDayGift.getRewardIcon()` 的活动卡片图标。 3. `SevenDayGiftReward.grant()` 的真实资产发放。 4. `SevenDayGiftRuntime.showRewardWindow()` 对公共奖励类型的转换。 5. `Reward.ts` 的公共奖励动画图标创建逻辑。 6. 图片资源及 `.meta`。 7. 后端奖励配置与服务端幂等处理。 只增加图片但不增加发奖分支,会出现“界面能看到、资产不增加”;只增加发奖分支但不配置图标,会出现“奖励到账但动画没有图”。 ### 10.4 修改 Bundle 加载策略 - 主包只能依赖 `SevenDayGiftHost.ts` 和 `SevenDayGiftBootstrapApi.ts`。 - 不要在主包脚本中静态 `import` Bundle 内的 `SevenDayGift`、`SevenDayGiftRuntime`、完整 API 或 Reward。 - `HomeScene.fire` 不要重新添加活动 Prefab 的序列化引用。 - 正式版保持按需加载;如果修改释放逻辑,必须验证关闭活动后 `cc.assetManager.getBundle("seven_day_gift")` 返回空,并验证第二天仍可重新加载。 ### 10.5 修改活动图片或 Prefab - 优先在 Cocos Creator 2.4.15 中操作 Prefab 和场景。 - 保留已有 `.meta`,不要删除后让 Creator 生成新 UUID。 - 替换图片时检查透明边距、原始尺寸和 Sprite `sizeMode`。 - 保存场景后检查是否只产生预期语义变化。 - 构建后必须在微信开发者工具再次验证,不能只点微信开发者工具“编译”来代替 Cocos 重新构建。 ## 11. 当前工作区风险快照 当前工作区仍有数千项状态变化,绝大多数为 `.meta` 修改,并有 3 个与七日活动无关的 `.meta` 删除: ```text assets/gacha_bundle/img/cat.meta assets/libs/dn-sdk-minigame.meta assets/pause/texture.meta ``` 不要使用未经检查的 `git add -A`,否则可能把大量 Creator 自动改写或无关资源变化一起提交。 建议提交前逐项确认以下范围: ```text assets/seven_day_gift.meta assets/seven_day_gift/ assets/Script/seven_day_gift.meta assets/Script/seven_day_gift/ assets/Script/ActivityPopupAnimator.ts assets/Script/ActivityPopupAnimator.ts.meta assets/Scene/HomeScene.fire assets/Script/GameManager.ts assets/Script/JiaZai.ts assets/Script/Reward.ts assets/Script/module/Pay/Utils.ts docs/seven-day-gift-maintenance.md ``` 项目配置文件和 `build-templates` 不属于当前七日活动相对 `main` 的有效内容差异,除非负责人明确要求更新,否则不要顺手提交。 ## 12. 已知边界与维护原则 - 活动创建、触发等级、自然日、可领取状态和过期判断的最终权威是后端。 - 上线分支没有内置测试面板,活动状态测试依赖后端测试账号和微信开发者工具 Network 面板。 - 自动弹出记录是设备本地状态,清缓存和换设备后可能再次弹出;但后端 `canClaim` 仍决定是否有奖励可领。 - 客户端 `claimId` 防重不能代替服务端幂等。 - 正式版不打印七日 API 的详细前端日志,因此正式环境需要后端监控。 - 体验版走测试服,无法仅靠体验版证明正式服务器配置正确;正式发布前必须单独验证正式接口部署和配置。 - 场景和 Prefab 的 UUID 依赖 `.meta`,资源提交必须完整。 - 修改主项目公共奖励窗口或网络基类时,要回归其他活动,避免只验证七日活动。 - Bundle 卸载只能保证七日活动自身持有的资源引用被释放;若其他主包节点重新持有 Bundle 内 SpriteFrame、Prefab 或脚本对象,资源仍可能无法及时回收。