# 足球投注平台产品需求与 MVP 实施计划（PRD）v1.2

> 文档日期：2026-06-02  
> 文档状态：访谈结论定稿版  
> 适用对象：产品、研发、测试、UI/UX、运营、财务、代理运营  
> 业务前提：面向赌博合法化国家/地区的合法运营场景。本文不展开法律合规风险论证，只描述产品、业务、账务、权限、交互、技术实现和质量控制。  
> 第一版目标：**尽量简单、快速上线、优先保证下注、结算、账务和代理额度正确。**

---

## 0. 本版结论摘要

本版根据访谈确认，采用以下默认方案作为第一版开发依据。

| 模块 | 第一版定稿方案 |
|---|---|
| 体育项目 | 只做足球，数据结构预留其他体育项目。 |
| 下注模式 | 只做赛前盘，不做滚球 / Live / In-Play。 |
| 赔率来源 | 后台手动创建赛事、盘口、赔率，不接自动赔率源。 |
| 开奖方式 | 后台手动录入半场比分、全场比分，系统生成结算预览，管理员确认后入账。 |
| 前台语言 | 简体中文 `zh-CN`、马来语 / Bahasa Melayu `ms-MY`、英文 `en-US`。 |
| UI 方向 | 参考成熟体育投注站的信息密度和 Bet Slip 交互：赛事列表、盘口分组、赔率按钮、投注单抽屉；不复制任何品牌素材。 |
| 支持玩法 | 波胆、上半场波胆、下半场波胆、全场让球、全场大/小、全场独赢盘、全场单/双、半场让球、半场大/小、半场独赢盘、冠军竞猜。 |
| 串关 | 支持基础 `2 串 1` 到 `5 串 1`；不做系统串关；不允许同场串关；冠军竞猜不允许串关；四分之一让球/大小球第一版不允许进入串关。 |
| 让球/大小球 | 单关支持整数、半球、四分之一球；串关只允许整数和半球盘口，降低结算复杂度。 |
| 代理层级 | 第一版最多 2 级代理：平台 → 一级代理 → 二级代理 → 玩家。 |
| 代理额度 | 采用代理信用额度池。玩家余额、玩家冻结投注金额、下级代理占用都会消耗代理额度；玩家输掉或下分释放额度。 |
| 玩家钱包 | 可用余额 + 冻结金额；下注冻结本金，结算后释放并派彩或扣除。 |
| 返水 | 第一版只做玩家返水；按有效投注额计算；后台生成报表，人工确认发放。 |
| 暂不做 | 滚球、系统串关、同场串关、自动数据源、自动赛果源、Cash Out、Edit Bet、Bet Builder、原生 App、无限代理层级、代理佣金自动结算。 |

---

## 1. 项目目标与范围

### 1.1 产品目标

搭建一个足球投注平台，支持平台后台、代理后台、玩家前台三类核心端口。

核心业务流程：

```mermaid
flowchart LR
    A[平台创建代理/玩家] --> B[平台给代理授信额度]
    B --> C[代理创建下级代理/玩家]
    C --> D[代理给直属玩家上分]
    D --> E[玩家前台登录]
    E --> F[查看足球赛事与盘口]
    F --> G[单关或串关下注]
    G --> H[系统冻结玩家本金]
    H --> I[后台录入半场/全场比分]
    I --> J[系统生成结算预览]
    J --> K[管理员确认结算]
    K --> L[系统派彩/扣款/退水]
    L --> M[玩家查看注单/账变/返水]
```

### 1.2 第一版产品原则

1. **先稳定后丰富**：第一版不追求 Bet365 的完整功能，只参考其成熟的信息架构与下注体验。
2. **账务不可直接改余额**：所有余额变化必须来自账变流水，不允许直接编辑钱包余额。
3. **赔率必须快照化**：玩家确认下注时锁定赔率、盘口、玩法、选项、赔率版本。
4. **结算必须可回溯**：每张注单的结算依据、比分、操作人、时间、重结算记录都必须留存。
5. **代理必须受额度控制**：代理不能无限给下级或玩家上分，额度可为负展示，但负数状态禁止继续放款。
6. **多语言从底层设计**：界面文本、赛事名称、球队名称、Banner、公告、规则说明均支持多语言字段和 fallback。
7. **第一版以移动端 H5 为主**：桌面端可用即可，移动端体验优先。

### 1.3 MVP 必须交付

| 模块 | 必须交付内容 |
|---|---|
| 玩家前台 | 登录、改密码、语言切换、赛事列表、赛事详情、投注单、单关下注、串关下注、我的投注、账变记录、返水记录、公告/Banner/走马灯。 |
| 代理后台 | 创建直属玩家、创建下级代理、给直属下级上分/下分、查看额度、查看下级玩家注单和报表。 |
| 平台后台 | 用户管理、代理管理、额度管理、账务流水、赛事管理、盘口赔率管理、结算预览、确认开奖、返水批次、报表、内容管理、多语言管理、操作日志。 |
| 注单引擎 | 支持指定 10 类足球玩法 + 冠军竞猜；支持单关和基础 2-5 串 1；赔率快照；余额冻结；幂等提交。 |
| 结算引擎 | 支持半场/全场比分结算、下半场净比分结算、亚洲让球、大小球、单双、波胆、串关结算、取消退款、重结算冲正。 |
| 账务系统 | 玩家钱包、代理额度池、账变流水、额度流水、返水入账、人工上分/下分。 |
| 系统安全 | 后台角色权限、关键操作二次确认、操作日志、软删除、登录失败锁定、接口幂等。 |

### 1.4 第一版明确不做

| 暂不做功能 | 原因 |
|---|---|
| 滚球 / Live / In-Play | 涉及实时比分、暂停下注、赔率频繁变化、延迟确认，第一版风险高。 |
| 系统串关，如 3 串 4、4 串 11 | 结算复杂，测试量大。 |
| 同场串关 | 强相关投注，风控与结算争议较多。 |
| 四分之一球串关 | 会产生半赢/半输拆注，第一版先限制。 |
| 自动赔率源 / 自动赛果源 | 先验证业务闭环，避免接口成本。 |
| Cash Out / Edit Bet / Bet Builder | 复杂度高，作为二期体验增强。 |
| 无限代理层级 | 报表、额度和权限复杂度过高。 |
| 代理佣金自动结算 | 第一版先做玩家返水和代理报表。 |
| 原生 iOS/Android App | 第一版先做移动端 H5。 |

---

## 2. 用户角色与权限

### 2.1 角色定义

| 角色 | 入口 | 说明 |
|---|---|---|
| 超级管理员 | 平台后台 | 拥有全部权限，管理系统配置、代理、玩家、账务、赛事、开奖、返水、报表。 |
| 赛事管理员 | 平台后台 | 创建赛事、联赛、球队、盘口、赔率、封盘、录入赛果、发起结算预览。 |
| 财务管理员 | 平台后台 | 玩家上分/下分、代理额度调整、账变查询、返水发放、财务报表。 |
| 客服/查询员 | 平台后台 | 查询玩家资料、投注历史、账变、重置密码，无账务执行权限。 |
| 一级代理 | 代理后台 | 创建二级代理和直属玩家，给直属下级分配额度或上分/下分，查看组织树报表。 |
| 二级代理 | 代理后台 | 创建直属玩家，给直属玩家上分/下分，查看直属玩家报表。 |
| 玩家 | 玩家前台 | 登录、查看赛事、下注、查看注单、查看账单、查看返水、修改密码。 |

### 2.2 权限矩阵

| 功能 | 超级管理员 | 赛事管理员 | 财务管理员 | 客服 | 一级代理 | 二级代理 | 玩家 |
|---|---:|---:|---:|---:|---:|---:|---:|
| 创建后台账号 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
| 创建一级代理 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
| 创建二级代理 | 是 | 否 | 否 | 否 | 是 | 否 | 否 |
| 创建玩家 | 是 | 否 | 可选 | 可选 | 是 | 是 | 否 |
| 设置代理额度 | 是 | 否 | 是 | 否 | 仅下级 | 否 | 否 |
| 玩家上分/下分 | 是 | 否 | 是 | 否 | 直属下级 | 直属下级 | 否 |
| 赛事维护 | 是 | 是 | 否 | 查看 | 查看 | 查看 | 查看 |
| 赔率维护 | 是 | 是 | 否 | 查看 | 查看 | 查看 | 查看 |
| 赛事封盘 | 是 | 是 | 否 | 否 | 否 | 否 | 否 |
| 录入赛果 | 是 | 是 | 否 | 否 | 否 | 否 | 否 |
| 确认结算 | 是 | 是/可选 | 否 | 否 | 否 | 否 | 否 |
| 重结算 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
| 返水批次 | 是 | 否 | 是 | 查看 | 查看下级 | 查看下级 | 查看自己 |
| 报表 | 全量 | 赛事报表 | 财务报表 | 查询报表 | 组织树 | 直属玩家 | 自己 |
| Banner/公告/走马灯 | 是 | 是 | 否 | 否 | 否 | 否 | 查看 |

