Files
hfb_sys/docs/分销网管理后台设计方案.md
yml2213 2a76d59a30 feat(distribution): 公告中心支持分站自定义
公告中心(前台公告列表/详情)此前完全没有站点概念,分站访客只能看到主站公告。
本次按「默认继承主站、站长可切仅本站」的口径支持分站自定义。

数据与口径:
- 新增 announcements.distribution_site_id(0=主站),前台按站点隔离
- 新增 distribution_sites.announcement_mode:inherit(默认,主站+本站)/ own_only(仅本站)

后端:
- 公告模块新增 ResolvePublicSiteScope:主站 [0]、inherit [0, siteID]、own_only [siteID],
  站点编码无效/已停用回落主站;列表与详情都按该范围过滤,详情不再允许跨站按 ID 读取
- 管理端公告列表支持按站点筛选(site_id:不传=全部,0=主站,>0=分站)并带出站点名
- 分销模块新增本站公告 CRUD(distribution/announcement.go):强制 distribution_site_id=本站,
  先过 ensureSiteAccess,跨站更新/删除/上下架一律 ErrAnnouncementNotFound
- UpdateSiteBranding 支持 announcement_mode 切换(非法值报错,读侧非法历史值回落 inherit)
- 新增权限 distribution:announcement_view|manage 并授予 super_admin/ops/finance,
  站长开通时继承 ops 角色即自动获得
- 路由:站长侧 /api/distribution/announcements*,平台侧 /api/admin/distribution/announcements*

前端:
- 分销后台新增「公告中心」页:来源开关(继承主站+本站 / 仅本站)、本站公告列表与
  新建/编辑/发布/下架/归档/恢复/删除,空态按来源模式给出引导
- 平台后台公告页新增「站点」列与筛选,新建公告可选择归属站点(主站或指定分站代发)
- 前台 PC/移动无需改动:请求已带 X-Distribution-Site-Code,后端按站点隔离,页面已有空态

测试:
- 公告模块:主站/继承/仅本站三种可见范围、跨站详情拦截、无效站点回落、管理端站点筛选
- 分销模块:本站公告 CRUD 与跨站防护、公告来源开关校验与非法值容错
2026-10-01 10:02:31 +08:00

38 KiB
Raw Permalink Blame History

分销网管理后台设计方案

状态:草案 v0.8
更新时间:2026-09-15
v0.8 变更:通道手续费改由主站承担、不再计入提价利润基数,第 2、7.5、7.8、14、16 节与代码实现(distribution/pricing.go)对齐。
适用范围:分销网站正常租赁订单管理、订单分账、分销客服与支付配置

1. 文档目的

本文档记录分销网管理后台的产品计划、领域模型、分账口径、接口边界、部署方案和实施顺序。

本文档是持续维护的设计基线。业务规则尚未确认的部分使用“待确认”标记,进入开发前必须补齐;已创建的订单必须使用规则和金额快照,不能因后续规则变更而重算历史账目。

2. 现有系统基础

当前 HFB Sys 是 Go + Gin + GORM + MySQL + Redis 后端,Vue 3 + Element Plus 用户端/运营后台前端,生产通过 Caddy 托管静态文件并反代单个 backend 服务。

可复用的现有领域:

  • 用户:users、实名认证、用户状态。
  • 商品和账号:rental_listings、game_accounts、账号资产快照。
  • 正常订单:rental_orders、交接、归还、结账、退款和订单过程事件。
  • 订单来源:rental_orders 的正常租赁交易;分销网只处理卖家和租客都在网站内完成的正常订单。
  • 资金:wallet_accounts、wallet_ledger、withdrawal_requests。
  • 支付:payment_merchant_configs、支付单、退款单和支付配置使用日志。
  • 客服:chat_conversations、chat_messages、客服组和二维码池。
  • 管理权限:admin_users、roles、permissions、角色权限关联和审计日志。

现有系统的价格快照包含 seller_ratio、buyer_ratio、seller_total_price、buyer_total_price 和 platform_markup_amount:

  • 主站提价逻辑:收号时录入卖家底价 seller_total_price 与回收比例 seller_ratio,主站定价引擎通过固定加价(小额)或减比例加价(大额)算得面向买家的挂牌比例 buyer_ratio 与买家价 buyer_total_price。两者的差额即为主站提价利润(platform_markup_amount = buyer_total_price - seller_total_price)。
  • 分销分账本质:分账分的是主站提价多出来的利润,按收号方 35% / 卖出方 40% / 平台服务费 25% 切分;号主底价作为本金成本 100% 归号主,不参与分账。支付通道手续费由主站承担,不计入提价利润基数,只落库供对账(见 7.5)。
  • 分站自主加价:分站货架可在主站挂牌价基础上进一步自主提价;分站自己提价多挣的钱 100% 属于分站自己,不进入三方分成池。
  • 挂牌比例定义:挂牌比例语义为「1 元兑换多少万哈夫币」,价格 = 哈夫币万数 / 比例,比例越小售价越贵(加价是调小比例)。分销分成的 35% / 40% / 25% 是利润分成百分比,不能与兑换比例混淆。

