Compare commits

..

No commits in common. "06e469888845e8a326b69d995fc91ea3e3dc745b" and "98972401c27fe879612c5d2825acd608d27b3ac5" have entirely different histories.

6 changed files with 16 additions and 42 deletions

View File

@ -21,7 +21,7 @@ env:
SSH_PASSWORD: ${{ github.ref_name == 'main' && vars.SSH_PASSWORD || vars.DEV_SSH_PASSWORD }}
# TG通知
TG_BOT_TOKEN: 8114337882:AAHkEx03HSu7RxN4IHBJJEnsK9aPPzNLIk0
TG_CHAT_ID: "-49402438031"
TG_CHAT_ID: "-4940243803"
# Go构建变量
SERVICE: vpn
SERVICE_STYLE: vpn

View File

@ -76,7 +76,7 @@ func CountScopedSubscribePurchaseOrders(
var count int64
query := db.WithContext(ctx).
Model(&modelOrder.Order{}).
Where("user_id IN ? AND subscribe_id = ? AND type IN ? AND amount > 0", scopeUserIDs, subscribeID, []int64{1, 2})
Where("user_id IN ? AND subscribe_id = ? AND type = 1", scopeUserIDs, subscribeID)
if len(statuses) > 0 {
query = query.Where("status IN ?", statuses)
}

View File

@ -2,33 +2,18 @@ package order
import "github.com/perfect-panel/server/internal/types"
// getDiscount returns the discount factor for the given quantity.
//
// - New user: pick the tier with the lowest discount value (biggest saving).
// - Non-new user: pick the tier with the highest discount value (least saving / closest to full price).
func getDiscount(discounts []types.SubscribeDiscount, inputMonths int64, isNewUser bool) float64 {
best := float64(-1)
for _, d := range discounts {
if d.Quantity != inputMonths || d.Discount <= 0 || d.Discount >= 100 {
for _, discount := range discounts {
if discount.NewUserOnly && !isNewUser {
continue
}
if isNewUser {
// lowest discount value = biggest saving
if best < 0 || d.Discount < best {
best = d.Discount
}
} else {
// highest discount value = least saving (closest to original price)
if best < 0 || d.Discount > best {
best = d.Discount
if inputMonths == discount.Quantity && discount.Discount > 0 && discount.Discount < 100 {
return discount.Discount / float64(100)
}
}
}
if best < 0 {
return 1
}
return best / float64(100)
}
// isNewUserOnlyForQuantity checks whether the matched discount tier has new_user_only enabled.
// Returns true only when all matching tiers for the given quantity require new-user status

View File

@ -82,7 +82,7 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
decision, routeErr := commonLogic.ResolvePurchaseRoute(
l.ctx,
l.svcCtx.Config.Subscribe.SingleModel,
entitlement.EffectiveUserID,
u.Id,
req.SubscribeId,
l.svcCtx.UserModel.FindSingleModeAnchorSubscribe,
)

View File

@ -81,17 +81,11 @@ func (l *RenewalLogic) Renewal(req *types.RenewalOrderRequest) (resp *types.Rene
if !*sub.Sell {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "subscribe not sell")
}
newUserDiscount, err := resolveNewUserDiscountEligibility(l.ctx, l.svcCtx.DB, u.Id, sub.Id, req.Quantity, sub.Discount)
if err != nil {
l.Errorw("[Renewal] Database query error resolving new user eligibility",
logger.Field("error", err.Error()),
logger.Field("user_id", u.Id),
)
return nil, err
}
var discount float64 = 1
if len(newUserDiscount.Discounts) > 0 {
discount = getDiscount(newUserDiscount.Discounts, req.Quantity, newUserDiscount.EligibleForDiscount)
if sub.Discount != "" {
var dis []types.SubscribeDiscount
_ = json.Unmarshal([]byte(sub.Discount), &dis)
discount = getDiscount(dis, req.Quantity, false)
}
price := sub.UnitPrice * req.Quantity
amount := int64(math.Round(float64(price) * discount))

View File

@ -229,14 +229,9 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
var userSub *user.Subscribe
// 单订阅模式下,优先兜底为续费语义”:延长已购订阅,避免并发下重复创建 user_subscribe
// 单订阅模式下,优先兜底为续费语义”:延长已购订阅,避免并发下重复创建 user_subscribe
if l.svc.Config.Subscribe.SingleModel {
// 家庭组场景:订阅实际属于 SubscriptionUserId成员/主),而非付款人 UserId
singleModeUserId := orderInfo.UserId
if orderInfo.SubscriptionUserId > 0 {
singleModeUserId = orderInfo.SubscriptionUserId
}
anchorSub, anchorErr := l.svc.UserModel.FindSingleModeAnchorSubscribe(ctx, singleModeUserId)
anchorSub, anchorErr := l.svc.UserModel.FindSingleModeAnchorSubscribe(ctx, orderInfo.UserId)
switch {
case anchorErr == nil && anchorSub != nil:
if orderInfo.ParentId == 0 && anchorSub.OrderId > 0 && anchorSub.OrderId != orderInfo.Id {
@ -276,7 +271,7 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
// 如果没有合并已购订阅再尝试合并赠送订阅order_id=0
if userSub == nil {
giftSub, giftErr := l.findGiftSubscription(ctx, singleModeUserId, orderInfo.SubscribeId)
giftSub, giftErr := l.findGiftSubscription(ctx, orderInfo.UserId, orderInfo.SubscribeId)
if giftErr == nil && giftSub != nil {
// 在赠送订阅上延长时间,保持 token 不变
userSub, err = l.extendGiftSubscription(ctx, giftSub, orderInfo, sub)