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.
This commit is contained in:
@@ -88,7 +88,7 @@ func NewContainer(
|
||||
// 初始化Service(注入缓存管理器)
|
||||
c.UserService = service.NewUserService(c.UserRepo, c.ConfigRepo, jwtService, redisClient, cacheManager, logger)
|
||||
c.ProfileService = service.NewProfileService(c.ProfileRepo, c.UserRepo, cacheManager, logger)
|
||||
c.TextureService = service.NewTextureService(c.TextureRepo, c.UserRepo, cacheManager, logger)
|
||||
c.TextureService = service.NewTextureService(c.TextureRepo, c.UserRepo, storageClient, cacheManager, logger)
|
||||
|
||||
// 获取Yggdrasil私钥并创建JWT服务(TokenService需要)
|
||||
// 注意:这里仍然需要预先初始化,因为TokenService在创建时需要YggdrasilJWT
|
||||
|
||||
@@ -113,8 +113,9 @@ func registerTextureRoutes(v1 *gin.RouterGroup, h *TextureHandler, jwtService *a
|
||||
textureAuth := textureGroup.Group("")
|
||||
textureAuth.Use(middleware.AuthMiddleware(jwtService))
|
||||
{
|
||||
textureAuth.POST("/upload-url", h.GenerateUploadURL)
|
||||
textureAuth.POST("", h.Create)
|
||||
textureAuth.POST("/upload", h.Upload) // 直接上传文件
|
||||
textureAuth.POST("/upload-url", h.GenerateUploadURL) // 生成预签名URL(保留兼容性)
|
||||
textureAuth.POST("", h.Create) // 创建材质记录(配合预签名URL使用)
|
||||
textureAuth.PUT("/:id", h.Update)
|
||||
textureAuth.DELETE("/:id", h.Delete)
|
||||
textureAuth.POST("/:id/favorite", h.ToggleFavorite)
|
||||
@@ -135,6 +136,9 @@ func registerProfileRoutesWithDI(v1 *gin.RouterGroup, h *ProfileHandler, jwtServ
|
||||
profileAuth := profileGroup.Group("")
|
||||
profileAuth.Use(middleware.AuthMiddleware(jwtService))
|
||||
{
|
||||
// 同时支持 /api/v1/profile 和 /api/v1/profile/ 两种形式返回列表与创建
|
||||
profileAuth.GET("", h.List)
|
||||
profileAuth.POST("", h.Create)
|
||||
profileAuth.POST("/", h.Create)
|
||||
profileAuth.GET("/", h.List)
|
||||
profileAuth.PUT("/:uuid", h.Update)
|
||||
|
||||
@@ -152,7 +152,23 @@ func (h *TextureHandler) Search(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, model.NewPaginationResponse(TexturesToTextureInfos(textures), total, page, pageSize))
|
||||
// 返回格式:
|
||||
// {
|
||||
// "code": 200,
|
||||
// "message": "操作成功",
|
||||
// "data": {
|
||||
// "list": [...],
|
||||
// "total": 1,
|
||||
// "page": 1,
|
||||
// "per_page": 5
|
||||
// }
|
||||
// }
|
||||
RespondSuccess(c, gin.H{
|
||||
"list": TexturesToTextureInfos(textures),
|
||||
"total": total,
|
||||
"page": page,
|
||||
"per_page": pageSize,
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新材质
|
||||
@@ -258,7 +274,12 @@ func (h *TextureHandler) GetUserTextures(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, model.NewPaginationResponse(TexturesToTextureInfos(textures), total, page, pageSize))
|
||||
RespondSuccess(c, gin.H{
|
||||
"list": TexturesToTextureInfos(textures),
|
||||
"total": total,
|
||||
"page": page,
|
||||
"per_page": pageSize,
|
||||
})
|
||||
}
|
||||
|
||||
// GetUserFavorites 获取用户收藏的材质列表
|
||||
@@ -278,5 +299,92 @@ func (h *TextureHandler) GetUserFavorites(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, model.NewPaginationResponse(TexturesToTextureInfos(textures), total, page, pageSize))
|
||||
RespondSuccess(c, gin.H{
|
||||
"list": TexturesToTextureInfos(textures),
|
||||
"total": total,
|
||||
"page": page,
|
||||
"per_page": pageSize,
|
||||
})
|
||||
}
|
||||
|
||||
// Upload 直接上传材质文件
|
||||
func (h *TextureHandler) Upload(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// 解析multipart表单
|
||||
if err := c.Request.ParseMultipartForm(32 << 20); err != nil { // 32MB
|
||||
RespondBadRequest(c, "解析表单失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取文件
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "获取文件失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "打开文件失败", err)
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
fileData := make([]byte, file.Size)
|
||||
if _, err := src.Read(fileData); err != nil {
|
||||
RespondBadRequest(c, "读取文件失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取表单字段
|
||||
name := c.PostForm("name")
|
||||
if name == "" {
|
||||
RespondBadRequest(c, "名称不能为空", nil)
|
||||
return
|
||||
}
|
||||
|
||||
description := c.PostForm("description")
|
||||
textureType := c.PostForm("type")
|
||||
if textureType == "" {
|
||||
textureType = "SKIN" // 默认值
|
||||
}
|
||||
|
||||
isPublic := c.PostForm("is_public") == "true"
|
||||
isSlim := c.PostForm("is_slim") == "true"
|
||||
|
||||
// 检查上传限制
|
||||
maxTextures := h.container.UserService.GetMaxTexturesPerUser()
|
||||
if err := h.container.TextureService.CheckUploadLimit(c.Request.Context(), userID, maxTextures); err != nil {
|
||||
RespondBadRequest(c, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// 调用服务上传
|
||||
texture, err := h.container.TextureService.UploadTexture(
|
||||
c.Request.Context(),
|
||||
userID,
|
||||
name,
|
||||
description,
|
||||
textureType,
|
||||
fileData,
|
||||
file.Filename,
|
||||
isPublic,
|
||||
isSlim,
|
||||
)
|
||||
if err != nil {
|
||||
h.logger.Error("上传材质失败",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("file_name", file.Filename),
|
||||
zap.Error(err),
|
||||
)
|
||||
RespondBadRequest(c, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
RespondSuccess(c, TextureToTextureInfo(texture))
|
||||
}
|
||||
|
||||
@@ -10,11 +10,14 @@ import (
|
||||
func CORS() gin.HandlerFunc {
|
||||
// 获取配置,如果配置未初始化则使用默认值
|
||||
var allowedOrigins []string
|
||||
var isTestEnv bool
|
||||
if cfg, err := config.GetConfig(); err == nil {
|
||||
allowedOrigins = cfg.Security.AllowedOrigins
|
||||
isTestEnv = cfg.IsTestEnvironment()
|
||||
} else {
|
||||
// 默认允许所有来源(向后兼容)
|
||||
allowedOrigins = []string{"*"}
|
||||
isTestEnv = false
|
||||
}
|
||||
|
||||
return gin.HandlerFunc(func(c *gin.Context) {
|
||||
@@ -22,7 +25,8 @@ func CORS() gin.HandlerFunc {
|
||||
|
||||
// 检查是否允许该来源
|
||||
allowOrigin := "*"
|
||||
if len(allowedOrigins) > 0 && allowedOrigins[0] != "*" {
|
||||
// 测试环境下强制使用 *,否则按配置处理
|
||||
if !isTestEnv && len(allowedOrigins) > 0 && allowedOrigins[0] != "*" {
|
||||
allowOrigin = ""
|
||||
for _, allowed := range allowedOrigins {
|
||||
if allowed == origin || allowed == "*" {
|
||||
|
||||
@@ -24,3 +24,8 @@ func (Client) TableName() string {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ type Texture struct {
|
||||
Description string `gorm:"column:description;type:text" json:"description,omitempty"`
|
||||
Type TextureType `gorm:"column:type;type:varchar(50);not null;index:idx_textures_public_type_status,priority:2" json:"type"` // SKIN, CAPE
|
||||
URL string `gorm:"column:url;type:varchar(255);not null" json:"url"`
|
||||
Hash string `gorm:"column:hash;type:varchar(64);not null;uniqueIndex:idx_textures_hash" json:"hash"` // SHA-256
|
||||
Hash string `gorm:"column:hash;type:varchar(64);not null;index:idx_textures_hash" json:"hash"` // SHA-256
|
||||
Size int `gorm:"column:size;type:integer;not null;default:0" json:"size"`
|
||||
IsPublic bool `gorm:"column:is_public;not null;default:false;index:idx_textures_public_type_status,priority:1" json:"is_public"`
|
||||
DownloadCount int `gorm:"column:download_count;type:integer;not null;default:0;index:idx_textures_download_count,sort:desc" json:"download_count"`
|
||||
FavoriteCount int `gorm:"column:favorite_count;type:integer;not null;default:0;index:idx_textures_favorite_count,sort:desc" json:"favorite_count"`
|
||||
IsSlim bool `gorm:"column:is_slim;not null;default:false" json:"is_slim"` // Alex(细) or Steve(粗)
|
||||
IsSlim bool `gorm:"column:is_slim;not null;default:false" json:"is_slim"` // Alex(细) or Steve(粗)
|
||||
Status int16 `gorm:"column:status;type:smallint;not null;default:1;index:idx_textures_public_type_status,priority:3;index:idx_textures_uploader_status,priority:2" json:"status"` // 1:正常, 0:审核中, -1:已删除
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:CURRENT_TIMESTAMP;index:idx_textures_uploader_created,priority:2,sort:desc;index:idx_textures_created_at,sort:desc" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
|
||||
@@ -47,7 +47,8 @@ type TextureRepository interface {
|
||||
Create(ctx context.Context, texture *model.Texture) error
|
||||
FindByID(ctx context.Context, id int64) (*model.Texture, error)
|
||||
FindByHash(ctx context.Context, hash string) (*model.Texture, error)
|
||||
FindByIDs(ctx context.Context, ids []int64) ([]*model.Texture, error) // 批量查询
|
||||
FindByHashAndUploaderID(ctx context.Context, hash string, uploaderID int64) (*model.Texture, error) // 根据Hash和上传者ID查找
|
||||
FindByIDs(ctx context.Context, ids []int64) ([]*model.Texture, error) // 批量查询
|
||||
FindByUploaderID(ctx context.Context, uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error)
|
||||
Search(ctx context.Context, keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error)
|
||||
Update(ctx context.Context, texture *model.Texture) error
|
||||
|
||||
@@ -33,6 +33,12 @@ func (r *textureRepository) FindByHash(ctx context.Context, hash string) (*model
|
||||
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
|
||||
|
||||
@@ -57,6 +57,7 @@ type ProfileService interface {
|
||||
type TextureService interface {
|
||||
// 材质CRUD
|
||||
Create(ctx context.Context, uploaderID int64, name, description, textureType, url, hash string, size int, isPublic, isSlim bool) (*model.Texture, error)
|
||||
UploadTexture(ctx context.Context, uploaderID int64, name, description, textureType string, fileData []byte, fileName string, isPublic, isSlim bool) (*model.Texture, error) // 直接上传材质文件
|
||||
GetByID(ctx context.Context, id int64) (*model.Texture, error)
|
||||
GetByHash(ctx context.Context, hash string) (*model.Texture, error)
|
||||
GetByUserID(ctx context.Context, uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"carrotskin/internal/model"
|
||||
"carrotskin/internal/repository"
|
||||
"carrotskin/pkg/database"
|
||||
"carrotskin/pkg/storage"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -16,6 +22,7 @@ import (
|
||||
type textureService struct {
|
||||
textureRepo repository.TextureRepository
|
||||
userRepo repository.UserRepository
|
||||
storage *storage.StorageClient
|
||||
cache *database.CacheManager
|
||||
cacheKeys *database.CacheKeyBuilder
|
||||
cacheInv *database.CacheInvalidator
|
||||
@@ -26,12 +33,14 @@ type textureService struct {
|
||||
func NewTextureService(
|
||||
textureRepo repository.TextureRepository,
|
||||
userRepo repository.UserRepository,
|
||||
storageClient *storage.StorageClient,
|
||||
cacheManager *database.CacheManager,
|
||||
logger *zap.Logger,
|
||||
) TextureService {
|
||||
return &textureService{
|
||||
textureRepo: textureRepo,
|
||||
userRepo: userRepo,
|
||||
storage: storageClient,
|
||||
cache: cacheManager,
|
||||
cacheKeys: database.NewCacheKeyBuilder(""),
|
||||
cacheInv: database.NewCacheInvalidator(cacheManager),
|
||||
@@ -46,13 +55,16 @@ func (s *textureService) Create(ctx context.Context, uploaderID int64, name, des
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
|
||||
// 检查Hash是否已存在
|
||||
// 检查是否有任何用户上传过相同Hash的皮肤(复用URL,不重复保存文件)
|
||||
existingTexture, err := s.textureRepo.FindByHash(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 如果已存在相同Hash的皮肤,复用已存在的URL
|
||||
finalURL := url
|
||||
if existingTexture != nil {
|
||||
return nil, errors.New("该材质已存在")
|
||||
finalURL = existingTexture.URL
|
||||
}
|
||||
|
||||
// 转换材质类型
|
||||
@@ -61,13 +73,13 @@ func (s *textureService) Create(ctx context.Context, uploaderID int64, name, des
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建材质
|
||||
// 创建材质记录(即使Hash相同,也创建新的数据库记录)
|
||||
texture := &model.Texture{
|
||||
UploaderID: uploaderID,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Type: textureTypeEnum,
|
||||
URL: url,
|
||||
URL: finalURL, // 复用已存在的URL或使用新URL
|
||||
Hash: hash,
|
||||
Size: size,
|
||||
IsPublic: isPublic,
|
||||
@@ -304,6 +316,116 @@ func (s *textureService) CheckUploadLimit(ctx context.Context, uploaderID int64,
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadTexture 直接上传材质文件
|
||||
func (s *textureService) UploadTexture(ctx context.Context, uploaderID int64, name, description, textureType string, fileData []byte, fileName string, isPublic, isSlim bool) (*model.Texture, error) {
|
||||
// 验证用户存在
|
||||
user, err := s.userRepo.FindByID(ctx, uploaderID)
|
||||
if err != nil || user == nil {
|
||||
return nil, ErrUserNotFound
|
||||
}
|
||||
|
||||
// 验证文件大小和扩展名
|
||||
fileSize := len(fileData)
|
||||
const minSize = 512 // 512B
|
||||
const maxSize = 10 * 1024 * 1024 // 10MB
|
||||
if int64(fileSize) < minSize || int64(fileSize) > maxSize {
|
||||
return nil, fmt.Errorf("文件大小必须在 %d 到 %d 字节之间", minSize, maxSize)
|
||||
}
|
||||
|
||||
// 验证文件扩展名(只支持PNG)
|
||||
ext := strings.ToLower(filepath.Ext(fileName))
|
||||
if ext != ".png" {
|
||||
return nil, fmt.Errorf("不支持的文件格式: %s,仅支持PNG格式", ext)
|
||||
}
|
||||
|
||||
// 验证材质类型
|
||||
if textureType != "SKIN" && textureType != "CAPE" {
|
||||
return nil, errors.New("无效的材质类型")
|
||||
}
|
||||
|
||||
// 计算文件SHA256哈希
|
||||
hashBytes := sha256.Sum256(fileData)
|
||||
hash := hex.EncodeToString(hashBytes[:])
|
||||
|
||||
// 检查是否有任何用户上传过相同Hash的皮肤(复用URL,不重复保存文件)
|
||||
existingTexture, err := s.textureRepo.FindByHash(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var finalURL string
|
||||
if existingTexture != nil {
|
||||
// 如果已存在相同Hash的皮肤,复用已存在的URL,不重复上传
|
||||
finalURL = existingTexture.URL
|
||||
s.logger.Info("复用已存在的材质文件",
|
||||
zap.String("hash", hash),
|
||||
zap.String("url", finalURL),
|
||||
)
|
||||
} else {
|
||||
// 如果不存在,上传到对象存储
|
||||
if s.storage == nil {
|
||||
return nil, errors.New("存储服务不可用")
|
||||
}
|
||||
|
||||
// 获取存储桶名称
|
||||
bucketName, err := s.storage.GetBucket("textures")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取存储桶失败: %w", err)
|
||||
}
|
||||
|
||||
// 生成对象名称(路径)
|
||||
// 格式: hash/{hash[:2]}/{hash[2:4]}/{hash}.png
|
||||
// 使用哈希值作为路径,避免重复存储相同文件
|
||||
textureTypeFolder := strings.ToLower(textureType)
|
||||
objectName := fmt.Sprintf("%s/%s/%s/%s/%s%s", textureTypeFolder, hash[:2], hash[2:4], hash, hash, ext)
|
||||
|
||||
// 上传文件
|
||||
reader := bytes.NewReader(fileData)
|
||||
contentType := "image/png"
|
||||
if err := s.storage.UploadObject(ctx, bucketName, objectName, reader, int64(fileSize), contentType); err != nil {
|
||||
return nil, fmt.Errorf("上传文件失败: %w", err)
|
||||
}
|
||||
|
||||
// 构建文件URL
|
||||
finalURL = s.storage.BuildFileURL(bucketName, objectName)
|
||||
s.logger.Info("上传新的材质文件",
|
||||
zap.String("hash", hash),
|
||||
zap.String("url", finalURL),
|
||||
)
|
||||
}
|
||||
|
||||
// 转换材质类型
|
||||
textureTypeEnum, err := parseTextureTypeInternal(textureType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建材质记录(即使Hash相同,也创建新的数据库记录)
|
||||
texture := &model.Texture{
|
||||
UploaderID: uploaderID,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Type: textureTypeEnum,
|
||||
URL: finalURL,
|
||||
Hash: hash,
|
||||
Size: fileSize,
|
||||
IsPublic: isPublic,
|
||||
IsSlim: isSlim,
|
||||
Status: 1,
|
||||
DownloadCount: 0,
|
||||
FavoriteCount: 0,
|
||||
}
|
||||
|
||||
if err := s.textureRepo.Create(ctx, texture); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 清除用户的 texture 列表缓存(所有分页)
|
||||
s.cacheInv.BatchInvalidate(ctx, fmt.Sprintf("texture:user:%d:*", uploaderID))
|
||||
|
||||
return texture, nil
|
||||
}
|
||||
|
||||
// parseTextureTypeInternal 解析材质类型
|
||||
func parseTextureTypeInternal(textureType string) (model.TextureType, error) {
|
||||
switch textureType {
|
||||
|
||||
@@ -572,7 +572,7 @@ func TestTextureServiceImpl_Create(t *testing.T) {
|
||||
tt.textureType,
|
||||
"http://example.com/texture.png",
|
||||
tt.hash,
|
||||
1024,
|
||||
512,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
|
||||
@@ -129,7 +129,7 @@ func GetUploadConfig(fileType FileType) *UploadConfig {
|
||||
".gif": true,
|
||||
".webp": true,
|
||||
},
|
||||
MinSize: 1024, // 1KB
|
||||
MinSize: 512, // 512B
|
||||
MaxSize: 5 * 1024 * 1024, // 5MB
|
||||
Expires: 15 * time.Minute,
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func GetUploadConfig(fileType FileType) *UploadConfig {
|
||||
AllowedExts: map[string]bool{
|
||||
".png": true,
|
||||
},
|
||||
MinSize: 1024, // 1KB
|
||||
MinSize: 512, // 512B
|
||||
MaxSize: 10 * 1024 * 1024, // 10MB
|
||||
Expires: 15 * time.Minute,
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ func TestGetUploadConfig_AvatarConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
// 验证文件大小限制
|
||||
if config.MinSize != 1024 {
|
||||
t.Errorf("Avatar MinSize = %d, want 1024", config.MinSize)
|
||||
if config.MinSize != 512 {
|
||||
t.Errorf("Avatar MinSize = %d, want 512", config.MinSize)
|
||||
}
|
||||
|
||||
if config.MaxSize != 5*1024*1024 {
|
||||
@@ -122,8 +122,8 @@ func TestGetUploadConfig_TextureConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
// 验证文件大小限制
|
||||
if config.MinSize != 1024 {
|
||||
t.Errorf("Texture MinSize = %d, want 1024", config.MinSize)
|
||||
if config.MinSize != 512 {
|
||||
t.Errorf("Texture MinSize = %d, want 512", config.MinSize)
|
||||
}
|
||||
|
||||
if config.MaxSize != 10*1024*1024 {
|
||||
@@ -259,7 +259,7 @@ func TestUploadConfig_Structure(t *testing.T) {
|
||||
AllowedExts: map[string]bool{
|
||||
".png": true,
|
||||
},
|
||||
MinSize: 1024,
|
||||
MinSize: 512,
|
||||
MaxSize: 5 * 1024 * 1024,
|
||||
Expires: 15 * time.Minute,
|
||||
}
|
||||
@@ -325,8 +325,8 @@ func TestGenerateAvatarUploadURL_Success(t *testing.T) {
|
||||
t.Fatalf("objectName should contain original file name, got: %s", objectName)
|
||||
}
|
||||
// 检查大小与过期时间传递
|
||||
if minSize != 1024 {
|
||||
t.Fatalf("minSize = %d, want 1024", minSize)
|
||||
if minSize != 512 {
|
||||
t.Fatalf("minSize = %d, want 512", minSize)
|
||||
}
|
||||
if maxSize != 5*1024*1024 {
|
||||
t.Fatalf("maxSize = %d, want 5MB", maxSize)
|
||||
|
||||
Reference in New Issue
Block a user