Files
web_huangguo2_h5/app/service/playletser/search.go
T
谢宇宁andClaude Opus 5.5 0fbdba5ccf Initial commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:47:47 +07:00

177 lines
4.9 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.
package playletser
import (
"fmt"
"net/url"
"strconv"
"strings"
"videoweb/app/service/authser"
"videoweb/app/service/upstream"
"videoweb/pub/common/log"
"github.com/gin-gonic/gin"
)
const (
searchPath = "/api/app/playlet/search"
searchSuggestPath = "/api/app/playlet/search/suggest"
defaultSearchPageSize = 25
)
// SearchQuery 搜索分页参数(上游 query:keyword / pageNum / pageSize)。
type SearchQuery struct {
Keyword string
PageNum int
PageSize int
}
// Normalize 校正分页默认值。
func (q *SearchQuery) Normalize() {
q.Keyword = strings.TrimSpace(q.Keyword)
if q.PageNum <= 0 {
q.PageNum = 1
}
if q.PageSize <= 0 {
q.PageSize = defaultSearchPageSize
}
if q.PageSize > 50 {
q.PageSize = 50
}
}
// FetchSearch ES 分页搜索短剧。
// 文档:GET /api/app/playlet/search → proto.PlayletSearchResp
func FetchSearch(c *gin.Context, q SearchQuery) (*PlayletSearchResp, error) {
q.Normalize()
if q.Keyword == "" {
return nil, fmt.Errorf("playlet search keyword is empty")
}
authser.EnsureGuestOnEnter(c)
env, err := fetchSearchOnce(c, q)
if err != nil {
return nil, err
}
if env.Code != 200 && authser.IsSessionExpiredCode(env.Code) {
if authser.RecoverContentSession(c, env.Code) {
env, err = fetchSearchOnce(c, q)
if err != nil {
return nil, err
}
}
}
if env.Code != 200 {
return nil, fmt.Errorf("playlet search code=%d msg=%s tip=%s", env.Code, env.Msg, env.Tip)
}
return &env.Data, nil
}
func fetchSearchOnce(c *gin.Context, q SearchQuery) (*APIEnvelope[PlayletSearchResp], error) {
params := url.Values{}
params.Set("pageNum", strconv.Itoa(q.PageNum))
params.Set("pageSize", strconv.Itoa(q.PageSize))
params.Set("keyword", q.Keyword)
var env APIEnvelope[PlayletSearchResp]
if err := upstream.GetJSON(c, searchPath+"?"+params.Encode(), &env); err != nil {
return nil, err
}
return &env, nil
}
// FetchSearchOrEmpty 失败时返回空列表。
func FetchSearchOrEmpty(c *gin.Context, q SearchQuery) *PlayletSearchResp {
data, err := FetchSearch(c, q)
if err != nil {
log.Error("fetch playlet search failed", log.E(err))
return &PlayletSearchResp{Keyword: q.Keyword, PageNum: q.PageNum, PageSize: q.PageSize}
}
if data == nil {
return &PlayletSearchResp{Keyword: q.Keyword, PageNum: q.PageNum, PageSize: q.PageSize}
}
return data
}
// FetchSearchSuggest 搜索框下拉联想。
// 文档:GET /api/app/playlet/search/suggest → proto.PlayletSearchSuggestResp
// http://172.104.181.99:25319/swagger/index.html#/app短剧相关接口/get_api_app_playlet_search_suggest
func FetchSearchSuggest(c *gin.Context, keyword string) (*PlayletSearchSuggestResp, error) {
keyword = strings.TrimSpace(keyword)
if keyword == "" {
return nil, fmt.Errorf("playlet search suggest keyword is empty")
}
authser.EnsureGuestOnEnter(c)
env, err := fetchSearchSuggestOnce(c, keyword)
if err != nil {
return nil, err
}
if env.Code != 200 && authser.IsSessionExpiredCode(env.Code) {
if authser.RecoverContentSession(c, env.Code) {
env, err = fetchSearchSuggestOnce(c, keyword)
if err != nil {
return nil, err
}
}
}
if env.Code != 200 {
return nil, fmt.Errorf("playlet search suggest code=%d msg=%s tip=%s", env.Code, env.Msg, env.Tip)
}
return &env.Data, nil
}
func fetchSearchSuggestOnce(c *gin.Context, keyword string) (*APIEnvelope[PlayletSearchSuggestResp], error) {
params := url.Values{}
params.Set("keyword", keyword)
var env APIEnvelope[PlayletSearchSuggestResp]
if err := upstream.GetJSON(c, searchSuggestPath+"?"+params.Encode(), &env); err != nil {
return nil, err
}
return &env, nil
}
// FetchSearchSuggestOrEmpty 失败时返回空列表。
func FetchSearchSuggestOrEmpty(c *gin.Context, keyword string) *PlayletSearchSuggestResp {
data, err := FetchSearchSuggest(c, keyword)
if err != nil {
log.Error("fetch playlet search suggest failed", log.E(err))
return &PlayletSearchSuggestResp{Keyword: strings.TrimSpace(keyword)}
}
if data == nil {
return &PlayletSearchSuggestResp{Keyword: strings.TrimSpace(keyword)}
}
return data
}
func searchPageURL(keyword string, pageNum int) string {
keyword = strings.TrimSpace(keyword)
if keyword == "" {
return "/search"
}
path := "/search/" + url.PathEscape(keyword)
if pageNum > 1 {
path += "/page/" + strconv.Itoa(pageNum)
}
return path
}
func SearchCanonicalPath(q SearchQuery) string {
q.Normalize()
return searchPageURL(q.Keyword, q.PageNum)
}
// BuildSearchPagination 搜索分页。
func BuildSearchPagination(q SearchQuery, totalCount int64) PaginationVM {
q.Normalize()
return BuildPagination(func(p int) string {
return searchPageURL(q.Keyword, p)
}, q.PageNum, q.PageSize, totalCount)
}
// ParseSearchQuery 从站点 query 解析(q → keyword)。
func ParseSearchQuery(qStr, pageStr string) SearchQuery {
q := SearchQuery{PageSize: defaultSearchPageSize, Keyword: strings.TrimSpace(qStr)}
if n, err := strconv.Atoi(strings.TrimSpace(pageStr)); err == nil {
q.PageNum = n
}
q.Normalize()
return q
}