### 2.3 代理权限边界

1. 代理只能创建和操作直属下级。
2. 一级代理可以创建二级代理和直属玩家。
3. 二级代理只能创建直属玩家。
4. 一级代理不能直接给二级代理名下玩家上分，除非该玩家是一级代理直属玩家。
5. 下级代理的额度、回水比例、单笔限额、日限额不能超过上级授权范围。
6. 代理不能修改赛事、盘口、赔率、开奖结果。
7. 代理不能撤销玩家已结算注单。
8. 代理账号被禁用后，其下级玩家可以继续登录还是一起冻结，需要后台配置；MVP 默认只禁用该代理操作权限，不自动冻结玩家。

---

## 3. 多语言与本地化

### 3.1 支持语言

| 语言 | Locale | 前台显示 | 备注 |
|---|---|---|---|
| 简体中文 | `zh-CN` | 中文 | 默认候选语言。 |
| 马来语 / Bahasa Melayu | `ms-MY` | Bahasa Melayu | 用户所说“马来西亚语”按马来语处理。 |
| 英文 | `en-US` | English | 默认 fallback 语言。 |

### 3.2 语言切换规则

1. 登录页、前台首页、玩家中心均提供语言切换。
2. 未登录用户：语言选择保存到浏览器 localStorage / cookie。
3. 已登录用户：语言选择保存到用户偏好 `user_preferences.locale`。
4. 后台也支持同三种语言，但第一版后台可以优先中文 + 英文，马来语可后补。
5. 内容缺失时 fallback 顺序：当前语言 → 英文 → 中文。
6. 后台维护赛事、球队、联赛时，至少录入一个主语言名称，其他语言可为空。

### 3.3 多语言内容范围

| 内容 | 是否多语言 | 说明 |
|---|---:|---|
| 系统菜单、按钮、错误提示 | 是 | 使用语言包 key。 |
| 玩法名称、盘口名称 | 是 | 使用系统内置翻译。 |
| 联赛、球队、赛事标题 | 是 | 后台可录入多语言名称，缺失时 fallback。 |
| Banner 标题、图片、跳转 | 是 | 不同语言可使用不同图片。 |
| 公告/走马灯 | 是 | 后台按语言维护。 |
| 投注规则说明 | 是 | 必须三语，减少争议。 |
| 注单状态 | 是 | 使用统一枚举翻译。 |

### 3.4 关键翻译 Key 示例

| Key | 中文 | Bahasa Melayu | English |
|---|---|---|---|
| nav.home | 首页 | Laman Utama | Home |
| nav.football | 足球 | Bola Sepak | Football |
| nav.my_bets | 我的投注 | Pertaruhan Saya | My Bets |
| auth.login | 登录 | Log Masuk | Login |
| auth.username | 账号 | Nama Pengguna | Username |
| wallet.balance | 余额 | Baki | Balance |
| bet.bet_slip | 投注单 | Slip Pertaruhan | Bet Slip |
| bet.stake | 投注金额 | Jumlah Pertaruhan | Stake |
| bet.place_bet | 确认下注 | Letak Pertaruhan | Place Bet |
| bet.parlay | 串关 | Pertaruhan Berganda | Accumulator |
| market.correct_score | 波胆 | Skor Tepat | Correct Score |
| market.ft_handicap | 全场让球 | Handicap Masa Penuh | Full Time Handicap |
| market.ft_over_under | 全场大/小 | Atas/Bawah Masa Penuh | Full Time Over/Under |
| market.ft_1x2 | 全场独赢盘 | 1X2 Masa Penuh | Full Time 1X2 |
| market.ft_odd_even | 全场单/双 | Ganjil/Genap Masa Penuh | Full Time Odd/Even |
| market.ht_handicap | 半场让球 | Handicap Separuh Masa | Half Time Handicap |
| market.ht_over_under | 半场大/小 | Atas/Bawah Separuh Masa | Half Time Over/Under |
| market.ht_1x2 | 半场独赢盘 | 1X2 Separuh Masa | Half Time 1X2 |
| error.odds_changed | 赔率已变化，请重新确认 | Odds telah berubah, sila sahkan semula | Odds changed, please confirm again |
| error.market_closed | 盘口已关闭 | Pasaran telah ditutup | Market closed |
| error.insufficient_balance | 余额不足 | Baki tidak mencukupi | Insufficient balance |

---

## 4. 前台 UI / UX 设计

### 4.1 总体风格

界面可参考成熟体育投注平台的信息架构：深色或高对比背景、清晰赛事分组、赔率按钮突出、右侧或底部投注单、快速查看余额、热门赛事与公告入口。

需要注意：参考的是**交互模式和信息组织方式**，不是复制 Bet365 的商标、Logo、图标、图片、文案或视觉资产。

### 4.2 移动端优先布局

第一版建议优先实现移动端 H5。

```mermaid
flowchart TD
    A[顶部栏: Logo/语言/余额] --> B[Banner]
    B --> C[公告走马灯]
    C --> D[体育类型: 足球]
    D --> E[联赛筛选]
    E --> F[赛事列表]
    F --> G[点击赔率加入投注单]
    G --> H[底部投注单浮层]
    H --> I[确认下注]
    I --> J[下注成功页]
```

底部导航建议：

| Tab | 内容 |
|---|---|
| 首页 | Banner、公告、热门赛事、今日赛事。 |
| 足球 | 联赛筛选、赛事列表、赛事详情。 |
| 投注单 | 当前已选择投注项，支持单关/串关。 |
| 我的投注 | 未结算、已结算、已取消注单。 |
| 我的 | 余额、账单、返水、改密码、语言。 |

### 4.3 桌面端布局

桌面端采用三栏结构：

| 区域 | 内容 |
|---|---|
| 左侧 | 体育类型、联赛、日期筛选。 |
| 中间 | 赛事列表、盘口赔率、赛事详情。 |
| 右侧 | 投注单、余额、快捷投注金额、最近投注。 |

### 4.4 首页模块

| 模块 | 第一版要求 |
|---|---|
| 顶部栏 | Logo、语言切换、登录/余额、我的投注入口。 |
| Banner | 后台配置图片、标题、跳转链接、排序、语言。 |
| 公告走马灯 | 后台配置，支持多语言，点击可查看详情。 |
| 热门赛事 | 后台可设为热门；按开赛时间排序。 |
| 今日赛事 | 默认展示当天可下注赛事。 |
| 联赛筛选 | 按联赛折叠/展开。 |
| 投注单入口 | 移动端固定底部浮层，显示已选数量。 |

### 4.5 赛事列表页

列表页只展示核心盘口，避免页面过长。

| 列表页展示 | 说明 |
|---|---|
| 全场独赢盘 | 主胜 / 平 / 客胜。 |
| 全场让球 | 主队 / 客队，两项。 |
| 全场大/小 | 大 / 小，两项。 |
| 更多盘口入口 | 点击进入赛事详情页展示全部玩法。 |

### 4.6 赛事详情页

赛事详情页按盘口分组展示：

1. 全场独赢盘
2. 全场让球
3. 全场大/小
4. 全场单/双
5. 半场独赢盘
6. 半场让球
7. 半场大/小
8. 波胆
9. 上半场波胆
10. 下半场波胆

每个盘口组支持折叠/展开。赔率按钮显示：选项名、盘口线、赔率。

### 4.7 投注单交互

| 场景 | 交互 |
|---|---|
| 用户点击赔率 | 加入投注单；同一场同一盘口重复点击则取消选择。 |
| 单个选择项 | 展示单关投注金额输入框。 |
| 多个选择项 | 展示每项单关输入 + 串关区域。MVP 可默认只打开串关输入。 |
| 同场多个选项 | 投注单提示“同一场比赛不能串关”，但可分别作为单关投注。 |
| 赔率变化 | 提交时校验赔率版本；变化则提示重新确认。 |
| 盘口封盘 | 提交时提示盘口已关闭并移除该选择项。 |
| 余额不足 | 禁止提交并提示余额不足。 |
| 下注成功 | 展示注单号、投注金额、赔率、预计返还、投注时间。 |

---

## 5. 赛事、盘口与赔率管理

### 5.1 赛事结构

```mermaid
flowchart LR
    A[体育类型: 足球] --> B[联赛]
    B --> C[比赛 Match]
    C --> D[盘口 Market]
    D --> E[选项 Selection]
    E --> F[赔率 Odds]
```

