perf: 优化dashboard API,41次查询12次

- 合并30次循环查询为1次(onlineTrend)
- 使用 GROUP BY DATE() 一次获取所有日期数据
- 在内存中填充缺失日期,避免 N+1 问题
- API 响应时间预计从 1-2s 降至 100-200ms
This commit is contained in:
2026-05-06 07:55:36 +08:00
parent 3cf702d9b8
commit 488b1581e9
+39 -15
View File
@@ -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)