MatchMaster/docs/starter-pack-v2.md

80 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 新手礼包逻辑接入
沿用用户搭建的 `assets/action_bundle/prefab/newbieGift.prefab`,本次代码不创建、删除或重新布局 UI 节点。
`NewbieGift` 使用 `timeContainer/time` 显示 `HH:MM:SS`,使用 `btnContainer/btn` 处理购买;保留 `closeStarter_pack`、`buyProduct`、`againGet` 按钮绑定。脚本不依赖旧宝箱/气泡 Spine 和 propBg 节点,兼容在编辑器中删除这些旧节点。`Loading`、`ConfirmBox` 沿用现有节点,确认框标题为“幸运礼包充值”。到期后显示“已结束”,禁用购买按钮并隐藏首页入口。
## 当前职责划分
后端管理 48 小时活动期限、旧期限迁移及重新激活间隔,奖励仍由前端发放。后端实现只位于同级独立 `../server` 仓库;MatchMaster 内的 `server` 目录未修改。
前端按 3 元购买,当前统一发放 3000 金币、锤子/冻结/魔法棒各 3 个,以及 30 分钟无限体力。奖励配置位于 `assets/Script/module/Config/StarterPack.ts`,`infinite_health` 单位为秒(1800)。正常购买和登录补单共用该配置,不读取订单奖励版本或快照;改版前创建但尚未发放的订单,由新版客户端补发时也采用新版奖励。已经发过的订单不会因此自动补差额。
首页开启门槛不变:通关第 15 关后(内部 level 为 15),满足原支付入口条件。首次触发立即弹出并记入当前账号当天记录,以后每天首次进入首页提醒一次,关闭后保留入口。加载失败不消耗提醒次数。
## 与原支付接口衔接
- 购买前读取活动截止时间和购买状态,在前端检查是否仍可购买;不要求活动接口或订单接口返回奖励版本。
- 直购订单查询返回 `pay_state=2` 表示已支付待领取,随后调用原 `getOrderReward`;收到 `code=1, data="ok"` 即按前端配置发奖。
- 直购领取确认失败时,本次会话保存已经确认支付的订单号,重试领取确认,避免重新查单被当成已完成。
- 旧 iOS 客服查单成功时,接口已完成订单;前端直接发奖,不再调用一次领取确认。
- 直购查询返回已领取,或旧 iOS 接口返回“已经获取到奖励”时,清除过期的待支付界面状态,不再次发奖。
- 正常购买与补单都显式传递原始订单号,在本地按账号和订单号去重;原领取接口不返回订单元数据。两条路径都通过 `setUserPowerTime` 发放 1800 秒无限体力,未开启或已过期时从领取时间起算,仍有效时在原截止时间上叠加,并同步后端。领奖窗口显示无限体力,资源埋点沿用该方法,补单标记为 compensate。月卡倍率和普通体力数量不变。
## 真机支付排查
“获得新手礼包数据”来自 `limitedTimeEvent` 活动查询,不是发奖日志。微信支付成功回调和回到前台可能各触发一次查询;查单进行中不会再次开启并发查询链。
新手礼包直购每轮查单最长 30 秒,超时显示重新领取确认框,保留原订单,不新建订单、不把微信客户端成功回调当作服务端已支付。晚到的查询响应不会继续触发已经超时的一轮处理。领取确认失败后继续使用已经确认支付的订单重试。
日志前缀为 `[新手礼包支付]`,依次包含微信回调成功、查单目标服务器、每次查单返回、领取确认和前端发奖。日志只输出订单号末 6 位,不输出 token 或微信支付凭证。
体验版和开发版当前连接测试服 `sor779u2w8.sealoshzh.site`,正式版连接 `q6rvwvtnga.sealoshzh.site`。直购签名的支付环境仍为 `env=0`。真机支付成功但查单超时时,需要按同一订单核对微信支付发货回调的实际地址、目标云函数日志和订单库:`state=0` 尚未记录支付,`state=1` 已支付待领取,`state=2` 已确认领取。当前代码无法证明微信后台实际配置了哪个回调地址,不应仅凭前端成功日志手动发奖。
## 有效期与限制
首次触发从服务器当前时间起计 48 小时。未购买且仍有效的旧 24 小时礼包在读取时增加 24 小时,并标记已迁移。已购买不重新开放;已过期不会因为普通读取或首次触发请求自动续期,符合下述新规则时可重新激活。用户上的 `starterPackVersion` 仅作为期限迁移标记,客户端发奖不使用它。
## 重新激活(2026-09-10)
必须同时满足未购买、已触发且已过期、距离最近一次实际展示礼包弹窗严格超过 48 小时,再满足以下任一行为,重新从服务器当前时间开放 48 小时:
- 金币低于 500:首页检查/到期时,以及金币成功同步到服务器后检查。服务端使用数据库金币数判定,500 不满足。
- 关卡内点击商城或道具购买入口。
- 通过任何入口实际打开商城,统一在商城脚本中检查。
- 连续挑战同一关卡失败 4 次:本地按账号和关卡保存计数,一次挑战内复活后再次失败不重复累计;通关清零。助战关卡不计入本人当前关卡。该计数不跨设备同步,也不由服务器独立结算;后端核对上报关卡与当前关卡一致、次数为至少 4 的整数。
重新激活后,首页恢复入口并弹出礼包;关卡内复用已有预制体显示礼包,关闭时恢复原暂停状态。加载期间如果已购买、过期或进入胜利结算,不再展示。因场景切换或加载失败未能展示时,后续首页检查仍可按原每日提醒规则展示。
实际展示时上报 `action=shown`,服务器保存 `starterPackLastShownAt`(毫秒)。首页按钮、自动提醒和重新激活的弹出都会更新该时间;单纯查看活动状态、进入商城或显示首页按钮不会更新。旧记录缺少该字段时,以原截止时间作为保守起点,须从该时间再过 48 小时才允许重新激活。本地保留未成功上报的展示时间,后续检查只能用它延后重开,不能缩短服务端间隔。
保留原有每天首次进首页提醒,不增加每次 login 弹窗;本次不添加商城宣传标签,也不修改 UI 节点。3 元价格和真实支付流程保持现状,当前奖励配置见上文。
部署时先发布独立 server 仓库的完整 `limitedTimeEvent.ts`,再发布客户端;无需新增云函数或批量清空用户数据。新增 `reactivate`/`shown` 动作,原 `read`/`save` 兼容旧客户端。未部署后端时,新客户端不能完成重新激活。
本次相关回归:客户端 119 项、后端 31 项通过;后端支付分流测试按现有要求提供测试回调地址环境变量。客户端类型检查无新增诊断,仍有既有诊断。尚未部署或进行真机重新激活验收。
到期前已创建的有效订单可继续走原支付流程。因后端下单接口恢复原逻辑,到期禁购由前端入口和购买前检查控制,不再保证请求到达服务端时仍未过期,也无法阻止旧客户端或直接请求在到期后下单。前端发奖保留原有跨设备去重及中断恢复方面的限制;旧 iOS 查单将订单置为完成后若客户端未收到成功结果,不能仅靠重试保证补发。
## 本地验证与发布
### 恢复真实支付(2026-09-09)
前端发奖经体验版验证后,已撤销非正式版跳过支付的临时逻辑。开发版、体验版、正式版均恢复原有下单、支付、查单、领取确认和前端发奖流程。此前的本地测试领取标记不再参与礼包资格判断,已发放的测试资源不会回滚。
独立 server 仓库的订单分流提交 0030b5a 保留,尚未部署。部署环境变量、三个函数和发布顺序见该仓库的 laf-cloud/paymentRouting.README.md;其中描述客户端测试旁路的段落是撤销前状态,以本文为准。生产分流上线前,测试服真实支付仍可能遇到回调落在生产服、测试订单保持 state=0 的问题。
```sh
node --test tools/test-starter-pack.cjs tools/test-first-game-entry.cjs tools/test-career-loading.cjs
```
测试读取实际预制体,覆盖节点绑定、首次/次日提醒、到期按钮、原接口返回格式、旧 iOS 直接发奖、领取确认重试、登录补单、统一奖励和本地去重。客户端测试不再依赖同级 server 仓库。
上次有效期简化验证:客户端 104 项、后端 14 项测试通过。客户端 134 个 TypeScript 文件在补充运行时 `cc.fx` 声明后与 HEAD 对比,均有 17 条既有类型诊断,没有新增类型诊断;这不等于项目全量编译通过。
本次真机查单问题回归:客户端 108 项测试通过,新增支付回调成功但服务端未确认、30 秒后保留原单重试、超时后晚到响应、异常查询数据和缺失订单号场景。后端未修改。
随后根据云端 `function starterPackConfig not found` 日志,已将时间规则合并到独立 server 仓库的 `limitedTimeEvent.ts`。活动接口修复只需替换并发布该完整文件,不再依赖额外的 `starterPackConfig` 云函数。该错误属于活动接口,不能代替 `wx/payCallBack` 的调用记录来判断支付是否确认。
后端测试和部署范围见独立仓库的 `laf-cloud/starterPack.README.md`。若之前已发布带订单版本校验的后端,需要配套恢复原支付函数,否则不带版本的新请求会被旧校验拒绝。未进行真实设备支付验收,也未推送或部署云函数。