@@ -0,0 +1,229 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"videoweb/app/service/authser"
|
||||
"videoweb/app/service/playletser"
|
||||
"videoweb/app/service/usercenterser"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/useragent"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type profileWork struct {
|
||||
Title, Meta, Episodes, Badge, Image, Progress, Remaining, URL string
|
||||
}
|
||||
|
||||
// Profile 从当前会话拉取用户信息、观看历史和收藏,不展示演示账号数据。
|
||||
func Profile(c *gin.Context) {
|
||||
data := gin.H{
|
||||
"title": "个人中心 - 黄果短剧", "navActive": "profile", "accountTab": "profile",
|
||||
}
|
||||
responses := gin.H{}
|
||||
loadAccountSummary(c, data, responses)
|
||||
if useragent.TokenFromRequest(c.Request) != "" {
|
||||
fetchProfileLists(c, data, responses)
|
||||
}
|
||||
if pretty, err := json.MarshalIndent(responses, "", " "); err == nil {
|
||||
data["responseJSON"] = string(pretty)
|
||||
}
|
||||
HTMLOK(c, "profile.html", data)
|
||||
}
|
||||
|
||||
func loadAccountSummary(c *gin.Context, data, responses gin.H) {
|
||||
data["userName"] = "未登录"
|
||||
data["balance"] = "—"
|
||||
data["historyCount"] = "—"
|
||||
data["favoriteCount"] = "—"
|
||||
data["chasingCount"] = "—"
|
||||
data["boughtChapterCount"] = "—"
|
||||
user := authser.SyncUserOnEnter(c)
|
||||
if user == nil {
|
||||
if useragent.TokenFromRequest(c.Request) != "" {
|
||||
responses["auth/getInfo"] = gin.H{"error": "加载失败"}
|
||||
fetchProfileStats(c, data, responses)
|
||||
return
|
||||
}
|
||||
responses["auth/getInfo"] = gin.H{"error": "暂无登录会话"}
|
||||
return
|
||||
}
|
||||
applyProfileInfo(data, responses, user)
|
||||
if useragent.TokenFromRequest(c.Request) != "" {
|
||||
fetchProfileStats(c, data, responses)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchProfileStats(c *gin.Context, data, responses gin.H) {
|
||||
stats, code, err := usercenterser.Fetch(c)
|
||||
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
||||
stats, code, err = usercenterser.Fetch(c)
|
||||
}
|
||||
if err != nil || stats == nil {
|
||||
responses["user/center/data"] = gin.H{"error": "加载失败"}
|
||||
if err != nil {
|
||||
log.Error("fetch user center data failed", log.E(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
responses["user/center/data"] = gin.H{"code": code, "data": stats}
|
||||
data["historyCount"] = fmt.Sprint(stats.WatchCount)
|
||||
data["favoriteCount"] = fmt.Sprint(stats.CollectCount)
|
||||
data["chasingCount"] = fmt.Sprint(stats.ChasingCount)
|
||||
data["boughtChapterCount"] = fmt.Sprint(stats.BoughtChapterCount)
|
||||
}
|
||||
|
||||
func fetchProfileLists(c *gin.Context, data, responses gin.H) {
|
||||
query := playletser.HistoryListQuery{PageNum: 1, PageSize: 6}
|
||||
history, code, err := playletser.FetchHistoryList(c, query)
|
||||
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
||||
history, _, err = playletser.FetchHistoryList(c, query)
|
||||
}
|
||||
if err == nil && history != nil {
|
||||
responses["playlet/history/list"] = gin.H{"code": 200, "data": history}
|
||||
data["history"] = profileHistoryWorks(history.List)
|
||||
} else if err != nil {
|
||||
responses["playlet/history/list"] = gin.H{"error": "加载失败"}
|
||||
log.Error("fetch profile history failed", log.E(err))
|
||||
data["historyUnavailable"] = true
|
||||
}
|
||||
|
||||
collectQuery := playletser.CollectListQuery{PageNum: 1, PageSize: 6, WatchStatus: 0}
|
||||
favorites, code, err := playletser.FetchCollectList(c, collectQuery)
|
||||
if retry, _ := authser.OnSessionExpired(c, code); retry {
|
||||
favorites, _, err = playletser.FetchCollectList(c, collectQuery)
|
||||
}
|
||||
if err == nil && favorites != nil {
|
||||
responses["playlet/collect/list"] = gin.H{"code": 200, "data": favorites}
|
||||
data["favorites"] = profileFavoriteWorks(favorites.List)
|
||||
} else if err != nil {
|
||||
responses["playlet/collect/list"] = gin.H{"error": "加载失败"}
|
||||
log.Error("fetch profile favorites failed", log.E(err))
|
||||
data["favoritesUnavailable"] = true
|
||||
}
|
||||
}
|
||||
|
||||
func applyProfileInfo(data, responses gin.H, user *authser.LoginResp) {
|
||||
if user == nil {
|
||||
return
|
||||
}
|
||||
// 登录响应可能包含 token;调试区域只展示非凭证字段。
|
||||
rawUser, _ := json.Marshal(user)
|
||||
var safeUser map[string]any
|
||||
_ = json.Unmarshal(rawUser, &safeUser)
|
||||
delete(safeUser, "token")
|
||||
responses["auth/getInfo"] = gin.H{"code": 200, "data": safeUser}
|
||||
name := strings.TrimSpace(user.NickName)
|
||||
if name == "" {
|
||||
name = strings.TrimSpace(user.AccountNo)
|
||||
}
|
||||
if name == "" {
|
||||
name = "用户"
|
||||
}
|
||||
data["userName"] = name
|
||||
data["setting"] = authser.BuildSettingVM(user)
|
||||
data["userID"] = user.UserID
|
||||
data["userId"] = fmt.Sprint(user.UserID)
|
||||
data["balance"] = fmt.Sprint(user.Recharge)
|
||||
data["recharge"] = user.Recharge
|
||||
data["rechargeText"] = authser.FormatRecharge(user.Recharge)
|
||||
if avatar := safeProfileImage(user.Avatar); avatar != "" {
|
||||
data["avatar"] = avatar
|
||||
}
|
||||
}
|
||||
|
||||
func safeProfileImage(raw string) string {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if strings.HasPrefix(raw, "/static/") {
|
||||
return raw
|
||||
}
|
||||
u, err := url.Parse(raw)
|
||||
if err == nil && (u.Scheme == "https" || u.Scheme == "http") && u.Host != "" {
|
||||
return raw
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func profileHistoryWorks(items []playletser.PlayletHistoryData) []profileWork {
|
||||
works := make([]profileWork, 0, len(items))
|
||||
for _, item := range items {
|
||||
if len(works) == 6 {
|
||||
break
|
||||
}
|
||||
name := strings.TrimSpace(item.Title)
|
||||
if name == "" {
|
||||
name = strings.TrimSpace(item.PlayName)
|
||||
}
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
progress := 0
|
||||
if item.TotalEpisode > 0 {
|
||||
progress = item.WatchedCount * 100 / item.TotalEpisode
|
||||
}
|
||||
if progress < 0 {
|
||||
progress = 0
|
||||
}
|
||||
if progress > 100 {
|
||||
progress = 100
|
||||
}
|
||||
meta := "观看记录"
|
||||
if item.LastEpisode > 0 {
|
||||
meta = fmt.Sprintf("看至第 %d 集", item.LastEpisode)
|
||||
}
|
||||
remaining := ""
|
||||
if item.UnwatchedCount > 0 {
|
||||
remaining = fmt.Sprintf("剩 %d 集", item.UnwatchedCount)
|
||||
}
|
||||
works = append(works, profileWork{Title: name, Meta: meta, Image: profileCover(item.Cover), Progress: fmt.Sprintf("%d%%", progress), Remaining: remaining, URL: profilePlayURL(item.Slug, item.ID, item.LastEpisode)})
|
||||
}
|
||||
return works
|
||||
}
|
||||
|
||||
func profileFavoriteWorks(items []playletser.PlayletCollectData) []profileWork {
|
||||
works := make([]profileWork, 0, len(items))
|
||||
for _, item := range items {
|
||||
if len(works) == 6 {
|
||||
break
|
||||
}
|
||||
name := strings.TrimSpace(item.Title)
|
||||
if name == "" {
|
||||
name = strings.TrimSpace(item.PlayName)
|
||||
}
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
work := profileWork{Title: name, Meta: strings.Join(item.ThemeNames, " "), Image: profileCover(item.Cover), URL: profilePlayURL(item.Slug, item.ID, 1)}
|
||||
if item.TotalEpisode > 0 {
|
||||
work.Episodes = fmt.Sprintf("全 %d 集", item.TotalEpisode)
|
||||
}
|
||||
if item.IsFeatured {
|
||||
work.Badge = "爆剧"
|
||||
}
|
||||
works = append(works, work)
|
||||
}
|
||||
return works
|
||||
}
|
||||
|
||||
func profileCover(raw string) string {
|
||||
if safe := safeProfileImage(raw); safe != "" {
|
||||
return safe
|
||||
}
|
||||
return "/static/images/placeholder.png?v=2"
|
||||
}
|
||||
|
||||
func profilePlayURL(slug string, id int64, episode int) string {
|
||||
if slug == "" {
|
||||
if id <= 0 {
|
||||
return ""
|
||||
}
|
||||
slug = fmt.Sprint(id)
|
||||
}
|
||||
if episode < 1 {
|
||||
episode = 1
|
||||
}
|
||||
return "/play/" + url.PathEscape(slug) + "/" + fmt.Sprint(episode)
|
||||
}
|
||||
Reference in New Issue
Block a user