package interfaces import ( "time" "mengstack/internal/kernel/response" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type Handler struct { db *gorm.DB } func NewHandler(db *gorm.DB) *Handler { return &Handler{db: db} } type StatsResponse struct { TenantCount int64 `json:"tenantCount"` UserCount int64 `json:"userCount"` RoleCount int64 `json:"roleCount"` OnlineCount int64 `json:"onlineCount"` TenantGrowth float64 `json:"tenantGrowth"` UserGrowth float64 `json:"userGrowth"` RoleGrowth float64 `json:"roleGrowth"` TodayActiveUsers int64 `json:"todayActiveUsers"` } // GetStats godoc // @Summary 仪表盘统计 // @Description 返回平台核心指标的统计数据 // @Tags Dashboard // @Produce json // @Success 200 {object} response.Response{data=StatsResponse} // @Security Bearer // @Security TenantID // @Router /dashboard/stats [get] func (h *Handler) GetStats(c *gin.Context) { tenantID, _ := c.Get("tenant_id") isSuperAdmin := tenantID == "" var tenantCount, userCount, roleCount int64 var tenantPrev, userPrev, rolePrev int64 now := time.Now() thirtyDaysAgo := now.AddDate(0, 0, -30) sixtyDaysAgo := now.AddDate(0, 0, -60) if isSuperAdmin { h.db.Table("tenants").Count(&tenantCount) h.db.Table("users").Count(&userCount) h.db.Table("roles").Count(&roleCount) h.db.Table("tenants").Where("created_at < ? AND created_at >= ?", thirtyDaysAgo, sixtyDaysAgo).Count(&tenantPrev) h.db.Table("users").Where("created_at < ? AND created_at >= ?", thirtyDaysAgo, sixtyDaysAgo).Count(&userPrev) h.db.Table("roles").Where("created_at < ? AND created_at >= ?", thirtyDaysAgo, sixtyDaysAgo).Count(&rolePrev) } else { h.db.Table("users").Where("tenant_id = ?", tenantID).Count(&userCount) h.db.Table("roles").Where("tenant_id = ?", tenantID).Count(&roleCount) h.db.Table("users").Where("tenant_id = ? AND created_at < ? AND created_at >= ?", tenantID, thirtyDaysAgo, sixtyDaysAgo).Count(&userPrev) h.db.Table("roles").Where("tenant_id = ? AND created_at < ? AND created_at >= ?", tenantID, thirtyDaysAgo, sixtyDaysAgo).Count(&rolePrev) } var todayActiveUsers int64 todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) if isSuperAdmin { h.db.Table("users").Where("last_login >= ?", todayStart).Count(&todayActiveUsers) } else { h.db.Table("users").Where("tenant_id = ? AND last_login >= ?", tenantID, todayStart).Count(&todayActiveUsers) } stats := StatsResponse{ TenantCount: tenantCount, UserCount: userCount, RoleCount: roleCount, OnlineCount: 0, TenantGrowth: calcGrowth(tenantCount, tenantPrev), UserGrowth: calcGrowth(userCount, userPrev), RoleGrowth: calcGrowth(roleCount, rolePrev), TodayActiveUsers: todayActiveUsers, } response.Success(c, stats) } func calcGrowth(current, previous int64) float64 { if previous == 0 { if current > 0 { return 100 } return 0 } return float64(current-previous) / float64(previous) * 100 }