# 「36字花」数据库与实施计划

**文档版本**：V1.16  
**依据**：《36字花 PRD》《业务流程说明书》《后端系统规格书》及现有表 `user`  
**目标**：明确分阶段落地步骤、需新建表、两表适配方向与可执行验证清单。

**DDL 脚本（可执行）**：[database/dfw_36zihua_schema_v1.sql](../database/dfw_36zihua_schema_v1.sql)  
内含：新建 `channel` 表，及 `user` / `admin` / `admin_group` 的 `ALTER` 语句，以及新建表完整 `CREATE TABLE`（字段级 `COMMENT` 即字段清单）。

---

## 一、现状与表定位

| 表名 | 当前角色 | 目标角色 |
|------|----------|----------|
| `channel` | 新渠道主表 | **顶级代理渠道分红配置表**：由超管创建，维护分红方式、分红金额、总利润等渠道参数 |
| `user` | 用户（coin、channel_id 等） | **C 端玩家主表**：余额与精度、归属代理、流水与风控字段 |
| `admin` | 后台管理员 | **子代理承载表**：顶级代理下级代理放在 `admin`，通过 `invite_code` 管理客户，统一无开奖控制权 |
| `admin_group` | 角色组 | **按渠道隔离**：角色组归属 `channel`，渠道仅管理本渠道角色组 |

### 1.1 全局对局与渠道职责（重要）

与「多渠道」并存的一条硬规则：**对局与开奖全局唯一**，渠道**不**切分牌桌、**不**各自开奖。

| 维度 | 口径 |
|------|------|
| **期号 / 对局** | **全平台共用一套** `game_period`（及全网唯一的当前 `period_no`、同一套状态机）。不存在「每个渠道一局」或「每渠道独立期号表」。 |
| **开奖结果** | **全渠道玩家共享同一期、同一 `result_number`**。所有玩家（无论来自哪个 `channel_id`）压的是**同一场**；避免用户感知「不同入口有不同局、可被渠道操纵」。 |
| **渠道的用途** | `channel`、`user.channel_id`、注单上的 **`channel_id` 快照**（若有）仅用于 **代理归属、分润、风控与后台数据范围**，**不**用于生成多套并行对局或独立开奖。 |
| **Redis / 接口** | 当前期倒计时、封盘、算票、开奖号码等 **热状态全局一份**；不得在业务上按渠道维护多套「当前期」或多套开奖结果。**已实现（2026-04）**：`GameHotDataRedis` 将 **`user` 全行、`game_config` 按 key、`game_record`（活跃局 / 按 id / 最新一行）** 以 JSON 缓存在 Redis（键前缀 `dfw:v1:`），配置见 `config/game_hot_cache.php` 与 `.env-example` 中 `GAME_HOT_CACHE_*`；与 `config/cache.php` 的 `CACHE_DRIVER`（系统表 `config` 文件缓存）**相互独立**。 |

> **与 DDL 的对应**：`game_period` **不设** `channel_id`；`bet_order.channel_id` 为下单时用户归属快照，不改变「全场一局」语义。详见 §11.5。

---

## 二、分阶段执行计划与「先核心、后细节」顺序

**原则**：先打通 **账号 / 渠道 / 余额与流水 / 最小可演示闭环**，再叠 **玩法细则、自动开奖调度、公告与站内信等展示类能力**。避免一上来就做全量 DDL 与全部后台菜单，导致联调面过大。

### 2.1 总览（与下文 P0～P4 对应）

| 阶段 | 目标 | 主要内容 |
|------|------|----------|
| **P0** | 数据地基 | 新建 `channel` 并适配 `user`、`admin`、`admin_group`；建立账本类最小表集（金额精度统一） |
| **P1** | 游戏核心 | 期号、注单、开奖、系统配置；**Redis 热点读缓存（user / game_config / game_record）已落地**；可选 MQ 异步落库等后续增强 |
| **P2** | 资金与风控 | 充提订单、流水账、提现审核、Jackpot / 大额拦截 |
| **P3** | 代理与结算 | 流水占比分桶、级差、联营占成与负结转（表结构 + 跑批骨架） |
| **P4** | 运营与审计 | 公告（含 Pop-out）、站内信、后台 RBAC 与操作审计 |

### 2.2 建议先做的：第一批建表（核心路径）

按依赖顺序执行 DDL（或 Phinx），**优先保证下列表/变更已落地**，其余表可分期补建：

