bindbox-game/docs/称号系统/说明文档.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

12 KiB
Raw Blame History

称号系统使用说明文档

版本v1.0
日期2025-11-16
适用范围:运营、后端、前端


一、项目规划

  • 业务目标:实现“用户抽奖后获得双倍奖励(可限时)”的称号能力,运营可视化配置,后端安全可控,前端可观测。
  • 范围:系统称号主数据、称号效果配置(双倍概率)、用户称号分配与时效管理、抽奖流程双倍应用。
  • 时间节点:
    • 2025-11-16建立说明文档完成创建流程与使用指南。
    • 2025-11-17完成抽奖流程集成验证与用例测试预期

二、实施方案

2.1 核心模型

  • SystemTitles称号主数据名称、描述、获取规则、适用范围
  • SystemTitleEffects称号效果类型、参数、叠加策略、封顶值、排序、状态
  • UserTitles用户称号记录生效状态、获得时间、过期时间、来源、备注
  • 参考文件:
    • internal/repository/mysql/model/system_titles.gen.go
    • internal/repository/mysql/model/system_title_effects.gen.go
    • internal/repository/mysql/model/user_titles.gen.go

2.2 现有预置效果

  • 已内置6类效果含“双倍之王EffectType=6”。
  • 参考internal/api/admin/titles_seed.go:18-37

2.3 后端接口

  • 系统称号(管理员):
    • GET/POST/PUT/DELETE /api/admin/system_titles
    • GET/POST/PUT/DELETE /api/admin/system_titles/:title_id/effects
  • 用户称号分配(管理员):
    • POST /api/admin/users/:user_id/titles
  • 路由参考internal/router/router.go
  • 控制器参考internal/api/admin/titles_admin.go

三、创建流程(运营页面)

3.1 进入页面

  • 管理端路径:/operations/titles
  • 若菜单缺失,可调用 EnsureTitlesMenu参考 internal/api/admin/titles_seed.go

3.2 创建称号

  • 基本信息:
    • 名称:例如“抽奖双倍达人”
    • 描述例如“抽奖奖励翻倍限时24小时”
    • 状态:启用
  • 获取规则ObtainRulesJSON建议
{
  "methods": ["lottery"],
  "conditions": {"lottery_type": "normal"}
}
  • 适用范围ScopesJSON可为空或限定具体用户等级/品类/区域/时段。

3.3 添加效果(双倍概率)

  • 选择效果类型EffectType=6双倍概率
  • 参数示例对所有奖品100%双倍周期最多1次
{
  "target_prize_ids": [],
  "chance_x1000": 1000,
  "period_cap_times": 1
}
  • 叠加与封顶:按需设置 StackingStrategyCapValueX1000,用于限制叠加与封顶行为。

3.4 保存与检查

  • 保存称号与效果后,在列表中确认显示;可进入“效果管理”查看参数是否正确。

四、分配与时效

4.1 运营手动分配

  • 在称号列表中点击“分配用户”:
    • 有效期类型:permanent(永久)、period(开始/结束时间)、days(按天数)
    • 建议设置:days=124小时有效
    • 备注:例如“抽奖获得双倍称号”
    • 可选:覆盖现有相同称号、发送通知