### 5.2 比赛字段

| 字段 | 说明 |
|---|---|
| match_id | 比赛 ID。 |
| sport_type | 第一版固定 `FOOTBALL`。 |
| league_id | 联赛 ID。 |
| home_team_id | 主队。 |
| away_team_id | 客队。 |
| start_time | 开赛时间。 |
| status | 比赛状态。 |
| is_hot | 是否热门。 |
| display_order | 排序。 |
| publish_time | 发布时间。 |
| close_time | 封盘时间。 |
| created_by / updated_by | 操作人。 |

### 5.3 比赛状态流

| 状态 | 说明 | 可操作 |
|---|---|---|
| DRAFT 草稿 | 后台创建中，前台不可见。 | 编辑赛事、赔率。 |
| PUBLISHED 已发布 | 前台可见且可下注。 | 编辑赔率、手动封盘。 |
| CLOSED 已封盘 | 前台可见但不可下注。 | 录入赛果。 |
| PENDING_SETTLEMENT 待结算 | 已录入比分，等待结算确认。 | 查看结算预览、确认结算。 |
| SETTLED 已结算 | 已派彩/扣款。 | 超级管理员可发起重结算。 |
| CANCELLED 已取消 | 比赛取消，相关未结算注单退款。 | 查看退款流水。 |
| VOID 作废 | 异常赛事，不参与结算。 | 查看操作记录。 |

### 5.4 自动封盘

1. 默认在 `start_time` 到达时自动封盘。
2. 后台可提前手动封盘。
3. 投注提交时必须二次校验比赛状态、盘口状态、选项状态、赔率版本。
4. 后台开赛时间修改后，需要重新计算封盘任务。

### 5.5 赔率管理规则

1. 所有赔率使用十进制赔率 Decimal Odds，例如 `1.85`、`2.10`。
2. 后台修改赔率时生成新的 `odds_version`。
3. 已下注订单使用投注时快照，不受后续赔率修改影响。
4. 赔率最低值、最高值后台配置，避免误填。
5. 赔率必须大于 `1.00`。
6. 已发布赛事修改赔率需二次确认。
7. 支持批量编辑波胆赔率，类似表格/Excel 输入。

---

## 6. 第一版支持的下注类型

### 6.1 玩法总表

| 编码 | 中文名称 | 英文建议名 | 结算依据 | 是否支持单关 | 是否支持串关 |
|---|---|---|---|---:|---:|
| `FT_CORRECT_SCORE` | 波胆 | Full Time Correct Score | 全场比分 | 是 | 是 |
| `HT_CORRECT_SCORE` | 上半场波胆 | Half Time Correct Score | 半场比分 | 是 | 是 |
| `SH_CORRECT_SCORE` | 下半场波胆 | Second Half Correct Score | 下半场净比分 | 是 | 是 |
| `FT_HANDICAP` | 全场让球 | Full Time Asian Handicap | 全场比分 + 让球 | 是 | 条件支持 |
| `FT_OVER_UNDER` | 全场大/小 | Full Time Over/Under | 全场总进球 | 是 | 条件支持 |
| `FT_1X2` | 全场独赢盘 | Full Time 1X2 | 全场胜平负 | 是 | 是 |
| `FT_ODD_EVEN` | 全场单/双 | Full Time Odd/Even | 全场总进球单双 | 是 | 是 |
| `HT_HANDICAP` | 半场让球 | Half Time Asian Handicap | 半场比分 + 让球 | 是 | 条件支持 |
| `HT_OVER_UNDER` | 半场大/小 | Half Time Over/Under | 半场总进球 | 是 | 条件支持 |
| `HT_1X2` | 半场独赢盘 | Half Time 1X2 | 半场胜平负 | 是 | 是 |
| `OUTRIGHT_WINNER` | 冠军竞猜 | Outright Winner | 后台选择冠军 | 是 | 否 |

串关条件支持说明：

1. 只支持 `2 串 1` 到 `5 串 1`。
2. 不允许同一场比赛的多个选项进入同一串关单。
3. 四分之一让球 / 四分之一大小球不允许进入串关，例如 `-0.25`、`-0.75`、`2.25`、`2.75`。
4. 冠军竞猜不允许进入串关。
5. 已封盘、暂停、赔率变化未确认的选项不能提交。

### 6.2 波胆

波胆即预测准确比分。

| 类型 | 结算依据 | 示例 |
|---|---|---|
| 全场波胆 | 全场比分，90 分钟 + 全场伤停补时，不含加时和点球。 | 2-1、1-1、其他主胜。 |
| 上半场波胆 | 上半场比分，45 分钟 + 上半场伤停补时。 | 1-0、0-0、2-1。 |
| 下半场波胆 | 下半场净比分，即全场比分减去半场比分。 | 半场 1-1，全场 3-1，则下半场比分为 2-0。 |

#### 6.2.1 波胆比分模板

为降低后台录入成本，第一版使用固定模板。

全场波胆建议模板：

| 分类 | 选项 |
|---|---|
| 平局 | 0-0、1-1、2-2、3-3、4-4、其他平局 |
| 主胜 | 1-0、2-0、2-1、3-0、3-1、3-2、4-0、4-1、4-2、4-3、其他主胜 |
| 客胜 | 0-1、0-2、1-2、0-3、1-3、2-3、0-4、1-4、2-4、3-4、其他客胜 |

半场 / 下半场波胆建议模板：

| 分类 | 选项 |
|---|---|
| 平局 | 0-0、1-1、2-2、其他平局 |
| 主胜 | 1-0、2-0、2-1、3-0、其他主胜 |
| 客胜 | 0-1、0-2、1-2、0-3、其他客胜 |

#### 6.2.2 “其他比分”结算规则

1. 如果最终比分命中模板中的具体比分，具体比分选项赢，其他比分选项输。
2. 如果最终比分不在模板具体比分中，则按结果归类：
   - 主队胜且不在具体比分中：其他主胜赢。
   - 客队胜且不在具体比分中：其他客胜赢。
   - 平局且不在具体比分中：其他平局赢。

### 6.3 全场让球 / 半场让球

让球采用亚洲让球两项盘。

| 项目 | 规则 |
|---|---|
| 全场让球 | 使用全场比分结算。 |
| 半场让球 | 使用半场比分结算。 |
| 盘口值 | 支持整数、半球、四分之一球。 |
| 单关 | 支持全赢、半赢、走水、半输、全输。 |
| 串关 | 第一版只允许整数和半球盘口进入串关；四分之一球不允许串关。 |

盘口值示例：`0`、`-0.25`、`-0.5`、`-0.75`、`-1`、`+0.25`、`+0.5`、`+0.75`、`+1`。

让球结算公式：

```text
adjusted_score = selected_team_goals + handicap - opponent_goals

adjusted_score > 0  => 赢
adjusted_score = 0  => 走水
adjusted_score < 0  => 输
```

四分之一球拆分规则：

| 盘口 | 拆分为 |
|---|---|
| -0.25 | 0 和 -0.5 |
| +0.25 | 0 和 +0.5 |
| -0.75 | -0.5 和 -1 |
| +0.75 | +0.5 和 +1 |
| -1.25 | -1 和 -1.5 |
| +1.25 | +1 和 +1.5 |
| -1.75 | -1.5 和 -2 |
| +1.75 | +1.5 和 +2 |

### 6.4 全场大/小 / 半场大/小

| 项目 | 规则 |
|---|---|
| 全场大/小 | 使用全场总进球数。 |
| 半场大/小 | 使用半场总进球数。 |
| 盘口值 | 支持整数、半球、四分之一球。 |
| 单关 | 支持全赢、半赢、走水、半输、全输。 |
| 串关 | 第一版只允许整数和半球盘口进入串关；四分之一球不允许串关。 |

大小球结算示例：

| 盘口 | 选择 | 实际总进球 | 结果 |
|---|---|---:|---|
| 2.5 | 大 | 3 | 赢 |
| 2.5 | 小 | 3 | 输 |
| 2 | 大 | 2 | 走水 |
| 2.25 | 大 | 2 | 半输 |
| 2.75 | 大 | 3 | 半赢 |

四分之一大小球拆分规则：

| 盘口 | 拆分为 |
|---|---|
| 2.25 | 2 和 2.5 |
| 2.75 | 2.5 和 3 |
| 3.25 | 3 和 3.5 |
| 3.75 | 3.5 和 4 |

### 6.5 全场独赢盘 / 半场独赢盘

独赢盘采用足球三项盘：

