package handler import ( "fmt" "io" "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" ) // Media handlers func (h *Handler) ListMedia(c *gin.Context) { limit := 10 // Default limit if limitStr := c.Query("limit"); limitStr != "" { if l, err := strconv.Atoi(limitStr); err == nil && l > 0 { limit = l } } offset := 0 // Default offset if offsetStr := c.Query("offset"); offsetStr != "" { if o, err := strconv.Atoi(offsetStr); err == nil && o >= 0 { offset = o } } media, err := h.service.ListMedia(c.Request.Context(), limit, offset) if err != nil { log.Error().Err(err).Msg("Failed to list media") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list media"}) return } c.JSON(http.StatusOK, media) } func (h *Handler) UploadMedia(c *gin.Context) { // Get user ID from context (set by auth middleware) userID, exists := c.Get("user_id") if !exists { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } // Get file from form file, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"}) return } // 文件大小限制 if file.Size > 10*1024*1024 { // 10MB c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds the limit (10MB)"}) return } // 文件类型限制 allowedTypes := map[string]bool{ "image/jpeg": true, "image/png": true, "image/gif": true, "video/mp4": true, "video/webm": true, "audio/mpeg": true, "audio/ogg": true, "application/pdf": true, } contentType := file.Header.Get("Content-Type") if _, ok := allowedTypes[contentType]; !ok { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid file type"}) return } // Upload file media, err := h.service.Upload(c.Request.Context(), file, userID.(int)) if err != nil { log.Error().Err(err).Msg("Failed to upload media") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to upload media"}) return } c.JSON(http.StatusCreated, media) } func (h *Handler) GetMedia(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid media ID"}) return } // Get media metadata media, err := h.service.GetMedia(c.Request.Context(), id) if err != nil { log.Error().Err(err).Msg("Failed to get media") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get media"}) return } // Get file content reader, info, err := h.service.GetFile(c.Request.Context(), id) if err != nil { log.Error().Err(err).Msg("Failed to get media file") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get media file"}) return } defer reader.Close() // Set response headers c.Header("Content-Type", media.MimeType) c.Header("Content-Length", fmt.Sprintf("%d", info.Size)) c.Header("Content-Disposition", fmt.Sprintf("inline; filename=%s", media.OriginalName)) // Stream the file if _, err := io.Copy(c.Writer, reader); err != nil { log.Error().Err(err).Msg("Failed to stream media file") return } } func (h *Handler) GetMediaFile(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid media ID"}) return } // Get file content reader, info, err := h.service.GetFile(c.Request.Context(), id) if err != nil { log.Error().Err(err).Msg("Failed to get media file") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get media file"}) return } defer reader.Close() // Set response headers c.Header("Content-Type", info.ContentType) c.Header("Content-Length", fmt.Sprintf("%d", info.Size)) c.Header("Content-Disposition", fmt.Sprintf("inline; filename=%s", info.Name)) // Stream the file if _, err := io.Copy(c.Writer, reader); err != nil { log.Error().Err(err).Msg("Failed to stream media file") return } } func (h *Handler) DeleteMedia(c *gin.Context) { // Get user ID from context (set by auth middleware) userID, exists := c.Get("user_id") if !exists { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid media ID"}) return } if err := h.service.DeleteMedia(c.Request.Context(), id, userID.(int)); err != nil { log.Error().Err(err).Msg("Failed to delete media") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete media"}) return } c.JSON(http.StatusNoContent, nil) }