aslan-server/rc-service/rc-service-other/docs/Aslan礼物挑战活动接口.md

111 lines
6.5 KiB
Markdown
Raw 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.

# Aslan 礼物挑战活动接口
## 接入约定
- H5 基础路径:`/activity/gift-challenge/aslan`
- WebConsole 基础路径:`/activity/gift-challenge`
- H5 请求必须经过网关并携带 `Authorization: Bearer ...``Req-Sys-Origin: ATYOU`
`Req-Client``Req-App-Intel`。用户 ID 与来源由网关注入,接口不接收客户端 userId。
- 时间均为毫秒时间戳;日榜日期是活动 `timeZone` 下的 `yyyy-MM-dd`
- 单个活动最多覆盖 366 个活动时区自然日;首次启用会批量幂等预建全部 DAILY 结算门闩,
因此没有任何参与者的日期也会按时冻结为空榜。
- 启用会冻结任务、排名区间所引用资源组的完整奖励配置(发放字段和 H5 展示字段),最多
5000 个奖励项。活动开始前修改任务、排名奖励或活动时间会先清理旧的 `NOT_STARTED`
门闩和旧奖励快照再整体重建;停用也会清理这些预建数据。
- `dailySettlementDelayMinutes``overallSettlementDelayMinutes` 是有界迟到窗口,不是无限
追溯。结算门闩开始后对应榜单不再接受迟到写入;执行自动或人工结算前必须监控
`ASLAN_GIFT_CHALLENGE_GIFT` consumer group lag确认落后量已进入可接受范围。
- 积分直接消费原始送礼事件:仅 `ATYOU + GOLD + 非背包 + amount > 0`,强制排除
`LUCKY_GIFT``MAGIC`,并且事件时间满足 `[startTime, endTime)`。金额固定使用
`GiveAwayGiftBatchEvent.countConsumAmountTotal()`,与礼物主流水口径一致。
## H5 接口
### 1. 活动详情
`GET /activity/gift-challenge/aslan/detail?activityId={id}`
- `activityId` 可选;缺省时返回当前进行中、最近待开始或最近结束的已启用活动。
- 返回 `activity`、三个任务配置、`DAILY/OVERALL` 排名奖励、活动状态和服务端时间。
- 本接口不修改任务H5 打开页面后必须调用 `/enter`
### 2. 每日进入并读取用户状态
`POST /activity/gift-challenge/aslan/enter`
```json
{
"activityId": "1234567890123456789"
}
```
- 服务端按活动时区创建当天三个任务快照,并幂等完成所有 `ENTER_PAGE` 任务。
- 返回 `activityId``statDate`、总积分、今日积分、日榜/总榜名次以及三个任务状态。
- 重复进入不会重复累计,也不会改变 `SEND_GIFT_GOLD` 任务进度。
### 3. 排行榜
`GET /activity/gift-challenge/aslan/ranking?activityId={id}&period={DAILY|OVERALL}&statDate={yyyy-MM-dd}&limit=100`
- `period` 缺省为 `DAILY`
- `statDate` 只对 `DAILY` 生效;缺省时自动选择活动窗口内的当前、首日或末日。
- `limit` 最终受活动 `displayTopN` 和服务端最大值 500 双重限制。
- 返回 `entries``my``settled`排序固定为积分降序、达到当前积分时间升序、userId 升序。
- 神秘人能力用户不出现在其他用户看到的公开榜单中,但本人仍可看到自己的排名。
### 4. 领取每日任务奖励
`POST /activity/gift-challenge/aslan/tasks/{taskCode}/claim`
```json
{
"activityId": "1234567890123456789",
"requestId": "h5-generated-request-id"
}
```
- 任务必须属于当前活动日并且已完成。
- `taskCode` 只允许 `A-Z/a-z/0-9/_/-`,长度 1 到 64保证它可安全作为 URL 路径段。
- 活动日任务行和逐奖励项 delivery item 是幂等边界;重复请求不会重复发放成功项。
- 首次成功抢占领取状态的 `requestId` 会写入任务日快照作为审计号;它不替代服务端任务行
和 delivery item 的发奖幂等边界。
- 发奖结果不确定时任务进入 `UNKNOWN`H5 不会自动重发,需运营在后台核账。
- 返回最新的完整用户状态。
## WebConsole 接口
| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/activity/gift-challenge/list` | 活动列表 |
| GET | `/activity/gift-challenge/detail/{id}` | 活动、任务、排名奖励详情 |
| POST | `/activity/gift-challenge/save` | 新增或按 version 乐观锁更新活动 |
| PUT | `/activity/gift-challenge/enable/{id}?enabled=true` | 启停活动 |
| GET/PUT | `/activity/gift-challenge/tasks/{id}` | 查询或保存恰好三个任务槽 |
| GET/PUT | `/activity/gift-challenge/rank-rewards/{id}` | 查询或保存日榜/总榜奖励区间 |
| GET | `/activity/gift-challenge/ranking/{id}` | 查询实时或冻结榜单 |
| GET | `/activity/gift-challenge/settlement-records/{id}` | 查询结算及逐项发奖状态 |
| POST | `/activity/gift-challenge/settlement/{id}` | 手动执行到期 DAILY/OVERALL 结算period 必填DAILY 还必须传 statDate |
| POST | `/activity/gift-challenge/delivery-item/resolve/{itemId}` | 核账确认 UNKNOWN 已到账或未到账 |
任务配置必须恰好三条:一条 `ENTER_PAGE` 和两条 `SEND_GIFT_GOLD`;两档送礼任务可分别
配置金币门槛和奖励,并且金币门槛必须按 `sortOrder` 严格递增。活动启用前必须同时配置 DAILY 和 OVERALL 奖励,
同一周期排名区间不得重叠。启用后的 H5 奖励展示、每日任务发奖和榜单结算发奖均只读取
该活动自己的冻结快照;共享资源组之后改名、改奖励或下架都不会改变本期用户所得。
## 礼物事件与发奖
活动使用独立 consumer group `ASLAN_GIFT_CHALLENGE_GIFT` 直接订阅原始
`GiveGiftSink.TAG`,与主礼物消费者形成 RocketMQ fan-out不依赖主消费者完成 Mongo
落库后再派生消息。对于 broker 已接收的消息,本 consumer 依靠 RocketMQ 重投和业务
唯一键实现 at-least-once原 tag 发送失败沿用既有 `GiftMqRetryTask` 全局补偿,活动内
不再新增第二套 retry tag。活动服务会再次校验完整资格并通过
`(activity_id, source_event_track_id)` 唯一键保证 RocketMQ 重投不会重复加分。
本活动不新增 IM 消息。奖励复用活动资源组发送器;启用时先形成活动级不可变奖励快照,
实际领取和结算再把快照中的每个资源配置物化为独立 delivery item 并抢占。超时或
进程中断统一转为 `UNKNOWN`,避免在下游到账结果不明时盲目重发。系统不设普通失败
重试分支;运营核账确认未到账后,该单项才会回到 `PENDING` 并补发。排行榜冻结与奖励
物化分属两个提交事务:门闩和获奖 parent 先提交,奖励项物化或发送短暂失败只会让
parent 保持 `PENDING`、周期保持 `PROCESSING`;调度器会从活动快照幂等物化并继续发放,
不会读取已经变化的共享资源组,也不会把已经冻结的榜单重新开放。