diff --git a/internal/logic/public/iap/apple/attachTransactionLogic.go b/internal/logic/public/iap/apple/attachTransactionLogic.go index 5ab445f..bfecea6 100644 --- a/internal/logic/public/iap/apple/attachTransactionLogic.go +++ b/internal/logic/public/iap/apple/attachTransactionLogic.go @@ -427,9 +427,37 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseInsertError), "insert error: %v", err.Error()) } l.sendIAPAttachTraceToTelegram("SUCCESS_COMMIT", orderInfo, u.Id, subscribeId, tier, duration, txPayload.PurchaseDate, txPayload.TransactionId, txPayload.OriginalTransactionId, "") - l.Infow("绑定完成", logger.Field("userId", u.Id), logger.Field("tier", tier), logger.Field("expiresAt", exp.Unix())) + + // 事务提交后立即清除订阅缓存,避免 App 查到旧数据(激活队列异步执行,存在竞态) + if orderLinkedSub != nil { + _ = l.svcCtx.UserModel.ClearSubscribeCache(l.ctx, orderLinkedSub) + } else if singleModeAnchorSub != nil { + _ = l.svcCtx.UserModel.ClearSubscribeCache(l.ctx, singleModeAnchorSub) + } + + // merged 路径下,exp 仅从购买日算起,需要用已有订阅到期时间 + duration 作为预估值返回前端 + responseExpire := exp + var mergeSub *user.Subscribe + if orderLinkedSub != nil { + mergeSub = orderLinkedSub + } else if singleModeAnchorSub != nil { + mergeSub = singleModeAnchorSub + } + if mergeSub != nil { + base := mergeSub.ExpireTime + now := time.Now() + if base.Before(now) { + base = now + } + estimated := base.AddDate(0, 0, int(duration)) + if estimated.After(responseExpire) { + responseExpire = estimated + } + } + + l.Infow("绑定完成", logger.Field("userId", u.Id), logger.Field("tier", tier), logger.Field("expiresAt", responseExpire.Unix())) return &types.AttachAppleTransactionResponse{ - ExpiresAt: exp.Unix(), + ExpiresAt: responseExpire.Unix(), Tier: tier, }, nil }