| 选项 | 说明 |
|---|---|
| 主胜 | 主队进球数大于客队。 |
| 平局 | 主队进球数等于客队。 |
| 客胜 | 主队进球数小于客队。 |

全场独赢盘使用全场比分；半场独赢盘使用半场比分。

### 6.6 全场单/双

全场单/双按全场总进球数判断。

| 总进球 | 结果 |
|---:|---|
| 0 | 双 |
| 1 | 单 |
| 2 | 双 |
| 3 | 单 |
| 4 | 双 |

### 6.7 冠军竞猜

冠军竞猜作为特殊长期盘实现。

| 项目 | 第一版规则 |
|---|---|
| 类型 | 特殊赛事 / 长期盘。 |
| 玩法 | 只支持选择冠军队伍。 |
| 赔率 | 后台手动维护。 |
| 封盘 | 后台手动封盘或到达配置时间自动封盘。 |
| 开奖 | 后台选择冠军队伍，生成结算预览，确认后派彩。 |
| 串关 | 第一版不允许串关。 |
| 取消 | 后台可整盘取消，未结算注单退还本金。 |

---

## 7. 单关下注逻辑

### 7.1 单关注单流程

```mermaid
sequenceDiagram
    participant U as 玩家
    participant FE as 前台
    participant API as 后端API
    participant DB as 数据库

    U->>FE: 选择赔率
    FE->>FE: 加入投注单
    U->>FE: 输入金额并确认下注
    FE->>API: 提交投注(selection_id, odds_version, stake, request_id)
    API->>DB: 开启事务
    API->>DB: 校验用户状态/余额/盘口状态/赔率版本/限额
    API->>DB: 冻结投注本金
    API->>DB: 创建注单和账变流水
    API->>DB: 提交事务
    API-->>FE: 返回下注成功
    FE-->>U: 显示注单号和详情
```

### 7.2 投注校验

提交下注时后端必须校验：

1. 玩家账号状态为正常。
2. 玩家所属代理链状态正常。
3. 比赛状态为已发布且未封盘。
4. 盘口状态为开放。
5. 选项状态为开放。
6. 前端提交的 `odds_version` 与数据库当前版本一致。
7. 投注金额满足最小/最大单注限制。
8. 玩家可用余额足够。
9. 不超过玩家每日投注限额。
10. 不超过盘口单项最大投注额。
11. 不超过平台单注最高预计派彩。
12. 请求幂等号 `request_id` 未被使用。

### 7.3 赔率变化处理

第一版采用严格校验方式：

| 情况 | 处理 |
|---|---|
| 赔率未变化 | 正常下注。 |
| 赔率已变化 | 拒绝下注，返回最新赔率，提示玩家重新确认。 |
| 盘口已封盘 | 拒绝下注，从投注单移除。 |
| 选项已暂停 | 拒绝下注，提示该选项不可下注。 |

### 7.4 投注金额与预计返还

十进制赔率下：

```text
预计返还 = 投注金额 × 赔率
预计盈利 = 投注金额 × (赔率 - 1)
```

示例：投注 100，赔率 1.85。

```text
预计返还 = 100 × 1.85 = 185
预计盈利 = 100 × 0.85 = 85
```

---

## 8. 串关玩法设计

### 8.1 第一版支持范围

| 项目 | 规则 |
|---|---|
| 串关类型 | 只支持 `2 串 1`、`3 串 1`、`4 串 1`、`5 串 1`。 |
| 系统串关 | 不支持。 |
| 同场串关 | 不支持。 |
| 最大串关场数 | 5 场。 |
| 最小串关场数 | 2 场。 |
| 冠军竞猜 | 不允许进入串关。 |
| 四分之一让球/大小球 | 不允许进入串关。 |
| 赔率 | 下单时锁定每个选项赔率。 |
| 结算 | 所有关联赛事结算后，系统自动结算串关。 |

### 8.2 串关可选盘口

| 玩法 | 是否可串 | 备注 |
|---|---:|---|
| 全场独赢盘 | 是 | 主胜/平/客胜。 |
| 半场独赢盘 | 是 | 主胜/平/客胜。 |
| 全场单/双 | 是 | 单/双。 |
| 波胆 | 是 | 高赔率，需受最高派彩限制。 |
| 上半场波胆 | 是 | 高赔率，需受最高派彩限制。 |
| 下半场波胆 | 是 | 高赔率，需受最高派彩限制。 |
| 全场让球 | 条件支持 | 仅整数、半球盘口可串。 |
| 半场让球 | 条件支持 | 仅整数、半球盘口可串。 |
| 全场大/小 | 条件支持 | 仅整数、半球盘口可串。 |
| 半场大/小 | 条件支持 | 仅整数、半球盘口可串。 |
| 冠军竞猜 | 否 | 长期盘，不进入第一版串关。 |

### 8.3 同场串关限制

同一张串关单中，不允许出现相同 `match_id` 的多个选择项。

示例：以下组合不允许作为串关：

| 赛事 | 选择项 |
|---|---|
| 曼联 vs 切尔西 | 曼联胜 |
| 曼联 vs 切尔西 | 全场大 2.5 |

原因：同一场比赛的不同盘口存在强相关性，第一版先禁止。

### 8.4 串关计算

如果所有选择项赢：

```text
串关返还 = 投注金额 × 赔率1 × 赔率2 × ... × 赔率N
串关盈利 = 串关返还 - 投注金额
```

如果任意一关输：

```text
串关注单 = 输
返还 = 0
```

如果某一关走水 / 取消 / 作废：

```text
该关赔率按 1.00 计算，其余关继续结算
```

如果所有关都走水 / 取消 / 作废：

```text
整张串关注单退还本金
```

示例：

| 关数 | 原赔率 | 结果 | 有效赔率 |
|---:|---:|---|---:|
| 1 | 1.80 | 赢 | 1.80 |
| 2 | 2.00 | 走水 | 1.00 |
| 3 | 1.90 | 赢 | 1.90 |

投注 100：

```text
返还 = 100 × 1.80 × 1.00 × 1.90 = 342
```

### 8.5 串关限制配置

后台需支持以下配置：

| 配置项 | 建议默认值 |
|---|---:|
| 最小串关数量 | 2 |
| 最大串关数量 | 5 |
| 单张串关最低投注额 | 1 |
| 单张串关最高投注额 | 视币种配置 |
| 单张串关最高派彩金额 | 视币种配置 |
| 玩家每日串关投注上限 | 视运营配置 |
| 玩家每日串关派彩上限 | 视运营配置 |
| 是否允许波胆串关 | 默认允许，但受派彩上限限制 |
| 是否允许同场串关 | 默认关闭 |
| 是否允许四分之一球串关 | 默认关闭 |

---

## 9. 结算规则

### 9.1 比分口径

| 类型 | 口径 |
|---|---|
| 全场比分 | 90 分钟 + 全场伤停补时，不含加时赛和点球大战。 |
| 半场比分 | 上半场 45 分钟 + 上半场伤停补时。 |
| 下半场比分 | 全场比分 - 半场比分。 |
| 冠军竞猜 | 后台选择的最终冠军队伍。 |

### 9.2 单关结算状态

| 状态 | 说明 | 返还公式 |
|---|---|---|
| WIN 全赢 | 下注选项完全赢 | `stake × odds` |
| HALF_WIN 半赢 | 四分之一球出现半赢 | `stake/2 × odds + stake/2` |
| PUSH 走水 | 盘口打平 | `stake` |
| HALF_LOSE 半输 | 四分之一球出现半输 | `stake/2` |
| LOSE 全输 | 下注选项输 | `0` |
| VOID 作废 | 比赛/盘口取消 | `stake` |

### 9.3 结算流程

```mermaid
flowchart TD
    A[管理员进入赛事结算页] --> B[录入半场比分]
    B --> C[录入全场比分]
    C --> D[点击生成结算预览]
    D --> E[系统计算所有相关单关选择项]
    E --> F[系统计算受影响串关]
    F --> G[展示注单数量/应扣/应派/退款/异常]
    G --> H{管理员确认?}
    H -- 否 --> I[返回修改比分或取消]
    H -- 是 --> J[系统事务入账]
    J --> K[更新注单状态]
    K --> L[生成账变流水]
    L --> M[更新玩家钱包]
    M --> N[更新代理额度占用]
    N --> O[生成结算日志]
```

### 9.4 结算预览

确认入账前必须展示：

| 指标 | 说明 |
|---|---|
| 比赛信息 | 联赛、主队、客队、开赛时间。 |
| 录入比分 | 半场比分、全场比分、自动计算下半场比分。 |
| 待结算单关注单数 | 本场相关单关数量。 |
| 待更新串关注单数 | 因本场结果影响的串关数量。 |
| 全赢金额 | 预计派彩金额。 |
| 输单金额 | 平台扣除本金金额。 |
| 走水/作废退款金额 | 需返还本金。 |
| 半赢/半输金额 | 四分之一盘口影响。 |
| 异常项 | 无赔率快照、注单状态异常、重复结算风险。 |
| 操作人 | 当前管理员。 |

