fix: 单订阅模式下避免重复创建订阅
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m31s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m31s
1. FindSingleModeAnchorSubscribe 补充 status=4(流量耗完)到查询范围, 避免流量耗尽的订阅被忽略导致续费时新建订阅 2. activateOrderLogic NewPurchase 路径去掉套餐ID匹配检查, 单订阅模式下无论购买何种套餐都更新现有订阅而非新建 3. singleModeHelper fallback 查询同步补充 status=4 Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
fd48afd0ab
commit
abc9864d46
@ -22,7 +22,7 @@ func findSingleModeMergeTarget(ctx context.Context, svcCtx *svc.ServiceContext,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userSubs, queryErr := svcCtx.UserModel.QueryUserSubscribe(ctx, userId, 0, 1, 2, 3, 5)
|
userSubs, queryErr := svcCtx.UserModel.QueryUserSubscribe(ctx, userId, 0, 1, 2, 3, 4, 5)
|
||||||
if queryErr != nil {
|
if queryErr != nil {
|
||||||
return nil, queryErr
|
return nil, queryErr
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ func (m *defaultUserModel) FindSingleModeAnchorSubscribe(ctx context.Context, us
|
|||||||
var data Subscribe
|
var data Subscribe
|
||||||
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, _ interface{}) error {
|
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, _ interface{}) error {
|
||||||
return conn.Model(&Subscribe{}).
|
return conn.Model(&Subscribe{}).
|
||||||
Where("user_id = ? AND token != '' AND (order_id > 0 OR token LIKE 'iap:%') AND `status` IN ?", userId, []int64{0, 1, 2, 3, 5}).
|
Where("user_id = ? AND token != '' AND (order_id > 0 OR token LIKE 'iap:%') AND `status` IN ?", userId, []int64{0, 1, 2, 3, 4, 5}).
|
||||||
Order("expire_time DESC").
|
Order("expire_time DESC").
|
||||||
Order("updated_at DESC").
|
Order("updated_at DESC").
|
||||||
Order("id DESC").
|
Order("id DESC").
|
||||||
|
|||||||
@ -234,38 +234,31 @@ func (l *ActivateOrderLogic) NewPurchase(ctx context.Context, orderInfo *order.O
|
|||||||
anchorSub, anchorErr := l.svc.UserModel.FindSingleModeAnchorSubscribe(ctx, orderInfo.UserId)
|
anchorSub, anchorErr := l.svc.UserModel.FindSingleModeAnchorSubscribe(ctx, orderInfo.UserId)
|
||||||
switch {
|
switch {
|
||||||
case anchorErr == nil && anchorSub != nil:
|
case anchorErr == nil && anchorSub != nil:
|
||||||
if anchorSub.SubscribeId == orderInfo.SubscribeId {
|
if orderInfo.ParentId == 0 && anchorSub.OrderId > 0 && anchorSub.OrderId != orderInfo.Id {
|
||||||
if orderInfo.ParentId == 0 && anchorSub.OrderId > 0 && anchorSub.OrderId != orderInfo.Id {
|
if patchErr := l.patchOrderParentID(ctx, orderInfo.Id, anchorSub.OrderId); patchErr != nil {
|
||||||
if patchErr := l.patchOrderParentID(ctx, orderInfo.Id, anchorSub.OrderId); patchErr != nil {
|
logger.WithContext(ctx).Error("Patch order parent_id failed",
|
||||||
logger.WithContext(ctx).Error("Patch order parent_id failed",
|
logger.Field("error", patchErr.Error()),
|
||||||
logger.Field("error", patchErr.Error()),
|
|
||||||
logger.Field("order_no", orderInfo.OrderNo),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
orderInfo.ParentId = anchorSub.OrderId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if renewErr := l.updateSubscriptionForRenewal(ctx, anchorSub, sub, orderInfo); renewErr != nil {
|
|
||||||
logger.WithContext(ctx).Error("Single mode renewal fallback failed",
|
|
||||||
logger.Field("error", renewErr.Error()),
|
|
||||||
logger.Field("anchor_user_subscribe_id", anchorSub.Id),
|
|
||||||
logger.Field("order_no", orderInfo.OrderNo),
|
logger.Field("order_no", orderInfo.OrderNo),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
userSub = anchorSub
|
orderInfo.ParentId = anchorSub.OrderId
|
||||||
logger.WithContext(ctx).Infow("Single mode purchase routed to renewal in activation",
|
|
||||||
logger.Field("mode", "single"),
|
|
||||||
logger.Field("route", "purchase_to_renewal"),
|
|
||||||
logger.Field("anchor_user_subscribe_id", anchorSub.Id),
|
|
||||||
logger.Field("order_no", orderInfo.OrderNo),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
logger.WithContext(ctx).Errorw("Single mode anchor subscribe mismatch in activation",
|
|
||||||
|
if renewErr := l.updateSubscriptionForRenewal(ctx, anchorSub, sub, orderInfo); renewErr != nil {
|
||||||
|
logger.WithContext(ctx).Error("Single mode renewal fallback failed",
|
||||||
|
logger.Field("error", renewErr.Error()),
|
||||||
|
logger.Field("anchor_user_subscribe_id", anchorSub.Id),
|
||||||
|
logger.Field("order_no", orderInfo.OrderNo),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
userSub = anchorSub
|
||||||
|
logger.WithContext(ctx).Infow("Single mode purchase routed to renewal in activation",
|
||||||
|
logger.Field("mode", "single"),
|
||||||
|
logger.Field("route", "purchase_to_renewal"),
|
||||||
|
logger.Field("plan_changed", anchorSub.SubscribeId != orderInfo.SubscribeId),
|
||||||
|
logger.Field("anchor_user_subscribe_id", anchorSub.Id),
|
||||||
logger.Field("order_no", orderInfo.OrderNo),
|
logger.Field("order_no", orderInfo.OrderNo),
|
||||||
logger.Field("order_subscribe_id", orderInfo.SubscribeId),
|
|
||||||
logger.Field("anchor_subscribe_id", anchorSub.SubscribeId),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case errors.Is(anchorErr, gorm.ErrRecordNotFound):
|
case errors.Is(anchorErr, gorm.ErrRecordNotFound):
|
||||||
@ -926,10 +919,18 @@ func (l *ActivateOrderLogic) updateSubscriptionForRenewal(ctx context.Context, u
|
|||||||
today := time.Now().Day()
|
today := time.Now().Day()
|
||||||
resetDay := userSub.ExpireTime.Day()
|
resetDay := userSub.ExpireTime.Day()
|
||||||
|
|
||||||
// Reset traffic if enabled
|
// 套餐变更:更新套餐ID和流量配额,并重置已用流量
|
||||||
if (sub.RenewalReset != nil && *sub.RenewalReset) || today == resetDay {
|
if userSub.SubscribeId != orderInfo.SubscribeId {
|
||||||
|
userSub.SubscribeId = orderInfo.SubscribeId
|
||||||
|
userSub.Traffic = sub.Traffic
|
||||||
userSub.Download = 0
|
userSub.Download = 0
|
||||||
userSub.Upload = 0
|
userSub.Upload = 0
|
||||||
|
} else {
|
||||||
|
// Reset traffic if enabled
|
||||||
|
if (sub.RenewalReset != nil && *sub.RenewalReset) || today == resetDay {
|
||||||
|
userSub.Download = 0
|
||||||
|
userSub.Upload = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if userSub.FinishedAt != nil {
|
if userSub.FinishedAt != nil {
|
||||||
@ -942,6 +943,7 @@ func (l *ActivateOrderLogic) updateSubscriptionForRenewal(ctx context.Context, u
|
|||||||
userSub.FinishedAt = nil
|
userSub.FinishedAt = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userSub.OrderId = orderInfo.Id
|
||||||
userSub.ExpireTime = tool.AddTime(sub.UnitTime, orderInfo.Quantity, userSub.ExpireTime)
|
userSub.ExpireTime = tool.AddTime(sub.UnitTime, orderInfo.Quantity, userSub.ExpireTime)
|
||||||
userSub.Status = 1
|
userSub.Status = 1
|
||||||
// 续费时重置过期流量字段
|
// 续费时重置过期流量字段
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user