Преглед изворни кода

feat(athlete): 添加运动员项目筛选功能并优化数据处理性能

- 在GameAthleteBo中新增projectId字段用于项目筛选
- 实现批量项目ID字符串转列表转换功能,提升数据处理效率
- 添加批量项目ID转项目名称功能,减少数据库查询次数
- 使用JSON_CONTAINS函数实现按项目ID筛选运动员功能
- 移除大量调试日志输出以提升系统性能
- 重构运动员列表查询逻辑,优化分页数据加载速度
zhou пре 3 дана
родитељ
комит
b469f753e6

+ 1 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/GameAthleteBo.java

@@ -123,6 +123,7 @@ public class GameAthleteBo extends BaseEntity {
      * 参与项目列表
      */
 //    @NotBlank(message = "参与项目列表不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long projectId;
     private String projectValue;
     private List<Long> projectList;
 

+ 56 - 50
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameAthleteServiceImpl.java

@@ -197,53 +197,64 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
         LambdaQueryWrapper<GameAthlete> lqw = buildQueryWrapper(bo);
 //        Page<GameAthleteVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         Page<GameAthleteVo> result = baseMapper.selectPageAthleteList(pageQuery.build(), lqw);
-        result.getRecords().stream()
-            .map(vo -> {
-                Optional.ofNullable(vo.getProjectValue())
-                    .filter(StringUtils::isNotBlank)
-                    .ifPresent(projectValue -> {
-//                        String[] projectIds = projectValue.split(",");
-                        List<Long> projectIds = JSONUtil.toList(projectValue, Long.class);
-                        if (CollUtil.isNotEmpty(projectIds)) {
-                            List<GameEventProjectVo> projects =
-                                gameEventProjectService.listProjectsByEventIdAndProjectIndex(
-                                    vo.getEventId(), projectIds);
-                            vo.setProjectList(projectIds);
-                        }
-//                        vo.setProjectValue(projects.stream()
-//                            .map(GameEventProjectVo::getProjectName)
-//                            .filter(StringUtils::isNotBlank)  // 过滤项目名为空的情况
-//                            .collect(Collectors.joining(",")));
-                    });
-                Optional.ofNullable(vo.getEventId())
-                    .filter(ObjectUtil::isNotEmpty)
-                    .ifPresent(eventId -> {
-                        GameEventVo gameEventVo = gameEventService.queryById(vo.getEventId());
-                        if (gameEventVo != null) {
-                            vo.setEventName(gameEventVo.getEventName());
-                        } else {
-                            log.warn("赛事ID {} 对应的赛事信息不存在", eventId);
-                            vo.setEventName("未知赛事");
-                        }
-                    });
-
-                Optional.ofNullable(vo.getTeamId())
-                    .filter(ObjectUtil::isNotEmpty)
-                    .ifPresent(teamId -> {
-                        GameTeamVo gameTeamVo = gameTeamService.queryById(vo.getTeamId());
-                        if (gameTeamVo != null) {
-                            vo.setTeamName(gameTeamVo.getTeamName());
-                        } else {
-                            log.warn("队伍ID {} 对应的队伍信息不存在", teamId);
-                            vo.setTeamName("未知队伍");
-                        }
-                    });
-                return vo;
-            })
-            .toList();  // 收集结果
+        if (CollUtil.isNotEmpty(result.getRecords())) {
+            convertProjectIdsToList(result.getRecords());
+            convertProjectIdsToNamesForPage(result.getRecords());
+        }
         return TableDataInfo.build(result);
     }
 
