删除福利应用
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
package applistser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"videoweb/app/service/upstream"
|
||||
"videoweb/pub/common/log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const listPath = "/api/app/applist/list"
|
||||
|
||||
// FetchList 拉取应用分类列表。categoryId=0 表示默认。
|
||||
func FetchList(c *gin.Context, categoryID int64) (*AppListResp, error) {
|
||||
path := fmt.Sprintf("%s?categoryId=%d", listPath, categoryID)
|
||||
var env APIEnvelope[AppListResp]
|
||||
if err := upstream.GetPublicJSON(c, path, &env); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if env.Code != 200 {
|
||||
return nil, fmt.Errorf("applist code=%d msg=%s", env.Code, env.Msg)
|
||||
}
|
||||
return &env.Data, nil
|
||||
}
|
||||
|
||||
// FetchListOrEmpty 失败时返回空结构,保证 SSR 可渲染。
|
||||
func FetchListOrEmpty(c *gin.Context, categoryID int64) *AppListResp {
|
||||
data, err := FetchList(c, categoryID)
|
||||
if err != nil {
|
||||
log.Error("fetch applist failed", log.E(err))
|
||||
return &AppListResp{}
|
||||
}
|
||||
if data == nil {
|
||||
return &AppListResp{}
|
||||
}
|
||||
return data
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package applistser
|
||||
|
||||
// AppListResp 对应 swagger proto.AppListResp 的业务字段(忽略无关 config/advitise)。
|
||||
type AppListResp struct {
|
||||
Category AppCategoryInfo `json:"category"`
|
||||
CategoryList []AppCategoryInfo `json:"categoryList"`
|
||||
}
|
||||
|
||||
// AppCategoryInfo 对应 swagger proto.AppCategoryInfo
|
||||
type AppCategoryInfo struct {
|
||||
ID int64 `json:"id"`
|
||||
Code int `json:"code"`
|
||||
Title string `json:"title"`
|
||||
Intro string `json:"intro"`
|
||||
Sort int `json:"sort"`
|
||||
AppList []AppInfoData `json:"appList"`
|
||||
}
|
||||
|
||||
// AppInfoData 对应 swagger proto.AppInfoData
|
||||
type AppInfoData struct {
|
||||
ID int64 `json:"id"`
|
||||
CategoryID int64 `json:"categoryId"`
|
||||
Name string `json:"name"`
|
||||
Intro string `json:"intro"`
|
||||
Description string `json:"description"`
|
||||
Logo string `json:"logo"`
|
||||
URL string `json:"url"`
|
||||
Sort int `json:"sort"`
|
||||
AdvitiseID string `json:"advitiseId"`
|
||||
Location int `json:"location"`
|
||||
}
|
||||
|
||||
// APIEnvelope 上游统一响应壳
|
||||
type APIEnvelope[T any] struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data T `json:"data"`
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package applistser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PageVM 福利应用页模板数据
|
||||
type PageVM struct {
|
||||
Categories []CategoryVM
|
||||
}
|
||||
|
||||
type CategoryVM struct {
|
||||
ID int64
|
||||
SectionID string
|
||||
Title string
|
||||
Intro string
|
||||
Total int
|
||||
Apps []AppCardVM
|
||||
IsFirst bool
|
||||
}
|
||||
|
||||
type AppCardVM struct {
|
||||
ID int64
|
||||
Name string
|
||||
Intro string
|
||||
Logo string
|
||||
URL string
|
||||
}
|
||||
|
||||
// BuildPageVM 按接口返回的 categoryList / appList 顺序组装页面数据,不做二次排序。
|
||||
func BuildPageVM(data *AppListResp) PageVM {
|
||||
vm := PageVM{Categories: []CategoryVM{}}
|
||||
if data == nil {
|
||||
return vm
|
||||
}
|
||||
list := data.CategoryList
|
||||
if len(list) == 0 && data.Category.ID > 0 {
|
||||
list = []AppCategoryInfo{data.Category}
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return vm
|
||||
}
|
||||
|
||||
for i, cat := range list {
|
||||
cards := make([]AppCardVM, 0, len(cat.AppList))
|
||||
for _, app := range cat.AppList {
|
||||
name := strings.TrimSpace(app.Name)
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
href := strings.TrimSpace(app.URL)
|
||||
if href == "" {
|
||||
href = "#"
|
||||
}
|
||||
intro := strings.TrimSpace(app.Intro)
|
||||
if intro == "" {
|
||||
intro = strings.TrimSpace(app.Description)
|
||||
}
|
||||
cards = append(cards, AppCardVM{
|
||||
ID: app.ID,
|
||||
Name: name,
|
||||
Intro: intro,
|
||||
Logo: strings.TrimSpace(app.Logo),
|
||||
URL: href,
|
||||
})
|
||||
}
|
||||
title := strings.TrimSpace(cat.Title)
|
||||
if title == "" {
|
||||
title = "应用分类"
|
||||
}
|
||||
vm.Categories = append(vm.Categories, CategoryVM{
|
||||
ID: cat.ID,
|
||||
SectionID: fmt.Sprintf("app-category-%d", cat.ID),
|
||||
Title: title,
|
||||
Intro: strings.TrimSpace(cat.Intro),
|
||||
Total: len(cards),
|
||||
Apps: cards,
|
||||
IsFirst: i == 0,
|
||||
})
|
||||
}
|
||||
return vm
|
||||
}
|
||||
@@ -20,7 +20,7 @@ func IsIndexablePath(raw string) bool {
|
||||
}
|
||||
switch path {
|
||||
case "/list", "/series", "/rank", "/today-update", "/topic", "/tag", "/category",
|
||||
"/download-app", "/application", "/home-road", "/detail", "/play", "/nav",
|
||||
"/download-app", "/home-road", "/detail", "/play", "/nav",
|
||||
"/about-us", "/aboutUs", "/help-center", "/helpCenter":
|
||||
return true
|
||||
default:
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"videoweb/app/service/applistser"
|
||||
"videoweb/app/service/configser"
|
||||
"videoweb/app/service/playletser"
|
||||
)
|
||||
@@ -410,7 +409,7 @@ func isCollectionPath(path string) bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return path == "/application" || path == "/nav"
|
||||
return path == "/nav"
|
||||
}
|
||||
|
||||
// itemListNode 为首页及列表型页面输出当前 SSR 首屏实际展示的站内详情链接。
|
||||
@@ -449,19 +448,6 @@ func itemListNode(siteURL, pageURL string, data map[string]any) ldThing {
|
||||
urls = append(urls, AbsURL(siteURL, path))
|
||||
}
|
||||
}
|
||||
// 福利应用页是一个可见的应用集合;使用页面实际渲染的链接生成通用
|
||||
// Schema.org ItemList。应用链接为外站落地页,因此不宣称具备 Google
|
||||
// 站内轮播资格,只帮助搜索引擎理解页面集合语义。
|
||||
if categories, ok := data["categories"].([]applistser.CategoryVM); ok {
|
||||
for _, category := range categories {
|
||||
for _, app := range category.Apps {
|
||||
appURL := structuredURL(siteURL, app.URL)
|
||||
if appURL != "" {
|
||||
urls = append(urls, appURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
seen := make(map[string]struct{}, len(urls))
|
||||
unique := make([]string, 0, len(urls))
|
||||
@@ -587,7 +573,7 @@ func genericBreadcrumb(siteURL, pageURL string, data map[string]any) ldThing {
|
||||
}
|
||||
|
||||
func hasVisibleBreadcrumb(path string) bool {
|
||||
for _, prefix := range []string{"/list", "/series", "/rank", "/today-update", "/topic", "/tag", "/category", "/richtext", "/application"} {
|
||||
for _, prefix := range []string{"/list", "/series", "/rank", "/today-update", "/topic", "/tag", "/category", "/richtext"} {
|
||||
if path == prefix || strings.HasPrefix(path, prefix+"/") {
|
||||
return true
|
||||
}
|
||||
@@ -668,8 +654,6 @@ func pageDescription(data map[string]any, cfg configser.AppConfigVM, path string
|
||||
}
|
||||
}
|
||||
switch path {
|
||||
case "/application":
|
||||
return "黄果短剧福利应用中心,精选实用应用与福利入口。"
|
||||
case "/download-app":
|
||||
return "下载黄果短剧APP,随时随地追看热门短剧。"
|
||||
case "/home-road":
|
||||
|
||||
@@ -39,8 +39,6 @@ func ResolveNavigationActiveKey(activeKey, requestPath string) string {
|
||||
return "todayUpdate"
|
||||
case strings.HasPrefix(path, "/category/"):
|
||||
return "category"
|
||||
case path == "/application" || strings.HasPrefix(path, "/application/"):
|
||||
return "application"
|
||||
case path == "/home-road" || strings.HasPrefix(path, "/home-road/"):
|
||||
return "homeRoad"
|
||||
case path == "/list" || strings.HasPrefix(path, "/detail/") || strings.HasPrefix(path, "/play/") || path == "/more" || strings.HasPrefix(path, "/more/") || path == "/search" || strings.HasPrefix(path, "/search/"):
|
||||
@@ -91,7 +89,6 @@ func DefaultHeaderNav() []HeaderNavItemVM {
|
||||
{Name: "回家的路", Href: "/home-road/", Key: "homeRoad"},
|
||||
{Name: "今日更新", Href: "/today-update/", Key: "todayUpdate"},
|
||||
{Name: "下载APP", Href: "javascript:;", Key: "downloadApp", IsDownload: true},
|
||||
{Name: "福利应用", Href: "/application/", Key: "application"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +114,10 @@ func BuildHeaderNav(info *AppTranslationInfo) []HeaderNavItemVM {
|
||||
SeoInfo: normalizeNavigationSEO(cat.SeoInfo),
|
||||
}
|
||||
href, external, download := normalizeNavURL(cat.URLValue, name)
|
||||
// 福利应用页已下线,后台残留的导航项不再展示
|
||||
if !external && normalizeNavPath(href) == "/application" {
|
||||
continue
|
||||
}
|
||||
item.Href = href
|
||||
item.IsExternal = external
|
||||
item.IsDownload = download
|
||||
@@ -270,8 +271,6 @@ func navActiveKey(href, name string, download bool) string {
|
||||
return "rank"
|
||||
case "/today-update":
|
||||
return "todayUpdate"
|
||||
case "/application":
|
||||
return "application"
|
||||
case "/tag":
|
||||
return "tagList"
|
||||
case "/topic":
|
||||
|
||||
@@ -13,7 +13,6 @@ func TestResolveNavigationActiveKey(t *testing.T) {
|
||||
"/topic/editor-picks/page/2": "topic",
|
||||
"/rank/2/page/3": "rank",
|
||||
"/category/latest-video/": "category",
|
||||
"/application": "application",
|
||||
"/home-road": "homeRoad",
|
||||
"/detail/example-playlet": "list",
|
||||
"/play/example-playlet/chapter-1": "list",
|
||||
@@ -81,3 +80,13 @@ func TestNormalizeNavURLKeepsConfiguredURL(t *testing.T) {
|
||||
t.Fatalf("normalizeNavURL configured download URL = (%q, %v, %v)", href, external, download)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildHeaderNavSkipsApplication(t *testing.T) {
|
||||
items := BuildHeaderNav(&AppTranslationInfo{CategoryList: []TranslationCategory{
|
||||
{Name: "排行榜", URLValue: "/rank/", CategoryType: 1},
|
||||
{Name: "福利应用", URLValue: "/application/", CategoryType: 1},
|
||||
}})
|
||||
if len(items) != 1 || items[0].Href != "/rank/" {
|
||||
t.Fatalf("BuildHeaderNav = %+v, want only /rank/", items)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user