feat: 充值订单审计与重新申请,优化赛事展示和余额刷新
- 新增 deposit_order_audit_logs 表,记录提交/审批/拒绝/撤销/重提全链路 - 管理端充值单页增加审计历史;玩家端充值历史支持时间线与重新申请 - 已拒绝订单可原单号重提;撤销入账使用 PLAYER_DEPOSIT_REVERSAL 并加强幂等 - 结算后清除热门标记,允许归档已结算赛事,完善今日赛事时区窗口 - 足球页今日/早盘独立折叠;资料与余额在进入钱包/个人页及下注后自动刷新 - 补充投注玩法、结算返水规则文档;新增 smoke/settlement CLI 脚本 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
|
||||
## MVP 验收清单(18 项)
|
||||
|
||||
玩法与串关规则参考:[投注玩法说明.md](./投注玩法说明.md)。
|
||||
|
||||
- [ ] 玩家可登录、改密码、切换语言
|
||||
- [ ] 代理可创建直属玩家
|
||||
- [ ] 代理可给直属玩家上分/下分
|
||||
|
||||
430
docs/投注玩法说明.md
Normal file
430
docs/投注玩法说明.md
Normal file
@@ -0,0 +1,430 @@
|
||||
# 投注玩法说明
|
||||
|
||||
本文档为 **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` 实现对齐。*
|
||||
410
docs/结算与返水金额规则.md
Normal file
410
docs/结算与返水金额规则.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# 结算与返水金额规则
|
||||
|
||||
本文档为 **Reference(参考)**:只描述**金额如何计算**,不涉及管理端操作步骤。各玩法定义与判赢规则见 [投注玩法说明.md](./投注玩法说明.md);赛事结算流程见 [settlement-and-fund-flow-analysis.md](./settlement-and-fund-flow-analysis.md)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 说明与术语
|
||||
|
||||
| 术语 | 含义 |
|
||||
|------|------|
|
||||
| **stake** | 投注本金(`Bet.stake`) |
|
||||
| **odds** | 欧赔,含本金系数(`BetSelection.odds` 或 leg 快照) |
|
||||
| **payout** | 派彩总额,**含本金**(函数 `calculatePayout` / `calculateParlayPayout` 的返回值) |
|
||||
| **actualReturn** | 确认结算后写入注单的派彩,与 `payout` 一致 |
|
||||
| **净盈亏** | `payout - stake`(LOSE 时 payout=0,净亏 = -stake) |
|
||||
| **rate** | 返水比例,**小数**(`0.01` = 1%) |
|
||||
| **lineAmount** | 单笔注单返水:`stake × rate` |
|
||||
|
||||
**精度**:业务金额在库中为 `Decimal(18,4)`;返水比例为 `Decimal(8,4)`。计算链使用 Prisma `Decimal` 全精度,**无额外 round**(Admin UI 百分比输入另有 `rate-percent.ts` 转换,不影响 API 计算)。
|
||||
|
||||
### 代码真源索引
|
||||
|
||||
| 主题 | 文件 |
|
||||
|------|------|
|
||||
| 单关/串关派彩、四分之一盘 | `apps/api/src/domains/settlement/domain/settlement-calculator.ts` |
|
||||
| 确认结算、`actualReturn`、注单状态 | `apps/api/src/domains/settlement/settlement.service.ts` |
|
||||
| 钱包冻结/结算/重结算 | `apps/api/src/domains/ledger/wallet.service.ts` |
|
||||
| 返水费率 | `apps/api/src/domains/operations/cashback/cashback-rate.resolver.ts` |
|
||||
| 返水聚合/批次/入账 | `apps/api/src/domains/operations/cashback/cashback.service.ts` |
|
||||
| 下注限额、`potentialReturn` | `apps/api/src/domains/betting/betting-limits.service.ts`、`bets.service.ts` |
|
||||
| 代理授信 | `apps/api/src/domains/agent/agent-credit.service.ts` |
|
||||
| 串关选盘限制 | `packages/shared/src/betting-rules.ts` |
|
||||
| 可执行数值对照 | `apps/api/src/infrastructure/database/run-settlement-audit.ts` |
|
||||
|
||||
---
|
||||
|
||||
## 2. 单关派彩公式
|
||||
|
||||
函数:`calculatePayout(stake, odds, result)`
|
||||
|
||||
| 腿级结果 `SelectionResult` | 公式 | 说明 |
|
||||
|---------------------------|------|------|
|
||||
| **WIN** | `stake × odds` | 全赢 |
|
||||
| **HALF_WIN** | `stake/2 × odds + stake/2` | 等价于 `stake × (odds + 1) / 2` |
|
||||
| **PUSH** | `stake` | 走水,退本 |
|
||||
| **VOID** | `stake` | 作废,退本 |
|
||||
| **HALF_LOSE** | `stake / 2` | 半输,退一半本金 |
|
||||
| **LOSE** | `0` | 全输 |
|
||||
|
||||
### 数值示例(stake = 100)
|
||||
|
||||
| 用例 ID | 场景 | odds | 结果 | payout | 净盈亏 |
|
||||
|---------|------|------|------|--------|--------|
|
||||
| BF001 | 1X2 主胜全赢 | 2.0 | WIN | **200.00** | +100.00 |
|
||||
| BF002 | 1X2 和局选项全输 | — | LOSE | **0.00** | -100.00 |
|
||||
| S009 | 让球 -1 全赢 | 1.85 | WIN | **185.00** | +85.00 |
|
||||
| S010 | 让球 -1 走水 | 1.85 | PUSH | **100.00** | 0.00 |
|
||||
| S011 | 让球 -0.25 半输 @ 0-0 | 1.85 | HALF_LOSE | **50.00** | -50.00 |
|
||||
| S011B | 半赢派彩系数 | 1.85 | HALF_WIN | **142.50** | +42.50 |
|
||||
| S012 | 让球 -0.5 全输 @ 0-0 | 1.85 | LOSE | **0.00** | -100.00 |
|
||||
| S015 | 大小 小球 0-0 | 1.95 | WIN | **195.00** | +95.00 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 串关派彩公式
|
||||
|
||||
函数:`calculateParlayPayout(stake, legs[])`
|
||||
返回:`{ betResult, payout, effectiveOdds }`
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start[开始] --> anyLose{任一脚 LOSE?}
|
||||
anyLose -->|是| lost["payout=0, betResult=LOST"]
|
||||
anyLose -->|否| combine[连乘有效因子]
|
||||
combine --> allPush{全部 PUSH 或 VOID?}
|
||||
allPush -->|是| push["payout=stake, betResult=PUSH"]
|
||||
allPush -->|否| won["payout=stake×combinedOdds, betResult=WON"]
|
||||
```
|
||||
|
||||
### 各腿有效因子
|
||||
|
||||
| 腿级结果 | 连乘因子 |
|
||||
|----------|----------|
|
||||
| WIN | × `odds` |
|
||||
| HALF_WIN | × `(odds + 1) / 2` |
|
||||
| HALF_LOSE | × `0.5` |
|
||||
| PUSH / VOID | × `1.0`(不参与升赔) |
|
||||
| LOSE | 整单终止,payout = 0 |
|
||||
|
||||
**最终**:`payout = stake × combinedOdds`(除非 LOST 或全 PUSH/VOID)。
|
||||
|
||||
### 数值示例(stake = 100)
|
||||
|
||||
| 用例 ID | 腿组合 | effectiveOdds | payout | 净盈亏 |
|
||||
|---------|--------|---------------|--------|--------|
|
||||
| S016 | 1.8 WIN × 2.0 WIN | 3.6000 | **360.00** | +260.00 |
|
||||
| S017 | 1.8 WIN × 2.0 LOSE | 0 | **0.00** | -100.00 |
|
||||
| S018 | 1.8 WIN × 2.0 PUSH × 1.9 WIN | 3.4200 | **342.00** | +242.00 |
|
||||
| S019 | 1.8 PUSH × 2.0 VOID | 1.0000 | **100.00** | 0.00 |
|
||||
|
||||
### 串关下注限制
|
||||
|
||||
串关**禁止**四分之一让球/大小盘(`.25` / `.75` 线),见 `canSelectForParlay` → 错误码 `QUARTER_LINE`。单关可使用四分之一盘。
|
||||
|
||||
### 跨场结算时序(影响何时产生 payout)
|
||||
|
||||
1. 结算**某一场比赛**时,只更新该场对应腿的 `resultStatus`。
|
||||
2. 若其他场腿尚无结果 → 注单仍为 **PENDING**,此时无最终 `payout`。
|
||||
3. **任一脚在本场结算为 LOSE** 且其余腿已有结果 → 整单 **LOST**,`payout = 0`。
|
||||
4. 全部腿均有结果后 → 调用 `calculateParlayPayout` 一次,写入 `actualReturn` 并入账。
|
||||
|
||||
---
|
||||
|
||||
## 4. 四分之一盘(.25 / .75)
|
||||
|
||||
让球/大小盘为 `.25` 或 `.75` 时,`settleHandicap` / `settleOverUnder` 拆成**两条半盘**分别判定 WIN/PUSH/LOSE,再合并:
|
||||
|
||||
| 两半组合 | 合并结果 |
|
||||
|----------|----------|
|
||||
| 两赢 | WIN |
|
||||
| 两输 | LOSE |
|
||||
| 一赢一平 | HALF_WIN |
|
||||
| 一输一平 | HALF_LOSE |
|
||||
| 一赢一输 | PUSH |
|
||||
|
||||
**示例(S011)**:主让 -0.25,比分 0-0 → **HALF_LOSE** → payout = 50(stake=100)。
|
||||
|
||||
---
|
||||
|
||||
## 5. `actualReturn` 与注单 `status` 映射
|
||||
|
||||
确认结算时(`SettlementService.confirmSettlement`):
|
||||
|
||||
- **单关(1 腿)**:`result = settleSelection(...)` → `payout = calculatePayout(...)` → **`actualReturn = payout`**
|
||||
- **单关多腿 / 串关**:各腿结果齐备后 → **`actualReturn = calculateParlayPayout(...).payout`**
|
||||
|
||||
注单状态由 `betStatusFromSelection` 映射:
|
||||
|
||||
| 腿级 / 整单结果 | `Bet.status` |
|
||||
|-----------------|--------------|
|
||||
| LOSE | **LOST** |
|
||||
| PUSH、VOID | **PUSH** |
|
||||
| WIN、HALF_WIN、**HALF_LOSE** | **WON** |
|
||||
|
||||
### 易错点
|
||||
|
||||
| 场景 | actualReturn | Bet.status |
|
||||
|------|--------------|------------|
|
||||
| 单关半输(HALF_LOSE) | `stake/2`(如 50) | **WON**(部分返还仍记赢单) |
|
||||
| 串关任一脚 LOSE | 0 | **LOST** |
|
||||
| 串关全 PUSH/VOID | stake | **PUSH** |
|
||||
|
||||
串关确认入账时,钱包侧 `result` 简化为:整单 LOST → `LOSE`;整单 PUSH → `PUSH`;整单 WON → `WIN`(不区分腿级半赢半输)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 钱包金额变动(结算侧)
|
||||
|
||||
### 下注冻结(`freezeForBet`)
|
||||
|
||||
```
|
||||
availableBalance -= stake
|
||||
frozenBalance += stake
|
||||
transactionType = BET_FREEZE
|
||||
```
|
||||
|
||||
余额不足(`availableBalance < stake`)→ `INSUFFICIENT_BALANCE`。
|
||||
|
||||
### 结算入账(`settleBet`)
|
||||
|
||||
```
|
||||
frozenBalance -= stake
|
||||
availableBalance += payout // payout 即 actualReturn
|
||||
```
|
||||
|
||||
| 传入 result | 流水类型 | payout 典型值 |
|
||||
|-------------|----------|---------------|
|
||||
| WIN | BET_SETTLE_WIN | stake × odds |
|
||||
| HALF_WIN | BET_SETTLE_WIN | 半赢派彩 |
|
||||
| LOSE | BET_SETTLE_LOSE | 0 |
|
||||
| HALF_LOSE | BET_SETTLE_LOSE | stake / 2 |
|
||||
| PUSH | BET_SETTLE_PUSH | stake |
|
||||
| VOID | BET_VOID_REFUND | stake |
|
||||
|
||||
幂等键:`businessKey = settle:{batchNo}:{betNo}`。
|
||||
|
||||
### 作废 / 取消比赛
|
||||
|
||||
- `Bet.status = VOID`,**`actualReturn = stake`**
|
||||
- 调用 `settleBet(..., payout=stake, result='VOID')` → **BET_VOID_REFUND**
|
||||
|
||||
### 重结算(`confirmResettlement`)
|
||||
|
||||
```
|
||||
delta = 新 payout - 旧 actualReturn
|
||||
```
|
||||
|
||||
- `delta > 0` → `applyResettleDelta`,流水 **BET_SETTLE_WIN**
|
||||
- `delta < 0` → 流水 **RESETTLE_REVERSE**(可扣至**负余额**)
|
||||
- 注单 `settlementStatus = RESETTLED`,`actualReturn` 更新为新 payout
|
||||
|
||||
### 端到端钱包示例
|
||||
|
||||
| 用例 ID | 流程 | 钱包变化 | actualReturn |
|
||||
|---------|------|----------|--------------|
|
||||
| BF001 | 单关赢 100@2.0,2-1 | 1000 → 900 avail + 100 frozen → **1100 avail** | 200 |
|
||||
| BF002 | 单关输(和局+2-1) | 1000 → **900 avail** | 0 |
|
||||
| BF003 | 幂等 50 注 | 500 → **450 avail + 50 frozen** | — |
|
||||
| BF004 | 余额不足 | **50 不变** | — |
|
||||
| BF005 | 代理线玩家输 100 | 玩家 **900 avail** | 0 |
|
||||
|
||||
BF001 流水顺序:`MANUAL_DEPOSIT` → `BET_FREEZE` → `BET_SETTLE_WIN`。
|
||||
|
||||
---
|
||||
|
||||
## 7. 下注时金额校验(与派彩相关)
|
||||
|
||||
### potentialReturn(下单时估算)
|
||||
|
||||
| 类型 | 公式 |
|
||||
|------|------|
|
||||
| 单关 | `stake × odds` |
|
||||
| 串关 | `stake × ∏(各腿 odds)` |
|
||||
|
||||
按**全赢**估算,不含半赢/走水;用于 `maxPayout*` 校验。
|
||||
|
||||
### 默认限额(`BettingLimitsService`,可被 `system_config` 覆盖)
|
||||
|
||||
| 配置键 | 默认值 |
|
||||
|--------|--------|
|
||||
| `bet.min_stake` | 1 |
|
||||
| `bet.max_stake_single` | 50,000 |
|
||||
| `bet.max_stake_parlay` | 20,000 |
|
||||
| `bet.max_payout_single` | 500,000 |
|
||||
| `bet.max_payout_parlay` | 1,000,000 |
|
||||
| `bet.daily_stake_limit` | 200,000(按 `placedAt` 当日,排除 VOID/CANCELLED) |
|
||||
|
||||
返水基数 `stake` 为通过上述校验后的下注金额,**与返水 rate 无联动**。
|
||||
|
||||
---
|
||||
|
||||
## 8. 返水金额算法
|
||||
|
||||
### 8.1 单笔返水
|
||||
|
||||
```
|
||||
lineAmount = stake × rate
|
||||
```
|
||||
|
||||
- **stake**:整单本金;串关**不按 leg 拆分**。
|
||||
- 实现:`cashback.service.ts` → `bet.stake.mul(rate)`。
|
||||
|
||||
### 8.2 费率解析(`resolveCashbackRateForBet`)
|
||||
|
||||
**规则表 `CashbackRule` 优先级**(数值越大越优先):
|
||||
|
||||
| 优先级 | targetType | 匹配条件 |
|
||||
|--------|------------|----------|
|
||||
| 3 | USER | `targetId === userId` |
|
||||
| 2 | AGENT | `targetId === agentId`(玩家直属代理) |
|
||||
| 1 | GLOBAL | 无 targetId 限制 |
|
||||
|
||||
- 规则带 **marketType** 时,注单**任一** `BetSelection.marketType` 命中才适用;否则跳过该规则。
|
||||
- **同优先级**:遍历规则时 `priority > best.priority`(**严格大于**),先写入的同优先级规则不会被后者覆盖。
|
||||
- **无规则命中** → 使用 `agentDefaultRate`(见下节)。
|
||||
|
||||
### 8.3 默认费率 `agentDefaultRate`(无 CashbackRule 时)
|
||||
|
||||
| 玩家类型 | 来源 |
|
||||
|----------|------|
|
||||
| 有 `parentId`(代理线下) | 直属代理 `AgentProfile.cashbackRate`;无 profile → **0** |
|
||||
| 无 parent,邀请人 sponsor 为 ADMIN | `system_config` → `cashback.admin_invite_rate` |
|
||||
| 无 parent 的其他平台直属 | `system_config` → `cashback.platform_direct_rate` |
|
||||
|
||||
未配置时平台直属/邀请费率默认 **0**。子代理 `cashbackRate` 不得高于父代理。
|
||||
|
||||
### 8.4 合格注单(进入返水批次)
|
||||
|
||||
查询条件(`aggregatePeriod`):
|
||||
|
||||
```
|
||||
status IN ('WON', 'LOST')
|
||||
settledAt 落在 [periodStart 00:00:00.000, periodEnd 23:59:59.999]
|
||||
rate > 0
|
||||
未被其他 PREVIEW / CONFIRMED 批次的 cashback_bets 占用
|
||||
```
|
||||
|
||||
**不包含**:PENDING、VOID、CANCELLED、**PUSH** 等。
|
||||
|
||||
周期按 **`settledAt`**,不是 `placedAt`。
|
||||
|
||||
### 8.5 批次汇总
|
||||
|
||||
| 层级 | 公式 |
|
||||
|------|------|
|
||||
| 单笔 | `lineAmount = stake × rate` |
|
||||
| 玩家 | `amount = Σ lineAmount`,`effectiveStake = Σ stake` |
|
||||
| 展示 rate | `amount / effectiveStake`(加权平均,仅展示) |
|
||||
| 平台批次 | `totalAmount = Σ 玩家 amount` |
|
||||
|
||||
### 8.6 发放入账
|
||||
|
||||
确认批次(`confirmBatch`)时:
|
||||
|
||||
| 字段 | 值 |
|
||||
|------|-----|
|
||||
| transactionType | **CASHBACK_DEPOSIT** |
|
||||
| amount | 玩家批次 `item.amount`(正数) |
|
||||
| businessKey | `cashback:{batchNo}:{userId}` |
|
||||
| 效果 | `availableBalance += amount` |
|
||||
|
||||
**平台直充,不扣代理 credit**;confirm **不**调用 `recalculateUsedCredit`。
|
||||
同时将批次内注单 `Bet.isCashbacked = true`。
|
||||
|
||||
### 8.7 数值示例(费率 → 到账)
|
||||
|
||||
| 用例 ID | 场景 | rate | stake 100 | stake 500 | stake 1000 |
|
||||
|---------|------|------|-----------|-----------|------------|
|
||||
| CB001 | 玩家专属规则 | 0.03 (3%) | 3.00 | 15.00 | 30.00 |
|
||||
| CB002 | 玩法专属 FT_HANDICAP | 0.005 (0.5%) | 0.50 | 2.50 | 5.00 |
|
||||
| CB003 | 无规则,代理默认 | 0.02 (2%) | 2.00 | 10.00 | 20.00 |
|
||||
| CB004 | 玩法不匹配回退默认 | 0.01 (1%) | 1.00 | — | — |
|
||||
|
||||
### 8.8 本地 dev seed
|
||||
|
||||
- `agent1` / `agent2` 的 `AgentProfile.cashbackRate` 默认为 schema **0**,seed 未显式设置。
|
||||
- seed **不创建** `CashbackRule`,**不写入** 平台返水 `system_config`。
|
||||
- 本地要产生返水批次,需在管理端配置代理默认比例、CashbackRule 或平台直属费率。
|
||||
|
||||
---
|
||||
|
||||
## 9. 代理授信与金额的间接关系
|
||||
|
||||
```
|
||||
usedCredit = directPlayerLiability + childExposure
|
||||
availableCredit = creditLimit - usedCredit
|
||||
```
|
||||
|
||||
- **directPlayerLiability** = Σ(直属玩家的 `availableBalance + frozenBalance`)
|
||||
- **childExposure** = Σ max(子代理 `creditLimit`, 子代理 `usedCredit`)
|
||||
|
||||
| 事件 | 与返水/结算关系 |
|
||||
|------|----------------|
|
||||
| 玩家结算输/赢 | 改变余额 → 结算后重算 usedCredit |
|
||||
| 返水 confirm | **不**扣代理 credit,**不**即时重算;余额增加后**下次重算**计入负债 |
|
||||
| 代理给玩家上分 | 检查 `availableCredit ≥ amount` |
|
||||
|
||||
**BF005**:玩家输 100 → 玩家 avail **900**;代理 `usedCredit` **1000 → 900**(结算后重算)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 数值对照总表与验证
|
||||
|
||||
### 10.1 派彩速查(stake = 100)
|
||||
|
||||
| 类型 | 场景 | payout |
|
||||
|------|------|--------|
|
||||
| 单关 | 1X2 @2.0 WIN | 200.00 |
|
||||
| 单关 | LOSE | 0.00 |
|
||||
| 单关 | 让球 -1 @1.85 WIN | 185.00 |
|
||||
| 单关 | PUSH | 100.00 |
|
||||
| 单关 | HALF_LOSE | 50.00 |
|
||||
| 单关 | HALF_WIN @1.85 | 142.50 |
|
||||
| 单关 | 小球 @1.95 WIN | 195.00 |
|
||||
| 串关 | 1.8×2.0 全中 | 360.00 |
|
||||
| 串关 | 一关 LOSE | 0.00 |
|
||||
| 串关 | 含 PUSH | 342.00 |
|
||||
| 串关 | 全 PUSH/VOID | 100.00 |
|
||||
|
||||
### 10.2 返水速查(rate × stake)
|
||||
|
||||
| rate | stake 100 | stake 1000 |
|
||||
|------|-----------|------------|
|
||||
| 3% (0.03) | 3.00 | 30.00 |
|
||||
| 2% (0.02) | 2.00 | 20.00 |
|
||||
| 0.5% (0.005) | 0.50 | 5.00 |
|
||||
|
||||
### 10.3 维护与回归命令
|
||||
|
||||
```bash
|
||||
# 打印与本文一致的金额对照表
|
||||
pnpm --filter @thebet365/api audit:settlement
|
||||
|
||||
# 结算引擎单测(含 S016–S019 串关)
|
||||
pnpm --filter @thebet365/api exec jest settlement-calculator.spec.ts --runInBand
|
||||
|
||||
# 全量 smoke(含 S009–S019、CB001–CB004、BF001–BF005)
|
||||
pnpm test:smoke
|
||||
```
|
||||
|
||||
修改 `settlement-calculator.ts`、`cashback-rate.resolver.ts` 或 smoke 期望金额时,**须同步更新本文档**并重新运行上述命令。
|
||||
|
||||
### 10.4 Smoke / 单测用例索引
|
||||
|
||||
| 套件 | ID 范围 | 内容 |
|
||||
|------|---------|------|
|
||||
| settlement | S009–S019 | 让球/大小/串关派彩数值 |
|
||||
| settlement | S011B | HALF_WIN 系数 |
|
||||
| cashback | CB001–CB004 | 费率解析 |
|
||||
| bet-flow | BF001–BF005 | 钱包 + 代理额度端到端 |
|
||||
|
||||
---
|
||||
|
||||
## 附录:支持的 marketType(结算判定入口)
|
||||
|
||||
金额规则与下列盘口共用 `settleSelection`;具体比分判定逻辑见 `settlement-calculator.ts`,本文不展开。
|
||||
|
||||
`FT_1X2`、`HT_1X2`、`FT_ODD_EVEN`、`FT_HANDICAP`、`HT_HANDICAP`、`FT_OVER_UNDER`、`HT_OVER_UNDER`、`FT_CORRECT_SCORE`、`HT_CORRECT_SCORE`、`SH_CORRECT_SCORE`、`HT_FT`、`FT_TOTAL_GOALS`、球队进球、角球/牌数相关盘、`OUTRIGHT_WINNER` 等。
|
||||
|
||||
未知 marketType 默认腿级结果 **LOSE**(payout = 0)。
|
||||
@@ -69,6 +69,8 @@
|
||||
|
||||
## 三、默认赛事与盘口
|
||||
|
||||
各玩法判赢规则与 18 种盘口完整说明见 [投注玩法说明.md](./投注玩法说明.md)。
|
||||
|
||||
### 联赛
|
||||
|
||||
| 代码 | 名称 |
|
||||
|
||||
Reference in New Issue
Block a user