+    /**
+     * 批量将项目ID字符串转换为项目ID列表
+     */
+    private void convertProjectIdsToList(List<GameAthleteVo> athleteList) {
+        athleteList.forEach(vo -> {
+            Optional.ofNullable(vo.getProjectValue())
+                .filter(StringUtils::isNotBlank)
+                .ifPresent(projectValue -> {
+                    try {
+                        List<Long> projectIds = JSONUtil.toList(projectValue, Long.class);
+                        vo.setProjectList(projectIds);
+                    } catch (Exception e) {
+                        log.error("解析项目数据失败 - 运动员: {}, projectValue: {}", vo.getName(), projectValue, e);
+                        vo.setProjectList(new ArrayList<>());
+                    }
+                });
+        });
+    }
+
+    /**
+     * 批量将项目ID列表转换为项目名称(分页场景专用)
+     */
+    private void convertProjectIdsToNamesForPage(List<GameAthleteVo> athleteList) {
+        Set<Long> allProjectIds = athleteList.stream()
+            .map(GameAthleteVo::getProjectList)
+            .filter(CollUtil::isNotEmpty)
+            .flatMap(List::stream)
+            .collect(Collectors.toSet());
+
+        if (CollUtil.isEmpty(allProjectIds)) {
+            return;
+        }
+
+        Map<Long, String> projectIdToNameMap = gameEventProjectMapper.selectList(
+            new LambdaQueryWrapper<GameEventProject>()
+                .in(GameEventProject::getProjectId, allProjectIds)
+        ).stream().collect(Collectors.toMap(
+            GameEventProject::getProjectId,
+            GameEventProject::getProjectName
+        ));
+
+        athleteList.forEach(athlete -> {
+            if (CollUtil.isNotEmpty(athlete.getProjectList())) {
+                List<String> projectNames = athlete.getProjectList().stream()
+                    .map(projectId -> projectIdToNameMap.getOrDefault(projectId, "未知项目"))
+                    .collect(Collectors.toList());
+                athlete.setProjectNames(String.join(",", projectNames));
+            }
+        });
+    }
+
     /**
      * 查询符合条件的参赛队员列表
      *
@@ -421,7 +432,6 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
                 allProjectIds.addAll(athlete.getProjectList());
             }
         });
-
         // 2. 批量查询项目信息
         Map<Long, String> projectIdToNameMap = new HashMap<>();
         if (CollUtil.isNotEmpty(allProjectIds)) {
@@ -431,7 +441,6 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
             projectIdToNameMap = projects.stream()
                 .collect(Collectors.toMap(GameEventProject::getProjectId, GameEventProject::getProjectName));
         }
-
         // 3. 设置项目名称列表
         final Map<Long, String> finalProjectMap = projectIdToNameMap;
         athleteList.forEach(athlete -> {
@@ -451,7 +460,6 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
         LambdaQueryWrapper<GameAthlete> lqw = Wrappers.lambdaQuery();
         lqw.orderByAsc(GameAthlete::getAthleteId);
         lqw.eq(bo.getEventId() != null, GameAthlete::getEventId, bo.getEventId());
-
         // 通过赛事名称模糊查询
         if (StringUtils.isNotBlank(bo.getEventName())) {
             GameEventBo gameEventBo = new GameEventBo();
@@ -466,9 +474,7 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
                 lqw.apply("1=0");
             }
         }
-
         lqw.eq(bo.getTeamId() != null, GameAthlete::getTeamId, bo.getTeamId());
-
         // 通过队伍名称模糊查询
         if (StringUtils.isNotBlank(bo.getTeamName())) {
             GameTeamBo gameTeamBo = new GameTeamBo();
@@ -483,13 +489,13 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
                 lqw.apply("1=0");
             }
         }
-
         lqw.like(StringUtils.isNotBlank(bo.getAthleteCode()), GameAthlete::getAthleteCode, bo.getAthleteCode());
         lqw.like(StringUtils.isNotBlank(bo.getName()), GameAthlete::getName, bo.getName());
         lqw.eq(StringUtils.isNotBlank(bo.getGroupType()), GameAthlete::getGroupType, bo.getGroupType());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), GameAthlete::getStatus, bo.getStatus());
         lqw.like(StringUtils.isNotBlank(bo.getPhone()), GameAthlete::getPhone, bo.getPhone());
         lqw.like(StringUtils.isNotBlank(bo.getLocation()), GameAthlete::getLocation, bo.getLocation());
+        lqw.apply(bo.getProjectId() != null, "JSON_CONTAINS(project_value, JSON_ARRAY({0}))", bo.getProjectId());
         return lqw;
     }
 

+ 27 - 36
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameScoreServiceImpl.java

@@ -289,16 +289,12 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
         if ("0".equals(classification)) {
             // 个人项目:获取运动员数据
-            log.info("处理个人项目数据");
             allDataList = getIndividualProjectData(eventId, projectId, searchValue, pageQuery);
         } else {
             // 团体项目:获取队伍数据
-            log.info("处理团体项目数据");
             allDataList = getTeamProjectData(eventId, projectId, searchValue, pageQuery);
         }
 
-        log.info("获取到总数据量: {}", allDataList.size());
-
         // 计算总数
         int total = allDataList.size();
 
@@ -308,13 +304,10 @@ public class GameScoreServiceImpl implements IGameScoreService {
         int startIndex = (pageNum - 1) * pageSize;
         int endIndex = Math.min(startIndex + pageSize, total);
 
-        log.info("分页参数: pageNum={}, pageSize={}, startIndex={}, endIndex={}", pageNum, pageSize, startIndex, endIndex);
-
         // 获取当前页的数据
         List<Map<String, Object>> pageData = new ArrayList<>();
         if (startIndex <= total) {
             pageData = allDataList.subList(startIndex, endIndex);
-            log.info("当前页数据量: {}", pageData.size());
         } else {
             log.warn("分页索引超出范围: startIndex={}, total={}", startIndex, total);
         }
@@ -324,7 +317,6 @@ public class GameScoreServiceImpl implements IGameScoreService {
         page.setRecords(pageData);
         page.setTotal(total);
 
-        log.info("分页结果: 总数={}, 当前页数据量={}", total, pageData.size());
         return TableDataInfo.build(page);
     }
 
@@ -344,10 +336,9 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
         // 查询参与该项目的运动员
         List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, searchValue);
-        log.info("查询到运动员数量: {}", athletes.size());
 
         for (GameAthleteVo athlete : athletes) {
-            log.info("处理运动员: athleteId={}, name={}, teamId={}", athlete.getAthleteId(), athlete.getName(), athlete.getTeamId());
+//            log.info("处理运动员: athleteId={}, name={}, teamId={}", athlete.getAthleteId(), athlete.getName(), athlete.getTeamId());
 
             Map<String, Object> data = new HashMap<>();
 //            data.put("id", athlete.getAthleteId());
@@ -403,7 +394,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 data.put("teamPerformance", score.getTeamPerformance());
                 data.put("scoreRank", score.getScoreRank());
                 data.put("updateTime", score.getUpdateTime());
-                log.info("获取到成绩信息: scoreId={}, scorePoint={}", score.getScoreId(), score.getScorePoint());
+//                log.info("获取到成绩信息: scoreId={}, scorePoint={}", score.getScoreId(), score.getScorePoint());
             } else {
                 data.put("scoreId", 0);
                 data.put("scorePoint", 0);
@@ -411,13 +402,13 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 data.put("teamPerformance", 0.0);
                 data.put("scoreRank", 0);
                 data.put("updateTime", "");
-                log.info("未找到成绩信息,使用默认值");
+//                log.info("未找到成绩信息,使用默认值");
             }
             data.put("classification", project.getClassification());
             resultList.add(data);
         }
 
-        log.info("个人项目数据处理完成,返回数据量: {}", resultList.size());
+//        log.info("个人项目数据处理完成,返回数据量: {}", resultList.size());
         return resultList;
     }
 
@@ -501,47 +492,47 @@ public class GameScoreServiceImpl implements IGameScoreService {
                                             bo.getIndividualPerformance() == null &&
                                             bo.getTeamPerformance() == null);
 
-        log.info("手动排名计算判断: scoreId={}, athleteId={}, teamId={}, individualPerformance={}, teamPerformance={}, isManualRanking={}",
-                bo.getScoreId(), bo.getAthleteId(), bo.getTeamId(), bo.getIndividualPerformance(), bo.getTeamPerformance(), isManualRankingCalculation);
+//        log.info("手动排名计算判断: scoreId={}, athleteId={}, teamId={}, individualPerformance={}, teamPerformance={}, isManualRanking={}",
+//                bo.getScoreId(), bo.getAthleteId(), bo.getTeamId(), bo.getIndividualPerformance(), bo.getTeamPerformance(), isManualRankingCalculation);
 
         if (isManualRankingCalculation) {
             // 手动排名计算:直接重新计算排名和积分
-            log.info("检测到手动排名计算请求,跳过成绩更新,直接计算排名");
+//            log.info("检测到手动排名计算请求,跳过成绩更新,直接计算排名");
             Boolean result = recalculateRankingsAndPoints(bo.getEventId(), bo.getProjectId());
-            log.info("手动排名计算完成,结果: {}", result);
+//            log.info("手动排名计算完成,结果: {}", result);
             return result;
         }
 
         // 获取项目信息,判断是个人项目还是团体项目
         GameEventProjectVo project = gameEventProjectService.queryById(bo.getProjectId());
-        log.info("项目信息: projectId: {}, classification: {}", bo.getProjectId(),
-        project != null ? project.getClassification() : "null");
+//        log.info("项目信息: projectId: {}, classification: {}", bo.getProjectId(),
+//        project != null ? project.getClassification() : "null");
 
         Boolean result = false;
 
         if (project != null && ProjectClassification.TEAM.getValue().equals(project.getClassification())) {
             // 团体项目:为队伍中的所有运动员创建或更新成绩记录
-            log.info("处理团体项目成绩更新");
+//            log.info("处理团体项目成绩更新");
             result = handleTeamScoreUpdate(bo);
         } else {
             // 个人项目:直接更新或插入
-            log.info("处理个人项目成绩更新,scoreId: {}", bo.getScoreId());
+//            log.info("处理个人项目成绩更新,scoreId: {}", bo.getScoreId());
             if (bo.getScoreId() != null && bo.getScoreId() > 0) {
                 result = updateByBo(bo);
-                log.info("更新现有成绩记录,结果: {}", result);
+//                log.info("更新现有成绩记录,结果: {}", result);
             } else {
                 result = insertByBo(bo);
-                log.info("插入新成绩记录,结果: {}", result);
+//                log.info("插入新成绩记录,结果: {}", result);
             }
         }
 
         if (result) {
             // 重新计算排名和积分
-            log.info("开始重新计算排名和积分");
+//            log.info("开始重新计算排名和积分");
             recalculateRankingsAndPoints(bo.getEventId(), bo.getProjectId());
         }
 
-        log.info("成绩更新处理完成,结果: {}", result);
+//        log.info("成绩更新处理完成,结果: {}", result);
         return result;
     }
 
@@ -556,14 +547,14 @@ public class GameScoreServiceImpl implements IGameScoreService {
             List<GameAthleteVo> teamAthletes = gameAthleteService.queryListByEventIdAndProjectId(
                 bo.getEventId(), bo.getProjectId(), null);
 
-            log.info("找到参与项目的运动员数量: {}", teamAthletes.size());
+//            log.info("找到参与项目的运动员数量: {}", teamAthletes.size());
 
             // 过滤出属于指定队伍的运动员
             List<GameAthleteVo> relevantAthletes = teamAthletes.stream()
                 .filter(athlete -> athlete.getTeamId() != null && athlete.getTeamId().equals(bo.getTeamId()))
                 .toList();
 
-            log.info("队伍 {} 的运动员数量: {}", bo.getTeamId(), relevantAthletes.size());
+//            log.info("队伍 {} 的运动员数量: {}", bo.getTeamId(), relevantAthletes.size());
 
             if (relevantAthletes.isEmpty()) {
                 log.warn("未找到队伍 {} 的运动员", bo.getTeamId());
@@ -572,7 +563,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
             // 为每个运动员创建或更新成绩记录
             for (GameAthleteVo athlete : relevantAthletes) {
-                log.info("处理运动员 {} 的成绩记录", athlete.getAthleteId());
+//                log.info("处理运动员 {} 的成绩记录", athlete.getAthleteId());
 
                 GameScoreBo athleteScoreBo = new GameScoreBo();
                 athleteScoreBo.setEventId(bo.getEventId());
@@ -592,19 +583,19 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 GameScoreVo existingScore = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), bo.getProjectId());
                 if (existingScore != null) {
                     // 更新现有记录
-                    log.info("更新运动员 {} 的现有成绩记录", athlete.getAthleteId());
+//                    log.info("更新运动员 {} 的现有成绩记录", athlete.getAthleteId());
                     athleteScoreBo.setScoreId(existingScore.getScoreId());
                     Boolean updateResult = updateByBo(athleteScoreBo);
-                    log.info("更新结果: {}", updateResult);
+//                    log.info("更新结果: {}", updateResult);
                 } else {
                     // 插入新记录
-                    log.info("为运动员 {} 插入新成绩记录", athlete.getAthleteId());
+//                    log.info("为运动员 {} 插入新成绩记录", athlete.getAthleteId());
                     Boolean insertResult = insertByBo(athleteScoreBo);
-                    log.info("插入结果: {}", insertResult);
+//                    log.info("插入结果: {}", insertResult);
                 }
             }
 
-            log.info("团体项目成绩更新处理完成");
+//            log.info("团体项目成绩更新处理完成");
             return true;
         } catch (Exception e) {
             log.error("处理团体项目成绩更新失败", e);
@@ -659,7 +650,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
         }
 
         String orderType = project.getOrderType();
-        log.info("个人项目排名计算,projectId: {}, orderType: {}", projectId, orderType);
+//        log.info("个人项目排名计算,projectId: {}, orderType: {}", projectId, orderType);
 
         // 根据orderType决定排序方式
         // orderType: 0-升序(成绩越小越好),1-降序(成绩越大越好)
@@ -778,7 +769,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
         }
 
         String orderType = project.getOrderType();
-        log.info("团体项目排名计算,projectId: {}, orderType: {}", projectId, orderType);
+//        log.info("团体项目排名计算,projectId: {}, orderType: {}", projectId, orderType);
 
         // 按队伍ID分组,获取每个队伍的最佳成绩
         Map<Long, BigDecimal> teamBestPerformance = new HashMap<>();
@@ -1616,7 +1607,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 workbook.write(response.getOutputStream());
             }
 
-            log.info("成绩详情导出完成");
+//            log.info("成绩详情导出完成");
 
         } catch (Exception e) {
             log.error("导出成绩详情失败", e);