golang-dy-back/internal/handlers/upload.go
2025-10-28 16:59:41 +08:00

69 lines
2.0 KiB
Go

package handlers
import (
"log"
"fmt"
"mime"
"net/http"
"path/filepath"
"strings"
"time"
"github.com/gin-gonic/gin"
"go-dy/internal/config"
osspkg "go-dy/internal/oss"
"go-dy/internal/resp"
)
func UploadHandler(cfg config.Config) gin.HandlerFunc {
return func(c *gin.Context) {
fileHeader, err := c.FormFile("file")
if err != nil {
resp.Error(c, http.StatusBadRequest, "missing file")
return
}
f, err := fileHeader.Open()
if err != nil {
log.Printf("file open failed: filename=%s, err=%v", fileHeader.Filename, err)
resp.Error(c, http.StatusInternalServerError, "file open failed")
return
}
defer f.Close()
prefix := c.PostForm("prefix")
prefix = strings.Trim(prefix, "/ ")
if prefix == "" {
prefix = time.Now().Format("uploads/2006/01/02")
}
base := filepath.Base(fileHeader.Filename)
ts := time.Now().UnixNano()
objectKey := fmt.Sprintf("%s/%d_%s", prefix, ts, base)
ct := fileHeader.Header.Get("Content-Type")
if ct == "" {
ct = mime.TypeByExtension(filepath.Ext(base))
}
// Lazy init OSS client to avoid startup dependency on OSS params
oss, err := osspkg.New(cfg)
if err != nil {
log.Printf("oss init failed: endpoint=%s bucket=%s err=%v", cfg.OSSEndpoint, cfg.OSSBucket, err)
resp.Error(c, http.StatusInternalServerError, "upload failed")
return
}
if err := oss.Upload(objectKey, f, ct); err != nil {
log.Printf("oss upload failed: key=%s contentType=%s err=%v", objectKey, ct, err)
resp.Error(c, http.StatusInternalServerError, "upload failed")
return
}
url := oss.PublicURL(objectKey)
log.Printf("oss upload success: key=%s url=%s", objectKey, url)
resp.OK(c, gin.H{
"key": objectKey,
"url": url,
})
}
}