Files
thebet365/docs/投注玩法说明.md
Mars afb5c5437e feat: 充值订单审计与重新申请,优化赛事展示和余额刷新
- 新增 deposit_order_audit_logs 表,记录提交/审批/拒绝/撤销/重提全链路
- 管理端充值单页增加审计历史;玩家端充值历史支持时间线与重新申请
- 已拒绝订单可原单号重提;撤销入账使用 PLAYER_DEPOSIT_REVERSAL 并加强幂等
- 结算后清除热门标记,允许归档已结算赛事,完善今日赛事时区窗口
- 足球页今日/早盘独立折叠;资料与余额在进入钱包/个人页及下注后自动刷新
- 补充投注玩法、结算返水规则文档;新增 smoke/settlement CLI 脚本

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 14:52:05 +08:00

431 lines
16 KiB
Markdown
Raw 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.
# 投注玩法说明
本文档为 **Explanation说明**:集中描述 thebet365 第一版**足球赛前盘**的每种玩法如何下注、如何判赢。
派彩金额公式见 [结算与返水金额规则.md](./结算与返水金额规则.md);结算操作流程见 [settlement-and-fund-flow-analysis.md](./settlement-and-fund-flow-analysis.md)。
---
## 1. 范围与注单类型
### 1.1 产品范围v1
| 项 | 说明 |
|----|------|
| 运动 | 仅足球(`SPORT_TYPE_FOOTBALL` |
| 时段 | **赛前盘**:开球时间之前可下注(`isPreMatchKickoff` |
| 不含 | 滚球、Cash Out、改单、系统串关 |
与玩家端「我的 → 投注规则」文案一致(`apps/player/src/i18n/zh-CN.ts` `rules_p1``rules_p5`)。
### 1.2 注单类型
| 类型 | 枚举 | 说明 |
|------|------|------|
| 单关 | `SINGLE` | 1 个选项1 笔本金 |
| 串关 | `PARLAY` | 25 腿(`PARLAY_MIN_LEGS=2``PARLAY_MAX_LEGS=5`),赔率连乘 |
**数据模型**:库表为 `Bet`(注单)+ `BetSelection`(选项腿)。玩家端 Pinia store 名 `betSlip`,逻辑上等价于「投注单」。
### 1.3 API 入口
| 操作 | 路径 |
|------|------|
| 单关下注 | `POST /api/player/bets/single` |
| 串关下注 | `POST /api/player/bets/parlay` |
---
## 2. 玩法总览表
权威目录:`packages/shared/src/market-catalog.ts``FOOTBALL_MARKET_CATALOG`**共 18 种**足球盘口)。
| marketType | 中文名 | 时段 | 主要选项 | 默认线 | 单关 | 串关 | 串关序 | 结算分类 | 结算依据 | 默认 seed |
|------------|--------|------|----------|--------|------|------|--------|----------|----------|-----------|
| `FT_1X2` | 全场 1X2 | FT | HOME / DRAW / AWAY | — | ✓ | ✓ | 3 | SCORE | 全场比分 | ✓ |
| `FT_HANDICAP` | 全场让球 | FT | HOME / AWAY | -0.5 | ✓ | ✓ | 1 | HANDICAP | 全场比分 + 让球线 | ✓ |
| `FT_OVER_UNDER` | 全场大小 | FT | OVER / UNDER | 2.5 | ✓ | ✓ | 2 | TOTAL | 全场总进球 + 大小线 | ✓ |
| `FT_ODD_EVEN` | 全场单双 | FT | ODD / EVEN | — | ✓ | ✓ | 4 | ODD_EVEN | 全场总进球奇偶 | ✓ |
| `HT_1X2` | 半场 1X2 | HT | HOME / DRAW / AWAY | — | ✓ | ✓ | 7 | SCORE | 半场比分 | ✓ |
| `HT_HANDICAP` | 半场让球 | HT | HOME / AWAY | -0.5 | ✓ | ✓ | 5 | HANDICAP | 半场比分 + 让球线 | ✓ |
| `HT_OVER_UNDER` | 半场大小 | HT | OVER / UNDER | 1.5 | ✓ | ✓ | 6 | TOTAL | 半场总进球 + 大小线 | ✓ |
| `FT_CORRECT_SCORE` | 全场波胆 | FT | 见 §3.E | — | ✓ | ✗ | — | CORRECT_SCORE | 全场精确比分 | ✓ |
| `HT_CORRECT_SCORE` | 上半场波胆 | HT | 见 §3.E | — | ✓ | ✗ | — | CORRECT_SCORE | 半场精确比分 | ✗ |
| `SH_CORRECT_SCORE` | 下半场波胆 | SH | 见 §3.E | — | ✓ | ✗ | — | CORRECT_SCORE | 下半场比分FTHT | ✗ |
| `OUTRIGHT_WINNER` | 冠军 | OUTRIGHT | 球队 code | — | ✓ | ✗ | — | OUTRIGHT | 冠军球队 code | ✗* |
| `FT_TEAM_TOTAL_HOME` | 主队进球大小 | FT | OVER / UNDER | 1.5 | ✓ | ✓ | 8 | TOTAL | 主队全场进球 | ✓ |
| `FT_TEAM_TOTAL_AWAY` | 客队进球大小 | FT | OVER / UNDER | 1.5 | ✓ | ✓ | 9 | TOTAL | 客队全场进球 | ✓ |
| `HT_FT` | 半全场 | FT | 9 组合,见 §3.F | — | ✓ | ✓ | 10 | SCORE | 半场结果 + 全场结果 | ✓ |
| `FT_TOTAL_GOALS` | 总进球数 | FT | TG_0_1 … TG_7_PLUS | — | ✓ | ✓ | 11 | SCORE | 全场总进球区间 | ✓ |
| `FT_CORNERS_HANDICAP` | 全场角球让球 | FT | HOME / AWAY | -0.5 | ✓ | ✓ | 12 | MANUAL_STATS | 主客角球 + 让球线 | ✓ |
| `FT_CORNERS_OVER_UNDER` | 全场角球大小 | FT | OVER / UNDER | 8.5 | ✓ | ✓ | 13 | MANUAL_STATS | 角球总数 + 大小线 | ✓ |
| `FT_CARDS_OVER_UNDER` | 全场罚牌大小 | FT | OVER / UNDER | 3.5 | ✓ | ✓ | 14 | MANUAL_STATS | 罚牌总数 + 大小线 | ✓ |
\* `OUTRIGHT_WINNER` 不在常规赛事 seed 模板中,由世界杯 48 强等单独同步,见 [默认数据说明.md](./默认数据说明.md)。
**默认 seed 刻意不含**`HT_CORRECT_SCORE``SH_CORRECT_SCORE`(系统仍识别并可结算)。
---
## 3. 按类别详解
以下判赢逻辑对应 `apps/api/src/domains/settlement/domain/settlement-calculator.ts``settleSelection()`
腿级结果:`WIN` | `HALF_WIN` | `PUSH` | `HALF_LOSE` | `LOSE` | `VOID`
### 3.A 独赢盘1X2
**结算分类**`SCORE`
#### FT_1X2全场 1X2 / Full Time 1X2
| 项 | 内容 |
|----|------|
| 玩法说明 | 预测**全场 90 分钟**(含补时,不含加时/点球)结束时的赛果 |
| 选项 | `HOME` 主胜 · `DRAW` 和局 · `AWAY` 客胜 |
| 判赢 | 比较 `ftHome``ftAway`:主胜 / 和 / 客胜 |
| 示例 | 全场 2:1`HOME`**WIN**;选 `DRAW`**LOSE** |
| 串关 | 允许(`parlayOrder=3` |
| 快照字段 | 无盘口线 |
#### HT_1X2半场 1X2
| 项 | 内容 |
|----|------|
| 玩法说明 | 预测**上半场**结束时的赛果 |
| 选项 | `HOME` / `DRAW` / `AWAY` |
| 判赢 | 比较 `htHome``htAway` |
| 示例 | 半场 0:0、全场 1:0选半场 `DRAW`**WIN** |
| 串关 | 允许(`parlayOrder=7` |
---
### 3.B 让球盘(亚洲盘)
**结算分类**`HANDICAP`(角球盘为 `MANUAL_STATS`,算法同为让球)
**通用规则**
- 选项:`HOME`(主队受让/让球侧)/ `AWAY`(客队)
- 让球线存于 `BetSelection.handicapLine`(下注时快照)
- 主队视角:`adj = 本队进球 + handicapLine 对手进球`
- `adj > 0` → WIN`adj = 0` → PUSH`adj < 0` → LOSE
- 客队选项使用 **相反符号** 的让球线(代码内对客队取 `-line`
- 四分之一盘(`.25` / `.75`)可产生半赢半输,见 [§5](#5-四分之一盘25--75)
#### FT_HANDICAP全场让球
| 项 | 内容 |
|----|------|
| 默认线 | -0.5(表示主队让半球,即主队需净胜至少 1 球才全赢) |
| 统计 | `ftHome``ftAway` |
| 串关 | 允许;**禁止** `.25`/`.75` 线进入串关 |
**示例**(线 -0.5,选主队 `HOME`
| 比分 | 结果 |
|------|------|
| 2:1 | WIN2 + (-0.5) 1 = 0.5 > 0 |
| 1:1 | LOSE |
| 1:0 | WIN |
#### HT_HANDICAP半场让球
| 项 | 内容 |
|----|------|
| 默认线 | -0.5 |
| 统计 | `htHome``htAway` |
| 串关 | 允许(禁止四分之一线) |
#### FT_CORNERS_HANDICAP全场角球让球
| 项 | 内容 |
|----|------|
| 默认线 | -0.5 |
| 统计 | 管理员录入 `homeCorners``awayCorners`;缺失时结算报错 `SETTLEMENT_STAT_MISSING` |
| 判赢 | 与足球让球相同,但用角球数代替进球 |
| 串关 | 允许(禁止四分之一线) |
---
### 3.C 大小盘Over/Under
**结算分类**`TOTAL`(角球/罚牌为 `MANUAL_STATS`,算法同为大小)
**通用规则**
- 选项:`OVER`(大)/ `UNDER`(小)
- 大小线存于 `BetSelection.totalLine`
- 大球:`总进球 > line` → WIN`= line` → PUSH`< line` → LOSE
- 小球:相反
- 支持四分之一盘半赢半输;串关禁止 `.25`/`.75` 线
| marketType | 中文名 | 默认线 | 统计对象 |
|------------|--------|--------|----------|
| `FT_OVER_UNDER` | 全场大小 | 2.5 | `ftHome + ftAway` |
| `HT_OVER_UNDER` | 半场大小 | 1.5 | `htHome + htAway` |
| `FT_TEAM_TOTAL_HOME` | 主队进球大小 | 1.5 | `ftHome` |
| `FT_TEAM_TOTAL_AWAY` | 客队进球大小 | 1.5 | `ftAway` |
| `FT_CORNERS_OVER_UNDER` | 全场角球大小 | 8.5 | `homeCorners + awayCorners` |
| `FT_CARDS_OVER_UNDER` | 全场罚牌大小 | 3.5 | `homeCards + awayCards` |
**示例**`FT_OVER_UNDER` 线 2.5,选 `OVER`
| 比分 | 总进球 | 结果 |
|------|--------|------|
| 2:1 | 3 | WIN |
| 1:1 | 2 | LOSE |
| 2:0 | 2 | LOSE2 不大于 2.5 |
角球/罚牌盘:结算前须在管理端录入对应统计字段,否则无法确认结算。
---
### 3.D 单双Odd/Even
#### FT_ODD_EVEN全场单双
| 项 | 内容 |
|----|------|
| 选项 | `ODD` 单 · `EVEN` 双 |
| 判赢 | 全场总进球 `ftHome + ftAway` 为奇数或偶数 |
| 示例 | 0:0 → 总进球 0 → **双EVEN 赢)** |
| 串关 | 允许(`parlayOrder=4` |
---
### 3.E 波胆Correct Score— 仅单关
**结算分类**`CORRECT_SCORE`
**串关**:全部 `allowParlay: false`,不可进入串关。
| marketType | 比分来源 |
|------------|----------|
| `FT_CORRECT_SCORE` | 全场 `ftHome:ftAway` |
| `HT_CORRECT_SCORE` | 半场 `htHome:htAway` |
| `SH_CORRECT_SCORE` | 下半场 `(ftHomehtHome):(ftAwayhtAway)` |
**选项类型**
1. **精确比分**code 形如 `SCORE_2_1`(表示 2:1
2. **其它主胜** `OTHER_HOME`:主胜,且精确比分不在模板列表中
3. **其它和局** `OTHER_DRAW`:和局,且精确比分不在模板列表中
4. **其它客胜** `OTHER_AWAY`:客胜,且精确比分不在模板列表中
**模板列表**`market-catalog.ts`
- 全场:`FT_CORRECT_SCORE_TEMPLATE`28 项,含 3 个 OTHER_*
- 半场/下半场:`HT_CORRECT_SCORE_TEMPLATE`17 项)
**判赢逻辑**
-`SCORE_h_a`:实际比分完全相等 → WIN否则 LOSE
- 若实际比分在模板中有对应 `SCORE_*` 项,则 OTHER_* 选项 LOSE
- 若实际比分**不在**模板中,则按主胜/和/客胜归到对应 OTHER_* → WIN
**示例**(全场波胆,实际 4:2
- 模板含 `SCORE_4_2` → 选 `SCORE_4_2` **WIN**,选 `OTHER_HOME` **LOSE**
- 若模板不含 4:2 → 选 `OTHER_HOME` **WIN**(主队胜)
---
### 3.F 组合 / 区间
#### HT_FT半全场 / Half TimeFull Time
| 项 | 内容 |
|----|------|
| 玩法说明 | 同时预测**半场结果**与**全场结果** |
| 选项 code | `{半场}_{全场}`,各为 `HOME` / `DRAW` / `AWAY`,共 9 种 |
| 判赢 | 实际组合须与选项完全一致 |
| code | 含义 |
|------|------|
| `HOME_HOME` | 半场主胜 + 全场主胜 |
| `HOME_DRAW` | 半场主胜 + 全场和 |
| `HOME_AWAY` | 半场主胜 + 全场客胜 |
| `DRAW_HOME` | 半场和 + 全场主胜 |
| `DRAW_DRAW` | 半场和 + 全场和 |
| `DRAW_AWAY` | 半场和 + 全场客胜 |
| `AWAY_HOME` | 半场客胜 + 全场主胜 |
| `AWAY_DRAW` | 半场客胜 + 全场和 |
| `AWAY_AWAY` | 半场客胜 + 全场客胜 |
**示例**:半场 1:0、全场 1:1 → 半场 HOME、全场 DRAW → 选 `HOME_DRAW` **WIN**
#### FT_TOTAL_GOALS总进球数区间
| 选项 code | 区间 |
|-----------|------|
| `TG_0_1` | 01 球 |
| `TG_2_3` | 23 球 |
| `TG_4_6` | 46 球 |
| `TG_7_PLUS` | 7 球及以上 |
判赢:按全场 `ftHome + ftAway` 落入区间。
**示例**3:2 → 总进球 5 → 选 `TG_4_6` **WIN**
---
### 3.G 冠军Outright
#### OUTRIGHT_WINNER
| 项 | 内容 |
|----|------|
| 玩法说明 | 预测联赛/赛事**最终冠军**(如世界杯夺冠球队) |
| 选项 | 各参赛队 `selectionCode` = 球队 code`FRA``BRA` |
| 判赢 | `selectionCode === winnerTeamCode`(管理员指定冠军) |
| 串关 | **禁止** |
| 前置条件 | 联赛内常规赛事须全部 `SETTLED``CANCELLED` 后才可结算冠军盘 |
| 玩家入口 | `/bet` →「优胜冠军」→ `OutrightBetModal`**不走** BetSlip 串关) |
---
## 4. 串关规则
实现:`packages/shared/src/betting-rules.ts``canSelectForParlay`)、`apps/api/src/domains/betting/bets.service.ts``apps/player/src/stores/betSlip.ts`
| 规则 | 说明 |
|------|------|
| 腿数 | **25 腿** |
| 同场限制 | **每场比赛最多 1 项**(前端 `SAME_MATCH`;后端 `PARLAY_SAME_MATCH_FORBIDDEN` |
| 禁止玩法 | 波胆3 种)、冠军盘 |
| 禁止盘口线 | 让球/大小族(含队进球、角球、罚牌)的 **`.25` / `.75` 线**`QUARTER_LINE` |
| 可串关玩法 | `PARLAY_MARKET_TYPES`**14 种**(见总览表「串关=✓」行) |
| 串关列表 API | `GET /api/player/matches?scope=parlay` 仅返回含可串关盘口的赛事 |
**串关派彩**(连乘有效因子、任一脚 LOSE 整单 LOST 等)见 [结算与返水金额规则.md §3](./结算与返水金额规则.md)。
---
## 5. 四分之一盘(.25 / .75
让球/大小盘盘口线为 **0.25 或 0.75** 的整数倍时(如 -0.25、2.75),系统将盘口**拆成两条半盘**分别判定,再合并为腿级结果:
| 两半组合 | 合并结果 |
|----------|----------|
| 两赢 | WIN |
| 两输 | LOSE |
| 一赢一走 | HALF_WIN |
| 一输一走 | HALF_LOSE |
| 一赢一输 | PUSH |
| 场景 | 单关 | 串关 |
|------|------|------|
| 四分之一线 | **允许**下注 | **禁止**选入(`QUARTER_LINE` |
**示例 1** — 全场让球 **-0.25**,选主队,比分 **0:0**
- 拆为 -0 与 -0.5 两半:-0 → PUSH-0.5 → LOSE
- 合并 → **HALF_LOSE**(退一半本金,见派彩文档)
**示例 2** — 全场大小 **2.25**,选小球,总进球 **2**
- 拆为 2.0 与 2.5:对 2.0 小球 PUSH对 2.5 小球 WIN
- 合并 → **HALF_WIN**
---
## 6. 下注校验与限额
### 6.1 下注校验(`BetsService.validateSelection`
| 校验项 | 说明 |
|--------|------|
| 盘口状态 | 选项与盘口均为 `OPEN` |
| 玩家可见 | `showOnPlayer = true` |
| 赛事 | `PUBLISHED`;非冠军盘须未开球 |
| 运动 | 仅足球 |
| 赔率版本 | 请求 `oddsVersion` 须与库内一致 |
| 单关/串关 | 单关要求 `allowSingle`;串关走 `canSelectForParlay` |
| 资金 | 通过 `FundsPostingService.freezeBet` 冻结本金 |
### 6.2 默认限额(`betting-limits.service.ts`
| 配置项 | 默认值 |
|--------|--------|
| 最小单注 | 1 |
| 单关最大投注 | 50,000 |
| 串关最大投注 | 20,000 |
| 单关最高派彩 | 500,000 |
| 串关最高派彩 | 1,000,000 |
| 玩家每日投注上限 | 200,000 |
可在管理端 `systemConfig` 覆盖;`potentialReturn` 超限会拒单(`MAX_PAYOUT`)。
### 6.3 其它
- **未知 marketType** 结算时默认 **LOSE**
- **选项 code 回退**:若快照无 code可从中文名推断`settlement-helpers.ts`
- **玩家选盘**:赛事详情 → 点赔率 → `BetSlipDrawer`;波胆用 `CorrectScorePanel`
---
## 7. 下注与结算流程摘要
```mermaid
sequenceDiagram
participant Player
participant API
participant Admin
Player->>API: POST /player/bets/single 或 parlay
API->>API: validateSelection + freezeBet
Admin->>API: recordScore
Admin->>API: previewSettlement
Admin->>API: confirmSettlement
API->>API: settleSelection 逐腿判赢
API->>API: calculatePayout 或 calculateParlayPayout
API->>Player: 钱包 settleBet 入账
```
| 阶段 | 说明 |
|------|------|
| 下注 | 创建 `Bet` + `BetSelection`,冻结 `stake` |
| 录入比分 | 赛事 → `PENDING_SETTLEMENT` |
| 预览 | 生成 `SettlementBatch`PREVIEW可含角球/罚牌统计 |
| 确认 | 写入腿级 `resultStatus`、注单 `status`/`actualReturn`,解冻并派彩 |
**跨场串关**:每场结算时只更新该场腿的 `resultStatus`;全部腿有结果后才调用 `calculateParlayPayout` 一次。
详细流程见 [settlement-and-fund-flow-analysis.md](./settlement-and-fund-flow-analysis.md)。
---
## 8. 代码真源与相关文档
### 8.1 代码索引
| 主题 | 文件 |
|------|------|
| 玩法目录18 种) | `packages/shared/src/market-catalog.ts` |
| 串关选盘规则 | `packages/shared/src/betting-rules.ts` |
| 下注与校验 | `apps/api/src/domains/betting/bets.service.ts` |
| 下注限额 | `apps/api/src/domains/betting/betting-limits.service.ts` |
| 腿级结算 | `apps/api/src/domains/settlement/domain/settlement-calculator.ts` |
| 结算流程 | `apps/api/src/domains/settlement/settlement.service.ts` |
| 结算辅助 | `apps/api/src/domains/settlement/domain/settlement-helpers.ts` |
| 单元测试 | `apps/api/src/domains/settlement/domain/settlement-calculator.spec.ts` |
| Smoke 用例 | `apps/api/src/domains/operations/smoke-tests/smoke-test.cases.ts` |
| 玩家投注单 | `apps/player/src/stores/betSlip.ts` |
### 8.2 相关文档
| 文档 | 内容 |
|------|------|
| [结算与返水金额规则.md](./结算与返水金额规则.md) | 单关/串关派彩公式、四分之一盘金额、返水 |
| [settlement-and-fund-flow-analysis.md](./settlement-and-fund-flow-analysis.md) | 结算三步、钱包流水 |
| [默认数据说明.md](./默认数据说明.md) | seed 盘口范围、48 强冠军盘 |
| [UAT_CHECKLIST.md](./UAT_CHECKLIST.md) | 投注与串关 UAT 项 |
### 8.3 文档分工
| 本文档 | 结算金额文档 |
|--------|--------------|
| 每种玩法怎么选、怎么判赢 | stake × odds 怎么算 |
| 串关能否选、同场限制 | 串关连乘因子与 payout |
| 角球/罚牌统计要求 | HALF_WIN 派彩数值示例 |
---
*最后更新:与 `FOOTBALL_MARKET_CATALOG`18 种)及 `settlement-calculator.ts` 实现对齐。*