diff --git a/backend/internal/api/handlers/dashboard.go b/backend/internal/api/handlers/dashboard.go index 89cefed..9312b5f 100644 --- a/backend/internal/api/handlers/dashboard.go +++ b/backend/internal/api/handlers/dashboard.go @@ -279,7 +279,7 @@ func (h *DashboardHandler) GetRecentReleases(c *gin.Context) { // GetMetrics 获取监控指标 // @Summary 获取监控指标 -// @Description 获取系统监控指标数据 +// @Description 获取系统监控指标数据(基于 AgentReport 真实数据) // @Tags 仪表盘 // @Produce json // @Security Bearer @@ -288,28 +288,38 @@ func (h *DashboardHandler) GetRecentReleases(c *gin.Context) { // @Router /dashboard/metrics [get] func (h *DashboardHandler) GetMetrics(c *gin.Context) { hours := 24 + if hv := c.Query("hours"); hv != "" { + if parsed, err := strconv.Atoi(hv); err == nil && parsed > 0 && parsed <= 168 { + hours = parsed + } + } + + // 从 agent_reports 表查最近 N 小时的真实数据 + since := time.Now().Add(-time.Duration(hours) * time.Hour) + type avgPoint struct { + Bucket time.Time + AvgCPU float64 + AvgMem float64 + } + var rows []avgPoint + h.db.Model(&models.AgentReport{}). + Select("strftime('%Y-%m-%d %H:00', created_at) as bucket, AVG(cpu_usage) as avg_cpu, AVG(mem_usage) as avg_mem"). + Where("created_at >= ?", since). + Group("bucket"). + Order("bucket ASC"). + Scan(&rows) - // 生成模拟数据 var metrics []models.MetricData - now := time.Now() + for _, r := range rows { + metrics = append(metrics, + models.MetricData{Name: "cpu", Value: r.AvgCPU, Timestamp: r.Bucket}, + models.MetricData{Name: "memory", Value: r.AvgMem, Timestamp: r.Bucket}, + ) + } - for i := 0; i < hours; i++ { - timestamp := now.Add(-time.Duration(hours-i) * time.Hour) - metrics = append(metrics, models.MetricData{ - Name: "cpu", - Value: 40 + float64(i%30), - Timestamp: timestamp, - }) - metrics = append(metrics, models.MetricData{ - Name: "memory", - Value: 50 + float64(i%20), - Timestamp: timestamp, - }) - metrics = append(metrics, models.MetricData{ - Name: "disk", - Value: 45 + float64(i%10), - Timestamp: timestamp, - }) + // 如果没有真实数据,返回空数组(不造假数据) + if metrics == nil { + metrics = []models.MetricData{} } c.JSON(http.StatusOK, models.Response{