| 顺序 | 类型 | 对象 | 说明 |
|------|------|------|------|
| 1 | 新建 | **`channel`** | 渠道与顶级代理参数；替代历史 `game_channel` 方向 |
| 2 | 适配 | **`user`、`admin`、`admin_group`** | `coin` 精度、`channel_id`、邀请码与风控等（见 §四～§六） |
| 3 | 新建 | **`game_config`** | 全局可调参数（局时长、下注窗口等），避免写死 |
| 4 | 新建 | **`user_wallet_record`** | 玩家钱包流水，与余额变更同事务、可审计 |
| 5 | 新建 | **`game_period`**、**`bet_order`** | 最小「一期号 + 注单」闭环；先有表再写状态机与接口 |

**第一批可暂缓的表（归入后续迭代）**：`game_bet_auto`（自动托管）、`operation_notice` / `user_notice_read` / `user_site_message`（纯展示与触达）、`game_agent_wallet` 及结算域各表（代理分佣与联营跑批）。

### 2.3 建议先做的：第一批后台菜单（与核心能力对齐）

在 BuildAdmin **`admin_rule`** 中，**优先保证**与下列能力相关的菜单与按钮权限可配置（具体 `component` 路径以仓库为准）：

| 优先级 | 菜单能力 | 目的 |
|--------|----------|------|
| 高 | **渠道**、**游戏用户**、**角色组 / 管理员**（含渠道与邀请码相关字段） | 搭好「谁管哪条线、玩家归谁」 |
| 高 | **用户管理 / 用户钱包流水** | 覆盖玩家主数据与账务对账 |
| 高 | **游戏对局 / 压注订单** | 核心玩法与对账入口 |
| 中 | **游戏配置**（侧栏目录名）：**常规配置**（`game_config` 通用 KV，列表默认每页 50 条，不含 `deposit_tier` / `streak_win_reward` / `zi_hua_36_dictionary`）、**连胜奖励**、**充值档位**、**36字花字典** | 运营参数与字典维护 |
| 中 | **充值订单 / 提现订单** | 充提流程管理与审核 |
| 低 | **公告 / 站内信**、**代理结算** 等 | 属 **P3～P4**，核心跑通后再接 |

### 2.4 明确放到「细节阶段」的能力（勿阻塞第一期）

下列项依赖 **P1 状态机、定时任务、前端 C 端页面** 较完整后再做，避免与「账号 + 余额 + 最小下注」抢工期：

- **玩法细则**：选号上限、连胜倍率、Jackpot 条件等在 `game_config` 与代码中逐步细化即可。  
- **自动开奖 / 调度**：依赖期号服务、Redis 与（可选）MQ；表结构可先建，**调度与算票逻辑后迭代**。  
- **游戏公告、强弹窗、站内信展示**：表可后建；**后台编辑 + C 端展示** 属于运营体验增强，放在核心闭环之后。

### 2.5 最小可验收里程碑（建议）

1. **P0 完成**：能创建渠道与子代理管理员，玩家归属正确，`coin` 与 `user_wallet_record` 手工或脚本入账可对上。  
2. **P1 骨架完成**：能创建期号、写入注单、产生钱包流水（即使开奖仍为**手动或脚本模拟**）。  
3. 再推进 **自动流程、充提、公告展示** 与 **P3 结算**。

### 2.6 本次重构迁移顺序（已执行口径）

1. 新建订单表：`deposit_order`、`withdraw_order`（带 `order_no` 唯一索引、`user_id/status/create_time` 常用索引）。  
2. 硬重命名：`game_user -> user`、`game_bet_order -> bet_order`。  
3. 重建菜单与权限目录：`user`、`order`、`game`、`config`、`record`。  
4. 新增菜单节点：
   - `user/user`
   - `order/betOrder`、`order/depositOrder`、`order/withdrawOrder`
   - `game/period`
   - `config/gameConfig`、`config/ziHuaDictionary`
   - `user/userWalletRecord`
5. 清理收口：删除迁移过程中的冗余权限别名规则，仅保留最终模块节点（`user/order/game/config/record`）。
6. 运营模块：`operation_notice`、`user_notice_read` 表与后台目录 **`operation`**（子菜单 `operation/operationNotice`、`operation/userNoticeRead`）。

### 2.7 `game_config` 连胜与派彩（2026-04 起）

| `config_key` | 说明 |
|--------------|------|
| `streak_win_reward` | JSON：`rows[]` 每项含 `streak`（1～10）、`odds_factor`（与 33 相乘为整段赔率）、`is_jackpot`（是否大奖）。派彩公式：`total_amount × odds_factor × 33`。默认第 10 档 `is_jackpot=true`。 |
| `deposit_tier` | 仍由「充值档位」独立菜单维护，**不出现在**「常规配置」列表。 |

