核心语义反转: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
90 lines
3.0 KiB
Go
90 lines
3.0 KiB
Go
package listing
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"hfb_sys/backend/internal/model"
|
|
)
|
|
|
|
// ReceiveCostDeltaBySiteCode 读取分站收号压价点数(新口径,收号比例 = R + 点数)。
|
|
func (r *Repository) ReceiveCostDeltaBySiteCode(ctx context.Context, siteCode string) float64 {
|
|
siteCode = strings.TrimSpace(siteCode)
|
|
if r == nil || r.db == nil || siteCode == "" {
|
|
return 0
|
|
}
|
|
var delta float64
|
|
_ = r.db.WithContext(ctx).Model(&model.DistributionSite{}).
|
|
Select("COALESCE(receive_cost_delta, 0)").
|
|
Where("site_code = ? AND status = 'active'", siteCode).
|
|
Limit(1).
|
|
Scan(&delta)
|
|
return NormalizeSiteReceiveCostDelta(delta)
|
|
}
|
|
|
|
// resolveSiteReceiveCostDelta 按站点编码或商品归属站点解析压价点数。
|
|
// 返回 onDistribution 表示当前上下文是否为分站(false 时压价不生效)。
|
|
func (r *Repository) resolveSiteReceiveCostDelta(ctx context.Context, listingID uint64, siteCode string) (float64, bool) {
|
|
if code := strings.TrimSpace(siteCode); code != "" {
|
|
return r.ReceiveCostDeltaBySiteCode(ctx, code), true
|
|
}
|
|
if r == nil || r.db == nil || listingID == 0 {
|
|
return 0, false
|
|
}
|
|
var siteID *uint64
|
|
if err := r.db.WithContext(ctx).Model(&model.RentalListing{}).
|
|
Select("distribution_site_id").
|
|
Where("id = ?", listingID).
|
|
Limit(1).
|
|
Scan(&siteID).Error; err != nil || siteID == nil || *siteID == 0 {
|
|
return 0, false
|
|
}
|
|
var delta float64
|
|
_ = r.db.WithContext(ctx).Model(&model.DistributionSite{}).
|
|
Select("COALESCE(receive_cost_delta, 0)").
|
|
Where("id = ? AND status = 'active'", *siteID).
|
|
Limit(1).
|
|
Scan(&delta)
|
|
return NormalizeSiteReceiveCostDelta(delta), true
|
|
}
|
|
|
|
// ReceiveRatioDeltaBySiteCode 旧口径(加价抢货)读取,保留只读兼容。
|
|
func (r *Repository) ReceiveRatioDeltaBySiteCode(ctx context.Context, siteCode string) float64 {
|
|
siteCode = strings.TrimSpace(siteCode)
|
|
if r == nil || r.db == nil || siteCode == "" {
|
|
return 0
|
|
}
|
|
var delta float64
|
|
_ = r.db.WithContext(ctx).Model(&model.DistributionSite{}).
|
|
Select("COALESCE(receive_ratio_delta, 0)").
|
|
Where("site_code = ? AND status = 'active'", siteCode).
|
|
Limit(1).
|
|
Scan(&delta)
|
|
return NormalizeSiteReceiveRatioDelta(delta)
|
|
}
|
|
|
|
// ResolveReceiveRatioDelta 旧口径解析入口,保留供旧快照读侧使用。
|
|
func (r *Repository) ResolveReceiveRatioDelta(ctx context.Context, listingID uint64, siteCode string) (float64, bool) {
|
|
if code := strings.TrimSpace(siteCode); code != "" {
|
|
return r.ReceiveRatioDeltaBySiteCode(ctx, code), true
|
|
}
|
|
if r == nil || r.db == nil || listingID == 0 {
|
|
return 0, false
|
|
}
|
|
var siteID *uint64
|
|
if err := r.db.WithContext(ctx).Model(&model.RentalListing{}).
|
|
Select("distribution_site_id").
|
|
Where("id = ?", listingID).
|
|
Limit(1).
|
|
Scan(&siteID).Error; err != nil || siteID == nil || *siteID == 0 {
|
|
return 0, false
|
|
}
|
|
var delta float64
|
|
_ = r.db.WithContext(ctx).Model(&model.DistributionSite{}).
|
|
Select("COALESCE(receive_ratio_delta, 0)").
|
|
Where("id = ? AND status = 'active'", *siteID).
|
|
Limit(1).
|
|
Scan(&delta)
|
|
return NormalizeSiteReceiveRatioDelta(delta), true
|
|
}
|