Files
JuYou/API/internal/handler/drama.go
T
2026-08-25 17:59:42 +08:00

211 lines
5.2 KiB
Go

package handler
import (
"errors"
"io"
"net/http"
"strings"
"juhe-factory/api/internal/service"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
func (h *Creative) PreviewDramaImport(c *gin.Context) {
projectID, ok := h.projectID(c)
if !ok {
return
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 4<<20)
if err := c.Request.ParseMultipartForm(4 << 20); err != nil {
h.bad(c, errors.New("导入内容无效"))
return
}
if c.Request.MultipartForm != nil {
defer c.Request.MultipartForm.RemoveAll()
}
rawText := strings.TrimSpace(c.PostForm("raw_text"))
var filename string
var content []byte
file, header, err := c.Request.FormFile("file")
if err == nil {
defer file.Close()
filename = header.Filename
content, err = io.ReadAll(io.LimitReader(file, 3*1024*1024+1))
if err != nil {
h.bad(c, errors.New("读取小说文件失败"))
return
}
} else if rawText == "" {
h.bad(c, errors.New("请选择小说文件或粘贴文本"))
return
}
preview, err := h.service.PreviewDramaImport(currentWebUser(c).ID, projectID, filename, content, rawText)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"data": preview})
}
func (h *Creative) ConfirmDramaImport(c *gin.Context) {
projectID, ok := h.projectID(c)
if !ok {
return
}
var body struct {
ImportToken uuid.UUID `json:"import_token"`
ChaptersPerEpisode int `json:"chapters_per_episode"`
StartEpisodeNo int `json:"start_episode_no"`
TreatAsSingleEpisode bool `json:"treat_as_single_episode"`
}
if err := c.ShouldBindJSON(&body); err != nil || body.ImportToken == uuid.Nil {
h.bad(c, errors.New("导入确认参数无效"))
return
}
items, err := h.service.ConfirmDramaImport(currentWebUser(c).ID, projectID, body.ImportToken, body.ChaptersPerEpisode, body.StartEpisodeNo, body.TreatAsSingleEpisode)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusCreated, gin.H{"data": items})
}
func (h *Creative) GetDramaEpisodeSource(c *gin.Context) {
projectID, episodeID, ok := h.dramaEpisodeIDs(c)
if !ok {
return
}
source, err := h.service.EpisodeSource(currentWebUser(c).ID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"data": source})
}
func (h *Creative) SaveDramaEpisodeSource(c *gin.Context) {
projectID, episodeID, ok := h.dramaEpisodeIDs(c)
if !ok {
return
}
var body struct {
Title string `json:"title"`
RawContent string `json:"raw_content"`
}
if err := c.ShouldBindJSON(&body); err != nil {
h.bad(c, err)
return
}
source, err := h.service.SaveEpisodeSource(currentWebUser(c).ID, projectID, episodeID, body.RawContent, body.Title)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"data": source})
}
func (h *Creative) QueueDramaParse(c *gin.Context) {
projectID, episodeID, ok := h.dramaEpisodeIDs(c)
if !ok {
return
}
task, err := h.service.QueueDramaParse(currentWebUser(c).ID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusAccepted, gin.H{"data": task})
}
func (h *Creative) ReparseDrama(c *gin.Context) {
if !h.objectStorageAvailable(c) {
return
}
projectID, episodeID, ok := h.dramaEpisodeIDs(c)
if !ok {
return
}
userID := currentWebUser(c).ID
objectKeys, err := h.service.ResetEpisodeAnalysis(userID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
if !h.deleteStoredObjects(c, objectKeys) {
return
}
task, err := h.service.QueueDramaParse(userID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusAccepted, gin.H{"data": task})
}
func (h *Creative) ListDramaParseTasks(c *gin.Context) {
projectID, ok := h.projectID(c)
if !ok {
return
}
var episodeID *uuid.UUID
if raw := strings.TrimSpace(c.Query("episode_id")); raw != "" {
parsed, err := service.ParseUUID(raw, "剧集")
if err != nil {
h.bad(c, err)
return
}
episodeID = &parsed
}
items, err := h.service.ListDramaParseTasks(currentWebUser(c).ID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusOK, gin.H{"data": items})
}
func (h *Creative) CancelDramaParse(c *gin.Context) {
projectID, ok := h.projectID(c)
if !ok {
return
}
taskID, err := service.ParseUUID(c.Param("task_id"), "解析任务")
if err != nil {
h.bad(c, err)
return
}
if err = h.service.CancelDramaParse(currentWebUser(c).ID, projectID, taskID); err != nil {
h.respondError(c, err)
return
}
c.Status(http.StatusNoContent)
}
func (h *Creative) CreateDramaStoryboard(c *gin.Context) {
projectID, episodeID, ok := h.dramaEpisodeIDs(c)
if !ok {
return
}
storyboard, err := h.service.CreateStoryboard(currentWebUser(c).ID, projectID, episodeID)
if err != nil {
h.respondError(c, err)
return
}
c.JSON(http.StatusCreated, gin.H{"data": storyboard})
}
func (h *Creative) dramaEpisodeIDs(c *gin.Context) (uuid.UUID, uuid.UUID, bool) {
projectID, ok := h.projectID(c)
if !ok {
return uuid.Nil, uuid.Nil, false
}
episodeID, err := service.ParseUUID(c.Param("episode_id"), "剧集")
if err != nil {
h.bad(c, err)
return uuid.Nil, uuid.Nil, false
}
return projectID, episodeID, true
}