开奖结算后更新 **`user.current_streak`**：本期有中奖注单则 `min(streak_at_bet+1, 10)`，否则 **连胜归 0**（无档位配置）。若命中大奖档，向玩家 **私有频道** `private-user-{uuid}` 与 **公共频道** `public-game-period` 推送事件 **`jackpot.hit`**（负载含 `period_id`、`period_no`、`result_number`、`server_time` 与 `hits[]`；`hits[]` 每项含 `user_id`、**`nickname`**（昵称优先、空则 fallback 到 username）、`period_no`、`total_win`、`result_number`，供前端弹窗/通知直接展示）。

> **派彩期间 `period.tick` 静默规则**：开奖到派彩宽限期结束（`status=payouting`）期间**不再推送 `period.tick`**，避免覆盖中奖动画；本期进入 `finished`/`void` 时各推一帧边界帧（每期号每状态去重，Redis Key `dfw:v1:ws:tick:boundary:{period_no}:{status}`，TTL 300s），下一期 `betting` 时恢复每秒推送。详见《36字花-移动端接口设计草案》§7.1.3。

---

## 三、`channel` 设计（替代 `game_channel`）

### 3.1 建议保留字段

`id`、`code`（可作渠道码）、`invite_code`、`name`、`status`、`remark`、`admin_id`、`admin_group_id`、`create_time`、`update_time`。

### 3.2 建议新增或调整（按你确认口径）

| 方向 | 说明 |
|------|------|
| 渠道负责人 | `admin_id`：渠道对应一名管理员（`admin.id`），权限与数据范围以该账号为准；不再单独维护 `top_admin_id` |
| 代理模式参数 | `agent_mode`（`turnover` 普通刷水 / `affiliate` 联营）、`turnover_share_rate`、`affiliate_share_rate`、`affiliate_fee_rate`、`carryover_balance` |
| 渠道经营指标 | `profit_amount`（精度升级）、`total_profit_amount`、`commission_pool_amount` |
| 邀请码参数 | 渠道不生成邀请码，邀请码由管理员自动生成并用于注册归属 |
| 代理钱包 | 余额可字段扩展或独立 `game_agent_wallet`（推荐独立表，便于对账） |

### 3.3 注意

`channel` 不承担子代理树结构；子代理层级与邀请码归属下沉到 `admin`。除超管外，渠道管理仅可查看当前管理员归属渠道。

---

## 四、`user` 适配（用户表）

### 4.1 建议保留字段

`id`、`username` / `phone`、`password`、`uuid`、`head_image`、`channel_id`（归属渠道）、`status`、`create_time`、`update_time`。

### 4.2 建议新增或调整

| 方向 | 说明 |
|------|------|
| 金额精度 | `coin` 调整为 **`decimal(18,2)`**（与规格书一致，禁止用浮点存币） |
| 注册与归属 | `invite_code` 或注册时解析 URL 与 `channel.code` 绑定 |
| 提现门槛 | `user.total_deposit_coin` / `user.total_withdraw_coin` / `user.bet_flow_coin` + `game_config.withdraw_bet_flow_ratio`（净充值打码口径，全项目统一） |
| 风控 | 禁止登录 / 禁止下注 / 禁止提现等，可用位标记或独立布尔字段 |
| 连胜持久化 | 可选 `current_streak`、`last_bet_period_id`；高频仍以 **Redis** 为准，DB 作兜底同步 |
| 邮箱 | PRD 支持手机或邮箱注册时，可增加可空字段 `email`（是否唯一索引按产品定） |

---

## 五、`admin` 适配（子代理承载）

| 方向 | 说明 |
|------|------|
| 层级关系 | `parent_admin_id` 表示上级代理 |
| 渠道归属 | `channel_id` 表示该子代理属于哪个顶级渠道 |
| 邀请管理 | `invite_code` 自动生成且全局唯一，用于发展玩家并做归属绑定 |
| 角色标识 | `agent_role`（如 `agent_admin` / `sub_agent` / `staff`） |
| 分红设置 | 不再使用 `admin` / `admin_group` 分红字段；统一改为渠道维度结算后按 `channel_admin_share` 二次分配 |
| 开奖权限 | 不在数据层开放给渠道/子代理；开奖权限仅由超管 RBAC 控制 |

### 5.1 分红计算口径（现行）

- 渠道分红：先按 `channel.agent_mode` 计算渠道总佣金
- 管理员分红：再按 `channel_admin_share.share_rate` 对渠道总佣金进行二次分配
- 角色组仅用于权限与数据范围，不再参与金额拆分

---

## 六、`admin_group` 适配（角色组仅归属渠道）

| 方向 | 说明 |
|------|------|
| 渠道归属 | 增加 `channel_id` 字段，角色组只属于一个渠道 |
| 管理边界 | 渠道管理员只能增删改查本渠道 `admin_group` |
| 系统角色组 | `channel_id` 可为空表示系统级（仅超管可见） |

