package user import ( "context" "errors" "time" "bindbox-game/internal/repository/mysql/model" "gorm.io/gorm" ) // AddItemCard 给用户添加道具卡 // 功能描述: // - 根据道具卡模板ID查询模板信息 // - 验证道具卡状态是否有效(status=1) // - 创建用户道具卡记录,继承模板的有效期设置 // - 支持批量添加,quantity参数控制数量 // // 参数说明: // - ctx: 上下文 // - userID: 用户ID // - cardID: 道具卡模板ID // - quantity: 添加数量,如果<=0则默认为1 // // 返回说明: // - error: 错误信息,包括数据库查询失败、模板不存在等情况 func (s *service) AddItemCard(ctx context.Context, userID int64, cardID int64, quantity int) error { if quantity <= 0 { quantity = 1 } if quantity > 100 { quantity = 100 } tpl, err := s.readDB.SystemItemCards.WithContext(ctx).Where(s.readDB.SystemItemCards.ID.Eq(cardID)).First() if err != nil { return err } if tpl == nil || tpl.Status != 1 { return errors.New("item card not found or disabled") } // 用户持有上限:不做限制 now := time.Now() for i := 0; i < quantity; i++ { item := &model.UserItemCards{UserID: userID, CardID: cardID, Status: 1} if !tpl.ValidStart.IsZero() { item.ValidStart = tpl.ValidStart } else { item.ValidStart = now } if !tpl.ValidEnd.IsZero() { item.ValidEnd = tpl.ValidEnd } do := s.writeDB.UserItemCards.WithContext(ctx) // 避免写入未使用相关字段的零值,触发 MySQL 时间字段校验错误 do = do.Omit( s.writeDB.UserItemCards.UsedAt, s.writeDB.UserItemCards.UsedDrawLogID, s.writeDB.UserItemCards.UsedActivityID, s.writeDB.UserItemCards.UsedIssueID, ) if tpl.ValidEnd.IsZero() { do = do.Omit(s.writeDB.UserItemCards.ValidEnd) } if err := do.Create(item); err != nil { return err } } return nil } func (s *service) VoidUserItemCard(ctx context.Context, adminID int64, userID int64, userItemCardID int64) error { if userID <= 0 || userItemCardID <= 0 { return gorm.ErrInvalidData } uc, err := s.readDB.UserItemCards.WithContext(ctx). Where(s.readDB.UserItemCards.ID.Eq(userItemCardID)). Where(s.readDB.UserItemCards.UserID.Eq(userID)). First() if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return gorm.ErrRecordNotFound } return err } if uc.Status != 1 { return gorm.ErrInvalidData } db := s.repo.GetDbW() if err := db.Exec("UPDATE user_item_cards SET status=3, updated_at=NOW(3), remark=CONCAT(IFNULL(remark,''),'|void_by_admin') WHERE id=? AND user_id=? AND status=1", userItemCardID, userID).Error; err != nil { return err } _ = adminID return nil }