package handlers import ( "net/url" "strings" "github.com/gin-gonic/gin" "github.com/niangaodev/art-code/repositories" "github.com/niangaodev/art-code/utils" ) // GetDashboardStats 获取仪表盘统计数据 func GetDashboardStats(c *gin.Context) { startDate := c.Query("startDate") endDate := c.Query("endDate") // URL解码日期参数,处理+号被编码的情况 if startDate != "" { if decoded, err := url.QueryUnescape(startDate); err == nil { // 将+号替换为空格(URL编码中+可能代表空格) startDate = strings.ReplaceAll(decoded, "+", " ") } } if endDate != "" { if decoded, err := url.QueryUnescape(endDate); err == nil { // 将+号替换为空格(URL编码中+可能代表空格) endDate = strings.ReplaceAll(decoded, "+", " ") } } // 1. 获取博文增长趋势 postsTrend, err := repositories.GetNewPostsTrend(startDate, endDate) if err != nil { postsTrend = []repositories.TrendData{} // Fallback empty } // 2. 获取访客UV (根据IP) uvTrend, err := repositories.GetDailyUV(startDate, endDate) if err != nil { uvTrend = []repositories.UVTrendData{} } // 3. 用户画像-地域分布(使用 user_access_logs 表) userRegions, err := repositories.GetUserRegionsFromUserAccessLogs(startDate, endDate) if err != nil { // 即使出错,也返回所有34个省份的默认数据(Count为0) userRegions = repositories.GetDefaultUserRegions() } // 4. 热门文章 Top 5 // 优先使用访问日志统计,不足5条则用posts表的read_count补齐 topPosts, err := repositories.GetTopArticlesByAccess(5) if err != nil { topPosts = []struct { ArticleID int `json:"article_id"` Title string `json:"title"` Count int `json:"count"` }{} } if len(topPosts) < 5 { // Fetch more than needed to ensure we find unique ones, or just fetch top 5 dbPosts, err := repositories.GetTopPosts(10) if err == nil { // Create a map of existing IDs to avoid duplicates existingIDs := make(map[int]bool) for _, p := range topPosts { existingIDs[p.ArticleID] = true } for _, p := range dbPosts { if len(topPosts) >= 5 { break } if !existingIDs[int(p.ID)] { topPosts = append(topPosts, struct { ArticleID int `json:"article_id"` Title string `json:"title"` Count int `json:"count"` }{ ArticleID: int(p.ID), Title: p.Title, Count: int(p.ReadCount), }) existingIDs[int(p.ID)] = true } } } } // 5. 合作咨询总数 inquiryCount, _ := repositories.GetInquiryCount() // 6. 作品总数 workCount, _ := repositories.GetWorkCount() // 7. 文章总数 postCount, _ := repositories.GetPostCount() // 8. 管理员操作统计 operationTrend, err := repositories.GetOperationTrend(startDate, endDate) if err != nil { operationTrend = []repositories.OperationTrendData{} } utils.Success(c, gin.H{ "postsTrend": postsTrend, "uvTrend": uvTrend, "userRegions": userRegions, "topPosts": topPosts, "inquiryCount": inquiryCount, "posts": postCount, "works": workCount, "operationTrend": operationTrend, }) }