This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,111 @@
---
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`(宁可少算不可多算) |