145 lines
4.3 KiB
Go
145 lines
4.3 KiB
Go
package handler
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"api-server/internal/scraper"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// ContentHandler 内容列表 API 处理器
|
||
type ContentHandler struct {
|
||
authorSession *scraper.Session
|
||
categorySession *scraper.Session
|
||
}
|
||
|
||
// NewContentHandler 创建内容处理器
|
||
func NewContentHandler() *ContentHandler {
|
||
return &ContentHandler{
|
||
authorSession: scraper.NewSession(),
|
||
categorySession: scraper.NewSession(),
|
||
}
|
||
}
|
||
|
||
// RegisterRoutes 注册路由
|
||
func (h *ContentHandler) RegisterRoutes(r *gin.RouterGroup) {
|
||
r.GET("/categories", h.ListCategories)
|
||
r.GET("/category/:code", h.CategoryVideos)
|
||
r.GET("/author/:uid", h.AuthorVideos)
|
||
}
|
||
|
||
// ListCategories 分类目录
|
||
// @Summary 分类目录
|
||
// @Description 返回所有可用的视频分类及其代码和描述
|
||
// @Tags content
|
||
// @Produce json
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Router /categories [get]
|
||
func (h *ContentHandler) ListCategories(c *gin.Context) {
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"code": 0,
|
||
"data": scraper.Categories,
|
||
})
|
||
}
|
||
|
||
// CategoryVideos 分类视频列表
|
||
// @Summary 分类视频列表
|
||
// @Description 获取指定分类下的视频列表,支持分页和全量获取
|
||
// @Tags content
|
||
// @Produce json
|
||
// @Param code path string true "分类代码: rf/top/ori/hot/long/longer/tf/hd/md/mf"
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param viewtype query string false "视图类型" default(basic)
|
||
// @Param max_pages query int false "最大页数(0=只第1页)" default(0)
|
||
// @Param all query bool false "是否全量获取"
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Failure 400 {object} map[string]interface{}
|
||
// @Failure 500 {object} map[string]interface{}
|
||
// @Router /category/{code} [get]
|
||
func (h *ContentHandler) CategoryVideos(c *gin.Context) {
|
||
code := c.Param("code")
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
viewtype := c.DefaultQuery("viewtype", "basic")
|
||
maxPages := scraper.ParseMaxPages(c.DefaultQuery("max_pages", "0"))
|
||
allMode := c.Query("all") == "true"
|
||
|
||
valid := false
|
||
for _, cat := range scraper.Categories {
|
||
if cat.Code == code {
|
||
valid = true
|
||
break
|
||
}
|
||
}
|
||
if !valid {
|
||
c.JSON(http.StatusBadRequest, gin.H{
|
||
"code": 1,
|
||
"msg": "无效的分类代码,可用: rf, top, ori, hot, long, longer, tf, hd, md, mf",
|
||
})
|
||
return
|
||
}
|
||
|
||
var result *scraper.CategoryResult
|
||
var err error
|
||
|
||
if allMode || maxPages > 1 {
|
||
result, err = scraper.ExtractCategoryAll(h.categorySession, code, viewtype, maxPages)
|
||
} else {
|
||
result, err = scraper.ExtractCategory(h.categorySession, code, page, viewtype)
|
||
}
|
||
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 1,
|
||
"msg": "提取失败: " + err.Error(),
|
||
})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{"code": 0, "data": result})
|
||
}
|
||
|
||
// AuthorVideos 作者视频列表
|
||
// @Summary 作者视频列表
|
||
// @Description 获取指定作者的全部视频,支持分页和全量获取
|
||
// @Description 每页8个视频,自动探测总页数
|
||
// @Tags content
|
||
// @Produce json
|
||
// @Param uid path string true "作者 UID"
|
||
// @Param page query int false "页码" default(1)
|
||
// @Param all query bool false "是否全量获取"
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Failure 400 {object} map[string]interface{}
|
||
// @Failure 500 {object} map[string]interface{}
|
||
// @Router /author/{uid} [get]
|
||
func (h *ContentHandler) AuthorVideos(c *gin.Context) {
|
||
uid := c.Param("uid")
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
allMode := c.Query("all") == "true"
|
||
|
||
if uid == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"code": 1, "msg": "请提供作者 UID"})
|
||
return
|
||
}
|
||
|
||
var result *scraper.AuthorResult
|
||
var err error
|
||
|
||
if allMode {
|
||
result, err = scraper.ExtractAuthorAll(h.authorSession, uid)
|
||
} else {
|
||
result, err = scraper.ExtractAuthor(h.authorSession, uid, page)
|
||
}
|
||
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{
|
||
"code": 1,
|
||
"msg": "提取失败: " + err.Error(),
|
||
})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{"code": 0, "data": result})
|
||
}
|