### 9.5 重结算与冲正

如果比分录错或结算错误，允许超级管理员重结算。

重结算规则：

1. 不允许直接改余额。
2. 必须生成反向冲正账变。
3. 必须保留原结算记录和新结算记录。
4. 必须记录操作原因。
5. 重结算前生成影响预览：影响玩家数、注单数、需扣回金额、需补发金额。
6. 如果玩家余额不足以扣回，应形成负余额或异常待处理；MVP 默认允许负余额展示并冻结提现/下分。

---

## 10. 钱包、账变与代理额度

### 10.1 玩家钱包

玩家钱包字段：

| 字段 | 说明 |
|---|---|
| available_balance | 可用余额，可下注金额。 |
| frozen_balance | 冻结金额，未结算投注本金。 |
| total_balance | 总余额 = 可用余额 + 冻结金额。 |
| currency | 币种。 |
| status | 正常、冻结、禁用。 |

下注时：

```text
available_balance -= stake
frozen_balance += stake
```

结算赢：

```text
frozen_balance -= stake
available_balance += payout
```

结算输：

```text
frozen_balance -= stake
available_balance += 0
```

走水/作废：

```text
frozen_balance -= stake
available_balance += stake
```

### 10.2 账变流水类型

| 类型 | 说明 | 余额影响 |
|---|---|---|
| MANUAL_DEPOSIT | 后台/代理上分 | 增加可用余额。 |
| MANUAL_WITHDRAW | 后台/代理下分 | 减少可用余额。 |
| BET_FREEZE | 投注冻结 | 可用减少、冻结增加。 |
| BET_SETTLE_WIN | 赢单派彩 | 冻结减少、可用增加派彩金额。 |
| BET_SETTLE_LOSE | 输单扣除 | 冻结减少。 |
| BET_SETTLE_PUSH | 走水退回 | 冻结减少、可用增加本金。 |
| BET_VOID_REFUND | 作废退款 | 冻结减少、可用增加本金。 |
| CASHBACK | 玩家返水 | 增加可用余额。 |
| RESETTLE_REVERSE | 重结算冲正 | 按冲正方向变化。 |
| MANUAL_ADJUST | 人工调整 | 仅超级管理员，必须备注。 |

账变流水必须包含：

- `transaction_id`
- `user_id`
- `wallet_id`
- `transaction_type`
- `amount`
- `balance_before`
- `balance_after`
- `frozen_before`
- `frozen_after`
- `reference_type`
- `reference_id`
- `operator_id`
- `remark`
- `created_at`

### 10.3 代理额度模型

第一版采用信用额度池，不把代理额度等同于真实资金账户。

核心字段：

| 字段 | 说明 |
|---|---|
| credit_limit | 上级授予该代理的总额度。 |
| used_credit | 已占用额度。 |
| available_credit | 可用额度 = credit_limit - used_credit。 |
| direct_player_liability | 直属玩家总余额占用。 |
| child_agent_exposure | 下级代理占用。 |
| status | 正常、额度不足、冻结、禁用。 |

推荐公式：

```text
agent_used_credit = direct_player_total_balance + child_agent_exposure
agent_available_credit = agent_credit_limit - agent_used_credit

child_agent_exposure = max(child_agent_credit_limit, child_agent_used_credit)
```

解释：

1. 代理给玩家上分，玩家总余额增加，代理额度被占用。
2. 玩家下注时，可用余额变成冻结金额，总余额不变，因此代理额度不变。
3. 玩家输掉，玩家总余额减少，代理额度释放。
4. 玩家赢了，玩家总余额增加，代理额度进一步占用。
5. 代理给下级代理分配额度，会占用自己的额度。
6. 如果下级代理因玩家赢钱导致实际占用超过其授信额度，上级看到的下级占用按更大的实际占用计算。
7. 代理额度可以显示为负数，但负数时禁止继续上分或继续给下级分配额度。

### 10.4 代理额度示例

平台给一级代理 A 授信 10,000。

| 动作 | A 可用额度变化 |
|---|---:|
| 初始 | 10,000 |
| A 给玩家 P 上分 1,000 | 9,000 |
| A 给二级代理 B 分配额度 3,000 | 6,000 |
| P 下注 500 未结算 | 6,000，总余额不变 |
| P 输掉 500 | 6,500，玩家余额减少 |
| P 赢 2,000 | 4,500，玩家余额增加 |
| B 名下玩家赢钱导致 B 实际占用 4,000 | A 可用额度减少为 3,500，因为 B 实际占用超过授信 3,000 |

### 10.5 上分/下分规则

| 场景 | 规则 |
|---|---|
| 平台给玩家上分 | 超级管理员/财务管理员可操作，直接入账并生成流水。 |
| 代理给直属玩家上分 | 受代理可用额度、单笔限额、日限额限制。 |
| 代理给玩家下分 | 只能操作直属玩家；玩家可用余额必须足够。 |
| 平台给代理授信 | 增加代理 `credit_limit`。 |
| 代理给下级代理分配额度 | 增加下级 `credit_limit`，占用本级额度。 |
| 回收下级代理额度 | 下级实际占用不能超过回收后的额度，否则禁止回收或提示会导致负额度。 |

---

## 11. 返水机制

### 11.1 第一版返水策略

第一版只做玩家返水，不做自动代理佣金。

| 项目 | 规则 |
|---|---|
| 计算方式 | 按有效投注额 × 返水比例。 |
| 发放方式 | 后台生成返水报表，管理员确认后入账。 |
| 配置维度 | 可按玩家、代理线、玩法类型设置返水比例。MVP 可先按玩家或代理线配置。 |
| 发放周期 | 日结或周结，后台可选时间范围。 |
| 入账方式 | 生成 `CASHBACK` 账变流水，增加玩家可用余额。 |

### 11.2 有效投注额口径

计入有效投注额：

1. 已结算且非作废注单。
2. 赢单、输单、半赢、半输均按原始投注金额计入。
3. 串关注单按串关本金计入一次。

不计入有效投注额：

1. 未结算注单。
2. 已取消注单。
3. 作废退款注单。
4. 全走水注单。
5. 重结算冲正流水本身。

### 11.3 返水批次流程

```mermaid
flowchart LR
    A[选择周期] --> B[系统统计有效投注额]
    B --> C[生成返水预览]
    C --> D[财务确认]
    D --> E[生成返水批次]
    E --> F[逐玩家入账]
    F --> G[生成账变流水]
    G --> H[玩家前台查看返水记录]
```

---

## 12. 后台管理功能

### 12.1 平台后台模块

| 模块 | 功能 |
|---|---|
| 控制台 | 今日投注额、派彩额、平台盈亏、待结算赛事、异常注单、代理额度预警。 |
| 用户管理 | 玩家列表、新增玩家、禁用/启用、重置密码、查看钱包、查看注单、查看账变。 |
| 代理管理 | 新增代理、代理层级树、授信额度、回收额度、代理报表、禁用代理。 |
| 财务管理 | 上分、下分、账变流水、额度流水、人工调整、导出报表。 |
| 赛事管理 | 联赛、球队、比赛、开赛时间、热门标记、发布/封盘/取消。 |
| 盘口管理 | 为比赛启用玩法模板、录入盘口值、录入赔率、批量修改。 |
| 开奖结算 | 录入半场/全场比分、生成预览、确认结算、查看结算日志、重结算。 |
| 注单管理 | 单关注单、串关注单、按玩家/代理/赛事/状态筛选。 |
| 返水管理 | 返水比例配置、生成返水批次、确认发放、返水记录。 |
| 内容管理 | Banner、公告、走马灯、多语言内容、排序、上下架。 |
| 多语言管理 | 语言包 key、翻译缺失检查、导入导出。 |
| 系统设置 | 限额配置、赔率范围、串关规则、币种、小数位、时区。 |
| 操作日志 | 查询所有后台、代理后台关键操作记录。 |

### 12.2 赛事创建流程

```mermaid
flowchart TD
    A[创建联赛/选择联赛] --> B[创建比赛]
    B --> C[选择主队/客队]
    C --> D[设置开赛时间]
    D --> E[选择玩法模板]
    E --> F[系统生成盘口结构]
    F --> G[批量录入赔率]
    G --> H[保存草稿]
    H --> I[发布比赛]
```

### 12.3 盘口模板

后台创建比赛时，建议提供一键生成模板：

