# 投注玩法说明 本文档为 **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` | 2–5 腿(`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 | 下半场比分(FT−HT) | ✗ | | `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 | WIN(2 + (-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 | LOSE(2 不大于 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` | 下半场 `(ftHome−htHome):(ftAway−htAway)` | **选项类型**: 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 Time–Full 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` | 0–1 球 | | `TG_2_3` | 2–3 球 | | `TG_4_6` | 4–6 球 | | `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`。 | 规则 | 说明 | |------|------| | 腿数 | **2–5 腿** | | 同场限制 | **每场比赛最多 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` 实现对齐。*