package playletser import ( "fmt" "net/url" "strconv" "strings" "videoweb/app/service/upstream" "videoweb/pub/common/log" "github.com/gin-gonic/gin" ) const ( listPath = "/api/app/playlet/list" themePath = "/api/app/theme/list" defaultListPageSize = 25 sortHeat = 1 // 热度优先 sortTodayUpdate = 2 // 今日更新 // 站点统一类型:1-非成人 2-成人(与 themeType 一致)。 contentTypeNonAdult = 1 contentTypeAdult = 2 // playlet/list 上游 type 与站点定义相反:1-成人 2-非成人。 upstreamListTypeAdult = 1 upstreamListTypeNonAdult = 2 ) // ListQuery 短剧列表查询参数。 type ListQuery struct { PageNum int PageSize int SortOrder int ThemeID int64 ThemeSlug string Type int } // Normalize 校正分页与排序默认值。 func (q *ListQuery) Normalize() { if q.PageNum <= 0 { q.PageNum = 1 } if q.PageSize <= 0 { q.PageSize = defaultListPageSize } if q.PageSize > 50 { q.PageSize = 50 } if q.SortOrder != sortTodayUpdate { q.SortOrder = sortHeat } if q.ThemeID < 0 { q.ThemeID = 0 } q.Type = normalizeContentType(q.Type) } // FetchList 分页查询已上架短剧。 func FetchList(c *gin.Context, q ListQuery) (*PlayletVideoResp, error) { q.Normalize() params := url.Values{} params.Set("pageNum", strconv.Itoa(q.PageNum)) params.Set("pageSize", strconv.Itoa(q.PageSize)) params.Set("sortOrder", strconv.Itoa(q.SortOrder)) if strings.TrimSpace(q.ThemeSlug) != "" { params.Set("themeSlug", strings.TrimSpace(q.ThemeSlug)) } else if q.ThemeID > 0 { params.Set("themeId", strconv.FormatInt(q.ThemeID, 10)) } else { params.Set("type", strconv.Itoa(listTypeForUpstream(q.Type))) } var env APIEnvelope[PlayletVideoResp] if err := upstream.GetPublicJSON(c, listPath+"?"+params.Encode(), &env); err != nil { return nil, err } if env.Code != 200 { return nil, fmt.Errorf("playlet list code=%d msg=%s", env.Code, env.Msg) } return &env.Data, nil } // FetchListOrEmpty 失败时返回空列表。 func FetchListOrEmpty(c *gin.Context, q ListQuery) *PlayletVideoResp { data, err := FetchList(c, q) if err != nil { log.Error("fetch playlet list failed", log.E(err)) return &PlayletVideoResp{PageNum: q.PageNum, PageSize: q.PageSize} } if data == nil { return &PlayletVideoResp{PageNum: q.PageNum, PageSize: q.PageSize} } data.SeoInfo.Normalize() return data } // FetchThemes 拉取题材列表。 func FetchThemes(c *gin.Context, contentType int) ([]PlayletThemeItem, error) { contentType = normalizeContentType(contentType) params := url.Values{} params.Set("themeType", strconv.Itoa(contentType)) var env APIEnvelope[PlayletThemeListResponse] if err := upstream.GetPublicJSON(c, themePath+"?"+params.Encode(), &env); err != nil { return nil, err } if env.Code != 200 { return nil, fmt.Errorf("theme list code=%d msg=%s", env.Code, env.Msg) } return env.Data.List, nil } // FetchThemesOrEmpty 失败时返回空题材。 func FetchThemesOrEmpty(c *gin.Context, contentType int) []PlayletThemeItem { list, err := FetchThemes(c, contentType) if err != nil { log.Error("fetch theme list failed", log.E(err)) return nil } return list } func normalizeContentType(contentType int) int { if contentType == contentTypeAdult { return contentTypeAdult } return contentTypeNonAdult } // listTypeForUpstream 将站点统一类型转为 playlet/list 的 type(该接口 1=成人 2=非成人)。 func listTypeForUpstream(contentType int) int { if normalizeContentType(contentType) == contentTypeAdult { return upstreamListTypeAdult } return upstreamListTypeNonAdult }