| 模板 | 自动生成内容 |
|---|---|
| 全场独赢盘 | 主胜、平局、客胜。 |
| 半场独赢盘 | 主胜、平局、客胜。 |
| 全场让球 | 主队、客队，需填写盘口值和赔率。 |
| 半场让球 | 主队、客队，需填写盘口值和赔率。 |
| 全场大/小 | 大、小，需填写盘口线和赔率。 |
| 半场大/小 | 大、小，需填写盘口线和赔率。 |
| 全场单/双 | 单、双。 |
| 波胆 | 按固定比分模板生成选项。 |
| 上半场波胆 | 按半场比分模板生成选项。 |
| 下半场波胆 | 按半场比分模板生成选项。 |
| 冠军竞猜 | 批量添加参赛队伍。 |

### 12.4 高危操作二次确认

以下操作必须二次确认并写入操作日志：

1. 大额上分/下分。
2. 代理额度调整。
3. 已发布赛事修改开赛时间。
4. 已发布赛事修改赔率。
5. 手动封盘。
6. 取消赛事。
7. 确认结算。
8. 发起重结算。
9. 发放返水批次。
10. 禁用代理或玩家。

---

## 13. 数据库设计建议

### 13.1 核心表清单

| 表名 | 说明 |
|---|---|
| `users` | 用户基础表，包含玩家、代理、后台用户。 |
| `user_auth` | 登录账号、密码哈希、登录失败次数、最后登录。 |
| `roles` / `permissions` | 后台角色权限。 |
| `agent_profiles` | 代理资料、层级、上级、额度。 |
| `agent_closure` | 代理树闭包表，便于查询下级。 |
| `wallets` | 玩家钱包。 |
| `wallet_transactions` | 玩家账变流水。 |
| `agent_credit_transactions` | 代理额度流水。 |
| `leagues` | 联赛。 |
| `teams` | 球队。 |
| `matches` | 比赛。 |
| `match_scores` | 半场、全场、下半场比分。 |
| `market_types` | 玩法类型配置。 |
| `markets` | 比赛下的盘口。 |
| `market_selections` | 盘口选项。 |
| `odds_change_logs` | 赔率变更日志。 |
| `bets` | 注单主表，单关和串关。 |
| `bet_selections` | 注单明细，每个选择项一行。 |
| `settlement_batches` | 结算批次。 |
| `settlement_items` | 结算明细。 |
| `cashback_rules` | 返水规则。 |
| `cashback_batches` | 返水批次。 |
| `cashback_items` | 玩家返水明细。 |
| `contents` | Banner、公告、走马灯。 |
| `content_translations` | 内容多语言。 |
| `entity_translations` | 联赛、球队、赛事多语言名称。 |
| `i18n_messages` | 系统语言包。 |
| `audit_logs` | 操作日志。 |

### 13.2 注单主表关键字段

```sql
CREATE TABLE bets (
  id BIGINT PRIMARY KEY,
  bet_no VARCHAR(64) NOT NULL UNIQUE,
  user_id BIGINT NOT NULL,
  agent_id BIGINT,
  bet_type VARCHAR(20) NOT NULL, -- SINGLE / PARLAY
  stake DECIMAL(18, 4) NOT NULL,
  total_odds DECIMAL(18, 6),
  potential_return DECIMAL(18, 4),
  actual_return DECIMAL(18, 4) DEFAULT 0,
  status VARCHAR(32) NOT NULL, -- PENDING / WON / LOST / PUSH / VOID / CANCELLED / SETTLED
  settlement_status VARCHAR(32),
  currency VARCHAR(16) NOT NULL,
  request_id VARCHAR(128) NOT NULL,
  placed_at TIMESTAMP NOT NULL,
  settled_at TIMESTAMP,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL,
  UNIQUE(user_id, request_id)
);
```

### 13.3 注单明细表关键字段

```sql
CREATE TABLE bet_selections (
  id BIGINT PRIMARY KEY,
  bet_id BIGINT NOT NULL,
  match_id BIGINT,
  market_id BIGINT NOT NULL,
  selection_id BIGINT NOT NULL,
  market_type VARCHAR(64) NOT NULL,
  period VARCHAR(16), -- FT / HT / SH / OUTRIGHT
  selection_name_snapshot VARCHAR(255) NOT NULL,
  handicap_line DECIMAL(8, 2),
  total_line DECIMAL(8, 2),
  odds DECIMAL(18, 6) NOT NULL,
  odds_version BIGINT NOT NULL,
  result_status VARCHAR(32), -- WIN / HALF_WIN / PUSH / HALF_LOSE / LOSE / VOID
  effective_odds DECIMAL(18, 6),
  sort_order INT,
  created_at TIMESTAMP NOT NULL
);
```

### 13.4 市场与选项字段

`markets`：

| 字段 | 说明 |
|---|---|
| id | 盘口 ID。 |
| match_id | 所属比赛。 |
| market_type | 玩法类型。 |
| period | FT / HT / SH / OUTRIGHT。 |
| line_value | 让球线或大小球线，可为空。 |
| status | OPEN / SUSPENDED / CLOSED。 |
| allow_single | 是否允许单关。 |
| allow_parlay | 是否允许串关。 |
| sort_order | 排序。 |

`market_selections`：

| 字段 | 说明 |
|---|---|
| id | 选项 ID。 |
| market_id | 所属盘口。 |
| selection_code | HOME / DRAW / AWAY / OVER / UNDER / ODD / EVEN / SCORE_2_1 等。 |
| selection_name | 默认名称。 |
| odds | 当前赔率。 |
| odds_version | 当前赔率版本。 |
| status | OPEN / SUSPENDED / CLOSED。 |

---

## 14. API 范围建议

### 14.1 玩家前台 API

| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/player/auth/login` | 玩家登录。 |
| POST | `/api/player/auth/logout` | 退出登录。 |
| POST | `/api/player/auth/change-password` | 修改密码。 |
| GET | `/api/player/profile` | 玩家资料、余额、语言。 |
| POST | `/api/player/language` | 切换语言。 |
| GET | `/api/player/home` | 首页 Banner、公告、热门赛事。 |
| GET | `/api/player/matches` | 赛事列表。 |
| GET | `/api/player/matches/{id}` | 赛事详情和全部盘口。 |
| POST | `/api/player/bets/single` | 提交单关注单。 |
| POST | `/api/player/bets/parlay` | 提交串关注单。 |
| GET | `/api/player/bets` | 我的投注列表。 |
| GET | `/api/player/bets/{bet_no}` | 注单详情。 |
| GET | `/api/player/wallet/transactions` | 账变流水。 |
| GET | `/api/player/cashbacks` | 返水记录。 |

### 14.2 平台后台 API

| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/admin/auth/login` | 后台登录。 |
| GET | `/api/admin/dashboard` | 控制台指标。 |
| GET/POST | `/api/admin/users` | 玩家/用户管理。 |
| POST | `/api/admin/users/{id}/reset-password` | 重置密码。 |
| GET/POST | `/api/admin/agents` | 代理管理。 |
| POST | `/api/admin/agents/{id}/credit` | 调整代理额度。 |
| POST | `/api/admin/wallet/deposit` | 玩家上分。 |
| POST | `/api/admin/wallet/withdraw` | 玩家下分。 |
| GET | `/api/admin/wallet/transactions` | 账变查询。 |
| GET/POST | `/api/admin/leagues` | 联赛管理。 |
| GET/POST | `/api/admin/teams` | 球队管理。 |
| GET/POST | `/api/admin/matches` | 比赛管理。 |
| POST | `/api/admin/matches/{id}/publish` | 发布比赛。 |
| POST | `/api/admin/matches/{id}/close` | 封盘。 |
| POST | `/api/admin/matches/{id}/cancel` | 取消比赛。 |
| POST | `/api/admin/matches/{id}/markets/templates` | 生成盘口模板。 |
| PUT | `/api/admin/markets/{id}` | 更新盘口。 |
| PUT | `/api/admin/selections/{id}/odds` | 更新赔率。 |
| POST | `/api/admin/matches/{id}/settlement/preview` | 生成结算预览。 |
| POST | `/api/admin/matches/{id}/settlement/confirm` | 确认结算。 |
| POST | `/api/admin/matches/{id}/resettle/preview` | 重结算预览。 |
| POST | `/api/admin/matches/{id}/resettle/confirm` | 确认重结算。 |
| GET | `/api/admin/bets` | 注单查询。 |
| POST | `/api/admin/cashbacks/preview` | 返水预览。 |
| POST | `/api/admin/cashbacks/confirm` | 确认发放返水。 |
| GET/POST | `/api/admin/contents` | Banner、公告、走马灯。 |
| GET/POST | `/api/admin/i18n/messages` | 语言包管理。 |
| GET | `/api/admin/audit-logs` | 操作日志。 |

