|
@@ -33,6 +33,8 @@ import java.util.stream.Collectors;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import org.dromara.system.domain.bo.GameEventProjectBo;
|
|
import org.dromara.system.domain.bo.GameEventProjectBo;
|
|
|
import org.dromara.system.domain.bo.GameTeamBo;
|
|
import org.dromara.system.domain.bo.GameTeamBo;
|
|
|
|
|
+import org.dromara.system.service.ISysDictTypeService;
|
|
|
|
|
+import org.dromara.system.domain.vo.SysDictDataVo;
|
|
|
|
|
|
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
|
|
|
|
|
@@ -57,6 +59,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
private final GameAthleteMapper gameAthleteMapper;
|
|
private final GameAthleteMapper gameAthleteMapper;
|
|
|
private final GameEventProjectMapper projectMapper;
|
|
private final GameEventProjectMapper projectMapper;
|
|
|
private final IGameEventProjectService gameEventProjectService;
|
|
private final IGameEventProjectService gameEventProjectService;
|
|
|
|
|
+ private final ISysDictTypeService dictTypeService;
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -308,7 +311,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
|
|
|
|
|
// 获取当前页的数据
|
|
// 获取当前页的数据
|
|
|
List<Map<String, Object>> pageData = new ArrayList<>();
|
|
List<Map<String, Object>> pageData = new ArrayList<>();
|
|
|
- if (startIndex < total) {
|
|
|
|
|
|
|
+ if (startIndex <= total) {
|
|
|
pageData = allDataList.subList(startIndex, endIndex);
|
|
pageData = allDataList.subList(startIndex, endIndex);
|
|
|
log.info("当前页数据量: {}", pageData.size());
|
|
log.info("当前页数据量: {}", pageData.size());
|
|
|
} else {
|
|
} else {
|
|
@@ -331,6 +334,9 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
log.info("开始获取个人项目数据: eventId={}, projectId={}, searchValue={}", eventId, projectId, searchValue);
|
|
log.info("开始获取个人项目数据: eventId={}, projectId={}, searchValue={}", eventId, projectId, searchValue);
|
|
|
|
|
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
|
|
|
// 查询参与该项目的运动员
|
|
// 查询参与该项目的运动员
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, searchValue);
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, searchValue);
|
|
@@ -369,7 +375,13 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
if (score != null) {
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
- data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
|
|
|
|
+ // 如果是计时类项目,转换为时间格式显示
|
|
|
|
|
+ if (isTiming && score.getIndividualPerformance() != null) {
|
|
|
|
|
+ String timeFormat = convertDecimalToTimeScore(score.getIndividualPerformance());
|
|
|
|
|
+ data.put("individualPerformance", timeFormat != null ? timeFormat : score.getIndividualPerformance());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
|
|
+ }
|
|
|
data.put("teamPerformance", score.getTeamPerformance());
|
|
data.put("teamPerformance", score.getTeamPerformance());
|
|
|
data.put("scoreRank", score.getScoreRank());
|
|
data.put("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
data.put("updateTime", score.getUpdateTime());
|
|
@@ -377,7 +389,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
} else {
|
|
} else {
|
|
|
data.put("scoreId", 0);
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 0);
|
|
data.put("scorePoint", 0);
|
|
|
- data.put("individualPerformance", 0.0);
|
|
|
|
|
|
|
+ data.put("individualPerformance", isTiming ? "00:00:00.000" : 0.0);
|
|
|
data.put("teamPerformance", 0.0);
|
|
data.put("teamPerformance", 0.0);
|
|
|
data.put("scoreRank", 0);
|
|
data.put("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
data.put("updateTime", "");
|
|
@@ -424,18 +436,28 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
|
|
|
|
|
// 查询成绩信息(使用第一个运动员的成绩作为队伍成绩)
|
|
// 查询成绩信息(使用第一个运动员的成绩作为队伍成绩)
|
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
+
|
|
|
if (score != null) {
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
data.put("individualPerformance", score.getIndividualPerformance());
|
|
data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
- data.put("teamPerformance", score.getTeamPerformance());
|
|
|
|
|
|
|
+ // 如果是计时类项目,转换为时间格式显示
|
|
|
|
|
+ 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("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
data.put("updateTime", score.getUpdateTime());
|
|
|
} else {
|
|
} else {
|
|
|
data.put("scoreId", 0);
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 0);
|
|
data.put("scorePoint", 0);
|
|
|
data.put("individualPerformance", 0.0);
|
|
data.put("individualPerformance", 0.0);
|
|
|
- data.put("teamPerformance", 0.0);
|
|
|
|
|
|
|
+ data.put("teamPerformance", isTiming ? "00:00:00.000" : 0.0);
|
|
|
data.put("scoreRank", 0);
|
|
data.put("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
data.put("updateTime", "");
|
|
|
}
|
|
}
|
|
@@ -987,9 +1009,14 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
vo.setClassification("");
|
|
vo.setClassification("");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 设置成绩信息
|
|
|
|
|
- vo.setIndividualPerformance(convertToBigDecimal(score.getIndividualPerformance()));
|
|
|
|
|
- vo.setTeamPerformance(convertToBigDecimal(score.getTeamPerformance()));
|
|
|
|
|
|
|
+ // 设置成绩信息 - 如果是计时类项目,需要特殊处理
|
|
|
|
|
+ BigDecimal individualPerf = convertToBigDecimal(score.getIndividualPerformance());
|
|
|
|
|
+ BigDecimal teamPerf = convertToBigDecimal(score.getTeamPerformance());
|
|
|
|
|
+
|
|
|
|
|
+ // 注意:AppScoreVo 的字段类型是 BigDecimal,但如果是计时类项目,我们仍然存储 BigDecimal
|
|
|
|
|
+ // 前端可以根据项目类型决定如何显示
|
|
|
|
|
+ vo.setIndividualPerformance(individualPerf);
|
|
|
|
|
+ vo.setTeamPerformance(teamPerf);
|
|
|
vo.setScorePoint(score.getScorePoint() != null ? score.getScorePoint() : 0);
|
|
vo.setScorePoint(score.getScorePoint() != null ? score.getScorePoint() : 0);
|
|
|
vo.setScoreRank(score.getScoreRank() != null ? score.getScoreRank() : 0);
|
|
vo.setScoreRank(score.getScoreRank() != null ? score.getScoreRank() : 0);
|
|
|
|
|
|
|
@@ -1503,33 +1530,33 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
public void exportScoresDetail(Long eventId, HttpServletResponse response) {
|
|
public void exportScoresDetail(Long eventId, HttpServletResponse response) {
|
|
|
try {
|
|
try {
|
|
|
log.info("开始导出成绩详情,eventId: {}", eventId);
|
|
log.info("开始导出成绩详情,eventId: {}", eventId);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 1. 获取所有项目
|
|
// 1. 获取所有项目
|
|
|
List<GameEventProjectVo> projects = gameEventProjectService.queryListByEventId(eventId);
|
|
List<GameEventProjectVo> projects = gameEventProjectService.queryListByEventId(eventId);
|
|
|
if (projects.isEmpty()) {
|
|
if (projects.isEmpty()) {
|
|
|
throw new RuntimeException("未找到赛事项目");
|
|
throw new RuntimeException("未找到赛事项目");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 2. 创建Excel工作簿
|
|
// 2. 创建Excel工作簿
|
|
|
try (Workbook workbook = new XSSFWorkbook()) {
|
|
try (Workbook workbook = new XSSFWorkbook()) {
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 3. 创建样式
|
|
// 3. 创建样式
|
|
|
CellStyle headerStyle = createHeaderStyle(workbook);
|
|
CellStyle headerStyle = createHeaderStyle(workbook);
|
|
|
CellStyle dataStyleOdd = createDataStyle(workbook, IndexedColors.WHITE);
|
|
CellStyle dataStyleOdd = createDataStyle(workbook, IndexedColors.WHITE);
|
|
|
CellStyle dataStyleEven = createDataStyle(workbook, IndexedColors.GREY_25_PERCENT);
|
|
CellStyle dataStyleEven = createDataStyle(workbook, IndexedColors.GREY_25_PERCENT);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 4. 为每个项目创建Sheet页
|
|
// 4. 为每个项目创建Sheet页
|
|
|
for (GameEventProjectVo project : projects) {
|
|
for (GameEventProjectVo project : projects) {
|
|
|
createProjectSheet(workbook, project, eventId, headerStyle, dataStyleOdd, dataStyleEven);
|
|
createProjectSheet(workbook, project, eventId, headerStyle, dataStyleOdd, dataStyleEven);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 5. 设置响应头并输出
|
|
// 5. 设置响应头并输出
|
|
|
setResponseHeaders(response, "成绩详情表");
|
|
setResponseHeaders(response, "成绩详情表");
|
|
|
workbook.write(response.getOutputStream());
|
|
workbook.write(response.getOutputStream());
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
log.info("成绩详情导出完成");
|
|
log.info("成绩详情导出完成");
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("导出成绩详情失败", e);
|
|
log.error("导出成绩详情失败", e);
|
|
|
throw new RuntimeException("导出失败:" + e.getMessage());
|
|
throw new RuntimeException("导出失败:" + e.getMessage());
|
|
@@ -1539,7 +1566,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
/**
|
|
/**
|
|
|
* 为单个项目创建Sheet页
|
|
* 为单个项目创建Sheet页
|
|
|
*/
|
|
*/
|
|
|
- private void createProjectSheet(Workbook workbook, GameEventProjectVo project, Long eventId,
|
|
|
|
|
|
|
+ private void createProjectSheet(Workbook workbook, GameEventProjectVo project, Long eventId,
|
|
|
CellStyle headerStyle, CellStyle dataStyleOdd, CellStyle dataStyleEven) {
|
|
CellStyle headerStyle, CellStyle dataStyleOdd, CellStyle dataStyleEven) {
|
|
|
|
|
|
|
|
// 1. 创建Sheet页,名称限制在31个字符内
|
|
// 1. 创建Sheet页,名称限制在31个字符内
|
|
@@ -1548,8 +1575,8 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
|
|
|
|
|
// 2. 获取项目详细数据
|
|
// 2. 获取项目详细数据
|
|
|
List<Map<String, Object>> projectData = getProjectScoreDataAll(
|
|
List<Map<String, Object>> projectData = getProjectScoreDataAll(
|
|
|
- eventId,
|
|
|
|
|
- project.getProjectId(),
|
|
|
|
|
|
|
+ eventId,
|
|
|
|
|
+ project.getProjectId(),
|
|
|
project.getClassification()
|
|
project.getClassification()
|
|
|
);
|
|
);
|
|
|
|
|
|
|
@@ -1568,7 +1595,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
*/
|
|
*/
|
|
|
private List<Map<String, Object>> getProjectScoreDataAll(Long eventId, Long projectId, String classification) {
|
|
private List<Map<String, Object>> getProjectScoreDataAll(Long eventId, Long projectId, String classification) {
|
|
|
log.info("获取项目全部数据: eventId={}, projectId={}, classification={}", eventId, projectId, classification);
|
|
log.info("获取项目全部数据: eventId={}, projectId={}, classification={}", eventId, projectId, classification);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if ("0".equals(classification)) {
|
|
if ("0".equals(classification)) {
|
|
|
// 个人项目:获取所有运动员数据
|
|
// 个人项目:获取所有运动员数据
|
|
|
return getIndividualProjectDataAll(eventId, projectId);
|
|
return getIndividualProjectDataAll(eventId, projectId);
|
|
@@ -1583,13 +1610,16 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
*/
|
|
*/
|
|
|
private List<Map<String, Object>> getIndividualProjectDataAll(Long eventId, Long projectId) {
|
|
private List<Map<String, Object>> getIndividualProjectDataAll(Long eventId, Long projectId) {
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
-
|
|
|
|
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
+
|
|
|
// 查询参与该项目的所有运动员(不分页)
|
|
// 查询参与该项目的所有运动员(不分页)
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (GameAthleteVo athlete : athletes) {
|
|
for (GameAthleteVo athlete : athletes) {
|
|
|
Map<String, Object> data = new HashMap<>();
|
|
Map<String, Object> data = new HashMap<>();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 基础信息
|
|
// 基础信息
|
|
|
data.put("athleteId", athlete.getAthleteId());
|
|
data.put("athleteId", athlete.getAthleteId());
|
|
|
data.put("userId", athlete.getUserId());
|
|
data.put("userId", athlete.getUserId());
|
|
@@ -1600,7 +1630,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
data.put("name", athlete.getName());
|
|
data.put("name", athlete.getName());
|
|
|
data.put("unit", athlete.getUnit());
|
|
data.put("unit", athlete.getUnit());
|
|
|
data.put("groupType", athlete.getGroupType());
|
|
data.put("groupType", athlete.getGroupType());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 队伍信息
|
|
// 队伍信息
|
|
|
if (athlete.getTeamId() != null) {
|
|
if (athlete.getTeamId() != null) {
|
|
|
GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
|
|
GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
|
|
@@ -1609,13 +1639,19 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
data.put("teamCode", team.getTeamCode());
|
|
data.put("teamCode", team.getTeamCode());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 成绩信息
|
|
// 成绩信息
|
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
|
if (score != null) {
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
- data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
|
|
|
|
+ // 如果是计时类项目,转换为时间格式显示
|
|
|
|
|
+ if (isTiming && score.getIndividualPerformance() != null) {
|
|
|
|
|
+ String timeFormat = convertDecimalToTimeScore(score.getIndividualPerformance());
|
|
|
|
|
+ data.put("individualPerformance", timeFormat != null ? timeFormat : score.getIndividualPerformance());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
|
|
+ }
|
|
|
data.put("teamPerformance", score.getTeamPerformance());
|
|
data.put("teamPerformance", score.getTeamPerformance());
|
|
|
data.put("scoreRank", score.getScoreRank());
|
|
data.put("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
data.put("updateTime", score.getUpdateTime());
|
|
@@ -1623,15 +1659,15 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
// 设置默认值
|
|
// 设置默认值
|
|
|
data.put("scoreId", 0);
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 0);
|
|
data.put("scorePoint", 0);
|
|
|
- data.put("individualPerformance", 0.0);
|
|
|
|
|
|
|
+ data.put("individualPerformance", isTiming ? "00:00:00.000" : 0.0);
|
|
|
data.put("teamPerformance", 0.0);
|
|
data.put("teamPerformance", 0.0);
|
|
|
data.put("scoreRank", 0);
|
|
data.put("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
data.put("updateTime", "");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
resultList.add(data);
|
|
resultList.add(data);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return resultList;
|
|
return resultList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1641,51 +1677,61 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
private List<Map<String, Object>> getTeamProjectDataAll(Long eventId, Long projectId) {
|
|
private List<Map<String, Object>> getTeamProjectDataAll(Long eventId, Long projectId) {
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
Set<Long> processedTeamIds = new HashSet<>();
|
|
Set<Long> processedTeamIds = new HashSet<>();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
+
|
|
|
// 查询参与该项目的所有运动员
|
|
// 查询参与该项目的所有运动员
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (GameAthleteVo athlete : athletes) {
|
|
for (GameAthleteVo athlete : athletes) {
|
|
|
if (athlete.getTeamId() == null || processedTeamIds.contains(athlete.getTeamId())) {
|
|
if (athlete.getTeamId() == null || processedTeamIds.contains(athlete.getTeamId())) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
processedTeamIds.add(athlete.getTeamId());
|
|
processedTeamIds.add(athlete.getTeamId());
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 查询队伍信息
|
|
// 查询队伍信息
|
|
|
GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
|
|
GameTeamVo team = gameTeamService.queryById(athlete.getTeamId());
|
|
|
if (team == null) {
|
|
if (team == null) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
Map<String, Object> data = new HashMap<>();
|
|
Map<String, Object> data = new HashMap<>();
|
|
|
data.put("teamId", team.getTeamId());
|
|
data.put("teamId", team.getTeamId());
|
|
|
data.put("teamName", team.getTeamName());
|
|
data.put("teamName", team.getTeamName());
|
|
|
data.put("teamCode", team.getTeamCode());
|
|
data.put("teamCode", team.getTeamCode());
|
|
|
data.put("eventId", eventId);
|
|
data.put("eventId", eventId);
|
|
|
data.put("projectId", projectId);
|
|
data.put("projectId", projectId);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 查询成绩信息
|
|
// 查询成绩信息
|
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
|
if (score != null) {
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
data.put("individualPerformance", score.getIndividualPerformance());
|
|
data.put("individualPerformance", score.getIndividualPerformance());
|
|
|
- data.put("teamPerformance", score.getTeamPerformance());
|
|
|
|
|
|
|
+ // 如果是计时类项目,转换为时间格式显示
|
|
|
|
|
+ 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("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
data.put("updateTime", score.getUpdateTime());
|
|
|
} else {
|
|
} else {
|
|
|
data.put("scoreId", 0);
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 0);
|
|
data.put("scorePoint", 0);
|
|
|
data.put("individualPerformance", 0.0);
|
|
data.put("individualPerformance", 0.0);
|
|
|
- data.put("teamPerformance", 0.0);
|
|
|
|
|
|
|
+ data.put("teamPerformance", isTiming ? "00:00:00.000" : 0.0);
|
|
|
data.put("scoreRank", 0);
|
|
data.put("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
data.put("updateTime", "");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
resultList.add(data);
|
|
resultList.add(data);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return resultList;
|
|
return resultList;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1695,15 +1741,15 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
private void createProjectHeaderRow(Sheet sheet, GameEventProjectVo project, CellStyle headerStyle) {
|
|
private void createProjectHeaderRow(Sheet sheet, GameEventProjectVo project, CellStyle headerStyle) {
|
|
|
Row headerRow = sheet.createRow(0);
|
|
Row headerRow = sheet.createRow(0);
|
|
|
int colIndex = 0;
|
|
int colIndex = 0;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 根据项目类型确定列标题
|
|
// 根据项目类型确定列标题
|
|
|
if ("0".equals(project.getClassification())) {
|
|
if ("0".equals(project.getClassification())) {
|
|
|
// 个人项目列标题
|
|
// 个人项目列标题
|
|
|
String[] headers = {
|
|
String[] headers = {
|
|
|
- "序号", "队伍编号", "队伍名称", "姓名", "号码",
|
|
|
|
|
|
|
+ "序号", "队伍编号", "队伍名称", "姓名", "号码",
|
|
|
"个人成绩", "积分", "排名", "更新时间"
|
|
"个人成绩", "积分", "排名", "更新时间"
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (String header : headers) {
|
|
for (String header : headers) {
|
|
|
Cell cell = headerRow.createCell(colIndex++);
|
|
Cell cell = headerRow.createCell(colIndex++);
|
|
|
cell.setCellValue(header);
|
|
cell.setCellValue(header);
|
|
@@ -1712,10 +1758,10 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
} else {
|
|
} else {
|
|
|
// 团体项目列标题
|
|
// 团体项目列标题
|
|
|
String[] headers = {
|
|
String[] headers = {
|
|
|
- "序号", "队伍编号", "队伍名称", "团队成绩",
|
|
|
|
|
|
|
+ "序号", "队伍编号", "队伍名称", "团队成绩",
|
|
|
"积分", "排名", "更新时间"
|
|
"积分", "排名", "更新时间"
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
for (String header : headers) {
|
|
for (String header : headers) {
|
|
|
Cell cell = headerRow.createCell(colIndex++);
|
|
Cell cell = headerRow.createCell(colIndex++);
|
|
|
cell.setCellValue(header);
|
|
cell.setCellValue(header);
|
|
@@ -1727,7 +1773,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
/**
|
|
/**
|
|
|
* 填充项目数据行
|
|
* 填充项目数据行
|
|
|
*/
|
|
*/
|
|
|
- private void fillProjectDataRows(Sheet sheet, List<Map<String, Object>> projectData,
|
|
|
|
|
|
|
+ private void fillProjectDataRows(Sheet sheet, List<Map<String, Object>> projectData,
|
|
|
GameEventProjectVo project, CellStyle dataStyleOdd, CellStyle dataStyleEven) {
|
|
GameEventProjectVo project, CellStyle dataStyleOdd, CellStyle dataStyleEven) {
|
|
|
|
|
|
|
|
int rowIndex = 1;
|
|
int rowIndex = 1;
|
|
@@ -1771,7 +1817,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
if (projectName == null) {
|
|
if (projectName == null) {
|
|
|
return "项目";
|
|
return "项目";
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 替换Excel不允许的特殊字符
|
|
// 替换Excel不允许的特殊字符
|
|
|
String cleanName = projectName
|
|
String cleanName = projectName
|
|
|
.replace("*", "×") // 星号替换为乘号
|
|
.replace("*", "×") // 星号替换为乘号
|
|
@@ -1782,22 +1828,22 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
.replace("]", ")") // 右方括号替换为右括号
|
|
.replace("]", ")") // 右方括号替换为右括号
|
|
|
.replace(":", ":") // 英文冒号替换为中文冒号
|
|
.replace(":", ":") // 英文冒号替换为中文冒号
|
|
|
.trim(); // 去除首尾空格
|
|
.trim(); // 去除首尾空格
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 处理单引号问题
|
|
// 处理单引号问题
|
|
|
if (cleanName.startsWith("'") || cleanName.endsWith("'")) {
|
|
if (cleanName.startsWith("'") || cleanName.endsWith("'")) {
|
|
|
cleanName = cleanName.replace("'", "_");
|
|
cleanName = cleanName.replace("'", "_");
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 如果处理后为空,使用默认名称
|
|
// 如果处理后为空,使用默认名称
|
|
|
if (cleanName.isEmpty()) {
|
|
if (cleanName.isEmpty()) {
|
|
|
cleanName = "项目";
|
|
cleanName = "项目";
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 限制长度在31个字符内
|
|
// 限制长度在31个字符内
|
|
|
if (cleanName.length() > 31) {
|
|
if (cleanName.length() > 31) {
|
|
|
cleanName = cleanName.substring(0, 31);
|
|
cleanName = cleanName.substring(0, 31);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
return cleanName;
|
|
return cleanName;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1832,4 +1878,87 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
|
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
|
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
|
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断项目是否为计时类项目
|
|
|
|
|
+ * 根据项目的计算规则(scoreRule)判断
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param project 项目信息
|
|
|
|
|
+ * @return true表示是计时类项目,false表示不是
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isTimingProject(GameEventProjectVo project) {
|
|
|
|
|
+ if (project == null || project.getScoreRule() == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<SysDictDataVo> gameScoreType = dictTypeService.selectDictDataByType("game_score_type");
|
|
|
|
|
+ String scoreRule = project.getScoreRule().toLowerCase();
|
|
|
|
|
+ Optional<String> rule = gameScoreType.stream()
|
|
|
|
|
+ .filter(data -> data.getDictLabel().contains("计时"))
|
|
|
|
|
+ .map(SysDictDataVo::getDictValue)
|
|
|
|
|
+ .findFirst();
|
|
|
|
|
+ // 判断计算规则是否为计时类
|
|
|
|
|
+ return rule.isPresent() && scoreRule.equals(rule.get().toLowerCase());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("判断项目是否为计时类失败: {}", project.getProjectId(), e);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将小数格式的成绩转换成时间格式显示(时:分:秒.毫秒)
|
|
|
|
|
+ * 格式:xx:xx:xx.nnn (时:分:秒.毫秒)
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param decimalScore 以秒为单位的小数值
|
|
|
|
|
+ * @return 时间格式字符串,如 "01:23:45.678"
|
|
|
|
|
+ */
|
|
|
|
|
+ private String convertDecimalToTimeScore(BigDecimal decimalScore) {
|
|
|
|
|
+ if (decimalScore == null || decimalScore.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 计算小时
|
|
|
|
|
+ BigDecimal hoursBigDecimal = decimalScore.divide(BigDecimal.valueOf(3600), 0, java.math.RoundingMode.DOWN);
|
|
|
|
|
+ int hours = hoursBigDecimal.intValue();
|
|
|
|
|
+ BigDecimal remaining = decimalScore.remainder(BigDecimal.valueOf(3600));
|
|
|
|
|
+
|
|
|
|
|
+ // 计算分钟
|
|
|
|
|
+ BigDecimal minutesBigDecimal = remaining.divide(BigDecimal.valueOf(60), 0, java.math.RoundingMode.DOWN);
|
|
|
|
|
+ int minutes = minutesBigDecimal.intValue();
|
|
|
|
|
+ remaining = remaining.remainder(BigDecimal.valueOf(60));
|
|
|
|
|
+
|
|
|
|
|
+ // 秒和毫秒
|
|
|
|
|
+ int seconds = remaining.intValue();
|
|
|
|
|
+ // 计算毫秒:取小数部分乘以1000并四舍五入
|
|
|
|
|
+ BigDecimal millisecondsBigDecimal = remaining.subtract(BigDecimal.valueOf(seconds))
|
|
|
|
|
+ .multiply(BigDecimal.valueOf(1000))
|
|
|
|
|
+ .setScale(0, java.math.RoundingMode.HALF_UP);
|
|
|
|
|
+ int milliseconds = millisecondsBigDecimal.intValue();
|
|
|
|
|
+
|
|
|
|
|
+ // 处理毫秒溢出(理论上不应该发生,但保险起见)
|
|
|
|
|
+ if (milliseconds >= 1000) {
|
|
|
|
|
+ seconds += milliseconds / 1000;
|
|
|
|
|
+ milliseconds = milliseconds % 1000;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 处理秒溢出(理论上不应该发生,但保险起见)
|
|
|
|
|
+ if (seconds >= 60) {
|
|
|
|
|
+ minutes += seconds / 60;
|
|
|
|
|
+ seconds = seconds % 60;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 处理分钟溢出(理论上不应该发生,但保险起见)
|
|
|
|
|
+ if (minutes >= 60) {
|
|
|
|
|
+ hours += minutes / 60;
|
|
|
|
|
+ minutes = minutes % 60;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 格式化输出:时:分:秒.毫秒
|
|
|
|
|
+ return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("转换小数为时间格式失败: {}", decimalScore, e);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|