---
## 七、需新建的核心表

表名可按项目命名规范微调，须小写加下划线。

### 7.1 游戏引擎

**对局范围**：与 §1.1 一致——**全平台一套期号**，不按渠道分桌；详见 `game_period` 无 `channel_id` 的 DDL。

| 表名 | 用途 |
|------|------|
| `game_period`（或 `game_issue`） | **全局**期号、状态机阶段、开奖号码、自动/手动、作废标记（**非**每渠道一局） |
| `bet_order` | 注单：关联全局 `period_id`；可选 `channel_id` 为用户归属快照（分润/查询），**非**独立牌桌 |
| `game_bet_auto`（可选） | 自动托管：剩余局数、选号快照、启停状态（仍挂在全局期号下） |

### 7.2 系统配置

| 表名 | 用途 |
|------|------|
| `game_config`（或统一 `system_config_kv`） | 局时长、下注时长、选号上限、赔率步长、Jackpot 参数、RTP 放水、提现倍数与手续费等（须 DB 可配，禁止写死） |

### 7.3 资金与账本（强烈建议）

| 表名 | 用途 |
|------|------|
| **`user_wallet_record`**（原草案名 `user_wallet_ledger`，以 DDL 为准） | **玩家游戏币钱包流水**：充值、提现（含冻结/解冻）、平台划入划出、管理员加扣币、下注、派彩、手续费、作废退款、调账等；金额 **`decimal(18,2)`**，**只增不改**；与 `user.coin` 变更须同事务 + 条件更新 |
| `deposit_order` | 第三方充值、法币金额、汇率、游戏币到账、回调状态 |
| `withdraw_order` | 提现申请、手续费、审核状态、Jackpot / 大额标记 |

### 7.4 代理与结算

| 表名 | 用途 |
|------|------|
| `agent_settlement_period` | 结算周期、大盘盈亏快照 |
| `agent_commission_record` | 流水占比分桶结果、级差拆分、发放状态 |
| `affiliate_contract`（可选） | 联营契约、占成比例、阶梯条件 |
| `affiliate_carryover`（或与佣金记录合并设计） | 联营负结转余额与流水 |

### 7.5 运营

| 表名 | 用途 |
|------|------|
| `operation_notice` | 公告类型（静默 / Pop-out）、内容 |
| `user_notice_read` | 用户已读 / 强弹窗已确认 |

### 7.6 审计（按需）

若现有 `admin_log` 不足以覆盖财务与风控操作，可增补结构化审计表。

### 7.7 冷热分离（中后期）

历史注单与流水检索迁移至 **ElasticSearch 或 ClickHouse**，主库保留近期热数据与归档策略。

---

## 八、验证步骤

### 8.1 数据库与模型

1. DDL 执行后检查：金额字段均为 **`decimal(18,2)`**；`channel`、`user`、`admin`、`admin_group`、期号等关联字段有合理索引。  
2. 创建测试渠道（顶级）→ 创建子代理 `admin`（设置 `parent_admin_id`、`channel_id`、`invite_code`）→ 创建用户并挂载 `channel_id`，链路与后台筛选正常。  
3. 扣款更新采用「**条件更新**」语义（如 `WHERE balance >= 扣款额`），压测或单测验证**不出现负余额**。

### 8.1.1 菜单与权限回归（本次新增）

1. 使用超管登录，确认五大目录 `user/order/game/config/record` 可见。  
2. 使用普通角色登录，逐项验证按钮权限（`index/add/edit/del/save`）是否与授权一致。  
3. 抽查重点页面：
   - `user/user`
   - `order/depositOrder`、`order/withdrawOrder`、`order/betOrder`
   - `game/period`
   - `config/gameConfig`、`config/ziHuaDictionary`
   - `user/userWalletRecord`
   - `operation/operationNotice`、`operation/userNoticeRead`
4. 验证 `config/ziHuaDictionary` 的读取与保存权限均命中，且仅授权角色可操作。

### 8.2 业务规则（对照 PRD / 业务流程）

| 场景 | 验证要点 |
|------|----------|
| 注册与邀请 | 玩家使用子代理邀请码注册时，先命中 `admin.invite_code`，再落到对应 `channel_id` |
| 子代理权限 | 渠道与子代理账号均无开奖权限；仅超管角色可访问开奖控制接口 |
| 30 秒节奏 | 0–20s 可下注，20s 后拒绝；约 22s 后可查开奖结果 |
| 连胜与跳局 | 连续期号未下注则连胜清零；连赢时本轮总下注不超过上轮总下注 |
| Jackpot | 连胜达阈值且单局下注不低于配置最小额才触发额外大奖 |
| 提现 | 有效投注 ≥ 总充值×配置倍数；最低提现与 0.5% 手续费；大额 / Jackpot 进审核 |
| 灾难恢复 | 模拟期卡在「计算中」，启动退本流程：期作废、本金退回账本 |

