docs(distribution): 收录分站收号定价分析与改造方案并标注方案 B 实施情况
- 新增第 0 节「实施情况」:已落地口径、关键决策(压价上限 20 点、 新字段 receive_cost_delta、压价差进 35/40/25 分成池)、代码落点与回归锚点 - 状态行由「分析稿(未实施)」更新为「方案 B 已实施」,5.2 节与第 6、8 节同步标注 - 记录连带修正 a36332d:解耦仅作用于分站收号侧,主站加速出售买家价仍跟随卖家比例 - 第 2–4 节的改造前现状与问题定位原样保留,作为决策依据
This commit is contained in:
@@ -0,0 +1,486 @@
|
||||
# 分站收号定价分析与改造方案
|
||||
|
||||
> 状态:**方案 B 已实施**(2026-09-17)。第 2–4 节记录改造前的现状口径与问题定位,保留为决策依据;
|
||||
> 第 5 节起的候选方案中,**方案 B 已落地**,方案 C 未实施,方案 D 待办。实施口径见第 0 节。
|
||||
> 更新时间:2026-09-17
|
||||
> 适用范围:主站/分站的「收号(回收)比例」、号主底价、买家价、分销三方分账。
|
||||
> 关联文档:[分销网管理后台设计方案](分销网管理后台设计方案.md)、[出售加价规则](出售加价规则.md)、[发布比例计算](发布比例计算.md)
|
||||
|
||||
---
|
||||
|
||||
## 0. 实施情况(方案 B,2026-09-17)
|
||||
|
||||
### 0.1 已落地的口径
|
||||
|
||||
```
|
||||
分站收号比例 = 主站参考比例 R + receive_cost_delta (点数越大,收号价越低)
|
||||
分站买家价 = 锚定主站参考比例 R 推导 (不随收号价联动 ← 解耦核心)
|
||||
主站买家价 = 仍跟 seller_ratio 联动 (含加速出售,主站行为不变)
|
||||
压价差 = 经结算层 profit 自动进入 35/40/25 三方分成池
|
||||
货架自主加价 = 100% 归分站 (原有逻辑,未改动)
|
||||
```
|
||||
|
||||
两条死边界:分站收号价 ≤ 主站参考价(`receive_cost_delta ≥ 0` 保证);分站卖价 ≥ 主站挂牌价(原有 clamp 保证)。
|
||||
|
||||
### 0.2 关键决策
|
||||
|
||||
| 决策点 | 结论 |
|
||||
|---|---|
|
||||
| 压价点数上限 | 沿用 20 点 |
|
||||
| 字段方案 | 新增 `receive_cost_delta`(迁移 000072),旧 `receive_ratio_delta` 保留只读 |
|
||||
| 压价差归属 | 进入 35/40/25 分成池(非全归分站);仅货架自主加价 100% 归分站 |
|
||||
| 主站是否受影响 | 否。主站加速出售买卖仍联动,仅分站走解耦锚点 |
|
||||
|
||||
### 0.3 代码落点
|
||||
|
||||
| 位置 | 改动 |
|
||||
|---|---|
|
||||
| `backend/migrations/000072_distribution_site_receive_cost_delta.sql` | 新增 `receive_cost_delta` 列 |
|
||||
| `backend/internal/modules/listing/receive_pricing.go` | 新增 `Normalize/ApplySiteReceiveCostDelta`;分站买家锚点改用 R;快照写 `site_receive_cost_delta` 与 `pricing_model` |
|
||||
| `backend/internal/modules/listing/site_receive.go` | 新增 `ReceiveCostDeltaBySiteCode` / `resolveSiteReceiveCostDelta` |
|
||||
| `backend/internal/modules/distribution/{dto,repository}.go` | 新字段读写与 `normalizeReceiveCostDelta` 校验 |
|
||||
| `frontend/src/shared/utils/pricing.ts`、`usePricingCalculator.ts` | 买卖双轨试算(`calculatedRatio` 收号侧 / `anchorRatio` 买家侧) |
|
||||
| 主站后台弹窗、分销后台 SiteSettings | 文案改为价格语义「收号价比主站低 X 点」 |
|
||||
|
||||
### 0.4 连带修正
|
||||
|
||||
实现过程中发现并修正:主站加速出售的买家价一度被误锚到参考比例(`a36332d`)。
|
||||
解耦只应作用于分站收号侧,主站加速出售必须继续让买家价跟随卖家比例。
|
||||
|
||||
### 0.5 回归锚点
|
||||
|
||||
R=43、coinM=100 时:`receive_cost_delta=3` → 收号比例 46、号主收 **217.4**(低于主站 232.6)、
|
||||
买家价 **263.2 不变**、提价利润池 30.6 → **54.9**。已由 `receive_pricing_test.go` 固定。
|
||||
|
||||
---
|
||||
|
||||
## 1. 结论摘要(TL;DR)
|
||||
|
||||
1. **当前分站收号不是「低价收号赚差价」,而是「加价收号抢货源、买家买单」。**
|
||||
分站唯一可调的是「相对主站下调 X 点」,数学上 `卖家比例 = 主站参考比例 R − X`,比例变小 → **号主底价变高**;平台把买家价一起抬高,从而使三方分账池变大。
|
||||
2. **用户直觉(分站能低价收号 → 各方都多赚)与代码方向相反。**
|
||||
因为买家价是从「卖家收货价」推导出来的(`买家比例 = 卖家比例 − 修正点数` 或 `买家价 = 卖家价 + 固定加价`),分站一旦压价收货,买家价同步下移,**绝对毛利反而缩小**,省下来的钱全被买家拿走。
|
||||
3. **「一会高一会低、一会大一会小」有三个来源:**
|
||||
- 三套定价引擎在币量档位间硬切换,边界处毛利会「跳崖」甚至「币更多、利润更少」;
|
||||
- **390M 以上三档是「待定」**(配置里 `RatioSubtract = 0`),买家价 = 号主价,**提价利润恒为 0**,分账池为 0,且 `X` 调多少都没用;
|
||||
- 固定加价带(10–90M)里 `X` 只转移号主/买家的钱,**不改变分账池**,所以同一个 `X` 在不同档位效果完全不同。
|
||||
4. **根因:买价与卖价绑在同一个变量上,价差是公式给的固定比例差,不是市场差价。** 因此「分站的收货议价能力」无处体现。
|
||||
5. 建议分三阶段:**先做方案 D(补 390M+、抹平跳变,1–2 人天)止血 → 再做方案 B(解耦,5–8 人天,带影子计算开关)→ 最后做方案 C(分站自费让利,8–15 人天)**。
|
||||
|
||||
---
|
||||
|
||||
## 2. 术语与比例语义
|
||||
|
||||
所有比例统一为 **`1:X` = 1 元兑换 X 万哈夫币**,因此:
|
||||
|
||||
```
|
||||
价格(元) = 万哈夫币 ÷ X
|
||||
X 越小 → 价格越贵;X 越大 → 价格越便宜
|
||||
```
|
||||
|
||||
| 名称 | 代码字段 | 谁决定 | 取值 |
|
||||
|---|---|---|---|
|
||||
| 主站参考回收比例(上限) | `seller_reference_ratio` | 账号属性自动算 | 见 2.1 |
|
||||
| 主站挂牌回收比例 | `seller_ratio` | 号主可调,服务端 clamp | `[R, R+10]`(只能调大=降价加速出售) |
|
||||
| 分站收号比例 | 无独立字段,创建时实时算 | 分站 `receive_ratio_delta` | `max(0.01, R − delta)`,恒 ≤ R |
|
||||
| 买家比例 | `buyer_ratio` | 由卖家比例推导 | 比例带:`卖家比例 − 修正点数`;固定带:由固定加价反推 |
|
||||
| 分站货架加价 | `shelf_ratio_delta` / `shelf_markup_cent` | 分站自主 | 见 2.4,**与收号比例无关** |
|
||||
|
||||
### 2.1 主站参考比例 R 的计算
|
||||
|
||||
代码:`backend/internal/modules/listing/receive_pricing.go`(`calculateSellerReferenceRatio`),默认参数见 `backend/internal/modules/systemconfig/publish_options.go`。
|
||||
|
||||
```
|
||||
R = 保险基准比例 (3*3=40, 2*3=42, 2*2=47, 2*1=48)
|
||||
+ 缺配惩罚 (红皮/刀皮/砖皮 各 +1;满体力/满负重 缺失各 +1)
|
||||
+ 币量修正 (>130M +1, >230M +2.5, >380M +4, >530M +5)
|
||||
+ 日均损耗修正 = clamp(floor((日均损耗-10)/10), 0, 4)
|
||||
```
|
||||
|
||||
示例:1 亿哈夫币、3*3、满体力、满负重、无皮肤 → `R = 40 +(红皮1 + 刀皮1 + 砖皮1)= 43`。
|
||||
该用例已被单测固定:`backend/internal/modules/listing/receive_pricing_test.go`(期望号主基础价 232.6、买家比例 38、总价 263.20)。
|
||||
|
||||
### 2.2 主站与分站的规则差异
|
||||
|
||||
```go
|
||||
// backend/internal/modules/listing/receive_pricing.go:73-77
|
||||
sellerRatio := clampSaleRatio(referenceRatio, requestedRatio) // 主站:[R, R+10]
|
||||
if onDistributionSite {
|
||||
sellerRatio = ApplySiteReceiveRatioDelta(referenceRatio, delta) // 分站:R - delta
|
||||
}
|
||||
```
|
||||
|
||||
- **主站**:号主填的比例会被 clamp 到 `[R, R+10]`;填小于 R 会被拉回 R,填大是「加速出售」(主动降价)。
|
||||
- **分站**:号主填的加速比例**被完全忽略**,强制为 `R − delta`。即使号主愿意更便宜卖(比例更大),系统也会强制把价格抬到 `R − delta`。
|
||||
|
||||
### 2.3 生效链路与快照
|
||||
|
||||
```
|
||||
号主在分站域名/带 X-Distribution-Site-Code 的商城上架
|
||||
→ handler 取 header(handler_user.go)
|
||||
→ ResolveReceiveRatioDelta(listingID, siteCode)(listing/site_receive.go)
|
||||
→ applyMainSiteReceivePricing(...)(listing/receive_pricing.go)
|
||||
→ 结果写入 asset_summary.price_breakdown(seller_ratio / seller_total_price / buyer_ratio / site_receive_ratio_delta ...)
|
||||
→ 后续改 delta 不影响已发布商品;历史订单用下单时快照
|
||||
```
|
||||
|
||||
读侧:分站「收号管理」用 `ReceivePricingFromAssetSummary` 读快照(`distribution/repository.go` 约 2634 行)。
|
||||
|
||||
### 2.4 两套「分站加价」不要混淆
|
||||
|
||||
| 机制 | 适用对象 | 归属 |
|
||||
|---|---|---|
|
||||
| `receive_ratio_delta`(本文主题) | 号主在**分站上架**的账号(分站收号) | 影响号主底价与买家价,进 35/40/25 分账 |
|
||||
| `shelf_ratio_delta` | 主站账号同步到**分站销售** | 分站自主加价,溢价 100% 归分站(`listing/shelf_ratio.go`) |
|
||||
|
||||
### 2.5 从比例到价格、到分账
|
||||
|
||||
```
|
||||
万W = 哈夫币 / 10000
|
||||
号主基础价 seller_coin_base = round0.1( W / sellerRatio )
|
||||
号主总价 seller_total = 号主基础价 + 额外消耗品价
|
||||
买家价:
|
||||
coinM < 10M → 买家价 = 号主价(无加价)
|
||||
10M ≤ coinM < 90M → 买家价 = 号主基础价 + 固定加价(28/31/34/38)
|
||||
coinM ≥ 90M → 买家比例 = 卖家比例 − 修正点数(5/4/3.5/3/0),买家价 = round0.1(W / 买家比例)
|
||||
平台提价利润 = 买家总价 − 号主总价
|
||||
```
|
||||
|
||||
分账(`backend/internal/modules/distribution/pricing.go`):
|
||||
|
||||
- `CalculateSettlement`:`净支付 − 号主底价 − 有效分站加价 = 提价利润`;服务费按利润百分比单独计算;
|
||||
- `SplitSettlement`:收号方 35% + 卖出方 40%,服务费 25% 记财务快照;
|
||||
- 结算一律使用订单上的整数分快照,规则/站点后续变更不影响历史订单。
|
||||
|
||||
模式由买卖双方站点决定(`distribution/lifecycle.go` 的 `resolveDistributionMode`):
|
||||
|
||||
| 场景 | 模式 | 分成 |
|
||||
|---|---|---|
|
||||
| 号主挂分站、主站买家买(本主题:分站收号) | `two_party_distributor_receive` | 分站 35% / 主站卖出 40% / 服务费 25% |
|
||||
| 号主挂主站、分站买家买 | `two_party_platform_receive` | 主站收号 35% / 分站卖出 40% / 25% |
|
||||
| 同一分站买卖 | `site_self_sell` | 分站 75% / 25% |
|
||||
| 两个不同分站 | `three_party` | A 35% / B 40% / 25% |
|
||||
|
||||
---
|
||||
|
||||
## 3. 验证示例
|
||||
|
||||
以下数字均按项目口径(比例 1 位小数、金额 0.1 元、结算按分)计算,可用于回归对照。
|
||||
|
||||
### 3.1 例 A:1 亿哈夫币(coinM=100,W=10000 万),R=43,比例修正带 −5
|
||||
|
||||
| 场景 | 收号比例 | 号主底价 | 买家比例 | 买家价 | 提价利润 | 分站 35% | 主站 40% | 服务费 25% |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 主站默认 | 43.0 | 232.6 | 38.0 | 263.2 | 30.6 | 10.71 | 12.24 | 7.65 |
|
||||
| 主站加速 +10 | 53.0 | 188.7 | 48.0 | 208.3 | 19.6 | 6.86 | 7.84 | 4.90 |
|
||||
| 分站 delta=0 | 43.0 | 232.6 | 38.0 | 263.2 | 30.6 | 10.71 | 12.24 | 7.65 |
|
||||
| 分站 delta=3 | 40.0 | 250.0 | 35.0 | 285.7 | 35.7 | 12.50 | 14.28 | 8.93 |
|
||||
| 分站 delta=5 | 38.0 | 263.2 | 33.0 | 303.0 | 39.8 | 13.93 | 15.92 | 9.95 |
|
||||
| 分站 delta=10 | 33.0 | 303.0 | 28.0 | 357.1 | 54.1 | 18.93 | 21.64 | 13.53 |
|
||||
| 分站 delta=20 | 23.0 | 434.8 | 18.0 | 555.6 | 120.8 | 42.28 | 48.32 | 30.20 |
|
||||
|
||||
> delta 每加 1 点,号主底价相对涨约 `delta / (R − delta)`;≥90M 时买家价涨得更快,分账池随之变大。
|
||||
|
||||
### 3.2 例 B:2000 万哈夫币(coinM=20,W=2000 万),R=43,固定加价带 +28
|
||||
|
||||
| 场景 | 收号比例 | 号主底价 | 买家价 | 提价利润 | 分站 35% |
|
||||
|---|---|---|---|---|---|
|
||||
| 主站默认 | 43.0 | 46.5 | 74.5 | 28.0 | 9.80 |
|
||||
| 分站 delta=3 | 40.0 | 50.0 | 78.0 | 28.0 | 9.80 |
|
||||
| 分站 delta=5 | 38.0 | 52.6 | 80.6 | 28.0 | 9.80 |
|
||||
| 分站 delta=20 | 23.0 | 87.0 | 115.0 | 28.0 | 9.80 |
|
||||
|
||||
> **固定加价带里 delta 不改变分账池**:只是把「号主多得 = 买家多付」同额搬运。
|
||||
|
||||
### 3.3 例 C:2 亿哈夫币(coinM=200,W=20000 万),R=44(>130M 修正 +1),修正带 −4
|
||||
|
||||
| 场景 | 收号比例 | 号主底价 | 买家比例 | 买家价 | 提价利润 | 分站 35% |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 分站 delta=0 | 44.0 | 454.5 | 40.0 | 500.0 | 45.5 | 15.93 |
|
||||
| 分站 delta=5 | 39.0 | 512.8 | 35.0 | 571.4 | 58.6 | 20.51 |
|
||||
| 分站 delta=10 | 34.0 | 588.2 | 30.0 | 666.7 | 78.5 | 27.48 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 问题清单
|
||||
|
||||
### 4.1 问题一:方向反转——「低价收号」在当前引擎里反而缩小分账池
|
||||
|
||||
**证明(比例带)**:设卖家比例 `X`、修正点数 `s`、`W` 为万哈夫币:
|
||||
|
||||
```
|
||||
号主价 S = W / X
|
||||
买家价 B = W / (X − s)
|
||||
毛利 M = B − S = W·s / (X(X − s))
|
||||
dM/dX < 0 → X 越大(收货越便宜),M 越小
|
||||
```
|
||||
|
||||
**用 1 亿号(R=43、s=5)验证**:假设放开 2.2 节的 `R` 上限,允许分站压价 5 点(比例 43→48):
|
||||
|
||||
| 方案 | 号主收货价 | 买家价 | 毛利 | 分站 35% |
|
||||
|---|---|---|---|---|
|
||||
| 现状基准(delta=0) | 232.6 | 263.2 | 30.6 | 10.71 |
|
||||
| 假设压价收货 δ=+5 | **208.3**(号主少拿 24.3) | **232.6**(买家也少付 30.6) | **24.3(池子反而变小 6.3)** | **8.51(少赚 2.20)** |
|
||||
| 现行让利 δ=5 | 263.2(号主多拿) | 303.0(买家多付) | 39.8(池子变大 9.2) | 13.93 |
|
||||
|
||||
结论:**分站压价省下的 24.3 元被买家全部拿走,分账池还缩水。** 现行的「让利」之所以能让三方多赚,是因为成本转嫁给了买家。用户期望的「低收号 → 每方多赚」在当前结构下无法实现。
|
||||
|
||||
### 4.2 问题二:三套引擎切换 + 档位边界跳变
|
||||
|
||||
以满配 9 格账号为例(基础 40 + 币量修正,日均损耗 10),`delta=0` 与 `delta=5`:
|
||||
|
||||
| 币量 | R | 规则 | δ=0 利润 | δ=0 分站 35% | δ=5 利润 | δ=5 分站 35% |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 89M | 40 | 固定 +38 | 38.0 | 13.30 | 38.0 | 13.30 |
|
||||
| **91M** | 40 | 比例 −5 | **32.5**(比 89M 少) | 11.38 | 43.3 | 15.16 |
|
||||
| 130M | 40 | 比例 −5 | 46.4 | 16.24 | 61.9 | 21.67 |
|
||||
| **131M** | 41 | 比例 −5 | **44.4**(币更多、利润更少) | 15.54 | 58.7 | 20.55 |
|
||||
| 230M | 41 | 比例 −4 | 52.3 | 18.31 | 68.8 | 24.08 |
|
||||
| **231M** | 42.5 | 比例 −3.5 | **48.8**(又掉) | 17.08 | 63.4 | 22.19 |
|
||||
| 309M | 42.5 | 比例 −3.5 | 65.2 | 22.82 | 84.8 | 29.68 |
|
||||
| **310M** | 42.5 | 比例 −3 | **55.4**(掉 9.8) | 19.39 | 71.9 | 25.17 |
|
||||
| 380M | 42.5 | 比例 −3 | 67.9 | 23.77 | 88.1 | 30.84 |
|
||||
| **381M** | 44 | 比例 −3 | **63.4**(掉 4.5) | 22.19 | 81.4 | 28.49 |
|
||||
| 389M | 44 | 比例 −3 | 64.7 | 22.65 | 83.2 | 29.12 |
|
||||
| **390M** | 44 | 比例 −0 | **0.00** | **0.00** | **0.00** | **0.00** |
|
||||
| 600M | 45 | 比例 −0 | 0.00 | 0.00 | 0.00 | 0.00 |
|
||||
|
||||
跳变根因:固定加价档的边界(10/30/50/70/90)与比例修正档的边界(90/150/230/310/390/470/550)不同步;同时 `R` 的币量修正本身在 130/230/380/530M 处跳档,两者叠加造成非单调。
|
||||
|
||||
### 4.3 问题三:390M 以上「待定」档 → 0 利润、delta 完全失效
|
||||
|
||||
- 默认配置:`{390–470: 0}, {470–550: 0}, {550+: 0}`(`external_pricing.go` 与 `systemconfig/sale_price_config.go` 各一份)。
|
||||
- `买家比例 = 卖家比例 − 0`,即买家价 = 号主价,**提价利润恒为 0**;三方分账全为 0,服务费基数为 0 也为 0。
|
||||
- 此时 `delta` 无论调多少,卖家价与买家价同额上涨,利润仍是 0。
|
||||
- 文档 `docs/出售加价规则.md:17-19` 明确标注这三档为「待定」,属于未完成配置。
|
||||
|
||||
### 4.4 问题四:同一个 delta 在不同档位效果不同
|
||||
|
||||
| 档位 | delta 对分账池的影响 |
|
||||
|---|---|
|
||||
| 10M ≤ coinM < 90M(固定加价) | **无影响**(利润恒定 28/31/34/38) |
|
||||
| 90M ≤ coinM < 390M(比例修正) | 正影响(delta 越大池子越大) |
|
||||
| coinM ≥ 390M(修正 0) | **无影响**(恒为 0) |
|
||||
| coinM < 10M(无规则) | 无影响(恒为 0) |
|
||||
|
||||
运营视角即「调了这个数字,有时有用、有时没用、有时效果特别大」。
|
||||
|
||||
### 4.5 问题五:命名与文案反向误导
|
||||
|
||||
- 截图/主站后台文案:`相对主站下调 X 点`,字面像「把收货价往下调(更便宜)」;
|
||||
- 代码:`sellerRatio = R − delta`,比例下降 → `价格 = W / X` 上升 → **收货价更高**。
|
||||
- 同一界面上会同时出现 4 个「比例」(主站上限、回收比例、买家比例、货架加价比例),且与金额反向,极易理解错。
|
||||
|
||||
### 4.6 问题六:工程重复实现风险
|
||||
|
||||
- 前端 `frontend/src/shared/utils/pricing.ts` 与后端 `external_pricing.go` 是两套同口径实现,容易漂移;
|
||||
- 默认加价规则存在**三份副本**:
|
||||
1. `backend/internal/modules/listing/external_pricing.go:56` `defaultSalePriceConfig()`
|
||||
2. `backend/internal/modules/systemconfig/sale_price_config.go` `DefaultSalePriceConfig()`
|
||||
3. `frontend/src/features/listings/api/listingOptions.ts` `emptyListingSalePriceConfig`
|
||||
- 线上已存在的 `system_configs.listing.sale_price_config` 是初始化播种的(`systemconfig/repository.go`),**改代码默认值不会更新老库**,必须迁移或后台手改。
|
||||
|
||||
---
|
||||
|
||||
## 5. 候选改造方案
|
||||
|
||||
### 5.1 方案 A:保持现状(基线)
|
||||
|
||||
「分站加价收货抢货源,平台抬高买家价放大分账池」。不推荐作为长期方案,仅作为对照基线。
|
||||
|
||||
- 优点:抢货源有直接的价格武器;90–390M 区间三方分账随 delta 增长。
|
||||
- 缺点:买家承担全部成本;分站「低成本收货」能力无处体现;固定带与 ≥390M 时 delta 失效;价格随 delta 上涨可能流失买家。
|
||||
|
||||
### 5.2 方案 B:解耦(售价锚定主站,分站压价收货)— ✅ 已实施(2026-09-17)
|
||||
|
||||
**目标口径**
|
||||
|
||||
```
|
||||
收货价 P_buy = W / (R + δ) δ ≥ 0,分站靠议价压低收货价
|
||||
售价 P_sell = 主站售价(R) 不再与 P_buy 联动
|
||||
毛利 M = P_sell − P_buy → 35% 分站 / 40% 主站 / 25% 服务费
|
||||
```
|
||||
|
||||
**示例(1 亿号,R=43,主站售价锚定 263.2)**
|
||||
|
||||
| 分站压价 δ | 收货比例 | 号主收到 | 售价 | 毛利 | 分站 35% | 主站 40% | 平台 25% |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 0 | 43 | 232.6 | 263.2 | 30.6 | 10.71 | 12.24 | 7.65 |
|
||||
| 2 | 45 | 222.2 | 263.2 | 41.0 | 14.35 | 16.40 | 10.25 |
|
||||
| 5 | 48 | 208.3 | 263.2 | 54.9 | 19.21 | 21.96 | 13.73 |
|
||||
| 10 | 53 | 188.7 | 263.2 | 74.5 | 26.08 | 29.80 | 18.63 |
|
||||
| 20 | 63 | 158.7 | 263.2 | 104.5 | 36.57 | 41.80 | 26.13 |
|
||||
|
||||
小号同样成立(coinM=20,售价锚定 74.5):δ=5 时号主 41.7,毛利 28.0 → 32.8,分站 9.80 → 11.48。
|
||||
|
||||
**要点**:此口径下「每方多赚」指分站/主站/平台,**号主是让利方**,必须设收货价下限保护。
|
||||
|
||||
### 5.3 方案 C:方案 B + 分站自费让利
|
||||
|
||||
在 B 的基础上保留「加价抢货」能力,但**让利部分从分站自己的 35% 扣除,绝不抬高买家价**。
|
||||
|
||||
```
|
||||
收货价 = W / (R + δ_buy − δ_subsidy)
|
||||
分站净得 = 35% × 毛利 − 补贴(δ_subsidy 对应金额)
|
||||
```
|
||||
|
||||
需要额外定义:补贴封顶、分站应得为负时的处理(挂应收 or 归零)、退款/部分退款时的补贴冲回规则。
|
||||
|
||||
### 5.4 方案 D:只修数据坑(模型不动)
|
||||
|
||||
- 补齐 390M 以上三档的修正值;
|
||||
- 抹平档位跳变(连续化或让档位只升不降);
|
||||
- 统一/合并三份默认值,迁移线上 `system_configs`;
|
||||
- 修正文案与命名(比例 ↔ 价格语义)。
|
||||
|
||||
保持「让利抢货」口径不变。
|
||||
|
||||
### 5.5 方案对比
|
||||
|
||||
| 维度 | B 解耦 | C = B + 自费让利 | D 只修数据坑 |
|
||||
|---|---|---|---|
|
||||
| 新增 DB 字段 | 1(或给旧字段加语义版本) | 2–3(站点 + 订单快照 + 财务) | 0 |
|
||||
| 后端主要改动 | `receive_pricing.go`、配置默认值、站点字段 | 叠加 `distribution/pricing.go`、`lifecycle.go`、财务模型 | `systemconfig`、默认值、迁移更新配置行 |
|
||||
| 前端主要改动 | 发布页定价、分销后台设置 | 叠加结算/账务展示 | 默认规则数组、文案 |
|
||||
| 历史订单影响 | 无(快照) | 无,但新单财务字段增多 | 无 |
|
||||
| 改造量(含测试) | 5–8 人天 | 8–15 人天 | 1–2 人天 |
|
||||
| 主要风险 | 无下限压价伤号主、买家价基准变更 | 结算正确性、退款分摊、负余额、审计 | 老库配置不自动生效、三处默认值漏改 |
|
||||
| 回滚方式 | 代码回退 | 代码回退 + 新字段保留只读 | 代码回退 + 恢复旧配置 JSON |
|
||||
|
||||
---
|
||||
|
||||
## 6. 改造清单(方案 B 清单已实施,其余为计划项)
|
||||
|
||||
### 6.1 方案 B 清单
|
||||
|
||||
| 文件 | 计划改动 |
|
||||
|---|---|
|
||||
| `backend/internal/modules/listing/receive_pricing.go` | `applyMainSiteReceivePricing`:分站分支拆成「卖家压价比例」与「买家定价基准 R」两条;`ApplySiteReceiveRatioDelta`(`:115`)方向反转或改名 `ApplySiteReceiveCostDelta`,加下限;`NormalizeSiteReceiveRatioDelta`(`:104`)范围重定;`ReceivePricingFromAssetSummary`(`:28`)输出金额字段 |
|
||||
| `backend/internal/modules/listing/external_pricing.go` | `calculateExternalPlatformPricing`(`:118`)入参语义从「卖家比例」改为「基准 R」,明确区分,避免再次耦合 |
|
||||
| `backend/internal/modules/listing/site_receive.go` | 读取新字段 / 新语义 + 兼容旧字段 |
|
||||
| `backend/internal/model/distribution.go` | 新增 `receive_cost_delta`,保留旧 `receive_ratio_delta` 只读 |
|
||||
| `backend/internal/modules/distribution/repository.go` | `normalizeReceiveRatioDelta`(`:69`)校验、`UpdateSite`(`:329`/`:381`)、DTO 映射、读侧快照(约 `:2634`) |
|
||||
| `backend/migrations/`(新增 000072) | `ALTER TABLE distribution_sites ADD receive_cost_delta ...`;`price_breakdown` 增加 `pricing_model` 版本标记(仅代码写入,不改表也可) |
|
||||
| `frontend/src/shared/utils/pricing.ts` | `applySiteReceiveRatioDelta`(`:162`)与 `calculatePlatformPricing`(`:175`)解绑;买家定价改用基准 R |
|
||||
| `frontend/src/shared/composables/usePricingCalculator.ts` | 同步口径与展示 |
|
||||
| `frontend/src/features/listings/api/listingOptions.ts` | 类型与默认值同步 |
|
||||
| `frontend/src/stores/distributionSite.ts` | 读取新字段 |
|
||||
| `frontend/src/features/seller/composables/usePublishForm.ts` | 传参同步 |
|
||||
| `distribution-admin/src/pages/SiteSettings.tsx`、`distribution-admin/src/api.ts` | 输入改为「压价点数」,文案改为价格语义 |
|
||||
| `frontend/src/features/admin/views/AdminDistributionSitesView.vue` | 主站侧弹窗/列同步 |
|
||||
|
||||
### 6.2 方案 C 额外清单
|
||||
|
||||
| 文件 | 计划改动 |
|
||||
|---|---|
|
||||
| `backend/internal/model/distribution.go`、新迁移 | 站点加 `receive_subsidy_delta`;订单加补贴快照;`DistributionOrderFinancial`(`:89`)增列 |
|
||||
| `backend/internal/modules/distribution/pricing.go` | `CalculateSettlement`(`:173`)、`SplitSettlement`(`:273`)引入补贴项与封顶规则 |
|
||||
| `backend/internal/modules/distribution/lifecycle.go` | `SnapshotPaidOrderTx`(`:183`)、结算/释放/退款重算(`:300` 起)带补贴与按比例冲回 |
|
||||
| `backend/internal/modules/distribution/repository.go` | 结算批次与分站余额负数处理 |
|
||||
| `distribution-admin` 钱包/结算页、主站财务看板 | 补贴明细与净收益展示 |
|
||||
| `docs/分销网管理后台设计方案.md` 7.5 / 7.8 | 同步口径 |
|
||||
|
||||
### 6.3 方案 D 清单
|
||||
|
||||
| 文件 | 计划改动 |
|
||||
|---|---|
|
||||
| `backend/internal/modules/systemconfig/sale_price_config.go` | 补齐 390M+ 三档修正值 |
|
||||
| `backend/internal/modules/listing/external_pricing.go:56` | 同步默认值,并考虑与 `systemconfig` 合并消除重复 |
|
||||
| `backend/migrations/`(新增) | `UPDATE system_configs SET value=... WHERE key='listing.sale_price_config'`,且仅当当前值等于旧默认时更新,避免覆盖运营手改 |
|
||||
| `frontend/src/features/listings/api/listingOptions.ts` | 前端默认值与归一化同步 |
|
||||
| `docs/出售加价规则.md` | 「待定」改为确定值 |
|
||||
| 跳变处理(可选,会扩大改动) | `external_pricing.go` 档位判定 + 前端同名逻辑连续化 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 风险与回滚
|
||||
|
||||
### 7.1 通用风险
|
||||
|
||||
1. **前后端双实现必须同步**:任何口径改动都要同时改 `pricing.ts` 与 `external_pricing.go`,否则发布页预览与实际扣款不一致。
|
||||
2. **三份默认值 + 线上配置行**:改默认只影响新库;老库需迁移或后台手改。
|
||||
3. **快照语义**:`seller_ratio` 在旧/新口径下含义不同,建议在 `asset_summary.price_breakdown` 写入 `pricing_model` 版本号,报表才能区分。
|
||||
4. **历史数据不可重算**:所有金额在支付时快照,改引擎只影响之后的新发布/编辑商品与订单;这也意味着回滚不需要动历史数据。
|
||||
|
||||
### 7.2 方案特有风险
|
||||
|
||||
- **方案 B**:分站可能无限压价 → 号主流失、跨站套利;必须设收货价下限(如不低于主站回收价的某个百分比)与 `δ` 上限。分站收号商品的买家价基准变化可能引起客诉。
|
||||
- **方案 C**:资金链路改动,补贴参与退款/部分退款/超时释放/税费基数;需处理分站应得为负;对账口径需同步更新。
|
||||
- **方案 D**:改档位值会让 ≥390M 大额号的买家价一次性变化,需运营知情;迁移需保护运营已手改的配置。
|
||||
|
||||
### 7.3 回滚
|
||||
|
||||
- B / C:回退代码即可;新增列保留(可空、默认 0),历史订单/快照不受影响。
|
||||
- D:回退代码;若已执行配置迁移,需保留旧 JSON 以便恢复(或在迁移中同时记录旧值)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 建议实施顺序
|
||||
|
||||
1. **阶段 0:方案 D 止血** —— ⏳ 待办。补齐 390M+、消除「0 利润」与主要跳变。
|
||||
注:方案 B 解耦后,分站侧毛利不再依赖买家价下移,390M+ 的「0 提价利润」对分站压价收益的影响已减弱,但主站自身挂牌价仍受影响,故此项仍需处理。
|
||||
2. **阶段 1:方案 B** —— ✅ 已实施(2026-09-17)。未采用影子计算开关:以新字段
|
||||
`receive_cost_delta` + 快照 `pricing_model = site_cost_decoupled_v1` 标记区分口径,存量商品靠快照天然隔离。
|
||||
3. **阶段 2:方案 C** —— ⏳ 未实施。需先定义补贴封顶与退款冲回规则。
|
||||
|
||||
文案修正已随阶段 1 一并完成:主站/分销后台均改为价格语义「收号价比主站低 X 点」。
|
||||
|
||||
---
|
||||
|
||||
## 9. 验收与回归用例
|
||||
|
||||
### 9.1 确定性回归表
|
||||
|
||||
构造 `(coinM, 账号属性, delta)` → `(号主底价, 买家价, 毛利, 三方分账)` 的固定表格,前后端分别执行并逐项比对。已有可对齐的基准点:
|
||||
|
||||
- `R=43`、`coinM=100`:主站默认号主基础价 `232.6`、买家比例 `38`、买家总价 `263.20`(`receive_pricing_test.go` 已固定)。
|
||||
|
||||
### 9.2 属性断言
|
||||
|
||||
1. **单调性**:新口径下(方案 B/C)压价 δ 越大 → 毛利与三方分账单调不降。
|
||||
2. **无跳变**:相邻币量档位之间毛利变化有界,不出现「币更多、利润更少」。
|
||||
3. **非负**:任何档位、任何 δ 下毛利与分账 ≥ 0(除非产品明确允许负补贴)。
|
||||
4. **前后端一致**:同一输入下前端预览与后端快照金额完全一致。
|
||||
5. **边界**:coinM 在 10/30/50/70/90/130/230/310/380/390/470/530/550 各边界值前后各测一点。
|
||||
|
||||
### 9.3 回归范围
|
||||
|
||||
- 后端:`receive_pricing_test.go`、`external_adjustment_test.go`、`distribution/pricing_test.go`、`distribution/lifecycle_test.go`、`backend/internal/e2e`。
|
||||
- 前端:`usePricingCalculator` 相关单测(建议新增)、发布页 e2e。
|
||||
- 结算:结算批次、冷却释放、退款重算。
|
||||
|
||||
---
|
||||
|
||||
## 10. 附录
|
||||
|
||||
### 10.1 代码索引
|
||||
|
||||
| 主题 | 位置 |
|
||||
|---|---|
|
||||
| 收号定价主流程 | `backend/internal/modules/listing/receive_pricing.go:55` |
|
||||
| 分站 delta 应用 | `backend/internal/modules/listing/receive_pricing.go:115` |
|
||||
| 买家加价与档位规则 | `backend/internal/modules/listing/external_pricing.go:56`、`:118` |
|
||||
| 分站 delta 读取 | `backend/internal/modules/listing/site_receive.go` |
|
||||
| 分销分账 | `backend/internal/modules/distribution/pricing.go:173`、`:273` |
|
||||
| 订单来源/模式判定 | `backend/internal/modules/distribution/lifecycle.go:38` |
|
||||
| 支付快照 | `backend/internal/modules/distribution/lifecycle.go:183` |
|
||||
| 站点字段与校验 | `backend/internal/model/distribution.go`、`backend/internal/modules/distribution/repository.go:69` |
|
||||
| 收号比例迁移 | `backend/migrations/000070_distribution_site_receive_ratio.sql` |
|
||||
| 加价默认规则(后端·listing) | `backend/internal/modules/listing/external_pricing.go:56` |
|
||||
| 加价默认规则(后端·systemconfig) | `backend/internal/modules/systemconfig/sale_price_config.go` |
|
||||
| 加价默认规则(前端) | `frontend/src/features/listings/api/listingOptions.ts` |
|
||||
| 前端定价实现 | `frontend/src/shared/utils/pricing.ts:128/162/175`、`frontend/src/shared/composables/usePricingCalculator.ts` |
|
||||
| 分销后台设置 UI | `distribution-admin/src/pages/SiteSettings.tsx` |
|
||||
| 主站后台分站管理 UI | `frontend/src/features/admin/views/AdminDistributionSitesView.vue` |
|
||||
| 加价规则文档 | `docs/出售加价规则.md`、`docs/发布比例计算.md` |
|
||||
|
||||
### 10.2 术语表
|
||||
|
||||
| 术语 | 含义 |
|
||||
|---|---|
|
||||
| 主站参考比例 R | 按账号属性算出的回收比例基准,也是主站给号主的最高价(比例最小值) |
|
||||
| 回收比例 / 收号比例 | 号主侧的兑换比例,越大表示收购价越低 |
|
||||
| 买家比例 | 租客侧的兑换比例,由主站规则从卖家侧推导 |
|
||||
| δ(delta) | 分站相对主站的比例调整点数 |
|
||||
| 提价利润 | 买家价 − 号主价,进入 35/40/25 分账 |
|
||||
| 分站自主加价 | 主站账号在分站销售时的加价,100% 归分站 |
|
||||
Reference in New Issue
Block a user