refactor: replace standard log with zap logger and optimize code patterns

- Migrate all log.Printf/log.Println calls to structured zap logging
- Use cmp.Or for cleaner default value handling
- Replace manual loops with slices.ContainsFunc/IndexFunc
- Add batch query methods (IsLikedBatch, IsFavoritedBatch) to solve N+1 problem
- Update JSON tags from omitempty to omitzero for numeric fields
- Use errgroup-style wg.Go for worker goroutines
- Remove duplicate casbin/v2 dependency (keeping v3)
- Add plans/ to gitignore
This commit is contained in:
lafay
2026-03-17 00:47:17 +08:00
parent b028f7e1d3
commit 5d6c982c9c
38 changed files with 2256 additions and 290 deletions

View File

@@ -2,6 +2,7 @@ package service
import (
"bytes"
"cmp"
"context"
"crypto/sha256"
"fmt"
@@ -9,7 +10,6 @@ import (
"image/jpeg"
"image/png"
"io"
"log"
"mime"
"mime/multipart"
"net/http"
@@ -17,7 +17,9 @@ import (
"strings"
"carrot_bbs/internal/pkg/s3"
"github.com/disintegration/imaging"
"go.uber.org/zap"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/tiff"
@@ -65,7 +67,9 @@ func (s *UploadService) UploadImage(ctx context.Context, file *multipart.FileHea
// 生成预览图
previewURL, previewURLLarge, err := s.GeneratePreviewImages(ctx, processedData, hashStr)
if err != nil {
log.Printf("[WARN] Failed to generate preview images: %v", err)
zap.L().Warn("Failed to generate preview images",
zap.Error(err),
)
}
return url, previewURL, previewURLLarge, nil
@@ -189,10 +193,7 @@ func prepareImageForUpload(file *multipart.FileHeader) ([]byte, string, string,
// 优先从文件字节探测真实类型,避免前端压缩/转码后 header 与实际格式不一致
detectedType := normalizeImageContentType(http.DetectContentType(originalData))
headerType := normalizeImageContentType(file.Header.Get("Content-Type"))
contentType := detectedType
if contentType == "" || contentType == "application/octet-stream" {
contentType = headerType
}
contentType := cmp.Or(detectedType, headerType, "application/octet-stream")
compressedData, compressedType, err := compressImageData(originalData, contentType)
if err != nil {
@@ -201,21 +202,9 @@ func prepareImageForUpload(file *multipart.FileHeader) ([]byte, string, string,
compressedType = contentType
}
if compressedType == "" {
compressedType = contentType
}
if compressedType == "" {
compressedType = http.DetectContentType(compressedData)
}
compressedType = cmp.Or(compressedType, http.DetectContentType(compressedData))
ext := getExtFromContentType(compressedType)
if ext == "" {
ext = strings.ToLower(filepath.Ext(file.Filename))
}
if ext == "" {
// 最终兜底,避免对象名无扩展名导致 URL 语义不明确
ext = ".jpg"
}
ext := cmp.Or(getExtFromContentType(compressedType), strings.ToLower(filepath.Ext(file.Filename)), ".jpg")
return compressedData, compressedType, ext, nil
}
@@ -302,13 +291,17 @@ func (s *UploadService) GeneratePreviewImages(ctx context.Context, originalData
// 生成普通预览图(列表/网格模式)
previewURL, err = s.generatePreview(ctx, img, originalWidth, originalHeight, "preview", PreviewMaxWidth, hash)
if err != nil {
log.Printf("[WARN] Failed to generate preview: %v", err)
zap.L().Warn("Failed to generate preview",
zap.Error(err),
)
}
// 生成大预览图(详情页)
previewURLLarge, err = s.generatePreview(ctx, img, originalWidth, originalHeight, "large", PreviewMaxHeight, hash)
if err != nil {
log.Printf("[WARN] Failed to generate large preview: %v", err)
zap.L().Warn("Failed to generate large preview",
zap.Error(err),
)
}
return previewURL, previewURLLarge, nil