From 8d7b845c2f0e6b374346aa32646a394bc8d36a53 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Nov 2026 18:20:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=93=E9=A2=98=20canonical=20URL=20?= =?UTF-8?q?=E7=94=B1=20/list=3FthemeId=3DX=20=E6=94=B9=E4=B8=BA=20/topic/[?= =?UTF-8?q?slug]/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 sitemap 输出和前端规范地址保持一致,避免 canonical 指向会被 301 的旧路径。 Co-Authored-By: Claude Opus 4.7 --- app/service/playletthemeser/theme.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/service/playletthemeser/theme.go b/app/service/playletthemeser/theme.go index 0b9b29b..e54bf08 100644 --- a/app/service/playletthemeser/theme.go +++ b/app/service/playletthemeser/theme.go @@ -2,13 +2,13 @@ package playletthemeser import ( "context" - "strconv" "strings" "videoweb/app/api/proto" "videoweb/app/service/configser" "videoweb/app/service/playletcache" "videoweb/pub/common/netutil" "videoweb/pub/common/srvdef" + "videoweb/pub/common/utils" "videoweb/pub/pubdef" ) @@ -54,11 +54,18 @@ func buildThemeSeoInfo(item *playletcache.ThemeItem) *proto.SeoInfo { if len(custom.Keyworld) > 0 { seo.Keywords = append([]string{}, custom.Keyworld...) } - pagePath := "/list?themeId=" + strconv.FormatInt(item.Id, 10) - seo.CanonicalURL = joinCanonicalURL(seo.CanonicalURL, pagePath) + seo.CanonicalURL = joinCanonicalURL(seo.CanonicalURL, buildThemeCanonicalPath(item.Slug, item.Id)) return &seo } +// buildThemeCanonicalPath 专题详情页规范相对路径(对齐 sitemap /topic/[slug]/,前端 /list?themeId=X 会被 301)。 +func buildThemeCanonicalPath(slug string, id int64) string { + if segment := utils.PathSegment(slug, id); segment != "" { + return "/topic/" + segment + "/" + } + return "/topic/" +} + func normalizeThemeSeoValue(seo pubdef.SeoValue) pubdef.SeoValue { seo.Title = strings.TrimSpace(seo.Title) seo.Description = strings.TrimSpace(seo.Description)