feat(admin): 侧边栏布局 + 仪表盘 + 全局隐藏滚动条

- 全局隐藏滚动条(web + admin),保留正常滚动
- admin 顶栏改侧边栏导航(仪表盘/文章),响应式移动端抽屉
- 路由重构:首页→仪表盘,文章列表移到 /posts
- 仪表盘页:文章总数/已发布/草稿统计卡片 + 最近更新列表
- 后端 GET /api/admin/stats

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-17 16:31:37 +08:00
parent 7f050843f9
commit 6334dccf4a
10 changed files with 316 additions and 45 deletions
+20
View File
@@ -156,3 +156,23 @@ func (h *AdminPostHandler) Delete(c *gin.Context) {
}
resp.OK(c, nil)
}
// Stats GET /api/admin/stats — 概览统计(总数 / 已发布 / 草稿 / 最近文章)
func (h *AdminPostHandler) Stats(c *gin.Context) {
var total, published int64
if err := h.db.Model(&model.Post{}).Count(&total).Error; err != nil {
resp.ServerError(c, "查询失败")
return
}
h.db.Model(&model.Post{}).Where("published_at IS NOT NULL").Count(&published)
var recent []model.PostListItem
h.db.Model(&model.Post{}).Order("updated_at DESC").Limit(5).Find(&recent)
resp.OK(c, gin.H{
"total": total,
"published": published,
"draft": total - published,
"recent": recent,
})
}
+1
View File
@@ -42,6 +42,7 @@ func New(db *gorm.DB) (*gin.Engine, error) {
adminAPI := api.Group("/admin", middleware.Auth())
{
posts := handler.NewAdminPostHandler(db)
adminAPI.GET("/stats", posts.Stats)
adminAPI.GET("/posts", posts.List)
adminAPI.POST("/posts", posts.Create)
adminAPI.GET("/posts/:id", posts.Get)