package user import ( "context" "errors" "strconv" "go.uber.org/zap" ) // RedeemItemCard 积分兑换道具卡 func (s *service) RedeemItemCard(ctx context.Context, userID int64, cardID int64, quantity int) (ledgerID int64, err error) { if quantity <= 0 { quantity = 1 } // 1. 查卡 tpl, err := s.readDB.SystemItemCards.WithContext(ctx).Where(s.readDB.SystemItemCards.ID.Eq(cardID), s.readDB.SystemItemCards.Status.Eq(1)).First() if err != nil { return 0, errors.New("item card not found") } // 2. 算分 ptsPerUnit, _ := s.CentsToPoints(ctx, tpl.Price) needPoints := ptsPerUnit * int64(quantity) if needPoints <= 0 { needPoints = 1 } // 3. 扣分 (调用现有 Service) ledgerID, err = s.ConsumePointsFor(ctx, userID, needPoints, "system_item_cards", strconv.FormatInt(cardID, 10), "redeem item card", "redeem_item_card") if err != nil { return 0, err } // 4. 发卡 (如果失败,执行退分) if err := s.AddItemCard(ctx, userID, cardID, quantity); err != nil { s.logger.Error("failed to add item card after point consumption", zap.Int64("user_id", userID), zap.Int64("card_id", cardID), zap.Int64("ledger_id", ledgerID), zap.Error(err), ) // 自动退分 _, _ = s.RefundPoints(ctx, userID, needPoints, strconv.FormatInt(ledgerID, 10), "refund: grant item card failed") return ledgerID, errors.New("failed to grant item card: " + err.Error()) } return ledgerID, nil }