feat(admin): add comprehensive admin management system

- Add admin handlers and services for users, posts, comments, groups, and dashboard
- Implement role permission management with ability to view and update permissions
- Add database seeding for roles and Casbin permission policies
- Upgrade Casbin from v2 to v3 with GORM adapter for persistent policy storage
- Add admin-specific repository methods with filtering and pagination
- Register new admin API routes under /api/v1/admin/*
This commit is contained in:
2026-03-14 18:01:55 +08:00
parent ae5b997924
commit d3065b30cc
28 changed files with 4018 additions and 107 deletions

View File

@@ -0,0 +1,100 @@
package handler
import (
"strconv"
"carrot_bbs/internal/pkg/response"
"carrot_bbs/internal/service"
"github.com/gin-gonic/gin"
)
// AdminDashboardHandler 管理端仪表盘处理器
type AdminDashboardHandler struct {
dashboardService service.AdminDashboardService
}
// NewAdminDashboardHandler 创建管理端仪表盘处理器
func NewAdminDashboardHandler(dashboardService service.AdminDashboardService) *AdminDashboardHandler {
return &AdminDashboardHandler{
dashboardService: dashboardService,
}
}
// GetStats 获取统计数据
// GET /api/v1/admin/dashboard/stats
func (h *AdminDashboardHandler) GetStats(c *gin.Context) {
stats, err := h.dashboardService.GetStats(c.Request.Context())
if err != nil {
response.InternalServerError(c, "failed to get dashboard stats")
return
}
response.Success(c, stats)
}
// GetUserActivityTrend 获取用户活跃度趋势
// GET /api/v1/admin/dashboard/user-activity
func (h *AdminDashboardHandler) GetUserActivityTrend(c *gin.Context) {
// 解析天数参数默认7天
days, _ := strconv.Atoi(c.DefaultQuery("days", "7"))
if days <= 0 {
days = 7
}
if days > 30 {
days = 30
}
trend, err := h.dashboardService.GetUserActivityTrend(c.Request.Context(), days)
if err != nil {
response.InternalServerError(c, "failed to get user activity trend")
return
}
response.Success(c, trend)
}
// GetContentStats 获取内容统计
// GET /api/v1/admin/dashboard/content-stats
func (h *AdminDashboardHandler) GetContentStats(c *gin.Context) {
stats, err := h.dashboardService.GetContentStats(c.Request.Context())
if err != nil {
response.InternalServerError(c, "failed to get content stats")
return
}
response.Success(c, stats)
}
// GetPendingContent 获取待审核内容
// GET /api/v1/admin/dashboard/pending-content
func (h *AdminDashboardHandler) GetPendingContent(c *gin.Context) {
// 解析limit参数默认10条
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
if limit <= 0 {
limit = 10
}
if limit > 50 {
limit = 50
}
content, err := h.dashboardService.GetPendingContent(c.Request.Context(), limit)
if err != nil {
response.InternalServerError(c, "failed to get pending content")
return
}
response.Success(c, content)
}
// GetOnlineUsers 获取在线用户数
// GET /api/v1/admin/dashboard/online-users
func (h *AdminDashboardHandler) GetOnlineUsers(c *gin.Context) {
onlineUsers, err := h.dashboardService.GetOnlineUsers(c.Request.Context())
if err != nil {
response.InternalServerError(c, "failed to get online users count")
return
}
response.Success(c, onlineUsers)
}