From 488b1581e9728fc028b213887e1c82edaf905371 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 6 May 2026 07:55:36 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96dashboard=20API?= =?UTF-8?q?=EF=BC=8C41=E6=AC=A1=E6=9F=A5=E8=AF=A212=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 合并30次循环查询为1次(onlineTrend) - 使用 GROUP BY DATE() 一次获取所有日期数据 - 在内存中填充缺失日期,避免 N+1 问题 - API 响应时间预计从 1-2s 降至 100-200ms --- backend/internal/router/admin/dashboard.go | 54 ++++++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/backend/internal/router/admin/dashboard.go b/backend/internal/router/admin/dashboard.go index 782c132..a30f881 100644 --- a/backend/internal/router/admin/dashboard.go +++ b/backend/internal/router/admin/dashboard.go @@ -1,4 +1,4 @@ -package admin +package admin import ( "time" @@ -111,23 +111,47 @@ func handleGetDashboard(c *gin.Context) { } onlineTrend := make([]gin.H, 0, 30) - for i := 29; i >= 0; i-- { - date := time.Now().AddDate(0, 0, -i) - dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()) - dateEnd := dateStart.Add(24 * time.Hour) + if len(appIDs) > 0 { + type DailyCount struct { + Date string + Count int64 + } + var dailyCounts []DailyCount - var count int64 - if len(appIDs) > 0 { - database.DB.Model(&model.DeviceSession{}). - Joins("JOIN user_devices ON device_sessions.device_id = user_devices.id"). - Where("user_devices.application_id IN ? AND device_sessions.last_heartbeat >= ? AND device_sessions.last_heartbeat < ?", appIDs, dateStart, dateEnd). - Count(&count) + dateStart := time.Now().AddDate(0, 0, -29) + dateStart = time.Date(dateStart.Year(), dateStart.Month(), dateStart.Day(), 0, 0, 0, 0, dateStart.Location()) + + database.DB.Model(&model.DeviceSession{}). + Select("DATE(last_heartbeat) as date, COUNT(*) as count"). + Joins("JOIN user_devices ON device_sessions.device_id = user_devices.id"). + Where("user_devices.application_id IN ? AND last_heartbeat >= ?", appIDs, dateStart). + Group("DATE(last_heartbeat)"). + Order("date ASC"). + Find(&dailyCounts) + + countMap := make(map[string]int64) + for _, dc := range dailyCounts { + countMap[dc.Date] = dc.Count } - onlineTrend = append(onlineTrend, gin.H{ - "date": date.Format("01-02"), - "value": count, - }) + for i := 29; i >= 0; i-- { + date := time.Now().AddDate(0, 0, -i) + dateStr := date.Format("2006-01-02") + count := countMap[dateStr] + + onlineTrend = append(onlineTrend, gin.H{ + "date": date.Format("01-02"), + "value": count, + }) + } + } else { + for i := 29; i >= 0; i-- { + date := time.Now().AddDate(0, 0, -i) + onlineTrend = append(onlineTrend, gin.H{ + "date": date.Format("01-02"), + "value": 0, + }) + } } recentTickets := make([]gin.H, 0, 5)