server/laf-cloud/functions/activityConfig/README.md
2026-09-24 17:59:52 +08:00

87 lines
9.4 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.

# 公共活动配置与两集合方案
> 2026-09-23 百人赛单独上线:当前 `activityConfig/list` 只注册百人赛,黄金矿工查询及依赖已暂时移除。以下黄金矿工及两活动共同迁移说明保留作后续上线参考,本次不要执行。发布函数和三个所需集合见 [百人赛生产发布清单](../../百人赛生产发布清单.md)。
本次实现使用两个活动集合:`activityConfigs` 和 `goldMinerPlayerPeriods`。现有 `order/users/iosOrder`、百人赛的样本和轮次归档集合继续保留;“两个集合”指精简后的黄金矿工专属存储及公共配置,不是整个游戏只有两个集合。
## 首页公共活动查询
新增只读接口 `GET/POST /activityConfig/list`,从当前及未来七天内开始的活动中,为每个玩法选择一期(当前优先,否则最近未来一期),返回日程、服务器时间和建议刷新时间。按 providers 显式注册各玩法。百人赛返回已登录玩家的个人活动期,黄金矿工复用现有周周期规则。完整字段、扩展方式和部署依赖见 [接口文档](LIST-API.md)。客户端入口接入另行处理。
## 配置结构与选择
`activityConfigs` 的版本记录结构:
| 字段 | 含义 |
| --- | --- |
| activityId | `goldMiner` / `cloudRise`;所有配置查询必须限定此字段 |
| recordType | `version` 表示不可变版本,`control` 表示独立运行控制 |
| configVersion | 同一活动内唯一的版本标识字符串,如 `goldMinerTestV1`;不按字符串大小推断新旧 |
| status | 版本记录为 published 才参与游戏选择 |
| enabled | 公共参与开关,位于 version 外层;布尔值,缺省 true。false 阻止新开期/新参与,已有参与和权益继续 |
| effectiveFrom | 毫秒生效时间 |
| publishedAt | 后端生成的发布时间,不能由客户端回填 |
| config | 活动自己的参数对象;由对应活动管理接口分别校验 |
同一活动版本禁止覆盖,配置修改需要新的 configVersion。发布仅允许未来生效:
- 黄金矿工:effectiveFrom 从 `config.effectiveFromPeriodId` 对应周四计算。本期开启时刻之前发布且已经生效的版本中,按 effectiveFrom、publishedAt 倒序选择;相同时间冲突拒绝使用。周期时间由北京时间周历计算,运行时不再建立全服期集合。玩家首次参与会冻结完整配置;管理员不能中途更换本期商品、价格、门槛、目标和奖励。
- 百人赛:最新已生效、已发布版本作为首页请求开期模板,冻结 durationHours、unlockLevel、pools;个人 startsAt 为显式 open_period 请求创建时间,endsAt 从时长计算。登录和过关上报不开期;首页在已达 unlockLevel、无已开启个人期、距上次结束超过 12 小时(首次参与免等待)且 enabled 开启时才请求开期。已有未结束个人期保持原样。旧 config.endsAt 不再关闭个人活动,详情见 [百人赛说明](../cloudRise/README.md)。
- 管理端“最新版本”和游戏端“当前适用版本”不是同一个概念。未来配置发布不会提前改变正在进行的活动。
黄金矿工 `set_purchasable` 将 `{activityId:'goldMiner',recordType:'control',periodId,purchaseEnabled}` 保存到本集合,与不可变版本分开;不会改奖励配置。旧环境迁移可在同一控制记录保存 `frozenConfig`,只用于保留之前已经冻结的期配置,新的期不需要此字段。
## 公共 enabled 开关
所有活动版本共用外层 `enabled`,与 `status` 同级,不放入 `config`。管理发布接口接受请求顶层布尔值,公共 publish 默认写入 true,旧记录缺失时也按 true 处理。同版本重复发布会核对开关,不允许通过重试覆盖已发布版本。
- 必须先选最新适用的 published 版本,再判断开关;不得把 enabled:true 加进查询条件,避免回退旧版本继续开放。
- 百人赛只在登录创建新个人期时判断。关闭后已有未结束个人期保留,仍可报名及结算。
- 黄金矿工按该期开始前已发布的最新适用版本判断(保留周历及版本冻结规则)。关闭后不创建新的玩家期记录;已有 tasks 的玩家继续本期流程,已有已分配付费权益也可恢复。仅存在无 tasks、无权益的空记录不视为已参与。下一期重新判断,不把上一期参与资格带入下一期。
- 黄金矿工 info、进度、下单和 activityConfig/list 使用相同参与判断。匿名或未参与玩家看不到已关闭期;已有玩家仍能看到自己的本期活动。purchaseEnabled 继续独立控制购买,enabled 不撤销已购权益,不截断支付回调或历史结算。
- 临时测试期使用排期条目的外层 enabled,默认 true,语义相同;仍需开启测试环境双开关。迁移期冻结配置保持原样,有适用 version 时沿用其 enabled,只有旧冻结配置时兼容为开启。
新玩法必须复用 `activityConfig/store.publish` 发布版本;创建新活动期时使用 `latestEnabled`,或对 `latest` 选出的版本使用 `isEnabled`。需要保留已有参与者的玩法,先读取本玩家快照,再判断新参与开关,不能在公共列表末尾统一删除所有 disabled 活动。列表 provider 和直接参与接口必须使用同一个资格判断;历史结算读取已冻结记录。新增活动仍需注册 provider 和实现自身参与流程,写入配置不会自动创建新玩法。
运营直接维护数据库时,修改选中 version 的 enabled 即可切换新参与资格;管理发布接口仍要求新的未来配置版本。关闭到开启后,百人赛在下次登录新开期,黄金矿工在下次查询或参与时恢复。
## 可直接改值使用的发布示例
以下均为 **POST JSON 请求体**。域名、管理员 token 必须替换,不能将管理口令交给游戏客户端。示例从北京时间 **2026-09-24 00:00** 生效,需提前发布;此日期过去后应改为未来日期、期 ID 和新的版本号。
| 活动 | 请求地址 | 完整示例 |
| --- | --- | --- |
| 黄金矿工 | `/goldMiner/admin` | [config.publish.example.json](../goldMiner/config.publish.example.json) |
| 百人赛 | `/cloudRise/cloudRiseAdmin` | [cloudRise-config.publish.example.json](../cloudRise/cloudRise-config.publish.example.json) |
黄金矿工示例配置:通过主线 41 关后获得资格,解锁价格 100 分(1 元),3/5/7/9/10 次累计胜利分别获得 100/200/300/400/500 金币。该配置从指定周四起持续适用,直到未来另一版本生效;每一期仍需单独付费,进度重新累计。
百人赛示例模板从 9 月 24 日 00:00 生效,门槛 100 关;登录开期后计时 24 小时,三阶段奖池为 10000/15000/20000 金币。示例中的旧 endsAt 字段不再限制个人开期。这些数值为示例,不是已发布的运营配置。
发布后由后端包装写入 activityConfigs,无需手工创建数据库 `_id`、activityId、recordType 或 publishedAt。黄金矿工仍在 body.config 内传 configVersion;百人赛可在请求根字段传 configVersion(也兼容 config.configVersion)。
## 黄金矿工玩家期记录
`goldMinerPlayerPeriods` 以玩家和期 ID 唯一,保存以下全部状态:
- 日期、完整 configSnapshot、configVersion/configHash、任务奖励快照。
- 累计通关进度与本期事件去重。
- entitlement:来源订单、来源/目标期、reserved/active 状态、激活时间。下一期预留资格只创建轻量记录,开期前没有任务或奖励快照;开期后初始化目标期配置并激活。
- tasks:原稳定 grantId、奖励内容、授权时间、issuing/claimed 状态、客户端保存确认时间。
- settlementId、settlementTaskIds、settlementPreparedAt、settlementState、settlementAcknowledgedAt:原结算 ID 和补发状态,与任务发货状态在同一文档更新。
- revision:原子更新版本;settlementNextRetryAt/entitlementNextRetryAt:后台失败重试时间。
不再维护独立的全服期、资格、奖励授权、结算或扫描游标集合。`settlements`、`confirm_settlement_delivery`、`ack_settlement` 请求和返回协议保持 V1.4,旧 grantId 和 settlementId 不变。金币仍由客户端发放并保存,当前整值金币协议的多设备/断线限制不因本次合并而消失。
## 后台任务
`goldMiner/jobs` 继续每分钟触发,分别限量处理待查订单、到期未结算玩家、到时待激活资格、支付已确认待履约订单。普通类别每批最多 100 条,商户查单最多 5 条。
任务成功后通过业务状态退出待处理范围;失败保存下次重试时间(普通后台失败至少退避 60 秒,商户沿用原查单退避)。已结算但仍等待前端发货的记录不会反复结算,不再需要 JobCursors。并发重复运行依靠原订单及玩家文档的幂等和版本检查。
## 部署与旧数据
先阅读 [迁移说明](MIGRATION.md)。本次代码不自动操作已部署环境,也不会删除旧集合。
依赖发布顺序:activityConfig/store → goldMiner/config/service/payment/legacyPayment/jobs/admin → 相关活动入口;百人赛同步更新 cloudRise/cloudRise 与 cloudRise/cloudRiseAdmin。运行两个管理接口的 setup_indexes,并确认黄金矿工每分钟触发器仍绑定。迁移、依赖和入口代码必须在维护窗口一致切换,不能让新旧版本并行写不同集合。