Files
cursor/plans/充值后下注返水_c358d34a.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

112 lines
5.3 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.

---
name: 充值后下注返水
overview: 在下注发生时用现有 `user:recharged` 集合判断是否已充值,仅充值用户额外累计 `rebate_bet`;每日返水改用 `rebate_bet`,不影响 VIP 输钱返利等仍使用全量 `bet`
todos:
- id: pwa-rebate-bet
content: pwa UserProfitService 增加 rebate_bet并在 incBet 时用 user:recharged 集合判断后累计
status: completed
- id: console-use-rebate-bet
content: console UserProfitEntity + DailyRebateLogic 结算/同步改用 rebate_bet
status: completed
- id: deploy-doc-test
content: 更新 daily_rebate_deploy.md 发布顺序与冒烟用例;跑 verify + 相关测试
status: completed
isProject: false
---
# 充值后的下注才计入每日返水
## 背景与缺口
当前实现([`DailyRebateLogic`](file:///Users/ray/Documents/project/www/slot/slot_console/app/api/logic/DailyRebateLogic.php))仅在结算/同步时用 `userHasDeposit()` 过滤,下注额来自共享 Redis 日哈希([`slot_pwa` `UserProfitService::incBet`](file:///Users/ray/Documents/project/www/slot/slot_pwa/app/service/user/UserProfitService.php)**全天 `bet` 无差别累计**。
因此「同一天先下注、后首充」会把首充前下注也算进返水——与产品「充值后的下注才算」不符。
**产品已确认口径**
- 开启计时:普通充值 + 签到购(与现网 `RechargedUidSetService::add` 一致)
- 历史:仅上线日起按新规则;不回溯历史结算日
**约束**:同一 Redis 日盈利哈希还被 [`LoseReturnDeposit`](file:///Users/ray/Documents/project/www/slot/slot_console/app/command/LoseReturnDeposit.php)VIP 输钱返利)使用,**不能**改 `bet` 语义或阻止未充值用户累计 `bet`
```mermaid
flowchart LR
subgraph pwa [slot_pwa]
Bet[WalletService bet]
IncBet[UserProfitService.incBet]
Bet --> IncBet
IncBet --> betField["bet 全量"]
IncBet --> CheckSet["SISMEMBER user:recharged"]
CheckSet --> rebateBetField["充值用户才累加 rebate_bet"]
end
subgraph wallet [slot_wallet]
Recharge[recharge / rechargeSign]
Recharge --> SetUid[SADD user:recharged]
end
subgraph console [slot_console]
Settle[dailyRebateSettle]
Settle --> UseRebateBet["读 rebate_bet 算档"]
end
rebateBetField --> Settle
SetUid --> CheckSet
```
---
## 方案:新增 `rebate_bet`,下注时用集合判断
### 1. slot_pwa — 下注时累计 `rebate_bet`
扩展 [`UserProfitService`](file:///Users/ray/Documents/project/www/slot/slot_pwa/app/service/user/UserProfitService.php)
- 序列化结构:`bet``win`、**`rebate_bet`**(默认 0反序列化兼容旧数据
- 新建或复用一个轻量 `RechargedUidSetService`(读 share Redis `SISMEMBER user:recharged`
- `incBet` 逻辑:
- `bet` 仍始终 `+= fee`(供输钱返利等)
-`SISMEMBER user:recharged uid = 1`,则 `rebate_bet += fee`
- 否则不累加 `rebate_bet`
**性能**:每次下注 1 次 `SISMEMBER`;如下注高频,可对「已充值」状态做短 TTL 本地/Redis 缓存可选非必须。Redis 异常时按未充值处理,宁可少算不可多算。
### 2. slot_console — 返水只读 `rebate_bet`
| 文件 | 改动 |
|------|------|
| [`UserProfitEntity`](file:///Users/ray/Documents/project/www/slot/slot_console/app/entity/command/UserProfitEntity.php) | 增加 `public int $rebate_bet = 0` |
| [`DailyRebateLogic`](file:///Users/ray/Documents/project/www/slot/slot_console/app/api/logic/DailyRebateLogic.php) | `settleOneUserFromProfitHash``readTodayBetFromRedis``syncTodayPending` 使用 **`rebate_bet`** 作为有效下注(无字段或旧日为 0**禁止** fallback 到 `bet`,避免误发) |
| 结算日志 | `samples` 中 bet 字段可改为 `rebate_bet` 或同时打 `bet`/`rebate_bet` 便于对账 |
保留现有 `userHasDeposit()` 校验(双保险:未在集合内仍 skip
### 3. 部署与验收(更新 [`daily_rebate_deploy.md`](file:///Users/ray/Documents/project/www/slot/slot_console/doc/daily_rebate_deploy.md)
**发布顺序**:确认 `center`/`wallet` 已有 `user:recharged` 机制并完成回填 → 发布 `slot_pwa` → 发布 `slot_console``slot_pwa` 必须早于次日 `dailyRebateSettle` cron
**冒烟用例**
1. 未充值用户下注 → `rebate_bet=0` → 结算 skip / 无可领
2. 同日:先下注 100 → 再首充 → 再下注 200 → 仅 `rebate_bet=200` → 返水按 200 档位
3. 已充值老用户(已在 `user:recharged` 集合)→ 上线后下注直接累计 `rebate_bet`
4. VIP 输钱返利:仍读 `bet`,行为不变
---
## 不改动的部分
- `user:recharged` SET 语义不变
- `center` 不新增共享 Redis key
- `wallet` 充值成功后写集合的逻辑不变
- 领取/活动页 `userHasDeposit` 门槛不变
- 不改动 `slot_sdk`(无跨服务 HTTP
- 不做历史日 `rebate_bet` 回填
---
## 风险与说明
| 项 | 说明 |
|----|------|
| 上线前已在 set 的老用户 | 上线后发生的下注会直接累计 `rebate_bet`,符合“已充值用户后续下注算返水” |
| 首充与下注并发 | 以下注时 `SISMEMBER user:recharged` 的结果为准;集合写入前的下注不计入,写入后的下注计入 |
| Redis 异常 | pwa 判断集合失败应记 error 且 **不累加** `rebate_bet`(宁可少算不可多算) |