bindbox-game/.trae/documents/头衔系统与抽奖增益设计方案.md
邹方成 8141a47690
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
feat(称号系统): 新增称号管理功能与抽奖效果集成
- 新增系统称号模板与效果配置表及相关CRUD接口
- 实现用户称号分配与抽奖效果应用逻辑
- 优化抽奖接口支持用户ID参数以应用称号效果
- 新增称号管理前端页面与分配功能
- 修复Windows时区错误与JSON字段初始化问题
- 移除无用管理接口代码并更新文档说明
2025-11-16 11:37:40 +08:00

82 lines
3.8 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.

# 头衔加概率与折扣的可验证设计
## 结论
* 采用“权重修饰”的方式为持有头衔的用户提升抽奖概率。
* 哈希算法HMAC-SHA256 随机熵)保持不变;只扩展承诺与收据的字段以固化规则与有效权重,保证可验证性与不可篡改。
## 必要扩展
* 承诺扩展IssueRandomCommitment
* 新增 `AlgoRulesHash`:对“权重修饰规则(由头衔配置确定的纯函数)”做哈希并随期承诺固化。服务端在抽取前不能更改规则。
* 收据扩展Receipt
* 新增 `UserId`:明确本次抽取的用户。
* 新增 `WeightsTotalEffective`:按用户头衔修饰后的总权重,用于位置采样与第三方复核。
* 新增 `UserWeightFactorsRoot`:以 `reward_id -> factor` 做 Merkle 根,第三方可据此对 `Items(snapshot)` 重建有效权重。
* 编码消息扩展(不改算法,仅改输入)
* 仍使用 `HMAC(serverSubSeed, encodeMessage(...))``encodeMessage` 增加 `UserId``WeightsTotalEffective` 字段(保持确定性)。
## 规则与确定性
* 规则来源头衔模板配置百分比或加点以及叠加策略none|max|multiply
* 纯函数:`factor = F(user_titles, reward_id)`,只依赖用户持有的头衔与静态规则;不依赖随机数或服务端临时状态。
* 可复核:第三方得到 `ItemsRoot``AlgoRulesHash``UserWeightFactorsRoot``UserId` 与收据内快照,即可重建每个 `reward_id` 的有效权重与 `WeightsTotalEffective`,据同样的消息编码与哈希熵验证 `SelectedIndex`
## 核心流程(抽奖不变,仅插入修饰步骤)
1. 读取承诺:`GetIssueRandomCommit(...)``internal/service/activity/random_commit.go:99`)。
2. 载入奖励池快照:同现有实现(`internal/service/activity/draw_execute.go:21-35`)。
3. 计算用户权重修饰:`effective_weight[i] = base_weight[i] * factor(user, reward_id[i])`;汇总 `WeightsTotalEffective`
4. 使用 HMAC-SHA256 生成熵(算法不变),对 `encodeMessage(..., UserId, WeightsTotalEffective)` 取样位点。
5. 按有效权重的累加区间选中 `SelectedIndex/SelectedItemId`
6. 返回收据,并包含 `UserWeightFactorsRoot` 与证明材料。
## 折扣集成(独立不影响随机)
* 抽奖订单创建(新增):以活动门票价 `PriceDraw``internal/repository/mysql/model/activities.gen.go:22`)为基价。
* 头衔折扣:按叠加策略计算 `discount_amount`,落到订单字段 `DiscountAmount/ActualAmount``internal/repository/mysql/model/orders.gen.go:22`)。
* 与优惠券/积分叠加:默认“优惠券优先 + 头衔折上折”,可通过 `stack_policy` 切到“取最大”。
## 接口与服务
* 管理端:头衔模板 CRUD + 发放;配置权重修饰参数与叠加策略。
* APP
* 抽奖订单创建接口(新):返回计算后的金额。
* 抽奖接口:保持路径不变(`internal/api/activity/draw_app.go:28`),服务内执行权重修饰。
* 模拟与校验:
* 模拟接口增加 `user_id`,输出期望概率与观测分布。
* 校验接口以收据扩展字段重建有效权重,验证 `SelectedIndex`
## 验收标准
* 头衔发放后,持有用户的抽奖订单能正确展示并结算折扣。
* 抽奖收据包含新增字段,第三方使用承诺与收据可重放选中过程;不持有头衔的用户与持有者的分布差异符合规则。
* 哈希熵算法未变,安全与不可预测性不受影响。
## 说明:关于“加概率是否影响哈希算法”
* 不影响哈希算法本身(仍是 HMAC-SHA256
* 影响的是“采样空间”——由原始 `weights_total` 改为 `WeightsTotalEffective`,并且将该值与用户标识作为消息输入的一部分来固定采样过程;承诺和收据的扩展确保服务端无法事后调参。