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,108 @@
<!-- 215d598c-9837-4e65-a3e9-850d78cd5f00 -->
## 周返水Weekly Cashback实现方案
### 已定决策(来自本轮确认)
- 二、三:按评审意见修订需求文档、计费/配置与每日返水解耦。
- 四:方案 B —— 周有效投注每日落库,规避 `user:profit:Ymd` 的 7 天 TTL。
- 五.1VIP 费率存活动配置 `ext_config.vip_rates`type=13不放 VIP 表。
- 五.2VIP 取「周末最后一刻」(结算下周一读当前 VIP 即可)。
- 五.3:结算上周的同时把「上上周」未领取的置过期。
- 五.4VIP0 不进页面,不处理。
- 五.5/6/7倒计时对齐周界四周记录入库返水 `floor` 取整到厘。
### 计费模型(与每日返水的关键差异)
- 每日返水 = 下注累进分段(`tiers`);周返水 = `周有效投注 × rate(vip%)` 单乘,按 `floor` 取整。
- 统计周:周一 00:00:00 ~ 周日 23:59:59**服务器时区**(统一口径,修订文档里"美国时间"表述)。
- 周有效投注 = 当周 7 天 `rebate_bet` 之和(仅充值用户累加,沿用 `slot_pwa` 现有口径pwa 无需改动)。
### 数据流
```mermaid
flowchart TD
pwa["slot_pwa incBet 仅充值用户累加 rebate_bet"] --> redis["redis user:profit:Ymd TTL7天"]
accrue["weeklyRebateAccrue 每天00:05 处理昨日"] --> redis
accrue --> rec["weekly_rebate_record 当周Pending bet_amount累加"]
settle["weeklyRebateSettle 周一00:15"] --> rec
settle --> vip["读当前VIP rate=vip_rates level"]
settle --> expirePrev["上上周 Claimable -> Expired"]
claim["C端 claim 上周"] --> wallet["WalletService gift 类型68 打码Y3"]
```
### 落库方案 B幂等
- 新表 `weekly_rebate_record` 增加 `last_accrued_date`date
- `weeklyRebateAccrue`(每天)处理**昨日**key 仅 1 天,必在 TTL 内):遍历昨日 `user:profit:` 哈希,充值用户且 `rebate_bet>0` → 定位昨日所属周的记录(无则建 Pending→ 若 `last_accrued_date < 昨日``bet_amount += rebate_bet` 且更新 `last_accrued_date`(重跑不重复累加)。
- C 端「This Week」展示 = `record.bet_amount`(昨日及之前)+ 今日 redis 实时 `rebate_bet``rebate = floor(weekBet * rate /100)`(镜像每日返水 `syncTodayPending` 思路)。
### 结算/过期(周一)
- `weeklyRebateSettle`:对上周 `week_start` 的 Pending 记录,读当前 VIP → `rate=vip_rates[level]``rebate=floor(bet*rate/100)``rebate>0``Claimable`,写 `vip_level`/`rate_snapshot`/`claimable_at=本周一`/`expire_at=下周一`;同一次把「上上周」`Claimable 且 expire_at<=now``Expired`
- `weeklyRebateExpire`:兜底,`status=Claimable AND expire_at<=now -> Expired`(镜像 `expireDueRecords`)。
- 顺序accrue 先于 settle。
### 复用 vs 新建
- 复用骨架:领取短事务 CAS + 钱包入账失败回滚 + 结算结构化日志(镜像 [DailyRebateLogic](slot_console/app/api/logic/DailyRebateLogic.php)`RechargedUidSetService``UserProfitEntity`、四态 + `statusLabel`、Controller/Validator 形态。
- 新建VIP 费率,不复用 tiers 累进):`WeeklyRebateCalcService::calcRebateLi(betLi, ratePercent)``WeeklyRebateConfigService`(解析 `vip_rates``maxRate``rateForVip``canonicalExtConfigForStorage`)。
### 文件清单
slot_lib
- [Consts.php](slot_lib/src/common/const/Consts.php) 新增 `ACTIVITY_TYPE_WEEKLY_REBATE=13``TRANSACTION_TYPE_WEEKLY_REBATE=68`
slot_console
- 模型 `app/model/common/WeeklyRebateRecordModel.php`(四态 + `findByUidAndWeek`)。
- `RechargeGiftConfigModel``TYPE_WEEKLY_REBATE=13``getWeeklyRebateActiveInfo/...ByExactSource`(镜像每日返水方法)。
- 服务 `app/service/WeeklyRebateCalcService.php``app/service/WeeklyRebateConfigService.php`
- Logic `app/api/logic/WeeklyRebateLogic.php`info/claim/accrue/settle/expire
- Controller `app/api/controller/WeeklyRebateController.php`、Validator `app/api/validator/WeeklyRebateValidator.php`
- 命令 `app/command/WeeklyRebateAccrue.php``WeeklyRebateSettle.php``WeeklyRebateExpire.php`
- 路由:在 api 路由注册 weekly-rebate info/claim与每日返水同处
- SQL `db/weekly_rebate.sql`(含 `last_accrued_date`、唯一键 `uniq_uid_week`)。
- 活动配置入口 [ActivityConfigEntity.php](slot_console/app/entity/activity/ActivityConfigEntity.php) 读写处对 `TYPE_WEEKLY_REBATE``WeeklyRebateConfigService::canonicalExtConfigForStorage`
- 部署文档 `doc/weekly_rebate_deploy.md`(镜像 daily_rebate_deploy
backend/slot_admin+ vue
- 字典 `activity_type` 增「周返水」value=13菜单「周返水统计」活动 type=13 编辑页 VIP 费率16 档)配置 UI周返水统计页。
slot_wallet
- 确认 `TRANSACTION_TYPE_WEEKLY_REBATE=68` 打码归类为 活动赠送 Y3`SOURCE_TYPE_ACTIVITY_REWARD=3`),与每日返水一致;如有类型白名单需补 68。
### 需求文档修订(周返水.md
- 领取按钮「昨天返水金额」→「上一周返水金额」。
- 规则文案「refreshes daily」改为「本周累计实时刷新、每周一结算」。
- 时区统一为服务器时区(删「美国时间」歧义)。
- `No Btes``No Bets`
### ext_config 标准格式type=13
```json
{
"vip_rates": [
{"vip_level": 0, "rate_percent": 0},
{"vip_level": 1, "rate_percent": 0.5},
{"vip_level": 15, "rate_percent": 2.0}
],
"banner_image": ""
}
```
### cron
- `weeklyRebateAccrue` 每天 00:05`weeklyRebateSettle` 每周一 00:15`weeklyRebateExpire` 每周一 00:20兜底
### 收尾门禁
-`app/**/*.php` 后按 `slot-backend-completion-report` Skill 跑 `verify-slot-backend.sh` + docker `php -l`,回复附「检测结果」章节。
</plan>
<todos>
[
{"id": "doc-fix", "content": "修订 周返水.md 笔误(昨天->上周、daily->weekly、时区统一、No Bets"},
{"id": "consts", "content": "slot_lib Consts 新增 ACTIVITY_TYPE_WEEKLY_REBATE=13、TRANSACTION_TYPE_WEEKLY_REBATE=68"},
{"id": "sql-model", "content": "建 weekly_rebate.sql 与 WeeklyRebateRecordModel含 last_accrued_date、四态、findByUidAndWeek"},
{"id": "config-model-methods", "content": "RechargeGiftConfigModel 加 TYPE_WEEKLY_REBATE 与 getWeeklyRebateActiveInfo 系列方法"},
{"id": "services", "content": "WeeklyRebateCalcService(VIP费率单乘) 与 WeeklyRebateConfigService(解析 vip_rates/maxRate/rateForVip/canonical)"},
{"id": "logic", "content": "WeeklyRebateLogicinfo/claim(短事务CAS+钱包回滚)/accrue/settle(读VIP+过期上上周)/expire"},
{"id": "controller-route", "content": "WeeklyRebateController + WeeklyRebateValidator + 路由注册"},
{"id": "commands", "content": "命令 WeeklyRebateAccrue/Settle/Expire + cron 配置"},
{"id": "activity-entry", "content": "ActivityConfigEntity 读写 type=13 走 canonicalExtConfigForStorage"},
{"id": "admin", "content": "slot_admin 字典/菜单/type=13 VIP费率配置页/周返水统计页"},
{"id": "wallet-verify", "content": "slot_wallet 确认流水类型68 打码归 活动赠送Y3"},
{"id": "deploy-doc", "content": "编写 weekly_rebate_deploy.md 部署文档"},
{"id": "verify-gate", "content": "跑 verify-slot-backend.sh + php -l输出检测结果章节"}
]
</todos>
</invoke>