来源:hgdjnet-server 9bfbafe10d417deea959bd53117bc88a10e60a83 项目身份 HKDJ / JHA-216,独立官网仓库,Jenkins 守卫键 hkdjnet 测试目录 /server/hkdj_net,App/Web API 30331/30332 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
110 lines
3.0 KiB
Go
110 lines
3.0 KiB
Go
package playletthemeser
|
|
|
|
import (
|
|
"context"
|
|
"hkdj-web-server/app/api/proto"
|
|
"hkdj-web-server/app/service/configser"
|
|
"hkdj-web-server/app/service/playletcache"
|
|
"hkdj-web-server/pub/common/netutil"
|
|
"hkdj-web-server/pub/common/srvdef"
|
|
"hkdj-web-server/pub/pubdef"
|
|
"hkdj-web-server/pub/seo/h5path"
|
|
"strings"
|
|
)
|
|
|
|
// List 查询 app 端短剧题材列表(读题材缓存,含 SEO)
|
|
func List(ctx context.Context) (*proto.PlayletThemeListResponse, *srvdef.SrvErr) {
|
|
list := playletcache.ListEnabledThemes()
|
|
imgCdn := configser.GetAppImageCdn(configser.ClientIPFromCtx(ctx))
|
|
items := make([]*proto.PlayletThemeItem, 0, len(list))
|
|
for _, item := range list {
|
|
if item == nil {
|
|
continue
|
|
}
|
|
items = append(items, &proto.PlayletThemeItem{
|
|
Id: item.Id,
|
|
Name: item.Name,
|
|
Slug: item.Slug,
|
|
Icon: mergeThemeIcon(imgCdn, item.Icon),
|
|
Rank: item.Rank,
|
|
Status: item.Status,
|
|
IsRecommend: item.IsRecommend,
|
|
PlayletCount: item.PlayletCount,
|
|
SeoInfo: buildThemeSeoInfo(item),
|
|
})
|
|
}
|
|
return &proto.PlayletThemeListResponse{List: items}, nil
|
|
}
|
|
|
|
// buildThemeSeoInfo 将题材后台 SEO 转为页面 SeoInfo,缺失字段回退题材名/站点默认。
|
|
func buildThemeSeoInfo(item *playletcache.ThemeItem) *proto.SeoInfo {
|
|
seo := configser.GetSiteSeoInfo()
|
|
if item == nil {
|
|
return &seo
|
|
}
|
|
custom := normalizeThemeSeoValue(item.SeoInfo)
|
|
if title := strings.TrimSpace(custom.Title); title != "" {
|
|
seo.Title = title
|
|
} else if name := strings.TrimSpace(item.Name); name != "" {
|
|
seo.Title = name
|
|
}
|
|
if desc := strings.TrimSpace(custom.Description); desc != "" {
|
|
seo.Description = desc
|
|
}
|
|
if len(custom.Keyworld) > 0 {
|
|
seo.Keywords = append([]string{}, custom.Keyworld...)
|
|
}
|
|
pagePath := h5path.ListTheme(item.Slug, item.Id)
|
|
seo.CanonicalURL = joinCanonicalURL(seo.CanonicalURL, pagePath)
|
|
return &seo
|
|
}
|
|
|
|
func normalizeThemeSeoValue(seo pubdef.SeoValue) pubdef.SeoValue {
|
|
seo.Title = strings.TrimSpace(seo.Title)
|
|
seo.Description = strings.TrimSpace(seo.Description)
|
|
if seo.Keyworld == nil {
|
|
seo.Keyworld = make([]string, 0)
|
|
return seo
|
|
}
|
|
words := make([]string, 0, len(seo.Keyworld))
|
|
for _, word := range seo.Keyworld {
|
|
word = strings.TrimSpace(word)
|
|
if word == "" {
|
|
continue
|
|
}
|
|
words = append(words, word)
|
|
}
|
|
seo.Keyworld = words
|
|
return seo
|
|
}
|
|
|
|
func joinCanonicalURL(baseURL, pagePath string) string {
|
|
pagePath = strings.TrimSpace(pagePath)
|
|
if pagePath == "" {
|
|
return strings.TrimSpace(baseURL)
|
|
}
|
|
if !strings.HasPrefix(pagePath, "/") {
|
|
pagePath = "/" + pagePath
|
|
}
|
|
baseURL = strings.TrimSpace(baseURL)
|
|
if baseURL == "" {
|
|
return pagePath
|
|
}
|
|
return strings.TrimRight(baseURL, "/") + pagePath
|
|
}
|
|
|
|
// mergeThemeIcon 给题材图标拼接图片域名
|
|
func mergeThemeIcon(imgCdn string, icon string) string {
|
|
icon = strings.TrimSpace(icon)
|
|
if icon == "" {
|
|
return ""
|
|
}
|
|
if strings.HasPrefix(icon, "http://") || strings.HasPrefix(icon, "https://") {
|
|
return icon
|
|
}
|
|
if imgCdn == "" {
|
|
return icon
|
|
}
|
|
return netutil.MergeURL(imgCdn, icon)
|
|
}
|