bindbox-game/internal/service/user/item_card_redeem.go
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

51 lines
1.4 KiB
Go

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
}