chenshudong 2 місяців тому
батько
коміт
5b98e24c13

+ 41 - 0
airport-admin/src/main/java/com/sundot/airport/web/controller/home/SeizureRankingController.java

@@ -0,0 +1,41 @@
1
+package com.sundot.airport.web.controller.home;
2
+
3
+import com.sundot.airport.common.core.controller.BaseController;
4
+import com.sundot.airport.common.core.domain.AjaxResult;
5
+import com.sundot.airport.item.domain.dto.RankingQueryParamDto;
6
+import com.sundot.airport.item.domain.dto.SeizureRankingDto;
7
+import com.sundot.airport.item.service.SeizureRankingService;
8
+import io.swagger.annotations.Api;
9
+import io.swagger.annotations.ApiOperation;
10
+import org.springframework.beans.factory.annotation.Autowired;
11
+import org.springframework.stereotype.Controller;
12
+import org.springframework.web.bind.annotation.PostMapping;
13
+import org.springframework.web.bind.annotation.RequestBody;
14
+import org.springframework.web.bind.annotation.RequestMapping;
15
+import org.springframework.web.bind.annotation.ResponseBody;
16
+
17
+import java.util.List;
18
+
19
+/**
20
+ * 查获排名控制器
21
+ */
22
+@Api(tags = "查获排名")
23
+@Controller
24
+@RequestMapping("/item/seizure/ranking")
25
+public class SeizureRankingController extends BaseController {
26
+
27
+    @Autowired
28
+    private SeizureRankingService seizureRankingService;
29
+
30
+    /**
31
+     * 根据角色获取查获排名
32
+     */
33
+    @ApiOperation("根据角色获取查获排名")
34
+    @PostMapping("/getRankingByRole")
35
+    @ResponseBody
36
+    public AjaxResult getRankingByRole(@RequestBody RankingQueryParamDto param) {
37
+        List<SeizureRankingDto> result = seizureRankingService.getRankingByRole(param);
38
+        return AjaxResult.success(result);
39
+    }
40
+
41
+}

+ 78 - 0
airport-item/src/main/java/com/sundot/airport/item/domain/dto/RankingQueryParamDto.java

@@ -0,0 +1,78 @@
1
+package com.sundot.airport.item.domain.dto;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import io.swagger.annotations.ApiModelProperty;
5
+import lombok.Data;
6
+
7
+import java.io.Serializable;
8
+import java.util.Date;
9
+
10
+/**
11
+ * 排名查询参数DTO
12
+ */
13
+@Data
14
+public class RankingQueryParamDto implements Serializable {
15
+
16
+    private static final long serialVersionUID = 1L;
17
+
18
+    /**
19
+     * 开始日期
20
+     */
21
+    @JsonFormat(pattern = "yyyy-MM-dd")
22
+    private Date startDate;
23
+
24
+    /**
25
+     * 结束日期
26
+     */
27
+    @JsonFormat(pattern = "yyyy-MM-dd")
28
+    private Date endDate;
29
+
30
+    /**
31
+     * 用户ID
32
+     */
33
+    private Long userId;
34
+
35
+    /**
36
+     * 部门ID
37
+     */
38
+    private Long deptId;
39
+
40
+
41
+    /**
42
+     * 数据来源:individual(个人), team(班组), department(科室)
43
+     */
44
+    @ApiModelProperty("数据来源:individual(个人), team(班组)")
45
+    private String dataSource;
46
+
47
+    /**
48
+     * 班组ID(查询班组数据时使用)
49
+     */
50
+    @ApiModelProperty("班组ID")
51
+    private Long teamId;
52
+
53
+    /**
54
+     * 科室ID(查询科室数据时使用)
55
+     */
56
+    @ApiModelProperty("科室ID")
57
+    private Long departmentId;
58
+
59
+    /**
60
+     * 大队ID(查询大队数据时使用)
61
+     */
62
+    @ApiModelProperty("大队ID")
63
+    private Long brigadeId;
64
+
65
+    /**
66
+     * 站 ID
67
+     */
68
+    @ApiModelProperty("站 ID")
69
+    private Long stationId;
70
+
71
+    /**
72
+     * 时间范围类型:last_week(近一周), last_month(近一月), last_three_months(近三月),
73
+     * last_half_year(近半年), last_year(近一年)
74
+     */
75
+    @ApiModelProperty("时间范围类型:last_week(近一周), last_month(近一月), last_three_months(近三月), last_half_year(近半年), last_year(近一年)")
76
+    private String timeRangeType;
77
+
78
+}

