feat(listing): 极品专区发布时增加比例加价
This commit is contained in:
@@ -98,6 +98,28 @@ func applyMainSiteReceivePricing(req *CreateRequest, options systemconfig.Publis
|
||||
buyerAnchorCoinBase = referenceSellerCoinBasePrice(coinWan, referenceRatio)
|
||||
}
|
||||
pricing := calculateExternalPlatformPricing(coinM, buyerAnchorRatio, buyerAnchorCoinBase, consumablePrice, config)
|
||||
premiumRatioMarkup := 0.0
|
||||
if req.IsPremium {
|
||||
premiumRatioMarkup = NormalizePremiumReviewRatioMarkup(
|
||||
options.RatioConfig.PremiumReviewRatioMarkup,
|
||||
)
|
||||
}
|
||||
if premiumRatioMarkup > 0 && pricing.BuyerRatio > premiumRatioMarkup {
|
||||
beforeRatio := pricing.BuyerRatio
|
||||
afterRatio := roundRatio(beforeRatio - premiumRatioMarkup)
|
||||
buyerCoinBasePrice := roundMoney(coinWan / afterRatio)
|
||||
pricing = buildExternalPlatformPricing(
|
||||
coinWan,
|
||||
sellerTotalPrice,
|
||||
consumablePrice,
|
||||
buyerCoinBasePrice,
|
||||
pricing.RuleType,
|
||||
)
|
||||
breakdown["premium_review_ratio_markup"] = premiumRatioMarkup
|
||||
breakdown["premium_review_ratio_before"] = beforeRatio
|
||||
breakdown["premium_review_ratio_after"] = pricing.BuyerRatio
|
||||
breakdown["premium_review_ratio_markup_applied"] = true
|
||||
}
|
||||
breakdown["seller_reference_ratio"] = referenceRatio
|
||||
breakdown["seller_ratio"] = sellerRatio
|
||||
breakdown["seller_coin_base_price"] = sellerCoinBasePrice
|
||||
@@ -170,6 +192,17 @@ func NormalizeQualityOwnerRatioDiscount(value float64) float64 {
|
||||
return roundRatio(value)
|
||||
}
|
||||
|
||||
// NormalizePremiumReviewRatioMarkup 限制极品专区发布时额外增加的比例加价点数,最大 10。
|
||||
func NormalizePremiumReviewRatioMarkup(value float64) float64 {
|
||||
if value < 0 || math.IsNaN(value) || math.IsInf(value, 0) {
|
||||
return 0
|
||||
}
|
||||
if value > maxAcceleratedSaleRatioIncrement {
|
||||
return maxAcceleratedSaleRatioIncrement
|
||||
}
|
||||
return roundRatio(value)
|
||||
}
|
||||
|
||||
// referenceSellerCoinBasePrice 计算主站参考比例下的号主基础价,用作买家定价锚点。
|
||||
func referenceSellerCoinBasePrice(coinWan, referenceRatio float64) float64 {
|
||||
if referenceRatio <= 0 {
|
||||
|
||||
@@ -82,6 +82,28 @@ func TestApplyMainSiteReceivePricingKeepsAcceleratedRatioWithinMainSiteRange(t *
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyMainSiteReceivePricingIncludesPremiumReviewMarkup(t *testing.T) {
|
||||
req := fullReceivePricingRequest(50)
|
||||
req.IsPremium = true
|
||||
applyMainSiteReceivePricing(&req, systemconfig.DefaultPublishOptions(), defaultSalePriceConfig(), 0, 0, false)
|
||||
breakdown := ensurePriceBreakdown(req.AssetSummary)
|
||||
if got := readSummaryNumber(breakdown["premium_review_ratio_markup"]); got != 1 {
|
||||
t.Fatalf("premium review markup = %v, want 1", got)
|
||||
}
|
||||
if got := readSummaryNumber(breakdown["premium_review_ratio_before"]); got != 45 {
|
||||
t.Fatalf("premium buyer ratio before = %v, want 45", got)
|
||||
}
|
||||
if got := readSummaryNumber(breakdown["premium_review_ratio_after"]); got != 44 {
|
||||
t.Fatalf("premium buyer ratio after = %v, want 44", got)
|
||||
}
|
||||
if applied, _ := breakdown["premium_review_ratio_markup_applied"].(bool); !applied {
|
||||
t.Fatal("premium review markup should be applied before review")
|
||||
}
|
||||
if req.PriceCent != 22730 {
|
||||
t.Fatalf("premium PriceCent = %d, want final 22730", req.PriceCent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyMainSiteReceivePricingAllowsQualityOwnerExclusiveRatio(t *testing.T) {
|
||||
req := fullReceivePricingRequest(42)
|
||||
req.OwnerIsQualityOwner = true
|
||||
|
||||
@@ -183,6 +183,7 @@ type PublishDepositSkinGroupRule struct {
|
||||
|
||||
type PublishRatioConfig struct {
|
||||
QualityOwnerRatioDiscount float64 `json:"quality_owner_ratio_discount"`
|
||||
PremiumReviewRatioMarkup float64 `json:"premium_review_ratio_markup"`
|
||||
InsuranceBaseRatios []PublishInsuranceBaseRatio `json:"insurance_base_ratios"`
|
||||
ConfigItems []PublishRatioConfigItem `json:"config_items"`
|
||||
CoinCorrections []PublishCoinCorrection `json:"coin_corrections"`
|
||||
|
||||
@@ -252,6 +252,19 @@ func normalizePublishOptions(options *PublishOptionsDTO) {
|
||||
if len(options.RatioConfig.CoinCorrections) == 0 {
|
||||
options.RatioConfig.CoinCorrections = defaults.RatioConfig.CoinCorrections
|
||||
}
|
||||
options.RatioConfig.PremiumReviewRatioMarkup = normalizePremiumReviewRatioMarkup(
|
||||
options.RatioConfig.PremiumReviewRatioMarkup,
|
||||
)
|
||||
}
|
||||
|
||||
func normalizePremiumReviewRatioMarkup(value float64) float64 {
|
||||
if value < 0 || math.IsNaN(value) || math.IsInf(value, 0) {
|
||||
return 0
|
||||
}
|
||||
if value > 10 {
|
||||
return 10
|
||||
}
|
||||
return math.Round(value*10) / 10
|
||||
}
|
||||
|
||||
func normalizeSalePriceConfig(config *PublishSalePriceConfig) {
|
||||
|
||||
@@ -106,6 +106,7 @@ func DefaultPublishOptions() PublishOptionsDTO {
|
||||
},
|
||||
RatioConfig: PublishRatioConfig{
|
||||
QualityOwnerRatioDiscount: 1,
|
||||
PremiumReviewRatioMarkup: 1,
|
||||
InsuranceBaseRatios: []PublishInsuranceBaseRatio{
|
||||
{Insurance: "3*3", Ratio: 40},
|
||||
{Insurance: "2*3", Ratio: 42},
|
||||
|
||||
@@ -128,6 +128,36 @@ func TestNormalizePublishOptionsValueDefaultsQualityOwnerRatioDiscount(t *testin
|
||||
got.RatioConfig.QualityOwnerRatioDiscount,
|
||||
)
|
||||
}
|
||||
if got.RatioConfig.PremiumReviewRatioMarkup != 1 {
|
||||
t.Fatalf(
|
||||
"premium_review_ratio_markup = %v, want 1",
|
||||
got.RatioConfig.PremiumReviewRatioMarkup,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePublishOptionsValuePreservesExplicitZeroPremiumReviewRatioMarkup(t *testing.T) {
|
||||
options := DefaultPublishOptions()
|
||||
options.RatioConfig.PremiumReviewRatioMarkup = 0
|
||||
raw, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
t.Fatalf("构造配置失败: %v", err)
|
||||
}
|
||||
|
||||
normalized, err := normalizePublishOptionsValue(string(raw))
|
||||
if err != nil {
|
||||
t.Fatalf("规范化失败: %v", err)
|
||||
}
|
||||
var got PublishOptionsDTO
|
||||
if err := json.Unmarshal([]byte(normalized), &got); err != nil {
|
||||
t.Fatalf("解析规范化结果失败: %v", err)
|
||||
}
|
||||
if got.RatioConfig.PremiumReviewRatioMarkup != 0 {
|
||||
t.Fatalf(
|
||||
"premium_review_ratio_markup = %v, want explicit 0",
|
||||
got.RatioConfig.PremiumReviewRatioMarkup,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePublishOptionsValuePreservesExplicitZeroQualityOwnerDiscount(t *testing.T) {
|
||||
|
||||
@@ -337,6 +337,10 @@ func normalizePublishOptionsValue(value string) (string, error) {
|
||||
options.RatioConfig.QualityOwnerRatioDiscount =
|
||||
DefaultPublishOptions().RatioConfig.QualityOwnerRatioDiscount
|
||||
}
|
||||
if !hasNestedJSONField(fields, "ratio_config", "premium_review_ratio_markup") {
|
||||
options.RatioConfig.PremiumReviewRatioMarkup =
|
||||
DefaultPublishOptions().RatioConfig.PremiumReviewRatioMarkup
|
||||
}
|
||||
originalVersion := options.SchemaVersion
|
||||
if options.SchemaVersion < publishOptionsSchemaVersion {
|
||||
if hasLegacyPublishQuantityItem(options.QuantityItems) {
|
||||
|
||||
Reference in New Issue
Block a user