Przeglądaj źródła

feat(game-team): 新增队伍列表分页查询功能并优化查询性能

- 添加 selectPageTeamListWithProjects 方法支持包含项目名称的分页查询
- 实现 MyBatis XML 映射查询支持项目名称汇总显示
- 重构服务层代码简化运动员列表 JSON 转换逻辑
- 移除多余注释代码优化查询构建器实现
- 添加项目名称字段到队伍视图对象支持导出功能
zhou 1 tydzień temu
rodzic
commit
9c877987ce

+ 10 - 9
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/GameTeamVo.java

@@ -13,7 +13,6 @@ import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
 
-
 /**
  * 参赛队伍视图对象 game_team
  *
@@ -28,13 +27,13 @@ public class GameTeamVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
-   @ExcelProperty(value = "队伍Id")
+    @ExcelProperty(value = "队伍Id")
     private Long teamId;
 
     /**
      * 赛事ID
      */
-//    @ExcelProperty(value = "赛事ID")
+    // @ExcelProperty(value = "赛事ID")
     private Long eventId;
 
     /**
@@ -51,7 +50,7 @@ public class GameTeamVo implements Serializable {
     /**
      * 赛事名称
      */
-//    @ExcelProperty(value = "赛事名称")
+    // @ExcelProperty(value = "赛事名称")
     private String eventName;
 
     /**
@@ -75,15 +74,18 @@ public class GameTeamVo implements Serializable {
     /**
      * 队员列表
      */
-//    @ExcelProperty(value = "队员列表")
+    // @ExcelProperty(value = "队员列表")
     private String athleteValue;
     private List<Long> athleteList;
 
+    private String projectValue;
+    private List<Long> projectList;
+
     /**
-     * 参与项目列表
+     * 参与项目名称
      */
-//    @ExcelProperty(value = "参与项目列表")
-    private String projectValue;
+    @ExcelProperty(value = "参与项目")
+    private String projectNames;
 
     /**
      * 人数
@@ -116,5 +118,4 @@ public class GameTeamVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
-
 }

+ 10 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/GameTeamMapper.java

@@ -3,6 +3,7 @@ package org.dromara.system.mapper;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.dromara.common.mybatis.annotation.DataColumn;
 import org.dromara.common.mybatis.annotation.DataPermission;
@@ -33,6 +34,15 @@ public interface GameTeamMapper extends BaseMapperPlus<GameTeam, GameTeamVo> {
         return this.selectVoPage(page, queryWrapper);
     }
 
+    /**
+     * 分页查询队伍列表,包含汇总的项目名称
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "gt.create_dept"),
+        @DataColumn(key = "userName", value = "gt.create_by")
+    })
+    Page<GameTeamVo> selectPageTeamListWithProjects(@Param("page") Page<GameTeam> page, @Param("ew") Wrapper<GameTeam> queryWrapper);
+
     /**
      * 获取队伍列表,并进行数据权限控制
      */

+ 75 - 123
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameTeamServiceImpl.java

@@ -25,6 +25,7 @@ import org.dromara.system.domain.vo.GameTeamVo;
 import org.dromara.system.mapper.GameAthleteMapper;
 import org.dromara.system.mapper.GameEventMapper;
 import org.dromara.system.mapper.GameTeamMapper;
+import org.dromara.system.service.IGameEventProjectService;
 import org.dromara.system.service.IGameRankGroupService;
 import org.dromara.system.service.IGameTeamService;
 import org.springframework.stereotype.Service;
@@ -50,6 +51,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
     private final GameEventMapper gameEventMapper;
 
     private final IGameRankGroupService gameRankGroupService;
