package handler import ( "net/http" "sql-platform/internal/middleware" "sql-platform/internal/model" "github.com/gin-gonic/gin" ) // GET /api/v1/dashboard/stats — 匹配前端 DashboardStats 类型 func DashboardStats(c *gin.Context) { var ticketTotal, ticketPending, ticketExecuting int64 var instanceTotal, instanceOnline, userTotal int64 var queriesToday int64 model.DB.Model(&model.Ticket{}).Count(&ticketTotal) model.DB.Model(&model.Ticket{}).Where("status IN ?", []string{"pending", "reviewing"}).Count(&ticketPending) model.DB.Model(&model.Ticket{}).Where("status = ?", "executing").Count(&ticketExecuting) model.DB.Model(&model.Instance{}).Count(&instanceTotal) model.DB.Model(&model.Instance{}).Where("status = ?", "online").Count(&instanceOnline) model.DB.Model(&model.User{}).Count(&userTotal) model.DB.Model(&model.QueryHistory{}).Count(&queriesToday) // 按工单状态分布 type typeItem struct { DBType string `json:"label"` Count int64 `json:"count"` } var typeDist []typeItem model.DB.Model(&model.Ticket{}).Select("db_type as db_type, count(*) as count").Group("db_type").Scan(&typeDist) c.JSON(http.StatusOK, gin.H{ "ticket_total": ticketTotal, "ticket_pending": ticketPending, "ticket_month": ticketTotal, // 简化 "ticket_executing": ticketExecuting, "instance_total": instanceTotal, "instance_online": instanceOnline, "user_total": userTotal, "queries_today": queriesToday, "type_distribution": typeDist, "query_stats": gin.H{ "total": queriesToday, "avg_time_ms": 0, "slow_count": 0, "type_distribution": typeDist, }, }) } // GET /api/v1/dashboard/my-tickets func MyTickets(c *gin.Context) { userID, _, role := middleware.GetCurrentUser(c) var tickets []model.Ticket query := model.DB.Order("id DESC").Limit(10) switch role { case "admin": query = query.Where("status IN ?", []string{"pending", "reviewing", "executing"}) case "dba", "auditor": query = query.Where( "(applicant_id = ? AND status IN ?) OR (id IN (SELECT ticket_id FROM ticket_approvals WHERE approver_id = ?) AND status IN ?)", userID, []string{"pending", "executing"}, userID, []string{"pending", "reviewing", "executing"}, ) default: query = query.Where("applicant_id = ?", userID) } query.Find(&tickets) type ticketWithRelation struct { model.Ticket Relation string `json:"relation"` PendingInfo *string `json:"pending_info"` } var result []ticketWithRelation for _, t := range tickets { rel := "我提交的" if t.ApplicantID != userID { rel = "待我审批" } pi := "" if t.ApplicantID != userID { pi = "等待您审批" } result = append(result, ticketWithRelation{Ticket: t, Relation: rel, PendingInfo: &pi}) } if result == nil { result = []ticketWithRelation{} } c.JSON(http.StatusOK, result) }