|
|
@@ -33,6 +33,8 @@ import java.util.stream.Collectors;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import org.dromara.system.domain.bo.GameEventProjectBo;
|
|
|
import org.dromara.system.domain.bo.GameTeamBo;
|
|
|
+import org.dromara.system.service.ISysDictTypeService;
|
|
|
+import org.dromara.system.domain.vo.SysDictDataVo;
|
|
|
|
|
|
import java.net.URLEncoder;
|
|
|
|
|
|
@@ -57,6 +59,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
private final GameAthleteMapper gameAthleteMapper;
|
|
|
private final GameEventProjectMapper projectMapper;
|
|
|
private final IGameEventProjectService gameEventProjectService;
|
|
|
+ private final ISysDictTypeService dictTypeService;
|
|
|
|
|
|
|
|
|
/**
|
|
|
@@ -331,6 +334,9 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
log.info("开始获取个人项目数据: eventId={}, projectId={}, searchValue={}", eventId, projectId, searchValue);
|
|
|
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
|
// 查询参与该项目的运动员
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, searchValue);
|
|
|
@@ -369,7 +375,13 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
|
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("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
|
@@ -377,7 +389,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
} else {
|
|
|
data.put("scoreId", 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("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
|
@@ -424,18 +436,28 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
|
|
|
// 查询成绩信息(使用第一个运动员的成绩作为队伍成绩)
|
|
|
GameScoreVo score = getScoreByAthleteIdAndProjectId(athlete.getAthleteId(), projectId);
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
+
|
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
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("updateTime", score.getUpdateTime());
|
|
|
} else {
|
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 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("updateTime", "");
|
|
|
}
|
|
|
@@ -987,9 +1009,14 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
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.setScoreRank(score.getScoreRank() != null ? score.getScoreRank() : 0);
|
|
|
|
|
|
@@ -1583,6 +1610,9 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
*/
|
|
|
private List<Map<String, Object>> getIndividualProjectDataAll(Long eventId, Long projectId) {
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
|
|
|
// 查询参与该项目的所有运动员(不分页)
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
|
@@ -1615,7 +1645,13 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
if (score != null) {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
|
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("scoreRank", score.getScoreRank());
|
|
|
data.put("updateTime", score.getUpdateTime());
|
|
|
@@ -1623,7 +1659,7 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
// 设置默认值
|
|
|
data.put("scoreId", 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("scoreRank", 0);
|
|
|
data.put("updateTime", "");
|
|
|
@@ -1642,6 +1678,10 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
Set<Long> processedTeamIds = new HashSet<>();
|
|
|
|
|
|
+ // 获取项目信息,判断是否为计时类项目
|
|
|
+ GameEventProjectVo project = gameEventProjectService.queryById(projectId);
|
|
|
+ boolean isTiming = isTimingProject(project);
|
|
|
+
|
|
|
// 查询参与该项目的所有运动员
|
|
|
List<GameAthleteVo> athletes = gameAthleteService.queryListByEventIdAndProjectId(eventId, projectId, null);
|
|
|
|
|
|
@@ -1671,14 +1711,20 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
data.put("scoreId", score.getScoreId());
|
|
|
data.put("scorePoint", score.getScorePoint());
|
|
|
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("updateTime", score.getUpdateTime());
|
|
|
} else {
|
|
|
data.put("scoreId", 0);
|
|
|
data.put("scorePoint", 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("updateTime", "");
|
|
|
}
|
|
|
@@ -1832,4 +1878,87 @@ public class GameScoreServiceImpl implements IGameScoreService {
|
|
|
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
|
|
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;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|