+    private final IGameEventProjectService gameEventProjectService;
 
     /**
      * 查询参赛队伍
@@ -82,60 +84,22 @@ public class GameTeamServiceImpl implements IGameTeamService {
         if (bo.getEventId() == null) {
             Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
             if (cacheObject instanceof Integer) {
-                bo.setEventId(((Integer) cacheObject).longValue());  // 显式转换为 Long 类型
+                bo.setEventId(((Integer) cacheObject).longValue()); // 显式转换为 Long 类型
             } else if (cacheObject instanceof Long) {
                 bo.setEventId((Long) cacheObject);
             }
         }
         LambdaQueryWrapper<GameTeam> lqw = buildQueryWrapper(bo);
-//        Page<GameTeamVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        Page<GameTeamVo> result = baseMapper.selectPageTeamList(pageQuery.build(), lqw);
-        // 查询领队和队员列表
-        result.getRecords().stream()
-            .map(vo -> {
-                // 处理运动员列表
-                Optional.ofNullable(vo.getAthleteValue())
-                    .filter(StringUtils::isNotBlank)
-                    .ifPresent(athleteValue -> {
-//                        String[] projectIds = athleteValue.split(",");
-                        List<Long> athleteIds = JSONUtil.toList(athleteValue, Long.class);
-//                        List<GameAthlete> athletes = gameAthleteMapper.selectList(
-//                            Wrappers.<GameAthlete>lambdaQuery()
-//                                .in(GameAthlete::getAthleteId, projectIds)
-//                                .select(GameAthlete::getName));
-                        vo.setAthleteList(athleteIds);
-//                        vo.setAthleteValue(athletes.stream()
-//                            .map(GameAthlete::getName)
-//                            .filter(StringUtils::isNotBlank)
-//                            .collect(Collectors.joining(",")));
-                    });
-                // 处理领队
-                Optional.ofNullable(vo.getLeader())
-                    .filter(StringUtils::isNotBlank)
-                    .ifPresent(leaderId -> {
-                        GameAthlete athlete = gameAthleteMapper.selectOne(
-                            Wrappers.<GameAthlete>lambdaQuery()
-                                .eq(GameAthlete::getAthleteId, leaderId)
-                                .select(GameAthlete::getName));
-                        Optional.ofNullable(athlete)
-                            .map(GameAthlete::getName)
-                            .ifPresent(vo::setLeader);
-                    });
-                //处理赛事名称
-                Optional.ofNullable(vo.getEventId())
-                    .filter(ObjectUtil::isNotEmpty)
-                    .ifPresent(eventId -> {
-                        GameEvent gameEvent = gameEventMapper.selectOne(
-                            Wrappers.<GameEvent>lambdaQuery()
-                                .eq(GameEvent::getEventId, eventId)
-                                .select(GameEvent::getEventName));
-                        Optional.ofNullable(gameEvent)
-                            .map(GameEvent::getEventName)
-                            .ifPresent(vo::setEventName);
-                    });
-                return vo;
-            })
-            .toList();  // 收集结果
+        // Page<GameTeamVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        Page<GameTeamVo> result = baseMapper.selectPageTeamListWithProjects(pageQuery.build(), lqw);
+        // 处理队员列表 JSON 转换
+        result.getRecords().forEach(vo -> {
+            if (StringUtils.isNotBlank(vo.getAthleteValue())) {
+                List<Long> athleteIds = JSONUtil.toList(vo.getAthleteValue(), Long.class);
+                vo.setAthleteList(athleteIds);
+            }
+        });
+
         return TableDataInfo.build(result);
     }
 
@@ -150,7 +114,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
         if (bo.getEventId() == null) {
             Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
             if (cacheObject instanceof Integer) {
-                bo.setEventId(((Integer) cacheObject).longValue());  // 显式转换为 Long 类型
+                bo.setEventId(((Integer) cacheObject).longValue()); // 显式转换为 Long 类型
             } else if (cacheObject instanceof Long) {
                 bo.setEventId((Long) cacheObject);
             }
@@ -172,22 +136,21 @@ public class GameTeamServiceImpl implements IGameTeamService {
         lqw.eq(bo.getEventId() != null, GameTeam::getEventId, bo.getEventId());
 
         Optional.ofNullable(bo.getEventName())
-            .filter(StringUtils::isNotBlank)
-            .ifPresent(eventName -> {
-                List<GameEvent> gameEvents = gameEventMapper.selectList(
-                    Wrappers.<GameEvent>lambdaQuery()
-                        .like(GameEvent::getEventName, eventName)
-                        .select(GameEvent::getEventId)
-                );
-                if (CollectionUtils.isNotEmpty(gameEvents)) {
-                    Set<Long> set = gameEvents.stream()
-                        .map(GameEvent::getEventId)
-                        .collect(Collectors.toSet());
-                    lqw.in(GameTeam::getEventId, set);
-                } else {
-                    lqw.apply("1=0");
-                }
-            });
+                .filter(StringUtils::isNotBlank)
+                .ifPresent(eventName -> {
+                    List<GameEvent> gameEvents = gameEventMapper.selectList(
+                            Wrappers.<GameEvent>lambdaQuery()
+                                    .like(GameEvent::getEventName, eventName)
+                                    .select(GameEvent::getEventId));
+                    if (CollectionUtils.isNotEmpty(gameEvents)) {
+                        Set<Long> set = gameEvents.stream()
+                                .map(GameEvent::getEventId)
+                                .collect(Collectors.toSet());
+                        lqw.in(GameTeam::getEventId, set);
+                    } else {
+                        lqw.apply("1=0");
+                    }
+                });
 
         lqw.like(StringUtils.isNotBlank(bo.getTeamName()), GameTeam::getTeamName, bo.getTeamName());
         lqw.like(StringUtils.isNotBlank(bo.getTeamCode()), GameTeam::getTeamCode, bo.getTeamCode());
@@ -212,7 +175,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
         if (bo.getEventId() == null) {
             Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
             if (cacheObject instanceof Integer) {
-                bo.setEventId(((Integer) cacheObject).longValue());  // 显式转换为 Long 类型
+                bo.setEventId(((Integer) cacheObject).longValue()); // 显式转换为 Long 类型
             } else if (cacheObject instanceof Long) {
                 bo.setEventId((Long) cacheObject);
             }
@@ -222,12 +185,11 @@ public class GameTeamServiceImpl implements IGameTeamService {
         }
         GameTeam add = MapstructUtils.convert(bo, GameTeam.class);
         validEntityBeforeSave(add);
-        //查询是否重复
+        // 查询是否重复
         Long count = baseMapper.selectCount(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getEventId, add.getEventId())
-                .eq(GameTeam::getTeamName, add.getTeamName())
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getEventId, add.getEventId())
+                        .eq(GameTeam::getTeamName, add.getTeamName()));
         if (count > 0) {
             throw new ServiceException("队伍名称重复");
         }
@@ -249,7 +211,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
         if (bo.getEventId() == null) {
             Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
             if (cacheObject instanceof Integer) {
-                bo.setEventId(((Integer) cacheObject).longValue());  // 显式转换为 Long 类型
+                bo.setEventId(((Integer) cacheObject).longValue()); // 显式转换为 Long 类型
             } else if (cacheObject instanceof Long) {
                 bo.setEventId((Long) cacheObject);
             }
@@ -266,17 +228,16 @@ public class GameTeamServiceImpl implements IGameTeamService {
      * 保存前的数据校验
      */
     private void validEntityBeforeSave(GameTeam entity) {
-        //TODO 做一些数据校验,如唯一约束
-        //校验队伍编号的唯一性
-        if (entity.getTeamCode() != null){
+        // TODO 做一些数据校验,如唯一约束
+        // 校验队伍编号的唯一性
+        if (entity.getTeamCode() != null) {
             Long count = baseMapper.selectCount(
-                Wrappers.lambdaQuery(GameTeam.class)
-                    .eq(GameTeam::getEventId, entity.getEventId())
-                    .eq(GameTeam::getTeamCode, entity.getTeamCode())
-                    .ne(entity.getTeamId() != null,GameTeam::getTeamId, entity.getTeamId())
-            );
+                    Wrappers.lambdaQuery(GameTeam.class)
+                            .eq(GameTeam::getEventId, entity.getEventId())
+                            .eq(GameTeam::getTeamCode, entity.getTeamCode())
+                            .ne(entity.getTeamId() != null, GameTeam::getTeamId, entity.getTeamId()));
             if (count > 0) {
-                throw new ServiceException(entity.getTeamName()+"的编号已存在!");
+                throw new ServiceException(entity.getTeamName() + "的编号已存在!");
             }
         }
     }
