You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

196 lines
6.1 KiB

package statistics
import (
"net/http"
"strconv"
"time"
"task-track-backend/model"
"task-track-backend/pkg/database"
"github.com/gin-gonic/gin"
)
// OverviewResponse 总览统计响应
type OverviewResponse struct {
// 基本统计
TotalTasks int64 `json:"total_tasks"`
TotalUsers int64 `json:"total_users"`
TotalOrganizations int64 `json:"total_organizations"`
// 任务状态统计
TasksByStatus map[string]int64 `json:"tasks_by_status"`
// 任务优先级统计
TasksByPriority map[string]int64 `json:"tasks_by_priority"`
// 最近7天任务创建数
RecentTasksCount int64 `json:"recent_tasks_count"`
// 最近7天任务完成数
RecentCompletedTasks int64 `json:"recent_completed_tasks"`
// 今日任务统计
TodayTasks struct {
Created int64 `json:"created"`
Completed int64 `json:"completed"`
} `json:"today_tasks"`
// 本周任务统计
WeeklyTasks struct {
Created int64 `json:"created"`
Completed int64 `json:"completed"`
} `json:"weekly_tasks"`
// 本月任务统计
MonthlyTasks struct {
Created int64 `json:"created"`
Completed int64 `json:"completed"`
} `json:"monthly_tasks"`
}
func (h *StatisticsHandler) GetOverview(c *gin.Context) {
// 获取组织ID参数(可选)
organizationIDStr := c.Query("organization_id")
var organizationID uint
if organizationIDStr != "" {
if id, err := strconv.ParseUint(organizationIDStr, 10, 32); err == nil {
organizationID = uint(id)
}
}
db := database.GetDB()
var response OverviewResponse
// 基础查询构建器
baseTaskQuery := db.Model(&model.Task{})
if organizationID > 0 {
baseTaskQuery = baseTaskQuery.Where("organization_id = ?", organizationID)
}
// 1. 基本统计
// 总任务数
if err := baseTaskQuery.Count(&response.TotalTasks).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取任务统计失败"})
return
}
// 总用户数
userQuery := db.Model(&model.User{})
if err := userQuery.Count(&response.TotalUsers).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户统计失败"})
return
}
// 总组织数
if err := db.Model(&model.Organization{}).Count(&response.TotalOrganizations).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取组织统计失败"})
return
}
// 2. 任务状态统计
var statusStats []struct {
Status string `json:"status"`
Count int64 `json:"count"`
}
statusQuery := baseTaskQuery.Select("status, count(*) as count").Group("status")
if err := statusQuery.Find(&statusStats).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取任务状态统计失败"})
return
}
response.TasksByStatus = make(map[string]int64)
for _, stat := range statusStats {
response.TasksByStatus[stat.Status] = stat.Count
}
// 3. 任务优先级统计
var priorityStats []struct {
Priority string `json:"priority"`
Count int64 `json:"count"`
}
priorityQuery := baseTaskQuery.Select("priority, count(*) as count").Group("priority")
if err := priorityQuery.Find(&priorityStats).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取任务优先级统计失败"})
return
}
response.TasksByPriority = make(map[string]int64)
for _, stat := range priorityStats {
response.TasksByPriority[stat.Priority] = stat.Count
}
// 4. 时间范围统计
now := time.Now()
// 今日开始时间
todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
// 本周开始时间(周一)
weekStart := todayStart.AddDate(0, 0, -int(now.Weekday())+1)
if now.Weekday() == time.Sunday {
weekStart = weekStart.AddDate(0, 0, -7)
}
// 本月开始时间
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
// 最近7天开始时间
sevenDaysAgo := now.AddDate(0, 0, -7)
// 今日任务统计
todayTaskQuery := baseTaskQuery.Where("created_at >= ?", todayStart)
if err := todayTaskQuery.Count(&response.TodayTasks.Created).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取今日任务统计失败"})
return
}
todayCompletedQuery := baseTaskQuery.Where("status = ? AND updated_at >= ?", "completed", todayStart)
if err := todayCompletedQuery.Count(&response.TodayTasks.Completed).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取今日完成任务统计失败"})
return
}
// 本周任务统计
weekTaskQuery := baseTaskQuery.Where("created_at >= ?", weekStart)
if err := weekTaskQuery.Count(&response.WeeklyTasks.Created).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取本周任务统计失败"})
return
}
weekCompletedQuery := baseTaskQuery.Where("status = ? AND updated_at >= ?", "completed", weekStart)
if err := weekCompletedQuery.Count(&response.WeeklyTasks.Completed).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取本周完成任务统计失败"})
return
}
// 本月任务统计
monthTaskQuery := baseTaskQuery.Where("created_at >= ?", monthStart)
if err := monthTaskQuery.Count(&response.MonthlyTasks.Created).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取本月任务统计失败"})
return
}
monthCompletedQuery := baseTaskQuery.Where("status = ? AND updated_at >= ?", "completed", monthStart)
if err := monthCompletedQuery.Count(&response.MonthlyTasks.Completed).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取本月完成任务统计失败"})
return
}
// 最近7天任务统计
recentTaskQuery := baseTaskQuery.Where("created_at >= ?", sevenDaysAgo)
if err := recentTaskQuery.Count(&response.RecentTasksCount).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取最近任务统计失败"})
return
}
recentCompletedQuery := baseTaskQuery.Where("status = ? AND updated_at >= ?", "completed", sevenDaysAgo)
if err := recentCompletedQuery.Count(&response.RecentCompletedTasks).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取最近完成任务统计失败"})
return
}
c.JSON(http.StatusOK, response)
}