bindbox-game/internal/service/user/item_card_redeem.go

50 lines
1.4 KiB
Go
Executable File

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. 算分 - tpl.Price 是道具卡价格(分),直接用于扣除
needCents := tpl.Price * int64(quantity)
if needCents <= 0 {
needCents = 1
}
// 3. 扣分 (调用现有 Service)
ledgerID, err = s.ConsumePointsFor(ctx, userID, needCents, "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, needCents, strconv.FormatInt(ledgerID, 10), "refund: grant item card failed")
return ledgerID, errors.New("failed to grant item card: " + err.Error())
}
return ledgerID, nil
}