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

107 lines
8.8 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 百人赛单独上线:当前 `providers = [cloudRiseActivities]`,已移除黄金矿工 import 和查询函数;不论是否存在黄金矿工配置或玩家记录,都不返回该活动。匿名请求返回成功空列表;携带 uid/token 后只返回个人百人赛期。下文包含黄金矿工的示例和部署步骤是后续恢复时的参考,不是本次发布范围。当前发布依赖以 [百人赛生产发布清单](../../百人赛生产发布清单.md) 为准。
`POST /activityConfig/list`,登录客户端请求体为 `{ "uid": "100004", "token": "<当前登录 token>" }`。接口验证身份后返回该玩家的个人百人赛活动期和黄金矿工公共日程,只读,不创建活动期、不报名、不发奖。省略 uid 的 GET/POST 仍可查询公共活动,但不返回百人赛;提供无效 uid/token 返回 code:0。
## 返回内容
```json
{
"code": 1,
"msg": "ok",
"data": {
"schemaVersion": 1,
"serverNow": 1789885200000,
"windowEndsAt": 1790490000000,
"refreshAt": 1789885230000,
"activities": [
{
"activityId": "cloudRise",
"periodId": "cloudRise:100004:<随机期标识>",
"configVersion": "cloudRiseTestV1",
"startsAt": 1789833600000,
"endsAt": 1789920000000,
"unlockLevel": 100,
"phase": "active"
},
{
"activityId": "goldMiner",
"periodId": "goldMiner:2026-09-24",
"configVersion": "goldMinerTestV1",
"startsAt": 1790179200000,
"endsAt": 1790524800000,
"unlockLevel": 41,
"phase": "upcoming",
"purchaseEnabled": true
}
]
}
}
```
示例用于说明结构,具体活动和版本以环境配置为准。所有时间均为 Unix 毫秒,边界采用 `startsAt <= 当前时间 < endsAt`。
| 字段 | 含义 |
| --- | --- |
| schemaVersion | 返回结构版本,目前为 1 |
| serverNow | 服务器生成本次日程的时间,用于客户端校准时钟 |
| windowEndsAt | 本次查询未来七天的右边界,不含该时刻;已开始但尚未结束的活动也返回 |
| refreshAt | 建议最晚重新查询的服务器时间:30 秒后或最近的开始/结束边界,取较早值 |
| activities | 每个 activityId 最多一条;优先当前活动,无当前活动则返回最近即将开始的一期 |
| activityId | 固定玩法标识,不能用它表示期号 |
| periodId / configVersion | 活动期次和适用的配置版本 |
| startsAt / endsAt | 各玩法活动窗口;百人赛为 HomeScene 请求创建的个人期,endsAt 同时是匹配后的挑战截止时间 |
| unlockLevel | 已通过主线关卡数门槛,不是当前待挑战关卡编号 |
| phase | 请求时刻的 active / upcoming;缓存后应根据服务器校准时间重新计算 |
| purchaseEnabled | 黄金矿工购买开关;false 不代表关闭活动,也不影响已购权益 |
| openingRules | 开期条件数组;已登录玩家会收到百人赛规则,即使 activities 中尚无已开启活动 |
百人赛当前开期规则示例(无历史期):
```json
{"activityId":"cloudRise","enabled":true,"unlockLevel":100,"cooldownMs":43200000,"lastEndedAt":null,"hasOpenPeriod":false}
```
`lastEndedAt` 为上次失败/完成的最终阶段结束时间,或自然超时的原截止时间;null 表示没有已结束活动。HomeScene 使用已通过关卡数 >= unlockLevel、hasOpenPeriod=false、lastEndedAt=null 或校准当前时间-lastEndedAt > cooldownMs,并检查 enabled=true,满足后才发送 `cloudRise/index action=open_period`。列表只提供事实,查询不会开启活动。成功回执后显示新个人期入口。
接口不返回 eligible / visible,也不代替活动玩家接口。公共 enabled=false 只阻止新参与:百人赛已有个人期、黄金矿工已参与玩家和已分配付费权益仍按有效时间展示;黄金矿工需携带 uid/token 才能在关闭后返回本玩家的期次。匿名查询不会展示已关闭的黄金矿工期。百人赛挑战结束或到期后不再列出该个人期,下次登录开新期。待展示结算、未保存奖励和黄金矿工权益仍由对应玩法接口处理,不因列表缺少期次而丢弃。
无活动返回 code:1、activities:[]。查询失败返回 code:0、data:null,不能当作成功空列表。当前客户端按约定在每次实际请求前清空旧缓存,失败后重试;缓存按测试/正式环境和玩家 uid 隔离,账号或登录 token 变化后等待新的列表,不恢复上一登录的缓存。
## 查询及版本规则
- 百人赛:读取当前用户 users.cloudRisePeriod,兼容上线前仍进行中的旧挑战。只返回未结束的个人期;创建逻辑仅在 login。配置模板选择、个人计时和旧数据兼容见 [百人赛说明](../cloudRise/README.md)。
- 黄金矿工:复用 `goldMiner/config.calendar` 与 `goldMiner/service.periodById`,按北京时间周四起四天的窗口生成当前/后续期次。使用该期开启前已发布的适用配置;不把配置发布时间当作周期开启时间。兼容迁移冻结配置和购买开关,查询不创建玩家记录。
- 每个玩法只返回一期:优先当前进行中的活动;没有当前活动时,返回查询窗口内 startsAt 最早的未来一期。重叠的当前期保留 startsAt 最新优先、periodId 升序的规则,黄金矿工正在开放的测试临时期继续优先于普通周活动。最终列表按 activityId 排序。
- refreshAt 仍检查所有候选期的时间边界,包括本次没有返回的期次,确保测试临时期开始时可以及时重新选期。到期后由下一次查询返回新的当前期或最近未来期。
- 只输出明确列出的字段,不透传 config、任务奖励、支付参数或管理配置。
## 按活动查询及后续扩展
接口按玩法显式注册查询函数,并通过 Promise.all 并发执行后合并结果:
```ts
const providers = [cloudRiseActivities, goldMinerActivities];
```
- `cloudRiseActivities`:从已验证身份的 user 读取个人百人赛活动期;不扫描其他玩家,不创建或延长活动。
- `goldMinerActivities`:通过 `periodById` 只读取 `activityId: "goldMiner"` 的配置及控制记录,保留每周日历、版本选择、迁移冻结配置和购买开关规则。
- 未注册的活动不会因为配置写入 `activityConfigs` 就出现在列表中,也不会影响 `refreshAt`。
新增玩法时,新增一个只查询该玩法 activityId 的只读函数,接受 `(now, windowEndsAt, user)`(不需要玩家信息的玩法可忽略第三个参数),返回 `{ activities: ActivityInfo[], openingRules: OpeningRule[] }`(没有开期规则的玩法返回空 openingRules),并添加到 providers。函数负责本玩法的配置有效性、期次计算及版本选择;只返回当前开放或未来七天内开始且尚未结束的期次,允许读取本玩家活动状态,不写入玩家、订单或奖励记录。必须遵循公共 enabled 规则:先选版本再判断,新参与使用 store.latestEnabled 或 isEnabled,已有参与快照与权益按玩法保留;provider 与直接参与接口共用判断。函数执行失败时抛出错误,由接口统一返回失败,不能伪装成空列表。
新函数输出统一的 ActivityInfo 结构,客户端无需改变公共查询和缓存格式,但仍需接入新活动的图标、可见性和点击处理。部署新的查询函数及依赖后重新发布列表接口,活动才会返回。
## 前端接入时机与部署
登录后、回到首页或回到前台时按缓存有效期查询;首页根据已知开始/结束边界本地更新入口,并在 refreshAt 到期时刷新以发现登录后新发布的活动。客户端已接入公共日程查询和百人赛入口刷新,其他活动入口由各玩法分别接入。
先发布 activityConfig/store、新增 cloudRise/periods,以及已有 goldMiner/config、goldMiner/service、goldMiner/testPeriods 和 Utils 依赖;再同步发布 login、cloudRise/index、activityConfig/list 及 YAML。配套客户端必须携带 uid/token。列表无需新集合或数据迁移,POST 空请求仅能验证公共日程。本地修改不会自动部署。
本地验证:`node --test laf-cloud/functions/activityConfig/tests/list.test.mjs`。
## 黄金矿工测试临时期
测试服同时设置 `PAYMENT_APP_ENV=test`、`GOLD_MINER_TEST_PERIODS_ENABLED=true` 后,本接口包含已发布的 `goldMiner:test:...` 临时期。临时期正在开放时优先展示它,隐藏当前普通周活动条目,与黄金矿工 info 保持一致;结束后恢复周历选期。没有当前活动且它是最近未来一期时,临时期按 upcoming 返回。客户端在开始/结束边界重新查询列表,不要自行推算期 ID。其他字段与正式活动一致,配置和联调步骤见 [临时期说明](../goldMiner/TEST-PERIODS.md)。