#### 8.2.1 后台「游戏实时对局」：运行开关与作废

| 项 | 说明 |
|----|------|
| 配置键 | `game_config.config_key = game_live_runtime_enabled`：`1` = 运行（默认），`0` = 维护/关闭 |
| 关闭时服务端行为 | **禁止下注**（移动端 **`betPlace`** 返回 `3001`）；**无进行中局时**定时 **`GamePeriodAutoTicker`** 不创建新期；派彩宽限期结束后的 **`createNextRecordAfterDraw`** 不插入下一期。**当局仍继续**：**`tickAutoDraw` / `drawResult` / 结算**照常执行，直至本期结束。后台 **`POST /admin/game.Live/runtime` 且 `enabled=1`** 时，若 **`hasActiveRecord()` 为假**，则 **`bootstrapPeriodWhenRuntimeEnabled`** 立即插入新一期 |
| 后台快照 `maintenance_ui` | `!game_live_runtime_enabled && !hasActiveRecord()` 时为 `true`：表示**当局已完全结束**（含派彩），此时后台页展示「维护中」并锁定操作区（仅顶部「游戏运行」开关可用）；当局尚在 0–3 状态时为 `false`，倒计时与操作区保持可用直至收尾完成 |
| 作废本局（后台按钮） | 仅当本期为 **下注开放 / 已封盘**（`game_record.status` 为 `0` 或 `1`）：将所有 **待开奖** 注单（`bet_order.status = 1`）按 `total_amount` 退回余额并置 `bet_order.status = 3`，写钱包流水 `biz_type = bet_void`；本期 **`game_record.status = 5`**，写入 **`void_reason`**；并 **强制将 `game_live_runtime_enabled` 置为 `0`**。需管理员在后台再次打开「游戏运行」开关后，才恢复下注与后续期次创建 |
| 后台接口 | `POST /admin/game.Live/runtime`（body：`enabled` 0/1）；`POST /admin/game.Live/voidPeriod`（body：`record_id` 可选、`void_reason` 必填） |

### 8.3 代理与结算（逻辑就绪后）

1. 构造多代理树与多用户下注，跑一期结算脚本或单元测试纯算法。  
2. **大盘亏损**：本期代理分佣为 0。  
3. **大盘盈利**：流水占比分桶 + 级差，各级金额之和与线总包一致（可对照文档数值验算）。  
4. **联营**：客损为负产生负结转；下期盈利先抵扣再分佣。

### 8.3.1 渠道结算新流程（2026-04-23）

1. **仅超管可结算**：按渠道结算周期（支持自动任务与手动提前结算）执行渠道结算。  
2. **结算即发放**：结算时按 `channel_admin_share` 比例，直接发放到管理员钱包并写入 `admin_wallet_record`（`commission_income`），同时写 `agent_settlement_period` / `agent_commission_record`。  
3. **提前结算规则**：手动提前结算后，新的周期起点从本次结算结束时间开始，后续自动周期归入下个结算段。  
4. **停用渠道限制**：`channel.status != 1` 时，该渠道不再允许玩家注册与登录。

### 8.3.2 后台管理员资金与提现流程（2026-04-23）

1. **管理员钱包隔离**：新增 `admin_wallet`、`admin_wallet_record`，与玩家钱包完全隔离。  
2. **分红入账**：渠道分红结算后，写管理员钱包入账流水（`commission_income`）。  
3. **提现申请**：管理员在个人中心发起提现，金额先冻结（`withdraw_freeze`），生成 `admin_withdraw_order`（`status=0`）。  
4. **渠道超管审核**：仅该渠道顶级角色组（`admin_group.pid=0`）中的管理员可审核本渠道提现单。  
5. **审核通过/拒绝**：通过则扣减冻结并累计提现（`withdraw_success`）；拒绝则退回可用余额（`withdraw_refund`）。

### 8.4 非功能

