// 本文件负责剧集视频 ZIP 下载请求的参数校验、响应头设置和对象流写入。 package handler import ( "context" "io" "mime" "net/http" "juhe-factory/api/internal/service" "juhe-factory/api/internal/videoarchive" "github.com/gin-gonic/gin" ) // DownloadEpisodeVideos 下载当前剧集按项目类型筛选后的视频 ZIP。 func (h *Creative) DownloadEpisodeVideos(c *gin.Context) { if !h.objectStorageAvailable(c) { return } projectID, ok := h.projectID(c) if !ok { return } episodeID, err := service.ParseUUID(c.Param("episode_id"), "剧集") if err != nil { h.bad(c, err) return } manifest, err := h.service.EpisodeVideoArchive(currentWebUser(c).ID, projectID, episodeID) if err != nil { h.bad(c, err) return } c.Header("Content-Type", "application/zip") c.Header("Content-Disposition", mime.FormatMediaType("attachment", map[string]string{"filename": manifest.Name})) c.Header("X-Content-Type-Options", "nosniff") c.Status(http.StatusOK) err = videoarchive.Write(c.Request.Context(), c.Writer, manifest.Entries, func(ctx context.Context, objectKey string) (io.ReadCloser, error) { body, _, _, openErr := h.cos.Open(ctx, objectKey) return body, openErr }) if err != nil { _ = c.Error(err) c.Abort() } }