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:
@@ -17,6 +17,7 @@ type SiteDTO struct {
|
||||
DefaultSupportGroupID *uint64 `json:"default_support_group_id,omitempty"`
|
||||
ListingQrcodeURL string `json:"listing_qrcode_url"`
|
||||
ReceiveRatioDelta float64 `json:"receive_ratio_delta"`
|
||||
ReceiveCostDelta float64 `json:"receive_cost_delta"`
|
||||
TaxEnabled bool `json:"tax_enabled"`
|
||||
TaxRateBPS int64 `json:"tax_rate_bps"`
|
||||
SettlementHoldDays int `json:"settlement_hold_days"`
|
||||
@@ -32,6 +33,7 @@ type CreateSiteRequest struct {
|
||||
DefaultSupportGroupID *uint64 `json:"default_support_group_id"`
|
||||
ListingQrcodeURL *string `json:"listing_qrcode_url"`
|
||||
ReceiveRatioDelta *float64 `json:"receive_ratio_delta"`
|
||||
ReceiveCostDelta *float64 `json:"receive_cost_delta"`
|
||||
TaxEnabled *bool `json:"tax_enabled"`
|
||||
TaxRateBPS *int64 `json:"tax_rate_bps"`
|
||||
SettlementHoldDays *int `json:"settlement_hold_days"`
|
||||
@@ -45,6 +47,7 @@ type UpdateSiteRequest struct {
|
||||
DefaultSupportGroupID *uint64 `json:"default_support_group_id"`
|
||||
ListingQrcodeURL *string `json:"listing_qrcode_url"`
|
||||
ReceiveRatioDelta *float64 `json:"receive_ratio_delta"`
|
||||
ReceiveCostDelta *float64 `json:"receive_cost_delta"`
|
||||
TaxEnabled *bool `json:"tax_enabled"`
|
||||
TaxRateBPS *int64 `json:"tax_rate_bps"`
|
||||
SettlementHoldDays *int `json:"settlement_hold_days"`
|
||||
@@ -248,6 +251,7 @@ type PublicSiteInfoDTO struct {
|
||||
FooterInfoJSON string `json:"footer_info_json"`
|
||||
DefaultSupportGroupID *uint64 `json:"default_support_group_id,omitempty"`
|
||||
ReceiveRatioDelta float64 `json:"receive_ratio_delta"`
|
||||
ReceiveCostDelta float64 `json:"receive_cost_delta"`
|
||||
}
|
||||
|
||||
type UpdateAccountDisplayRequest struct {
|
||||
|
||||
@@ -73,6 +73,13 @@ func normalizeReceiveRatioDelta(delta float64) (float64, error) {
|
||||
return listingpkg.NormalizeSiteReceiveRatioDelta(delta), nil
|
||||
}
|
||||
|
||||
func normalizeReceiveCostDelta(delta float64) (float64, error) {
|
||||
if delta < 0 {
|
||||
return 0, ErrInvalidAmount
|
||||
}
|
||||
return listingpkg.NormalizeSiteReceiveCostDelta(delta), nil
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
db *gorm.DB
|
||||
redis *redis.Client
|
||||
@@ -333,6 +340,13 @@ func (r *Repository) CreateSite(ctx context.Context, req CreateSiteRequest) (*Si
|
||||
}
|
||||
row.ReceiveRatioDelta = delta
|
||||
}
|
||||
if req.ReceiveCostDelta != nil {
|
||||
delta, err := normalizeReceiveCostDelta(*req.ReceiveCostDelta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
row.ReceiveCostDelta = delta
|
||||
}
|
||||
if req.TaxEnabled != nil {
|
||||
row.TaxEnabled = *req.TaxEnabled
|
||||
}
|
||||
@@ -385,6 +399,13 @@ func (r *Repository) UpdateSite(ctx context.Context, adminID, id uint64, req Upd
|
||||
}
|
||||
row.ReceiveRatioDelta = delta
|
||||
}
|
||||
if req.ReceiveCostDelta != nil {
|
||||
delta, err := normalizeReceiveCostDelta(*req.ReceiveCostDelta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
row.ReceiveCostDelta = delta
|
||||
}
|
||||
if !globalAccess {
|
||||
if err := tx.Save(&row).Error; err != nil {
|
||||
return err
|
||||
@@ -573,6 +594,7 @@ func siteDTO(row model.DistributionSite) SiteDTO {
|
||||
DefaultSupportGroupID: row.DefaultSupportGroupID,
|
||||
ListingQrcodeURL: row.ListingQrcodeURL,
|
||||
ReceiveRatioDelta: row.ReceiveRatioDelta,
|
||||
ReceiveCostDelta: row.ReceiveCostDelta,
|
||||
TaxEnabled: row.TaxEnabled,
|
||||
TaxRateBPS: row.TaxRateBPS,
|
||||
SettlementHoldDays: row.SettlementHoldDays,
|
||||
@@ -2330,6 +2352,7 @@ func (r *Repository) GetPublicSiteInfo(ctx context.Context, code, domain string)
|
||||
AnnouncementsJSON: site.AnnouncementsJSON,
|
||||
FooterInfoJSON: site.FooterInfoJSON,
|
||||
ReceiveRatioDelta: site.ReceiveRatioDelta,
|
||||
ReceiveCostDelta: site.ReceiveCostDelta,
|
||||
}
|
||||
if r.redis != nil {
|
||||
if bytes, err := json.Marshal(res); err == nil {
|
||||
|
||||
Reference in New Issue
Block a user