diff --git a/backend/internal/modules/listing/receive_pricing.go b/backend/internal/modules/listing/receive_pricing.go index c81f299..7f90e7f 100644 --- a/backend/internal/modules/listing/receive_pricing.go +++ b/backend/internal/modules/listing/receive_pricing.go @@ -83,8 +83,14 @@ func applyMainSiteReceivePricing(req *CreateRequest, options systemconfig.Publis consumablePrice := consumableValue(req.AssetSummary) sellerTotalPrice := roundMoney(sellerCoinBasePrice + consumablePrice) dailyLoss := readSummaryNumber(req.AssetSummary["daily_loss_m"]) - // 买家价始终按主站口径推导:分站只改收号侧,卖价与主站同基准(压价差进入三方分成池)。 - pricing := calculateExternalPlatformPricing(coinM, referenceRatio, referenceSellerCoinBasePrice(coinWan, referenceRatio), consumablePrice, config) + // 主站买家价仍跟 sellerRatio(含加速出售);分站买家价锚定 R,压价差进入三方分成池。 + buyerAnchorRatio := sellerRatio + buyerAnchorCoinBase := sellerCoinBasePrice + if onDistributionSite { + buyerAnchorRatio = referenceRatio + buyerAnchorCoinBase = referenceSellerCoinBasePrice(coinWan, referenceRatio) + } + pricing := calculateExternalPlatformPricing(coinM, buyerAnchorRatio, buyerAnchorCoinBase, consumablePrice, config) breakdown["seller_reference_ratio"] = referenceRatio breakdown["seller_ratio"] = sellerRatio breakdown["seller_coin_base_price"] = sellerCoinBasePrice diff --git a/backend/internal/modules/listing/receive_pricing_test.go b/backend/internal/modules/listing/receive_pricing_test.go index e00ff66..4009f39 100644 --- a/backend/internal/modules/listing/receive_pricing_test.go +++ b/backend/internal/modules/listing/receive_pricing_test.go @@ -69,6 +69,16 @@ func TestApplyMainSiteReceivePricingKeepsAcceleratedRatioWithinMainSiteRange(t * if readSummaryNumber(breakdown["seller_reference_ratio"]) != 43 { t.Fatalf("seller_reference_ratio = %v, want 43", breakdown["seller_reference_ratio"]) } + if got := readSummaryNumber(breakdown["seller_coin_base_price"]); got != 200 { + t.Fatalf("accelerated seller_coin_base_price = %v, want 200", got) + } + // 主站加速出售买卖仍联动:买家比例 = 50 − 5 = 45,不能被误锚到参考比例 38。 + if readSummaryNumber(breakdown["buyer_ratio"]) != 45 { + t.Fatalf("accelerated buyer_ratio = %v, want 45 (follows seller ratio, not reference 38)", breakdown["buyer_ratio"]) + } + if req.PriceCent != 22220 { + t.Fatalf("accelerated PriceCent = %d, want 22220", req.PriceCent) + } } func TestDistributionReceiveCostDeltaZeroKeepsMainSitePrice(t *testing.T) { diff --git a/backend/internal/modules/listing/service_test.go b/backend/internal/modules/listing/service_test.go index d988a8a..61159d4 100644 --- a/backend/internal/modules/listing/service_test.go +++ b/backend/internal/modules/listing/service_test.go @@ -1172,6 +1172,9 @@ func TestCreateDistributionListingAppliesSiteReceiveCostDelta(t *testing.T) { if pricing.SellerRatio != 46 { t.Fatalf("seller_ratio = %v, want 46 after site cost delta 3 (R=43+3) under decoupled model", pricing.SellerRatio) } + if dto.PriceCent != 26320 { + t.Fatalf("listing PriceCent = %d, want 26320 (buyer price stays anchored to main-site R)", dto.PriceCent) + } } func mustMarshalSummary(t *testing.T, summary map[string]any) []byte { diff --git a/distribution-admin/src/pages/Sites.tsx b/distribution-admin/src/pages/Sites.tsx index d1e0d70..c8d732a 100644 --- a/distribution-admin/src/pages/Sites.tsx +++ b/distribution-admin/src/pages/Sites.tsx @@ -167,11 +167,11 @@ export default function Sites({ isSuperadmin = true }: { isSuperadmin?: boolean row.tax_enabled ? {row.tax_rate_bps / 100}% : 不征税, }, { - title: '收号下调', + title: '收号压价', width: 120, render: (_: unknown, row: Site) => - Number(row.receive_ratio_delta || 0) > 0 ? ( - -{Number(row.receive_ratio_delta).toFixed(1)} 点 + Number(row.receive_cost_delta || 0) > 0 ? ( + 低 {Number(row.receive_cost_delta).toFixed(1)} 点 ) : ( 与主站一致 ), diff --git a/frontend/src/shared/composables/usePricingCalculator.ts b/frontend/src/shared/composables/usePricingCalculator.ts index 28e11ca..2e7ad88 100644 --- a/frontend/src/shared/composables/usePricingCalculator.ts +++ b/frontend/src/shared/composables/usePricingCalculator.ts @@ -164,7 +164,7 @@ export function usePricingCalculator(options: { const saleRatioRangeText = computed(() => { if (calculatedDefaultSaleRatio.value <= 0) return '完成基础信息后自动计算参考比例' if (options.isDistribution?.value) { - return `主站上限 1:${formatNumber(calculatedDefaultSaleRatio.value)},本站收号 1:${formatNumber(calculatedRatio.value)}` + return `主站参考 1:${formatNumber(calculatedDefaultSaleRatio.value)},本站收号 1:${formatNumber(calculatedRatio.value)}` } return `可设置 1:${formatNumber(calculatedDefaultSaleRatio.value)} ~ 1:${formatNumber(maxAcceleratedSaleRatio.value)}` })