- **Redis（已落地）**  
  - **热点数据缓存**：`app/common/service/GameHotDataRedis.php`，依赖 `webman/redis` 与 `config/redis.php`。缓存对象：`user` 行（鉴权与余额类读路径）、`game_config` 行（按 `config_key`）、`game_record`（活跃局、按 id、最新一条）。**写库后一致性**：统一经 **`GameHotDataCoordinator`**（`afterUserCommitted` / `afterGameConfigKeyCommitted` / `afterGameRecordCommitted`）先 **同步回源**（`userReplaceCacheFromDb`、`gameConfigReplaceFromDb`、`gameRecordSyncCachesAfterDbWrite`），再视配置将幂等任务写入 **`GameHotDataWriteQueue`**，由进程 **`GameHotDataQueueConsumer`** 批量消化以削峰。互斥：**`GameHotDataLock`** 用于同一用户、同一 `game_config` 键、同一对局记录等资源的并发写串行化（后台钱包加减点、独立配置表单、开奖相关服务、**移动端 `betPlace` 扣款**等与后台共用用户锁）。环境变量 `GAME_HOT_CACHE_*` 控制开关、TTL、队列开关与背压（见 `.env-example` 与 `config/game_hot_cache.php`）。  
  - **规划/增强**（未替代上述）：当前期注单池、近 30 期开奖列表缓存、纯 Redis 状态机等，可按压测需求迭代。  
- **与 `CACHE_DRIVER`**：`config/cache.php` 默认 `file` 仅影响 **系统配置表 `config`**（如 `get_sys_config`），**不**控制 `GameHotDataRedis`。  
- MQ：派彩异步消费**幂等**（如 `period_id` + 用户 + 业务单号）。  
- API：下注、提现等核心接口**限流**生效。

---

## 九、风险与依赖

1. **子代理数据源**：子代理统一在 `admin`，避免在 `channel` 重复建树造成双主数据源。  
2. **现有 `profit_amount`（decimal(5,2)）**：与游戏币 **18,4** 精度不一致，演进时改为 `decimal(18,2)` 或迁移至结算域，避免对账误差。  
3. 文档要求 **AI 算票在 Redis 内完成**（演进目标），当前实现以 **MySQL `game_record` + 服务层缓存** 为主；主库仍应避免结算期大范围锁表；账本与注单以事务与幂等为准。  
4. **全局对局一致性**：任何需求（多租户展示、渠道后台）均不得引入「按渠道独立期号/独立开奖」；若出现产品歧义，以 **§1.1** 为准，避免公平性质疑与客诉。

---

## 十、相关文档索引

| 文档 | 说明 |
|------|------|
| `docs/36字花prd.md` | 玩法、代理双轨、风控与性能要求 |
| `docs/业务流程.md` | C 端、代理、联营、总控、灾难恢复流程 |
| `docs/后端.md` | 状态机、API、后台模块、安全与精度 |
| `docs/CRUD生成逻辑说明.md` | BuildAdmin CRUD 路径与表名规范 |
| `database/dfw_36zihua_schema_v1.sql` | 具体 DDL：字段、索引、注释 |

### 10.1 新建表一览（字段以 SQL 为准）

| 序号 | 表名 | 说明 |
|------|------|------|
| 1 | `game_config` | 动态参数 KV |
| 2 | `game_period` | 期号与状态机 |
| 3 | `bet_order` | 注单 |
| 4 | `game_bet_auto` | 自动托管 |
| 5 | `user_wallet_record` | 玩家游戏币钱包流水（替代旧名 `user_wallet_ledger`） |
| 6 | `deposit_order` | 充值订单 |
| 7 | `withdraw_order` | 提现订单 |
| 8 | `game_agent_wallet` | 代理钱包 |
| 9 | `game_agent_wallet_ledger` | 代理钱包流水 |
| 10 | `agent_settlement_period` | 结算周期与大盘快照 |
| 11 | `agent_commission_record` | 代理佣金明细 |
| 12 | `affiliate_contract` | 联营契约 |
| 13 | `affiliate_carryover` | 联营负结转 |
| 14 | `operation_notice` | 运营公告 |
| 15 | `user_notice_read` | 公告已读/确认 |
| 16 | `user_site_message` | 站内信 |

**既有表变更**：新建 `channel` 替代 `game_channel`；`admin` 增加子代理字段（`parent_admin_id`、`channel_id`、`invite_code`、`agent_role`）用于代理邀请链路管理；`admin_group` 增加 `channel_id` 实现角色组按渠道隔离；`game_user` 已硬重命名为 `user`，`game_bet_order` 已硬重命名为 `bet_order`；`user_wallet_record`、`game_config` 保持现名。

---

**变更记录**

