包含 NestJS 后端、三端前端、Prisma 数据模型、结算引擎测试与 PRD 文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
58 KiB
足球投注平台产品需求与 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 产品目标
搭建一个足球投注平台,支持平台后台、代理后台、玩家前台三类核心端口。
核心业务流程:
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 第一版产品原则
- 先稳定后丰富:第一版不追求 Bet365 的完整功能,只参考其成熟的信息架构与下注体验。
- 账务不可直接改余额:所有余额变化必须来自账变流水,不允许直接编辑钱包余额。
- 赔率必须快照化:玩家确认下注时锁定赔率、盘口、玩法、选项、赔率版本。
- 结算必须可回溯:每张注单的结算依据、比分、操作人、时间、重结算记录都必须留存。
- 代理必须受额度控制:代理不能无限给下级或玩家上分,额度可为负展示,但负数状态禁止继续放款。
- 多语言从底层设计:界面文本、赛事名称、球队名称、Banner、公告、规则说明均支持多语言字段和 fallback。
- 第一版以移动端 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 代理权限边界
- 代理只能创建和操作直属下级。
- 一级代理可以创建二级代理和直属玩家。
- 二级代理只能创建直属玩家。
- 一级代理不能直接给二级代理名下玩家上分,除非该玩家是一级代理直属玩家。
- 下级代理的额度、回水比例、单笔限额、日限额不能超过上级授权范围。
- 代理不能修改赛事、盘口、赔率、开奖结果。
- 代理不能撤销玩家已结算注单。
- 代理账号被禁用后,其下级玩家可以继续登录还是一起冻结,需要后台配置;MVP 默认只禁用该代理操作权限,不自动冻结玩家。
3. 多语言与本地化
3.1 支持语言
| 语言 | Locale | 前台显示 | 备注 |
|---|---|---|---|
| 简体中文 | zh-CN |
中文 | 默认候选语言。 |
| 马来语 / Bahasa Melayu | ms-MY |
Bahasa Melayu | 用户所说“马来西亚语”按马来语处理。 |
| 英文 | en-US |
English | 默认 fallback 语言。 |
3.2 语言切换规则
- 登录页、前台首页、玩家中心均提供语言切换。
- 未登录用户:语言选择保存到浏览器 localStorage / cookie。
- 已登录用户:语言选择保存到用户偏好
user_preferences.locale。 - 后台也支持同三种语言,但第一版后台可以优先中文 + 英文,马来语可后补。
- 内容缺失时 fallback 顺序:当前语言 → 英文 → 中文。
- 后台维护赛事、球队、联赛时,至少录入一个主语言名称,其他语言可为空。
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。
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 赛事详情页
赛事详情页按盘口分组展示:
- 全场独赢盘
- 全场让球
- 全场大/小
- 全场单/双
- 半场独赢盘
- 半场让球
- 半场大/小
- 波胆
- 上半场波胆
- 下半场波胆
每个盘口组支持折叠/展开。赔率按钮显示:选项名、盘口线、赔率。
4.7 投注单交互
| 场景 | 交互 |
|---|---|
| 用户点击赔率 | 加入投注单;同一场同一盘口重复点击则取消选择。 |
| 单个选择项 | 展示单关投注金额输入框。 |
| 多个选择项 | 展示每项单关输入 + 串关区域。MVP 可默认只打开串关输入。 |
| 同场多个选项 | 投注单提示“同一场比赛不能串关”,但可分别作为单关投注。 |
| 赔率变化 | 提交时校验赔率版本;变化则提示重新确认。 |
| 盘口封盘 | 提交时提示盘口已关闭并移除该选择项。 |
| 余额不足 | 禁止提交并提示余额不足。 |
| 下注成功 | 展示注单号、投注金额、赔率、预计返还、投注时间。 |
5. 赛事、盘口与赔率管理
5.1 赛事结构
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 自动封盘
- 默认在
start_time到达时自动封盘。 - 后台可提前手动封盘。
- 投注提交时必须二次校验比赛状态、盘口状态、选项状态、赔率版本。
- 后台开赛时间修改后,需要重新计算封盘任务。
5.5 赔率管理规则
- 所有赔率使用十进制赔率 Decimal Odds,例如
1.85、2.10。 - 后台修改赔率时生成新的
odds_version。 - 已下注订单使用投注时快照,不受后续赔率修改影响。
- 赔率最低值、最高值后台配置,避免误填。
- 赔率必须大于
1.00。 - 已发布赛事修改赔率需二次确认。
- 支持批量编辑波胆赔率,类似表格/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 | 后台选择冠军 | 是 | 否 |
串关条件支持说明:
- 只支持
2 串 1到5 串 1。 - 不允许同一场比赛的多个选项进入同一串关单。
- 四分之一让球 / 四分之一大小球不允许进入串关,例如
-0.25、-0.75、2.25、2.75。 - 冠军竞猜不允许进入串关。
- 已封盘、暂停、赔率变化未确认的选项不能提交。
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 “其他比分”结算规则
- 如果最终比分命中模板中的具体比分,具体比分选项赢,其他比分选项输。
- 如果最终比分不在模板具体比分中,则按结果归类:
- 主队胜且不在具体比分中:其他主胜赢。
- 客队胜且不在具体比分中:其他客胜赢。
- 平局且不在具体比分中:其他平局赢。
6.3 全场让球 / 半场让球
让球采用亚洲让球两项盘。
| 项目 | 规则 |
|---|---|
| 全场让球 | 使用全场比分结算。 |
| 半场让球 | 使用半场比分结算。 |
| 盘口值 | 支持整数、半球、四分之一球。 |
| 单关 | 支持全赢、半赢、走水、半输、全输。 |
| 串关 | 第一版只允许整数和半球盘口进入串关;四分之一球不允许串关。 |
盘口值示例:0、-0.25、-0.5、-0.75、-1、+0.25、+0.5、+0.75、+1。
让球结算公式:
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 单关注单流程
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 投注校验
提交下注时后端必须校验:
- 玩家账号状态为正常。
- 玩家所属代理链状态正常。
- 比赛状态为已发布且未封盘。
- 盘口状态为开放。
- 选项状态为开放。
- 前端提交的
odds_version与数据库当前版本一致。 - 投注金额满足最小/最大单注限制。
- 玩家可用余额足够。
- 不超过玩家每日投注限额。
- 不超过盘口单项最大投注额。
- 不超过平台单注最高预计派彩。
- 请求幂等号
request_id未被使用。
7.3 赔率变化处理
第一版采用严格校验方式:
| 情况 | 处理 |
|---|---|
| 赔率未变化 | 正常下注。 |
| 赔率已变化 | 拒绝下注,返回最新赔率,提示玩家重新确认。 |
| 盘口已封盘 | 拒绝下注,从投注单移除。 |
| 选项已暂停 | 拒绝下注,提示该选项不可下注。 |
7.4 投注金额与预计返还
十进制赔率下:
预计返还 = 投注金额 × 赔率
预计盈利 = 投注金额 × (赔率 - 1)
示例:投注 100,赔率 1.85。
预计返还 = 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 串关计算
如果所有选择项赢:
串关返还 = 投注金额 × 赔率1 × 赔率2 × ... × 赔率N
串关盈利 = 串关返还 - 投注金额
如果任意一关输:
串关注单 = 输
返还 = 0
如果某一关走水 / 取消 / 作废:
该关赔率按 1.00 计算,其余关继续结算
如果所有关都走水 / 取消 / 作废:
整张串关注单退还本金
示例:
| 关数 | 原赔率 | 结果 | 有效赔率 |
|---|---|---|---|
| 1 | 1.80 | 赢 | 1.80 |
| 2 | 2.00 | 走水 | 1.00 |
| 3 | 1.90 | 赢 | 1.90 |
投注 100:
返还 = 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 结算流程
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 重结算与冲正
如果比分录错或结算错误,允许超级管理员重结算。
重结算规则:
- 不允许直接改余额。
- 必须生成反向冲正账变。
- 必须保留原结算记录和新结算记录。
- 必须记录操作原因。
- 重结算前生成影响预览:影响玩家数、注单数、需扣回金额、需补发金额。
- 如果玩家余额不足以扣回,应形成负余额或异常待处理;MVP 默认允许负余额展示并冻结提现/下分。
10. 钱包、账变与代理额度
10.1 玩家钱包
玩家钱包字段:
| 字段 | 说明 |
|---|---|
| available_balance | 可用余额,可下注金额。 |
| frozen_balance | 冻结金额,未结算投注本金。 |
| total_balance | 总余额 = 可用余额 + 冻结金额。 |
| currency | 币种。 |
| status | 正常、冻结、禁用。 |
下注时:
available_balance -= stake
frozen_balance += stake
结算赢:
frozen_balance -= stake
available_balance += payout
结算输:
frozen_balance -= stake
available_balance += 0
走水/作废:
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_iduser_idwallet_idtransaction_typeamountbalance_beforebalance_afterfrozen_beforefrozen_afterreference_typereference_idoperator_idremarkcreated_at
10.3 代理额度模型
第一版采用信用额度池,不把代理额度等同于真实资金账户。
核心字段:
| 字段 | 说明 |
|---|---|
| credit_limit | 上级授予该代理的总额度。 |
| used_credit | 已占用额度。 |
| available_credit | 可用额度 = credit_limit - used_credit。 |
| direct_player_liability | 直属玩家总余额占用。 |
| child_agent_exposure | 下级代理占用。 |
| status | 正常、额度不足、冻结、禁用。 |
推荐公式:
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)
解释:
- 代理给玩家上分,玩家总余额增加,代理额度被占用。
- 玩家下注时,可用余额变成冻结金额,总余额不变,因此代理额度不变。
- 玩家输掉,玩家总余额减少,代理额度释放。
- 玩家赢了,玩家总余额增加,代理额度进一步占用。
- 代理给下级代理分配额度,会占用自己的额度。
- 如果下级代理因玩家赢钱导致实际占用超过其授信额度,上级看到的下级占用按更大的实际占用计算。
- 代理额度可以显示为负数,但负数时禁止继续上分或继续给下级分配额度。
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 有效投注额口径
计入有效投注额:
- 已结算且非作废注单。
- 赢单、输单、半赢、半输均按原始投注金额计入。
- 串关注单按串关本金计入一次。
不计入有效投注额:
- 未结算注单。
- 已取消注单。
- 作废退款注单。
- 全走水注单。
- 重结算冲正流水本身。
11.3 返水批次流程
flowchart LR
A[选择周期] --> B[系统统计有效投注额]
B --> C[生成返水预览]
C --> D[财务确认]
D --> E[生成返水批次]
E --> F[逐玩家入账]
F --> G[生成账变流水]
G --> H[玩家前台查看返水记录]
12. 后台管理功能
12.1 平台后台模块
| 模块 | 功能 |
|---|---|
| 控制台 | 今日投注额、派彩额、平台盈亏、待结算赛事、异常注单、代理额度预警。 |
| 用户管理 | 玩家列表、新增玩家、禁用/启用、重置密码、查看钱包、查看注单、查看账变。 |
| 代理管理 | 新增代理、代理层级树、授信额度、回收额度、代理报表、禁用代理。 |
| 财务管理 | 上分、下分、账变流水、额度流水、人工调整、导出报表。 |
| 赛事管理 | 联赛、球队、比赛、开赛时间、热门标记、发布/封盘/取消。 |
| 盘口管理 | 为比赛启用玩法模板、录入盘口值、录入赔率、批量修改。 |
| 开奖结算 | 录入半场/全场比分、生成预览、确认结算、查看结算日志、重结算。 |
| 注单管理 | 单关注单、串关注单、按玩家/代理/赛事/状态筛选。 |
| 返水管理 | 返水比例配置、生成返水批次、确认发放、返水记录。 |
| 内容管理 | Banner、公告、走马灯、多语言内容、排序、上下架。 |
| 多语言管理 | 语言包 key、翻译缺失检查、导入导出。 |
| 系统设置 | 限额配置、赔率范围、串关规则、币种、小数位、时区。 |
| 操作日志 | 查询所有后台、代理后台关键操作记录。 |
12.2 赛事创建流程
flowchart TD
A[创建联赛/选择联赛] --> B[创建比赛]
B --> C[选择主队/客队]
C --> D[设置开赛时间]
D --> E[选择玩法模板]
E --> F[系统生成盘口结构]
F --> G[批量录入赔率]
G --> H[保存草稿]
H --> I[发布比赛]
12.3 盘口模板
后台创建比赛时,建议提供一键生成模板:
| 模板 | 自动生成内容 |
|---|---|
| 全场独赢盘 | 主胜、平局、客胜。 |
| 半场独赢盘 | 主胜、平局、客胜。 |
| 全场让球 | 主队、客队,需填写盘口值和赔率。 |
| 半场让球 | 主队、客队,需填写盘口值和赔率。 |
| 全场大/小 | 大、小,需填写盘口线和赔率。 |
| 半场大/小 | 大、小,需填写盘口线和赔率。 |
| 全场单/双 | 单、双。 |
| 波胆 | 按固定比分模板生成选项。 |
| 上半场波胆 | 按半场比分模板生成选项。 |
| 下半场波胆 | 按半场比分模板生成选项。 |
| 冠军竞猜 | 批量添加参赛队伍。 |
12.4 高危操作二次确认
以下操作必须二次确认并写入操作日志:
- 大额上分/下分。
- 代理额度调整。
- 已发布赛事修改开赛时间。
- 已发布赛事修改赔率。
- 手动封盘。
- 取消赛事。
- 确认结算。
- 发起重结算。
- 发放返水批次。
- 禁用代理或玩家。
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 注单主表关键字段
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 注单明细表关键字段
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 下注事务要求
下注必须在单个数据库事务内完成:
- 锁定玩家钱包行。
- 校验余额。
- 校验比赛/盘口/选项状态。
- 校验赔率版本。
- 创建注单。
- 创建注单明细。
- 扣减可用余额、增加冻结金额。
- 创建账变流水。
- 提交事务。
15.3 结算事务要求
确认结算建议按批处理执行,但每批必须保证一致性:
- 锁定待结算注单。
- 防止重复结算。
- 计算返还金额。
- 更新注单状态。
- 更新钱包余额。
- 生成账变流水。
- 更新代理额度统计。
- 写入结算日志。
16. 报表需求
16.1 平台报表
| 报表 | 维度 |
|---|---|
| 平台投注汇总 | 日期、玩法、联赛、代理线、币种。 |
| 平台盈亏报表 | 投注额、派彩额、返水额、平台净盈亏。 |
| 待结算报表 | 比赛、开赛时间、待结算注单数、预估风险。 |
| 玩家报表 | 玩家余额、投注额、输赢、返水、上分/下分。 |
| 代理报表 | 代理额度、可用额度、下级余额、下级投注额、下级输赢。 |
| 盘口报表 | 每场比赛每个盘口投注分布。 |
| 串关报表 | 串关投注额、派彩额、最高风险。 |
| 账变报表 | 所有余额变动流水。 |
16.2 代理报表
代理后台至少展示:
- 当前总额度。
- 已用额度。
- 可用额度。
- 直属玩家总余额。
- 下级代理额度占用。
- 今日投注额。
- 今日派彩额。
- 今日玩家输赢。
- 下级玩家注单列表。
- 上分/下分记录。
16.3 玩家报表
玩家前台展示:
- 当前余额。
- 未结算投注。
- 已结算投注。
- 赢/输/走水/作废状态。
- 账变流水。
- 返水记录。
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:项目基础
交付内容:
- 前后台项目结构。
- 数据库初始化。
- 登录鉴权。
- RBAC 权限框架。
- 多语言框架。
- 操作日志基础能力。
- 钱包和账变基础表。
阶段 1:账号、代理、钱包
交付内容:
- 平台后台创建玩家。
- 平台后台创建一级代理。
- 一级代理创建二级代理和玩家。
- 二级代理创建玩家。
- 代理额度池。
- 玩家上分/下分。
- 钱包流水。
- 代理额度流水。
验收重点:代理权限隔离、额度计算、账变一致性。
阶段 2:赛事、盘口、赔率
交付内容:
- 联赛管理。
- 球队管理。
- 比赛管理。
- 盘口模板。
- 波胆批量赔率编辑。
- 发布/封盘/取消。
- 前台赛事列表。
- 前台赛事详情。
验收重点:赔率版本、封盘状态、多语言名称。
阶段 3:下注引擎
交付内容:
- 投注单 UI。
- 单关下注。
- 串关下注。
- 投注限额。
- 赔率变化提示。
- 注单列表和详情。
- 钱包冻结。
验收重点:幂等、余额冻结、同场串关限制、四分之一球串关限制。
阶段 4:结算引擎
交付内容:
- 录入半场/全场比分。
- 结算预览。
- 单关结算。
- 串关结算。
- 作废退款。
- 重结算冲正。
- 结算日志。
验收重点:所有玩法结算准确、重复结算防护、冲正账变。
阶段 5:返水、报表、内容
交付内容:
- 返水规则。
- 返水预览。
- 返水确认发放。
- 平台报表。
- 代理报表。
- 玩家账单。
- Banner。
- 公告和走马灯。
- 多语言内容管理。
验收重点:返水有效投注额口径、报表与账变一致。
阶段 6:UAT 与上线准备
交付内容:
- 测试账号。
- 测试赛事。
- 全玩法测试用例。
- 压测下注接口。
- 压测结算批次。
- 数据备份策略。
- 上线回滚方案。
- 后台操作培训文档。
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 后端建议
- 第一版采用单体后端,不建议微服务。
- 下注、结算、钱包、额度必须使用数据库事务。
- Redis 可用于会话、缓存、接口限流、封盘任务锁,但不能作为唯一账务来源。
- 账务金额使用
DECIMAL(18,4)或更高精度,禁止使用浮点数。 - 赔率使用
DECIMAL(18,6)。 - 所有核心表使用软删除或状态字段,不物理删除。
- 所有账务接口必须写操作日志。
23.2 前端建议
- 玩家前台优先移动端 H5。
- 投注单做成全局状态,切换页面不丢失。
- 投注提交后必须刷新余额和注单状态。
- 赔率变化时清晰提示,不自动替玩家接受新赔率。
- 多语言使用统一 i18n key,不把文案写死在组件里。
- 波胆区域需要折叠和分组,否则页面过长。
23.3 测试建议
- 结算引擎必须做单元测试。
- 钱包和代理额度必须做集成测试。
- 串关必须做全流程测试。
- 上线前用固定比分回归全部玩法。
- 重结算必须单独测试冲正逻辑。
- 并发下注必须压测。
24. 最终 MVP 业务规则定稿
以下规则作为第一版不可变更的默认规则,除非重新评审:
- 足球普通赛事只按常规时间结算,即 90 分钟 + 伤停补时,不含加时和点球。
- 半场玩法只按上半场比分结算。
- 下半场波胆按下半场净比分结算。
- 全场 0-0 的单/双结果为双。
- 所有下注按下注时赔率快照结算。
- 赔率变化必须重新确认,不能默认接受。
- 开赛时间到达后自动封盘。
- 后台录入比分后必须先生成结算预览,再确认入账。
- 结算错误只能通过重结算和冲正账变修正,不能直接改余额。
- 串关只支持 2-5 串 1。
- 串关不允许同场。
- 串关不允许冠军竞猜。
- 串关不允许四分之一让球/大小球。
- 串关中走水或作废的关卡按赔率 1.00 处理。
- 玩家下注时冻结本金,结算后释放冻结并派彩/扣除/退款。
- 代理采用信用额度池。
- 玩家余额变化会影响所属代理额度占用。
- 代理额度可以为负展示,但负数时禁止继续上分和分配额度。
- 玩家返水按有效投注额计算,后台确认后发放。
- 第一版不做滚球、系统串关、自动赔率源、自动赛果源、Cash Out、Edit Bet、Bet Builder。