125 lines
3.1 KiB
Go
125 lines
3.1 KiB
Go
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"
|
|
defaultSearchPageSize = 25
|
|
)
|
|
|
|
// SearchQuery 搜索分页参数(keyword 对应上游 query)。
|
|
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 分页搜索短剧。
|
|
func FetchSearch(c *gin.Context, q SearchQuery) (*PlayletVideoResp, 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[PlayletVideoResp], 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[PlayletVideoResp]
|
|
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) *PlayletVideoResp {
|
|
data, err := FetchSearch(c, q)
|
|
if err != nil {
|
|
log.Error("fetch playlet search failed", log.E(err))
|
|
return &PlayletVideoResp{PageNum: q.PageNum, PageSize: q.PageSize}
|
|
}
|
|
if data == nil {
|
|
return &PlayletVideoResp{PageNum: q.PageNum, PageSize: q.PageSize}
|
|
}
|
|
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
|
|
}
|