| 版本 | 日期 | 说明 |
|------|------|------|
| V1.0 | 2026-04-14 | 初稿：表适配、新建表清单、验证步骤 |
| V1.1 | 2026-04-14 | 增加可执行 DDL 脚本路径与新建表一览 |
| V1.2 | 2026-04-14 | 修正口径：`game_channel` 仅顶级分红参数，子代理迁移至 `admin` |
| V1.3 | 2026-04-14 | 收敛权限：仅超管可开奖，渠道/子代理仅拉用户 |
| V1.4 | 2026-04-14 | 新建 `channel` 替代 `game_channel`，`admin_group` 按渠道隔离 |
| V1.5 | 2026-04-15 | 落地 `game_user_wallet_record` 玩家钱包流水表；文档增补字段说明附录；与 DDL 统一命名 |
| V1.6 | 2026-04-15 | 增加「先核心后细节」实施顺序：先建表/菜单清单、可暂缓表与细节阶段能力；修正章节编号（验证步骤改为第八章） |
| V1.7 | 2026-04-15 | 明确「多渠道、单场对局」：全平台共用 `game_period` 与同一开奖；渠道仅归属/分润；附录 `game_period`/`bet_order` 注释对齐 |
| V1.8 | 2026-04-15 | §7.1 游戏引擎表与 §1.1 对齐：显式说明全局期号、`bet_order.channel_id` 仅为归属快照 |
| V1.9 | 2026-04-15 | 落地模块化重构：`game_user->user`、`game_bet_order->bet_order`；新增 `deposit_order`/`withdraw_order`；后台菜单重组为 `user/order/game/config/record` 五大目录 |
| V1.10 | 2026-04-15 | 完成表名与权限规则收口：`user_wallet_record`、`game_config` 保持不变；移除冗余 snake alias 菜单规则，文档口径与线上结构一致 |
| V1.11 | 2026-04-16 | 落地运营公告：`operation_notice`、`user_notice_read` 表与菜单目录 `operation`（运营公告、用户阅读记录） |
| V1.12 | 2026-04-18 | 下注口径：`bet_order` 仅保留 `total_amount`（整笔压注），删除 `unit_amount`、`pick_count`；DDL 与 Phinx 迁移 `20260418270000_bet_order_drop_unit_amount_pick_count` 对齐 |
| V1.14 | 2026-04-20 | 服务端 Redis 热点缓存：`GameHotDataRedis`（`user` / `game_config` / `game_record`），`config/game_hot_cache.php` 与 `.env-example` 中 `GAME_HOT_CACHE_*`；更新 §1.1、§2.1、§8.4、第九章风险与依赖、附录 `user`；与 `CACHE_DRIVER`（系统 `config` 表文件缓存）区分说明 |
| V1.15 | 2026-04-20 | 热点写路径收口：`GameHotDataCoordinator` + `GameHotDataLock` + `GameHotDataWriteQueue` / `GameHotDataQueueConsumer`；文档与实现对齐（替代仅 `*Forget` 描述）；移动端 `betPlace` 与后台钱包共用用户互斥锁及 `coin` 乐观更新 |
| V1.16 | 2026-04-23 | 渠道结算改为单阶段口径（仅超管结算，结算即按比例发放管理员钱包并记录操作人）与管理员钱包提现流程（`admin_wallet` / `admin_wallet_record` / `admin_withdraw_order`，渠道顶级组审核） |

---

## 十一、附录：主要表字段说明（与 `database/dfw_36zihua_schema_v1.sql` 同步）

以下为各表**字段含义与使用要点**，便于评审与联调；**以仓库内 DDL 为最终口径**。

### 11.1 `channel`（渠道 / 顶级代理分红参数）

| 字段 | 作用 |
|------|------|
| `id` | 主键 |
| `code` | 渠道标识，业务唯一 |
| `invite_code` | 渠道侧邀请码（与 PRD「邀请码由管理员生成」并存时，以产品定义为准） |
| `name` | 渠道名称 |
| `agent_mode` | `turnover` 普通刷水 / `affiliate` 联营，决定分红与契约字段使用方式 |
| `profit_amount` / `total_profit_amount` / `commission_pool_amount` | 经营与分红池快照类金额，**decimal(18,2)** |
| `turnover_share_rate` / `affiliate_share_rate` / `affiliate_fee_rate` | 分红与联营费率类参数 |
| `carryover_balance` | 联营负结转余额（可负） |
| `admin_id` / `admin_group_id` | 渠道负责人（管理员）、渠道绑定的角色组 |
| `status` / `remark` / `create_time` / `update_time` | 状态、备注、时间戳 |

### 11.2 `user`（C 端玩家）

