From 52aaaf4de521e7bf55edc6d1dcc48caab70ec05f Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Tue, 31 Mar 2026 07:14:37 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20getDiscount=20=E6=96=B0=E4=BA=BA?= =?UTF-8?q?=E4=BB=B7=E5=8F=96=E5=80=BC=E9=94=99=E8=AF=AF=20=E2=80=94=20?= =?UTF-8?q?=E5=A7=8B=E7=BB=88=E4=BC=98=E5=85=88=E5=8F=96=20new=5Fuser=5Fon?= =?UTF-8?q?ly=3Dfalse=20=E7=9A=84=E5=AE=9E=E9=99=85=E6=8A=98=E6=89=A3?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同一 quantity 有两条记录时: - new_user_only=true (discount=99.64) 是新人限制标记,非实际折扣 - new_user_only=false (discount=35.36) 是实际折扣价格 原逻辑遍历到第一条即返回,导致新人拿到 99.64 而非 35.36。 修复后优先取 new_user_only=false 的条目,仅在无 false 条目时才降级到 new_user_only=true。 Co-Authored-By: claude-flow --- internal/logic/public/order/getDiscount.go | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/internal/logic/public/order/getDiscount.go b/internal/logic/public/order/getDiscount.go index db107f3..d5d59bf 100644 --- a/internal/logic/public/order/getDiscount.go +++ b/internal/logic/public/order/getDiscount.go @@ -2,17 +2,34 @@ package order import "github.com/perfect-panel/server/internal/types" +// getDiscount returns the discount factor for the given quantity. +// +// Design: when a quantity has both a new_user_only=true entry and a new_user_only=false entry, +// the new_user_only=true entry is a "gating marker" (its discount value is irrelevant). +// The actual discounted price is always carried by the new_user_only=false entry. +// Whether the buyer is eligible to use this quantity is enforced by isNewUserOnlyForQuantity +// before calling this function. Here we simply return the best applicable discount. +// +// Priority: new_user_only=false entry beats new_user_only=true entry for the same quantity. func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64, isNewUser bool) float64 { - for _, discount := range discounts { - if discount.NewUserOnly && !isNewUser { + var best float64 = 1 + foundFallback := false + for _, d := range discounts { + if d.Quantity != inputMonths || d.Discount <= 0 || d.Discount >= 100 { continue } - if inputMonths == discount.Quantity && discount.Discount > 0 && discount.Discount < 100 { - return discount.Discount / float64(100) + factor := d.Discount / float64(100) + if !d.NewUserOnly { + // Prefer the non-new-user-only tier as the actual price tier. + best = factor + foundFallback = true + } else if !foundFallback && isNewUser { + // Fall back to new-user-only tier only when no general tier exists + // and the buyer qualifies. + best = factor } } - - return 1 + return best } // isNewUserOnlyForQuantity checks whether the matched discount tier has new_user_only enabled.