package logic import ( "context" "errors" "time" "juwan-backend/app/wallet/rpc/internal/models/wallet" "juwan-backend/app/wallet/rpc/internal/svc" "juwan-backend/app/wallet/rpc/pb" "github.com/shopspring/decimal" "github.com/zeromicro/go-zero/core/logx" ) type UpdateWalletsLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewUpdateWalletsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateWalletsLogic { return &UpdateWalletsLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *UpdateWalletsLogic) UpdateWallets(in *pb.UpdateWalletsReq) (*pb.UpdateWalletsResp, error) { if in.Version == nil { return nil, errors.New("version is required") } tx, err := l.svcCtx.WalletModelsRW.Tx(l.ctx) if err != nil { return nil, err } updater := tx.Wallet.Update(). Where(wallet.UserIDEQ(in.UserId), wallet.VersionEQ(int(in.GetVersion()))). AddVersion(1) if in.Balance != nil { parsedBalance, perr := decimal.NewFromString(in.GetBalance()) if perr != nil { _ = tx.Rollback() return nil, errors.New("invalid balance") } updater = updater.SetBalance(parsedBalance) } if in.FrozenBalance != nil { parsedFrozenBalance, perr := decimal.NewFromString(in.GetFrozenBalance()) if perr != nil { _ = tx.Rollback() return nil, errors.New("invalid frozenBalance") } updater = updater.SetFrozenBalance(parsedFrozenBalance) } if in.UpdatedAt != nil && in.GetUpdatedAt() > 0 { updater = updater.SetUpdatedAt(time.Unix(in.GetUpdatedAt(), 0)) } else { updater = updater.SetUpdatedAt(time.Now()) } affected, err := updater.Save(l.ctx) if err != nil { _ = tx.Rollback() return nil, err } if affected == 0 { exist, qerr := tx.Wallet.Query().Where(wallet.UserIDEQ(in.UserId)).Exist(l.ctx) _ = tx.Rollback() if qerr != nil { return nil, qerr } if !exist { return nil, errors.New("wallet not found") } return nil, errors.New("wallet update conflict") } if err = tx.Commit(); err != nil { return nil, err } return &pb.UpdateWalletsResp{}, nil }