refactor: 移除全局单例、修复分层违规、统一错误与响应
Some checks failed
Build / build (push) Successful in 7m52s
Build / build-docker (push) Has been cancelled

This commit is contained in:
lafay
2026-06-15 16:40:36 +08:00
parent d9de39a0a3
commit 7d1c78f965
55 changed files with 593 additions and 1744 deletions

View File

@@ -2,6 +2,7 @@ package service
import (
"bytes"
apperrors "carrotskin/internal/errors"
"carrotskin/internal/model"
"carrotskin/internal/repository"
"carrotskin/pkg/database"
@@ -13,8 +14,10 @@ import (
"fmt"
"path/filepath"
"strings"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
)
// textureService TextureService的实现
@@ -26,6 +29,7 @@ type textureService struct {
cacheKeys *database.CacheKeyBuilder
cacheInv *database.CacheInvalidator
logger *zap.Logger
db *gorm.DB
}
// NewTextureService 创建TextureService实例
@@ -35,6 +39,7 @@ func NewTextureService(
storageClient *storage.StorageClient,
cacheManager *database.CacheManager,
logger *zap.Logger,
db *gorm.DB,
) TextureService {
return &textureService{
textureRepo: textureRepo,
@@ -44,6 +49,7 @@ func NewTextureService(
cacheKeys: database.NewCacheKeyBuilder(""),
cacheInv: database.NewCacheInvalidator(cacheManager),
logger: logger,
db: db,
}
}
@@ -62,7 +68,7 @@ func (s *textureService) GetByID(ctx context.Context, id int64) (*model.Texture,
return nil, err
}
if texture2 == nil {
return nil, ErrTextureNotFound
return nil, apperrors.ErrTextureNotFound
}
if texture2.Status == -1 {
return nil, errors.New("材质已删除")
@@ -80,7 +86,7 @@ func (s *textureService) GetByID(ctx context.Context, id int64) (*model.Texture,
return nil, err
}
if texture2 == nil {
return nil, ErrTextureNotFound
return nil, apperrors.ErrTextureNotFound
}
if texture2.Status == -1 {
return nil, errors.New("材质已删除")
@@ -109,7 +115,7 @@ func (s *textureService) GetByHash(ctx context.Context, hash string) (*model.Tex
return nil, err
}
if texture2 == nil {
return nil, ErrTextureNotFound
return nil, apperrors.ErrTextureNotFound
}
if texture2.Status == -1 {
return nil, errors.New("材质已删除")
@@ -162,10 +168,10 @@ func (s *textureService) Update(ctx context.Context, textureID, uploaderID int64
return nil, err
}
if texture == nil {
return nil, ErrTextureNotFound
return nil, apperrors.ErrTextureNotFound
}
if texture.UploaderID != uploaderID {
return nil, ErrTextureNoPermission
return nil, apperrors.ErrTextureNoPermission
}
// 更新字段
@@ -200,10 +206,10 @@ func (s *textureService) Delete(ctx context.Context, textureID, uploaderID int64
return err
}
if texture == nil {
return ErrTextureNotFound
return apperrors.ErrTextureNotFound
}
if texture.UploaderID != uploaderID {
return ErrTextureNoPermission
return apperrors.ErrTextureNoPermission
}
err = s.textureRepo.Delete(ctx, textureID)
@@ -225,33 +231,41 @@ func (s *textureService) ToggleFavorite(ctx context.Context, userID, textureID i
return false, err
}
if texture == nil {
return false, ErrTextureNotFound
return false, apperrors.ErrTextureNotFound
}
isFavorited, err := s.textureRepo.IsFavorited(ctx, userID, textureID)
// 在事务中执行"切换收藏 + 增减计数"两步,保证数据一致性
var favorited bool
err = database.TransactionWithTimeout(ctx, s.db, 5*time.Second, func(tx *gorm.DB) error {
isFav, err := s.textureRepo.IsFavorited(ctx, userID, textureID)
if err != nil {
return err
}
if isFav {
// 已收藏 -> 取消收藏
if err := s.textureRepo.RemoveFavorite(ctx, userID, textureID); err != nil {
return err
}
if err := s.textureRepo.DecrementFavoriteCount(ctx, textureID); err != nil {
return err
}
favorited = false
return nil
}
// 未收藏 -> 添加收藏
if err := s.textureRepo.AddFavorite(ctx, userID, textureID); err != nil {
return err
}
if err := s.textureRepo.IncrementFavoriteCount(ctx, textureID); err != nil {
return err
}
favorited = true
return nil
})
if err != nil {
return false, err
}
if isFavorited {
// 已收藏 -> 取消收藏
if err := s.textureRepo.RemoveFavorite(ctx, userID, textureID); err != nil {
return false, err
}
if err := s.textureRepo.DecrementFavoriteCount(ctx, textureID); err != nil {
return false, err
}
return false, nil
}
// 未收藏 -> 添加收藏
if err := s.textureRepo.AddFavorite(ctx, userID, textureID); err != nil {
return false, err
}
if err := s.textureRepo.IncrementFavoriteCount(ctx, textureID); err != nil {
return false, err
}
return true, nil
return favorited, nil
}
func (s *textureService) GetUserFavorites(ctx context.Context, userID int64, page, pageSize int) ([]*model.Texture, int64, error) {
@@ -277,7 +291,7 @@ func (s *textureService) UploadTexture(ctx context.Context, uploaderID int64, na
// 验证用户存在
user, err := s.userRepo.FindByID(ctx, uploaderID)
if err != nil || user == nil {
return nil, ErrUserNotFound
return nil, apperrors.ErrUserNotFound
}
// 验证文件大小和扩展名
@@ -403,3 +417,28 @@ func parseTextureTypeInternal(textureType string) (model.TextureType, error) {
return "", errors.New("无效的材质类型")
}
}
// ==================== 管理员操作 ====================
// ListForAdmin 分页查询材质列表(管理员,含 Uploader 预加载)
func (s *textureService) ListForAdmin(ctx context.Context, page, pageSize int) ([]*model.Texture, int64, error) {
page, pageSize = NormalizePagination(page, pageSize)
return s.textureRepo.ListForAdmin(ctx, page, pageSize)
}
// AdminDelete 管理员删除材质(无权限校验)
func (s *textureService) AdminDelete(ctx context.Context, textureID int64) error {
texture, err := s.textureRepo.FindByIDForAdmin(ctx, textureID)
if err != nil {
return err
}
if texture == nil {
return apperrors.ErrTextureNotFound
}
return s.textureRepo.Delete(ctx, textureID)
}
// IncrementDownload 增加下载计数CustomSkinAPI 等场景使用)
func (s *textureService) IncrementDownload(ctx context.Context, textureID int64) error {
return s.textureRepo.IncrementDownloadCount(ctx, textureID)
}