+ 30 - 0
airport-item/src/main/java/com/sundot/airport/item/domain/dto/SeizureRankingDto.java

@@ -0,0 +1,30 @@
1
+package com.sundot.airport.item.domain.dto;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * 查获排名DTO
7
+ */
8
+@Data
9
+public class SeizureRankingDto {
10
+    /**
11
+     * 排名
12
+     */
13
+    private Integer rank;
14
+
15
+    /**
16
+     * 奖牌类型(1-金牌,2-银牌,3-铜牌,4-哭脸红,5-哭脸橙,6-哭脸黄)
17
+     */
18
+    private Integer medalType;
19
+
20
+    /**
21
+     * 奖牌类型描述
22
+     */
23
+    private String medalTypeDesc;
24
+
25
+    /**
26
+     * 用户类型(个人、班组、科室、大队)
27
+     */
28
+    private String userType;
29
+
30
+}

+ 21 - 0
airport-item/src/main/java/com/sundot/airport/item/service/SeizureRankingService.java

@@ -0,0 +1,21 @@
1
+package com.sundot.airport.item.service;
2
+
3
+import com.sundot.airport.item.domain.dto.RankingQueryParamDto;
4
+import com.sundot.airport.item.domain.dto.SeizureRankingDto;
5
+
6
+import java.util.List;
7
+
8
+/**
9
+ * 查获排名服务接口
10
+ */
11
+public interface SeizureRankingService {
12
+
13
+    /**
14
+     * 根据角色获取排名
15
+     *
16
+     * @param param 查询参数
17
+     * @return 排名列表
18
+     */
19
+    List<SeizureRankingDto> getRankingByRole(RankingQueryParamDto param);
20
+
21
+}

+ 339 - 0
airport-item/src/main/java/com/sundot/airport/item/service/impl/SeizureRankingServiceImpl.java

