Initial commit: web_hghl_server

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 16:28:14 +08:00
co-authored by Claude Opus 4.7
commit 65fca60622
653 changed files with 135901 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
package seo
import (
"context"
"path/filepath"
"strings"
"sync"
"time"
"videoweb/app/service/configser"
"videoweb/app/skd/job/dhsitemap"
"videoweb/app/skd/job/llmstxt"
"videoweb/app/skd/job/rss"
"videoweb/app/skd/job/sitemap"
"videoweb/pub/common/log"
"videoweb/pub/seo/sitemapdirty"
"github.com/robfig/cron/v3"
)
const (
// h5OutputDir 站点地图写在 h5 根目录,不进 public。
// 样式表仍由前端 public/static 提供,XML 里引用 /static/sitemap*.xsl。
h5OutputDir = "../h5"
pageTemplateOutputDir = "../h5/templates/page"
)
var seoCron *cron.Cron
func init() {
seoCron = cron.New(cron.WithSeconds())
}
var (
dirtyMu sync.Mutex
// generatedDirtyAt 最近一次 sitemap 生成所对应的内容变更时间
generatedDirtyAt time.Time
)
// Start 启动 SEO 静态资源生成(sitemap / RSS / llms.txt / dhsitemap)定时任务。
// 页面级搜索引擎推送由 web 进程的 seopush 任务负责,不在这里处理。
func Start() {
generatedDirtyAt = sitemapdirty.LastDirtyAt(context.Background())
go generateSitemapFiles(context.Background())
go dhsitemap.GenerateDHSitemap()
go llmstxt.GenerateLLMSTxt(pageTemplateOutputDir)
_, _ = seoCron.AddFunc("0 0 */6 * * ?", func() {
generateSitemapFiles(context.Background())
dhsitemap.GenerateDHSitemap()
llmstxt.GenerateLLMSTxt(pageTemplateOutputDir)
})
// 短剧/视频等发布发生在 web 进程,这里检查它留下的变更标记,有变更才重新生成
_, _ = seoCron.AddFunc("0 */2 * * * ?", func() {
regenerateSitemapIfDirty()
})
seoCron.Start()
log.Info("seo skd started")
}
func generateSitemapFiles(ctx context.Context) {
config, serr := configser.GetSystemConfig(ctx)
if serr != nil || config == nil {
log.Error("gen sitemap GetSystemConfig failed", log.Any("err", serr))
return
}
webAddr := strings.TrimSpace(config.WebAddr)
if webAddr == "" {
log.Error("gen sitemap WebAddr empty")
return
}
generator := sitemap.NewSitemapGenerator(webAddr, filepath.Join(h5OutputDir, "sitemaps"))
generator.IndexFile = filepath.Join(h5OutputDir, "sitemap.xml")
if err := generator.Generate(); err != nil {
log.Error("gen sitemap.xml err", log.E(err))
return
}
rss.GenerateRSS(ctx, pageTemplateOutputDir)
}
func regenerateSitemapIfDirty() {
if !dirtyMu.TryLock() {
return
}
defer dirtyMu.Unlock()
dirtyAt := sitemapdirty.LastDirtyAt(context.Background())
if dirtyAt.IsZero() || !dirtyAt.After(generatedDirtyAt) {
return
}
log.Info("seo: content changed, regenerate sitemap", log.Any("dirtyAt", dirtyAt))
generateSitemapFiles(context.Background())
dhsitemap.GenerateDHSitemap()
llmstxt.GenerateLLMSTxt(pageTemplateOutputDir)
generatedDirtyAt = dirtyAt
}
func Stop() {
if seoCron != nil {
seoCron.Stop()
}
}