Skip to content

00 · 架构总纲

0. 文档说明

内容
版本V1.0

本篇是全部系统设计的地基与总目录。任何单系统文档的疑问,先回到本篇的三层模型与通用约定。


一、定位与职责

BetCorgi 是一套多商户链游包网平台(multi-tenant white-label):平台方提供一份核心能力引擎与全套运营能力,支撑几十至上百套独立运营的子平台(租户/商户)。领域为链游/娱乐场——三方游戏聚合、优惠、返水、VIP、充提;不引入其他业态假设。

本篇定义:

  • 全平台的分层架构(三层模型)与两个平面(用户端 App / 运营后台);
  • 各业务系统之间的关系(系统全景,00–17);
  • 全部系统必须共同遵守的通用设计约定(配置驱动、币种无关、状态机、幂等、审计、事件、命名、数据隔离、降级)。

不做什么:本篇不展开任一具体系统的字段与规则,那是 01–17 各分册的事。


二、多商户三层模型(核心)

                        ┌───────────────────────────────────────────┐
   ③ 展示层             │  用户端 App(H5)     运营后台(→15)        │
   Presentation         │  纯渲染:读「租户配置 + 引擎数据」出界面    │
                        │  换皮、换布局、换文案 → 不碰引擎            │
                        └───────────────▲───────────────────────────┘
                                        │ 读配置 + 数据
                        ┌───────────────┴───────────────────────────┐
   ② 租户配置层         │  Tenant Config(每租户一份,继承+覆盖)     │
   Tenant Config        │  功能开关 / 币种 / 活动 / 等级门槛 / 费率   │
                        │  主题 / 布局 / 文案 / 合规区域 / 灰度       │
                        └───────────────▲───────────────────────────┘
                                        │ 配置注入(引擎读租户配置执行)
                        ┌───────────────┴───────────────────────────┐
   ① 核心能力引擎       │  Capability Engine(全租户共享)            │
   Capability Engine    │  规则 + 状态机 + 数据模型                   │
                        │  与租户/币种/主题无关,只认「配置 + 事件」  │
                        └───────────────────────────────────────────┘

2.1 三层各自的铁律

允许禁止
① 引擎定义规则、状态机、数据模型;读租户配置参数执行❌ 硬编码任何租户专属数值/文案/币种/费率;❌ 感知主题与布局
② 配置声明「这个子平台开什么、值多少、长什么样」❌ 写业务逻辑;❌ 直接操作数据
③ 展示渲染、交互、动效;按配置切皮换布局❌ 前端写死业务规则/汇率/费率;❌ 绕过引擎改数据

判断一段逻辑该放哪层:换一个子平台会不会变?会变 → 配置层。所有子平台都一样的算法 → 引擎层。只影响长相 → 展示层。

2.2 为什么这样分

  • 开新站近乎零开发:新子平台 = 复制默认配置模板 + 改差异项,不 fork 代码。
  • 引擎一处升级、全站受益:返水算法优化一次,上百个子平台同时生效。
  • 展示随便换皮不伤筋骨:UI/主题/布局是配置 + 设计系统的产物,不回灌业务。

2.3 两个平面(同一引擎的两类客户端)

平面使用者形态职责
用户端 App玩家移动 H5(原型 global.html)玩、充提、领奖
运营后台平台方 / 商户运营者桌面 Web(→ 15 运营后台)平台控制台:建站、模板/预设、跨租户管理;商户控制台:本站配置、活动、财务审核、报表

两个平面共用同一引擎与配置层,后台也是展示层的一种客户端——它多出的能力是「写配置、审工单」,同样不内嵌业务规则。运营后台在本项目范围内,详设归 15。

现有 global.html 原型即「Global 租户 · CNY 站(本位币 = CNY)」的一次用户端渲染。参见 01-多商户与租户配置


