Files
2026-06-10 03:29:17 +00:00

145 lines
4.3 KiB
Go
Raw Permalink 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.
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})
}