### 14.3 代理后台 API

| 方法 | 路径 | 说明 |
|---|---|---|
| POST | `/api/agent/auth/login` | 代理登录。 |
| GET | `/api/agent/profile` | 代理资料和额度。 |
| GET/POST | `/api/agent/players` | 直属玩家管理。 |
| GET/POST | `/api/agent/agents` | 下级代理管理，一级代理可用。 |
| POST | `/api/agent/players/{id}/deposit` | 给直属玩家上分。 |
| POST | `/api/agent/players/{id}/withdraw` | 给直属玩家下分。 |
| POST | `/api/agent/agents/{id}/credit` | 给直属下级代理分配额度。 |
| GET | `/api/agent/bets` | 下级注单查询。 |
| GET | `/api/agent/reports/summary` | 代理汇总报表。 |
| GET | `/api/agent/wallet-transactions` | 直属玩家账变查询。 |

---

## 15. 幂等、事务与并发控制

### 15.1 必须幂等的操作

| 操作 | 幂等 Key |
|---|---|
| 单关下注 | `user_id + request_id` |
| 串关下注 | `user_id + request_id` |
| 玩家上分 | `operator_id + external_ref/request_id` |
| 玩家下分 | `operator_id + external_ref/request_id` |
| 代理额度调整 | `operator_id + request_id` |
| 确认结算 | `match_id + settlement_batch_id` |
| 重结算 | `match_id + resettle_batch_id` |
| 发放返水 | `cashback_batch_id` |

### 15.2 下注事务要求

下注必须在单个数据库事务内完成：

1. 锁定玩家钱包行。
2. 校验余额。
3. 校验比赛/盘口/选项状态。
4. 校验赔率版本。
5. 创建注单。
6. 创建注单明细。
7. 扣减可用余额、增加冻结金额。
8. 创建账变流水。
9. 提交事务。

### 15.3 结算事务要求

确认结算建议按批处理执行，但每批必须保证一致性：

1. 锁定待结算注单。
2. 防止重复结算。
3. 计算返还金额。
4. 更新注单状态。
5. 更新钱包余额。
6. 生成账变流水。
7. 更新代理额度统计。
8. 写入结算日志。

---

## 16. 报表需求

### 16.1 平台报表

| 报表 | 维度 |
|---|---|
| 平台投注汇总 | 日期、玩法、联赛、代理线、币种。 |
| 平台盈亏报表 | 投注额、派彩额、返水额、平台净盈亏。 |
| 待结算报表 | 比赛、开赛时间、待结算注单数、预估风险。 |
| 玩家报表 | 玩家余额、投注额、输赢、返水、上分/下分。 |
| 代理报表 | 代理额度、可用额度、下级余额、下级投注额、下级输赢。 |
| 盘口报表 | 每场比赛每个盘口投注分布。 |
| 串关报表 | 串关投注额、派彩额、最高风险。 |
| 账变报表 | 所有余额变动流水。 |

### 16.2 代理报表

代理后台至少展示：

1. 当前总额度。
2. 已用额度。
3. 可用额度。
4. 直属玩家总余额。
5. 下级代理额度占用。
6. 今日投注额。
7. 今日派彩额。
8. 今日玩家输赢。
9. 下级玩家注单列表。
10. 上分/下分记录。

### 16.3 玩家报表

玩家前台展示：

1. 当前余额。
2. 未结算投注。
3. 已结算投注。
4. 赢/输/走水/作废状态。
5. 账变流水。
6. 返水记录。

---

## 17. 内容管理

### 17.1 Banner

字段：

| 字段 | 说明 |
|---|---|
| title | 标题，多语言。 |
| image_url | 图片，多语言可不同。 |
| link_type | 无跳转、赛事、公告、外链。 |
| link_target | 跳转目标。 |
| start_time / end_time | 展示时间。 |
| status | 草稿、启用、停用。 |
| sort_order | 排序。 |

### 17.2 走马灯 / 公告

| 类型 | 说明 |
|---|---|
| 走马灯 | 首页顶部滚动短文案。 |
| 公告 | 可点击查看详情的完整内容。 |
| 系统通知 | 维护、封盘、活动等提示。 |

公告必须支持三语内容。

---

## 18. 系统配置

### 18.1 投注限额配置

| 配置 | 维度 |
|---|---|
| 最小单注金额 | 全局 / 玩家等级 / 玩法。 |
| 最大单注金额 | 全局 / 玩家等级 / 玩法。 |
| 单张最高派彩 | 全局 / 玩法 / 串关。 |
| 玩家每日投注上限 | 玩家 / 代理线。 |
| 玩家每日派彩上限 | 玩家 / 代理线。 |
| 串关最小/最大场数 | 全局。 |
| 波胆最高派彩 | 玩法级。 |
| 赔率最小/最大值 | 全局。 |

### 18.2 账号安全配置

| 配置 | 建议默认值 |
|---|---:|
| 玩家登录失败锁定次数 | 5 次。 |
| 玩家锁定时长 | 15 分钟。 |
| 后台登录失败锁定次数 | 5 次。 |
| 后台二次验证 | 建议开启 Google Authenticator 或 IP 白名单。 |
| 密码最小长度 | 8 位。 |
| 密码复杂度 | 至少字母 + 数字。 |
| 会话过期 | 玩家 24 小时，后台 2 小时。 |

---

## 19. 测试用例重点

### 19.1 下注测试

| 编号 | 场景 | 预期 |
|---|---|---|
| B001 | 正常单关下注 | 创建注单、冻结本金、生成账变。 |
| B002 | 余额不足下注 | 拒绝下注，不生成注单。 |
| B003 | 赔率变化后提交 | 拒绝下注，提示重新确认。 |
| B004 | 封盘后提交 | 拒绝下注。 |
| B005 | 重复点击提交 | 只生成一张注单。 |
| B006 | 串关 2 串 1 正常提交 | 创建串关注单和多个明细。 |
| B007 | 串关包含同场多个选择项 | 拒绝提交。 |
| B008 | 串关包含四分之一球 | 拒绝提交。 |
| B009 | 串关超过 5 场 | 拒绝提交。 |
| B010 | 冠军竞猜加入串关 | 拒绝提交。 |

### 19.2 结算测试

| 编号 | 场景 | 预期 |
|---|---|---|
| S001 | 全场独赢主胜 | 主胜注单赢，平/客输。 |
| S002 | 全场独赢平局 | 平局注单赢。 |
| S003 | 半场独赢 | 按半场比分结算。 |
| S004 | 全场单双 0-0 | 双赢。 |
| S005 | 全场波胆命中 2-1 | 2-1 赢，其他输。 |
| S006 | 全场波胆其他主胜 | 具体比分未列且主胜，其他主胜赢。 |
| S007 | 上半场波胆 | 按半场比分结算。 |
| S008 | 下半场波胆 | 按全场减半场后的净比分结算。 |
| S009 | 让球全赢 | 返还 stake × odds。 |
| S010 | 让球走水 | 退回本金。 |
| S011 | 让球半赢 | 返还 stake/2 × odds + stake/2。 |
| S012 | 让球半输 | 返还 stake/2。 |
| S013 | 大小球全赢 | 正确派彩。 |
| S014 | 大小球走水 | 退回本金。 |
| S015 | 大小球半赢/半输 | 正确拆分。 |
| S016 | 串关全中 | 按赔率连乘派彩。 |
| S017 | 串关一关输 | 整单输。 |
| S018 | 串关一关走水 | 该关赔率按 1.00。 |
| S019 | 串关全部走水 | 退回本金。 |
| S020 | 比赛取消 | 未结算注单退款。 |
| S021 | 重结算 | 生成冲正流水并更新新结果。 |

### 19.3 代理额度测试

| 编号 | 场景 | 预期 |
|---|---|---|
| A001 | 代理给玩家上分 | 玩家余额增加，代理可用额度减少。 |
| A002 | 玩家下注未结算 | 玩家总余额不变，代理额度不变。 |
| A003 | 玩家输单 | 玩家总余额减少，代理额度释放。 |
| A004 | 玩家赢单 | 玩家总余额增加，代理额度占用增加。 |
| A005 | 代理额度为负 | 禁止继续上分和分配下级额度。 |
| A006 | 一级代理给二级代理分额 | 一级代理可用额度减少。 |
| A007 | 非直属玩家上分 | 拒绝操作。 |

### 19.4 多语言测试