三、系统全景(00–17)

                          ┌─────────────────────────────┐
                          │ 01 多商户与租户配置(地基)  │  ← 所有系统读它
                          └──────────────┬──────────────┘
        ┌──────────────┬────────────────┼────────────────┬──────────────┐
        ▼              ▼                 ▼                ▼              ▼
 ┌─────────────┐ ┌───────────┐  ┌───────────────┐ ┌───────────┐ ┌─────────────┐
 │05 账户/认证 │ │02 货币/钱包│  │12 游戏聚合    │ │06 等级    │ │09 优惠活动  │
 └──────┬──────┘ └─────┬─────┘  └───────┬───────┘ └─────┬─────┘ └──────┬──────┘
        │              │                │               │              │
        │        ┌─────┴─────┐          │        ┌──────┴──────┐       │
        │        ▼           ▼          │        ▼             ▼       │
        │  ┌──────────┐ ┌──────────┐    │  ┌──────────┐ ┌──────────┐   │
        │  │03 充值   │ │04 提现   │    │  │07 VIP俸禄│ │08 实时返水│   │
        │  └──────────┘ └──────────┘    │  └──────────┘ └──────────┘   │
        │                               │                              │
        │                        ┌──────┴──────┐                       │
        │                        ▼             ▼                       │
        │                  ┌──────────┐  ┌──────────┐                  │
        └─────────────────►│10 任务   │  │11 返佣   │◄─────────────────┘
                           └──────────┘  └──────────┘
                                  │             │
                                  ▼             ▼
                          ┌───────────────────────────┐
                          │ 13 记录与账变(账本底座)  │  ← 所有资金/权益动作留痕
                          └───────────────────────────┘
 ────────────────────────── 横切平面 ──────────────────────────
  14 风控与反作弊 —— 卡在一切「领取/派发/提现」路径上的前置校验
  15 运营后台 —— 全系统的管理面(平台控制台 + 商户控制台)
  16 消息通知 —— 订阅领域事件,站内信/推送
  17 数据看板 —— 聚合 13 流水,商户报表 + 平台经营视图

依赖关系速查

  • 02 货币/钱包是资金底座:03/04/07/08/09/10/11/12 的任何金额进出都经它记账。
  • 06 等级是权益底座:07 俸禄、08 返水、09 部分活动的档位都读用户等级。
  • 12 游戏聚合产出投注/输赢流水 → 驱动 08 返水、10 打码进度(06 成长值由充值驱动,→ 06 升级)。
  • 13 记录与账变是账本:一切余额变化写不可变流水,对账与展示都读它。
  • 14 风控是闸门:领取、派发、提现在入账前必须过风控前置校验。
  • 15 后台读写 01 配置、驱动 04 提现审核与 02 人工调整,一切操作留审计。
  • 17 看板只读:聚合 13 的流水与各系统快照,不产生业务写操作。

四、通用设计约定(全系统强制)

4.1 配置驱动(Config over Code)

任何「不同子平台可能不一样」的量都必须来自租户配置,禁止散落在引擎/前端。包括但不限于:金额、费率、比例、门槛、开关、文案、图标、精度、时区、合规限制。配置项命名以系统命名空间为前缀,如 wallet.currenciesvipSalary.levels[].dailyAmount

4.2 币种无关(Currency-agnostic)+ 单币种站型

引擎内部一律以 { amount, currency } 表达金额,禁止裸数字、禁止隐含币种、禁止前端/引擎写死汇率

  • 一租户 = 一「本位币站」:站内全链路单币种、单账户(本位币 baseCurrency,取 CNY 站 / USDT 站),站内无换算、无第二币种符号、一人一钱包;等级/俸禄/任务/统计一律本位币单口径。
  • 换算只发生在两个「钱包边界」,均锁价 + 快照 + 审计:充值(通道币种可 ≠ 本位币,下单时点锁价折入)、提现(本位币按提现时点锁价折出到通道币种);站内不提供币币兑换。
  • 展示铁律:已发生金额永远带「出生币种」,不重标、不换算;禁止「数字不变只换符号」的渲染
  • 平台跨站层面是多币种(不同站不同本位币),平台看板/跨租户对账「按币种分列」(→ 17);单站内部为单币种口径。 详见 02-货币与钱包系统

4.3 状态机优先(State machine)

凡有生命周期的实体(租户、活动、领取、充值、提现、任务、彩金、工单)必须显式定义状态枚举 + 允许的流转 + 触发条件,不用零散布尔位拼状态。每篇分册用状态图表达。

4.4 幂等与一致性(Idempotency)

一切资金/权益写操作(领取、派发、入账、扣款)必须幂等:携带业务唯一键(如 claimId),重复请求不重复入账。领取类动作先扣「可领资格」再入账,失败可重放。数据库层以 (tenant_id, op_code, biz_key) 唯一约束兜底。