@@ -291,9 +252,9 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
         if (isValid) {
-            //TODO 做一些业务上的校验,判断是否需要校验
+            // TODO 做一些业务上的校验,判断是否需要校验
         }
-        //批量删除前,删除运动员中的关联数据
+        // 批量删除前,删除运动员中的关联数据
         removeTeamFromAthletes(ids);
         return baseMapper.deleteByIds(ids) > 0;
     }
@@ -303,9 +264,8 @@ public class GameTeamServiceImpl implements IGameTeamService {
             return;
         }
         List<GameAthlete> athleteList = gameAthleteMapper.selectList(
-            Wrappers.<GameAthlete>lambdaQuery()
-                .in(GameAthlete::getTeamId, teamIds)
-        );
+                Wrappers.<GameAthlete>lambdaQuery()
+                        .in(GameAthlete::getTeamId, teamIds));
         if (CollectionUtils.isEmpty(athleteList)) {
             return;
         }
@@ -325,15 +285,14 @@ public class GameTeamServiceImpl implements IGameTeamService {
         }
         Long eventId = list.get(0).getEventId();
         Set<String> names = list.stream()
-            .map(GameTeam::getTeamName)
-            .collect(Collectors.toSet());
-        //查询是否重复
+                .map(GameTeam::getTeamName)
+                .collect(Collectors.toSet());
+        // 查询是否重复
         Long count = baseMapper.selectCount(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getEventId, eventId)
-                .in(GameTeam::getTeamName, names)
-        );
-        //批量添加队伍时,运动员列表为空列表而不是null
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getEventId, eventId)
+                        .in(GameTeam::getTeamName, names));
+        // 批量添加队伍时,运动员列表为空列表而不是null
         list.forEach(team -> {
             team.setAthleteValue(new ArrayList<Long>().toString());
         });
