Browse Source

fix:修复poi导入报名表,如果有该队伍则加人,没有该队伍就分配

wenkai 3 weeks ago
parent
commit
65cdeb9ef9

+ 2 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameTeamService.java

@@ -135,4 +135,6 @@ public interface IGameTeamService {
      * @return 结果
      */
     Boolean moveGroup(List<Long> teamIds, Long rgId);
+
+    List<GameTeam> queryTeamByEventId(Long eventId);
 }

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

@@ -485,12 +485,13 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
 
     @Override
     public String queryMaxNumber(Long teamId) {
-        return baseMapper.selectOne(
+        GameAthlete gameAthlete = baseMapper.selectOne(
             Wrappers.lambdaQuery(GameAthlete.class)
                 .eq(GameAthlete::getTeamId, teamId)
                 .orderByDesc(GameAthlete::getAthleteCode)
                 .select(GameAthlete::getAthleteCode)
                 .last("limit 1")
-        ).getAthleteCode();
+        );
+        return gameAthlete != null ? gameAthlete.getAthleteCode() : "0";
     }
 }

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

@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -19,7 +18,6 @@ import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.system.domain.GameAthlete;
 import org.dromara.system.domain.GameEvent;
 import org.dromara.system.domain.GameTeam;
-import org.dromara.system.domain.bo.GameRankGroupBo;
 import org.dromara.system.domain.bo.GameTeamBo;
 import org.dromara.system.domain.constant.GameEventConstant;
 import org.dromara.system.domain.vo.GameRankGroupVo;
@@ -458,4 +456,12 @@ public class GameTeamServiceImpl implements IGameTeamService {
 
         return baseMapper.batchUpdateRg(rgId, teamIds);
     }
+
+    @Override
+    public List<GameTeam> queryTeamByEventId(Long eventId) {
+        return baseMapper.selectList(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getEventId, eventId)
+        );
+    }
 }

+ 264 - 77
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/IEnrollServiceImpl.java

@@ -13,14 +13,17 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.ObjectUtils;
 import org.dromara.system.domain.GameTeam;
 import org.dromara.system.domain.bo.EnrollBo;
 import org.dromara.system.domain.bo.GameAthleteBo;
 import org.dromara.system.domain.bo.GameTeamBo;
 import org.dromara.system.domain.vo.EnrollProjectVo;