3. 总体架构

3.1 独立前端、复用后端

分销网管理后台独立为新的前端工程,推荐 React + TypeScript + Vite + Ant Design。现有 Vue + Element Plus 用户端和运营后台保持不变。

主站:https://hao858.com/
现有运营后台:https://hao858.com/manage-xxx
分销后台:暂定使用主域名下的独立子域名,例如 `distribution.hao858.com`

分销后台通过独立域名提供静态资源,/api/* 反代到现有 Go backend:

distribution.hao858.com(暂定)
  ├── /       独立 Ant Design 静态资源
  └── /api/*  reverse_proxy backend:8080

这样可以避免在同一个 Vue 应用中同时引入 Element Plus 和 Ant Design,也避免跨域 Cookie 和 CORS 配置。

3.2 后端暂不拆服务

第一阶段不新建独立分销后端服务。分销模块继续使用现有 MySQL、Redis、钱包、订单、支付、客服和权限体系,以便在同一事务中处理支付、退款、分成、税费和钱包流水。

建议新增后端目录:

backend/internal/modules/distribution/

建议文件:

dto.go
handler.go
service.go
repository.go
query.go
mutation.go
pricing.go
settlement.go
payment.go
qrcode.go
chat.go
presenter.go
audit.go

4. 业务目标与后台功能

4.1 分销后台功能

第一版需要覆盖(仅限正常租赁订单):

  1. 显示正常订单中已售出账号的详情。
  2. 显示分销网站自己通过正常订单收购/接收的账号详情(卖家在分销网站上架,租客完成交易)。
  3. 配置分销网站在正常订单中的收号分成百分比;主站卖出百分比统一或按规则版本管理(默认收号 35% / 卖出 40% / 服务费 25%)。
  4. 分销网站使用指定客服组和指定二维码池的拉群码。
  5. 查看通道手续费、服务费(利润的 25%)、货架兑换比例、税费、分成和结算金额。
  6. 配置分销网站是否展示账号,并可单独关闭某个账号。
  7. 配置分销网站可使用的一个或多个收款支付渠道。
  8. 分销客服只读订单信息和过程记录,并可按权限处理客服消息。
  9. 主站查看所有分销网站的收售订单、收款金额和结算数据。

4.2 建议页面

仪表盘
分销网站管理
正常订单售出账号
分销收售订单
佣金/分成明细
结算管理
比例与税费规则
支付通道
客服组与二维码
账号展示管理
报表
操作日志

5. 业务主体和权限

5.1 分销网站

建议使用独立主体表 distribution_sites。分销网站不是普通用户,也不直接等同于平台管理员。

分销网站至少需要保存:

  • 编码、名称、域名和状态。
  • 联系人信息。
  • 是否允许自动展示账号。
  • 默认客服组和专属二维码池。
  • 税费开关和税率。
  • 创建、停用和更新时间。

5.2 分销网站成员

建议使用 distribution_site_members 将现有 admin_users 映射到一个或多个分销网站。

成员类型建议包括:

  • operator:查看业务和账号展示。
  • finance:查看分成、结算和收款金额。
  • customer_service:查看订单、过程记录和客服消息。

分销网站成员只能看到所属站点的数据。前端传入的 site_id 不能扩大数据范围,后端必须从当前管理员成员关系中推导并校验。

5.3 权限码

建议新增:

distribution:site_view
distribution:site_manage
distribution:account_view
distribution:account_display
distribution:order_view
distribution:process_view
distribution:finance_view
distribution:settlement_view
distribution:settlement_manage
distribution:rule_view
distribution:rule_manage
distribution:payment_view
distribution:payment_manage
distribution:qrcode_view
distribution:qrcode_manage
distribution:chat_view
distribution:chat_send
distribution:all_view

分销客服默认只拥有:

distribution:order_view
distribution:process_view
distribution:chat_view
distribution:chat_send

客服禁止修改比例、支付配置、展示状态、退款、订单状态和结算结果。

6. 订单和账号展示

6.1 售出账号详情

分销后台需要显示:

  • 订单号、商品编号、账号基本信息和账号快照。
  • 分销网站、收号方、售出方和租客。
  • 收号 35%、卖出 40%、服务费 25%、该站 1 元兑换哈夫币比例、销售价和实际支付金额。
  • 退款、手续费、服务费、税费、各方收入和结算状态。
  • 交接、租用、归还、结账、退款、仲裁等过程事件。

账号密码、实名信息等敏感字段必须按照现有后台脱敏和权限规则返回。是否允许分销成员查看完整登录信息:待确认。

6.2 分销网站正常订单收号详情

分销网的收号不是线下提号记录,而是正常租赁订单中的一方角色:卖家在分销网站上架账号,租客在分销网站完成支付、交接、租用和归还。该类记录应从 rental_orders 及分销订单参与方快照查询,不能使用 admin_pickups 作为数据来源。

正常订单需要保存分销站点和参与方快照,例如:

distribution_site_id
seller_party_id
renter_party_id
receive_ratio
receive_amount_cent
rule_version

不新增独立的线下收号流程;如需展示“分销网收号记录”,通过正常订单中的 distributor_receive 角色和订单状态筛选实现。

6.3 账号展示开关

网站级配置:

distribution_sites.display_account_enabled

账号级配置:

distribution_site_accounts.display_status

账号状态建议为:

enabled
disabled
sold
offline

关闭展示不删除账号、不影响历史订单,只阻止新展示或新订单,并写入审计日志。

6.3.1 货源与自动铺货(已实现)

所有站点与主站共用同一套货源(rental_listings / game_accounts),分站货架不是独立商品库, 而是「同一批已审核商品在本站的展示关系 + 本站加价」。据此确定铺货规则:

  • 商品变为 published + approved(审核通过、后台直接上架、免审上架、编辑后重新上架)时, 自动为所有 status='active' AND display_account_enabled=true 的站点写入/恢复货架行 (listing.Approve → distribution.EnsureListingShelvedTx),不需要站长手动「一键同步主站商品」。
  • display_account_enabled 的语义是「本站是否参与自动铺货」:关闭后该站不自动接新货, 仍可由站长手动同步与选品。
  • 新增行加价 shelf_ratio_delta = 0(等于主站原价),站长可在货架页自主加价; 自动铺货不会覆盖已有加价。
  • 站长人工下架是选品决策,自动铺货与手动同步都不会覆盖;因此 distribution_site_accounts.display_disabled_by 记录下架来源 (operator = 站长人工、system = 系统自动、空 = 展示中或历史数据)。
  • 分站前台/搜索只要求 published + approved 且货架行 enabled;商品暂时下架、出租、 待审核都不需要改动货架行(前台条件本身就会隐藏),否则商品重新在售后会永久从分站消失。
  • 「一键同步主站商品」保留为兜底与修复入口:补全缺失货架行、恢复系统下架/历史无标记的行, clean_stale_listings 只清理「商品记录已被删除」的孤儿货架行。

货源归属与展示归属是两个概念:rental_listings.distribution_site_id 表示「这条货是谁收的」 (唯一),而 distribution_site_accounts 表示「这条货在哪些站的货架上卖」(可多站)。 具体分成口径由 resolveDistributionMode 按「买入站 × 货源站」判定 (同站自卖 / 主站收号分站卖 / 分站收号主站卖 / 三方跨站),避免重复出售与归因冲突。

6.3.2 公告中心(分站可自定义)

公告中心(前台「公告」页的列表/详情)按站点隔离,不再无条件继承主站:

  • announcements.distribution_site_id 标记归属站点(0 = 主站)。
  • distribution_sites.announcement_mode 决定分站来源: inherit(默认)= 主站公告 + 本站公告;own_only = 仅本站公告。
  • 前台可见范围由请求站点(X-Distribution-Site-Code / ?distribution_site_code)解析: 主站 [0]、inherit [0, siteID]、own_only [siteID];站点编码无效/已停用回落主站。 详情接口同样按该范围校验,避免跨站按 ID 读取。
  • 维护方:站长在分销后台「公告中心」自助维护本站公告 (/api/admin/distribution/announcements + distribution:announcement_view|manage, 站点由 ?site_id= 解析并校验成员权限,跨站 ID 一律视为不存在); 平台后台的公告管理可按站点筛选、并为指定分站代发。
  • 权限:新站点开通时站长继承 ops 角色,自动获得上述权限;超管/财务同样授予,便于代管。

6.4 不纳入分销网的业务

以下业务不属于分销网正常订单,不进入分销订单分账:

  • 平台或管理员线下提号(admin_pickups)。
  • 平台代管账号及线下交接、线下结算。
  • 撞车商品及撞车订单(mohong/crash)。
  • 分销网站之外的外部导入、私下交易或人工补录订单。

分销网订单必须同时满足:订单来源站点是分销网站、卖家和租客均属于该正常订单链路、支付和订单状态在平台系统内可追踪。

7. 比例、费用和分账口径

7.1 卖出后主站提价利润的百分比分成(已确认 v0.7)

口头常说的 3.5 / 4 / 2.5,统一写成 35% / 40% / 25%。这是卖出完成后的主站提价利润分成,三方合计 100%。不是挂牌定价比例(不是 1:3.5 / 1:4),文档、字段、后台和代码都只写百分比,不再写「成」。

分成 角色 说明
35% 收号 / 上架方 货源归属方分得主站提价利润的 35%
40% 卖出方 促成订单的销售站点分得主站提价利润的 40%
25% 平台服务费 主站平台收取主站提价利润的 25% 服务费
合计 100% 切完主站提价利润 四舍五入尾差除外,全部分配完毕
某方提价分成 = round_half_up(主站提价利润基数 × 百分比 / 100)

规则字段存 35 / 40 / 25,计算一律 × 百分比 / 100。

核心业务口径(v0.7 锁定,v0.8 修订通道手续费口径):

  1. 号主底价本金保底:号主应得走订单原有 owner_rent_amount_cent(对应 seller_total_price),属于履约本金,不参与任何分销分成,100% 结算给号主。
  2. 分账分的是提价的部分:分销分账的标的是主站收号定价多出来的利润(即 platform_markup_amount = buyer_total_price - seller_total_price)。该利润全额构成供三方切分的提价利润基数;支付通道手续费由主站承担,不从基数中扣除,只落库供对账(见 7.5)。
  3. 分站自主加价溢价 100% 归分站自己:若分站在货架上自主加价(或调比例加价),该加价溢价完全属于卖出分站自己,不进入 35/40/25 的三方分成池(详见 7.6 节)。

默认角色模式(可按站点、模式出新规则版本,历史订单用快照):

模式 参与方 初始提价分成
两方-分销网收号 分销网收号、主站卖出 分销网 35%,主站 40%,服务费 25%
两方-主站收号 分销网卖出、主站收号 分销网 40%,主站 35%,服务费 25%
三方 主站服务费、分销 A 上架、分销 B 卖出 主站服务费 25%,分销 A 35%,分销 B 40%

规则字段按参与方角色命名(distributor_receive_ratio 等)。后台文案写「35% / 40% / 25%」。

默认值必须通过迁移或初始化数据写入,不写死在结算公式里。新订单读取当前生效规则并写入快照,历史订单不跟随后台修改。

提价利润基数计算:

主站提价总额   = base_price_cent - owner_rent_amount_cent  (= platform_markup_amount)
有效加价       = min(shelf_markup_cent, max(净支付额 - owner_rent_amount_cent, 0))
提价利润基数   = max(净支付额 - owner_rent_amount_cent - 有效加价, 0)

通道手续费不进此式:由主站承担,只记录对账(见 7.5)。

7.2 必须确认的口径

v0.7 已锁定 7.1 的提价分成和 7.6 的分站自主加价独享。其余待确认项:

项目 状态
35% / 40% / 25% 的含义 已确认:主站收号提价利润的百分比分成;口头 3.5/4/2.5 不再使用
服务费 25% 已确认:主站提价利润的 25%,与收号、卖出同一基数
分站自主加价归属 已确认:分站自己加比例/加价多挣的钱 100% 属于分站自己,见 7.6
两方/三方角色 已确认:收号/上架 35%,卖出 40%,服务费 25%
利润是否扣号主、是否按结账消耗重算 已确认:号主底价作为本金扣除,分账只切提价部分
分销网站收号百分比上下限 待确认
三方亏损承担 待确认
税费税基 待确认:各方分成后毛利,还是利润基数
退款处理 待确认:重算剩余分成,还是生成反向冲正流水
四舍五入尾差 待确认:统一归主站还是按最大分成方承担

7.3 后台调整要求

后台调整规则时必须:

  1. 只允许具备 distribution:rule_manage 权限的管理员操作。
  2. 新增规则版本,不直接覆盖已生效版本的历史内容。
  3. 支持按分销网站、交易模式配置收号百分比、卖出百分比、服务费百分比、通道手续费和税费开关;三方百分比之和必须为 100。
  4. 支持设置生效时间;同一站点同一模式同一时刻只能有一个生效版本。
  5. 修改前展示影响范围和新旧值,确认后写入审计日志。
  6. 已创建、已支付或已结算订单继续使用其规则快照。
  7. 比例、费率和金额必须由后端校验范围,前端输入不能绕过校验。

7.4 推荐的金额模型

两套「比例」不能混用,快照里必须分开存:

挂牌兑换比例:1 元 = X 万哈夫币(主站 publish_ratio / buyer_ratio)
分成百分比:35 / 40 / 25(用于提价利润切分,字段存百分数不是 3.5)
分站加价溢价:shelf_markup_cent(分站自主加价金额,独立核算)

最终结算全部以整数分为准。每笔订单保存:

split_percent_snapshot  # 各方分成 35 / 40 / 25
shelf_markup_snapshot   # 分站自主加价溢价(分)
amount_snapshot
rule_version

建议所有金额字段使用 *_cent BIGINT。通道手续费、税率继续用基点 *_bps INT:

0.5% = 50 bps
1%   = 100 bps
分成 35% 存 35,计算用 × 35 / 100;不要存 3.5

7.5 通道手续费与平台服务费

支付通道手续费和平台服务费不是同一层。

通道手续费:按退款后的实际支付金额计算,费率 0.5%,四舍五入;由主站承担,不从提价利润基数中扣除,只落库 payment_fee_cent 供对账。

净支付额         = 支付金额 - 成功退款金额
通道手续费       = round_half_up(净支付额 × 50 / 10000)        # 主站承担,不进分成基数
主站提价总额     = base_price_cent - owner_rent_amount_cent
有效加价         = min(shelf_markup_cent, max(净支付额 - owner_rent_amount_cent, 0))
提价利润基数     = max(净支付额 - owner_rent_amount_cent - 有效加价, 0)
平台服务费       = round_half_up(提价利润基数 × 25 / 100)    # 25%
收号/上架分成    = round_half_up(提价利润基数 × 35 / 100)    # 35%
卖出方提价分成   = round_half_up(提价利润基数 × 40 / 100)    # 40%
分站自主加价溢价 = shelf_markup_cent                         # 100% 独享归卖出分站

payment_fee 与 service_fee 必须分字段。服务费是提价利润的 25%,不是通道手续费,不是固定元,也不是 实付/2.5。

通道手续费由主站自行承担:平台净收益 = 提价利润基数 × 25% + 四舍五入尾差 − 通道手续费,不向其他参与方回收。

7.6 分站货架自主提价(分站独享溢价,已确认 v0.7)

分站货架提价是分销商根据自身经营策略自主制定的加价:

  1. 加价多挣的钱属于分站自己: 分站在货架上自主提价所产生的差价收益(shelf_markup_cent = site_price_cent - base_price_cent),100% 归属于卖出该商品的分站。 分站自主提价溢价不参与 35/40/25 切分,平台与收号方不得切分该部分收益。
  2. 兑换比例与提价方向:
    • 比例语义:「1 元兑换多少万哈夫币」,价格 = 哈夫币万数 / 比例。
    • 比例越小,1 元换到的哈夫币越少,同样币数售价越高(提价);反之比例越大越便宜(打折)。
    • 若通过调整兑换比例加价,必须是减小兑换比例(site_ratio = base_ratio - ratio_delta),使得 site_price_cent >= base_price_cent。
    • 系统支持直接按元设置加价金额(shelf_markup_cent),或通过减比例自动换算为加价金额。
  3. 卖出分站总收入: \text{卖出分站总收入} = \text{分站自主加价溢价 (shelf\_markup\_cent)} + \text{卖出方提价分成 (40\%)}

约束:

  1. 自主加价保存在 distribution_site_accounts 上,只影响该站货架和该站订单。
  2. 主站挂牌价、主站订单、号主回收底价不因分站加价而变。
  3. 下单时将主站基础价快照 base_price_cent 与分站加价快照 shelf_markup_cent 写入订单,历史订单不受事后调价影响。

7.7 税费

计划要求对分销所得利益按毛利的 1% 计税,并支持开关和可调税率;每个主体承担自己的分成税费。

推荐配置:

tax_enabled
tax_rate_bps

推荐公式:

毛利 = 该主体收入 - 该主体收号成本 - 该主体承担的费用
税额 = round_half_up(毛利 × tax_rate_bps / 10000)

每个主体分别计算税费,主站、分销 A、分销 B 不合并税基。毛利为负时税额暂按 0 处理,亏损如何结转:待确认。

7.8 账务不变量与结算恒等式(已确认 v0.7,v0.8 修订)

每笔分销订单的结算必须满足:

净支付租金 (net_paid_amount_cent)
= 号主底价 (owner_rent_amount_cent)
 + 分站自主提价溢价 (shelf_markup_cent)  [100% 归卖出分站]
 + 提价利润基数 (split_base_amount_cent)

通道手续费 (payment_fee_cent) 不参与上式:由主站承担,只记录对账

提价利润基数
= 收号/上架 35%
 + 卖出 40%
 + 平台服务费 25%
 + 四舍五入尾差 (rounding_adjustment_cent)

各方收益结算:

  • 号主:得到完整的 owner_rent_amount_cent。
  • 收号方:分得 提价利润基数 × 35%。
  • 卖出方(分站):获得 分站自主加价溢价 (shelf_markup_cent) + (提价利润基数 × 40%)。
  • 平台:获得 提价利润基数 × 25% + 四舍五入尾差,并自行承担通道手续费(payment_fee_cent 只作记录,不从各方分成中回收)。

税费若开启,从各方分成中计,不破坏上面 100% 切完利润的关系;具体税基见 7.2。

退款、拒付、仲裁和结算撤销必须生成反向明细,不能直接覆盖原结算记录。

8. 建议数据模型

8.1 分销网站

distribution_sites

建议字段:

id, site_code, site_name, domain, status
display_account_enabled
default_support_group_id
tax_enabled, tax_rate_bps
created_at, updated_at

8.2 成员关系

distribution_site_members
id, site_id, admin_user_id, member_type, status, data_scope
created_at, updated_at

8.3 账号展示关系

distribution_site_accounts
id, site_id, account_id, listing_id, display_status
shelf_ratio_delta            # 该站加价:增加的 1 元兑换哈夫币比例点数,不是人民币
display_started_at, display_ended_at
created_at, updated_at

8.4 规则版本

distribution_rules
distribution_rule_versions

规则需要保存:

site_id
mode: two_party / three_party
platform_receive_ratio       # 百分比,默认 35
platform_sell_ratio          # 百分比,默认 40
distributor_receive_ratio    # 百分比,默认 35
distributor_sell_ratio       # 百分比,默认 40
distributor_a_ratio          # 百分比,默认 35
distributor_b_ratio          # 百分比,默认 40
service_fee_value            # 百分比,默认 25
service_fee_unit: percent    # 只表示百分数;禁止 fixed_amount / 金额÷value
payment_fee_bps
tax_enabled
tax_rate_bps
effective_from, effective_to
version, status

同一规则里收号 + 卖出 + 服务费必须等于 100。首批默认规则按第 7.1 节初始化:

two_party_distributor_receive: distributor_receive_ratio=35, platform_sell_ratio=40, service_fee_value=25
two_party_platform_receive: platform_receive_ratio=35, distributor_sell_ratio=40, service_fee_value=25
three_party: distributor_a_ratio=35, distributor_b_ratio=40, service_fee_value=25

字段按参与方角色命名。库里存百分数 35 / 40 / 25,计算一律 × 百分比 / 100。已写入的 3.5 / 4 / 2.5 不能当百分数用,迁移时换算成 35 / 40 / 25。默认规则必须通过迁移或初始化数据写入,不写死在结算代码中。

8.5 订单参与方

distribution_order_parties
order_id, site_id, party_role, user_id
ratio, base_amount_cent, markup_amount_cent
gross_amount_cent, fee_amount_cent, tax_amount_cent
net_amount_cent, status

party_role 建议支持:

platform
distributor_a
distributor_b
distributor_receive
seller
buyer

8.6 订单财务快照

distribution_order_financials
order_id UNIQUE
gross_paid_amount_cent
refund_amount_cent
net_paid_amount_cent
payment_fee_bps, payment_fee_cent
service_fee_bps, service_fee_cent
markup_amount_cent
tax_enabled, tax_rate_bps, tax_amount_cent
split_base_amount_cent
settlement_status
rule_version
created_at, settled_at

8.7 结算批次和明细

distribution_settlements
distribution_settlement_items

结算批次保存周期、状态、审核人、付款时间和失败原因;明细保存每个站点、参与方、收入、成本、毛利、手续费、税费和钱包流水关联。

8.8 支付配置绑定

distribution_site_payment_configs

一个分销网站可以绑定一个或多个现有 payment_merchant_configs。支付下单时保存 site_id 和 payment_config_id 快照,回调不重新依赖当前配置。

8.9 二维码和客服组

建议给二维码池或关联表增加:

distribution_site_id
support_group_id

取码优先匹配“分销网站 + 客服组”的专属二维码池。站点已配置专属池时,不回退到其他站点二维码。

9. API 规划

9.1 平台管理员

GET    /api/admin/distribution/sites
POST   /api/admin/distribution/sites
GET    /api/admin/distribution/sites/:id
PUT    /api/admin/distribution/sites/:id
POST   /api/admin/distribution/sites/:id/enable
POST   /api/admin/distribution/sites/:id/disable

GET    /api/admin/distribution/sold-orders
GET    /api/admin/distribution/sold-orders/:id
GET    /api/admin/distribution/receive-orders
GET    /api/admin/distribution/receive-orders/:id

GET    /api/admin/distribution/rules
POST   /api/admin/distribution/rules
PUT    /api/admin/distribution/rules/:id

GET    /api/admin/distribution/settlements
GET    /api/admin/distribution/settlements/:id
POST   /api/admin/distribution/settlements/:id/approve
POST   /api/admin/distribution/settlements/:id/reject

GET    /api/admin/distribution/reports/summary
GET    /api/admin/distribution/reports/orders
GET    /api/admin/distribution/reports/finance

9.2 分销网站成员

GET    /api/admin/distribution/me
GET    /api/admin/distribution/orders
GET    /api/admin/distribution/orders/:id
GET    /api/admin/distribution/receive-orders
GET    /api/admin/distribution/chats
GET    /api/admin/distribution/chats/:id/messages
POST   /api/admin/distribution/chats/:id/messages

同一套后端接口通过成员关系限制 site_id。平台管理员可以显式选择站点或查看全部;分销成员不能自行传入其他站点 ID。

10. 支付和域名上下文

生产环境建议通过请求 Host 解析分销网站:

请求域名 -> 服务端解析 site_id -> 校验站点状态 -> 选择绑定支付配置

开发环境可以临时使用 site_code,但生产支付下单不能完全信任前端提交的站点参数。

支付配置选择规则:

  1. 只读取当前站点启用的支付配置。
  2. 支持一个或多个配置,按优先级或健康状态选择。
  3. 支付单保存站点和支付配置快照。
  4. 回调、查询和退款使用支付单快照,不因后台配置变更而切换通道。

11. 独立前端工程

建议目录:

distribution-admin/
├── package.json
├── vite.config.ts
├── tsconfig.json
├── Dockerfile
└── src/
    ├── main.tsx
    ├── router/
    ├── layouts/
    ├── stores/
    ├── services/
    ├── types/
    └── features/
        ├── dashboard/
        ├── sites/
        ├── sold-orders/
        ├── receive-orders/
        ├── settlements/
        ├── payment-configs/
        ├── qrcodes/
        ├── chats/
        └── reports/

建议继续复用现有 API 响应格式:

{
  "code": "ok",
  "message": "ok",
  "data": {}
}

独立后台第一阶段可复用现有管理员登录接口和 HttpOnly Cookie,但不与现有前端共享 localStorage。是否建设分销员独立登录:待确认;如果分销员不是平台管理员,应新增独立主体和认证体系。

12. 部署方案

新增独立前端构建单元:

distribution-admin/Dockerfile

Caddy 增加独立子域名站点。子域名名称暂定,最终以 DNS、证书和运营规划确认的名称为准:

distribution.hao858.com {
    handle /api/* {
        reverse_proxy backend:8080
    }

    handle {
        root * /srv/distribution-admin
        try_files {path} /index.html
        file_server
    }
}

主站、现有运营后台和分销后台分别构建、分别发布。数据库迁移仍由现有生产发布流程执行,后端和前端发布需要保持兼容窗口。

13. 实施阶段

阶段 0:确认业务口径

  • 确认 3.5、4、2.5 的单位和方向。 已确认(v0.6):卖出后利润分成 35% / 40% / 25%,文档与字段只写百分比。
  • 确认加价形态。 已确认(v0.6):分站加价增加该站「1 元兑换哈夫币」比例,不是叠加人民币。
  • 确认两方、三方亏损承担。
  • 确认结账后利润是否按实际消耗重切。
  • 确认税费毛利计算口径。
  • 确认退款采用重算还是冲正。
  • 确认分销员和分销客服的身份模型。
  • 确认账号是否允许多站点展示。

阶段 1:数据库和计算引擎

新增 Goose 迁移,建议从 000062_distribution_init.sql 开始,包含站点、成员、展示关系、默认规则版本、订单参与方、财务快照、结算、支付绑定、二维码绑定和权限初始化。默认分账值先按第 7.1 节写入,后续通过后台规则页面调整。

先完成纯函数计算和单元测试,不接真实订单。

阶段 2:订单生命周期接入

接入:

支付成功
退款成功
订单完成
订单仲裁
订单取消

要求支付回调、退款回调、订单完成和结算操作幂等;规则修改不影响已有订单;钱包流水和分销结算明细金额一致。

阶段 3:后台 API

完成站点、售出订单、正常订单收号记录、比例规则、结算、支付通道、二维码客服和账号展示接口,并补齐站点数据隔离测试。

阶段 4:Ant Design 前端

开发顺序:登录和权限、仪表盘、售出订单、正常订单收号记录、站点配置、规则、结算、支付、客服二维码、报表。

阶段 5:独立生产部署

接入独立子域名、DNS、Caddy 配置、前端镜像和发布脚本,完成健康检查、登录、订单查询、支付配置和客服消息冒烟测试。

14. 测试和验收标准

权限隔离

  • 分销网站 A 不能查询分销网站 B。
  • 分销客服不能修改比例、支付配置、订单状态和结算。
  • 主站财务可查看全部站点资金数据。
  • 超级管理员可管理全部站点。

账务正确性

  • 通道手续费按退款后的实际支付金额计算,0.5%,四舍五入,以分保存。
  • 号主应得先扣,得到利润基数后再切 35% / 40% / 25%;通道手续费由主站承担,不计入利润基数。
  • 收号 35%、卖出 40%、服务费 25%;字段存 35/40/25,禁止存 3.5/4/2.5 再当百分数乘。
  • 分站加价改该站 1 元兑换哈夫币比例,不叠加人民币;历史订单用下单时的比例快照。
  • 各主体独立计算税费。
  • 重复支付、退款和结算请求不会重复入账。
  • 分销结算明细与钱包流水一致。
  • 同一订单同一参与方只允许一条结算明细(唯一键 uk_distribution_settlement_item_party):自动释放与手工批次并发时以唯一键冲突为准跳过该参与方,不重复入账。
  • 订单累计退款额取「本次回调金额与已退款成功流水合计」的较大值,多笔退款与退款结果重复回调都不会把口径写小;分销重算与仲裁回冲均按此累计额计算。
  • 关单(AdminClose / AdminSeal / AdminRejectRefund 的 close 分支)属于可释放终态,会补写 release_at,避免不退款关单的订单永远不被自动结算。

业务正确性

  • 售出订单和正常订单收号记录均可查询。
  • 线下提号、平台代管和撞车订单不会进入分销订单列表或分账。
  • 账号关闭展示后不影响历史订单。
  • 规则修改只影响新订单。
  • 支付只使用当前分销网站绑定的通道。
  • 分销网站使用指定客服组和二维码池。
  • 客服消息按站点隔离。

发布标准

  • ./scripts/check.sh 通过。
  • 新迁移具备 Up/Down 并通过 SQL 门禁。
  • 金额、退款、分账、税费和状态机变更包含回归测试。
  • 生产环境完成独立域名、后台登录、订单查询和支付配置冒烟验证。

15. 待确认清单

以下问题确认后,更新本文档版本并进入详细表结构和 API 契约设计:

  1. 分销网站是平台合作方,还是普通用户下的分销身份?
  2. 分销客服是否使用现有 admin_users?
  3. 3.5、4、2.5 的确切单位和计算方向是什么? 已确认:利润分成 35% / 40% / 25%,只写百分比,见 7.1。
  4. 服务费和支付手续费是否都按实际支付净额计算? 已确认:通道手续费按实付净额 0.5%;服务费是利润的 25%。
  5. 加价是否计入服务费、税费和退款基数? 已确认加价形态:改兑换比例,不是人民币;利润仍按 7.1 切 35% / 40% / 25%。
  6. 税费是否只对正毛利计提?亏损是否结转?
  7. 退款后佣金是重算剩余金额,还是追加负向冲正?
  8. 一个账号能否同时展示在多个分销网站?
  9. 分销后台子域名最终使用哪个名称(当前暂定 distribution.hao858.com)?
  10. 分销网站是否需要独立登录入口和独立账号体系?
  11. 分销网站是否能查看完整账号登录资料?

后续每次确认业务规则后,优先更新第 7、15 节,再同步更新第 8、9、13、14 节,确保规则、数据、接口、实施和验收标准保持一致。

16. 当前实现基线(v0.8)

本分支已落地第一批可运行功能,主站域名为 https://hao858.com/,独立后台工程位于 distribution-admin/,子域名暂定 https://distribution.hao858.com/:

  • Go 后端已实现 distribution_sites、成员、账号货架、规则版本、订单财务快照、订单参与方、结算批次/明细、支付通道绑定表。
  • rental_orders 增加分销站点、模式和规则版本字段,并具备 base_price_cent(主站基准价)与 shelf_markup_cent(分站自主加价溢价)快照。
  • 分账计算引擎与口径全面对齐 v0.8:
    1. 利润分成百分比使用 35%(收号/上架)、40%(卖出方)、25%(平台服务费);
    2. 号主底价成本(owner_rent_amount_cent)保底归号主,不参与任何分成;
    3. 分账标的为主站收号提价利润(platform_markup_amount = base_price - owner_rent),全额按 35/40/25 切分;通道手续费由主站承担,不从基数中扣除;
    4. 分站货架自主提价溢价(shelf_markup_cent)100% 独享归卖方分站,不参与三方切分;
    5. 兑换比例提价语义明确(比例越小售价越高,提价使分站售价增加)。
  • 管理 API 覆盖站点、规则、售出/收号订单查询、财务快照、账号展示开关、支付通道绑定和结算批次。
  • 货架铺货与展示口径(详见 6.3.1):商品变为 published + approved 时自动铺到所有开启自动展示的站点货架, 不再依赖站长手动同步;distribution_site_accounts.display_disabled_by 记录下架来源,自动铺货不覆盖站长人工下架; clean_stale_listings 只清理商品记录已删除的孤儿货架行。
  • 生产与测试口径一致:结算批次入账、站点提现与冷却期自动释放不再按 APP_ENV 冻结(原 liveMoneyMovementEnabled 生产保护已移除)。
  • 新建站点的默认结算冷却天数由系统配置 distribution.default_settlement_hold_days 统一控制(默认 7 天,0=立即释放,最大 365),管理端可在系统配置页调整;站点级 settlement_hold_days 仍可单独覆盖。
  • distribution-admin 基于 React + TypeScript + Vite + Ant Design,覆盖经营大盘、双视图资产管理、选品货架、订单中心、品牌装修与钱包明细。
  • 分站前台统一按「一手独立商城」呈现:不向顾客暴露分销身份(无「官方分销」标识), 登录/注册页与首页品牌区的站名、Logo 均取自站点配置。
  • 公告中心按站点隔离并可自定义(详见 6.3.2):announcements.distribution_site_id + 站点 announcement_mode (inherit 继承主站+本站 / own_only 仅本站),站长在分销后台自助维护本站公告。
  • 首页文案支持站长自定义:distribution_sites.storefront_text_json (tagline 头部副标题 / hero_badge 主视觉徽标 / hero_desc 主视觉描述 / card_sub 移动端卡片副标题), 在分销后台「品牌装修 → 首页文案」编辑;字段留空或整段为空时回落到前台内置默认文案。