@@ -362,9 +321,8 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public List<GameTeamVo> listByIds(Collection<Long> teamIds) {
         List<GameTeamVo> list = baseMapper.selectVoList(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .in(GameTeam::getTeamId, teamIds)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .in(GameTeam::getTeamId, teamIds));
         list.forEach(vo -> {
             vo.setAthleteList(JSONUtil.toList(vo.getAthleteValue(), Long.class));
         });
@@ -403,11 +361,10 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public Map<Long, String> getTeamIdAndNameMap(String eventId) {
         List<GameTeamVo> list = baseMapper.selectVoList(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getEventId, eventId)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getEventId, eventId));
         Map<Long, String> map = list.stream()
-            .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
+                .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
         return map;
     }
 
@@ -420,20 +377,18 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public Map<Long, String> getTeamIdAndNameMap(Collection<Long> teamIds) {
         List<GameTeamVo> list = baseMapper.selectVoList(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getTeamId, teamIds)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getTeamId, teamIds));
         Map<Long, String> map = list.stream()
-            .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
+                .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
         return map;
     }
 
     @Override
     public Long countByEventId(Long eventId) {
         return baseMapper.selectCount(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getEventId, eventId)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getEventId, eventId));
     }
 
     /**
@@ -445,21 +400,19 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public Map<Long, String> queryTeamIdAndName(Set<Long> teamIds) {
         List<GameTeamVo> list = baseMapper.selectVoList(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .in(GameTeam::getTeamId, teamIds)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .in(GameTeam::getTeamId, teamIds));
         Map<Long, String> map = list.stream()
-            .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
+                .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
         return map;
     }
 
     @Override
     public GameTeam queryByName(String teamName, Long eventId) {
         return baseMapper.selectOne(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getTeamName, teamName)
-                .eq(GameTeam::getEventId, eventId)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getTeamName, teamName)
+                        .eq(GameTeam::getEventId, eventId));
     }
 
     @Override
@@ -480,9 +433,9 @@ public class GameTeamServiceImpl implements IGameTeamService {
         }
 
         // 批量更新队伍的排名分组
-//        LambdaUpdateWrapper<GameTeam> updateWrapper = new LambdaUpdateWrapper<>();
-//        updateWrapper.in(GameTeam::getTeamId, teamIds)
-//            .set(GameTeam::getRgId, rgId);
+        // LambdaUpdateWrapper<GameTeam> updateWrapper = new LambdaUpdateWrapper<>();
+        // updateWrapper.in(GameTeam::getTeamId, teamIds)
+        // .set(GameTeam::getRgId, rgId);
 
         return baseMapper.batchUpdateRg(rgId, teamIds);
     }
@@ -490,9 +443,8 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public List<GameTeam> queryTeamByEventId(Long eventId) {
         return baseMapper.selectList(
-            Wrappers.lambdaQuery(GameTeam.class)
-                .eq(GameTeam::getEventId, eventId)
-        );
+                Wrappers.lambdaQuery(GameTeam.class)
+                        .eq(GameTeam::getEventId, eventId));
     }
 
     @Override

+ 28 - 0
ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/GameTeamMapper.xml

@@ -48,4 +48,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
         ORDER BY gt.team_id DESC
     </select>
+
+    <select id="selectPageTeamListWithProjects" resultType="org.dromara.system.domain.vo.GameTeamVo">
+        SELECT
+            gt.team_id,
+            gt.event_id,
+            gt.rg_id,
+            (SELECT rg_name FROM game_rank_group WHERE rg_id = gt.rg_id) as rgName,
+            gt.team_name,
+            gt.team_code,
+            (SELECT event_name FROM game_event WHERE event_id = gt.event_id) as eventName,
+            (SELECT name FROM game_athlete WHERE athlete_id = gt.leader) as leader,
+            gt.athlete_value as athleteValue,
+            gt.project_value as projectValue,
+            gt.athlete_num as athleteNum,
+            gt.number_range as numberRange,
+            gt.team_describe as teamDescribe,
+            gt.status,
+            gt.remark,
+            gt.create_time as createTime,
+            gt.update_time as updateTime,
+            (SELECT GROUP_CONCAT(DISTINCT gp.project_name SEPARATOR ', ')
+             FROM game_athlete ga
+             JOIN game_event_project gp ON (JSON_CONTAINS(ga.project_value, CAST(gp.project_id AS CHAR)) OR JSON_CONTAINS(ga.project_value, CONCAT('"', gp.project_id, '"')))
+             WHERE ga.team_id = gt.team_id AND ga.del_flag = '0' AND gp.del_flag = '0' AND gp.classification != '0'
+            ) as projectNames
+        FROM game_team gt
+        ${ew.customSqlSegment}
+    </select>
 </mapper>