# Yumi 礼物挑战接口 Yumi 的 Java `sysOrigin` 固定为 `LIKEI`。网关外部地址在以下路径前加 `/go`;Go 服务内部路径不加。所有 Snowflake ID 都使用十进制字符串,积分/任务金额使用精确两位小数字符串(如 `"100.50"`)。统一响应业务数据位于 `body`/`data`。 ## H5 用户接口 鉴权:`Authorization: Bearer `。 | 方法 | 地址 | 参数 | 主要返回 | |---|---|---|---| | 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` | 活动启用时会校验奖励组已上架且属于 LIKEI,并冻结完整奖励项。活动开始后仅允许通过 `/save` 修改名称和描述,其他统计/奖励口径只读。 日榜、总榜结算延迟均允许 `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 接口刷新任务和排行榜。