--- todos: - id: "create-base-models" content: "新建 app/model/GmStatSummaryModel.php 与 app/model/SlotUserModel.php(表映射 + @property)" status: pending - id: "tenant-extends" content: "租户 Model 改为 Tenant* 继承基类,迁移统计/分页方法" status: pending - id: "update-imports" content: "更新 DashboardLogic、MarketLogic 的 use 与实例化" status: pending - id: "docs-sync" content: "同步 00/03 文档中的 Model 路径约定" status: pending - id: "verify" content: "php -l + Logic 冒烟 + verify-slot-backend" status: pending isProject: false --- # 统一数据表 Model 到 app/model 层 ## 结论 **可以,且与项目既有约定一致。** [00-总览与公共约定.md](saas6.x/docs/商户后台/00-总览与公共约定.md) §4.3 已写明订单复用 `app\model\RechargeOrderModel` / `WithdrawalOrderModel`,`GameServerModel` 也已在 `app/model` 并被租户 Logic 直接调用。 当前实际是「**半统一**」: | 表 | 现状 | 目标 | |---|---|---| | `s_pay.recharge_order` | 基类 [`app/model/RechargeOrderModel`](saas6.x/server/app/model/RechargeOrderModel.php) + 租户扩展 [`TenantRechargeOrderModel`](saas6.x/server/app/tenant/model/order/TenantRechargeOrderModel.php) | 保持不变(已是最佳实践) | | `s_pay.withdrawal_order` | 同上 `WithdrawalOrderModel` + `TenantWithdrawalOrderModel` | 保持不变 | | `s_common.game_server` | 已在 `app/model/GameServerModel` | 保持不变 | | `s_statistics.gm_stat_summary` | 全在 [`app/tenant/model/market/GmStatSummaryModel`](saas6.x/server/app/tenant/model/market/GmStatSummaryModel.php) | **拆分**:基类上移到 `app/model` | | `slot_all.user` | 全在 [`app/tenant/model/user/SlotUserModel`](saas6.x/server/app/tenant/model/user/SlotUserModel.php) | **拆分**:基类上移到 `app/model` | ```mermaid flowchart TB subgraph app_model [app/model 表映射层] GmStatSummaryModel SlotUserModel RechargeOrderModel GameServerModel end subgraph tenant_model [app/tenant/model 租户扩展层] TenantGmStatSummaryModel TenantSlotUserModel TenantRechargeOrderModel TenantWithdrawalOrderModel end subgraph tenant_logic [app/tenant/logic] DashboardLogic MarketLogic end GmStatSummaryModel --> TenantGmStatSummaryModel SlotUserModel --> TenantSlotUserModel RechargeOrderModel --> TenantRechargeOrderModel TenantGmStatSummaryModel --> DashboardLogic TenantGmStatSummaryModel --> MarketLogic TenantSlotUserModel --> DashboardLogic ``` ## 分层原则(你选的 base_only 方案) ### 放 `app/model`(共享表映射) - `$table` / `$pk` / `$json` - 完整 `@property` PHPDoc(对齐 DDL) - **与业务场景无关**的基础查询:按 `source+date` 查单行、通用 scope 等 - **不**放 `organization + channels` 租户隔离逻辑(隔离仍在 Logic/Controller) ### 保留 `app/tenant/model`(租户扩展) - `extends app\model\*Model` - 商户后台专用统计方法,例如: - `paginateDailyRows()` / `listChannelSummaryRows()`(市场数据) - `sumDailyPrecompute()` / `sumTotals()`(首页) - `countRegisterByWindow()`(首页注册数) - `sumSuccessByPayTime()`(订单统计,已有) ### 关键约束:不要误用 `BaseSourceModel` [`BaseSourceModel`](saas6.x/server/app/model/BaseSourceModel.php) 带 `Source` 请求头全局 scope,适用于 **admin 总后台**(`RechargeOrderModel` 等)。 `GmStatSummaryModel` / `SlotUserModel` 应 **直接 `extends think\Model`**(与现网一致),**不要**继承 `BaseSourceModel`,否则租户请求可能被错误的 `Source` header 隐式过滤。 租户数据隔离仍由以下保证(迁 Model 位置**不改变**): - `MerchantBaseController::ensureMerchantChannels()` - Logic 入参显式 `organization` + `channels` - `restrictRequestSourceByChannels()` 收敛请求 `source` ## 建议的文件变更 ### 1. 新建 `app/model/GmStatSummaryModel.php` - 从现有 tenant 版抽出:`$table = s_statistics.gm_stat_summary`、完整 `@property` - 可保留 1~2 个中性方法:`findBySourceAndDate(string $source, string $date): ?self` ### 2. 新建 `app/model/SlotUserModel.php` - 表映射 `slot_all.user` + 完整 `@property`(对齐 [03-用户管理.md](saas6.x/docs/商户后台/03-用户管理.md) 字段) - 文档写的是 `UserAllModel`,代码可统一命名为 `SlotUserModel`(与表库名一致)或按文档改为 `UserAllModel`(二选一,建议 `SlotUserModel` 减少重命名面) ### 3. 租户扩展改名/改继承 | 现文件 | 调整后 | |---|---| | `app/tenant/model/market/GmStatSummaryModel.php` | 重命名为 `TenantGmStatSummaryModel.php`,`extends app\model\GmStatSummaryModel`,保留 `paginateDailyRows` / `listChannelSummaryRows` / `sumDailyPrecompute` / `sumTotals` | | `app/tenant/model/user/SlotUserModel.php` | 重命名为 `TenantSlotUserModel.php`,`extends app\model\SlotUserModel`,保留 `countRegisterByWindow` | ### 4. 更新引用 - [`DashboardLogic.php`](saas6.x/server/app/tenant/logic/dashboard/DashboardLogic.php):`TenantGmStatSummaryModel` / `TenantSlotUserModel` - [`MarketLogic.php`](saas6.x/server/app/tenant/logic/market/MarketLogic.php):`TenantGmStatSummaryModel` ### 5. 文档同步(小改) - [00-总览与公共约定.md](saas6.x/docs/商户后台/00-总览与公共约定.md) §4.3:补充「`app/model` 放表映射,租户扩展放 `app/tenant/model`」 - [03-用户管理.md](saas6.x/docs/商户后台/03-用户管理.md):Model 路径改为 `app/model/SlotUserModel` + `app/tenant/model/user/TenantSlotUserModel` ## 不在本次范围 - 不改 `RechargeOrderModel` / `WithdrawalOrderModel`(已符合模式) - 不把租户 Logic 里的 `organization/channels` 过滤下沉到 Model global scope(避免与 admin 混用) - 不新建无业务价值的 `*Service` 中转层 ## 验收 - `php -l` 全部改动 PHP 通过 - `DashboardLogic` / `MarketLogic` 行为不变(冒烟:`paginateDailyList`、`buildOverviewSummary`) - verify-slot-backend 门禁 PASS