diff --git a/apis/types.api b/apis/types.api index fe1ded4..060fc9a 100644 --- a/apis/types.api +++ b/apis/types.api @@ -229,6 +229,7 @@ type ( Quantity int64 `json:"quantity"` Discount float64 `json:"discount"` MapApple string `json:"map_apple"` + Promo *SubscribePromo `json:"promo"` } SubscribePromo { RuleName string `json:"rule_name"` @@ -250,7 +251,6 @@ type ( UnitPrice int64 `json:"unit_price"` UnitTime string `json:"unit_time"` Discount []SubscribeDiscount `json:"discount"` - Promo *SubscribePromo `json:"promo"` NodeCount int64 `json:"node_count"` Replacement int64 `json:"replacement"` Inventory int64 `json:"inventory"` diff --git a/internal/logic/public/subscribe/promo.go b/internal/logic/public/subscribe/promo.go index 1456d3c..5db776c 100644 --- a/internal/logic/public/subscribe/promo.go +++ b/internal/logic/public/subscribe/promo.go @@ -25,6 +25,7 @@ const ( type subscribePromoCandidate struct { SubscribeId int64 `gorm:"column:subscribe_id"` + Quantity int64 `gorm:"column:quantity"` RuleName string `gorm:"column:rule_name"` RuleType string `gorm:"column:rule_type"` PromoPrice int64 `gorm:"column:promo_price"` @@ -38,8 +39,8 @@ type promoRuleParams struct { InactiveMonths int `json:"inactive_months"` } -func loadSubscribePromoMap(ctx context.Context, svcCtx *svc.ServiceContext, subscribeIDs []int64) (map[int64]*types.SubscribePromo, error) { - result := make(map[int64]*types.SubscribePromo) +func loadSubscribePromoMap(ctx context.Context, svcCtx *svc.ServiceContext, subscribeIDs []int64) (map[int64]map[int64]*types.SubscribePromo, error) { + result := make(map[int64]map[int64]*types.SubscribePromo) if len(subscribeIDs) == 0 || svcCtx == nil || svcCtx.DB == nil { return result, nil } @@ -56,7 +57,7 @@ func loadSubscribePromoMap(ctx context.Context, svcCtx *svc.ServiceContext, subs evaluator := promoEligibilityEvaluator{ctx: ctx, db: svcCtx.DB, userInfo: userInfo} now := time.Now() for _, candidate := range candidates { - if _, exists := result[candidate.SubscribeId]; exists { + if _, exists := result[candidate.SubscribeId][candidate.Quantity]; exists { continue } if !candidate.isActive(now) { @@ -69,7 +70,10 @@ func loadSubscribePromoMap(ctx context.Context, svcCtx *svc.ServiceContext, subs if !ok { continue } - result[candidate.SubscribeId] = &types.SubscribePromo{ + if _, exists := result[candidate.SubscribeId]; !exists { + result[candidate.SubscribeId] = make(map[int64]*types.SubscribePromo) + } + result[candidate.SubscribeId][candidate.Quantity] = &types.SubscribePromo{ RuleName: candidate.RuleName, RuleType: candidate.RuleType, PromoPrice: candidate.PromoPrice, @@ -84,7 +88,7 @@ func querySubscribePromoCandidates(ctx context.Context, svcCtx *svc.ServiceConte var candidates []subscribePromoCandidate query := svcCtx.DB.WithContext(ctx). Table("subscribe_promo AS sp"). - Select("sp.subscribe_id, sp.promo_price, pr.name AS rule_name, pr.type AS rule_type, pr.params, pr.start_time, pr.end_time"). + Select("sp.subscribe_id, sp.quantity, sp.promo_price, pr.name AS rule_name, pr.type AS rule_type, pr.params, pr.start_time, pr.end_time"). Joins("JOIN promo_rule AS pr ON pr.id = sp.promo_rule_id AND pr.deleted_at IS NULL"). Where("sp.subscribe_id IN ? AND sp.promo_price > 0 AND pr.enabled = ?", subscribeIDs, true) if !loggedIn { @@ -92,6 +96,7 @@ func querySubscribePromoCandidates(ctx context.Context, svcCtx *svc.ServiceConte } err := query. Order("sp.subscribe_id ASC"). + Order("sp.quantity ASC"). Order("pr.priority DESC"). Order("pr.id ASC"). Scan(&candidates).Error diff --git a/internal/logic/public/subscribe/querySubscribeListLogic.go b/internal/logic/public/subscribe/querySubscribeListLogic.go index 4b7dda0..eb76835 100644 --- a/internal/logic/public/subscribe/querySubscribeListLogic.go +++ b/internal/logic/public/subscribe/querySubscribeListLogic.go @@ -56,11 +56,19 @@ func (l *QuerySubscribeListLogic) QuerySubscribeList(req *types.QuerySubscribeLi var discount []types.SubscribeDiscount _ = json.Unmarshal([]byte(item.Discount), &discount) sub.Discount = discount - list[i] = sub } list[i] = sub } + promos, err := loadSubscribePromoMap(l.ctx, l.svcCtx, subscribeIDs) + if err != nil { + l.Errorw("[QuerySubscribeListLogic] Query Promo Error", logger.Field("error", err.Error())) + return nil, err + } + for i := range list { + applySubscribeDiscountPromos(&list[i], promos[list[i].Id]) + } + // 老版本客户端(无 X-App-Id)去掉每个套餐 discount 的最后一个 hasAppId, _ := l.ctx.Value(constant.CtxKeyHasAppId).(bool) if !hasAppId { @@ -71,16 +79,13 @@ func (l *QuerySubscribeListLogic) QuerySubscribeList(req *types.QuerySubscribeLi } } - promos, err := loadSubscribePromoMap(l.ctx, l.svcCtx, subscribeIDs) - if err != nil { - l.Errorw("[QuerySubscribeListLogic] Query Promo Error", logger.Field("error", err.Error())) - return nil, err - } - for i := range list { - list[i].Promo = promos[list[i].Id] - } - resp.List = list resp.Total = int64(len(list)) return } + +func applySubscribeDiscountPromos(subscribe *types.Subscribe, promoByQuantity map[int64]*types.SubscribePromo) { + for i := range subscribe.Discount { + subscribe.Discount[i].Promo = promoByQuantity[subscribe.Discount[i].Quantity] + } +} diff --git a/internal/types/types.go b/internal/types/types.go index efba502..4260cdd 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -2789,7 +2789,6 @@ type Subscribe struct { UnitPrice int64 `json:"unit_price"` UnitTime string `json:"unit_time"` Discount []SubscribeDiscount `json:"discount"` - Promo *SubscribePromo `json:"promo"` NodeCount int64 `json:"node_count"` Replacement int64 `json:"replacement"` Inventory int64 `json:"inventory"` @@ -2850,10 +2849,11 @@ type SubscribeConfig struct { } type SubscribeDiscount struct { - Quantity int64 `json:"quantity"` - Discount float64 `json:"discount"` - NewUserOnly bool `json:"new_user_only"` - MapApple string `json:"map_apple"` + Quantity int64 `json:"quantity"` + Discount float64 `json:"discount"` + NewUserOnly bool `json:"new_user_only"` + MapApple string `json:"map_apple"` + Promo *SubscribePromo `json:"promo"` } type SubscribeGroup struct {