7.6 KiB
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 个奖励项。总榜结算开始前,即使活动已经进入或走完时间窗,WebConsole 仍可修改 时间、时区、任务、榜单和奖励;新配置只影响之后的事件和尚未物化/冻结的数据。
- 已生成用户任务、已冻结日榜、榜奖 parent 和 delivery item 永不回写;这些记录引用的 奖励组快照始终保留。同一已引用资源组不会刷新,修改奖励内容必须选择新的资源组。
dailySettlementDelayMinutes与overallSettlementDelayMinutes是有界迟到窗口,不是无限 追溯。结算门闩开始后对应榜单不再接受迟到写入;执行自动或人工结算前必须监控ASLAN_GIFT_CHALLENGE_GIFTconsumer 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
{
"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
{
"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 奖励展示、每日任务发奖和榜单结算发奖均只读取
该活动自己的冻结快照;共享资源组之后改名、改奖励或下架都不会改变本期用户所得。
| 活动状态 | 核心配置 | 启停约束 |
|---|---|---|
未启用 + NOT_STARTED(包括旧开始时间已过) |
时间、任务、榜单和奖励全部可编辑 | 启用前必须改为未来开始时间 |
已启用 + NOT_STARTED(开始前、进行中或已过结束时间) |
全部可编辑 | 历史事实保留,新配置向后生效;已有业务事实后禁止停用 |
| 任意已进入结算的状态 | 仅活动名称和说明可编辑 | 核心配置始终锁定,不受时间字段影响 |
三个任务的 taskCode/taskType/sortOrder 固定为 daily_enter/ENTER_PAGE/1、
daily_gift_1/SEND_GIFT_GOLD/2、daily_gift_2/SEND_GIFT_GOLD/3;活动中仅可修改文案、
门槛和奖励组。修改时区或时间窗后,旧日期已完成但未成功发放的任务仍可通过原 taskCode
继续领取,旧日榜也以实际保留的 period header 为准继续查询和结算。
礼物事件与发奖
活动使用独立 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;调度器会从活动快照幂等物化并继续发放,
不会读取已经变化的共享资源组,也不会把已经冻结的榜单重新开放。