|
|
@@ -3,6 +3,7 @@ package org.dromara.system.service.impl.app;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.system.domain.GameAthlete;
|
|
|
import org.dromara.system.domain.GameEvent;
|
|
|
import org.dromara.system.domain.GameEventProject;
|
|
|
@@ -14,6 +15,12 @@ import org.dromara.system.domain.vo.GameEventProjectVo;
|
|
|
import org.dromara.system.domain.vo.GameEventVo;
|
|
|
import org.dromara.system.domain.vo.app.UserEventInfoVo;
|
|
|
import org.dromara.system.domain.vo.app.UserLoginVo;
|
|
|
+import org.dromara.system.domain.vo.app.ExperienceMyInfoVo;
|
|
|
+import org.dromara.system.domain.vo.app.ExperienceMyRecordVo;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.stream.Collectors;
|
|
|
import org.dromara.system.mapper.*;
|
|
|
import org.dromara.system.mapper.app.GameUserMapper;
|
|
|
import org.dromara.system.service.app.IUserEventService;
|
|
|
@@ -92,20 +99,20 @@ public class UserEventServiceImpl implements IUserEventService {
|
|
|
}
|
|
|
|
|
|
String url = String.format(
|
|
|
- "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
|
|
|
- appId, secret, code
|
|
|
- );
|
|
|
+ "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
|
|
|
+ appId, secret, code);
|
|
|
|
|
|
// 先获取字符串响应,避免Content-Type不匹配问题
|
|
|
String responseBody = webClient.get()
|
|
|
- .uri(url)
|
|
|
- .retrieve()
|
|
|
- .onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
|
|
- response -> response.bodyToMono(String.class)
|
|
|
- .flatMap(body -> Mono.error(new RuntimeException("HTTP错误: " + response.statusCode() + ", 响应: " + body))))
|
|
|
- .bodyToMono(String.class)
|
|
|
- .timeout(Duration.ofSeconds(30)) // 30秒超时
|
|
|
- .block(); // 同步等待结果
|
|
|
+ .uri(url)
|
|
|
+ .retrieve()
|
|
|
+ .onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
|
|
+ response -> response.bodyToMono(String.class)
|
|
|
+ .flatMap(body -> Mono.error(new RuntimeException(
|
|
|
+ "HTTP错误: " + response.statusCode() + ", 响应: " + body))))
|
|
|
+ .bodyToMono(String.class)
|
|
|
+ .timeout(Duration.ofSeconds(30)) // 30秒超时
|
|
|
+ .block(); // 同步等待结果
|
|
|
|
|
|
if (responseBody == null || responseBody.trim().isEmpty()) {
|
|
|
throw new RuntimeException("微信接口返回空结果");
|
|
|
@@ -243,8 +250,8 @@ public class UserEventServiceImpl implements IUserEventService {
|
|
|
}
|
|
|
|
|
|
private UserEventInfoVo assembleUserEventInfo(GameUser user, GameAthlete athlete,
|
|
|
- GameEvent event, List<GameEventProject> projects,
|
|
|
- List<GameScore> scores) {
|
|
|
+ GameEvent event, List<GameEventProject> projects,
|
|
|
+ List<GameScore> scores) {
|
|
|
UserEventInfoVo result = new UserEventInfoVo();
|
|
|
result.setUserId(user.getUserId());
|
|
|
result.setUsername(user.getUsername());
|
|
|
@@ -271,11 +278,11 @@ public class UserEventServiceImpl implements IUserEventService {
|
|
|
// 将成绩信息添加到项目信息中,可以通过扩展字段或备注字段存储
|
|
|
// 这里我们使用备注字段来存储额外的成绩信息
|
|
|
String scoreInfo = String.format("个人成绩:%s, 团队成绩:%s, 积分:%d, 排名:%d, 奖项:%s",
|
|
|
- score.getIndividualPerformance() != null ? score.getIndividualPerformance().toString() : "无",
|
|
|
- score.getTeamPerformance() != null ? score.getTeamPerformance().toString() : "无",
|
|
|
- score.getScorePoint() != null ? score.getScorePoint() : 0,
|
|
|
- score.getScoreRank() != null ? score.getScoreRank() : 0,
|
|
|
- calculateAward(score.getScoreRank()));
|
|
|
+ score.getIndividualPerformance() != null ? score.getIndividualPerformance().toString() : "无",
|
|
|
+ score.getTeamPerformance() != null ? score.getTeamPerformance().toString() : "无",
|
|
|
+ score.getScorePoint() != null ? score.getScorePoint() : 0,
|
|
|
+ score.getScoreRank() != null ? score.getScoreRank() : 0,
|
|
|
+ calculateAward(score.getScoreRank()));
|
|
|
projectInfo.setRemark(scoreInfo);
|
|
|
}
|
|
|
|
|
|
@@ -283,7 +290,8 @@ public class UserEventServiceImpl implements IUserEventService {
|
|
|
}
|
|
|
|
|
|
// 按项目开始时间排序(处理null值)
|
|
|
- projectList.sort(Comparator.comparing(GameEventProjectVo::getStartTime, Comparator.nullsLast(Comparator.naturalOrder())));
|
|
|
+ projectList.sort(Comparator.comparing(GameEventProjectVo::getStartTime,
|
|
|
+ Comparator.nullsLast(Comparator.naturalOrder())));
|
|
|
result.setProjectList(projectList);
|
|
|
|
|
|
return result;
|
|
|
@@ -291,16 +299,67 @@ public class UserEventServiceImpl implements IUserEventService {
|
|
|
|
|
|
private GameScore findScoreByProjectId(List<GameScore> scores, Long projectId) {
|
|
|
return scores.stream()
|
|
|
- .filter(score -> score.getProjectId().equals(projectId))
|
|
|
- .findFirst()
|
|
|
- .orElse(null);
|
|
|
+ .filter(score -> score.getProjectId().equals(projectId))
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
}
|
|
|
|
|
|
private String calculateAward(Integer rank) {
|
|
|
- if (rank == null) return "无";
|
|
|
- if (rank == 1) return "金牌";
|
|
|
- if (rank == 2) return "银牌";
|
|
|
- if (rank == 3) return "铜牌";
|
|
|
+ if (rank == null)
|
|
|
+ return "无";
|
|
|
+ if (rank == 1)
|
|
|
+ return "金牌";
|
|
|
+ if (rank == 2)
|
|
|
+ return "银牌";
|
|
|
+ if (rank == 3)
|
|
|
+ return "铜牌";
|
|
|
return "无";
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ExperienceMyInfoVo getExperienceMyInfo(String userId) {
|
|
|
+ return gameUserMapper.getExperienceMyInfo(userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ExperienceMyRecordVo> getExperienceMyRecord(String phone) {
|
|
|
+ if (StringUtils.isBlank(phone)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ List<ExperienceMyRecordVo> records = gameUserMapper.getExperienceMyRecord(phone.trim());
|
|
|
+ if (CollectionUtils.isNotEmpty(records)) {
|
|
|
+ for (ExperienceMyRecordVo vo : records) {
|
|
|
+ if (vo.getRawScore() != null) {
|
|
|
+ vo.setScore(formatScore(vo.getRawScore(), vo.getScoreRule()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return records;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化成绩
|
|
|
+ * 计时类(scoreRule = "1")转换为 "HH:mm:ss.SSS" 格式,其它类型保留原始数字字符串
|
|
|
+ */
|
|
|
+ private String formatScore(BigDecimal rawScore, String scoreRule) {
|
|
|
+ if (rawScore == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ // "1" 代表计时类
|
|
|
+ if ("1".equals(scoreRule)) {
|
|
|
+ long totalSeconds = rawScore.longValue();
|
|
|
+ BigDecimal fraction = rawScore.subtract(BigDecimal.valueOf(totalSeconds));
|
|
|
+ long millis = fraction.multiply(BigDecimal.valueOf(1000))
|
|
|
+ .setScale(0, java.math.RoundingMode.HALF_UP)
|
|
|
+ .longValue();
|
|
|
+ long hours = totalSeconds / 3600;
|
|
|
+ long minutes = (totalSeconds % 3600) / 60;
|
|
|
+ long seconds = totalSeconds % 60;
|
|
|
+
|
|
|
+ return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
|
|
|
+ } else {
|
|
|
+ // 其它类型,去除尾随零后转为普通字符串
|
|
|
+ return rawScore.stripTrailingZeros().toPlainString();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|