Files
backend/internal/handler/upload_handler.go

135 lines
3.2 KiB
Go
Raw Normal View History

package handler
import (
"github.com/gin-gonic/gin"
"with_you/internal/pkg/response"
"with_you/internal/service"
)
// UploadHandler 上传处理器
type UploadHandler struct {
uploadService service.UploadService
}
// NewUploadHandler 创建上传处理器
func NewUploadHandler(uploadService service.UploadService) *UploadHandler {
return &UploadHandler{
uploadService: uploadService,
}
}
// UploadImage 上传图片
func (h *UploadHandler) UploadImage(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
response.Unauthorized(c, "")
return
}
file, err := c.FormFile("image")
if err != nil {
response.BadRequest(c, "image file is required")
return
}
url, previewURL, previewURLLarge, err := h.uploadService.UploadImage(c.Request.Context(), file)
if err != nil {
response.InternalServerError(c, "failed to upload image")
return
}
response.Success(c, gin.H{
"url": url,
"preview_url": previewURL,
"preview_url_large": previewURLLarge,
})
}
// UploadAvatar 上传头像
func (h *UploadHandler) UploadAvatar(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
response.Unauthorized(c, "")
return
}
file, err := c.FormFile("image")
if err != nil {
response.BadRequest(c, "avatar file is required")
return
}
url, err := h.uploadService.UploadAvatar(c.Request.Context(), userID, file)
if err != nil {
response.InternalServerError(c, "failed to upload avatar")
return
}
response.Success(c, gin.H{"url": url})
}
// UploadCover 上传头图(个人主页封面)
func (h *UploadHandler) UploadCover(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
response.Unauthorized(c, "")
return
}
file, err := c.FormFile("image")
if err != nil {
response.BadRequest(c, "image file is required")
return
}
url, err := h.uploadService.UploadCover(c.Request.Context(), userID, file)
if err != nil {
response.InternalServerError(c, "failed to upload cover")
return
}
response.Success(c, gin.H{"url": url})
}
// UploadFile 上传聊天/通用文件(非图片类资源)
// form 字段file必填、folder可选默认 chat
func (h *UploadHandler) UploadFile(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
response.Unauthorized(c, "")
return
}
file, err := c.FormFile("file")
if err != nil {
response.BadRequest(c, "file is required")
return
}
folder := c.DefaultPostForm("folder", "chat")
// 前端(尤其原生端 expo-file-system无法自定义 multipart filename
// 文件常被复制到缓存目录并以 UUID 命名,导致 header Filename 丢失真实名。
// 因此前端额外把真实文件名通过 "name" 字段回传,作为权威展示名。
displayName := c.PostForm("name")
result, err := h.uploadService.UploadFile(c.Request.Context(), file, folder, userID, displayName)
if err != nil {
// 参数类错误(大小/类型)返回 400其余返回 500
if file.Size > 0 && file.Size <= 100<<20 {
response.BadRequest(c, err.Error())
return
}
response.InternalServerError(c, "failed to upload file")
return
}
response.Success(c, gin.H{
"url": result.URL,
"name": result.Name,
"size": result.Size,
"mime_type": result.MimeType,
})
}