积分冻结与过期机制 — 未实现功能设计
本文档仅覆盖尚未实现的功能中需要用到积分冻结/过期机制的场景。
已实现功能(订单冻结、活动冻结、批次过期等)不在本文档范围内。
编写日期:2026-03-21
一、积分转赠(待实现功能 #26)
1.1 冻结机制
| 环节 |
操作 |
说明 |
| 发起转赠 |
freezePoints(senderId, amount, transferId) |
A 发起转赠→冻结 A 的积分 |
| 对方接收 |
consumeFrozenPoints(senderId, amount, transferId) + earnPoints(receiverId, ...) |
B 确认→扣除 A 冻结积分,发放给 B |
| 对方拒绝/超时 |
unfreezePoints(senderId, amount, transferId) |
超过24小时未接收→自动解冻退回 A |
1.2 过期机制
- B 收到的转赠积分创建新批次,有效期建议 90天(防止积分通过转赠无限续期)
- 转赠积分的有效期不应继承原批次剩余有效期(否则可通过互转刷新有效期)
1.3 风控要点
- 单日转赠上限:每人每日最多转出 500 积分
- 手续费:转赠扣除 10% 手续费(A 转 100,B 收到 90)
- 转赠积分不可再次转赠(标记
source = 'transfer_in',转赠时校验批次来源)
1.4 数据库设计建议
1.5 接口设计
二、优惠券系统(待实现功能 #16)
2.1 冻结机制 — 积分兑换优惠券
| 环节 |
操作 |
说明 |
| 兑换优惠券 |
freezePoints(userId, amount, couponOrderId) |
用户用积分兑换优惠券→先冻结 |
| 兑换确认 |
consumeFrozenPoints(userId, amount, couponOrderId) |
系统发放优惠券成功→消费冻结积分 |
| 兑换失败 |
unfreezePoints(userId, amount, couponOrderId) |
优惠券库存不足或系统异常→解冻退回 |
2.2 过期机制 — 优惠券与积分联动
- 优惠券本身有独立有效期,与积分过期无直接关系
- 但如果优惠券过期未使用且支持退还积分,退还的积分建议有效期 30天(短周期促消费)
2.3 风控要点
- 同一优惠券每人限兑 1 张(防囤券)
- 兑换冻结窗口 ≤ 5秒(快速确认,减少积分被长时间锁定)
三、限时折扣/秒杀活动(待实现功能 #17)
3.1 冻结机制 — 积分参与秒杀
| 环节 |
操作 |
说明 |
| 参与秒杀 |
freezeForActivity(userId, amount, activityId, title) |
用户参与积分秒杀→冻结积分 |
| 秒杀成功 |
consumeFrozenForActivity(userId, amount, activityId, title) |
中标→消费冻结积分,发放 Skill |
| 秒杀失败 |
unfreezeForActivity(userId, amount, activityId, title) |
未中→解冻退回 |
3.2 过期机制 — 活动赠送积分
- 限时活动赠送的积分建议有效期 7-15天(制造紧迫感,推动快速消费)
- 活动积分批次
source = 'activity',定时过期任务统一处理
3.3 关键设计
- 秒杀冻结必须原子操作(Redis + 乐观锁防超卖)
- 活动结束后批量解冻所有未中标用户的冻结积分(定时任务 / 活动结束回调)
四、安全风控体系(待实现功能 #25)
4.1 冻结机制 — 异常行为冻结
| 场景 |
冻结操作 |
说明 |
| 刷积分检测 |
冻结全部可用积分 |
检测到短时间大量签到/邀请奖励异常→冻结账户积分 |
| 恶意退款检测 |
冻结退还积分 |
频繁购买-退款套利→冻结退还的积分待人工审核 |
| 多账号关联 |
冻结关联账号积分 |
检测到同设备/IP多账号互相邀请→冻结所有关联账号 |
4.2 实现方式
4.3 数据库设计建议
4.4 风控规则示例
| 规则 |
触发条件 |
冻结策略 |
| 签到异常 |
同一设备 ≥3 个账号当天签到 |
冻结所有关联账号当天签到积分 |
| 邀请刷量 |
24小时内邀请 ≥10 人且被邀请人无后续活跃 |
冻结邀请奖励积分 |
| 退款套利 |
30天内退款 ≥3 次 |
冻结账户全部积分,人工审核 |
五、积分规则后台配置(待实现功能 #30)
5.1 过期机制 — 差异化有效期配置
当前 DEFAULT_EXPIRE_DAYS = 365 是硬编码。需要改为后台可配置:
5.2 配置示例
| 积分来源 |
建议有效期 |
配置字段 |
| register |
30天 |
expire_days = 30 |
| sign_in |
90天 |
expire_days = 90 |
| invite |
180天 |
expire_days = 180 |
| recharge |
365天 |
expire_days = 365 |
| activity |
7-15天 |
expire_days = 7 (按活动单独配置) |
| review |
90天 |
expire_days = 90 |
| admin_add |
0(永不过期) |
expire_days = 0 |
| refund |
180天 |
expire_days = 180 |
| transfer_in |
90天 |
expire_days = 90 |
5.3 代码改造要点
六、在线客服/工单系统(待实现功能 #22)
6.1 冻结机制 — 争议工单积分冻结
| 场景 |
操作 |
说明 |
| 用户提交争议工单 |
可选冻结争议订单关联积分 |
涉及积分纠纷的工单,客服可手动冻结相关积分 |
| 工单解决 |
解冻或扣除 |
根据裁决结果解冻退回或扣除 |
6.2 实现方式
- 客服后台增加"冻结用户积分"操作按钮
- 记录操作日志(关联工单ID),审计可追溯
- 解冻需要高级客服或管理员权限
七、实现优先级建议
| 优先级 |
功能 |
冻结/过期关键点 |
依赖 |
| P1 |
#30 积分规则后台配置 |
差异化有效期是所有过期策略的基础 |
无 |
| P1 |
#25 风控体系 |
风控冻结是防刷核心手段 |
无 |
| P2 |
#26 积分转赠 |
冻结防并发+过期防续期 |
无 |
| P2 |
#16 优惠券系统 |
兑换冻结+退还过期 |
优惠券模块 |
| P2 |
#17 秒杀活动 |
参与冻结+活动积分短过期 |
活动模块增强 |
| P3 |
#22 客服工单 |
争议冻结 |
客服系统 |
八、通用技术要点
8.1 冻结与解冻的幂等性
所有冻结/解冻操作必须带业务ID(orderId/transferId/activityId),防止重复冻结:
8.2 过期批次的FIFO消费
消费积分时优先扣最早到期的批次(已实现 consumeBatchesFIFO),确保:
- 用户总是先用"快过期"的积分
- 减少过期浪费,提升用户体验
8.3 冻结积分不参与过期
被冻结的积分在冻结期间不应触发过期(过期定时任务需排除冻结状态的批次)。如果业务解冻后发现原批次已过期,应创建新批次并设合理有效期。
本文档随功能开发进度持续更新