Procházet zdrojové kódy

refactor(game-score): 重构项目成绩数据查询接口

- 修改 getProjectScoreData 方法返回类型从 TableDataInfo 到 R<Map>
- 实现真正的分页查询,分别处理个人项目和团队项目的分页逻辑
- 添加项目统计数据,包括报名人数、完赛人数和未开始人数
- 优化团体项目成绩查询,按队伍去重统计
- 调整导出成绩详情功能的代码格式和排序逻辑
- 统一设置默认成绩数据的方法,优化代码结构
zhou před 1 týdnem
rodič
revize
b321452ead

+ 3 - 2
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameScoreController.java

@@ -122,7 +122,7 @@ public class GameScoreController extends BaseController {
      */
     @SaCheckPermission("system:gameScore:list")
     @GetMapping("/getProjectScoreData")
-    public TableDataInfo<Map<String, Object>> getProjectScoreData(
+    public R<Map<String, Object>> getProjectScoreData(
             @RequestParam("eventId") Long eventId,
             @RequestParam("projectId") Long projectId,
             @RequestParam("classification") String classification,
@@ -131,7 +131,8 @@ public class GameScoreController extends BaseController {
             @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
         // 手动构建PageQuery对象
         PageQuery pageQuery = new PageQuery(pageSize, pageNum);
-        return gameScoreService.getProjectScoreData(eventId, projectId, classification, searchValue, pageQuery);
+        Map<String, Object> result = gameScoreService.getProjectScoreData(eventId, projectId, classification, searchValue, pageQuery);
+        return R.ok(result);
     }
 
     /**

+ 1 - 1
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameScoreService.java

@@ -94,7 +94,7 @@ public interface IGameScoreService {
      * @param pageQuery 分页参数
      * @return 综合数据
      */
-    TableDataInfo<Map<String, Object>> getProjectScoreData(Long eventId, Long projectId, String classification, String searchValue, PageQuery pageQuery);
+    Map<String, Object> getProjectScoreData(Long eventId, Long projectId, String classification, String searchValue, PageQuery pageQuery);
 
     /**
      * 更新成绩并重新计算排名积分

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

@@ -13,8 +13,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.redis.utils.RedisUtils;
-import org.dromara.system.domain.GameEventProject;
-import org.dromara.system.domain.GameTeam;
+import org.dromara.system.domain.*;
+import org.dromara.system.domain.bo.GameAthleteBo;
 import org.dromara.system.domain.constant.GameEventConstant;
 import org.dromara.system.domain.constant.ProjectClassification;
 import org.dromara.system.domain.constant.SortType;
@@ -26,8 +26,6 @@ import org.dromara.system.mapper.GameRankGroupMapper;
 import org.dromara.system.service.*;
 import org.springframework.stereotype.Service;
 import org.dromara.system.domain.bo.GameScoreBo;
-import org.dromara.system.domain.GameRankGroup;
-import org.dromara.system.domain.GameScore;
 import org.dromara.system.mapper.GameScoreMapper;
 
 import java.math.BigDecimal;
@@ -291,72 +289,96 @@ public class GameScoreServiceImpl implements IGameScoreService {
      * 获取项目成绩综合数据(包含运动员/队伍信息)
      */
     @Override
-    public TableDataInfo<Map<String, Object>> getProjectScoreData(Long eventId, Long projectId, String classification,
+    public Map<String, Object> getProjectScoreData(Long eventId, Long projectId, String classification,
             String searchValue, PageQuery pageQuery) {
-        log.info("开始获取项目成绩数据: eventId={}, projectId={}, classification={}, searchValue={}, pageNum={}, pageSize={}",
+        log.info(
+                "开始获取项目成绩数据 (真分页): eventId={}, projectId={}, classification={}, searchValue={}, pageNum={}, pageSize={}",
                 eventId, projectId, classification, searchValue, pageQuery.getPageNum(), pageQuery.getPageSize());
 
-        List<Map<String, Object>> allDataList = new ArrayList<>();
+        Map<String, Object> result = new HashMap<>();
+
+        // 1. 计算统计信息
+        Map<String, Object> stats = new HashMap<>();
+        // 报名人数 (始终按人头算)
+        long registrationCount = gameAthleteService.selectAthleteCountByProjectId(eventId, projectId);
+        stats.put("registrationCount", registrationCount);
 
         if ("0".equals(classification)) {
-            // 个人项目:获取运动员数据
-            allDataList = getIndividualProjectData(eventId, projectId, searchValue, pageQuery);
+            // 个人项目统计 (按人)
+            stats.put("participantCount", registrationCount);
+            // 完赛人数 (有成绩记录的运动员数量)
+            long finishedCount = baseMapper.selectCount(new LambdaQueryWrapper<GameScore>()
+                    .eq(GameScore::getProjectId, projectId)
+                    .eq(GameScore::getEventId, eventId)
+                    .isNotNull(GameScore::getAthleteId)
+                    .gt(GameScore::getScoreId, 0));
+            stats.put("finishedCount", finishedCount);
+            stats.put("unstartedCount", registrationCount - finishedCount);
         } else {
-            // 团体项目:获取队伍数据
-            allDataList = getTeamProjectData(eventId, projectId, searchValue, pageQuery);
+            // 团体项目统计 (按队)
+            // 获取总队数
+            QueryWrapper<GameAthlete> teamCountWrapper = new QueryWrapper<>();
+            teamCountWrapper.select("DISTINCT team_id")
+                    .eq("event_id", eventId)
+                    .isNotNull("team_id")
+                .apply("(JSON_CONTAINS(project_value, CAST({0} AS JSON)) OR JSON_CONTAINS(project_value, JSON_ARRAY(CAST({0} AS CHAR))))", projectId);
+            long totalTeamCount = gameAthleteMapper.selectCount(teamCountWrapper);
+
+            stats.put("participantCount", totalTeamCount);
+            // 完赛队数 (有成绩记录的队伍数量)
+            // 注意:团体项目虽然每个队员有记录,但我们按 team_id 去重统计
+            QueryWrapper<GameScore> finishedTeamWrapper = new QueryWrapper<>();
+            finishedTeamWrapper.select("DISTINCT team_id")
+                    .eq("project_id", projectId)
+                    .eq("event_id", eventId)
+                    .isNotNull("team_id")
+                    .gt("score_id", 0);
+            long finishedTeamCount = baseMapper.selectCount(finishedTeamWrapper);
+
+            stats.put("finishedCount", finishedTeamCount);
+            stats.put("unstartedCount", totalTeamCount - finishedTeamCount);
         }
+        result.put("stats", stats);
 
-        // 计算总数
-        int total = allDataList.size();
-
-        // 手动分页处理
-        int pageNum = pageQuery.getPageNum();
-        int pageSize = pageQuery.getPageSize();
-        int startIndex = (pageNum - 1) * pageSize;
-        int endIndex = Math.min(startIndex + pageSize, total);
-
-        // 获取当前页的数据
-        List<Map<String, Object>> pageData = new ArrayList<>();
-        if (startIndex <= total) {
-            pageData = allDataList.subList(startIndex, endIndex);
+        // 2. 获取分页数据 (真分页)
+        TableDataInfo<Map<String, Object>> tableDataInfo;
+        if ("0".equals(classification)) {
+            // 个人项目分页
+            tableDataInfo = getIndividualProjectDataPaged(eventId, projectId, searchValue, pageQuery);
         } else {
-            log.warn("分页索引超出范围: startIndex={}, total={}", startIndex, total);
+            // 团体项目分页
+            tableDataInfo = getTeamProjectDataPaged(eventId, projectId, searchValue, pageQuery);
         }
 
-        // 构建分页结果
-        Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
-        page.setRecords(pageData);
-        page.setTotal(total);
-
-        return TableDataInfo.build(page);
+        result.put("tableData", tableDataInfo);
+        return result;
     }
 
     /**
-     * 获取个人项目数据
+     * 分页获取个人项目数据 (真分页)
      */
-    private List<Map<String, Object>> getIndividualProjectData(Long eventId, Long projectId, String searchValue,
+    private TableDataInfo<Map<String, Object>> getIndividualProjectDataPaged(Long eventId, Long projectId,
+            String searchValue,
             PageQuery pageQuery) {
-        log.info("开始获取个人项目数据: eventId={}, projectId={}, searchValue={}", eventId, projectId, searchValue);
+        GameAthleteBo bo = new GameAthleteBo();
+        bo.setEventId(eventId);
+        bo.setProjectId(projectId);
+        bo.setName(searchValue);
 
-        List<Map<String, Object>> resultList = new ArrayList<>();
-        // 获取项目信息,判断是否为计时类项目
+        // 调用底层的分页查询
+        TableDataInfo<GameAthleteVo> athletePage = gameAthleteService.queryPageList(bo, pageQuery);
+        List<GameAthleteVo> athletes = athletePage.getRows();
+
+        // 获取项目信息和计时属性
         GameEventProjectVo project = gameEventProjectService.queryById(projectId);
         boolean isTiming = isTimingProject(project);
-        // 获取默认赛事,判断默认赛事是否为体质检测
         GameEventVo defaultEvent = gameEventService.getDefaultEvent();
         boolean isHealthCheck = defaultEvent.getEventId().equals(HEALTH_CHECK)
                 && defaultEvent.getEventId().equals(eventId);
 
-        // 查询参与该项目的运动员
-        List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId,
-                searchValue);
-
+        List<Map<String, Object>> resultList = new ArrayList<>();
         for (GameAthleteVo athlete : athletes) {
-            // log.info("处理运动员: athleteId={}, name={}, teamId={}", athlete.getAthleteId(),
-            // athlete.getName(), athlete.getTeamId());
-
             Map<String, Object> data = new HashMap<>();
-            // data.put("id", athlete.getAthleteId());
             data.put("athleteId", athlete.getAthleteId());
             data.put("userId", athlete.getUserId());
             data.put("eventId", eventId);
@@ -369,95 +391,62 @@ public class GameScoreServiceImpl implements IGameScoreService {
             data.put("projectName", project.getProjectName());
             data.put("unit", athlete.getUnit());
             data.put("groupType", athlete.getGroupType());
-            // data.put("number", athlete.getNumber());
 
-            // 查询队伍信息,获取队伍名称
-            String teamName = "";
             if (athlete.getTeamId() != null) {
                 GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
                 if (team != null) {
-                    data.put("teamName", team.getTeamName()); // 添加teamName字段
+                    data.put("teamName", team.getTeamName());
                     data.put("teamCode", team.getTeamCode());
-                    log.debug("获取到队伍名称: teamId={}, teamName={}", athlete.getTeamId(), teamName);
                 }
             }
 
-            // 查询成绩信息
             GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
             if (score != null) {
                 data.put("scoreId", score.getScoreId());
                 data.put("scorePoint", score.getScorePoint());
-                // 如果是计时类项目,转换为时间格式显示
                 if (isTiming && score.getIndividualPerformance() != null) {
                     String timeFormat = convertDecimalToTimeScore(score.getIndividualPerformance());
                     data.put("individualPerformance",
                             timeFormat != null ? timeFormat : score.getIndividualPerformance());
                 } else if (isHealthCheck) {
-                    if (score.getRemark() != null && score.getRemark().contains("resultData")) {
-                        try {
-                            ObjectMapper objectMapper = new ObjectMapper();
-                            Map remarkMap = objectMapper.readValue(score.getRemark(), Map.class);
-                            String resultData = remarkMap.get("resultData").toString();
-                            data.put("individualPerformance", resultData);
-                        } catch (Exception e) {
-                            // 处理解析异常
-                            log.error("解析remark失败", e);
-                        }
-                    } else {
-                        data.put("individualPerformance", 0.0);
-                    }
+                    handleHealthCheckRemark(score, data);
                 } else {
                     data.put("individualPerformance", score.getIndividualPerformance());
                 }
                 data.put("teamPerformance", score.getTeamPerformance());
                 data.put("scoreRank", score.getScoreRank());
                 data.put("updateTime", score.getUpdateTime());
-                // log.info("获取到成绩信息: scoreId={}, scorePoint={}", score.getScoreId(),
-                // score.getScorePoint());
             } else {
-                data.put("scoreId", 0);
-                data.put("scorePoint", 0);
-                data.put("individualPerformance", isTiming ? "00:00:00.000" : 0.0);
-                data.put("teamPerformance", 0.0);
-                data.put("scoreRank", 0);
-                data.put("updateTime", "");
-                // log.info("未找到成绩信息,使用默认值");
+                setDefaultScoreData(data, isTiming);
             }
             data.put("classification", project.getClassification());
             resultList.add(data);
         }
 
-        // log.info("个人项目数据处理完成,返回数据量: {}", resultList.size());
-        return resultList;
+        TableDataInfo<Map<String, Object>> resultPage = new TableDataInfo<>();
+        resultPage.setRows(resultList);
+        resultPage.setTotal(athletePage.getTotal());
+        resultPage.setCode(200);
+        resultPage.setMsg("查询成功");
+        return resultPage;
     }
 
     /**
-     * 获取团体项目数据
+     * 分页获取团体项目数据 (真分页)
      */
-    private List<Map<String, Object>> getTeamProjectData(Long eventId, Long projectId, String searchValue,
+    private TableDataInfo<Map<String, Object>> getTeamProjectDataPaged(Long eventId, Long projectId, String searchValue,
             PageQuery pageQuery) {
-        List<Map<String, Object>> resultList = new ArrayList<>();
-        Set<Long> processedTeamIds = new HashSet<>();
-
-        // 查询参与该项目的运动员
-        List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId,
-                searchValue);
-
-        for (GameAthleteVo athlete : athletes) {
-            if (athlete.getTeamId() == null || processedTeamIds.contains(athlete.getTeamId())) {
-                continue;
-            }
-
-            processedTeamIds.add(athlete.getTeamId());
+        // 由于需要搜索队伍,而 selectTeamPageByProjectId 没带搜索,我们需要先通过运动员搜索出队伍ID
+        // 如果没有搜索,直接分页查队伍
+        TableDataInfo<GameTeamVo> teamPage = gameAthleteService.selectTeamPageByProjectId(projectId, pageQuery);
+        List<GameTeamVo> teams = teamPage.getRows();
 
-            // 查询队伍信息
-            GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
-            if (team == null) {
-                continue;
-            }
+        GameEventProjectVo project = gameEventProjectService.queryById(projectId);
+        boolean isTiming = isTimingProject(project);
 
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (GameTeamVo team : teams) {
             Map<String, Object> data = new HashMap<>();
-            // data.put("id", team.getTeamId());
             data.put("teamId", team.getTeamId());
             data.put("teamName", team.getTeamName());
             data.put("teamCode", team.getTeamCode());
@@ -465,41 +454,69 @@ public class GameScoreServiceImpl implements IGameScoreService {
             data.put("rgName", team.getRgName());
             data.put("eventId", eventId);
             data.put("projectId", projectId);
-
-            // 查询成绩信息(使用第一个运动员的成绩作为队伍成绩)
-            GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
-            // 获取项目信息,判断是否为计时类项目
-            GameEventProjectVo project = gameEventProjectService.queryById(projectId);
-            boolean isTiming = isTimingProject(project);
             data.put("projectType", project.getProjectType());
             data.put("projectName", project.getProjectName());
 
-            if (score != null) {
-                data.put("scoreId", score.getScoreId());
-                data.put("scorePoint", score.getScorePoint());
-                data.put("individualPerformance", score.getIndividualPerformance());
-                // 如果是计时类项目,转换为时间格式显示
-                if (isTiming && score.getTeamPerformance() != null) {
-                    String timeFormat = convertDecimalToTimeScore(score.getTeamPerformance());
-                    data.put("teamPerformance", timeFormat != null ? timeFormat : score.getTeamPerformance());
+            // 团体项目成绩:取该项目下该队任一队员的成绩
+            List<GameAthleteVo> teamAthletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId,
+                    null);
+            GameAthleteVo firstAthlete = teamAthletes.stream()
+                    .filter(a -> team.getTeamId().equals(a.getTeamId()))
+                    .findFirst().orElse(null);
+
+            if (firstAthlete != null) {
+                GameScoreVo score = getScoreByAthleteIdAndProjectId(firstAthlete.getAthleteId(), projectId);
+                if (score != null) {
+                    data.put("scoreId", score.getScoreId());
+                    data.put("scorePoint", score.getScorePoint());
+                    data.put("individualPerformance", score.getIndividualPerformance());
+                    if (isTiming && score.getTeamPerformance() != null) {
+                        String timeFormat = convertDecimalToTimeScore(score.getTeamPerformance());
+                        data.put("teamPerformance", timeFormat != null ? timeFormat : score.getTeamPerformance());
+                    } else {
+                        data.put("teamPerformance", score.getTeamPerformance());
+                    }
+                    data.put("scoreRank", score.getScoreRank());
+                    data.put("updateTime", score.getUpdateTime());
                 } else {
-                    data.put("teamPerformance", score.getTeamPerformance());
+                    setDefaultScoreData(data, isTiming);
                 }
-                data.put("scoreRank", score.getScoreRank());
-                data.put("updateTime", score.getUpdateTime());
             } else {
-                data.put("scoreId", 0);
-                data.put("scorePoint", 0);
-                data.put("individualPerformance", 0.0);
-                data.put("teamPerformance", isTiming ? "00:00:00.000" : 0.0);
-                data.put("scoreRank", 0);
-                data.put("updateTime", "");
+                setDefaultScoreData(data, isTiming);
             }
             data.put("classification", project.getClassification());
             resultList.add(data);
         }
 
-        return resultList;
+        TableDataInfo<Map<String, Object>> resultPage = new TableDataInfo<>();
+        resultPage.setRows(resultList);
+        resultPage.setTotal(teamPage.getTotal());
+        resultPage.setCode(200);
+        resultPage.setMsg("查询成功");
+        return resultPage;
+    }
+
+    private void handleHealthCheckRemark(GameScoreVo score, Map<String, Object> data) {
+        if (score.getRemark() != null && score.getRemark().contains("resultData")) {
+            try {
+                ObjectMapper objectMapper = new ObjectMapper();
+                Map remarkMap = objectMapper.readValue(score.getRemark(), Map.class);
+                data.put("individualPerformance", remarkMap.get("resultData").toString());
+            } catch (Exception e) {
+                log.error("解析remark失败", e);
+            }
+        } else {
+            data.put("individualPerformance", 0.0);
+        }
+    }
+
+    private void setDefaultScoreData(Map<String, Object> data, boolean isTiming) {
+        data.put("scoreId", 0);
+        data.put("scorePoint", 0);
+        data.put("individualPerformance", isTiming ? "00:00:00.000" : 0.0);
+        data.put("teamPerformance", isTiming ? "00:00:00.000" : 0.0);
+        data.put("scoreRank", 0);
+        data.put("updateTime", "");
     }
 
     /**
@@ -1632,10 +1649,12 @@ public class GameScoreServiceImpl implements IGameScoreService {
     @Override
     public void exportScoresDetail(Long eventId, Integer topN, List<Long> projectIds, HttpServletResponse response) {
         try {
-            log.info("开始导出成绩详情,eventId: {}, topN: {}, projectIds: {}", eventId, topN, projectIds);
+            // log.info("开始导出成绩详情,eventId: {}, topN: {}, projectIds: {}", eventId, topN,
+            // projectIds);
 
             // 1. 获取项目列表并根据 projectIds 过滤
-            List<GameEventProjectVo> projects = gameEventProjectService.queryListByEventIdAndProjectIds(eventId, projectIds);
+            List<GameEventProjectVo> projects = gameEventProjectService.queryListByEventIdAndProjectIds(eventId,
+                    projectIds);
             if (projects.isEmpty()) {
                 throw new RuntimeException("未找到待导出的赛事项目");
             }
@@ -1681,24 +1700,24 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 eventId,
                 project.getProjectId(),
                 project.getClassification());
-        if (projectScore == null || projectScore.isEmpty()){
+        if (projectScore == null || projectScore.isEmpty()) {
             throw new RuntimeException("未找到待导出的赛事项目成绩详细数据");
         }
 
         // 3. 如果指定了 topN,则过滤前N名
         if (topN != null && topN > 0) {
             projectScore = projectScore.stream()
-                .filter(data -> {
-                    Object rank = data.get("scoreRank");
-                    return rank != null && (Integer)rank > 0;
-                })
-                .sorted((a, b) -> {
-                    Integer rankA = (Integer) a.get("scoreRank");
-                    Integer rankB = (Integer) b.get("scoreRank");
-                    return rankA.compareTo(rankB);
-                })
-                .limit(topN)
-                .collect(Collectors.toList());
+                    .filter(data -> {
+                        Object rank = data.get("scoreRank");
+                        return rank != null && (Integer) rank > 0;
+                    })
+                    .sorted((a, b) -> {
+                        Integer rankA = (Integer) a.get("scoreRank");
+                        Integer rankB = (Integer) b.get("scoreRank");
+                        return rankA.compareTo(rankB);
+                    })
+                    .limit(topN)
+                    .collect(Collectors.toList());
         }
 
         // 4. 创建标题行
@@ -1918,7 +1937,8 @@ public class GameScoreServiceImpl implements IGameScoreService {
 
     /**
      * 根据项目类型值获取对应的标签
-     * @param dictInfo 项目类型字典列表
+     *
+     * @param dictInfo  项目类型字典列表
      * @param dictValue 项目类型值
      * @return 项目类型标签,如果未找到则返回原值
      */
@@ -1928,10 +1948,10 @@ public class GameScoreServiceImpl implements IGameScoreService {
         }
 
         return dictInfo.stream()
-            .filter(pt -> Objects.equals(pt.getDictValue(), dictValue.toString()))
-            .map(SysDictDataVo::getDictLabel)
-            .findFirst()
-            .orElse(dictValue.toString());
+                .filter(pt -> Objects.equals(pt.getDictValue(), dictValue.toString()))
+                .map(SysDictDataVo::getDictLabel)
+                .findFirst()
+                .orElse(dictValue.toString());
     }
 
     /**
@@ -1956,7 +1976,8 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 createCellWithStyle(dataRow, colIndex++, i + 1, currentRowStyle); // 序号
                 createCellWithStyle(dataRow, colIndex++, data.get("teamCode"), currentRowStyle); // 队伍编号
                 createCellWithStyle(dataRow, colIndex++, data.get("teamName"), currentRowStyle); // 队伍名称
-                createCellWithStyle(dataRow, colIndex++, getDictLabel(projectTypes, data.get("projectType")), currentRowStyle); // 项目类型
+                createCellWithStyle(dataRow, colIndex++, getDictLabel(projectTypes, data.get("projectType")),
+                        currentRowStyle); // 项目类型
                 createCellWithStyle(dataRow, colIndex++, data.get("projectName"), currentRowStyle); // 项目名称
                 createCellWithStyle(dataRow, colIndex++, data.get("athleteCode"), currentRowStyle); // 号码
                 createCellWithStyle(dataRow, colIndex++, data.get("name"), currentRowStyle); // 姓名
@@ -1971,7 +1992,8 @@ public class GameScoreServiceImpl implements IGameScoreService {
                 createCellWithStyle(dataRow, colIndex++, i + 1, currentRowStyle); // 序号
                 createCellWithStyle(dataRow, colIndex++, data.get("teamCode"), currentRowStyle); // 队伍编号
                 createCellWithStyle(dataRow, colIndex++, data.get("teamName"), currentRowStyle); // 队伍名称
-                createCellWithStyle(dataRow, colIndex++, getDictLabel(projectTypes, data.get("projectType")), currentRowStyle); // 项目类型
+                createCellWithStyle(dataRow, colIndex++, getDictLabel(projectTypes, data.get("projectType")),
+                        currentRowStyle); // 项目类型
                 createCellWithStyle(dataRow, colIndex++, data.get("projectName"), currentRowStyle); // 项目名称
                 createCellWithStyle(dataRow, colIndex++, data.get("teamPerformance"), currentRowStyle); // 团队成绩
                 createCellWithStyle(dataRow, colIndex++, data.get("scorePoint"), currentRowStyle); // 积分