image_handler.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package handler
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "time"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // ImageHandler 图片上传处理器
  12. type ImageHandler struct {
  13. uploadDir string
  14. }
  15. // NewImageHandler 创建图片处理器
  16. func NewImageHandler(uploadDir string) *ImageHandler {
  17. return &ImageHandler{uploadDir: uploadDir}
  18. }
  19. // Init 初始化上传目录
  20. func (h *ImageHandler) Init() error {
  21. return os.MkdirAll(h.uploadDir, 0755)
  22. }
  23. // Upload 上传图片
  24. func (h *ImageHandler) Upload(c *gin.Context) {
  25. file, err := c.FormFile("image")
  26. if err != nil {
  27. c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "请选择图片文件"})
  28. return
  29. }
  30. // 验证文件类型
  31. ext := strings.ToLower(filepath.Ext(file.Filename))
  32. allowedExts := map[string]bool{
  33. ".jpg": true,
  34. ".jpeg": true,
  35. ".png": true,
  36. ".gif": true,
  37. ".webp": true,
  38. ".bmp": true,
  39. }
  40. if !allowedExts[ext] {
  41. c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "不支持的图片格式,仅支持 jpg、png、gif、webp"})
  42. return
  43. }
  44. // 验证文件大小 (最大 5MB)
  45. if file.Size > 5*1024*1024 {
  46. c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "图片大小不能超过 5MB"})
  47. return
  48. }
  49. // 生成唯一文件名
  50. filename := fmt.Sprintf("%d_%s%s", time.Now().UnixNano(), randomString(8), ext)
  51. filepath := filepath.Join(h.uploadDir, filename)
  52. // 保存文件
  53. if err := c.SaveUploadedFile(file, filepath); err != nil {
  54. c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "message": "保存图片失败"})
  55. return
  56. }
  57. // 返回访问 URL
  58. url := "/uploads/" + filename
  59. c.JSON(http.StatusOK, gin.H{
  60. "code": 0,
  61. "message": "上传成功",
  62. "data": gin.H{
  63. "url": url,
  64. },
  65. })
  66. }
  67. // randomString 生成随机字符串
  68. func randomString(length int) string {
  69. const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  70. result := make([]byte, length)
  71. for i := range result {
  72. result[i] = chars[time.Now().UnixNano()%int64(len(chars))]
  73. time.Sleep(time.Nanosecond)
  74. }
  75. return string(result)
  76. }