Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
- 新增系统称号模板与效果配置表及相关CRUD接口 - 实现用户称号分配与抽奖效果应用逻辑 - 优化抽奖接口支持用户ID参数以应用称号效果 - 新增称号管理前端页面与分配功能 - 修复Windows时区错误与JSON字段初始化问题 - 移除无用管理接口代码并更新文档说明
207 lines
7.1 KiB
Markdown
207 lines
7.1 KiB
Markdown
## 目标与范围
|
||
|
||
* 支持用户持有多个头衔,并在各类业务事件中正确生效与结算。
|
||
|
||
* 覆盖六类效果:领取优惠券、抽奖折扣、签到双倍积分、领取道具卡、概率加成、双倍奖励卡。
|
||
|
||
* 与既有四张表对齐:`system_titles`、`system_title_effects`、`user_titles`、`user_title_effect_claims`。
|
||
|
||
## 整体架构
|
||
|
||
* 配置层:运营通过`system_titles`与`system_title_effects`完成模板与效果配置。
|
||
|
||
* 持有层:`user_titles`记录用户持有与激活状态、有效期与来源。
|
||
|
||
* 事件引擎:在`SIGNIN`、`DRAW_PURCHASE`、`DRAW_EXECUTE`与`CLAIM`类接口中查询并结算效果。
|
||
|
||
* 防重限流:`user_title_effect_claims`按周期唯一键实现并发防重与频次限制。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[用户行为事件] --> B[查询激活头衔 user_titles]
|
||
B --> C[加载效果 system_title_effects]
|
||
C --> D{按scopes/effect_type过滤}
|
||
D --> E[叠加/上限策略计算]
|
||
E --> F[结算(积分/折扣/概率/发放)]
|
||
F --> G[必要时写 user_title_effect_claims]
|
||
```
|
||
|
||
## 效果模型与参数规范
|
||
|
||
* 统一字段:`effect_type`、`params_json`、`stacking_strategy`、`cap_value_x1000`、`scopes_json`、`status`。
|
||
|
||
* 固定小数:所有比例/倍数/折扣统一用`*_x1000`(例如 10% = 100,2倍 = 2000)。
|
||
|
||
* `params_json`建议结构:
|
||
|
||
* 领取优惠券(`COUPON_CLAIM`): `{template_id, frequency:{period:'day|week|month', times:int}, start_at?, end_at?}`
|
||
|
||
* 抽奖折扣(`DRAW_DISCOUNT`): `{discount_type:'percentage|fixed', value_x1000, min_price?, max_discount?}`
|
||
|
||
* 签到倍数(`SIGNIN_MULTIPLIER`): `{multiplier_x1000, daily_cap_points?}`
|
||
|
||
* 领取道具卡(`ITEM_CARD_CLAIM`): `{template_id, frequency:{period, times}}`
|
||
|
||
* 概率加成(`PROBABILITY_BOOST`): `{target_pool_ids?:[], target_prize_ids?:[], boost_x1000, combine:'sum|max', cap_x1000?}`
|
||
|
||
* 双倍奖励卡(`DOUBLE_REWARD`): `{chance_x1000, target_prize_ids?:[], period_cap_times?:int}`
|
||
|
||
## 叠加与上限策略
|
||
|
||
* `stacking_strategy`枚举:
|
||
|
||
* `none`:不叠加,取单一最高优先级或最大值。
|
||
|
||
* `sum_with_cap`:求和后受`cap_value_x1000`或业务cap约束。
|
||
|
||
* `max_only`:取最大项。
|
||
|
||
* `multiply_with_cap`:倍数相乘后再cap(适用于少数特殊配置)。
|
||
|
||
* `priority_order`:按`priority`字段逐项应用,遇到冲突按优先级覆盖。
|
||
|
||
* 推荐缺省:
|
||
|
||
* 抽奖折扣:`max_only`(防止过度优惠),可选`sum_with_cap`。
|
||
|
||
* 签到倍数:`sum_with_cap`(如多头衔加总倍数,上限控制)。
|
||
|
||
* 概率加成:`sum_with_cap`(保持可解释性与稳定性)。
|
||
|
||
* 领取型权益:同模板同周期`sum_with_cap`或`max_only`,按运营策略选择。
|
||
|
||
* 双倍奖励卡:多卡按`chance_x1000`合并使用`sum_with_cap`,并设`period_cap_times`。
|
||
|
||
## 作用域与生效判定
|
||
|
||
* `scopes_json`建议:`{activity_ids?:[], phase_ids?:[], category_ids?:[], exclude?:{...}}`。
|
||
|
||
* 判定顺序:事件上下文→按`activity/phase/category`过滤→`status=active`→用户头衔`active=1`且未过期→计算叠加与cap。
|
||
|
||
* 冲突处理:包含与排除并存时优先排除;多效果同类型按`stacking_strategy`解决。
|
||
|
||
## 事件结算流程
|
||
|
||
* 签到(`SIGNIN`):
|
||
|
||
* 载入`SIGNIN_MULTIPLIER`→合并倍数→应用上限→计算积分→落账。
|
||
|
||
* 抽奖购票(`DRAW_PURCHASE`):
|
||
|
||
* 载入`DRAW_DISCOUNT`→取最大或合并后cap→计算优惠→生成支付单。
|
||
|
||
* 抽奖执行(`DRAW_EXECUTE`):
|
||
|
||
* 载入`PROBABILITY_BOOST`→对目标池/奖品加权(总概率归一)→进行抽取→载入`DOUBLE_REWARD`测试加倍机会→如命中,倍增奖品数量/价值并校验当期可用次数。
|
||
|
||
* 领取(`COUPON_CLAIM`/`ITEM_CARD_CLAIM`):
|
||
|
||
* 解析`frequency.period`生成`period_key`(`YYYYMMDD|YYYYWW|YYYYMM`)→检查唯一键是否已存在→未存在则发放并写`user_title_effect_claims`;已存在直接返回已领取。
|
||
|
||
## 防重与限流实现
|
||
|
||
* 唯一键:`user_id + title_id + effect_type + target_template_id + period_key`。
|
||
|
||
* 并发:使用数据库唯一约束天然防重;接口层加幂等键`Idempotency-Key`进一步防抖。
|
||
|
||
* 频次:根据`frequency.times`控制当期可用次数;若需累计多效果,按`stacking_strategy`决定合并或取最大。
|
||
|
||
## 接口设计(示例)
|
||
|
||
* 头衔管理
|
||
|
||
* `POST /titles/assign`:分配或续期;参数:`user_id, title_id, obtained_at, expires_at, source`。
|
||
|
||
* `PATCH /titles/:user_id/:title_id/activate`:激活/停用。
|
||
|
||
* `GET /titles/user/:user_id?active=1`:查询用户激活头衔与效果摘要。
|
||
|
||
* 事件接口
|
||
|
||
* `POST /events/signin`:入参`user_id, context`;出参`points, applied_effects`。
|
||
|
||
* `POST /events/draw/purchase`:入参`user_id, base_price, context`;出参`final_price, discount_breakdown`。
|
||
|
||
* `POST /events/draw/execute`:入参`user_id, context`;出参`prize, boost_detail, double_reward_applied, audit_id`。
|
||
|
||
* `POST /claims/coupon`:入参`user_id, template_id, context`;出参`claimed, period_key, remaining_times`。
|
||
|
||
* `POST /claims/item-card`:入参同上。
|
||
|
||
* 诊断/审计
|
||
|
||
* `GET /effects/preview`:给定`user_id+context`预览本次将应用的合并效果,用于运营核对。
|
||
|
||
## 数据与索引建议
|
||
|
||
* 复用现有索引:
|
||
|
||
* `user_titles`: `idx_user_titles_user`。
|
||
|
||
* `system_title_effects`: `idx_title_effects_title` + 按`effect_type/status`过滤。
|
||
|
||
* `user_title_effect_claims`: 周期唯一索引。
|
||
|
||
* 读优化:
|
||
|
||
* 缓存`system_title_effects`(按`title_id`与`scopes_json`分片,TTL 5\~15 分钟)。
|
||
|
||
* 针对`DRAW_EXECUTE`的概率表做内存映射,命中后快速归一化计算。
|
||
|
||
## 风险与边界处理
|
||
|
||
* 浮点误差:统一`*_x1000`避免精度问题。
|
||
|
||
* 过度优惠/过度概率:必须设置`cap_value_x1000`或业务cap。
|
||
|
||
* 多模板冲突:同类型不同模板时采用`priority_order`或业务白名单优先级。
|
||
|
||
* 过期与停用:事件前统一校验有效期与`status`,过期/停用不生效。
|
||
|
||
* 诊断可视化:提供`preview`接口给运营验证,防误配置上线。
|
||
|
||
## 测试与验收标准
|
||
|
||
* 单元测试:
|
||
|
||
* 每类效果的合并逻辑与cap测试;周期键生成与唯一约束;概率加成归一化与双倍卡应用顺序。
|
||
|
||
* 并发/幂等:
|
||
|
||
* 高并发领取/购票/抽奖的防重与一致性测试。
|
||
|
||
* 集成测试:
|
||
|
||
* 端到端场景:
|
||
|
||
* 多头衔叠加签到倍数,限制生效。
|
||
|
||
* 两个折扣叠加取最大或cap限。
|
||
|
||
* 抽奖概率加成后命中率变更,双倍卡当期次数受限。
|
||
|
||
* 同模板每日领取限 1 次,多效果按策略合并。
|
||
|
||
* 验收标准:
|
||
|
||
* 用户可持有多个头衔并正确生效;
|
||
|
||
* 六类效果在对应事件中结算正确,含叠加与上限;
|
||
|
||
* 领取型权益防重与限流稳定;
|
||
|
||
* 审计日志完整,能输出`applied_effects`明细;
|
||
|
||
* 性能满足并发指标(按业务要求)。
|
||
|
||
## 交付物
|
||
|
||
* 结算引擎与效果合并模块的实现方案说明与接口契约。
|
||
|
||
* 管理/诊断接口的API说明与示例。
|
||
|
||
* 测试用例清单与通过报告。
|
||
|
||
* 运营使用指引:效果配置、叠加策略与风险提示。
|
||
|