feat: SSR 公开板块索引 /boards

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-29 06:53:20 +08:00
parent d4b29f5b7c
commit 2a46c01c85
13 changed files with 209 additions and 4 deletions

53
routers/web/boards.go Normal file
View File

@@ -0,0 +1,53 @@
package web
import (
"net/http"
"git.iioio.com/freefire/jiang13-forum/modules/webctx"
"github.com/gin-gonic/gin"
)
type boardsItemView struct {
ID uint
Name string
Description string
Icon string
ColorIndex int
PostCount int
}
type boardsPageData struct {
PageChrome
Items []boardsItemView
}
// BoardsGet 公开板块索引
func (d Deps) BoardsGet(c *gin.Context) {
ctx := d.ctx(c)
d.renderBoards(ctx)
}
func (d Deps) renderBoards(ctx *webctx.Context) {
brand := d.Settings.SiteBranding()
chrome := d.chrome(ctx, "板块 · "+brand.Name, "", "")
list, _ := d.Board.ListWithStats()
items := make([]boardsItemView, 0, len(list))
for _, b := range list {
color := b.ColorIndex
if color < 0 {
color = int(b.ID % 8)
}
items = append(items, boardsItemView{
ID: b.ID,
Name: b.Name,
Description: b.Description,
Icon: b.Icon,
ColorIndex: color,
PostCount: b.PostCount,
})
}
ctx.HTML(http.StatusOK, "boards/list", boardsPageData{
PageChrome: chrome,
Items: items,
})
}

View File

@@ -46,6 +46,7 @@ type PageChrome struct {
ViewerName string
Boards []BoardView
ActiveBoard uint
Path string // 当前请求路径,供侧栏高亮
Inner string // 保留字段;入口模板已固定组合,不再动态 template
CSRF string
Flash string
@@ -88,6 +89,10 @@ func (d Deps) chrome(ctx *webctx.Context, title, desc, inner string) PageChrome
if ctx.IsSigned() && ctx.Doer != nil {
viewerPoints = ctx.Doer.Points
}
path := ""
if ctx.C != nil && ctx.C.Request != nil && ctx.C.Request.URL != nil {
path = ctx.C.Request.URL.Path
}
return PageChrome{
Title: title,
Description: desc,
@@ -98,6 +103,7 @@ func (d Deps) chrome(ctx *webctx.Context, title, desc, inner string) PageChrome
IsAdmin: ctx.IsAdmin(),
ViewerName: name,
Boards: bv,
Path: path,
Inner: inner,
CSRF: ctx.EnsureCSRF(),
Flash: ctx.TakeFlash(),

View File

@@ -83,7 +83,7 @@ func Register(r *gin.Engine, deps Deps, authMW *auth.AuthMiddleware) {
g.POST("/links/apply/:id/cancel", authMW.RequireAuth(), deps.LinksApplyCancelPost)
g.POST("/links/logo", authMW.RequireAuth(), deps.LinksLogoUpload)
g.GET("/projects", deps.PendingPage)
g.GET("/boards", deps.PendingPage)
g.GET("/boards", deps.BoardsGet)
}
// HomePageData Feed