4.5 审计留痕(Auditability)

余额或权益的每次变化写 13 账变流水(谁、何时、因何事件、变动前后值),不可变、可对账。后台侧一切配置变更与人工操作写 15 审计日志(谁改了哪个租户的哪项、前后值)。

4.6 事件驱动解耦(Event-driven)+ 事件登记表

系统间用领域事件通信,不直接互调内部逻辑。新事件必须先在本表登记再使用;载荷一律含 eventId / tenantId / occurredAt

事件生产者主要消费者载荷关键字段幂等键
UserRegistered0509(新手活动)、11(绑定上级)、16userId, channel, ref(短链 slug 归因,无邀请码)userId
DepositSucceeded0302(入账)、06(成长值)、09(充值活动)、11、16orderId, currency, amount, isFirstOverall(该租户首笔), isFirstOfKind(法币/加密各自首笔)orderId
WithdrawCompleted0416、17withdrawId, currency, amountwithdrawId
BetSettled1208(返水)、10(打码)、17(报表)betId, gameType, vendor, currency, validTurnover, winLossbetId
BetCancelled1208(冲正)、10(冲正)、17(修正)betId, reasonbetId+cancelSeq
LevelChanged0607(俸禄档位)、08(返水率)、16userId, fromLevel, toLevel, reason(UP/DOWN/ADJUST)userId+changeSeq
RewardClaimed07/08/09/10/1102(入账)、13、14(事后画像)、16claimId, source, currency, amount, target(available/bonus)claimId
BonusUnlocked10(打码引擎)02(转可用)、16grantId, currency, amountgrantId
RiskFlagged14相关系统(拦截/冻结)、15(工单)flagId, userId, ruleId, actionflagId

登记表口径锁定(全库唯一源,各分册对齐本表):

  • BonusUnlocked 生产者 = 10 打码引擎:10 判定打码达标 → 调用 02 执行 BONUS_UNLOCK 入账(bonus→available)→ 由 10BonusUnlocked(幂等键 grantId),02 §2.4 状态机的「发 BonusUnlocked」即指此步由 10 触发(打码进度权威 = 10 wagering_obligations,02 bonus_grantswagering_progress 为冗余展示,以 grantId 关联)。
  • LevelChanged.reason 枚举 = {UP, DOWN, ADJUST}(无 KEEP——保级维持不发事件;ADJUST = 人工调级,→ 06/16)。
  • DepositSucceeded 载荷含 isFirstOverall(该租户首笔)+ isFirstOfKind(法币/加密各自首笔) 两布尔(不用单一 isFirst,供 09 区分首存/钱包首入/虚拟币首入,→ 03/09)。
  • BetCancelled 幂等键 = betId+cancelSeq(同注单可多次/部分取消,08/10/12 消费方均以此为准)。

4.7 展示契约(Presentation Contract)

每篇分册末列出「驱动 UI 的字段」及其到原型 DOM/JS 的映射,前端据此对接,以字段为准而非截图。

4.8 命名与单位约定

  • 金额:存储用高精度定点小数 DECIMAL(32,8);API 传输一律字符串(如 "888.88"),禁止 float;展示精度由本位币 wallet.decimals 决定,内部精度高于展示精度。逐笔金额恒带「出生币种」(→ §4.2 展示铁律)。
  • 比例/费率:统一用小数(0.006 表示 0.6%),展示时格式化。
  • 时间:存储 UTC,展示按 tenant.timezone
  • 标识:业务唯一键统一 xxxId;枚举用大写下划线常量;表字段蛇形命名。

4.9 数据隔离与租户上下文

  • 默认:共享库表 + 行级隔离 —— 所有业务表强制 tenant_id;业务唯一键一律做成 (tenant_id, …) 复合唯一;数据访问层(DAL/中间件)强制注入租户过滤,不依赖开发者手写 WHERE
  • 请求链路:入口按域名解析出 tenantId(→ 01 §2.4),写入请求上下文,贯穿到存储层。
  • 逃生口:超大租户或强合规区域可整租户拆库(同 schema、独立实例),对引擎透明。
  • 用户、钱包、KYC、流水等一切数据按租户强隔离;同一自然人在不同子平台默认是两套独立账户。

