package apple import ( "context" "time" iapmodel "github.com/perfect-panel/server/internal/model/iap/apple" "github.com/perfect-panel/server/internal/model/user" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" "github.com/perfect-panel/server/pkg/constant" iapapple "github.com/perfect-panel/server/pkg/iap/apple" "github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/xerr" "github.com/google/uuid" "github.com/pkg/errors" "gorm.io/gorm" ) type RestoreLogic struct { logger.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewRestoreLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RestoreLogic { return &RestoreLogic{ Logger: logger.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *RestoreLogic) Restore(req *types.RestoreAppleTransactionsRequest) error { u, ok := l.ctx.Value(constant.CtxKeyUser).(*user.User) if !ok || u == nil { return errors.Wrapf(xerr.NewErrCode(xerr.InvalidAccess), "invalid access") } pm, _ := iapapple.ParseProductMap(l.svcCtx.Config.Site.CustomData) return l.svcCtx.DB.Transaction(func(tx *gorm.DB) error { for _, j := range req.Transactions { txp, err := iapapple.ParseTransactionJWS(j) if err != nil { continue } m, ok := pm.Items[txp.ProductId] if !ok { continue } _, e := iapmodel.NewModel(l.svcCtx.DB, l.svcCtx.Redis).FindByOriginalId(l.ctx, txp.OriginalTransactionId) if e == nil { continue } iapTx := &iapmodel.Transaction{ UserId: u.Id, OriginalTransactionId: txp.OriginalTransactionId, TransactionId: txp.TransactionId, ProductId: txp.ProductId, PurchaseAt: txp.PurchaseDate, RevocationAt: txp.RevocationDate, JWSHash: "", } if err := tx.Model(&iapmodel.Transaction{}).Create(iapTx).Error; err != nil { return err } exp := iapapple.CalcExpire(txp.PurchaseDate, m.DurationDays) userSub := user.Subscribe{ UserId: u.Id, SubscribeId: m.SubscribeId, StartTime: time.Now(), ExpireTime: exp, Traffic: 0, Download: 0, Upload: 0, Token: txp.OriginalTransactionId, UUID: uuid.New().String(), Status: 1, } if err := l.svcCtx.UserModel.InsertSubscribe(l.ctx, &userSub, tx); err != nil { return err } } return nil }) }