fix: 按实际纯币结算金额计算保险费用
This commit is contained in:
@@ -406,7 +406,7 @@ func calculateCheckoutSettlement(order model.RentalOrder, consumableAmountCent i
|
||||
// 可完结时租客实际承担的租金向金额;有 shortfall 时仍展示完整应付便于协商
|
||||
actualRentAmountCent := actualBuyerRentCent
|
||||
ownerRentIncomeCent := actualOwnerRentCent
|
||||
insuranceFeeCent := calculateInsuranceFeeCent(ownerRentIncomeCent, order.InsuranceFeeBps)
|
||||
insuranceFeeCent := calculateInsuranceFeeCent(usedOwnerCoinPriceCent, order.InsuranceFeeBps)
|
||||
ownerRentIncomeCent = maxCent(ownerRentIncomeCent-insuranceFeeCent, 0)
|
||||
platformFeeCent := maxCent(actualRentAmountCent-ownerRentIncomeCent, 0)
|
||||
depositCompensationCent := damageAppliedCent
|
||||
|
||||
@@ -49,13 +49,48 @@ func TestCalculateCheckoutSettlementDeductsPremiumInsuranceFee(t *testing.T) {
|
||||
}
|
||||
|
||||
settlement := calculateCheckoutSettlement(order, 12000, 100, 0)
|
||||
if settlement.InsuranceFeeBps != 400 || settlement.InsuranceFeeCent != 1412 {
|
||||
if settlement.InsuranceFeeBps != 400 || settlement.InsuranceFeeCent != 932 {
|
||||
t.Fatalf("保险费用快照不正确: bps=%d fee=%d", settlement.InsuranceFeeBps, settlement.InsuranceFeeCent)
|
||||
}
|
||||
if settlement.OwnerRentIncomeCent != 33888 {
|
||||
t.Fatalf("号主净租金 = %d, want 33888", settlement.OwnerRentIncomeCent)
|
||||
if settlement.OwnerRentIncomeCent != 34368 {
|
||||
t.Fatalf("号主净租金 = %d, want 34368", settlement.OwnerRentIncomeCent)
|
||||
}
|
||||
if settlement.PlatformFeeCent != 4412 {
|
||||
t.Fatalf("平台收入 = %d, want 4412", settlement.PlatformFeeCent)
|
||||
if settlement.PlatformFeeCent != 3932 {
|
||||
t.Fatalf("平台收入 = %d, want 3932", settlement.PlatformFeeCent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCheckoutSettlementUsesActualPureCoinAsInsuranceBase(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
RentAmountCent: 25000,
|
||||
OwnerRentAmountCent: 25000,
|
||||
DepositAmountCent: 15000,
|
||||
InsuranceFeeBps: 800,
|
||||
AccountSnapshot: datatypes.JSON([]byte(`{
|
||||
"haf_coin_amount": 100000000,
|
||||
"asset_summary": {
|
||||
"price_breakdown": {
|
||||
"buyer_ratio": 40,
|
||||
"seller_ratio": 40,
|
||||
"buyer_coin_base_price": 250,
|
||||
"seller_coin_base_price": 250,
|
||||
"consumable_price": 0
|
||||
}
|
||||
}
|
||||
}`)),
|
||||
}
|
||||
|
||||
settlement := calculateCheckoutSettlement(order, 5000, 50, 0)
|
||||
if settlement.PureCoinAmountCent != 12500 {
|
||||
t.Fatalf("实际纯币原价 = %d, want 12500", settlement.PureCoinAmountCent)
|
||||
}
|
||||
if settlement.InsuranceFeeCent != 1000 {
|
||||
t.Fatalf("保险费用 = %d, want 1000", settlement.InsuranceFeeCent)
|
||||
}
|
||||
if settlement.ExtraItemAmountCent != 5000 {
|
||||
t.Fatalf("额外物品 = %d, want 5000", settlement.ExtraItemAmountCent)
|
||||
}
|
||||
if settlement.OwnerRentIncomeCent != 16500 {
|
||||
t.Fatalf("号主净租金 = %d, want 16500", settlement.OwnerRentIncomeCent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,21 @@ import (
|
||||
const defaultBannerHotspotHoverScale = 1.06
|
||||
const maxBannerHotspotHoverScale = 1.5
|
||||
|
||||
func migrateInsuranceBillingCopy(value string) string {
|
||||
value = strings.Replace(
|
||||
value,
|
||||
"注:选择此方案,需额外抽取订单佣金的8.0%作为服务费:押金须达到推荐押金方可购买。",
|
||||
"无忧保险服务费按实际纯币结算金额计算,额外物品不计入计费基数;具体费率以当前配置为准。押金须达到推荐押金方可购买。",
|
||||
1,
|
||||
)
|
||||
return strings.Replace(
|
||||
value,
|
||||
"并从卖家实际到手租金中扣除。",
|
||||
"并按实际纯币结算金额计算,额外物品不计入保险基数。",
|
||||
1,
|
||||
)
|
||||
}
|
||||
|
||||
func normalizeAnnouncements(items []string) []string {
|
||||
normalized := make([]string, 0, len(items))
|
||||
for _, item := range items {
|
||||
@@ -236,9 +251,15 @@ func normalizePublishOptions(options *PublishOptionsDTO) {
|
||||
}
|
||||
if options.PriceConfig.PremiumZoneTooltip == "" {
|
||||
options.PriceConfig.PremiumZoneTooltip = defaults.PriceConfig.PremiumZoneTooltip
|
||||
} else {
|
||||
options.PriceConfig.PremiumZoneTooltip =
|
||||
migrateInsuranceBillingCopy(options.PriceConfig.PremiumZoneTooltip)
|
||||
}
|
||||
if options.PriceConfig.CompensationNote == "" {
|
||||
options.PriceConfig.CompensationNote = defaults.PriceConfig.CompensationNote
|
||||
} else {
|
||||
options.PriceConfig.CompensationNote =
|
||||
migrateInsuranceBillingCopy(options.PriceConfig.CompensationNote)
|
||||
}
|
||||
if options.PriceConfig.PricePlaceholder == "" {
|
||||
options.PriceConfig.PricePlaceholder = defaults.PriceConfig.PricePlaceholder
|
||||
|
||||
@@ -120,9 +120,9 @@ func DefaultPublishOptions() PublishOptionsDTO {
|
||||
1. 发布条件:仅已认证且有效的优质号主可以开启;未开通时需先缴纳平台要求的信用保证金并完成优质号主认证。
|
||||
2. 专区展示:商品审核通过后将在首页“极品专区”展示,获得更聚焦的高端账号曝光。
|
||||
3. 价格规则:系统会按后台配置在基础比例上计算极品专区专享比例,审核页展示的最终价格通过后不再改价。
|
||||
4. 保险服务:可选择无忧租号保险,服务费率按优质号主及极品专区的当前配置执行,并从卖家实际到手租金中扣除。
|
||||
4. 保险服务:可选择无忧租号保险,服务费率按优质号主及极品专区的当前配置执行,并按实际纯币结算金额计算,额外物品不计入保险基数。
|
||||
5. 责任说明:开启专区不会免除商品审核、资料真实性及发布协议中的责任,请如实填写账号资产与出租条件。`,
|
||||
CompensationNote: "普通赔付方案如下:账号在租期内或祖期外出现封禁,追回、洗号等情况,最高可获赔全款相金+押金\n\n无忧保险赔付方案:按账号市场价值进行赔付(可参照螃蟹,盼之等主流交易平台)。注:选择此方案,需额外抽取订单佣金的8.0%作为服务费:押金须达到推荐押金方可购买。",
|
||||
CompensationNote: "普通赔付方案如下:账号在租期内或祖期外出现封禁,追回、洗号等情况,最高可获赔全款相金+押金\n\n无忧保险赔付方案:按账号市场价值进行赔付(可参照螃蟹,盼之等主流交易平台)。无忧保险服务费按实际纯币结算金额计算,额外物品不计入计费基数;具体费率以当前配置为准。押金须达到推荐押金方可购买。",
|
||||
PricePlaceholder: "填写币数、保险、体力和负重后自动计算;发布总价=纯币基础价+额外消耗品",
|
||||
RatioDescription: "1:xx 表示 1 元人民币(RMB)等价兑换 xx 万哈夫币",
|
||||
},
|
||||
|
||||
@@ -178,6 +178,33 @@ func TestNormalizePublishOptionsValueDefaultsPremiumZoneTooltip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePublishOptionsValueMigratesInsuranceBillingBaseCopy(t *testing.T) {
|
||||
options := DefaultPublishOptions()
|
||||
options.PriceConfig.CompensationNote = "注:选择此方案,需额外抽取订单佣金的8.0%作为服务费:押金须达到推荐押金方可购买。"
|
||||
options.PriceConfig.PremiumZoneTooltip = "4. 保险服务:服务费率按当前配置执行,并从卖家实际到手租金中扣除。"
|
||||
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 !strings.Contains(got.PriceConfig.CompensationNote, "按实际纯币结算金额计算") {
|
||||
t.Fatalf("赔付说明未迁移纯币计费口径: %q", got.PriceConfig.CompensationNote)
|
||||
}
|
||||
if strings.Contains(got.PriceConfig.CompensationNote, "订单佣金") {
|
||||
t.Fatalf("赔付说明仍含旧计费口径: %q", got.PriceConfig.CompensationNote)
|
||||
}
|
||||
if !strings.Contains(got.PriceConfig.PremiumZoneTooltip, "额外物品不计入保险基数") {
|
||||
t.Fatalf("专区说明未迁移纯币计费口径: %q", got.PriceConfig.PremiumZoneTooltip)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizePublishOptionsValuePreservesExplicitZeroPremiumReviewRatioMarkup(t *testing.T) {
|
||||
options := DefaultPublishOptions()
|
||||
options.RatioConfig.PremiumReviewRatioMarkup = 0
|
||||
|
||||
Reference in New Issue
Block a user