Files
jiang13-bbs/backend/handler/seo.go
freefire 996a870015 feat: 新增站点公告系统与多项体验优化
此提交完成了以下核心功能与优化:
1. 新增站点公告全流程支持:包含公告模型、CRUD接口、管理后台页面、公告详情页与首页展示
2. 实现评论楼层化与回复嵌套:重构评论系统为树状结构,支持回复评论与层级限制
3. 添加用户在线状态追踪:异步更新用户最后活跃时间并做SQL限频
4. 优化用户体验:移动端浮动操作条、统一板块标签样式、用户页签到积分展示、注册即登录优化
5. 其他细节优化:SEO站点地图新增公告页、评论分页与统计、登录/注册表单增强等
2026-09-13 21:38:01 +08:00

92 lines
2.2 KiB
Go

package handler
import (
"encoding/xml"
"fmt"
"net/http"
"time"
"github.com/freefire/jiang13-bbs/model"
"github.com/gin-gonic/gin"
)
const siteBaseURL = "http://localhost:3000"
// RobotsTxt robots.txt
func (h *Handlers) RobotsTxt(c *gin.Context) {
content := fmt.Sprintf(`User-agent: *
Allow: /
Sitemap: %s/sitemap.xml
`, siteBaseURL)
c.String(http.StatusOK, content)
}
// SitemapXML 生成 sitemap
func (h *Handlers) SitemapXML(c *gin.Context) {
type urlEntry struct {
Loc string `xml:"loc"`
Lastmod string `xml:"lastmod"`
Changefreq string `xml:"changefreq"`
Priority string `xml:"priority"`
}
type urlset struct {
XMLName xml.Name `xml:"urlset"`
Xmlns string `xml:"xmlns,attr"`
URLs []urlEntry `xml:"url"`
}
now := time.Now().Format("2006-01-02")
entries := []urlEntry{
{Loc: siteBaseURL + "/", Lastmod: now, Changefreq: "daily", Priority: "1.0"},
}
// 板块页
var boards []model.Board
model.DB.Find(&boards)
for _, b := range boards {
entries = append(entries, urlEntry{
Loc: fmt.Sprintf("%s/board/%d", siteBaseURL, b.ID),
Lastmod: now,
Changefreq: "daily",
Priority: "0.8",
})
}
// 帖子详情页
var posts []model.Post
model.DB.Where("status = ?", model.ContentStatusPublished).
Order("created_at DESC").Limit(1000).Find(&posts)
for _, p := range posts {
entries = append(entries, urlEntry{
Loc: fmt.Sprintf("%s/post/%d", siteBaseURL, p.ID),
Lastmod: p.UpdatedAt.Format("2006-01-02"),
Changefreq: "weekly",
Priority: "0.6",
})
}
// 站点公告
var anns []model.Announcement
model.DB.Where("published = ?", true).Order("created_at DESC").Limit(200).Find(&anns)
for _, a := range anns {
entries = append(entries, urlEntry{
Loc: fmt.Sprintf("%s/announcement/%d", siteBaseURL, a.ID),
Lastmod: a.UpdatedAt.Format("2006-01-02"),
Changefreq: "weekly",
Priority: "0.5",
})
}
us := urlset{
Xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9",
URLs: entries,
}
output, err := xml.MarshalIndent(us, "", " ")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.Header("Content-Type", "application/xml")
c.String(http.StatusOK, xml.Header+string(output))
}