Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
- 新增系统称号模板与效果配置表及相关CRUD接口 - 实现用户称号分配与抽奖效果应用逻辑 - 优化抽奖接口支持用户ID参数以应用称号效果 - 新增称号管理前端页面与分配功能 - 修复Windows时区错误与JSON字段初始化问题 - 移除无用管理接口代码并更新文档说明
12 KiB
12 KiB
称号系统使用说明文档
版本: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
- GET/POST/PUT/DELETE
- 用户称号分配(管理员):
- POST
/api/admin/users/:user_id/titles
- POST
- 路由参考: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
}
- 叠加与封顶:按需设置
StackingStrategy与CapValueX1000,用于限制叠加与封顶行为。
3.4 保存与检查
- 保存称号与效果后,在列表中确认显示;可进入“效果管理”查看参数是否正确。
四、分配与时效
4.1 运营手动分配
- 在称号列表中点击“分配用户”:
- 有效期类型:
permanent(永久)、period(开始/结束时间)、days(按天数) - 建议设置:
days=1(24小时有效) - 备注:例如“抽奖获得双倍称号”
- 可选:覆盖现有相同称号、发送通知
- 有效期类型:
4.2 抽奖后自动分配(后端集成)
- 在抽奖成功后调用用户称号分配接口或服务方法:
- 若用户未持有称号 → 写入 UserTitles,设定
expires_at(例如当前时间+24小时) - 若已持有且未过期 → 按策略决定是否延长或保持(可由业务规则决定)
- 若用户未持有称号 → 写入 UserTitles,设定
五、抽奖流程应用双倍效果
5.1 判定逻辑
- 读取用户激活且未过期的 UserTitles。
- 聚合其中类型为 EffectType=6 的 SystemTitleEffects。
- 按
chance_x1000(概率)与period_cap_times(周期次数)判定是否触发。 - 若触发:将奖品数量或价值翻倍(对指定
target_prize_ids生效或全部奖品)。 - 记录当期触发次数,避免超过
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 数据核查
- 检查 UserTitles:
active/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范围内。
- A:检查有效期是否过期;确认
- Q:如何限制只对特定奖品翻倍?
- A:在效果参数中填入
target_prize_ids指定的奖品ID数组。
- A:在效果参数中填入
- 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-69activity_ids,issue_ids,category_idsexclude.activity_ids,exclude.issue_ids,exclude.category_ids
- 匹配逻辑:
internal/service/title/effects_resolver.go:133-155 - 抽奖期过滤(简化版,仅按 issue):
internal/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-170),sort控制同内顺序,status控制启用。 - 叠加策略(
SystemTitleEffects.StackingStrategy):internal/repository/mysql/model/system_title_effects.gen.go:190最大值(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-233effect_type=5概率加成:解析target_prize_ids/boost_x1000/cap_x1000后调整权重effect_type=6双倍奖励:合并target_prize_ids与chance_x1000后概率判定,命中则倍数x2
11.4 规则助手(前端可视化配置)
- 入口位置:
web/admin/src/views/operations/titles/components/RuleConfigDialog.vue - 获得规则 UI → JSON 映射:
methods/consume/invite/activity(RuleConfigDialog.vue:225-242, 283-297) - 使用范围 UI → JSON 映射:
user_level/category_ids/region/time(RuleConfigDialog.vue:245-257, 298-318) - 加载现有规则:
RuleConfigDialog.vue:331-393 - 保存规则:
RuleConfigDialog.vue:395-450 - 注意事项:
- 效果编辑表单与后端字段对齐(effect_type=5/6):
- 5(概率加成)后端期望:
target_prize_ids, boost_x1000, cap_x1000(internal/service/activity/draw_with_effects.go:104-133) - 6(双倍奖励)后端期望:
target_prize_ids, chance_x1000, period_cap_times(internal/service/activity/draw_with_effects.go:133-149) - 当前前端默认参数返回与后端不一致:
web/admin/src/views/operations/titles/components/EffectEditDialog.vue:244-261 - 建议在运营使用时,按后端字段结构填写
params_json,或由后续改造对齐表单字段;本文档已标注对齐需求,待前端改造确认后更新。
- 5(概率加成)后端期望:
- 效果编辑表单与后端字段对齐(effect_type=5/6):
十二、字段参考速查表
-
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)