package repository import ( "carrotskin/internal/model" "context" "gorm.io/gorm" ) // textureRepository TextureRepository的实现 type textureRepository struct { db *gorm.DB } // NewTextureRepository 创建TextureRepository实例 func NewTextureRepository(db *gorm.DB) TextureRepository { return &textureRepository{db: db} } func (r *textureRepository) Create(ctx context.Context, texture *model.Texture) error { return r.db.WithContext(ctx).Create(texture).Error } func (r *textureRepository) FindByID(ctx context.Context, id int64) (*model.Texture, error) { var texture model.Texture err := r.db.WithContext(ctx).Preload("Uploader").First(&texture, id).Error return handleNotFoundResult(&texture, err) } func (r *textureRepository) FindByHash(ctx context.Context, hash string) (*model.Texture, error) { var texture model.Texture err := r.db.WithContext(ctx).Where("hash = ?", hash).First(&texture).Error return handleNotFoundResult(&texture, err) } func (r *textureRepository) FindByIDs(ctx context.Context, ids []int64) ([]*model.Texture, error) { if len(ids) == 0 { return []*model.Texture{}, nil } var textures []*model.Texture // 使用 IN 查询优化批量查询,并预加载关联 err := r.db.WithContext(ctx).Where("id IN ?", ids). Preload("Uploader"). Find(&textures).Error return textures, err } func (r *textureRepository) FindByUploaderID(ctx context.Context, uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error) { var textures []*model.Texture var total int64 query := r.db.WithContext(ctx).Model(&model.Texture{}).Where("uploader_id = ? AND status != -1", uploaderID) if err := query.Count(&total).Error; err != nil { return nil, 0, err } err := query.Scopes(Paginate(page, pageSize)). Preload("Uploader"). Order("created_at DESC"). Find(&textures).Error if err != nil { return nil, 0, err } return textures, total, nil } func (r *textureRepository) Search(ctx context.Context, keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error) { var textures []*model.Texture var total int64 query := r.db.WithContext(ctx).Model(&model.Texture{}).Where("status = 1") if publicOnly { query = query.Where("is_public = ?", true) } if textureType != "" { query = query.Where("type = ?", textureType) } if keyword != "" { query = query.Where("name LIKE ? OR description LIKE ?", "%"+keyword+"%", "%"+keyword+"%") } if err := query.Count(&total).Error; err != nil { return nil, 0, err } err := query.Scopes(Paginate(page, pageSize)). Preload("Uploader"). Order("created_at DESC"). Find(&textures).Error if err != nil { return nil, 0, err } return textures, total, nil } func (r *textureRepository) Update(ctx context.Context, texture *model.Texture) error { return r.db.WithContext(ctx).Save(texture).Error } func (r *textureRepository) UpdateFields(ctx context.Context, id int64, fields map[string]interface{}) error { return r.db.WithContext(ctx).Model(&model.Texture{}).Where("id = ?", id).Updates(fields).Error } func (r *textureRepository) Delete(ctx context.Context, id int64) error { return r.db.WithContext(ctx).Model(&model.Texture{}).Where("id = ?", id).Update("status", -1).Error } func (r *textureRepository) BatchUpdate(ctx context.Context, ids []int64, fields map[string]interface{}) (int64, error) { if len(ids) == 0 { return 0, nil } result := r.db.WithContext(ctx).Model(&model.Texture{}).Where("id IN ?", ids).Updates(fields) return result.RowsAffected, result.Error } func (r *textureRepository) BatchDelete(ctx context.Context, ids []int64) (int64, error) { if len(ids) == 0 { return 0, nil } result := r.db.WithContext(ctx).Model(&model.Texture{}).Where("id IN ?", ids).Update("status", -1) return result.RowsAffected, result.Error } func (r *textureRepository) IncrementDownloadCount(ctx context.Context, id int64) error { return r.db.WithContext(ctx).Model(&model.Texture{}).Where("id = ?", id). UpdateColumn("download_count", gorm.Expr("download_count + ?", 1)).Error } func (r *textureRepository) IncrementFavoriteCount(ctx context.Context, id int64) error { return r.db.WithContext(ctx).Model(&model.Texture{}).Where("id = ?", id). UpdateColumn("favorite_count", gorm.Expr("favorite_count + ?", 1)).Error } func (r *textureRepository) DecrementFavoriteCount(ctx context.Context, id int64) error { return r.db.WithContext(ctx).Model(&model.Texture{}).Where("id = ?", id). UpdateColumn("favorite_count", gorm.Expr("favorite_count - ?", 1)).Error } func (r *textureRepository) CreateDownloadLog(ctx context.Context, log *model.TextureDownloadLog) error { return r.db.WithContext(ctx).Create(log).Error } func (r *textureRepository) IsFavorited(ctx context.Context, userID, textureID int64) (bool, error) { var count int64 // 使用 Select("1") 优化,只查询是否存在,不需要查询所有字段 err := r.db.WithContext(ctx).Model(&model.UserTextureFavorite{}). Select("1"). Where("user_id = ? AND texture_id = ?", userID, textureID). Limit(1). Count(&count).Error return count > 0, err } func (r *textureRepository) AddFavorite(ctx context.Context, userID, textureID int64) error { favorite := &model.UserTextureFavorite{ UserID: userID, TextureID: textureID, } return r.db.WithContext(ctx).Create(favorite).Error } func (r *textureRepository) RemoveFavorite(ctx context.Context, userID, textureID int64) error { return r.db.WithContext(ctx).Where("user_id = ? AND texture_id = ?", userID, textureID). Delete(&model.UserTextureFavorite{}).Error } func (r *textureRepository) GetUserFavorites(ctx context.Context, userID int64, page, pageSize int) ([]*model.Texture, int64, error) { var textures []*model.Texture var total int64 subQuery := r.db.WithContext(ctx).Model(&model.UserTextureFavorite{}). Select("texture_id"). Where("user_id = ?", userID) query := r.db.WithContext(ctx).Model(&model.Texture{}). Where("id IN (?) AND status = 1", subQuery) if err := query.Count(&total).Error; err != nil { return nil, 0, err } err := query.Scopes(Paginate(page, pageSize)). Preload("Uploader"). Order("created_at DESC"). Find(&textures).Error if err != nil { return nil, 0, err } return textures, total, nil } func (r *textureRepository) CountByUploaderID(ctx context.Context, uploaderID int64) (int64, error) { var count int64 err := r.db.WithContext(ctx).Model(&model.Texture{}). Where("uploader_id = ? AND status != -1", uploaderID). Count(&count).Error return count, err }