-import org.dromara.system.service.*;
+import org.dromara.system.domain.vo.GameTeamVo;
+import org.dromara.system.service.IEnrollService;
+import org.dromara.system.service.IGameAthleteService;
+import org.dromara.system.service.IGameEventProjectService;
+import org.dromara.system.service.IGameTeamService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -30,6 +33,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -175,14 +179,14 @@ public class IEnrollServiceImpl implements IEnrollService {
     @Override
     public Boolean importDataForPoi(MultipartFile file, Long eventId) {
         //查询赛事下是否已经有报名信息,如果有就禁止导入
-        Long count = gameAthleteService.countByEventId(eventId);
-        if (count > 0) {
-            throw new ServiceException("该赛事下已经有报名信息,禁止导入");
-        }
-        count = gameTeamService.countByEventId(eventId);
-        if (count > 0) {
-            throw new ServiceException("该赛事下已经有报名信息,禁止导入");
-        }
+        // Long count = gameAthleteService.countByEventId(eventId);
+        // if (count > 0) {
+        //     throw new ServiceException("该赛事下已经有报名信息,禁止导入");
+        // }
+        // count = gameTeamService.countByEventId(eventId);
+        // if (count > 0) {
+        //     throw new ServiceException("该赛事下已经有报名信息,禁止导入");
+        // }
         //1.解析报名信息
         List<EnrollProjectVo> enrollList = parseData(file);
         //2.保存报名信息
@@ -456,99 +460,208 @@ public class IEnrollServiceImpl implements IEnrollService {
      * @param eventId
      * @return
      */
+    // @Transactional(rollbackFor = Exception.class)
+    // public boolean saveEnrollData(List<EnrollProjectVo> dataList, Long eventId) {
+    //     // 1. 根据队伍分类成Map
+    //     Map<String, List<EnrollProjectVo>> groupedByTeam = dataList.stream()
+    //         .collect(Collectors.groupingBy(EnrollProjectVo::getTeamName));
+    //     // 查询当前赛事下的项目 名称和id映射关系
+    //     Map<String, Long> projectList = gameEventProjectService.mapProjectAndProjectId(eventId);
+    //     // 1.2 根据队伍生成号码段
+    //     Map<String, String> numberRanges = new HashMap<>();
+    //     Map<String, AtomicInteger> currentNumbers = new HashMap<>(); // 记录每个队伍当前分配到的号码
+    //     AtomicInteger teamIndex = new AtomicInteger(1);
+    //     Snowflake snowflake = IdUtil.createSnowflake(1, 1);
+    //
+    //     for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
+    //         String teamName = entry.getKey();
+    //         String range = generateNumberRange(dataList.size(), teamIndex.getAndIncrement());
+    //         numberRanges.put(teamName, range);
+    //
+    //         // 解析起始号码作为初始值
+    //         int startNum = Integer.parseInt(range.split("-")[0]);
+    //         currentNumbers.put(teamName, new AtomicInteger(startNum));
+    //     }
+    //
+    //     // 2. 保存参赛队伍 & 队员
+    //     for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
+    //         String teamName = entry.getKey();
+    //         List<EnrollProjectVo> athletes = entry.getValue();
+    //         GameTeamBo gameTeamBo = new GameTeamBo();
+    //         gameTeamBo.setTeamId(snowflake.nextId());
+    //         Long teamId = gameTeamBo.getTeamId();
+    //         // 获取该队伍的当前编号计数器
+    //         AtomicInteger currentNumber = currentNumbers.get(teamName);
+    //         int width = (dataList.size() > 100) ? 5 : 4; // 决定格式化宽度
+    //         List<Long> athletesId = new ArrayList<>();
+    //         // 3. 保存参赛队员
+    //         for (EnrollProjectVo enrollInfo : athletes) {
+    //             GameAthleteBo gameAthleteBo = new GameAthleteBo();
+    //             gameAthleteBo.setEventId(eventId);
+    //             gameAthleteBo.setTeamId(teamId);
+    //             gameAthleteBo.setTeamName(teamName);
+    //             // 分配编号:从当前计数器获取并递增
+    //             int assignedNumber = currentNumber.getAndIncrement();
+    //             String formattedCode = String.format("%0" + width + "d", assignedNumber);
+    //             gameAthleteBo.setAthleteCode(formattedCode);
+    //
+    //             gameAthleteBo.setName(enrollInfo.getName());
+    //             gameAthleteBo.setGender(enrollInfo.getSex());
+    //             gameAthleteBo.setAge(Long.valueOf(enrollInfo.getAge()));
+    //             gameAthleteBo.setPhone(enrollInfo.getPhone());
+    //             gameAthleteBo.setUnit(teamName);
+    //             Map<String, Boolean> selectProjects = enrollInfo.getProjectSelections();
+    //             //查询出对应的赛事id
+    //             List<Long> selectionProjectIds = new ArrayList<>();
+    //             for (Map.Entry<String, Boolean> selectProject : selectProjects.entrySet()) {
+    //                 Long projectId = projectList.get(selectProject.getKey());
+    //                 if (ObjectUtils.isNotEmpty(projectId)) {
+    //                     selectionProjectIds.add(projectId);
+    //                 }
+    //             }
+    //             gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(selectionProjectIds));
+    //
+    //             gameAthleteBo.setStatus("0");
+    //
+    //             gameAthleteService.insertByBo(gameAthleteBo);
+    //             athletesId.add(gameAthleteBo.getAthleteId());
+    //         }
+    //
+    //         gameTeamBo.setEventId(eventId);
+    //         gameTeamBo.setTeamName(teamName);
+    //         // gameTeamBo.setTeamCode("");
+    //         gameTeamBo.setLeader(athletes.get(0).getLeader());
+    //         gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(athletesId));
+    //         gameTeamBo.setAthleteNum(Long.valueOf(athletes.size()));
+    //         gameTeamBo.setNumberRange(numberRanges.get(teamName));
+    //         gameTeamBo.setStatus("0");
+    //         gameTeamService.insertByBo(gameTeamBo);
+    //
+    //
+    //     }
+    //     return true;
+    // }
     @Transactional(rollbackFor = Exception.class)
     public boolean saveEnrollData(List<EnrollProjectVo> dataList, Long eventId) {
         // 1. 根据队伍分类成Map
         Map<String, List<EnrollProjectVo>> groupedByTeam = dataList.stream()
             .collect(Collectors.groupingBy(EnrollProjectVo::getTeamName));
-        // 查询当前赛事下的项目 名称和id映射关系
-        Map<String, Long> projectList = gameEventProjectService.mapProjectAndProjectId(eventId);
-        // 1.2 根据队伍生成号码段
-        Map<String, String> numberRanges = new HashMap<>();
-        Map<String, AtomicInteger> currentNumbers = new HashMap<>(); // 记录每个队伍当前分配到的号码
-        AtomicInteger teamIndex = new AtomicInteger(1);
-        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
 
-        for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
-            String teamName = entry.getKey();
-            String range = generateNumberRange(dataList.size(), teamIndex.getAndIncrement());
-            numberRanges.put(teamName, range);
+        // 查询当前赛事下的项目名称和id映射关系
+        Map<String, Long> projectList = gameEventProjectService.mapProjectAndProjectId(eventId);
 
-            // 解析起始号码作为初始值
-            int startNum = Integer.parseInt(range.split("-")[0]);
-            currentNumbers.put(teamName, new AtomicInteger(startNum));
+        // 查询当前赛事下已存在的队伍
+        List<GameTeam> existingTeams = gameTeamService.queryTeamByEventId(eventId);
+        Map<String, GameTeam> existingTeamMap = existingTeams.stream()
+            .collect(Collectors.toMap(GameTeam::getTeamName, Function.identity()));
+
+        // 查询当前赛事最大的号码段结束值,用于确定新队伍的起始号码
+        Integer maxEventNumber;
+        GameTeam maxNumberTeam = gameTeamService.queryMaxNumber(eventId);
+        if (maxNumberTeam != null && maxNumberTeam.getNumberRange() != null) {
+            String[] rangeParts = maxNumberTeam.getNumberRange().split("-");
+            maxEventNumber = Integer.valueOf(rangeParts[1]);
+        } else {
+            maxEventNumber = 0;
         }
-        // 2. 保存参赛队伍 & 队员
+
+        // 计算新队伍的起始队伍编号(从当前最大号码段的下一个300倍数开始)
+        int nextTeamIndex = (maxEventNumber / 300) + 1;
+        AtomicInteger teamIndexCounter = new AtomicInteger(nextTeamIndex);
+
+        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
+        int width = (dataList.size() > 100) ? 5 : 4; // 决定格式化宽度
+
+        // 2. 处理每个队伍
         for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
             String teamName = entry.getKey();
             List<EnrollProjectVo> athletes = entry.getValue();
-            GameTeamBo gameTeamBo = new GameTeamBo();
-            gameTeamBo.setTeamId(snowflake.nextId());
-            Long teamId = gameTeamBo.getTeamId();
-            // 获取该队伍的当前编号计数器
-            AtomicInteger currentNumber = currentNumbers.get(teamName);
-            int width = (dataList.size() > 100) ? 5 : 4; // 决定格式化宽度
-            List<Long> athletesId = new ArrayList<>();
-            // 3. 保存参赛队员
-            for (EnrollProjectVo enrollInfo : athletes) {
-                GameAthleteBo gameAthleteBo = new GameAthleteBo();
-                gameAthleteBo.setEventId(eventId);
-                gameAthleteBo.setTeamId(teamId);
-                gameAthleteBo.setTeamName(teamName);
-                // 分配编号:从当前计数器获取并递增
-                int assignedNumber = currentNumber.getAndIncrement();
-                String formattedCode = String.format("%0" + width + "d", assignedNumber);
-                gameAthleteBo.setAthleteCode(formattedCode);
-
-                gameAthleteBo.setName(enrollInfo.getName());
-                gameAthleteBo.setGender(enrollInfo.getSex());
-                gameAthleteBo.setAge(Long.valueOf(enrollInfo.getAge()));
-                gameAthleteBo.setPhone(enrollInfo.getPhone());
-                gameAthleteBo.setUnit(teamName);
-                Map<String, Boolean> selectProjects = enrollInfo.getProjectSelections();
-                //查询出对应的赛事id
-                List<Long> selectionProjectIds = new ArrayList<>();
-                for (Map.Entry<String, Boolean> selectProject : selectProjects.entrySet()) {
-                    Long projectId = projectList.get(selectProject.getKey());
-                    if (ObjectUtils.isNotEmpty(projectId)) {
-                        selectionProjectIds.add(projectId);
+
+            Long teamId;
+            AtomicInteger currentNumber;
+            boolean isNewTeam = false;
+            String numberRange = "";
+
+            // 判断队伍是否已存在
+            if (existingTeamMap.containsKey(teamName)) {
+                // 队伍已存在,使用现有队伍的号码段
+                GameTeam existingTeam = existingTeamMap.get(teamName);
+                teamId = existingTeam.getTeamId();
+                numberRange = existingTeam.getNumberRange();
+
+                try {
+                    // 尝试查询该队伍的最大队员编号
+                    String maxNumberStr = gameAthleteService.queryMaxNumber(teamId);
+                    Integer maxNumber = Integer.valueOf(maxNumberStr);
+
+                    // 如果最大编号为0,说明队伍实际上没有队员,从号码段起始开始
+                    if (maxNumber == 0) {
+                        String[] rangeParts = numberRange.split("-");
+                        int startNumber = Integer.valueOf(rangeParts[0]);
+                        currentNumber = new AtomicInteger(startNumber);
+                    } else {
+                        // 成功获取到有效编号,续着分配
+                        currentNumber = new AtomicInteger(maxNumber + 1);
                     }
+                } catch (Exception e) {
+                    // 出现异常,从号码段起始开始分配
+                    String[] rangeParts = numberRange.split("-");
+                    int startNumber = Integer.valueOf(rangeParts[0]);
+                    currentNumber = new AtomicInteger(startNumber);
                 }
-                gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(selectionProjectIds));
-
-                gameAthleteBo.setStatus("0");
+            } else {
+                // 队伍不存在,创建新队伍并分配新的300号码段
+                isNewTeam = true;
+                teamId = snowflake.nextId();
+
+                // 为新队伍生成300个号码段
+                int teamIndex = teamIndexCounter.getAndIncrement();
+                numberRange = generateNumberRange(dataList.size(), teamIndex);
+
+                // 解析号码段起始号码
+                String[] rangeParts = numberRange.split("-");
+                int startNumber = Integer.valueOf(rangeParts[0]);
+                currentNumber = new AtomicInteger(startNumber);
+            }
 
+            // 保存队员信息
+            List<Long> athletesId = new ArrayList<>();
+            for (EnrollProjectVo enrollInfo : athletes) {
+                GameAthleteBo gameAthleteBo = createAthleteBo(enrollInfo, eventId, teamId, teamName,
+                    currentNumber, width, projectList);
                 gameAthleteService.insertByBo(gameAthleteBo);
                 athletesId.add(gameAthleteBo.getAthleteId());
             }
 
-            gameTeamBo.setEventId(eventId);
-            gameTeamBo.setTeamName(teamName);
-            // gameTeamBo.setTeamCode("");
-            gameTeamBo.setLeader(athletes.get(0).getLeader());
-            gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(athletesId));
-            gameTeamBo.setAthleteNum(Long.valueOf(athletes.size()));
-            gameTeamBo.setNumberRange(numberRanges.get(teamName));
-            gameTeamBo.setStatus("0");
-            gameTeamService.insertByBo(gameTeamBo);
-
-
+            if (isNewTeam) {
+                // 保存新队伍信息
+                GameTeamBo gameTeamBo = new GameTeamBo();
+                gameTeamBo.setTeamId(teamId);
+                gameTeamBo.setEventId(eventId);
+                gameTeamBo.setTeamName(teamName);
+                gameTeamBo.setLeader(athletes.get(0).getLeader());
+                gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(athletesId));
+                gameTeamBo.setAthleteNum(Long.valueOf(athletes.size()));
+                gameTeamBo.setNumberRange(numberRange); // 设置300个号码段
+                gameTeamBo.setStatus("0");
+                gameTeamService.insertByBo(gameTeamBo);
+            } else {
+                // 更新现有队伍的队员列表和数量
+                updateExistingTeam(teamId, athletesId, athletes.size());
+            }
         }
+
         return true;
     }
 
-
     /**
      * 生成号码段
-     * 需求:
-     * 不超100人,一般4位。0101-0199;超过100人,一般5位,01001-01101;
-     * 根据队伍分配,最多不超过300个
      * 规则:
-     * 1. 按照队伍分类,每个队伍生成一个号码段
-     * 2. 直接给每个队伍分配300个号码,多余的预留起来,防止后续有新的人加入该队伍参赛,预留号码可直接分配给他
-     * 3. 号码从1开始递增,高位填充0
+     * 1. 按照队伍分类,每个队伍分配300个号码
+     * 2. 号码从1开始递增,高位填充0
+     * 3. 超过100人使用5位,否则使用4位
      *
-     * @param member 人数
+     * @param member 人数(用于决定位数)
      * @param team   当前是第几队
      * @return 号码段字符串,如 "0001-0300" 或 "00001-00300"
      */
@@ -566,5 +679,79 @@ public class IEnrollServiceImpl implements IEnrollService {
         return startStr + "-" + endStr;
     }
 
+    /**
+     * 创建运动员BO对象
+     */
+    private GameAthleteBo createAthleteBo(EnrollProjectVo enrollInfo, Long eventId, Long teamId,
+                                          String teamName, AtomicInteger currentNumber, int width,
+                                          Map<String, Long> projectList) {
+        GameAthleteBo gameAthleteBo = new GameAthleteBo();
+        gameAthleteBo.setEventId(eventId);
+        gameAthleteBo.setTeamId(teamId);
+        gameAthleteBo.setTeamName(teamName);
+
+        // 分配编号
+        int assignedNumber = currentNumber.getAndIncrement();
+        String formattedCode = String.format("%0" + width + "d", assignedNumber);
+        gameAthleteBo.setAthleteCode(formattedCode);
+
+        gameAthleteBo.setName(enrollInfo.getName());
+        gameAthleteBo.setGender(enrollInfo.getSex());
+        gameAthleteBo.setAge(Long.valueOf(enrollInfo.getAge()));
+        gameAthleteBo.setPhone(enrollInfo.getPhone());
+        gameAthleteBo.setUnit(teamName);
+
+        // 处理项目选择
+        Map<String, Boolean> selectProjects = enrollInfo.getProjectSelections();
+        List<Long> selectionProjectIds = new ArrayList<>();
+        for (Map.Entry<String, Boolean> selectProject : selectProjects.entrySet()) {
+            Long projectId = projectList.get(selectProject.getKey());
+            if (ObjectUtils.isNotEmpty(projectId)) {
+                selectionProjectIds.add(projectId);
+            }
+        }
+        gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(selectionProjectIds));
+        gameAthleteBo.setStatus("0");
+
+        return gameAthleteBo;
+    }
+
+    /**
+     * 更新现有队伍信息
+     */
+    private void updateExistingTeam(Long teamId, List<Long> newAthletesId, int newAthleteCount) {
+        GameTeamVo existingTeam = gameTeamService.queryById(teamId);
+        if (existingTeam != null) {
+            // 合并现有队员ID和新队员ID
+            List<Long> existingAthletes = JSONUtil.toList(existingTeam.getAthleteValue(), Long.class);
+            List<Long> allAthletes = new ArrayList<>();
+            if (existingAthletes != null) {
+                allAthletes.addAll(existingAthletes);
+            }
+            allAthletes.addAll(newAthletesId);
+
+            // 更新队伍信息
+            GameTeamBo updateTeamBo = new GameTeamBo();
+            updateTeamBo.setTeamId(teamId);
+            updateTeamBo.setAthleteValue(JSONUtil.toJsonStr(allAthletes));
+            updateTeamBo.setAthleteNum(existingTeam.getAthleteNum() + newAthleteCount);
+            gameTeamService.updateByBo(updateTeamBo);
+        }
+    }
+
+    private String generateNumberRangeByMax(int maxNumber) {
+        // 每个队伍固定分配300个号码
+        int start = maxNumber + 1;
+        int end = maxNumber + 300;
+
+        // 判断使用5位
+        int width = 5;
+
+        String startStr = String.format("%0" + width + "d", start);
+        String endStr = String.format("%0" + width + "d", end);
+
+        return startStr + "-" + endStr;
+    }
+
     // endregion 辅助方法
 }