feat(distribution): 分站收号压价解耦买家价(方案 B 新口径)
核心语义反转:receive_cost_delta 为压价点数,收号比例 = 主站参考比例 R + 点数, 点数越大号主收号价越低;买家售价锚定主站参考比例推导,不再随收号价联动。 - 迁移 000072:distribution_sites 新增 receive_cost_delta(旧 receive_ratio_delta 保留只读) - receive_pricing:新增 Normalize/ApplySiteReceiveCostDelta;分站定价买家侧改用 R 锚点(referenceSellerCoinBasePrice),快照写入 site_receive_cost_delta 与 pricing_model 标记 - site_receive:新增 resolveSiteReceiveCostDelta 读取链路,旧 ResolveReceiveRatioDelta 保留 - 分成不变:压价差经结算层 profit 自动进入 35/40/25 三方分成池; 货架自主加价仍 100% 归分站,两条边界均以主站为锚 - 权限对齐旧字段:主站全局管理员与分站操作员均可设置 - 前端三端同步:主站 pricing.ts/usePricingCalculator 买卖解耦试算、 主站后台弹窗改「收号压价」价格语义文案、分销后台 SiteSettings 同步 - 测试:单测锚定 R=43 时 cost_delta=3 → 收号 217.4 / 卖价 263.2 不变 / markup 池 30.6→54.9
This commit is contained in:
@@ -19,11 +19,10 @@ import {
|
||||
hasAcceleratedSaleRatioInput as hasAcceleratedSaleRatioValue,
|
||||
isQuantityItemDisabledForInsurance,
|
||||
readFinalSaleRatio,
|
||||
applySiteReceiveRatioDelta,
|
||||
applySiteReceiveCostDelta,
|
||||
roundMoney,
|
||||
roundRatio,
|
||||
} from '@/shared/utils/pricing'
|
||||
|
||||
export function usePricingCalculator(options: {
|
||||
publishOptions: Ref<ListingPublishOptions>
|
||||
salePriceConfig: Ref<PublishSalePriceConfig>
|
||||
@@ -34,6 +33,7 @@ export function usePricingCalculator(options: {
|
||||
selectedSkins: Ref<string[]>
|
||||
isDistribution?: Ref<boolean>
|
||||
receiveRatioDelta?: Ref<number>
|
||||
receiveCostDelta?: Ref<number>
|
||||
}) {
|
||||
const serverOptions = computed(() => options.publishOptions.value.server_options)
|
||||
const faceOptions = computed(() => options.publishOptions.value.face_options)
|
||||
@@ -91,12 +91,17 @@ export function usePricingCalculator(options: {
|
||||
const siteReceiveRatioDelta = computed(() =>
|
||||
Math.max(0, Number(options.receiveRatioDelta?.value || 0))
|
||||
)
|
||||
const siteReceiveCostDelta = computed(() =>
|
||||
Math.max(0, Number(options.receiveCostDelta?.value || 0))
|
||||
)
|
||||
// 分站新口径:收号价按「R + 压价点数」计算(压价收号);买家定价仍按主站口径推导。
|
||||
// 买卖两侧解耦:calculatedRatio 决定号主收号价,anchorRatio 决定买家价基准。
|
||||
const calculatedRatio = computed(() => {
|
||||
if (calculatedDefaultSaleRatio.value <= 0) return 0
|
||||
if (options.isDistribution?.value) {
|
||||
return applySiteReceiveRatioDelta(
|
||||
return applySiteReceiveCostDelta(
|
||||
calculatedDefaultSaleRatio.value,
|
||||
siteReceiveRatioDelta.value
|
||||
siteReceiveCostDelta.value
|
||||
)
|
||||
}
|
||||
return readFinalSaleRatio(
|
||||
@@ -105,10 +110,19 @@ export function usePricingCalculator(options: {
|
||||
maxAcceleratedSaleRatio.value
|
||||
)
|
||||
})
|
||||
const anchorRatio = computed(() => {
|
||||
if (calculatedDefaultSaleRatio.value <= 0) return 0
|
||||
if (options.isDistribution?.value) return calculatedDefaultSaleRatio.value
|
||||
return calculatedRatio.value
|
||||
})
|
||||
const calculatedCoinBasePrice = computed(() => {
|
||||
if (calculatedRatio.value <= 0) return 0
|
||||
return roundMoney(coinWanAmount.value / calculatedRatio.value)
|
||||
})
|
||||
const anchorCoinBasePrice = computed(() => {
|
||||
if (anchorRatio.value <= 0) return 0
|
||||
return roundMoney(coinWanAmount.value / anchorRatio.value)
|
||||
})
|
||||
const calculatedConsumablePrice = computed(() =>
|
||||
calculateConsumablePrice({
|
||||
quantityItems: quantityItems.value,
|
||||
@@ -122,13 +136,18 @@ export function usePricingCalculator(options: {
|
||||
? roundMoney(calculatedCoinBasePrice.value + calculatedConsumablePrice.value)
|
||||
: 0
|
||||
)
|
||||
const anchorSellerPrice = computed(() =>
|
||||
anchorRatio.value > 0
|
||||
? roundMoney(anchorCoinBasePrice.value + calculatedConsumablePrice.value)
|
||||
: 0
|
||||
)
|
||||
const calculatedPlatformPricing = computed(() =>
|
||||
calculatePlatformPricing({
|
||||
coinMAmount: coinMAmount.value,
|
||||
coinWanAmount: coinWanAmount.value,
|
||||
sellerRatio: calculatedRatio.value,
|
||||
sellerCoinBasePrice: calculatedCoinBasePrice.value,
|
||||
sellerTotalPrice: calculatedSellerPrice.value,
|
||||
sellerRatio: anchorRatio.value,
|
||||
sellerCoinBasePrice: anchorCoinBasePrice.value,
|
||||
sellerTotalPrice: anchorSellerPrice.value,
|
||||
consumablePrice: calculatedConsumablePrice.value,
|
||||
salePriceConfig: options.salePriceConfig.value,
|
||||
})
|
||||
@@ -212,6 +231,7 @@ export function usePricingCalculator(options: {
|
||||
calculatedDefaultSaleRatio,
|
||||
maxAcceleratedSaleRatio,
|
||||
siteReceiveRatioDelta,
|
||||
siteReceiveCostDelta,
|
||||
calculatedRatio,
|
||||
calculatedCoinBasePrice,
|
||||
calculatedConsumablePrice,
|
||||
|
||||
@@ -165,6 +165,16 @@ export function applySiteReceiveRatioDelta(referenceRatio: number, delta: number
|
||||
return roundRatio(Math.max(referenceRatio - safeDelta, 0.01))
|
||||
}
|
||||
|
||||
/**
|
||||
* 分站收号压价(新口径):收号比例 = 主站参考比例 R + 点数,比例变大 → 收号价更低。
|
||||
* 买家价已解耦,不再从收号比例推导,始终锚定主站参考口径。
|
||||
*/
|
||||
export function applySiteReceiveCostDelta(referenceRatio: number, delta: number) {
|
||||
if (referenceRatio <= 0) return 0
|
||||
const safeDelta = Math.min(20, Math.max(0, Number(delta) || 0))
|
||||
return roundRatio(referenceRatio + safeDelta)
|
||||
}
|
||||
|
||||
export function hasAcceleratedSaleRatioInput(value: number | '' | null | undefined) {
|
||||
const ratio = Number(value)
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user