Files
ttstd-infinite-canvas/backend/internal/handler/project_unit_routes.go

248 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 项目分集(unit)与画布关联接口。
package handler
import (
"net/http"
"yingce/backend/internal/service"
"github.com/gin-gonic/gin"
)
func registerProjectUnitRoutes(r *gin.RouterGroup, svc *service.Service) {
r.POST("/projects/:id/units", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 2<<20)
var req service.CreateProjectUnitRequest
if err := c.ShouldBindJSON(&req); err != nil {
fail(c, http.StatusBadRequest, err)
return
}
unit, err := svc.CreateProjectUnit(user.ID, c.Param("id"), req)
if err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"unit": unit})
})
r.GET("/projects/:id/units", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
units, err := svc.ProjectUnitSummaries(user.ID, c.Param("id"))
if err != nil {
failService(c, err)
return
}
ok(c, units)
})
r.GET("/projects/:id/units/:unitId", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
unit, err := svc.GetProjectUnit(user.ID, c.Param("id"), c.Param("unitId"))
if err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"unit": unit})
})
r.GET("/projects/:id/units/:unitId/workspace", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
workspace, err := svc.ProjectUnitWorkspace(user.ID, c.Param("id"), c.Param("unitId"))
if err != nil {
failService(c, err)
return
}
ok(c, workspace)
})
r.POST("/projects/:id/units/import", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
// 长篇小说可能包含两千章以上,限制请求体防止滥用的同时为整本原子导入留足空间。
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 32<<20)
var req service.ImportProjectUnitsRequest
if err := c.ShouldBindJSON(&req); err != nil {
fail(c, http.StatusBadRequest, err)
return
}
units, err := svc.ImportProjectUnits(user.ID, c.Param("id"), req)
if err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
// 导入响应只需返回新章节标识与摘要,正文不再原样回传一次。
for index := range units {
units[index].SourceText = ""
}
ok(c, gin.H{"units": units})
})
r.PATCH("/projects/:id/units/reorder", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 256<<10)
var req service.ReorderProjectUnitsRequest
if err := c.ShouldBindJSON(&req); err != nil {
fail(c, http.StatusBadRequest, err)
return
}
if err := svc.ReorderProjectUnits(user.ID, c.Param("id"), req); err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"unitIds": req.UnitIDs})
})
r.PATCH("/projects/:id/units/:unitId", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 2<<20)
var req service.UpdateProjectUnitRequest
if err := c.ShouldBindJSON(&req); err != nil {
fail(c, http.StatusBadRequest, err)
return
}
unit, err := svc.UpdateProjectUnit(user.ID, c.Param("id"), c.Param("unitId"), req)
if err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"unit": unit})
})
r.DELETE("/projects/:id/units/:unitId", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
if err := svc.DeleteProjectUnit(user.ID, c.Param("id"), c.Param("unitId")); err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"id": c.Param("unitId")})
})
r.POST("/projects/:id/canvas-links", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 64<<10)
var req service.LinkCanvasUnitRequest
if err := c.ShouldBindJSON(&req); err != nil {
fail(c, http.StatusBadRequest, err)
return
}
link, err := svc.LinkCanvasUnit(user.ID, c.Param("id"), req)
if err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"link": link})
})
r.DELETE("/projects/:id/canvas-links/:canvasId/units/:unitId", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
if err := svc.UnlinkCanvasUnit(user.ID, c.Param("id"), c.Param("canvasId"), c.Param("unitId")); err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"canvasId": c.Param("canvasId"), "unitId": c.Param("unitId")})
})
r.DELETE("/projects/:id/canvases/:canvasId", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
if err := svc.UnlinkCanvasProject(user.ID, c.Param("id"), c.Param("canvasId")); err != nil {
if service.IsProjectNotFound(err) {
fail(c, http.StatusNotFound, err)
return
}
failService(c, err)
return
}
ok(c, gin.H{"canvasId": c.Param("canvasId")})
})
r.GET("/projects/:id/canvases", func(c *gin.Context) {
user, err := currentUser(c, svc)
if err != nil {
failService(c, err)
return
}
page, err := parsePositiveQueryInt(c.Query("page"), 1)
if err != nil {
fail(c, http.StatusBadRequest, err)
return
}
pageSize, err := parsePositiveQueryInt(c.Query("pageSize"), 40)
if err != nil {
fail(c, http.StatusBadRequest, err)
return
}
result, err := svc.ProjectCanvasesPage(user.ID, c.Param("id"), page, pageSize)
if err != nil {
failService(c, err)
return
}
ok(c, result)
})
}