统一文件上传方式为直接上传,更新环境变量示例
This commit is contained in:
@@ -95,8 +95,8 @@ func registerUserRoutes(v1 *gin.RouterGroup, h *UserHandler, jwtService *auth.JW
|
||||
userGroup.PUT("/profile", h.UpdateProfile)
|
||||
|
||||
// 头像相关
|
||||
userGroup.POST("/avatar/upload-url", h.GenerateAvatarUploadURL)
|
||||
userGroup.PUT("/avatar", h.UpdateAvatar)
|
||||
userGroup.POST("/avatar/upload", h.UploadAvatar) // 直接上传头像文件
|
||||
userGroup.PUT("/avatar", h.UpdateAvatar) // 更新头像URL(外部URL)
|
||||
|
||||
// 更换邮箱
|
||||
userGroup.POST("/change-email", h.ChangeEmail)
|
||||
@@ -122,9 +122,7 @@ func registerTextureRoutes(v1 *gin.RouterGroup, h *TextureHandler, jwtService *a
|
||||
textureAuth := textureGroup.Group("")
|
||||
textureAuth.Use(middleware.AuthMiddleware(jwtService))
|
||||
{
|
||||
textureAuth.POST("/upload", h.Upload) // 直接上传文件
|
||||
textureAuth.POST("/upload-url", h.GenerateUploadURL) // 生成预签名URL(保留兼容性)
|
||||
textureAuth.POST("", h.Create) // 创建材质记录(配合预签名URL使用)
|
||||
textureAuth.POST("/upload", h.Upload) // 直接上传文件
|
||||
textureAuth.PUT("/:id", h.Update)
|
||||
textureAuth.DELETE("/:id", h.Delete)
|
||||
textureAuth.POST("/:id/favorite", h.ToggleFavorite)
|
||||
|
||||
@@ -25,93 +25,6 @@ func NewTextureHandler(c *container.Container) *TextureHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateUploadURL 生成材质上传URL
|
||||
func (h *TextureHandler) GenerateUploadURL(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req types.GenerateTextureUploadURLRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
RespondBadRequest(c, "请求参数错误", err)
|
||||
return
|
||||
}
|
||||
|
||||
if h.container.Storage == nil {
|
||||
RespondServerError(c, "存储服务不可用", nil)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.container.UploadService.GenerateTextureUploadURL(
|
||||
c.Request.Context(),
|
||||
userID,
|
||||
req.FileName,
|
||||
string(req.TextureType),
|
||||
)
|
||||
if err != nil {
|
||||
h.logger.Error("生成材质上传URL失败",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("file_name", req.FileName),
|
||||
zap.String("texture_type", string(req.TextureType)),
|
||||
zap.Error(err),
|
||||
)
|
||||
RespondBadRequest(c, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
RespondSuccess(c, &types.GenerateTextureUploadURLResponse{
|
||||
PostURL: result.PostURL,
|
||||
FormData: result.FormData,
|
||||
TextureURL: result.FileURL,
|
||||
ExpiresIn: 900,
|
||||
})
|
||||
}
|
||||
|
||||
// Create 创建材质记录
|
||||
func (h *TextureHandler) Create(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req types.CreateTextureRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
RespondBadRequest(c, "请求参数错误", err)
|
||||
return
|
||||
}
|
||||
|
||||
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.Create(
|
||||
c.Request.Context(),
|
||||
userID,
|
||||
req.Name,
|
||||
req.Description,
|
||||
string(req.Type),
|
||||
req.URL,
|
||||
req.Hash,
|
||||
req.Size,
|
||||
req.IsPublic,
|
||||
req.IsSlim,
|
||||
)
|
||||
if err != nil {
|
||||
h.logger.Error("创建材质失败",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("name", req.Name),
|
||||
zap.Error(err),
|
||||
)
|
||||
RespondBadRequest(c, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
RespondSuccess(c, TextureToTextureInfo(texture))
|
||||
}
|
||||
|
||||
// Get 获取材质详情
|
||||
func (h *TextureHandler) Get(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
|
||||
@@ -102,44 +102,66 @@ func (h *UserHandler) UpdateProfile(c *gin.Context) {
|
||||
RespondSuccess(c, UserToUserInfo(updatedUser))
|
||||
}
|
||||
|
||||
// GenerateAvatarUploadURL 生成头像上传URL
|
||||
func (h *UserHandler) GenerateAvatarUploadURL(c *gin.Context) {
|
||||
// UploadAvatar 直接上传头像文件
|
||||
func (h *UserHandler) UploadAvatar(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var req types.GenerateAvatarUploadURLRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
RespondBadRequest(c, "请求参数错误", err)
|
||||
// 解析multipart表单
|
||||
if err := c.Request.ParseMultipartForm(10 << 20); err != nil { // 10MB
|
||||
RespondBadRequest(c, "解析表单失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
if h.container.Storage == nil {
|
||||
RespondServerError(c, "存储服务不可用", nil)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.container.UploadService.GenerateAvatarUploadURL(c.Request.Context(), userID, req.FileName)
|
||||
// 获取文件
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
h.logger.Error("生成头像上传URL失败",
|
||||
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
|
||||
}
|
||||
|
||||
// 调用服务上传头像
|
||||
avatarURL, err := h.container.UserService.UploadAvatar(c.Request.Context(), userID, fileData, file.Filename)
|
||||
if err != nil {
|
||||
h.logger.Error("上传头像失败",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("file_name", req.FileName),
|
||||
zap.String("file_name", file.Filename),
|
||||
zap.Error(err),
|
||||
)
|
||||
RespondBadRequest(c, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
RespondSuccess(c, &types.GenerateAvatarUploadURLResponse{
|
||||
PostURL: result.PostURL,
|
||||
FormData: result.FormData,
|
||||
AvatarURL: result.FileURL,
|
||||
ExpiresIn: 900,
|
||||
// 获取更新后的用户信息
|
||||
user, err := h.container.UserService.GetByID(c.Request.Context(), userID)
|
||||
if err != nil || user == nil {
|
||||
RespondNotFound(c, "用户不存在")
|
||||
return
|
||||
}
|
||||
|
||||
RespondSuccess(c, gin.H{
|
||||
"avatar_url": avatarURL,
|
||||
"user": UserToUserInfo(user),
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateAvatar 更新头像URL
|
||||
// UpdateAvatar 更新头像URL(保留用于外部URL)
|
||||
func (h *UserHandler) UpdateAvatar(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
|
||||
Reference in New Issue
Block a user