| .. | ||
| prefab | ||
| script | ||
| texture | ||
| prefab.meta | ||
| README.md | ||
| README.md.meta | ||
| script.meta | ||
| texture.meta | ||
CoinMadness(黄金矿工)活动前端说明
核对日期:2026-09-30,客户端基准 7e14f661。本文描述实际实现,不代表完整兼容仓库后端 V1.7 或已完成线上验收。文档入口 · 接入差异与验证状态。请求示例省略真实账号和 token。
活动预制体、图片和面板脚本在 coin_madness 分包;Host、GoldMinerService、BrownLoadingSpinner 在主包侧,入口图在 resources。游戏测试包、活动测试面板及演示场景已移除。普通 Creator 预览不启动真实活动;独立预览夹具仍在 tools/coin-madness。
1. 代码分工
| 文件 | 职责 |
|---|---|
| script/CoinMadnessPanel.ts | 活动主面板、购买和领取按钮、倒计时、金币动画 |
| script/CoinMadnessSettlement.ts | 补发到账通知窗口 |
| script/CoinMadnessDigits.ts | 图片数字显示 |
| ../Script/coin_madness/CoinMadnessHost.ts | 首页入口、同步时机、分包加载释放、主面板/说明/结算窗口切换 |
| ../Script/coin_madness/GoldMinerService.ts | 活动接口、支付订单、领奖与补发、交付记录和恢复流程 |
| ../Script/module/Pay/Utils.ts | POSTJSON、服务器选择、金币保存队列、通关保存请求 |
| ../Script/module/Tool/GameTool.ts | addLevel 中接入真实通关事件 |
| ../Script/GameManager.ts | startGame 中提前获取首页活动状态 |
| ../Script/JiaZai.ts | 挂载 Host、首页左侧活动补位、金币数字刷新 |
通常调用关系:
CoinMadnessPanel(用户操作)
→ CoinMadnessHost.requestActivity
→ GoldMinerService(组织业务)
→ Utils.POSTJSON(发送 HTTP)
→ 后端
真实通关另走 GameTool.addLevel → Utils.setUserLevel;活动胜利事件附在原有关卡保存请求里。
2. 环境与接口清单
活动请求使用 POST JSON。Utils.serverUrl 根据微信版本选择服务器:开发版/体验版使用 testHttpip,其余使用 httpip。具体地址以 Utils.ts 为准,不在本文重复硬编码。
当前两个地址相同:合入 main 后,开发版/体验版也会请求同一正式服。账本隔离依据实际 URL 和 uid,不依据版本名称。
GoldMinerService.post 为认证请求补充 uid;Utils.POSTJSON 补充 token。activityConfig/list 使用非认证请求。
共涉及 8 个主要后端地址。goldMiner/index 是同一个地址,通过 action 区分业务。
| 地址 | action | 用途 | 直接调用位置 |
|---|---|---|---|
| activityConfig/list | 无 | 活动日程、服务器时间,辅助判断通关所属期次 | GoldMinerService.readSchedule |
| goldMiner/index | info | 玩家活动状态、价格、进度、任务和领取状态 | GoldMinerService.readInfo |
| goldMiner/index | claim | 检查资格,返回本档奖励授权与金额 | GoldMinerService.deliver |
| goldMiner/index | confirm_delivery | 确认普通奖励已保存到账 | GoldMinerService.deliver |
| goldMiner/index | settlements | 查询往期补发清单 | GoldMinerService.settle |
| goldMiner/index | confirm_settlement_delivery | 确认补发奖励已保存到账 | GoldMinerService.deliver |
| userLevel | save | 保存关卡,并携带 goldMiner 胜利事件 | Utils.setUserLevel |
| userCoin | save | 保存领取/补发后的金币总余额 | GoldMinerService.deliver |
| wx/orderPaySig | 无 | Android 原生支付下单,返回支付参数 | GoldMinerService.purchase |
| wx/iosorderPaySig | 无 | iOS 原生支付下单,返回支付参数 | GoldMinerService.purchase |
| wx/getPayInfo | 无 | 查询 Android 订单支付和权益结果 | GoldMinerService.queryOrder |
| wx/iosgetPayInfo | 无 | 查询 iOS 订单支付和权益结果 | GoldMinerService.queryOrder |
Network 中多个 index 请求不一定重复:必须查看 Payload.action。HTTP 200 只代表获得 HTTP 响应,业务成功仍要检查响应 code 和内部业务结果。
3. 首页、入口和完整刷新
触发时机
- 首次登录:GameManager.startGame 在加载画面期间调用 readForDisplay,和商店分包加载并行;拿到首份活动状态或请求失败后继续进入首页。
- 首页 Host 启动、游戏返回前台:调用 sync。
- 打开活动面板:先显示 service.view 的已有数据,再请求首份最新信息。
- 本地检测到活动时间阶段变化:触发同步,包括到期。
readForDisplay 会启动/复用 refresh,但只等待第一次 info。后续恢复仍继续执行,并不是只请求 info。
refresh 的真实执行顺序
info ← 首份数据返回后即可显示入口/主面板
→ activityConfig/list
→ 遍历未完成订单,逐笔 queryOrder
→ 恢复未完成的普通领奖和 issuing 奖励
→ settlements,处理补发
→ info ← 获取最终任务状态
没有待恢复订单、没有奖励、没有分页时,通常仍有 4 次请求:info → list → settlements → info。
同一客户端的在途 refresh 会复用 Promise;前一轮完成后再次触发会新开一轮。恢复与购买、领奖使用同一串行队列,避免并发交付,但后面的操作可能等待前面的恢复任务。
入口显示与布局
- 有补发到账通知或可领取/发放中的奖励时,入口可显示红点。
- 普通展示还要求 canIos 开关允许,且 info.status 为 purchasable、purchase_disabled 或 unlocked。
- locked、unavailable 默认不显示入口,奖励通知是例外。
- 使用 HomeScene 的 Load/Top/CoinMadnessEntry;找不到时才创建。
- JiaZai.refreshHomeActivityEntryLayout 统一排列左侧入口,参与首页渐隐控制;不固定悬浮在另一套坐标上。
4. 倒计时、到期与重试
前端用服务器时间与本地时间差校准:
offset = serverTime - Date.now()
剩余时间 = endsAt - (Date.now() + offset)
面板每秒重新计算显示,Host 每 0.5 秒检查本地时间阶段/红点。这些本地检查本身不发请求。当前没有固定每 30 秒的全量轮询。
到期时活动面板退出:已有到账通知则切换结算窗口;否则关闭并触发同步,补发处理成功后再展示通知。
settlements 返回 settling、补发失败或查单失败会设置重试标记。Host 的重试间隔依次为 2、3、5、7、10、15、25、30、50 秒,当前计数未重置时最多追加 9 次。回前台等 resumeSync 会重置计数。
恢复标记触发 retryRecovery,只查未完成订单与补发;订单有变化或通知金额改变时才读取 info,不重读日程或重放普通领奖。完整同步抛错则重试完整 refresh。重新进入首页、回前台或期次边界可触发新一轮;重试次数不是整个会话的总请求上限。
已知边界:
- 后端临时开启一个前端未知的活动,玩家一直停在首页时,当前实现没有固定轮询自动发现,要等下次同步。
- settlements 返回空列表且未标记 settling 时,前端按本次无记录处理,不会仅因空列表重试。
- 后端持续 settling 超过有限重试次数,需要后续同步或检查服务端结算任务。
5. 真实通关流程
GameTool.addLevel
→ 本地关卡推进
→ GoldMinerService.victory 生成活动事件
→ Utils.setUserLevel
→ userLevel / save(附带 goldMiner)
→ GoldMinerService.victoryResult 处理活动结果
主线上报示例(省略认证字段):
{
"action": "save",
"levelAmount": 91,
"goldMiner": {
"periodId": "实际活动期ID",
"eventId": "本次胜利唯一ID",
"outcome": "win",
"mode": "main",
"clearedMainLevel": 91
}
}
- 主线省略 isWuXian;无尽使用字符串 "true",goldMiner.mode 为 endless 并携带 endlessSequence。
- 前端需识别有效活动期和符合条件的真实胜利,才附带 goldMiner;配置补关等不作为真实胜利计数。
- 不是再单独请求 index 给活动加进度。
- 检查 data.goldMiner.code、activityCounted、duplicate、progressWins。外层 code=1 不等于活动计数一定成功。
- victoryResult 更新本地活动累计次数;完整任务领取状态由后续 info 获取。
- 本地关卡已前进不代表服务器保存成功。userLevel 整体不是纯活动幂等接口,不应自动无限重放失败请求。
6. 购买解锁流程
Panel.run('purchase')
→ Host.requestActivity
→ Service.request → purchase
→ info:校验活动期、购买状态与价格
→ 下单:返回 outTradeNo、支付参数
→ 微信客户端拉起支付
→ queryOrder:查询后端订单权益
→ info:刷新解锁状态
→ 面板更新,成功解锁后自动打开一次“?”说明
| 渠道 | 下单地址 | 微信客户端 API | 查单地址 |
|---|---|---|---|
| Android 原生 | wx/orderPaySig | wx.requestMidasPaymentGameItem | wx/getPayInfo |
| iOS 原生 | wx/iosorderPaySig | wx.requestMidasPaymentGameItem | wx/iosgetPayInfo |
| 当前 iOS 客服 | Utils.GoKEFu 本地生成订单及会话参数 | wx.openCustomerServiceConversation | wx/iosgetPayInfo |
微信支付 API 与 wx.showToast 是客户端 API,不是本项目后端地址。支付窗口关闭不等于后端确认成功。
queryOrder 验证 pay_state=2、rewardDelivery='goldMiner.claim' 和 goldMiner 权益数据。支付客户端调用成功后最多尝试查单四次,间隔 1.5、3、4.5 秒;PAYMENT_PENDING 和 NETWORK_UNKNOWN 可快速重试,其他异常提前退出。仍未确认时提示“支付结果确认中”。每次有效购买生成新 createRequestId;iOS 原生明确返回错误码 16 且非取消时回退 GoKEFu。当前客服链路不同于后端 V1.7 的 create_order 签名票据,见接入差异。
提示使用 wx.showToast:购买成功、已取消支付、购买失败或支付结果确认中。购买只解锁权益,不自动发放全部任务金币。跨期承接权益可能分配给下一期,不等于当前期立即解锁。
7. 点击领取一档任务奖励
Panel.run('claim')
→ Host.requestActivity
→ Service.request → deliver
→ claim:取得奖励授权
→ userCoin/save:保存增加后的总余额
→ onSaved:立即启动金币动画,飞到顶部后释放数字显示等待
→ confirm_delivery:确认该档到账(不等待动画)
→ info:读取最新任务状态
以余额 1000、奖励 300 为例,userCoin/save 上传 coinAmount=1300,不能上传 300。
正常首次领取通常四次请求。金币保存确认成功后就播放动画,无须等待 confirm_delivery 或最后一次 info;服务端确认失败时仍保留恢复凭证。网络和串行队列可能造成保存前等待。
金币余额实际保存早于动画,只有数字显示被延迟。当前每档动画产生 16 枚金币,约 0.935 秒后释放显示等待,再过 0.24 秒清理动画层;并发动画全部到达后刷新顶部数字。关闭面板也会恢复显示。
已保存但未确认的奖励恢复时只重试确认;已确认奖励不重复加金币。具体取决于本地交付记录和后端响应。
8. 活动结束后的补发
Service.refresh → settle
→ settlements:获得补发清单
→ 对每档 reward 调用 deliver(直接使用清单中的授权)
→ userCoin/save
→ confirm_settlement_delivery
→ refresh 末尾 info
→ Host.showSettlementNotice
→ 显示补发到账窗口
补发清单包含奖励授权,不再对过期任务调用 claim。
一档 1000 金币待补发的结构示例:
{
"code": 1,
"data": {
"items": [{
"settlementId": "实际结算ID",
"periodId": "实际活动期ID",
"rewards": [{
"taskId": "实际任务ID",
"grantId": "实际奖励凭证ID",
"items": [{ "type": "coin", "count": 1000 }]
}]
}],
"nextCursor": null
},
"msg": "成功"
}
同一奖励的 ID 应稳定,多个任务分别列出各自的 reward。不要仅返回总金额,也不要在可处理清单上继续标记 settling。
confirm_settlement_delivery 请求携带 settlementId、grantIds;当前逐档调用,grantIds 每次包含一档的 grantId。客户端验证响应中的 settlementId 和 confirmedGrantIds。
如果一页有三档待补发奖励,核心流程通常是:查询一次 + 保存三次 + 确认三次,完整 refresh 还包含其他查询。
客户端仍发送 limit=100,但 V1.7 已改为服务器控制页大小,不能依赖这个参数决定返回数量。非 settling 响应中,nextCursor 非空时用 afterId 翻页,即使 items 为空也继续。当前遇 settling 会立即退出,即使有 nextCursor;这与 V1.7 要求继续扫描其他期的规则不同,尚待对齐。no_pending_rewards 的空列表、空游标可自然结束本轮。
返回 settling 时表示尚未生成可处理清单,不表示没有奖励,也不表示到账。
离线结束的活动在下次进入首页时同样查询,不依赖打开活动面板。仅有符合补发条件、实际处理成功的金额才形成到账通知,不是所有玩家到期都弹结算。
关闭结算窗口只调用 dismissNotice 清除本地通知,不再发币、不再调用确认接口。若到账后未关闭窗口就退出,下次可能再次显示通知,但不应再次发币。
补发通知直接加载 CoinMadnessSettlement,不先实例化活动主面板。关闭通知后立即更新入口及左侧补位;过期任务的残留红点不保留入口。如果已有新一期可参与活动,则保留新一期入口。
9. 标识关联与本地记录
| 字段 | 含义及用途 |
|---|---|
| periodId | 关联某一期活动的通关、权益、任务和补发 |
| eventId | 一次胜利的唯一事件标识,用于活动事件去重 |
| outTradeNo | 下单返回的订单号,查单使用 |
| taskId | 一档活动任务 |
| grantId | 具体奖励授权,确认与交付恢复使用 |
| settlementId | 一笔补发结算,补发确认使用 |
本地账本按服务器和账号隔离,包含 orders、grants、events、notices 等数据。
确认接口存在的原因:查询到授权不等于金币已保存。保存金币成功后,确认接口才告诉活动后端“这档已完成”。
但当前 userCoin/save 是总余额覆盖,与确认接口不是同一个事务;仅靠 grantId 不能保证重装、多设备等情况下严格只发一次。余额保存结果不明时,代码会阻止直接重复加币,需要核对,不能只因仍是 issuing 就再加一次。
10. 为什么 getPayInfo 经常出现
每次完整 refresh 都遍历本地订单:有订单号、未标记 done、且不是 cancelled 的订单都会查。因此历史未付款或失败订单可能反复出现。
查单失败设置 refreshNeedsRetry,下一轮恢复重试会再查这些订单。多个期次订单意味着一轮多个 getPayInfo。这是查单,不是重复下单或扣款;同一期本地只保留最近一次购买记录,旧记录被替换后不再由该账本恢复。
完整 refresh 包括首屏、订单、领奖恢复和补发;retryRecovery 已单独用于恢复重试。首屏提前返回第一次 info,后台完整刷新仍会继续。
11. 排查与验证
2026-09-30 清理:已删除游戏测试分包、活动测试面板、首页测试入口及两个演示场景。保留活动正式流程、支付诊断日志和离线回归检查。
- 进度不涨:查看真实通关那条 userLevel 的请求 goldMiner 与响应 data.goldMiner,再对比 info 的 periodId/progressWins/tasks。
- 未弹补发:查看 settlements 是否 settling、有无 items、后续 userCoin/save 和 confirm_settlement_delivery 是否成功。
- 领取慢:检查串行队列中的前序恢复,以及 claim → 保存 → 确认 → info 各次耗时。
- “网络结果未知”:检查 transportReason、HTTP 状态。空响应、非 JSON、超时、连接失败需分别定位。
- 在浏览器地址栏打开接口是 GET,不等于游戏实际 POST;应查看 Network 中同一条请求的 Response。
仓库根目录可运行以下离线检查(不操作真实支付和余额):
node tools/coin-madness/check-api.cjs
node tools/coin-madness/check-first-display.cjs
node tools/coin-madness/check-expiry-sync.cjs
node tools/coin-madness/check-expired-panel.cjs
node tools/coin-madness/check-release-ui.cjs
node tools/coin-madness/check-home-entry-ready.cjs
node tools/coin-madness/check-settlement-entry.cjs
node tools/coin-madness/check-types.cjs
上面列出的是可运行的现有脚本,不代表全部已通过。上次 check-types 报 Utils.ts 的 wx 声明问题,check-release-ui 的夹具及断言待维护;通过记录和真机待验项见接入说明。类型检查以 HEAD 为基线,提交后基线随之改变,“无新增”不等于零错误。
最新仓库协议:后端 V1.7;当前兼容边界:接入说明。V1.3/V1.5 只作历史参考,不能据此认定客户端已完成 V1.7 接入。