fix(order): prevent duplicate subscriptions and repair invite gifts
Build docker and publish / build (20.15.1) (push) Successful in 5m6s

This commit is contained in:
2026-04-24 21:16:21 -07:00
parent ae62ecc6b3
commit 9db4762904
17 changed files with 3013 additions and 52 deletions
+9 -5
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"math"
"strings"
"time"
"github.com/google/uuid"
@@ -111,18 +112,21 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
}
}
// 单订阅模式下,若用户已有同套餐订阅(含过期),提前路由为续费,防止创建重复订阅
// 全局单订阅口径:若用户已有任意付费订阅(含过期),提前路由为续费/换套餐
// 防止不同套餐购买创建第二条订阅。
if !l.svcCtx.Config.Subscribe.SingleModel && orderType == 1 {
var existSub user.Subscribe
if e := l.svcCtx.DB.WithContext(l.ctx).
Model(&user.Subscribe{}).
Where("user_id = ? AND subscribe_id = ?", entitlement.EffectiveUserID, targetSubscribeID).
Where("user_id = ? AND token != '' AND (order_id > 0 OR token LIKE 'iap:%')", entitlement.EffectiveUserID).
Order("expire_time DESC").
Order("updated_at DESC").
Order("id DESC").
First(&existSub).Error; e == nil && existSub.Id > 0 && existSub.Token != "" {
orderType = 2
parentOrderID = existSub.OrderId
subscribeToken = existSub.Token
l.Infow("[Purchase] non-single mode purchase routed to renewal (existing subscription found)",
l.Infow("[Purchase] purchase routed to renewal/change plan (existing subscription found)",
logger.Field("existing_subscribe_id", existSub.Id),
logger.Field("existing_status", existSub.Status),
logger.Field("user_id", u.Id),
@@ -311,13 +315,13 @@ func (l *PurchaseLogic) Purchase(req *types.PurchaseOrderRequest) (resp *types.P
// check subscribe plan quota limit inside transaction to prevent race condition
if orderInfo.Type == 1 && sub.Quota > 0 {
var currentUserSub []user.Subscribe
if e := db.Model(&user.Subscribe{}).Where("user_id = ?", u.Id).Find(&currentUserSub).Error; e != nil {
if e := db.Model(&user.Subscribe{}).Where("user_id = ?", entitlement.EffectiveUserID).Find(&currentUserSub).Error; e != nil {
l.Errorw("[Purchase] Database query error", logger.Field("error", e.Error()), logger.Field("user_id", u.Id))
return e
}
var count int64
for _, v := range currentUserSub {
if v.SubscribeId == targetSubscribeID {
if v.OrderId > 0 || strings.HasPrefix(v.Token, "iap:") {
count++
}
}