@@ -0,0 +1,339 @@
1
+package com.sundot.airport.item.service.impl;
2
+
3
+import com.sundot.airport.common.core.domain.entity.SysDept;
4
+import com.sundot.airport.common.core.domain.entity.SysUser;
5
+import com.sundot.airport.common.core.domain.model.LoginUser;
6
+import com.sundot.airport.common.enums.MedalTypeEnum;
7
+import com.sundot.airport.common.enums.RoleTypeEnum;
8
+import com.sundot.airport.common.enums.portrait.UserType;
9
+import com.sundot.airport.common.utils.DateUtils;
10
+import com.sundot.airport.common.utils.SecurityUtils;
11
+import com.sundot.airport.item.domain.dto.RankingQueryParamDto;
12
+import com.sundot.airport.item.domain.dto.SeizureRankingDto;
13
+import com.sundot.airport.item.domain.home.SeizureReportDTO;
14
+import com.sundot.airport.item.mapper.SeizureReportMapper;
15
+import com.sundot.airport.item.service.SeizureRankingService;
16
+import com.sundot.airport.system.service.ISysDeptService;
17
+import org.springframework.beans.factory.annotation.Autowired;
18
+import org.springframework.stereotype.Service;
19
+
20
+import java.util.ArrayList;
21
+import java.util.Arrays;
22
+import java.util.Calendar;
23
+import java.util.Date;
24
+import java.util.List;
25
+
26
+/**
27
+ * 查获排名服务实现类
28
+ */
29
+@Service
30
+public class SeizureRankingServiceImpl implements SeizureRankingService {
31
+
32
+    @Autowired
33
+    private SeizureReportMapper seizureReportMapper;
34
+
35
+    @Autowired
36
+    private ISysDeptService sysDeptService;
37
+
38
+    @Override
39
+    public List<SeizureRankingDto> getRankingByRole(RankingQueryParamDto param) {
40
+        List<String> roleKeys = addParam(param);
41
+        if (param.getStartDate() == null) {
42
+            // 设置时间范围
43
+            setTimeRangeByType(param);
44
+        }
45
+        if (param.getEndDate() != null) {
46
+            param.setEndDate(DateUtils.addSeconds(DateUtils.truncate(param.getEndDate(), Calendar.DAY_OF_MONTH), 86399));
47
+        }
48
+        if (roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode())) {
49
+            return getIndividualRanking(param);
50
+        } else if (roleKeys.contains(RoleTypeEnum.banzuzhang.getCode())) {
51
+            //个人和班组的切换
52
+            if ("team".equals(param.getDataSource())) {
53
+                return getTeamRanking(param);
54
+            } else {
55
+                return getIndividualRanking(param);
56
+            }
57
+        } else if (roleKeys.contains(RoleTypeEnum.kezhang.getCode())) {
58
+            return getDepartmentRanking(param);
59
+        } else if (roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode())) {
60
+            return getBrigadeRanking(param);
61
+        } else {
62
+            return new ArrayList<>();
63
+        }
64
+    }
65
+
66
+    /**
67
+     * 添加参数
68
+     */
69
+    private List<String> addParam(RankingQueryParamDto param) {
70
+        LoginUser loginUser = SecurityUtils.getLoginUser();
71
+        SysUser currentUser = loginUser.getUser();
72
+        Long userId = currentUser.getUserId();
73
+        Long deptId = currentUser.getDeptId();
74
+        param.setDeptId(deptId);
75
+        param.setUserId(userId);
76
+        // 获取用户角色列表
77
+        List<String> roleKeys = currentUser.getRoles().stream()
78
+                .map(role -> role.getRoleKey())
79
+                .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
80
+
81
+        if (roleKeys.contains(RoleTypeEnum.SecurityCheck.getCode()) || roleKeys.contains(RoleTypeEnum.banzuzhang.getCode())) {
82
+            Long sectionDeptId = getSectionDeptId(deptId);
83
+            Long brigadeDeptId = getBrigadeDeptId(sectionDeptId);
84
+            Long stationDeptId = getStationDeptId(brigadeDeptId);
85
+            param.setTeamId(deptId);
86
+            param.setDepartmentId(sectionDeptId);
87
+            param.setBrigadeId(brigadeDeptId);
88
+            param.setStationId(stationDeptId);
89
+        } else if (roleKeys.contains(RoleTypeEnum.kezhang.getCode())) {
90
+            Long brigadeDeptId = getBrigadeDeptId(deptId);
91
+            Long stationDeptId = getStationDeptId(deptId);
92
+            param.setDepartmentId(deptId);
93
+            param.setBrigadeId(brigadeDeptId);
94
+            param.setStationId(stationDeptId);
95
+        } else if (roleKeys.contains(RoleTypeEnum.jingli.getCode()) || roleKeys.contains(RoleTypeEnum.xingzheng.getCode())) {
96
+            Long stationDeptId = getStationDeptId(deptId);
97
+            param.setBrigadeId(deptId);
98
+            param.setStationId(stationDeptId);
99
+        }
100
+        return roleKeys;
101
+    }
102
+
103
+    /**
104
+     * 获取科室部门ID(根据班组ID获取父级科室)
105
+     */
106
+    private Long getSectionDeptId(Long teamDeptId) {
107
+        return seizureReportMapper.selectSectionDeptIdByTeamId(teamDeptId);
108
+    }
109
+
110
+    /**
111
+     * 获取大队部门ID(根据科室ID获取父级大队)
112
+     */
113
+    private Long getBrigadeDeptId(Long teamDeptId) {
114
+        return seizureReportMapper.selectBrigadeDeptIdByDepartmentId(teamDeptId);
115
+    }
116
+
117
+    /**
118
+     * 获取站点部门ID(根据大队ID获取站点级别ID)
119
+     */
120
+    private Long getStationDeptId(Long deptId) {
121
+        return seizureReportMapper.selectStationDeptIdByDeptId(deptId);
122
+    }
123
+
124
+    /**
125
+     * 根据时间范围类型设置时间参数
126
+     */
127
+    private void setTimeRangeByType(RankingQueryParamDto param) {
128
+        if (param.getTimeRangeType() == null) {
129
+            // 默认近一年
130
+            setDefaultTimeRange(param);
131
+            return;
132
+        }
133
+        Date endDate = new Date();
134
+        Calendar calendar = Calendar.getInstance();
135
+        calendar.setTime(endDate);
136
+        calendar.add(Calendar.DAY_OF_MONTH, -1); // 不包括今天
137
+        endDate = calendar.getTime();
138
+        Date startDate;
139
+        switch (param.getTimeRangeType()) {
140
+            case "last_week":
141
+                calendar.add(Calendar.DAY_OF_MONTH, -7);
142
+                startDate = calendar.getTime();
143
+                break;
144
+            case "last_month":
145
+                calendar.add(Calendar.MONTH, -1);
146
+                startDate = calendar.getTime();
147
+                break;
148
+            case "last_three_months":
149
+                calendar.add(Calendar.MONTH, -3);
150
+                startDate = calendar.getTime();
151
+                break;
152
+            case "last_half_year":
153
+                calendar.add(Calendar.MONTH, -6);
154
+                startDate = calendar.getTime();
155
+                break;
156
+            case "last_year":
157
+            default:
158
+                calendar.add(Calendar.YEAR, -1);
159
+                startDate = calendar.getTime();
160
+                break;
161
+        }
162
+        param.setStartDate(startDate);
163
+        param.setEndDate(endDate);
164
+    }
165
+
166
+    /**
167
+     * 设置默认时间范围(近一年,不包括今天)
168
+     */
169
+    private void setDefaultTimeRange(RankingQueryParamDto param) {
170
+        Date endDate = new Date();
171
+        Calendar calendar = Calendar.getInstance();
172
+        calendar.setTime(endDate);
173
+        calendar.add(Calendar.DAY_OF_MONTH, -1); // 不包括今天
174
+        endDate = calendar.getTime();
175
+        calendar.add(Calendar.YEAR, -1); // 近一年
176
+        Date startDate = calendar.getTime();
177
+        param.setStartDate(startDate);
178
+        param.setEndDate(endDate);
179
+    }
180
+
181
+    /**
182
+     * 获取个人排名
183
+     */
184
+    public List<SeizureRankingDto> getIndividualRanking(RankingQueryParamDto param) {
185
+        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
186
+        Integer stationCurrentRank = seizureReportMapper.selectSelfRanking(param.getUserId(), param.getStationId(), "station", param.getStartDate(), param.getEndDate());
187
+        Integer stationTotalUsers = seizureReportMapper.selectUserCountByStationId(param.getStationId());
188
+        stationRanking.setCurrentRank(stationCurrentRank);
189
+        if (stationCurrentRank == null) {
190
+            stationRanking.setCurrentRank(stationTotalUsers);
191
+        }
192
+        stationRanking.setTotalItems(stationTotalUsers);
193
+        // 处理排名
194
+        return processRankingWithMedal(stationRanking, UserType.PERSONAL.getDescription(), param);
195
+    }
196
+
197
+    /**
198
+     * 处理班组排名和奖牌逻辑
199
+     */
200
+    public List<SeizureRankingDto> getTeamRanking(RankingQueryParamDto param) {
201
+        // 获取全站排名(班组在全站内的排名)
202
+        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
203
+        Integer stationTeamRank = getTeamRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
204
+        Integer stationTeamTotal = seizureReportMapper.selectTeamCountByStationId(param.getStationId());
205
+        stationRanking.setCurrentRank(stationTeamRank);
206
+        stationRanking.setTotalItems(stationTeamTotal);
207
+        // 处理排名和奖牌逻辑
208
+        return processRankingWithMedal(stationRanking, UserType.TEAM.getDescription(), param);
209
+    }
210
+
211
+    /**
212
+     * 获取班组在全站内的排名
213
+     */
214
+    private Integer getTeamRankInStation(Long teamId, Long stationId, Date startDate, Date endDate) {
215
+        // 获取全站下所有班组的排名
216
+        List<SeizureReportDTO.TeamRankingItem> allStationTeamRankings = seizureReportMapper.selectAllTeamRankingsInStation(stationId, startDate, endDate);
217
+        // 找到指定班组的排名
218
+        for (int i = 0; i < allStationTeamRankings.size(); i++) {
219
+            SeizureReportDTO.TeamRankingItem item = allStationTeamRankings.get(i);
220
+            // 由于TeamRankingItem的teamName包含科室名称+班组名称,我们需要通过其他方式匹配
221
+            SysDept currentTeam = sysDeptService.selectDeptById(teamId);
222
+            if (currentTeam != null) {
223
+                // 检查是否包含班组名称
224
+                if (item.getTeamName().contains(currentTeam.getDeptName())) {
225
+                    return i + 1; // 排名从1开始
226
+                }
227
+            }
228
+        }
229
+        return allStationTeamRankings.size() + 1; // 如果未找到,则为最后一名
230
+    }
231
+
232
+    /**
233
+     * 处理科室排名和奖牌逻辑
234
+     */
235
+    public List<SeizureRankingDto> getDepartmentRanking(RankingQueryParamDto param) {
236
+        // 设置全站排名 - 科室排名/全站科室数总和
237
+        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
238
+        Integer deptInStationRank = getDepartmentRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
239
+        Integer stationTotalDepts = seizureReportMapper.selectDepartmentCountByStationId(param.getStationId());
240
+        stationRanking.setCurrentRank(deptInStationRank);
241
+        stationRanking.setTotalItems(stationTotalDepts);
242
+        // 处理排名和奖牌逻辑
243
+        return processRankingWithMedal(stationRanking, UserType.DEPARTMENT.getDescription(), param);
244
+    }
245
+
246
+    /**
247
+     * 获取科室在全站内的排名
248
+     */
249
+    private Integer getDepartmentRankInStation(Long deptId, Long stationId, Date startDate, Date endDate) {
250
+        // 获取全站下所有科室的排名
251
+        List<SeizureReportDTO.DepartmentRankingItem> allStationDeptRankings = seizureReportMapper.selectAllDepartmentRankingsInStation(stationId, startDate, endDate);
252
+        // 找到指定科室的排名
253
+        SysDept currentDept = sysDeptService.selectDeptById(deptId);
254
+        if (currentDept != null) {
255
+            for (int i = 0; i < allStationDeptRankings.size(); i++) {
256
+                SeizureReportDTO.DepartmentRankingItem item = allStationDeptRankings.get(i);
257
+                if (item.getDepartmentName().equals(currentDept.getDeptName())) {
258
+                    return i + 1; // 排名从1开始
259
+                }
260
+            }
261
+        }
262
+        return allStationDeptRankings.size() + 1; // 如果未找到,则为最后一名
263
+    }
264
+
265
+    /**
266
+     * 处理单个用户排名和奖牌逻辑(用于个人排名)
267
+     */
268
+    private List<SeizureRankingDto> processRankingWithMedal(SeizureReportDTO.RankingInfo rankingInfo, String userType, RankingQueryParamDto param) {
269
+        if (rankingInfo == null || rankingInfo.getCurrentRank() == null) {
270
+            return new ArrayList<>();
271
+        }
272
+        SeizureRankingDto dto = new SeizureRankingDto();
273
+        dto.setRank(rankingInfo.getCurrentRank());
274
+        dto.setUserType(userType);
275
+        // 根据排名设置奖牌类型
276
+        if (rankingInfo.getCurrentRank() != null) {
277
+            if (rankingInfo.getCurrentRank() == 1) {
278
+                dto.setMedalType(MedalTypeEnum.GOLD.getCode());
279
+                dto.setMedalTypeDesc(MedalTypeEnum.GOLD.getDesc());
280
+            } else if (rankingInfo.getCurrentRank() == 2) {
281
+                dto.setMedalType(MedalTypeEnum.SILVER.getCode());
282
+                dto.setMedalTypeDesc(MedalTypeEnum.SILVER.getDesc());
283
+            } else if (rankingInfo.getCurrentRank() == 3) {
284
+                dto.setMedalType(MedalTypeEnum.BRONZE.getCode());
285
+                dto.setMedalTypeDesc(MedalTypeEnum.BRONZE.getDesc());
286
+            } else if (rankingInfo.getTotalItems() != null &&
287
+                    rankingInfo.getCurrentRank() >= rankingInfo.getTotalItems() - 2 &&
288
+                    rankingInfo.getCurrentRank() <= rankingInfo.getTotalItems()) {
289
+                // 后三名:最后一名哭脸红,倒数第二名哭脸橙,倒数第三名哭脸黄
290
+                int positionFromEnd = rankingInfo.getTotalItems() - rankingInfo.getCurrentRank() + 1;
291
+                if (positionFromEnd == 1) { // 最后一名
292
+                    dto.setMedalType(MedalTypeEnum.CRY_RED.getCode());
293
+                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_RED.getDesc());
294
+                } else if (positionFromEnd == 2) { // 倒数第二名
295
+                    dto.setMedalType(MedalTypeEnum.CRY_ORANGE.getCode());
296
+                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_ORANGE.getDesc());
297
+                } else if (positionFromEnd == 3) { // 倒数第三名
298
+                    dto.setMedalType(MedalTypeEnum.CRY_YELLOW.getCode());
299
+                    dto.setMedalTypeDesc(MedalTypeEnum.CRY_YELLOW.getDesc());
300
+                }
301
+            }
302
+        }
303
+        return Arrays.asList(dto);
304
+    }
305
+
306
+    /**
307
+     * 获取大队在全站内的排名
308
+     */
309
+    public List<SeizureRankingDto> getBrigadeRanking(RankingQueryParamDto param) {
310
+        // 设置全站排名 - 大队排名/全站大队数总和
311
+        SeizureReportDTO.RankingInfo stationRanking = new SeizureReportDTO.RankingInfo();
312
+        Integer deptInStationRank = getBrigadeRankInStation(param.getDeptId(), param.getStationId(), param.getStartDate(), param.getEndDate());
313
+        Integer stationTotalDepts = seizureReportMapper.selectBrigadeCountByStationId(param.getStationId());
314
+        stationRanking.setCurrentRank(deptInStationRank);
315
+        stationRanking.setTotalItems(stationTotalDepts);
316
+        // 处理排名和奖牌逻辑
317
+        return processRankingWithMedal(stationRanking, UserType.BRIGADE.getDescription(), param);
318
+    }
319
+
320
+    /**
321
+     * 获取大队在全站内的排名
322
+     */
323
+    private Integer getBrigadeRankInStation(Long deptId, Long stationId, Date startDate, Date endDate) {
324
+        // 获取全站下所有科室的排名
325
+        List<SeizureReportDTO.BrigadeRankingItem> allStationDeptRankings = seizureReportMapper.selectAllBrigadeRankingsInStation(stationId, startDate, endDate);
326
+        // 找到指定科室的排名
327
+        SysDept currentDept = sysDeptService.selectDeptById(deptId);
328
+        if (currentDept != null) {
329
+            for (int i = 0; i < allStationDeptRankings.size(); i++) {
330
+                SeizureReportDTO.BrigadeRankingItem item = allStationDeptRankings.get(i);
331
+                if (item.getBrigadeName().equals(currentDept.getDeptName())) {
332
+                    return i + 1; // 排名从1开始
333
+                }
334
+            }
335
+        }
336
+        return allStationDeptRankings.size() + 1; // 如果未找到,则为最后一名
337
+    }
338
+
339
+}