4.10 错误与降级

  • 配置缺键:合并链保证任何键都有默认模板兜底值(→ 01 §四),引擎不因缺键崩溃。
  • 引擎/下游异常:展示层展示兜底态(如「暂时无法领取,请稍后再试」),禁止前端自行估算金额或跳过校验。
  • 三方游戏厂商故障:该厂商标记维护中,不影响其他厂商与平台功能(→ 12)。

五、租户配置解析链路(引擎如何拿到「这个站的值」)

默认模板配置(平台级基线)
      │  继承

区域/行业预设 Preset(可选)
      │  继承

租户覆盖配置(该子平台的差异项)
      │  继承

灰度 / A-B / 站点覆盖(可选)
      │  合并(深合并,后者覆盖前者;合规层只收紧不放开)

有效配置 EffectiveConfig(引擎与前端实际读到的)

合并规则、域名→租户解析、bootstrap 契约、版本灰度回滚详见 01-多商户与租户配置


六、端到端示例:领取 VIP 俸禄(一次走通三层)

① 展示层(App)   用户在「奖励中心·VIP俸禄」点【领取日俸禄】
                  POST /rewards/vip-salary/claim  { claimId: "cs-20260713-u1001-daily" }
② 引擎·校验      读 EffectiveConfig:vipSalary.enabled?
                  用户等级 V18 → vipSalary.levels[18].daily = 888(本位币口径,本站 = CNY 站)
                  读状态:今日未领?保级打码达标?(规则归 06/07)
③ 风控前置(14)  领取频次 / 设备指纹 / 黑名单 检查 → 放行
④ 记账(02+13)   REWARD_CREDIT(available, +888 CNY, 幂等键=claimId) → 写账变流水
⑤ 事件(§4.6)    发 RewardClaimed{claimId, source: VIP_SALARY, currency: CNY, amount: "888"}
                  → 16 到账通知 · 17 看板计数 · 14 事后画像
⑥ 展示层回显     余额胶囊 +888 · 按钮转「明日可领」倒计时 · 奖励 tab 红点按新状态刷新
  • 用户重复点击(同 claimId)→ ④ 幂等返回首次结果,不重复入账。
  • 改这条链路的方式:改各级俸禄额 → 只改②的租户配置;改风控阈值 → 只改 14 的规则;改按钮文案样式 → 只动展示层。三层互不惊动——这就是分层的意义。

七、术语表

术语含义
包网平台方提供整套技术与运营能力,商户「租用开站」独立运营的模式
租户 / 商户 / 子平台一套独立运营的站点实例,拥有独立配置、用户、账本、域名
平台控制台 / 商户控制台运营后台的两侧:平台方管全局;商户运营者管自己站(→ 15)
引擎 / 能力全租户共享的业务逻辑与数据模型
有效配置 EffectiveConfig默认模板 + 预设 + 租户覆盖 + 灰度合并后的最终配置
本位币 baseCurrency站的唯一记账与展示币种;站内全链路单币种
站型CNY 站 / USDT 站(= 本位币取值),一租户一站型,建站锁定
通道币种 channelCurrency充值/提现通道对外收付的币种,可 ≠ 本位币,边界锁价
链路 route场馆向厂商申报币种的选择:原生 / CNY 映射(→ 12)
映射 mappingCNY 映射链路下 1:1 标签替换(非换算、无小数、进出等值可逆)
锁价 lockedRate边界事件发生时点快照的汇率,存单据、可审计
钱包 Wallet用户在本站本位币下的资金账户(可用 + 彩金 + 冻结);单币种站一人一钱包
打码 / 流水有效投注额,用于解锁彩金、保级、返水计算
幂等键资金/权益写操作的业务唯一键,重复请求不重复生效
工单后台侧需审批的操作(资金调整、提现审核等),有自己的状态机(→ 15)
展示契约分册末定义的「字段 → UI」映射,前端对接依据

八、扩展点与开放问题

  • 区域合规:不同地区对活动/币种/KYC 有强监管差异,配置层已留「合规强制层」,细则待 05 展开。
  • 多语言:文案入配置层 + i18n 字典;以配置层文案键为准。
  • 事件基础设施:事件的投递保证(至少一次 + 消费端幂等)与重放机制,属技术选型,文档只约束语义。
  • 展示层金额渲染:各分册「展示契约」定义前端对接标准;资金面禁止「数字不变只换符号」的重刷(只格式化本位币,不做符号替换,→ 02 展示铁律)。