4.2 抽奖后自动分配(后端集成)

  • 在抽奖成功后调用用户称号分配接口或服务方法:
    • 若用户未持有称号 → 写入 UserTitles设定 expires_at(例如当前时间+24小时
    • 若已持有且未过期 → 按策略决定是否延长或保持(可由业务规则决定)

五、抽奖流程应用双倍效果

5.1 判定逻辑

  1. 读取用户激活且未过期的 UserTitles。
  2. 聚合其中类型为 EffectType=6 的 SystemTitleEffects。
  3. chance_x1000(概率)与 period_cap_times(周期次数)判定是否触发。
  4. 若触发:将奖品数量或价值翻倍(对指定 target_prize_ids 生效或全部奖品)。
  5. 记录当期触发次数,避免超过 period_cap_times

5.2 参数含义

  • target_prize_ids限定生效的奖品ID集合空数组表示对所有奖品生效。
  • chance_x1000千分制概率1000=100%、200=20%。
  • period_cap_times:周期内最多触发次数(建议结合自然日或活动期定义周期)。

六、配置示例集

6.1 获取规则(抽奖获得)

{
  "methods": ["lottery"],
  "conditions": {"lottery_type": "normal"}
}

6.2 双倍效果100%/限1次

{
  "target_prize_ids": [],
  "chance_x1000": 1000,
  "period_cap_times": 1
}

6.3 用户分配有效期(按天)

{
  "expire_type": "days",
  "days": 1,
  "remark": "抽奖获得双倍称号",
  "override_existing": true,
  "send_notification": true
}

七、测试与验收

7.1 管理端用例

  • 创建称号与效果 → 列表校验
  • 为测试用户分配days=1→ 显示生效与过期时间

7.2 抽奖用例

  • 用户持有称号时抽奖 → 奖励翻倍,次数受 period_cap_times 控制
  • 称号过期后抽奖 → 不再翻倍

7.3 数据核查

  • 检查 UserTitlesactive/expires_at/remark
  • 检查效果:SystemTitleEffects.params_json 是否符合配置

7.4 验收标准

  • 正常流程:在有效期内至少一次成功翻倍
  • 边界:过期后不生效;超过 period_cap_times 不再触发
  • 失败路径:接口异常可回滚或重试,日志可追踪

八、进度记录

  • 2025-11-16建立说明文档完成创建流程、分配与时效、抽奖双倍应用、配置示例与验收标准。
  • 2025-11-17计划完成抽奖流程集成代码的验证与单元测试。

九、常见问题

  • Q为什么双倍没有触发
    • A检查有效期是否过期确认 chance_x1000 是否为期望值;校验 period_cap_times 是否已用尽;确认奖品是否在 target_prize_ids 范围内。
  • Q如何限制只对特定奖品翻倍
    • A在效果参数中填入 target_prize_ids 指定的奖品ID数组。
  • Q如何延长用户称号有效期
    • A重新分配该称号并设置新的有效期覆盖现有

十、后续工作

  • 如需我在抽奖服务中添加自动分配与双倍应用的具体代码,请告知周期定义(按自然日/活动期)与触发记录存储位置,我将补充实现与测试用例并更新本说明文档进度。

十一、字段级详解与代码绑定点

11.1 获得规则ObtainRulesJSON

  • 字段结构:
    • methods: string[] 获得方式集合(如 register/consume/invite/activity/manual/lottery
    • conditions: object 按不同方式的约束条件(示例键:lottery_type, min_amount, time_range, participate_times 等)
  • 用途说明:当前后端仅进行“存取”,尚未在服务层解析并自动授予头衔;需后续集成到具体事件(抽奖、消费、邀请等)的规则评估器。
  • 代码绑定:
    • 创建时写入默认空对象:internal/api/admin/titles_admin.go:88
    • 创建落库:internal/api/admin/titles_admin.go:94-96
    • 修改时更新:internal/api/admin/titles_admin.go:125
    • 预置种子:internal/api/admin/titles_seed.go:54
    • DAO 字段映射:internal/repository/mysql/dao/system_titles.gen.go:34, 53, 77, 102
  • 前端规则助手来源:
    • 载入与保存:web/admin/src/views/operations/titles/components/RuleConfigDialog.vue:331-393, 395-450
    • JSON 预览构造:web/admin/src/views/operations/titles/components/RuleConfigDialog.vue:283-322
  • 示例配置:
{
  "methods": ["lottery"],
  "conditions": {"lottery_type": "normal", "participate_times": 1}
}

(说明:目前该 JSON 仅随标题存储,不会自动触发授予;若需要自动授予,需新增服务层解析器与事件钩子。)

11.2 使用范围ScopesJSON

  • 标题层SystemTitles.ScopesJSON
    • 用途:目前仅存取,并未在运行时判定中直接使用。
    • 创建写入:internal/api/admin/titles_admin.go:89, 95-96
    • 修改更新:internal/api/admin/titles_admin.go:126
  • 效果层SystemTitleEffects.ScopesJSON
    • 用途:运行时用于过滤效果的生效范围(活动/期/分类等),排除优先,包含其次,未配置则视为全局。
    • 解析结构:internal/service/title/effects_resolver.go:60-69
      • activity_ids, issue_ids, category_ids
      • exclude.activity_ids, exclude.issue_ids, exclude.category_ids
    • 匹配逻辑:internal/service/title/effects_resolver.go:133-155
    • 抽奖期过滤(简化版,仅按 issueinternal/service/activity/draw_with_effects.go:85-103
    • 管理端写入:internal/api/admin/titles_admin.go:196-206, 251
  • 示例配置:
{
  "activity_ids": [1001, 1002],
  "issue_ids": [2001],
  "category_ids": [],
  "exclude": { "issue_ids": [2003] }
}

(说明:当事件上下文命中 exclude 列表则不生效;若配置了包含列表且不命中则不生效;都未配置视为全局。)

11.3 效果数量与叠加策略StackingStrategy/CapValueX1000

  • 多效果:一个称号可挂载多个效果,列表接口返回总数(internal/api/admin/titles_admin.go:156-170sort 控制同内顺序,status 控制启用。
  • 叠加策略(SystemTitleEffects.StackingStrategyinternal/repository/mysql/model/system_title_effects.gen.go:19
    • 0 最大值max_only取每个目标的最大增益
    • 1 累加封顶sum_with_cap叠加并用 cap 限制
    • 2 首个匹配first_match只在当前为 0 时赋值
    • 默认:累加并使用 CapValueX1000 统一封顶
  • 统一封顶(SystemTitleEffects.CapValueX1000):千分比封顶值,用于限制概率/倍数累积的上限。
  • 抽奖应用点:internal/service/activity/draw_with_effects.go:104-149, 152-166, 197-233
    • effect_type=5 概率加成:解析 target_prize_ids/boost_x1000/cap_x1000 后调整权重
    • effect_type=6 双倍奖励:合并 target_prize_idschance_x1000 后概率判定,命中则倍数 x2

11.4 规则助手(前端可视化配置)

  • 入口位置:web/admin/src/views/operations/titles/components/RuleConfigDialog.vue
  • 获得规则 UI → JSON 映射:methods/consume/invite/activityRuleConfigDialog.vue:225-242, 283-297
  • 使用范围 UI → JSON 映射:user_level/category_ids/region/timeRuleConfigDialog.vue:245-257, 298-318
  • 加载现有规则:RuleConfigDialog.vue:331-393
  • 保存规则:RuleConfigDialog.vue:395-450
  • 注意事项:
    • 效果编辑表单与后端字段对齐effect_type=5/6
      • 5概率加成后端期望target_prize_ids, boost_x1000, cap_x1000internal/service/activity/draw_with_effects.go:104-133
      • 6双倍奖励后端期望target_prize_ids, chance_x1000, period_cap_timesinternal/service/activity/draw_with_effects.go:133-149
      • 当前前端默认参数返回与后端不一致:web/admin/src/views/operations/titles/components/EffectEditDialog.vue:244-261
      • 建议在运营使用时,按后端字段结构填写 params_json,或由后续改造对齐表单字段;本文档已标注对齐需求,待前端改造确认后更新。

十二、字段参考速查表

  • ObtainRulesJSON

    • methods: string[](注册/消费/邀请/活动/抽奖/手动)
    • conditions: object按场景扩展键lottery_type/min_amount/time_range/participate_times 等)
    • 绑定点:创建/修改/预置/DAO 映射(见 11.1
  • ScopesJSON效果层

    • activity_ids/issue_ids/category_ids: number[]
    • exclude.activity_ids/issue_ids/category_ids: number[]
    • 绑定点:解析/匹配/抽奖过滤/写入(见 11.2
  • SystemTitleEffects效果通用

    • effect_type: 1~6见模型注释
    • params_json: 按效果类型字段定义
    • stacking_strategy: 0/1/2/默认
    • cap_value_x1000: 千分封顶
    • sort/status: 顺序与启用
    • 绑定点:创建/修改/抽奖应用(见 11.3