## 每周返水统计(后台) 镜像现有 Free Credits 统计页([FreeCreditsStatsController.php](backend/slot_admin/app/game/controller/FreeCreditsStatsController.php) / [FreeCreditsStatsLogic.php](backend/slot_admin/app/game/logic/FreeCreditsStatsLogic.php) / [freeCreditsStats/index.vue](backend/slot_admin_vue/src/views/game/freeCreditsStats/index.vue) / [menu-free-credits-stats.sql](backend/slot_admin/db/menu-free-credits-stats.sql)),同请求返回 `data/total/otherData(总计)`。 ### 依赖 - 依赖「周返水核心」计划已建表 `s_common.weekly_rebate_record`(字段:`uid, source, week_start, bet_amount(厘), rebate_amount(厘), status(1待定/2待领/3已领/4过期), vip_level, rate_snapshot, last_accrued_date, claimable_at, expire_at, claimed_at`)。 - 小调整(核心计划侧):`weeklyRebateAccrue` 累加当周 Pending 行时,同时把当前 `vip_level` 与 `rate_snapshot` 写入该行,使后台对所有状态(含待定)都能直接读行内费率,无需查实时 VIP / 共享 Redis。 ### 数据流 ```mermaid flowchart LR vue["每周返水统计 index.vue sa-table"] -->|"GET /game/weeklyRebateStats/index"| ctrl["WeeklyRebateStatsController"] ctrl --> dto["WeeklyRebateStatsQueryDTO + Validate"] dto --> logic["WeeklyRebateStatsLogic list + statistics"] logic --> model["WeeklyRebateRecordModel connection s_common"] logic -->|"data/total"| vue logic -->|"otherData 总计"| vue ``` ### 后端文件(backend/slot_admin) - 模型 `app/game/model/common/WeeklyRebateRecordModel.php`:`connection='s_common'`、`table='weekly_rebate_record'`,四态常量 + `statusLabel`(镜像 [FreeCreditsPlayerModel.php](backend/slot_admin/app/game/model/common/FreeCreditsPlayerModel.php))。 - DTO `app/game/dto/WeeklyRebateStatsQueryDTO.php`(镜像 [FreeCreditsStatsQueryDTO.php](backend/slot_admin/app/game/dto/FreeCreditsStatsQueryDTO.php),归一化 page/limit)。 - 校验 `app/game/validate/WeeklyRebateStatsValidate.php`:`uid/source/status/stat_range[]/orderBy(in:bet_amount,rebate_amount)/orderType/page/limit`(镜像 [FreeCreditsStatsValidate.php](backend/slot_admin/app/game/validate/FreeCreditsStatsValidate.php))。 - 控制器 `app/game/controller/WeeklyRebateStatsController.php`:`index()` 返回 `list + otherData=statistics`(路由自动 `/game/weeklyRebateStats/index`)。 - Logic `app/game/logic/WeeklyRebateStatsLogic.php`: - `buildQuery($params)`:`uid` 精确;`source` 精确;`status` 单/多选 `whereIn`;按日范围 snap 整周 → `week_start >= 周一(start)` 且 `week_start <= 周一(end)`;排序白名单 `bet_amount`/`rebate_amount`,默认 `week_start desc`。 - `list()`:分页取行,逐行补 `rate(=rate_snapshot)`、`week_start/week_end(week_start+6)`、`is_current_week`、`status_label`,金额 `getNumberFormat` 转美元字符串。 - `statistics()`(顶部总计,对筛选集合聚合): - 总领取 `SUM(rebate_amount) WHERE status=已领` - 总待领取 `SUM(rebate_amount) WHERE status=待领取` - 总过期 `SUM(rebate_amount) WHERE status=过期` - 领取率 `总领取/(总领取+总待领取+总过期)`(分母 0 → 0),保留 2 位百分比 - 待定 `SUM(rebate_amount) WHERE status=待定`,仅当筛选范围包含本周时计算,否则 0 ### 前端(backend/slot_admin_vue) - `src/api/game/weeklyRebateStats.js`:`getPageList` → `/game/weeklyRebateStats/index`。 - `src/views/game/weeklyRebateStats/index.vue`:`sa-table`(镜像 freeCreditsStats) - 搜索区:用户ID(input)、渠道(`commonStore.allSourcesOptionsNoAll` 可搜)、状态(四种 select)、统计周期(`a-range-picker` mode=date 不带时分)。 - `#tableAfterButtons` 顶部总计:总领取 / 总待领取 / 总过期 / 领取率% / 待定。 - 列:用户ID、渠道号、有效下注额(sortable)、返水率、返水金额(sortable)、状态(tag)、统计周期(`本周` 或 `week_start - week_end`)。 - `stats = crudRef.getTableOtherData()`;金额已由后端格式化,前端直接展示。 ### 菜单 SQL(backend/slot_admin/db/menu-weekly-rebate-stats.sql) - 镜像 [menu-free-credits-stats.sql](backend/slot_admin/db/menu-free-credits-stats.sql):挂在「综合统计」父菜单下(部署时确认其 `sm_system_menu.id`,缺失则建),`code/route/component = game/weeklyRebateStats/index`,并补 `sm_system_group_menu` 授权。 ### 字段口径与说明 - 仅统计充值用户(`weekly_rebate_record` 本就只对充值用户落库)。 - 返水率取行内 `rate_snapshot`:历史行为结算时快照,待定行为 accrue 时写入的当前 VIP 费率(每周按最新 VIP)。 - 待定行 `bet_amount` 为已 accrue 到昨日的累计(后台读库口径,不含当日实时增量)。 - 金额单位厘 → `getNumberFormat` 转美元展示。 ### 收尾门禁 - 改 `app/**/*.php` 后按 `slot-backend-completion-report` Skill 跑 `verify-slot-backend.sh` + docker `php -l`,回复附「检测结果」章节(含 PHPDoc:checked)。 [ {"id": "stats-model", "content": "slot_admin WeeklyRebateRecordModel(connection s_common) + 四态/statusLabel"}, {"id": "stats-dto-validate", "content": "WeeklyRebateStatsQueryDTO + Validate(uid/source/status/stat_range/orderBy白名单)"}, {"id": "stats-controller", "content": "WeeklyRebateStatsController index 返回 list + otherData"}, {"id": "stats-logic", "content": "WeeklyRebateStatsLogic:buildQuery(周snap/排序) + list(行补week区间/rate/状态) + statistics(五项总计+领取率+待定本周判断)"}, {"id": "stats-vue", "content": "weeklyRebateStats api.js + index.vue(筛选/顶部总计/可排序列/统计周期展示)"}, {"id": "stats-menu-sql", "content": "menu-weekly-rebate-stats.sql 挂综合统计父菜单 + 分组授权"}, {"id": "accrue-rate-snapshot", "content": "核心侧调整:accrue 对 Pending 行写入当前 vip_level/rate_snapshot"}, {"id": "stats-verify", "content": "跑 verify + php -l 输出检测结果章节"} ]