yumi-golang/docs/yumi_gift_challenge_api.md

63 lines
5.7 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.

# Yumi 礼物挑战接口
Yumi 的 Java `sysOrigin` 固定为 `LIKEI`。网关外部地址在以下路径前加 `/go`Go 服务内部路径不加。所有 Snowflake ID 都使用十进制字符串,积分/任务金额使用精确两位小数字符串(如 `"100.50"`)。统一响应业务数据位于 `body`/`data`
## H5 用户接口
鉴权:`Authorization: Bearer <app token>`
| 方法 | 地址 | 参数 | 主要返回 |
|---|---|---|---|
| GET | `/app/h5/gift-challenge/yumi/detail` | query `activityId` 可选 | `activity`、固定三任务 `tasks`、日/总榜奖励 `rankRewards` |
| POST | `/app/h5/gift-challenge/yumi/enter` | JSON `{ "activityId": "..." }` | 当日 `totalScore``dailyScore`、名次和任务状态;幂等完成进入页面任务 |
| GET | `/app/h5/gift-challenge/yumi/ranking` | query `activityId` 可选、`periodType=DAILY\|OVERALL`、DAILY 可传 `statDate=yyyy-MM-dd``limit`(默认/最大 30 | 原始 Top N 过滤神秘人后的 `entries`、本人真实 `my``settled` |
| POST | `/app/h5/gift-challenge/yumi/tasks/:taskCode/claim` | JSON `{ "activityId": "...", "requestId": "..." }` | 更新后的当日用户状态;`requestId` 最长 128 |
只有 `GOLD`、非背包、非 `LUCKY_GIFT`/`MAGIC` 的普通礼物计分。积分按 `giftCandy × quantity × 去重有效收礼人数` 精确计算,支持最多两位小数。
## Webconsole 接口
鉴权Console `Authorization`。所有 GET 还要求页面菜单 `ResidentYumiGiftChallenge`;写操作分别校验按钮权限。
基础地址:`/resident-activity/yumi-gift-challenge`
| 方法 | 地址 | 参数/返回 | 权限 |
|---|---|---|---|
| GET | `/list` | query `sysOrigin=LIKEI&page&size`,返回 `{records,total,current,size}` | 页面菜单 |
| GET | `/detail/:id` | 完整活动、任务、奖励 | 页面菜单 |
| GET | `/tasks/:id` | 返回任务数组 | 页面菜单 |
| GET | `/rank-rewards/:id` | 返回日榜/总榜奖励数组 | 页面菜单 |
| GET | `/ranking/:id` | query `periodType,statDate,limit` | 页面菜单 |
| GET | `/settlement-records/:id` | query `periodType,statDate,deliveryStatus,page,size` | 页面菜单 |
| POST | `/save` | 完整活动 JSON新活动固定 3 个启用任务,榜奖区间可配置 | `resident-activity:yumi-gift-challenge:edit` |
| PUT | `/enable/:id` | query `enabled=true\|false` | `resident-activity:yumi-gift-challenge:enable` |
| PUT | `/tasks/:id` | JSON `{ "activityId":"...", "tasks":[...] }` | `...:edit` |
| PUT | `/rank-rewards/:id` | JSON `{ "activityId":"...", "rankRewards":[...] }` | `...:edit` |
| POST | `/settlement/:id` | JSON `{ "periodType":"DAILY\|OVERALL", "statDate":"yyyy-MM-dd" }`OVERALL 不传日期 | `...:settle` |
| POST | `/delivery-item/resolve/:itemId` | JSON `{ "delivered": true\|false }`;仅人工核账 UNKNOWN | `...:reconcile` |
新建并启用活动、或重新启用已停用活动时,只要求 `endTime` 晚于服务端当前时间;`startTime` 已经过期但活动尚未结束时仍可中途启用。服务端把本次实际启用时间写入 `enabled_time`,只接收事件时间不早于该时刻的礼物,因此不会补算启用前的历史消息。同时校验奖励组已上架且属于 LIKEI并冻结完整奖励项。活动即使已经进入时间窗只要 `overallSettlementStatus=NOT_STARTED`,仍可通过 `/save``/tasks/:id``/rank-rewards/:id` 修改完整配置。只有总榜结算进入 `PROCESSING/COMPLETED/RECONCILIATION_REQUIRED` 后,才仅允许修改活动名称和说明。
进行中编辑按提交时点向后生效,不回算已经入账的积分。已物化的用户日任务、已冻结日榜、榜奖 parent 和 delivery item 保留原目标及奖励;尚未物化的用户/日期和未冻结榜奖使用新配置。旧任务或榜奖引用的资源组快照始终保留;同一已引用资源组不会刷新,若要更换奖励内容应选择新的资源组。修改时间窗或时区后,事件事务会在活动共享锁内重新读取窗口和时区;已产生数据的历史日期门闩保留,其余 `NOT_STARTED` 门闩按新配置重建。
日榜、总榜结算延迟均允许 `0-1440` 分钟,且 `overallSettlementDelayMinutes` 必须大于或等于 `dailySettlementDelayMinutes`,保证最终日榜不会晚于总榜关门。
## chatapp-cron 触发
`POST /internal/yumi-gift-challenge/settle-due?batch=20`
- 鉴权头:`X-Internal-Token`,值与 `CHATAPP_HTTP_INTERNAL_CALLBACK_SECRET` 一致。
- Go 服务或 cron 任一侧未配置该密钥时均 fail-closed不发送/不执行结算请求。
- 单轮最多处理 `batch` 个到期 `NOT_STARTED/PROCESSING` 日榜或总榜,并各恢复最多 `batch` 个任务/榜奖 owner`batch` 默认 20、最大 100。
- 返回 `periodsScanned``periodsFrozen``taskOwnersScanned``settlementOwnersScanned``ownersProcessed``failedKeys`
- HTTP 200 仍可能表示部分 owner 已成功、部分待恢复cron 会把非空 `failedKeys` 提升为失败告警,下轮依靠数据库状态幂等续跑。
- 该端点可重复、可多实例并发调用;周期门闩、业务唯一键和逐奖励项 trackId 保证幂等。过租期 `PROCESSING` 会保守转为 `UNKNOWN`,不会自动盲目补发。
建议 chatapp-cron 每 10 秒至 1 分钟触发一次,单次 HTTP 超时至少覆盖每项 30 秒的下游上限和配置的 batch。
## RocketMQ 与 IM
- 独立消费组:`YUMI_GIFT_CHALLENGE_GIFT`
- 默认 topic/tag`RC_DEFAULT_APP_ORDINARY` / `give_gift_v3`
- 环境变量前缀:`CHATAPP_YUMI_GIFT_CHALLENGE_ROCKETMQ_*`;缺少 endpoint/密钥时消费者不会伪造凭证启动。
- 本活动没有新增 IM 消息、房间广播或客户端 IM 协议H5 通过上述 HTTP 接口刷新任务和排行榜。