bindbox-game/.trae/documents/抽奖接口通用化与策略化设计.md
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

69 lines
4.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.

## 现状与问题
- 当前 APP 抽奖接口:`POST /api/app/activities/:activity_id/issues/:issue_id/draw`,处理函数 `internal/api/activity/draw_app.go:27-46`,服务侧使用 `internal/service/activity/draw_execute.go:12-89` 的可验证随机抽样HMAC-SHA256 + 拒绝采样)。
- 现有实现按期issue维度抽取奖励已具备收据与随机性证明但不同活动类型分类/玩法)未来可能有差异化前置校验、选择规则与奖励发放流程。
- 需求:我们将有很多活动,接口到底通用还是分活动?
## 结论选择
- 接口保持通用(单一端点),后端采用策略模式按活动类别/配置差异化实现逻辑。这样:
- 前端保持统一调用与响应结构,降低复杂度与版本碎片。
- 后端可插拔扩展不同活动的校验、选择、奖励发放与效果管道,避免复制粘贴与接口膨胀。
- 与现有 `Receipt` 结构兼容,保留可验证性。
## 技术方案
- 保留通用端点:`POST /api/app/activities/:activity_id/issues/:issue_id/draw`
- 引入“活动策略”接口(示例命名):
- `ActivityDrawStrategy`
- `PreChecks(ctx, activity, issue, user) error`(余额/订单/库存/状态/时间窗/限频)
- `SelectItem(ctx, issue, baseSelector) (selectedRewardID, proof)`(可复用当前 HMAC 随机选择器作为 `baseSelector`,策略可注入权重或过滤规则)
- `GrantReward(ctx, user, rewardID) error`(扣减数量、落库收据/日志、发放道具/实物/积分/券)
- `PostEffects(ctx, user, activity, issue, rewardID)`(道具效果、称号、积分等联动)
- 策略注册与路由:
- 基于 `activity.activity_category_id` 或活动配置选择策略;默认策略沿用当前实现(完全兼容)。
- 效果管道:
- 抽奖前置/后置效果处理如限时加权、Boss 限制、用户卡片效果),设计为中间件式管道,便于组合。
- 并发与一致性:
- 引入期级别乐观扣减或分布式锁(后续落地),确保高并发下数量与日志一致。
- 支持 `X-Idempotency-Key` 防重(后续扩展),避免重复下单/重复抽取。
- 监控与审计:
- 统一埋点:抽奖尝试、成功、失败原因、库存变化、用户画像。
- 审计日志与追踪 ID 与收据关联。
## API 契约
- 请求:保持不变;可新增可选头 `X-Idempotency-Key`
- 响应:保持 `receipt` 字段结构;策略仅影响内部选择/发放过程,不破坏契约。
- 错误码:标准化前置校验失败(余额不足、活动未开始、库存不足、限频)与系统错误。
## 数据与规则
- 数量规则:`original_qty` 为期初总数,`quantity` 当前剩余;不限量为 `-1`,选择与发放逻辑需正确处理。
- 收据:继续包含随机性证明与所选项快照,具备可验证性。
- 扣减与发放:在 `GrantReward` 中统一实现(现阶段代码只返回收据,发放与扣减建议纳入策略实现)。
## 变更范围
1. 新增 `internal/service/activity/strategy/` 策略接口与默认实现;注册表按分类 ID 选择策略。
2.`ExecuteDraw()` 增强:
- 解析活动与用户上下文,调用策略 `PreChecks``SelectItem``GrantReward``PostEffects`
- 默认策略复用当前 `draw_execute.go` 的随机选择器。
3. `draw_app.go` 维持统一端点,增加对用户上下文的传递(如需要),契约不变。
## 分阶段实施
1. 引入策略接口与默认策略(不改变行为)。
2. 接入活动类别路由与注册(读取 `ActivityCategoryID`)。
3. 将扣减与发放迁移到策略中,补充事务与并发控制。
4. 增强效果管道,接入道具卡、称号、积分的已有模块。
5. 增加监控与限频、幂等,完善错误码。
6. 编写单元测试与集成测试:
- 权重选择正确性与拒绝采样无偏。
- 不限量与零库存边界。
- 并发扣减一致性。
- 幂等与限频。
## 验收标准
- 单一抽奖端点适配 2+ 类活动策略,无需前端切换接口。
- 收据结构与随机性证明保持一致,验证脚本通过。
- 库存扣减与奖励发放在并发下无不一致;关键路径有审计日志。
- 测试覆盖关键流程与边界条件。
## 后续扩展
- 按活动类型开放“策略配置”与“玩法参数”在管理端,可动态调整权重、效果、限频。
- 如某玩法确有完全不同交互(例如合成/多次抽/队列结算),再考虑单独端点,但仍优先在通用端点层面通过参数与策略实现。