| 字段 | 作用 |
|------|------|
| `coin` | 当前游戏币余额，**decimal(18,2)**，更新须条件更新防负余额 |
| `channel_id` | 归属渠道；历史 `game_channel_id` 若仍存在，迁移期注意双写/对照 |
| `register_invite_code` | 注册时邀请码快照，用于审计与归属 |
| `total_deposit_coin` / `total_withdraw_coin` | 累计充值入账、累计提现出账（提现受理时累加）；与「净充值」口径配合校验提现门槛 |
| `bet_flow_coin` | 打码量/流水（历史名 `total_valid_bet_coin`，2026-04-18 迁移重命名）；开奖结算成功时按注单 `total_amount` 1:1 累加，提现门槛 `bet_flow_coin >= (total_deposit_coin - total_withdraw_coin) × withdraw_bet_flow_ratio` |
| `risk_flags` | 风控位（如禁止登录/下注/提现，按位定义） |
| `current_streak` / `last_bet_period_no` | 连胜与期号兜底；**读路径**可通过 **`GameHotDataRedis` 缓存 `user` 行** 降低压力，**写路径**以下注/结算后落库为准，并经 **`GameHotDataCoordinator::afterUserCommitted`** 同步刷新 Redis 与写队列入队 |
| `admin_id` | 归属子代理管理员 |
| 其余 | 账号、头像、状态、时间戳等见 DDL |

### 11.3 `admin` / `admin_group`（子代理与角色组）

| 表/字段 | 作用 |
|---------|------|
| `admin.parent_admin_id` | 子代理上下级 |
| `admin.channel_id` | 所属渠道 |
| `admin.invite_code` | 子代理邀请码，注册归属 |
| `admin.agent_role` | 角色类型（均无开奖权） |
| `admin_group.channel_id` | 角色组归属渠道；`NULL` 可为系统级（仅超管） |
| `channel_admin_share.share_rate` | 渠道内管理员分配比例（百分比，启用项合计=100） |

### 11.4 `game_config`（动态参数）

| 字段 | 作用 |
|------|------|
| `config_key` | 全局唯一键 |
| `config_value` / `value_type` | 参数值及类型（含 JSON） |
| `remark` | 说明，禁止业务写死应读此表 |

### 11.5 `game_period` / `bet_order` / `game_bet_auto`

| 表 | 要点 |
|----|------|
| `game_period` | **全平台唯一**期号：`period_no` 全局唯一；`status` 状态机；开奖结果与作废原因。**无 `channel_id` 字段**：对局不按渠道拆分。 |
| `game_play_record`（兼容视图 `bet_order`） | 游玩记录关联**全局** `period_id`；`channel_id` 为**用户/归属快照**，便于分润与查询，**不表示**独立牌桌或独立开奖。`pick_numbers` 为所选号码集合；**`total_amount` 为整笔游玩金额**（命中集合内任一开奖号码即按该金额参与派彩倍率计算）。已移除历史字段 `unit_amount` / `pick_count`。`idempotency_key` 幂等；金额 **18,4**；`win_amount` / `jackpot_extra_amount` |
| `game_bet_auto` | 托管剩余局数、选号快照、抖动时间等；仍挂在**全局**期号下 |

### 11.6 `user_wallet_record`（玩家钱包流水）

| 字段 | 作用 |
|------|------|
| `user_id` | 玩家 `user.id` |
| `channel_id` | **账务发生时**渠道快照，便于按渠道查询与对账；入账逻辑应写入 |
| `biz_type` | 业务类型：`deposit`、`withdraw`、`platform_in`、`platform_out`、`admin_credit`、`admin_deduct`、`bet`、`payout`、`fee`、`void_refund`、`adjust` 等（字符串枚举，与代码常量一致） |
| `direction` | `1` 入金 / `2` 出金；与 `amount` 恒正配合使用 |
| `amount` | 变动额，**恒正** |
| `balance_before` / `balance_after` | 变动前后余额，对账与审计 |
| `ref_type` / `ref_id` | 关联订单或业务主键（如 `deposit_order`、`bet_order`） |
| `idempotency_key` | 幂等键，防重复记账（唯一索引，允许多 `NULL`） |
| `operator_admin_id` | 人工加扣币时的操作者 `admin.id` |
| `remark` | 说明 |
| `create_time` | 流水时间；**本表不设 `update_time`，禁止 UPDATE** |

### 11.7 `deposit_order` / `withdraw_order`

| 表 | 要点 |
|----|------|
| `deposit_order` | 法币、`fx_rate`、`coin_amount`、网关单号、回调存档 |
| `withdraw_order` | 申请额、手续费、审核与 Jackpot 标记、驳回原因 |

### 11.8 代理钱包与结算域（`game_agent_wallet`、`game_agent_wallet_ledger`、`agent_settlement_period`、`agent_commission_record`、`affiliate_*`）

见 DDL 注释：代理余额与流水、结算周期大盘快照、佣金行、联营契约与负结转；金额均为 **decimal(18,2)**，与玩家账本区分职责。

### 11.9 运营与消息（`operation_notice`、`user_notice_read`、`user_site_message`）

公告类型（含强弹）、已读确认；站内信与公告分离存储，详见各表 `COMMENT`。
