Files
cursor/plans/每日返水活动化改造_dd1575a1.plan.md
ray zhou f71a5c59af ok
2026-05-29 11:21:40 +08:00

226 lines
11 KiB
Markdown
Raw Permalink 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: 将每日返水从独立档位表方案改为与首充定格Free Credits, type=11一致的活动配置模式新增活动类型 12、档位写入 recharge_gift_config.ext_config保留 daily_rebate_record 做用户日统计与领取,综合统计页独立不变。
todos:
- id: activity-type-12
content: 新增 TYPE_DAILY_REBATE=12RechargeGiftConfigModel、getDailyRebateActiveInfo、Consts、activity_type 字典 SQL
status: completed
- id: activity-ext-config
content: ActivityValidate::checkDailyRebateExt + ActivityController save/updateactivity/edit.vue & index.vue type=12 档位 UI
status: completed
- id: refactor-daily-rebate-service
content: DailyRebateService 改读 recharge_gift_config.ext_configdaily_rebate_record 增加 activity_id
status: completed
- id: remove-tier-table
content: 删除 daily_rebate_tier_config 及相关 Admin CRUD/菜单;更新 daily_rebate.sql
status: completed
- id: complete-stats-api
content: 补全 dailyRebateStats 前端页 + 确认 DailyRebateSettle/Expire/API/流水类型 65
status: completed
- id: tests-acceptance
content: DailyRebateCalcServiceTest + 端到端验收(配置→结算→领取→统计)
status: completed
isProject: false
---
# 每日返水 — 活动化改造方案(对齐首充定格)
## 背景与纠偏
你已指出:**这是活动,应新增活动类型,返水档位在「活动配置」里维护**参考首充定格Free Credits
现有代码库中首充定格模式:
| 层级 | 实现 |
|------|------|
| 配置表 | [`s_recharge_gift_config`](slot_console/app/model/common/RechargeGiftConfigModel.php)(后台称「充值活动配置」) |
| 活动类型 | `TYPE_FREE_CREDITS = 11` |
| 业务参数 | `ext_config` JSON千分位 `_qf` 字段) |
| 后台入口 | [活动管理 → 充值活动配置](backend/slot_admin_vue/src/views/game/activity/index.vue) + [edit.vue type==11 表单项](backend/slot_admin_vue/src/views/game/activity/edit.vue) |
| 校验 | [`ActivityValidate::checkFreeCreditsExt`](backend/slot_admin/app/game/validate/ActivityValidate.php) + [`ActivityController::save/update`](backend/slot_admin/app/game/controller/ActivityController.php) |
| 运行时查询 | [`RechargeGiftConfigModel::getFreeCreditsActiveInfo`](slot_console/app/model/common/RechargeGiftConfigModel.php) |
| 用户状态 | 独立表 `free_credits_player` / `free_credits_package` |
**先前中断实现的问题**:已创建 [`daily_rebate_tier_config`](slot_console/db/daily_rebate.sql) 独立表及 [`DailyRebateTierConfig*`](backend/slot_admin/app/game/controller/DailyRebateTierConfigController.php) 后台 — **与产品约定不符,应废弃并改为 ext_config**
**可保留部分**(逻辑正确,仅需改配置来源):
- [`DailyRebateCalcService`](slot_console/app/service/DailyRebateCalcService.php) — 累进分段计算
- [`daily_rebate_record`](slot_console/db/daily_rebate.sql) — 用户日返水记录(需加 `activity_id`
- [`DailyRebateSettle` / `DailyRebateExpire`](slot_console/app/command/DailyRebateSettle.php) 定时任务
- [`DailyRebateController`](slot_console/app/api/controller/DailyRebateController.php) C 端 info/claim
- [`DailyRebateStats*`](backend/slot_admin/app/game/controller/DailyRebateStatsController.php) — **综合统计/每日返水统计**(独立菜单,同 Free Credits 统计)
```mermaid
flowchart TB
subgraph admin [活动管理 slot_admin]
ActivityUI["activity/edit.vue type=12"]
ActivityAPI["ActivityController + ActivityService"]
end
subgraph config [s_common]
RGC["recharge_gift_config ext_config.tiers"]
DRR["daily_rebate_record"]
end
subgraph runtime [slot_console]
Settle["dailyRebateSettle"]
API["DailyRebateService info/claim"]
end
ActivityUI --> ActivityAPI --> RGC
Settle --> RGC
Settle --> DRR
API --> RGC
API --> DRR
```
---
## 1. 新增活动类型 `12` — 每日返水
### 1.1 常量与模型
- [`RechargeGiftConfigModel`](slot_console/app/model/common/RechargeGiftConfigModel.php) 增加:
```php
const TYPE_DAILY_REBATE = 12; // 每日返水
```
- 新增方法 `getDailyRebateActiveInfo(string $source)`,逻辑**复制** `getFreeCreditsActiveInfo``status=1`、`type=12`、时间窗、`source` 优先于 `all`。
- [`slot_lib/Consts.php`](slot_lib/src/common/const/Consts.php) 增加 `ACTIVITY_TYPE_DAILY_REBATE = 12`(与现有 19 并列,便于订单/日志引用)。
- 字典 `activity_type` 增加一条SQL 或后台字典):`value=12, label=每日返水`(与 type=11「首充定格/Free Credits」同级
### 1.2 `ext_config` 结构(档位配置)
```json
{
"tiers": [
{ "sort": 1, "min_bet_qf": 0, "max_bet_qf": 1000000, "rate_percent": 3 },
{ "sort": 2, "min_bet_qf": 1000001, "max_bet_qf": 3000000, "rate_percent": 2 },
{ "sort": 3, "min_bet_qf": 3000001, "max_bet_qf": 5000000, "rate_percent": 1 },
{ "sort": 4, "min_bet_qf": 5000001, "max_bet_qf": null, "rate_percent": 0.5 }
]
}
```
- 金额与全站一致:**存储千分位(厘)**;后台表单用美元展示,提交时 `×1000`(与 type=11 的 `toQf` 一致)。
- 默认种子:可在活动保存时由前端预填 4 档,或提供 migration 插入一条 `type=12` 的 default 活动(`source=all`)。
### 1.3 校验
在 [`ActivityValidate`](backend/slot_admin/app/game/validate/ActivityValidate.php) 新增 `checkDailyRebateExt(array $extConfig)`
- `tiers` 非空数组,每档含 `sort/min_bet_qf/rate_percent`;非最后一档 `max_bet_qf` 必填。
- 复用 [`DailyRebateCalcService::validateTiersContinuous`](slot_console/app/service/DailyRebateCalcService.php)(入参转为 `min_bet`/`max_bet` 厘)。
在 [`ActivityController`](backend/slot_admin/app/game/controller/ActivityController.php) 的 `save` / `update``updateData` 时)对 `type === 12` 调用该校验(与 type=11 并列)。
---
## 2. 管理后台 — 活动配置 UI核心
参考 type=11在 [`activity/edit.vue`](backend/slot_admin_vue/src/views/game/activity/edit.vue) 增加 **`formData.type == 12`** 区块:
| 表单项 | 说明 |
|--------|------|
| 返水档位表 | 可增删行:排序、下限($)、上限($,最后一档可空)、比例(%) |
| 规则说明 | 复用活动主表 `help` 字段(与 Free Credits 一致) |
| 展示时间/生效时间 | 复用现有 `show_*` / `start_time` / `end_time` |
**交互约束**(与 type=11 相同):
- `onlyGift` 计算属性加入 `12` → 不展示「赠送配置 goods」区块。
- `submit` 时:`type===12` → `data.goods=[]``ext_config.tiers` 做 `toQf` 转换。
- `setFormData` 时:`tiers` 从 `_qf` 还原为美元展示。
[`activity/index.vue`](backend/slot_admin_vue/src/views/game/activity/index.vue) 列表 `ext_config` 列type=12 时展示各档比例摘要(类似 type=11 展示门槛)。
**删除**(不再单独维护档位):
- [`DailyRebateTierConfigController`](backend/slot_admin/app/game/controller/DailyRebateTierConfigController.php) 及 Logic/Validate/Model
- [`dailyRebateTierConfig.js`](backend/slot_admin_vue/src/api/game/dailyRebateTierConfig.js) 与对应 vue若已创建
- [`menu-daily-rebate.sql`](backend/slot_admin/db/menu-daily-rebate.sql) 中「每日返水档位」菜单项3082
- 表 `daily_rebate_tier_config`(不建或迁移后 DROP
**保留菜单**:仅「综合统计 → 每日返水统计」3084挂在活动管理同级或统计分组下。
---
## 3. 运行时改造slot_console
### 3.1 配置读取
改造 [`DailyRebateService`](slot_console/app/service/DailyRebateService.php)
- 删除对 `DailyRebateTierConfigModel` 的依赖。
- 通过 `RechargeGiftConfigModel::getDailyRebateActiveInfo($source)` 取活动;无生效活动 → C 端 `unlocked=false` 或整活动不可用(与未开 Free Credits 一致)。
- 从 `ext_config['tiers']` 解析为 `DailyRebateCalcService` 入参(`min_bet`/`max_bet`/`rate_percent`)。
- `info()` 返回的 `tiers` 来自当前活动配置;`tier_snapshot` 结算时写入完整 tiers JSON。
### 3.2 用户记录表
调整 [`daily_rebate_record`](slot_console/db/daily_rebate.sql)
- 增加 `activity_id bigint``recharge_gift_config.id`),结算/待定时写入。
- **删除** `daily_rebate_tier_config` 建表与种子 SQL。
### 3.3 结算与领取
- [`DailyRebateSettle`](slot_console/app/command/DailyRebateSettle.php):按渠道解析活动配置后再算返利;未充值用户仍跳过。
- 领取:继续 `TRANSACTION_TYPE_DAILY_REBATE = 65`(已在 [`Consts.php`](slot_lib/src/common/const/Consts.php) 规划/部分落地)。
### 3.4 C 端 API不变路径
- `GET /api/daily-rebate/info`
- `POST /api/daily-rebate/claim`
需校验:**当前用户渠道存在生效的 type=12 活动**,否则返回活动未开启。
---
## 4. 综合统计页(保持独立)
与 [Free Credits 统计](backend/slot_admin/app/game/controller/FreeCreditsStatsController.php) 相同定位:
- 菜单:**综合统计 / 每日返水统计**(非活动配置页)
- 实现:沿用已规划的 [`DailyRebateStatsLogic`](backend/slot_admin/app/game/logic/DailyRebateStatsLogic.php) + [`dailyRebateStats/index.vue`](backend/slot_admin_vue/src/views/game/dailyRebateStats/index.vue)(若 vue 未写完则补全)
- 数据源:`daily_rebate_record`;筛选/汇总规则不变
---
## 5. 与首充定格的差异对照
| 项 | Free Credits (11) | 每日返水 (12) |
|----|-------------------|---------------|
| ext_config | 门槛、分档金额、Banner | **tiers 累进档位** |
| 用户状态表 | free_credits_player/package | daily_rebate_record |
| 统计页 | Free Credits 统计 | 每日返水统计 |
| 充值门槛 | 首充定格业务 | **历史充值过即可**wallet `r>0` |
| 计费基础 | 定格池 | 当日 `user_profit_daily.bet` |
---
## 6. 实施步骤(建议顺序)
1. **活动类型与 ext_config 契约**Model 常量 + `getDailyRebateActiveInfo` + ActivityValidate + ActivityController + 字典 SQL。
2. **后台 activity/edit.vue + index.vue**type=12 档位表 UI 与 qf 换算。
3. **重构 DailyRebateService**:读活动 ext_configrecord 加 `activity_id`。
4. **清理**:移除 tier 独立表/Controller/菜单;更新 `daily_rebate.sql`。
5. **补全**:统计 vue、PWA 流水类型 65、单元测试仍用 tiers 数组驱动 CalcService。
6. **验收**:后台新建 type=12 活动 → 用户下注 → 日切结算 → 领取 → 统计页数字一致。
---
## 7. 验收要点
1. 仅在「充值活动配置」可创建/编辑 type=12档位保存后 `ext_config.tiers` 正确落库。
2. 同渠道多条 type=12 时行为与 type=11 一致(优先具体 source
3. 改档位仅影响**新结算日**`tier_snapshot` 审计旧记录)。
4. 不再出现「每日返水档位」独立菜单。
5. $2000 下注 → 次日返水 $50与累进公式一致。
---
## Definition of Done硬规则对齐
- [ ] `grep -r DailyRebateService ~/Documents/project/www/slot --include='*.php'` → 无命中(排除 vendor
- [ ] [`DailyRebateController`](slot_console/app/api/controller/DailyRebateController.php) 对齐 [`FreeCreditsController`](slot_console/app/api/controller/FreeCreditsController.php)`BaseController` + Logic + Validate
- [ ] 已删除 orphan`slot_admin_vue` 下 `dailyRebateTierConfig/*`、`api/game/dailyRebateTierConfig.js`
- [ ] `~/.cursor/hooks/verify-slot-backend.sh` 输出 `PASS`