修正外部上传加价逻辑
This commit is contained in:
@@ -0,0 +1,241 @@
|
|||||||
|
package listing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"math"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const salePriceConfigKey = "listing.sale_price_config"
|
||||||
|
|
||||||
|
type salePriceConfig struct {
|
||||||
|
FixedMarkupRules []saleFixedMarkupRule `json:"fixed_markup_rules"`
|
||||||
|
RatioAdjustmentRules []saleRatioAdjustmentRule `json:"ratio_adjustment_rules"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type saleFixedMarkupRule struct {
|
||||||
|
MinM float64 `json:"min_m"`
|
||||||
|
MaxM float64 `json:"max_m"`
|
||||||
|
MarkupAmount float64 `json:"markup_amount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type saleRatioAdjustmentRule struct {
|
||||||
|
MinM float64 `json:"min_m"`
|
||||||
|
MaxM float64 `json:"max_m"`
|
||||||
|
RatioSubtract float64 `json:"ratio_subtract"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type externalPlatformPricing struct {
|
||||||
|
BuyerCoinBasePrice float64
|
||||||
|
BuyerTotalPrice float64
|
||||||
|
BuyerRatio float64
|
||||||
|
PlatformMarkupPrice float64
|
||||||
|
RuleType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) externalSalePriceConfig(ctx context.Context) (salePriceConfig, error) {
|
||||||
|
config := defaultSalePriceConfig()
|
||||||
|
if s.config == nil {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
value, err := s.config.FindValue(ctx, salePriceConfigKey)
|
||||||
|
if err != nil {
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(value) == "" {
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(value), &config); err != nil {
|
||||||
|
return defaultSalePriceConfig(), nil
|
||||||
|
}
|
||||||
|
return normalizeSalePriceConfig(config), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultSalePriceConfig() salePriceConfig {
|
||||||
|
return salePriceConfig{
|
||||||
|
FixedMarkupRules: []saleFixedMarkupRule{
|
||||||
|
{MinM: 10, MaxM: 30, MarkupAmount: 28},
|
||||||
|
{MinM: 30, MaxM: 50, MarkupAmount: 31},
|
||||||
|
{MinM: 50, MaxM: 70, MarkupAmount: 34},
|
||||||
|
{MinM: 70, MaxM: 90, MarkupAmount: 38},
|
||||||
|
},
|
||||||
|
RatioAdjustmentRules: []saleRatioAdjustmentRule{
|
||||||
|
{MinM: 90, MaxM: 150, RatioSubtract: 5},
|
||||||
|
{MinM: 150, MaxM: 230, RatioSubtract: 4},
|
||||||
|
{MinM: 230, MaxM: 310, RatioSubtract: 3.5},
|
||||||
|
{MinM: 310, MaxM: 390, RatioSubtract: 3},
|
||||||
|
{MinM: 390, MaxM: 470, RatioSubtract: 0},
|
||||||
|
{MinM: 470, MaxM: 550, RatioSubtract: 0},
|
||||||
|
{MinM: 550, RatioSubtract: 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeSalePriceConfig(config salePriceConfig) salePriceConfig {
|
||||||
|
config.FixedMarkupRules = filterFixedMarkupRules(config.FixedMarkupRules)
|
||||||
|
config.RatioAdjustmentRules = filterRatioAdjustmentRules(config.RatioAdjustmentRules)
|
||||||
|
if len(config.FixedMarkupRules) == 0 && len(config.RatioAdjustmentRules) == 0 {
|
||||||
|
return defaultSalePriceConfig()
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterFixedMarkupRules(rules []saleFixedMarkupRule) []saleFixedMarkupRule {
|
||||||
|
result := make([]saleFixedMarkupRule, 0, len(rules))
|
||||||
|
for _, rule := range rules {
|
||||||
|
if !isFiniteNonNegative(rule.MinM) ||
|
||||||
|
!isFiniteNonNegative(rule.MaxM) ||
|
||||||
|
!isFiniteNonNegative(rule.MarkupAmount) ||
|
||||||
|
(rule.MaxM > 0 && rule.MaxM < rule.MinM) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, rule)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterRatioAdjustmentRules(rules []saleRatioAdjustmentRule) []saleRatioAdjustmentRule {
|
||||||
|
result := make([]saleRatioAdjustmentRule, 0, len(rules))
|
||||||
|
for _, rule := range rules {
|
||||||
|
if !isFiniteNonNegative(rule.MinM) ||
|
||||||
|
!isFiniteNonNegative(rule.MaxM) ||
|
||||||
|
!isFiniteNonNegative(rule.RatioSubtract) ||
|
||||||
|
(rule.MaxM > 0 && rule.MaxM < rule.MinM) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, rule)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFiniteNonNegative(value float64) bool {
|
||||||
|
return value >= 0 && !math.IsNaN(value) && !math.IsInf(value, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateExternalPlatformPricing 将外部回收租金视为纯币价格;额外物品与平台加价均单独计算。
|
||||||
|
func calculateExternalPlatformPricing(
|
||||||
|
coinM float64,
|
||||||
|
sellerRatio float64,
|
||||||
|
sellerCoinBasePrice float64,
|
||||||
|
consumablePrice float64,
|
||||||
|
config salePriceConfig,
|
||||||
|
) externalPlatformPricing {
|
||||||
|
sellerCoinBasePrice = nonNegativeMoney(sellerCoinBasePrice)
|
||||||
|
consumablePrice = nonNegativeMoney(consumablePrice)
|
||||||
|
sellerTotalPrice := roundMoney(sellerCoinBasePrice + consumablePrice)
|
||||||
|
coinWan := coinM * 100
|
||||||
|
sellerRatio = roundRatio(sellerRatio)
|
||||||
|
if sellerRatio <= 0 && coinWan > 0 && sellerCoinBasePrice > 0 {
|
||||||
|
sellerRatio = roundRatio(coinWan / sellerCoinBasePrice)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule, ok := findRatioAdjustmentRule(config.RatioAdjustmentRules, coinM); ok && sellerRatio > 0 {
|
||||||
|
buyerRatio := sellerRatio - rule.RatioSubtract
|
||||||
|
if buyerRatio > 0 && coinWan > 0 {
|
||||||
|
buyerCoinBasePrice := roundMoney(coinWan / buyerRatio)
|
||||||
|
if buyerCoinBasePrice < sellerCoinBasePrice {
|
||||||
|
buyerCoinBasePrice = sellerCoinBasePrice
|
||||||
|
}
|
||||||
|
return buildExternalPlatformPricing(
|
||||||
|
coinWan,
|
||||||
|
sellerTotalPrice,
|
||||||
|
consumablePrice,
|
||||||
|
buyerCoinBasePrice,
|
||||||
|
"ratio_subtract",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule, ok := findFixedMarkupRule(config.FixedMarkupRules, coinM); ok {
|
||||||
|
return buildExternalPlatformPricing(
|
||||||
|
coinWan,
|
||||||
|
sellerTotalPrice,
|
||||||
|
consumablePrice,
|
||||||
|
roundMoney(sellerCoinBasePrice+rule.MarkupAmount),
|
||||||
|
"fixed_markup",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildExternalPlatformPricing(
|
||||||
|
coinWan,
|
||||||
|
sellerTotalPrice,
|
||||||
|
consumablePrice,
|
||||||
|
sellerCoinBasePrice,
|
||||||
|
"none",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nonNegativeMoney(value float64) float64 {
|
||||||
|
if value <= 0 || math.IsNaN(value) || math.IsInf(value, 0) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return roundMoney(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildExternalPlatformPricing(
|
||||||
|
coinWan float64,
|
||||||
|
sellerTotalPrice float64,
|
||||||
|
consumablePrice float64,
|
||||||
|
buyerCoinBasePrice float64,
|
||||||
|
ruleType string,
|
||||||
|
) externalPlatformPricing {
|
||||||
|
buyerCoinBasePrice = nonNegativeMoney(buyerCoinBasePrice)
|
||||||
|
buyerTotalPrice := roundMoney(buyerCoinBasePrice + consumablePrice)
|
||||||
|
return externalPlatformPricing{
|
||||||
|
BuyerCoinBasePrice: buyerCoinBasePrice,
|
||||||
|
BuyerTotalPrice: buyerTotalPrice,
|
||||||
|
BuyerRatio: roundRatio(coinWan / buyerCoinBasePrice),
|
||||||
|
PlatformMarkupPrice: roundMoney(buyerTotalPrice - sellerTotalPrice),
|
||||||
|
RuleType: ruleType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func findFixedMarkupRule(rules []saleFixedMarkupRule, coinM float64) (saleFixedMarkupRule, bool) {
|
||||||
|
sorted := append([]saleFixedMarkupRule(nil), rules...)
|
||||||
|
sort.Slice(sorted, func(i, j int) bool {
|
||||||
|
return sorted[i].MinM < sorted[j].MinM
|
||||||
|
})
|
||||||
|
for index, rule := range sorted {
|
||||||
|
if isCoinInPriceRuleRange(rule.MinM, rule.MaxM, index, len(sorted), coinM, true, false) {
|
||||||
|
return rule, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return saleFixedMarkupRule{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func findRatioAdjustmentRule(rules []saleRatioAdjustmentRule, coinM float64) (saleRatioAdjustmentRule, bool) {
|
||||||
|
sorted := append([]saleRatioAdjustmentRule(nil), rules...)
|
||||||
|
sort.Slice(sorted, func(i, j int) bool {
|
||||||
|
return sorted[i].MinM < sorted[j].MinM
|
||||||
|
})
|
||||||
|
for index, rule := range sorted {
|
||||||
|
if isCoinInPriceRuleRange(rule.MinM, rule.MaxM, index, len(sorted), coinM, false, true) {
|
||||||
|
return rule, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return saleRatioAdjustmentRule{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCoinInPriceRuleRange(
|
||||||
|
minM float64,
|
||||||
|
maxM float64,
|
||||||
|
index int,
|
||||||
|
total int,
|
||||||
|
coinM float64,
|
||||||
|
includeLastMax bool,
|
||||||
|
excludeFirstMin bool,
|
||||||
|
) bool {
|
||||||
|
minMatched := coinM >= minM
|
||||||
|
if excludeFirstMin && index == 0 {
|
||||||
|
minMatched = coinM > minM
|
||||||
|
}
|
||||||
|
if !minMatched {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if maxM <= 0 || coinM < maxM {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return includeLastMax && index == total-1 && coinM <= maxM
|
||||||
|
}
|
||||||
@@ -33,11 +33,15 @@ func (s *Service) ImportExternalUpload(ctx context.Context, req ExternalUploadRe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
salePriceConfig, err := s.externalSalePriceConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
clientUploadTime := parseClientUploadTime(req.UploadTime)
|
clientUploadTime := parseClientUploadTime(req.UploadTime)
|
||||||
results := make([]ExternalUploadResult, 0, len(items))
|
results := make([]ExternalUploadResult, 0, len(items))
|
||||||
resp := &ExternalUploadResponse{Total: len(items)}
|
resp := &ExternalUploadResponse{Total: len(items)}
|
||||||
for index, item := range items {
|
for index, item := range items {
|
||||||
createReq := externalAccountToCreateRequest(uploaderName, req.UploadTime, item)
|
createReq := externalAccountToCreateRequest(uploaderName, req.UploadTime, item, salePriceConfig)
|
||||||
if err := validateRequest(createReq, rules); err != nil {
|
if err := validateRequest(createReq, rules); err != nil {
|
||||||
if len(items) == 1 {
|
if len(items) == 1 {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -235,9 +239,14 @@ func parseClientUploadTime(value int64) *time.Time {
|
|||||||
return &parsed
|
return &parsed
|
||||||
}
|
}
|
||||||
|
|
||||||
func externalAccountToCreateRequest(uploaderName string, uploadTime int64, item ExternalAccountData) CreateRequest {
|
func externalAccountToCreateRequest(
|
||||||
|
uploaderName string,
|
||||||
|
uploadTime int64,
|
||||||
|
item ExternalAccountData,
|
||||||
|
salePriceConfig salePriceConfig,
|
||||||
|
) CreateRequest {
|
||||||
hafCoinM := item.Currency.HafuCoin
|
hafCoinM := item.Currency.HafuCoin
|
||||||
price := item.Currency.RecycleRent
|
pureCoinPrice := item.Currency.RecycleRent
|
||||||
ratio := item.Currency.RecycleRatio
|
ratio := item.Currency.RecycleRatio
|
||||||
insurance := insuranceFromSafeSlots(item.SafeSlots)
|
insurance := insuranceFromSafeSlots(item.SafeSlots)
|
||||||
staminaLevel := levelText(item.DailyConsumption.Stamina)
|
staminaLevel := levelText(item.DailyConsumption.Stamina)
|
||||||
@@ -245,16 +254,25 @@ func externalAccountToCreateRequest(uploaderName string, uploadTime int64, item
|
|||||||
skins := cleanStrings(item.Inventory.Skins)
|
skins := cleanStrings(item.Inventory.Skins)
|
||||||
remark := strings.TrimSpace(item.Remark)
|
remark := strings.TrimSpace(item.Remark)
|
||||||
onlineTimeText := normalizeExternalOnlineTimeText(item.OwnerOnlineTime)
|
onlineTimeText := normalizeExternalOnlineTimeText(item.OwnerOnlineTime)
|
||||||
|
resources := externalResources(item.Inventory)
|
||||||
|
consumablePrice := consumableValue(map[string]any{"resources": resources})
|
||||||
|
pricing := calculateExternalPlatformPricing(
|
||||||
|
hafCoinM,
|
||||||
|
ratio,
|
||||||
|
pureCoinPrice,
|
||||||
|
consumablePrice,
|
||||||
|
salePriceConfig,
|
||||||
|
)
|
||||||
assetSummary := map[string]any{
|
assetSummary := map[string]any{
|
||||||
"face_owner": "",
|
"face_owner": "",
|
||||||
"secret_kd": item.SecretKD,
|
"secret_kd": item.SecretKD,
|
||||||
"fire_level": item.Level,
|
"fire_level": item.Level,
|
||||||
"daily_loss_m": item.DailyLossM,
|
"daily_loss_m": item.DailyLossM,
|
||||||
"publish_ratio": ratio,
|
"publish_ratio": pricing.BuyerRatio,
|
||||||
"season_insurance": insurance,
|
"season_insurance": insurance,
|
||||||
"stamina_level": staminaLevel,
|
"stamina_level": staminaLevel,
|
||||||
"load_level": loadLevel,
|
"load_level": loadLevel,
|
||||||
"resources": externalResources(item.Inventory),
|
"resources": resources,
|
||||||
"skin_groups": externalSkinGroups(skins),
|
"skin_groups": externalSkinGroups(skins),
|
||||||
"online_time_text": onlineTimeText,
|
"online_time_text": onlineTimeText,
|
||||||
"ban_record": normalizeBanRecord(item.BanRecord),
|
"ban_record": normalizeBanRecord(item.BanRecord),
|
||||||
@@ -268,14 +286,14 @@ func externalAccountToCreateRequest(uploaderName string, uploadTime int64, item
|
|||||||
"price_breakdown": map[string]any{
|
"price_breakdown": map[string]any{
|
||||||
"seller_reference_ratio": ratio,
|
"seller_reference_ratio": ratio,
|
||||||
"seller_ratio": ratio,
|
"seller_ratio": ratio,
|
||||||
"seller_coin_base_price": price,
|
"seller_coin_base_price": roundMoney(pureCoinPrice),
|
||||||
"seller_total_price": price,
|
"seller_total_price": roundMoney(pureCoinPrice + consumablePrice),
|
||||||
"consumable_price": consumableValue(map[string]any{"resources": externalResources(item.Inventory)}),
|
"consumable_price": consumablePrice,
|
||||||
"buyer_coin_base_price": price,
|
"buyer_coin_base_price": pricing.BuyerCoinBasePrice,
|
||||||
"buyer_total_price": price,
|
"buyer_total_price": pricing.BuyerTotalPrice,
|
||||||
"buyer_ratio": ratio,
|
"buyer_ratio": pricing.BuyerRatio,
|
||||||
"platform_markup_amount": 0,
|
"platform_markup_amount": pricing.PlatformMarkupPrice,
|
||||||
"platform_rule_type": "external_upload",
|
"platform_rule_type": pricing.RuleType,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if start, end, ok := parseExternalOnlineTimeRange(onlineTimeText); ok {
|
if start, end, ok := parseExternalOnlineTimeRange(onlineTimeText); ok {
|
||||||
@@ -293,7 +311,7 @@ func externalAccountToCreateRequest(uploaderName string, uploadTime int64, item
|
|||||||
HafCoinAmount: int64(math.Round(hafCoinM * 1000000)),
|
HafCoinAmount: int64(math.Round(hafCoinM * 1000000)),
|
||||||
AssetSummary: assetSummary,
|
AssetSummary: assetSummary,
|
||||||
ScreenshotURLS: []string{defaultUploadScreenshot},
|
ScreenshotURLS: []string{defaultUploadScreenshot},
|
||||||
PriceCent: yuanToCent(price),
|
PriceCent: yuanToCent(pricing.BuyerTotalPrice),
|
||||||
DepositAmountCent: yuanToCent(item.Deposit),
|
DepositAmountCent: yuanToCent(item.Deposit),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ func TestExternalAccountToCreateRequestMapsUploadFields(t *testing.T) {
|
|||||||
Level6Armor: 17,
|
Level6Armor: 17,
|
||||||
Skins: []string{"信条", "电锯惊魂"},
|
Skins: []string{"信条", "电锯惊魂"},
|
||||||
},
|
},
|
||||||
})
|
}, defaultSalePriceConfig())
|
||||||
|
|
||||||
if req.Description != "有语音封禁\n封禁历史:2026/01/23封禁3天" {
|
if req.Description != "有语音封禁\n封禁历史:2026/01/23封禁3天" {
|
||||||
t.Fatalf("Description = %q", req.Description)
|
t.Fatalf("Description = %q", req.Description)
|
||||||
@@ -515,7 +515,7 @@ func TestExternalAccountToCreateRequestMapsUploadFields(t *testing.T) {
|
|||||||
if req.HafCoinAmount != 197100000 {
|
if req.HafCoinAmount != 197100000 {
|
||||||
t.Fatalf("expected haf coin amount 197100000, got %d", req.HafCoinAmount)
|
t.Fatalf("expected haf coin amount 197100000, got %d", req.HafCoinAmount)
|
||||||
}
|
}
|
||||||
if req.PriceCent != 45800 || req.DepositAmountCent != 40000 {
|
if req.PriceCent != 59590 || req.DepositAmountCent != 40000 {
|
||||||
t.Fatalf("unexpected price/deposit cent %d/%d", req.PriceCent, req.DepositAmountCent)
|
t.Fatalf("unexpected price/deposit cent %d/%d", req.PriceCent, req.DepositAmountCent)
|
||||||
}
|
}
|
||||||
if req.AssetSummary["season_insurance"] != "3*3" {
|
if req.AssetSummary["season_insurance"] != "3*3" {
|
||||||
@@ -547,6 +547,63 @@ func TestExternalAccountToCreateRequestMapsUploadFields(t *testing.T) {
|
|||||||
if len(req.ScreenshotURLS) != 1 || req.ScreenshotURLS[0] != defaultUploadScreenshot {
|
if len(req.ScreenshotURLS) != 1 || req.ScreenshotURLS[0] != defaultUploadScreenshot {
|
||||||
t.Fatalf("expected default screenshot, got %#v", req.ScreenshotURLS)
|
t.Fatalf("expected default screenshot, got %#v", req.ScreenshotURLS)
|
||||||
}
|
}
|
||||||
|
breakdown, ok := req.AssetSummary["price_breakdown"].(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("price_breakdown = %#v", req.AssetSummary["price_breakdown"])
|
||||||
|
}
|
||||||
|
if breakdown["seller_coin_base_price"] != 458.0 ||
|
||||||
|
breakdown["consumable_price"] != 90.5 ||
|
||||||
|
breakdown["seller_total_price"] != 548.5 ||
|
||||||
|
breakdown["buyer_coin_base_price"] != 505.4 ||
|
||||||
|
breakdown["buyer_total_price"] != 595.9 ||
|
||||||
|
breakdown["buyer_ratio"] != 39.0 ||
|
||||||
|
breakdown["platform_markup_amount"] != 47.4 ||
|
||||||
|
breakdown["platform_rule_type"] != "ratio_subtract" {
|
||||||
|
t.Fatalf("unexpected price breakdown: %#v", breakdown)
|
||||||
|
}
|
||||||
|
if req.AssetSummary["publish_ratio"] != 39.0 {
|
||||||
|
t.Fatalf("publish_ratio = %#v", req.AssetSummary["publish_ratio"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExternalAccountToCreateRequestSeparatesPureCoinAndExtraItems(t *testing.T) {
|
||||||
|
req := externalAccountToCreateRequest("客服1", 1772526103000, ExternalAccountData{
|
||||||
|
LoginMethod: "QQ账号密码",
|
||||||
|
Rank: "黑鹰",
|
||||||
|
Level: 60,
|
||||||
|
SafeSlots: 9,
|
||||||
|
Deposit: 400,
|
||||||
|
Currency: ExternalUploadCurrency{
|
||||||
|
HafuCoin: 282,
|
||||||
|
RecycleRatio: 42.8,
|
||||||
|
RecycleRent: 659,
|
||||||
|
},
|
||||||
|
DailyConsumption: ExternalDailyConsumption{Stamina: 7, Weight: 7},
|
||||||
|
Inventory: ExternalUploadInventory{
|
||||||
|
AWMBullets: 10,
|
||||||
|
Level6Armor: 2,
|
||||||
|
},
|
||||||
|
}, defaultSalePriceConfig())
|
||||||
|
|
||||||
|
breakdown, ok := req.AssetSummary["price_breakdown"].(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("price_breakdown = %#v", req.AssetSummary["price_breakdown"])
|
||||||
|
}
|
||||||
|
if breakdown["seller_coin_base_price"] != 659.0 ||
|
||||||
|
breakdown["consumable_price"] != 11.0 ||
|
||||||
|
breakdown["seller_total_price"] != 670.0 {
|
||||||
|
t.Fatalf("回收租金未按纯币价与额外物品拆分:%#v", breakdown)
|
||||||
|
}
|
||||||
|
if breakdown["buyer_coin_base_price"] != 717.6 ||
|
||||||
|
breakdown["buyer_total_price"] != 728.6 ||
|
||||||
|
breakdown["buyer_ratio"] != 39.3 ||
|
||||||
|
breakdown["platform_markup_amount"] != 58.6 ||
|
||||||
|
breakdown["platform_rule_type"] != "ratio_subtract" {
|
||||||
|
t.Fatalf("外部上传未按比例加价:%#v", breakdown)
|
||||||
|
}
|
||||||
|
if req.PriceCent != 72860 {
|
||||||
|
t.Fatalf("PriceCent = %d, want 72860", req.PriceCent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExternalSkinGroupsClassifiesKnownSkins(t *testing.T) {
|
func TestExternalSkinGroupsClassifiesKnownSkins(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user