|
@@ -0,0 +1,347 @@
|
|
|
+package org.dromara.system.service.impl.app;
|
|
|
+
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.system.domain.GameAthlete;
|
|
|
+import org.dromara.system.domain.GameEventProject;
|
|
|
+import org.dromara.system.domain.GameScore;
|
|
|
+import org.dromara.system.domain.vo.app.PhysicalDeviceVo;
|
|
|
+import org.dromara.system.domain.vo.app.PhysicalTestVo;
|
|
|
+import org.dromara.system.mapper.GameAthleteMapper;
|
|
|
+import org.dromara.system.mapper.GameEventProjectMapper;
|
|
|
+import org.dromara.system.mapper.GameScoreMapper;
|
|
|
+import org.dromara.system.service.app.IPhysicalTestService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 体质测试Service业务层处理
|
|
|
+ *
|
|
|
+ * @author zlt
|
|
|
+ * @date 2025-01-27
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class PhysicalTestServiceImpl implements IPhysicalTestService {
|
|
|
+
|
|
|
+ private final GameEventProjectMapper projectMapper;
|
|
|
+ private final GameAthleteMapper athleteMapper;
|
|
|
+ private final GameScoreMapper scoreMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean processPhysicalTestData(List<PhysicalTestVo> results, Long eventId) {
|
|
|
+ try {
|
|
|
+ log.info("开始处理体质测试数据,数据条数: {}, 赛事ID: {}", results.size(), eventId);
|
|
|
+
|
|
|
+ for (PhysicalTestVo result : results) {
|
|
|
+ log.debug("处理体质测试数据: testName={}, testKey={}, userId={}, name={}",
|
|
|
+ result.getTestName(), result.getTestKey(), result.getUserId(), result.getName());
|
|
|
+
|
|
|
+ // 1. 处理项目数据
|
|
|
+ Long projectId = processProject(result, eventId);
|
|
|
+ log.debug("项目处理完成,projectId: {}", projectId);
|
|
|
+
|
|
|
+ // 2. 处理运动员数据
|
|
|
+ Long athleteId = processAthlete(result, eventId);
|
|
|
+ log.debug("运动员处理完成,athleteId: {}", athleteId);
|
|
|
+
|
|
|
+ // 3. 处理成绩数据
|
|
|
+ processScore(result, eventId, projectId, athleteId);
|
|
|
+ log.debug("成绩处理完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("体质测试数据处理完成,共处理 {} 条数据", results.size());
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理体质测试数据失败", e);
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean saveDeviceData(PhysicalDeviceVo deviceVo, Long eventId) {
|
|
|
+ try {
|
|
|
+ log.info("开始处理设备体质测试数据,项目: {}, 记录数: {}", deviceVo.getTestName(), deviceVo.getRecordCount());
|
|
|
+
|
|
|
+ // 1. 处理项目数据 - 根据testName查找或创建项目
|
|
|
+ Long projectId = processDeviceProject(deviceVo.getTestName(), eventId);
|
|
|
+ log.debug("设备项目处理完成,projectId: {}", projectId);
|
|
|
+
|
|
|
+ // 2. 处理每条记录
|
|
|
+ for (PhysicalDeviceVo.Record record : deviceVo.getResultInfo()) {
|
|
|
+ log.debug("处理设备记录: stuNo={}, name={}", record.getStuNo(), record.getName());
|
|
|
+
|
|
|
+ // 3. 处理运动员数据 - 根据stuNo作为身份证号查找或创建运动员
|
|
|
+ Long athleteId = processDeviceAthlete(record, eventId);
|
|
|
+ log.debug("设备运动员处理完成,athleteId: {}", athleteId);
|
|
|
+
|
|
|
+ // 4. 处理成绩数据 - 将testTime、resultData、referee存为JSON
|
|
|
+ processDeviceScore(record, eventId, projectId, athleteId);
|
|
|
+ log.debug("设备成绩处理完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("设备体质测试数据处理完成,共处理 {} 条数据", deviceVo.getRecordCount());
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理设备体质测试数据失败", e);
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理项目数据
|
|
|
+ */
|
|
|
+ private Long processProject(PhysicalTestVo result, Long eventId) {
|
|
|
+ // 根据testKey查找项目
|
|
|
+ LambdaQueryWrapper<GameEventProject> projectWrapper = Wrappers.lambdaQuery(GameEventProject.class)
|
|
|
+ .eq(GameEventProject::getEventId, eventId)
|
|
|
+ .eq(GameEventProject::getRemark, result.getTestKey())
|
|
|
+ .eq(GameEventProject::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameEventProject existingProject = projectMapper.selectOne(projectWrapper);
|
|
|
+
|
|
|
+ if (existingProject != null) {
|
|
|
+ log.debug("找到现有项目,projectId: {}", existingProject.getProjectId());
|
|
|
+ // 更新项目名称(如果不同)
|
|
|
+ if (!result.getTestName().equals(existingProject.getProjectName())) {
|
|
|
+ log.info("项目名称不符: {} -> {}", existingProject.getProjectName(), result.getTestName());
|
|
|
+ throw new RuntimeException("项目名称不符");
|
|
|
+ }
|
|
|
+ return existingProject.getProjectId();
|
|
|
+ } else {
|
|
|
+ // 创建新项目
|
|
|
+ log.info("创建新项目: testName={}, testKey={}", result.getTestName(), result.getTestKey());
|
|
|
+ GameEventProject newProject = new GameEventProject();
|
|
|
+ newProject.setEventId(eventId);
|
|
|
+ newProject.setProjectName(result.getTestName());
|
|
|
+ newProject.setRemark(result.getTestKey());
|
|
|
+ newProject.setProjectType("5"); // 体测
|
|
|
+ newProject.setClassification("0"); // 个人
|
|
|
+ newProject.setStatus("0"); // 正常状态
|
|
|
+ newProject.setDelFlag("0");
|
|
|
+
|
|
|
+ int insertResult = projectMapper.insert(newProject);
|
|
|
+ if (insertResult > 0) {
|
|
|
+ log.info("新项目创建成功,projectId: {}", newProject.getProjectId());
|
|
|
+ return newProject.getProjectId();
|
|
|
+ } else {
|
|
|
+ log.error("项目插入失败");
|
|
|
+ throw new RuntimeException("项目创建失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理运动员数据
|
|
|
+ */
|
|
|
+ private Long processAthlete(PhysicalTestVo result, Long eventId) {
|
|
|
+ // 根据身份证号查找运动员
|
|
|
+ LambdaQueryWrapper<GameAthlete> athleteWrapper = Wrappers.lambdaQuery(GameAthlete.class)
|
|
|
+ .eq(GameAthlete::getEventId, eventId)
|
|
|
+ .eq(GameAthlete::getIdCard, result.getUserId())
|
|
|
+ .eq(GameAthlete::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameAthlete existingAthlete = athleteMapper.selectOne(athleteWrapper);
|
|
|
+
|
|
|
+ if (existingAthlete != null) {
|
|
|
+ log.debug("找到现有运动员,athleteId: {}", existingAthlete.getAthleteId());
|
|
|
+ // 更新运动员姓名(如果不同)
|
|
|
+ if (!result.getName().equals(existingAthlete.getName())) {
|
|
|
+ log.info("要更新的运动员姓名不符: {} -> {}", existingAthlete.getName(), result.getName());
|
|
|
+ throw new RuntimeException("要更新的运动员姓名不符");
|
|
|
+ }
|
|
|
+ return existingAthlete.getAthleteId();
|
|
|
+ } else {
|
|
|
+ // 创建新运动员
|
|
|
+ log.info("创建新运动员: name={}, idCard={}", result.getName(), result.getUserId());
|
|
|
+ GameAthlete newAthlete = new GameAthlete();
|
|
|
+ newAthlete.setEventId(eventId);
|
|
|
+ newAthlete.setIdCard(result.getUserId());
|
|
|
+ newAthlete.setName(result.getName());
|
|
|
+ newAthlete.setStatus("0"); // 正常状态
|
|
|
+ newAthlete.setDelFlag("0");
|
|
|
+
|
|
|
+ int insertResult = athleteMapper.insert(newAthlete);
|
|
|
+ if (insertResult > 0) {
|
|
|
+ log.info("新运动员创建成功,athleteId: {}", newAthlete.getAthleteId());
|
|
|
+ return newAthlete.getAthleteId();
|
|
|
+ } else {
|
|
|
+ log.error("运动员插入失败:{}", newAthlete.getName());
|
|
|
+ throw new RuntimeException("运动员创建失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理成绩数据
|
|
|
+ */
|
|
|
+ private void processScore(PhysicalTestVo result, Long eventId, Long projectId, Long athleteId) {
|
|
|
+ // 检查是否已存在该运动员该项目的成绩
|
|
|
+ LambdaQueryWrapper<GameScore> scoreWrapper = Wrappers.lambdaQuery(GameScore.class)
|
|
|
+ .eq(GameScore::getEventId, eventId)
|
|
|
+ .eq(GameScore::getProjectId, projectId)
|
|
|
+ .eq(GameScore::getAthleteId, athleteId)
|
|
|
+ .eq(GameScore::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameScore existingScore = scoreMapper.selectOne(scoreWrapper);
|
|
|
+
|
|
|
+ // 构建remark数据
|
|
|
+ Map<String, Object> remarkData = new HashMap<>();
|
|
|
+ remarkData.put("testTime", result.getTestTime());
|
|
|
+ remarkData.put("resultData", result.getResultData());
|
|
|
+ String remarkJson = JSONUtil.toJsonStr(remarkData);
|
|
|
+
|
|
|
+ if (existingScore != null) {
|
|
|
+ // 更新现有成绩
|
|
|
+ log.info("更新现有成绩记录,scoreId: {}, 新分数: {}", existingScore.getScoreId(), result.getResultScore());
|
|
|
+ existingScore.setIndividualPerformance(result.getResultScore());
|
|
|
+ existingScore.setRemark(remarkJson);
|
|
|
+ existingScore.setStatusFlag("1"); // 处理完毕
|
|
|
+ scoreMapper.updateById(existingScore);
|
|
|
+ } else {
|
|
|
+ // 创建新成绩记录
|
|
|
+ log.info("创建新成绩记录,athleteId: {}, projectId: {}, score: {}",
|
|
|
+ athleteId, projectId, result.getResultScore());
|
|
|
+ GameScore newScore = new GameScore();
|
|
|
+ newScore.setEventId(eventId);
|
|
|
+ newScore.setProjectId(projectId);
|
|
|
+ newScore.setAthleteId(athleteId);
|
|
|
+ newScore.setIndividualPerformance(result.getResultScore());
|
|
|
+ newScore.setRemark(remarkJson);
|
|
|
+ newScore.setScoreType("physicalTest"); // 默认成绩类型
|
|
|
+ newScore.setStatusFlag("1"); // 处理完毕
|
|
|
+ newScore.setStatus("0"); // 正常状态
|
|
|
+ newScore.setDelFlag("0");
|
|
|
+
|
|
|
+ int insertResult = scoreMapper.insert(newScore);
|
|
|
+ if (insertResult > 0) {
|
|
|
+ log.info("新成绩记录创建成功,scoreId: {}", newScore.getScoreId());
|
|
|
+ } else {
|
|
|
+ log.error("成绩记录插入失败");
|
|
|
+ throw new RuntimeException("成绩记录创建失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理设备项目数据
|
|
|
+ */
|
|
|
+ private Long processDeviceProject(String testName, Long eventId) {
|
|
|
+ // 根据testName查找项目
|
|
|
+ LambdaQueryWrapper<GameEventProject> projectWrapper = Wrappers.lambdaQuery(GameEventProject.class)
|
|
|
+ .eq(GameEventProject::getEventId, eventId)
|
|
|
+ .eq(GameEventProject::getProjectName, testName)
|
|
|
+ .eq(GameEventProject::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameEventProject existingProject = projectMapper.selectOne(projectWrapper);
|
|
|
+
|
|
|
+ if (existingProject != null) {
|
|
|
+ log.debug("找到现有项目,projectId: {}", existingProject.getProjectId());
|
|
|
+ return existingProject.getProjectId();
|
|
|
+ } else {
|
|
|
+ log.error(testName + "项目不存在"); //不能创建项目,因为没有项目key
|
|
|
+ throw new RuntimeException(testName + "项目不存在");
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理设备运动员数据
|
|
|
+ */
|
|
|
+ private Long processDeviceAthlete(PhysicalDeviceVo.Record record, Long eventId) {
|
|
|
+ // 根据stuNo作为身份证号查找运动员
|
|
|
+ LambdaQueryWrapper<GameAthlete> athleteWrapper = Wrappers.lambdaQuery(GameAthlete.class)
|
|
|
+ .eq(GameAthlete::getEventId, eventId)
|
|
|
+ .eq(GameAthlete::getIdCard, record.getStuNo())
|
|
|
+ .eq(GameAthlete::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameAthlete existingAthlete = athleteMapper.selectOne(athleteWrapper);
|
|
|
+
|
|
|
+ if (existingAthlete != null) {
|
|
|
+ log.debug("找到现有运动员,athleteId: {}", existingAthlete.getAthleteId());
|
|
|
+ // 更新运动员姓名(如果不同)
|
|
|
+ if (!record.getName().equals(existingAthlete.getName())) {
|
|
|
+ log.info("要更新的运动员姓名不符: {} -> {}", existingAthlete.getName(), record.getName());
|
|
|
+ throw new RuntimeException("要更新的运动员姓名不符");
|
|
|
+ }
|
|
|
+ return existingAthlete.getAthleteId();
|
|
|
+ } else {
|
|
|
+ // 创建新运动员
|
|
|
+ log.info("创建新运动员: name={}, stuNo={}", record.getName(), record.getStuNo());
|
|
|
+ GameAthlete newAthlete = new GameAthlete();
|
|
|
+ newAthlete.setEventId(eventId);
|
|
|
+ newAthlete.setIdCard(record.getStuNo()); // stuNo映射到IdCard
|
|
|
+ newAthlete.setName(record.getName()); // name映射到name
|
|
|
+ newAthlete.setStatus("0"); // 正常状态
|
|
|
+ newAthlete.setDelFlag("0");
|
|
|
+
|
|
|
+ int insertResult = athleteMapper.insert(newAthlete);
|
|
|
+ if (insertResult > 0) {
|
|
|
+ log.info("新运动员创建成功,athleteId: {}", newAthlete.getAthleteId());
|
|
|
+ return newAthlete.getAthleteId();
|
|
|
+ } else {
|
|
|
+ log.error("运动员插入失败:{}", newAthlete.getName());
|
|
|
+ throw new RuntimeException("运动员创建失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理设备成绩数据
|
|
|
+ */
|
|
|
+ private void processDeviceScore(PhysicalDeviceVo.Record record, Long eventId, Long projectId, Long athleteId) {
|
|
|
+ // 检查是否已存在该运动员该项目的成绩
|
|
|
+ LambdaQueryWrapper<GameScore> scoreWrapper = Wrappers.lambdaQuery(GameScore.class)
|
|
|
+ .eq(GameScore::getEventId, eventId)
|
|
|
+ .eq(GameScore::getProjectId, projectId)
|
|
|
+ .eq(GameScore::getAthleteId, athleteId)
|
|
|
+ .eq(GameScore::getDelFlag, "0");
|
|
|
+
|
|
|
+ GameScore existingScore = scoreMapper.selectOne(scoreWrapper);
|
|
|
+
|
|
|
+ // 构建remark数据 - 包含testTime、resultData、referee
|
|
|
+ Map<String, Object> remarkData = new HashMap<>();
|
|
|
+ remarkData.put("testTime", record.getTestTime());
|
|
|
+ remarkData.put("resultData", record.getResultData());
|
|
|
+ remarkData.put("referee", record.getReferee());
|
|
|
+ String remarkJson = JSONUtil.toJsonStr(remarkData);
|
|
|
+
|
|
|
+ if (existingScore != null) {
|
|
|
+ // 更新现有成绩
|
|
|
+ log.info("更新现有成绩记录,scoreId: {}", existingScore.getScoreId());
|
|
|
+ existingScore.setRemark(remarkJson);
|
|
|
+ existingScore.setStatusFlag("1"); // 处理完毕
|
|
|
+ scoreMapper.updateById(existingScore);
|
|
|
+ } else {
|
|
|
+ // 创建新成绩记录
|
|
|
+ log.info("创建新成绩记录,athleteId: {}, projectId: {}", athleteId, projectId);
|
|
|
+ GameScore newScore = new GameScore();
|
|
|
+ newScore.setEventId(eventId);
|
|
|
+ newScore.setProjectId(projectId);
|
|
|
+ newScore.setAthleteId(athleteId);
|
|
|
+ newScore.setRemark(remarkJson);
|
|
|
+ newScore.setScoreType("physicalDevice"); // 默认成绩类型
|
|
|
+ newScore.setStatusFlag("1"); // 处理完毕
|
|
|
+ newScore.setStatus("0"); // 正常状态
|
|
|
+ newScore.setDelFlag("0");
|
|
|
+
|
|
|
+ int insertResult = scoreMapper.insert(newScore);
|
|
|
+ if (insertResult > 0) {
|
|
|
+ log.info("新成绩记录创建成功,scoreId: {}", newScore.getScoreId());
|
|
|
+ } else {
|
|
|
+ log.error("成绩记录插入失败");
|
|
|
+ throw new RuntimeException("成绩记录创建失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|