Codex Assistant
1 天以前 ba94ceae1315174798ae1967ef62268c6d16cd5b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package com.rongyichuang.dashboard.service;
 
import com.rongyichuang.activity.repository.ActivityRepository;
import com.rongyichuang.dashboard.dto.response.DashboardStatsResponse;
import com.rongyichuang.dashboard.dto.response.RegionRegistrationStat;
import com.rongyichuang.dashboard.dto.response.RegistrationTrendPoint;
import com.rongyichuang.judge.repository.JudgeRepository;
import com.rongyichuang.player.repository.ActivityPlayerRepository;
import com.rongyichuang.player.repository.PlayerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * Dashboard 统计数据服务
 */
@Service
public class DashboardService {
 
    private static final int DEFAULT_TREND_DAYS = 15;
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final String UNASSIGNED_REGION_NAME = "未选择区域";
 
    @Autowired
    private ActivityRepository activityRepository;
 
    @Autowired
    private PlayerRepository playerRepository;
 
    @Autowired
    private ActivityPlayerRepository activityPlayerRepository;
 
    @Autowired
    private JudgeRepository judgeRepository;
 
    /**
     * 获取Dashboard统计数据
     */
    public DashboardStatsResponse getDashboardStats() {
        DashboardStatsResponse stats = new DashboardStatsResponse();
 
        // 当前进行比赛数量(状态为1的比赛,pid=0表示主比赛)
        long activeActivities = activityRepository.countActiveActivities();
        stats.setActiveActivities((int) activeActivities);
 
        // 参赛总人数(状态为1的参赛选手)
        long totalPlayers = playerRepository.countByState(1);
        stats.setTotalPlayers((int) totalPlayers);
 
        // 报名待审核人数(activityPlayer状态为0表示待审核)
        long pendingReviews = activityPlayerRepository.countByState(0);
        stats.setPendingReviews((int) pendingReviews);
 
        // 评委总数(状态为1的评委)
        long totalJudges = judgeRepository.countByState(1);
        stats.setTotalJudges((int) totalJudges);
 
        return stats;
    }
 
    /**
     * 获取最近报名趋势(默认最近15天,仅统计第一阶段)
     */
    public List<RegistrationTrendPoint> getRegistrationTrend(Integer days) {
        int queryDays = (days == null || days <= 0) ? DEFAULT_TREND_DAYS : days;
        LocalDate today = LocalDate.now();
        LocalDate startDate = today.minusDays(queryDays - 1L);
        LocalDateTime startDateTime = startDate.atStartOfDay();
 
        List<Object[]> rawData = activityPlayerRepository.countFirstStageRegistrationsByDate(startDateTime);
        Map<String, Long> dataMap = new HashMap<>();
 
        for (Object[] row : rawData) {
            if (row == null || row.length < 2) {
                continue;
            }
            Object dateObj = row[0];
            LocalDate date;
            if (dateObj instanceof java.sql.Date sqlDate) {
                date = sqlDate.toLocalDate();
            } else if (dateObj instanceof LocalDate localDate) {
                date = localDate;
            } else {
                date = LocalDate.parse(dateObj.toString());
            }
            Long count = row[1] != null ? ((Number) row[1]).longValue() : 0L;
            dataMap.put(date.format(DATE_FORMATTER), count);
        }
 
        List<RegistrationTrendPoint> result = new ArrayList<>(queryDays);
        for (int i = 0; i < queryDays; i++) {
            LocalDate date = startDate.plusDays(i);
            String key = date.format(DATE_FORMATTER);
            Long count = dataMap.getOrDefault(key, 0L);
            result.add(new RegistrationTrendPoint(key, count));
        }
        return result;
    }
 
    /**
     * 获取区域报名分布(仅统计第一阶段,剔除非叶子区域)
     */
    public List<RegionRegistrationStat> getRegionRegistrationStats() {
        List<Object[]> rawData = activityPlayerRepository.countFirstStageRegistrationsByRegion();
        List<RegionRegistrationStat> stats = new ArrayList<>();
 
        for (Object[] row : rawData) {
            if (row == null || row.length < 4) {
                continue;
            }
            String regionId = null;
            if (row[0] != null) {
                Object regionIdObj = row[0];
                if (regionIdObj instanceof Number number) {
                    regionId = String.valueOf(number.longValue());
                } else {
                    regionId = regionIdObj.toString();
                }
            }
            String regionName = row[1] != null ? row[1].toString() : UNASSIGNED_REGION_NAME;
            // leaf_flag字段在不同驱动下的类型可能差异,需要统一转换
            Boolean leafFlag = null;
            Object leafObj = row[2];
            if (leafObj instanceof Number number) {
                leafFlag = number.intValue() == 1;
            } else if (leafObj instanceof Boolean bool) {
                leafFlag = bool;
            } else if (leafObj != null) {
                String leafText = leafObj.toString().trim().toLowerCase();
                if (!leafText.isEmpty()) {
                    if ("1".equals(leafText) || "true".equals(leafText)) {
                        leafFlag = true;
                    } else if ("0".equals(leafText) || "false".equals(leafText)) {
                        leafFlag = false;
                    }
                }
            }
            Long count = row[3] != null ? ((Number) row[3]).longValue() : 0L;
 
            if (Boolean.FALSE.equals(leafFlag)) {
                // 非叶子区域不参与统计
                continue;
            }
 
            if (regionName == null || regionName.isBlank()) {
                regionName = UNASSIGNED_REGION_NAME;
            }
 
            stats.add(new RegionRegistrationStat(regionId, regionName, leafFlag, count));
        }
 
        return stats;
    }
}