Files
rootandClaude Opus 4.7 85c0071fd8 feat: 从黄果 NET hgdjnet-server 9bfbafe 导入 HKDJ 官网后端
来源: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>
2026-10-16 11:20:04 +08:00

60 lines
1.3 KiB
Go

package seo
import (
"context"
"hkdj-web-server/app/skd/job/sitemap"
"hkdj-web-server/pub/common/log"
"hkdj-web-server/pub/seo/sitemapdirty"
"sync"
"time"
"github.com/robfig/cron/v3"
)
var seoCron *cron.Cron
func init() {
seoCron = cron.New(cron.WithSeconds())
}
var (
dirtyMu sync.Mutex
// generatedDirtyAt 最近一次 sitemap 生成所对应的内容变更时间
generatedDirtyAt time.Time
)
// Start 启动 SEO 静态资源生成(sitemap)。
// 页面级搜索引擎推送由 web 进程的 seopush 任务负责,不在这里处理。
func Start() {
generatedDirtyAt = sitemapdirty.LastDirtyAt(context.Background())
sitemap.StartSitemapJob(6*time.Hour, sitemap.OutputDir)
// 短剧发布/更新/下架发生在 web 进程,这里检查它留下的变更标记,有变更才重新生成
_, _ = seoCron.AddFunc("0 */2 * * * ?", func() {
regenerateSitemapIfDirty()
})
seoCron.Start()
log.Info("seo skd started")
}
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))
sitemap.GenerateSitemap()
generatedDirtyAt = dirtyAt
}
func Stop() {
if seoCron != nil {
seoCron.Stop()
}
}