339 lines
10 KiB
Go
339 lines
10 KiB
Go
package web
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"videoweb/app/service/authser"
|
|
"videoweb/app/service/playletser"
|
|
"videoweb/app/service/videoser"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/common/useragent"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type favoriteWork struct {
|
|
ID int64
|
|
Title string
|
|
Genre string
|
|
DesktopMeta string
|
|
Episodes string
|
|
Badge string
|
|
Image string
|
|
Kind string
|
|
URL string
|
|
DramaID int64
|
|
Episode int
|
|
VideoID int64
|
|
TotalEpisode int
|
|
}
|
|
|
|
// Favorites 我的收藏:短剧 / 剧集(视频) / 章节收藏。
|
|
// 文档:
|
|
// http://172.104.181.99:25319/swagger/index.html#/app短剧相关接口/get_api_app_playlet_collect_list
|
|
// http://172.104.181.99:25319/swagger/index.html#/视频相关接口/get_api_app_video_collect_list
|
|
func Favorites(c *gin.Context) {
|
|
filter, page, validRoute := favoritesRoute(c)
|
|
if !validRoute {
|
|
NotFound(c)
|
|
return
|
|
}
|
|
|
|
data := gin.H{"title": "我的收藏 - 黄果短剧", "navActive": "favorites", "accountTab": "favorites"}
|
|
responses := gin.H{}
|
|
loadAccountSummary(c, data, responses)
|
|
|
|
status := 0
|
|
switch filter {
|
|
case "short", "chapter", "series":
|
|
case "following":
|
|
status = 1
|
|
case "finished":
|
|
status = 2
|
|
default:
|
|
filter = "all"
|
|
}
|
|
data["filter"] = filter
|
|
|
|
pageSize := 12
|
|
query := playletser.CollectListQuery{PageNum: page, PageSize: pageSize, WatchStatus: status}
|
|
|
|
if useragent.TokenFromRequest(c.Request) == "" {
|
|
responses["playlet/collect/list"] = gin.H{"error": "暂无登录会话"}
|
|
responses["video/collect/list"] = gin.H{"error": "暂无登录会话"}
|
|
data["favoritesResponse"] = responses["playlet/collect/list"]
|
|
data["playletCollectResponse"] = responses["playlet/collect/list"]
|
|
data["videoCollectResponse"] = responses["video/collect/list"]
|
|
data["favoritesDebug"] = responses
|
|
renderFavorites(c, data)
|
|
return
|
|
}
|
|
|
|
if filter == "chapter" {
|
|
list, code, err := playletser.FetchChapterCollectList(c, query)
|
|
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
|
list, _, err = playletser.FetchChapterCollectList(c, query)
|
|
}
|
|
if err != nil {
|
|
log.Error("fetch chapter favorites page failed", log.E(err))
|
|
responses["playlet/chapter/collect/list"] = gin.H{"error": "加载失败", "msg": err.Error()}
|
|
data["favoritesUnavailable"] = true
|
|
} else if list != nil {
|
|
responses["playlet/chapter/collect/list"] = gin.H{"code": 200, "data": list}
|
|
data["paging"] = makeFavoritesPage(query.PageNum, query.PageSize, list.TotalCount, filter)
|
|
data["favorites"] = chapterFavoriteWorks(list.List)
|
|
} else {
|
|
responses["playlet/chapter/collect/list"] = gin.H{"code": code, "data": list}
|
|
}
|
|
data["favoritesResponse"] = responses["playlet/chapter/collect/list"]
|
|
data["playletCollectResponse"] = responses["playlet/chapter/collect/list"]
|
|
data["favoritesDebug"] = responses
|
|
renderFavorites(c, data)
|
|
return
|
|
}
|
|
|
|
if filter == "series" {
|
|
loadVideoFavorites(c, data, responses, page, pageSize)
|
|
data["favoritesResponse"] = responses["video/collect/list"]
|
|
data["playletCollectResponse"] = gin.H{}
|
|
data["videoCollectResponse"] = responses["video/collect/list"]
|
|
data["favoritesDebug"] = responses
|
|
renderFavorites(c, data)
|
|
return
|
|
}
|
|
|
|
var works []favoriteWork
|
|
var totalCount int64
|
|
playletFailed := false
|
|
videoFailed := false
|
|
|
|
if filter == "all" || filter == "short" || filter == "following" || filter == "finished" {
|
|
list, code, err := playletser.FetchCollectList(c, query)
|
|
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
|
list, code, err = playletser.FetchCollectList(c, query)
|
|
}
|
|
if err == nil && list != nil {
|
|
responses["playlet/collect/list"] = gin.H{"code": 200, "data": list}
|
|
works = append(works, playletFavoriteWorks(list.List)...)
|
|
totalCount += list.TotalCount
|
|
} else if err != nil {
|
|
responses["playlet/collect/list"] = gin.H{"error": "加载失败", "msg": err.Error()}
|
|
log.Error("fetch favorites page failed", log.E(err))
|
|
playletFailed = true
|
|
} else {
|
|
responses["playlet/collect/list"] = gin.H{"code": code, "data": list}
|
|
}
|
|
}
|
|
|
|
if filter == "all" {
|
|
videoQuery := videoser.CollectListQuery{PageNum: page, PageSize: pageSize}
|
|
videoList, videoCode, videoErr := videoser.FetchCollectList(c, videoQuery)
|
|
if retry, _ := authser.OnSessionExpired(c, videoCode); retry {
|
|
videoList, videoCode, videoErr = videoser.FetchCollectList(c, videoQuery)
|
|
}
|
|
if videoErr == nil && videoList != nil {
|
|
responses["video/collect/list"] = gin.H{"code": 200, "data": videoList}
|
|
works = append(works, videoFavoriteWorks(videoList.List)...)
|
|
totalCount += videoList.TotalCount
|
|
} else if videoErr != nil {
|
|
responses["video/collect/list"] = gin.H{"error": "加载失败", "msg": videoErr.Error()}
|
|
log.Error("fetch video favorites page failed", log.E(videoErr))
|
|
videoFailed = true
|
|
} else {
|
|
responses["video/collect/list"] = gin.H{"code": videoCode, "data": videoList}
|
|
}
|
|
}
|
|
|
|
if playletFailed && (filter != "all" || videoFailed) {
|
|
data["favoritesUnavailable"] = true
|
|
}
|
|
if filter == "all" && playletFailed && videoFailed {
|
|
data["favoritesUnavailable"] = true
|
|
}
|
|
|
|
data["paging"] = makeFavoritesPage(page, pageSize, totalCount, filter)
|
|
data["favorites"] = works
|
|
data["favoritesResponse"] = responses["playlet/collect/list"]
|
|
data["playletCollectResponse"] = responses["playlet/collect/list"]
|
|
data["videoCollectResponse"] = responses["video/collect/list"]
|
|
data["favoritesDebug"] = responses
|
|
renderFavorites(c, data)
|
|
}
|
|
|
|
// renderFavorites 收藏为空时附带「大家都在看」后渲染。
|
|
func renderFavorites(c *gin.Context, data gin.H) {
|
|
attachFavoritesRecommended(c, data)
|
|
HTMLOK(c, "favorites.html", data)
|
|
}
|
|
|
|
// attachFavoritesRecommended 列表为空时拉取最热短剧(与搜索无结果一致)。
|
|
// 上游:GET /api/app/playlet/all/list sortType=2
|
|
func attachFavoritesRecommended(c *gin.Context, data gin.H) {
|
|
if works, ok := data["favorites"].([]favoriteWork); ok && len(works) > 0 {
|
|
return
|
|
}
|
|
watchingQ := playletser.AllListQuery{
|
|
PageNum: 1,
|
|
PageSize: 6,
|
|
SortType: 2, // 最热
|
|
UpdateStatus: 0,
|
|
}
|
|
watching := playletser.FetchAllListOrEmpty(c, watchingQ)
|
|
if watching == nil || len(watching.List) == 0 {
|
|
return
|
|
}
|
|
list := watching.List
|
|
if len(list) > 6 {
|
|
list = list[:6]
|
|
}
|
|
data["recommended"] = list
|
|
}
|
|
|
|
func loadVideoFavorites(c *gin.Context, data gin.H, responses gin.H, page, pageSize int) {
|
|
videoQuery := videoser.CollectListQuery{PageNum: page, PageSize: pageSize}
|
|
list, code, err := videoser.FetchCollectList(c, videoQuery)
|
|
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
|
list, code, err = videoser.FetchCollectList(c, videoQuery)
|
|
}
|
|
if err != nil {
|
|
log.Error("fetch video favorites page failed", log.E(err))
|
|
responses["video/collect/list"] = gin.H{"error": "加载失败", "msg": err.Error()}
|
|
data["favoritesUnavailable"] = true
|
|
return
|
|
}
|
|
if list == nil {
|
|
responses["video/collect/list"] = gin.H{"code": code, "data": list}
|
|
return
|
|
}
|
|
responses["video/collect/list"] = gin.H{"code": 200, "data": list}
|
|
data["paging"] = makeFavoritesPage(page, pageSize, list.TotalCount, "series")
|
|
data["favorites"] = videoFavoriteWorks(list.List)
|
|
}
|
|
|
|
func favoritesRoute(c *gin.Context) (filter string, page int, valid bool) {
|
|
if c.Request.URL.Query().Has("filter") {
|
|
return "", 0, false
|
|
}
|
|
filter = strings.TrimSpace(c.Param("filter"))
|
|
switch filter {
|
|
case "":
|
|
filter = "all"
|
|
case "short", "chapter", "series", "following", "finished":
|
|
default:
|
|
return "", 0, false
|
|
}
|
|
|
|
page, valid = accountPageNum(c)
|
|
if !valid {
|
|
return "", 0, false
|
|
}
|
|
return filter, page, true
|
|
}
|
|
|
|
func favoritesPagePath(filter string, page int) string {
|
|
path := "/favorites"
|
|
if filter != "" && filter != "all" {
|
|
path += "/" + filter
|
|
}
|
|
if page > 1 {
|
|
path += "/page/" + strconv.Itoa(page)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func makeFavoritesPage(page, size int, count int64, filter string) accountPage {
|
|
total := int((count + int64(size) - 1) / int64(size))
|
|
pagination := accountPage{Current: page, Total: total, Count: count}
|
|
if page > 1 {
|
|
pagination.PrevURL = favoritesPagePath(filter, page-1)
|
|
}
|
|
if page < total {
|
|
pagination.NextURL = favoritesPagePath(filter, page+1)
|
|
}
|
|
return pagination
|
|
}
|
|
|
|
func playletFavoriteWorks(items []playletser.PlayletCollectData) []favoriteWork {
|
|
works := make([]favoriteWork, 0, len(items))
|
|
for _, item := range items {
|
|
title := strings.TrimSpace(item.PlayName)
|
|
if title == "" {
|
|
title = strings.TrimSpace(item.Title)
|
|
}
|
|
if title == "" {
|
|
continue
|
|
}
|
|
work := favoriteWork{
|
|
ID: item.ID, Title: title, Genre: strings.Join(item.ThemeNames, " "),
|
|
Image: profileCover(item.Cover), Kind: "short",
|
|
URL: playletser.ChapterPlayPath(item.Slug, item.ID, item.LastChapterID),
|
|
DramaID: item.ID, Episode: item.LastEpisode, VideoID: item.LastChapterID,
|
|
TotalEpisode: item.TotalEpisode,
|
|
}
|
|
if work.Episode <= 0 {
|
|
work.Episode = 1
|
|
}
|
|
if item.TotalEpisode > 0 {
|
|
work.Episodes = fmt.Sprintf("全 %d 集", item.TotalEpisode)
|
|
work.DesktopMeta = work.Episodes
|
|
}
|
|
if item.IsFeatured {
|
|
work.Badge = "爆剧"
|
|
}
|
|
works = append(works, work)
|
|
}
|
|
return works
|
|
}
|
|
|
|
func chapterFavoriteWorks(items []playletser.PlayletChapterCollectData) []favoriteWork {
|
|
works := make([]favoriteWork, 0, len(items))
|
|
for _, item := range items {
|
|
title := strings.TrimSpace(item.PlayletTitle)
|
|
if title == "" {
|
|
continue
|
|
}
|
|
work := favoriteWork{
|
|
ID: item.ChapterID, Title: title, Image: profileCover(item.PlayletCover), Kind: "chapter",
|
|
URL: playletser.ChapterPlayPath(item.PlayletSlug, item.PlayletID, item.ChapterID), DesktopMeta: item.ChapterTitle,
|
|
DramaID: item.PlayletID, Episode: item.CurrentEpisode, VideoID: item.ChapterID,
|
|
TotalEpisode: item.TotalEpisode,
|
|
}
|
|
if work.Episode <= 0 {
|
|
work.Episode = 1
|
|
}
|
|
if item.CurrentEpisode > 0 {
|
|
work.Genre = fmt.Sprintf("第 %d 集", item.CurrentEpisode)
|
|
}
|
|
if item.TotalEpisode > 0 {
|
|
work.Episodes = fmt.Sprintf("全 %d 集", item.TotalEpisode)
|
|
}
|
|
works = append(works, work)
|
|
}
|
|
return works
|
|
}
|
|
|
|
func videoFavoriteWorks(items []videoser.VideoCollectData) []favoriteWork {
|
|
works := make([]favoriteWork, 0, len(items))
|
|
for _, item := range items {
|
|
title := strings.TrimSpace(item.Title)
|
|
if title == "" {
|
|
continue
|
|
}
|
|
work := favoriteWork{
|
|
ID: item.ID, Title: title, Genre: strings.Join(item.Keyworld, " "),
|
|
Image: profileCover(item.CoverImg), Kind: "series",
|
|
URL: videoser.VideoPlayURL(item.Slug, item.ID),
|
|
}
|
|
if item.VideoTime > 0 {
|
|
work.Episodes = formatVideoDuration(item.VideoTime)
|
|
work.DesktopMeta = work.Episodes
|
|
} else {
|
|
work.Episodes = "剧集"
|
|
work.DesktopMeta = "剧集"
|
|
}
|
|
works = append(works, work)
|
|
}
|
|
return works
|
|
}
|