feat(distribution): 完善分销站与主站业务数据及权益风控隔离,修复历史商品归属

This commit is contained in:
yml2213
2026-09-08 15:25:46 +08:00
parent 0fcb6a513f
commit fd4e490ed3
16 changed files with 221 additions and 35 deletions
@@ -47,8 +47,10 @@ func (r *Repository) finalizeCheckout(tx *gorm.DB, order *model.RentalOrder, che
if err := appendCheckoutCompletedNotifications(tx, order, renterContent); err != nil {
return nil, err
}
if err := rentergrowth.AwardOrderCompleted(tx, order, settlement.PureCoinAmountCent, rentergrowth.SourceOrderCompleted); err != nil {
return nil, err
if order.DistributionSiteID == nil || *order.DistributionSiteID == 0 {
if err := rentergrowth.AwardOrderCompleted(tx, order, settlement.PureCoinAmountCent, rentergrowth.SourceOrderCompleted); err != nil {
return nil, err
}
}
if err := saveFinalizedCheckout(tx, order, checkout, listing, account); err != nil {
return nil, err
+1
View File
@@ -228,6 +228,7 @@ type SellerHandoffQuery struct {
Page int
PageSize int
Status string
SiteCode string
}
// SellerHandoffMetrics 为号主待办页提供跨分页的状态统计。
@@ -34,7 +34,7 @@ func (h *Handler) List(c *gin.Context) {
return
}
page, pageSize := parsePagination(c)
siteCode := strings.TrimSpace(firstNonEmpty(c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
items, err := h.service.ListForUser(c.Request.Context(), userID, page, pageSize, siteCode)
if err != nil {
writeOrderError(c, err)
@@ -50,10 +50,12 @@ func (h *Handler) ListSellerHandoffs(c *gin.Context) {
return
}
page, pageSize := parsePagination(c)
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
items, err := h.service.ListSellerHandoffs(c.Request.Context(), userID, SellerHandoffQuery{
Page: page,
PageSize: pageSize,
Status: c.Query("status"),
SiteCode: siteCode,
})
if err != nil {
writeOrderError(c, err)
@@ -72,7 +74,7 @@ func (h *Handler) Detail(c *gin.Context) {
if !ok {
return
}
siteCode := strings.TrimSpace(firstNonEmpty(c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
item, err := h.service.FindForUser(c.Request.Context(), userID, id, siteCode)
if err != nil {
writeOrderError(c, err)
+14 -3
View File
@@ -63,9 +63,20 @@ func (r *Repository) Create(ctx context.Context, renterID uint64, req CreateRequ
return err
}
rentOriginalAmountCent := pricing.RentAmountCent
growthSnapshot, err := rentergrowth.SnapshotForUser(tx, renterID)
if err != nil {
return err
var growthSnapshot rentergrowth.DiscountSnapshot
if distributionSite == nil {
snap, err := rentergrowth.SnapshotForUser(tx, renterID)
if err != nil {
return err
}
growthSnapshot = snap
} else {
// 分销站点订单隔离主站成长等级免押与折扣,防止主站免押坏账与折扣侵蚀分销收益
growthSnapshot = rentergrowth.DiscountSnapshot{
LevelCode: rentergrowth.DefaultLevelCode,
LevelName: rentergrowth.DefaultLevelName,
DiscountBps: rentergrowth.DefaultDiscountBps,
}
}
rentDiscountAmountCent := rentergrowth.CalculateDiscountCent(pricing.PureCoinAmountCent, pricing.PureCoinPlatformFeeCent, growthSnapshot.DiscountBps)
if rentDiscountAmountCent > 0 {
+15 -5
View File
@@ -63,6 +63,11 @@ func (r *Repository) ListSellerHandoffs(ctx context.Context, userID uint64, quer
if query.Status != "" {
base = base.Where("o.status = ?", query.Status)
}
if query.SiteCode != "" {
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", query.SiteCode)
} else {
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
}
var total int64
if err := base.Session(&gorm.Session{}).Count(&total).Error; err != nil {
@@ -77,7 +82,7 @@ func (r *Repository) ListSellerHandoffs(ctx context.Context, userID uint64, quer
for _, row := range rows {
items = append(items, row.toUserListItem(userID, nil))
}
metrics, err := r.sellerHandoffMetrics(ctx, userID)
metrics, err := r.sellerHandoffMetrics(ctx, userID, query.SiteCode)
if err != nil {
return nil, err
}
@@ -90,16 +95,21 @@ func (r *Repository) ListSellerHandoffs(ctx context.Context, userID uint64, quer
}, nil
}
func (r *Repository) sellerHandoffMetrics(ctx context.Context, userID uint64) (SellerHandoffMetrics, error) {
func (r *Repository) sellerHandoffMetrics(ctx context.Context, userID uint64, siteCode ...string) (SellerHandoffMetrics, error) {
base := r.db.WithContext(ctx).Table("rental_orders AS o").Where("o.owner_id = ?", userID)
if len(siteCode) > 0 && siteCode[0] != "" {
base = base.Joins("INNER JOIN distribution_sites AS ds ON ds.id = o.distribution_site_id AND ds.site_code = ?", siteCode[0])
} else if len(siteCode) > 0 {
base = base.Where("o.distribution_site_id IS NULL OR o.distribution_site_id = 0")
}
var metrics SellerHandoffMetrics
if err := base.Where("o.status = ? AND o.handoff_status = ?", orderStatusPendingHandoff, handoffStatusPendingOwner).Count(&metrics.PendingHandoff).Error; err != nil {
if err := base.Session(&gorm.Session{}).Where("o.status = ? AND o.handoff_status = ?", orderStatusPendingHandoff, handoffStatusPendingOwner).Count(&metrics.PendingHandoff).Error; err != nil {
return SellerHandoffMetrics{}, err
}
if err := r.db.WithContext(ctx).Table("rental_orders AS o").Where("o.owner_id = ? AND o.status = ?", userID, orderStatusPendingCheckoutConfirm).Count(&metrics.PendingCheckout).Error; err != nil {
if err := base.Session(&gorm.Session{}).Where("o.status = ?", orderStatusPendingCheckoutConfirm).Count(&metrics.PendingCheckout).Error; err != nil {
return SellerHandoffMetrics{}, err
}
if err := r.db.WithContext(ctx).Table("rental_orders AS o").Where("o.owner_id = ? AND o.status IN ?", userID, sellerHandoffAbnormalStatuses()).Count(&metrics.Abnormal).Error; err != nil {
if err := base.Session(&gorm.Session{}).Where("o.status IN ?", sellerHandoffAbnormalStatuses()).Count(&metrics.Abnormal).Error; err != nil {
return SellerHandoffMetrics{}, err
}
return metrics, nil