此提交完成了以下核心功能与优化: 1. 新增站点公告全流程支持:包含公告模型、CRUD接口、管理后台页面、公告详情页与首页展示 2. 实现评论楼层化与回复嵌套:重构评论系统为树状结构,支持回复评论与层级限制 3. 添加用户在线状态追踪:异步更新用户最后活跃时间并做SQL限频 4. 优化用户体验:移动端浮动操作条、统一板块标签样式、用户页签到积分展示、注册即登录优化 5. 其他细节优化:SEO站点地图新增公告页、评论分页与统计、登录/注册表单增强等
92 lines
2.2 KiB
Go
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))
|
|
}
|