| 编号 | 场景 | 预期 |
|---|---|---|
| L001 | 切换中文 | 所有系统文案显示中文。 |
| L002 | 切换马来语 | 前台文案显示 Bahasa Melayu。 |
| L003 | 切换英文 | 前台文案显示英文。 |
| L004 | 球队名缺少马来语 | fallback 到英文或中文。 |
| L005 | Banner 不同语言图片 | 按当前语言展示正确图片。 |

---

## 20. BUG 风险与控制方案

| 风险 | 可能后果 | 控制方案 |
|---|---|---|
| 赔率变化未校验 | 玩家按旧赔率下注，引发争议。 | 提交时校验 `odds_version`。 |
| 重复提交下注 | 重复扣款。 | `user_id + request_id` 幂等唯一约束。 |
| 结算重复执行 | 重复派彩。 | 结算批次唯一、注单状态锁、事务处理。 |
| 半赢/半输算错 | 钱包金额错误。 | 结算引擎单元测试覆盖四分之一盘口。 |
| 下半场波胆口径错 | 结算争议。 | 明确下半场净比分 = 全场 - 半场。 |
| 串关包含同场选项 | 强相关风险和规则争议。 | 后端强制校验 `match_id` 唯一。 |
| 玩家余额并发扣款 | 余额负数或超额下注。 | 钱包行级锁 / 乐观锁。 |
| 代理额度超用 | 代理无限放款。 | 每次上分、分额、派彩后重新计算额度。 |
| 人工改余额 | 账务不可追踪。 | 禁止直接改余额，只能账变。 |
| 比赛开始未封盘 | 开赛后仍可下注。 | 自动封盘任务 + 提交下注二次校验。 |
| 多语言缺失 | 页面显示混乱。 | fallback 机制 + 后台缺失翻译检查。 |
| 重结算扣回失败 | 玩家余额不足。 | 允许负余额并冻结下分，生成异常报表。 |

---

## 21. 开发实施路径

### 21.1 推荐里程碑

#### 阶段 0：项目基础

交付内容：

1. 前后台项目结构。
2. 数据库初始化。
3. 登录鉴权。
4. RBAC 权限框架。
5. 多语言框架。
6. 操作日志基础能力。
7. 钱包和账变基础表。

#### 阶段 1：账号、代理、钱包

交付内容：

1. 平台后台创建玩家。
2. 平台后台创建一级代理。
3. 一级代理创建二级代理和玩家。
4. 二级代理创建玩家。
5. 代理额度池。
6. 玩家上分/下分。
7. 钱包流水。
8. 代理额度流水。

验收重点：代理权限隔离、额度计算、账变一致性。

#### 阶段 2：赛事、盘口、赔率

交付内容：

1. 联赛管理。
2. 球队管理。
3. 比赛管理。
4. 盘口模板。
5. 波胆批量赔率编辑。
6. 发布/封盘/取消。
7. 前台赛事列表。
8. 前台赛事详情。

验收重点：赔率版本、封盘状态、多语言名称。

#### 阶段 3：下注引擎

交付内容：

1. 投注单 UI。
2. 单关下注。
3. 串关下注。
4. 投注限额。
5. 赔率变化提示。
6. 注单列表和详情。
7. 钱包冻结。

验收重点：幂等、余额冻结、同场串关限制、四分之一球串关限制。

#### 阶段 4：结算引擎

交付内容：

1. 录入半场/全场比分。
2. 结算预览。
3. 单关结算。
4. 串关结算。
5. 作废退款。
6. 重结算冲正。
7. 结算日志。

验收重点：所有玩法结算准确、重复结算防护、冲正账变。

#### 阶段 5：返水、报表、内容

交付内容：

1. 返水规则。
2. 返水预览。
3. 返水确认发放。
4. 平台报表。
5. 代理报表。
6. 玩家账单。
7. Banner。
8. 公告和走马灯。
9. 多语言内容管理。

验收重点：返水有效投注额口径、报表与账变一致。

#### 阶段 6：UAT 与上线准备

交付内容：

1. 测试账号。
2. 测试赛事。
3. 全玩法测试用例。
4. 压测下注接口。
5. 压测结算批次。
6. 数据备份策略。
7. 上线回滚方案。
8. 后台操作培训文档。

### 21.2 MVP 上线验收清单

| 验收项 | 是否必须 |
|---|---:|
| 玩家可登录、改密码、切换语言 | 是 |
| 代理可创建直属玩家 | 是 |
| 代理可给直属玩家上分/下分 | 是 |
| 代理额度正确扣减和释放 | 是 |
| 后台可创建比赛和盘口 | 是 |
| 后台可批量录入波胆赔率 | 是 |
| 前台可展示赛事和盘口 | 是 |
| 玩家可单关下注 | 是 |
| 玩家可 2-5 串 1 | 是 |
| 同场串关被禁止 | 是 |
| 四分之一盘口不能进入串关 | 是 |
| 开赛自动封盘 | 是 |
| 后台可录入比分并生成预览 | 是 |
| 确认结算后钱包正确变化 | 是 |
| 玩家可查看注单和账变 | 是 |
| 后台可生成并发放返水 | 是 |
| Banner/公告/走马灯可配置 | 是 |
| 所有关键操作有日志 | 是 |

---

## 22. 二期规划

第一版稳定后，再考虑以下能力：

| 二期功能 | 说明 |
|---|---|
| 滚球 / Live | 实时盘口、赔率变化、下注延迟确认、危险进攻暂停。 |
| 系统串关 | 3 串 4、4 串 11、5 串 26 等组合。 |
| 同场组合投注 | 类似 Bet Builder 的同场多条件组合。 |
| Cash Out | 提前兑现。 |
| Edit Bet | 修改已下注串关。 |
| 自动赔率接口 | 接入第三方数据源。 |
| 自动赛果接口 | 自动获取比分和赛果。 |
| 多赔率格式 | Decimal、Malay、Hong Kong、Indonesian、American。 |
| 更多体育项目 | 篮球、网球、电竞等。 |
| 原生 App | iOS / Android。 |
| 代理佣金自动结算 | 按流水、净输赢、分层比例自动计算。 |
| 更复杂返水 | 按等级、玩法、时间段、活动自动返水。 |

---

## 23. 研发交付建议

### 23.1 后端建议

1. 第一版采用单体后端，不建议微服务。
2. 下注、结算、钱包、额度必须使用数据库事务。
3. Redis 可用于会话、缓存、接口限流、封盘任务锁，但不能作为唯一账务来源。
4. 账务金额使用 `DECIMAL(18,4)` 或更高精度，禁止使用浮点数。
5. 赔率使用 `DECIMAL(18,6)`。
6. 所有核心表使用软删除或状态字段，不物理删除。
7. 所有账务接口必须写操作日志。

### 23.2 前端建议

1. 玩家前台优先移动端 H5。
2. 投注单做成全局状态，切换页面不丢失。
3. 投注提交后必须刷新余额和注单状态。
4. 赔率变化时清晰提示，不自动替玩家接受新赔率。
5. 多语言使用统一 i18n key，不把文案写死在组件里。
6. 波胆区域需要折叠和分组，否则页面过长。

### 23.3 测试建议

1. 结算引擎必须做单元测试。
2. 钱包和代理额度必须做集成测试。
3. 串关必须做全流程测试。
4. 上线前用固定比分回归全部玩法。
5. 重结算必须单独测试冲正逻辑。
6. 并发下注必须压测。

---

## 24. 最终 MVP 业务规则定稿

以下规则作为第一版不可变更的默认规则，除非重新评审：

1. 足球普通赛事只按常规时间结算，即 90 分钟 + 伤停补时，不含加时和点球。
2. 半场玩法只按上半场比分结算。
3. 下半场波胆按下半场净比分结算。
4. 全场 0-0 的单/双结果为双。
5. 所有下注按下注时赔率快照结算。
6. 赔率变化必须重新确认，不能默认接受。
7. 开赛时间到达后自动封盘。
8. 后台录入比分后必须先生成结算预览，再确认入账。
9. 结算错误只能通过重结算和冲正账变修正，不能直接改余额。
10. 串关只支持 2-5 串 1。
11. 串关不允许同场。
12. 串关不允许冠军竞猜。
13. 串关不允许四分之一让球/大小球。
14. 串关中走水或作废的关卡按赔率 1.00 处理。
15. 玩家下注时冻结本金，结算后释放冻结并派彩/扣除/退款。
16. 代理采用信用额度池。
17. 玩家余额变化会影响所属代理额度占用。
18. 代理额度可以为负展示，但负数时禁止继续上分和分配额度。
19. 玩家返水按有效投注额计算，后台确认后发放。
20. 第一版不做滚球、系统串关、自动赔率源、自动赛果源、Cash Out、Edit Bet、Bet Builder。
