Files
backend/internal/repository/texture_repository.go
lan 8858fd1ede feat: Enhance texture upload functionality and API response format
- Introduced a new upload endpoint for direct texture file uploads, allowing users to upload textures with validation for size and format.
- Updated existing texture-related API responses to a standardized format, improving consistency across the application.
- Refactored texture service methods to handle file uploads and reuse existing texture URLs based on hash checks.
- Cleaned up Dockerfile and other files by removing unnecessary whitespace.
2025-12-04 20:07:30 +08:00

213 lines
6.7 KiB
Go

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) FindByHashAndUploaderID(ctx context.Context, hash string, uploaderID int64) (*model.Texture, error) {
var texture model.Texture
err := r.db.WithContext(ctx).Where("hash = ? AND uploader_id = ?", hash, uploaderID).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
}