|
@@ -1,5 +1,6 @@
|
|
|
package org.dromara.system.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.img.FontUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
@@ -19,6 +20,7 @@ import com.itextpdf.text.pdf.PdfWriter;
|
|
|
import jakarta.annotation.Resource;
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
+import jakarta.validation.constraints.NotNull;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.io.IOUtils;
|
|
|
import org.apache.commons.io.output.ByteArrayOutputStream;
|
|
@@ -33,17 +35,13 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
|
import org.dromara.system.domain.GameEvent;
|
|
|
-import org.dromara.system.domain.bo.GameAthleteBo;
|
|
|
-import org.dromara.system.domain.bo.GameEventBo;
|
|
|
-import org.dromara.system.domain.bo.GameTeamBo;
|
|
|
-import org.dromara.system.domain.bo.GenerateBibBo;
|
|
|
+import org.dromara.system.domain.GameEventGroup;
|
|
|
+import org.dromara.system.domain.PdfEntry;
|
|
|
+import org.dromara.system.domain.bo.*;
|
|
|
import org.dromara.system.domain.constant.GameEventConstant;
|
|
|
import org.dromara.system.domain.vo.*;
|
|
|
import org.dromara.system.mapper.GameEventMapper;
|
|
|
-import org.dromara.system.service.IGameAthleteService;
|
|
|
-import org.dromara.system.service.IGameEventProjectService;
|
|
|
-import org.dromara.system.service.IGameEventService;
|
|
|
-import org.dromara.system.service.IGameTeamService;
|
|
|
+import org.dromara.system.service.*;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -54,8 +52,13 @@ import javax.imageio.ImageIO;
|
|
|
import java.awt.image.BufferedImage;
|
|
|
import java.io.*;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
import java.util.stream.Collectors;
|
|
|
+import java.util.zip.ZipEntry;
|
|
|
+import java.util.zip.ZipOutputStream;
|
|
|
|
|
|
/**
|
|
|
* 赛事基本信息Service业务层处理
|
|
@@ -871,4 +874,227 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
return BaseFont.createFont(temp.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取赛事项目进度信息
|
|
|
+ *
|
|
|
+ * @param eventId 赛事ID
|
|
|
+ * @return 项目进度列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<ProjectProgressVo> getProjectProgress(Long eventId) {
|
|
|
+ try {
|
|
|
+ // 1. 获取该赛事的所有项目
|
|
|
+ List<GameEventProjectVo> projects = gameEventProjectService.queryListByEventId(eventId);
|
|
|
+ if (CollectionUtils.isEmpty(projects)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取所有项目的组别信息
|
|
|
+ GameEventGroupBo bo = new GameEventGroupBo();
|
|
|
+ bo.setEventId(eventId);
|
|
|
+ List<GameEventGroupVo> allGroups = gameEventGroupService.queryList(bo);
|
|
|
+ Map<Long, List<GameEventGroupVo>> projectGroupsMap = allGroups.stream()
|
|
|
+ .collect(Collectors.groupingBy(GameEventGroupVo::getProjectId));
|
|
|
+
|
|
|
+ // 3. 构建项目进度信息
|
|
|
+ List<ProjectProgressVo> progressList = new ArrayList<>();
|
|
|
+ Date currentTime = new Date();
|
|
|
+
|
|
|
+ for (GameEventProjectVo project : projects) {
|
|
|
+ ProjectProgressVo progressVo = new ProjectProgressVo();
|
|
|
+ progressVo.setProjectId(project.getProjectId());
|
|
|
+ progressVo.setProjectName(project.getProjectName());
|
|
|
+ progressVo.setProjectType(project.getProjectType());
|
|
|
+ progressVo.setClassification(project.getClassification());
|
|
|
+ progressVo.setLocation(project.getLocation());
|
|
|
+ progressVo.setStartTime(project.getStartTime());
|
|
|
+ progressVo.setEndTime(project.getEndTime());
|
|
|
+
|
|
|
+ // 获取该项目的组别信息
|
|
|
+ List<GameEventGroupVo> projectGroups = projectGroupsMap.get(project.getProjectId());
|
|
|
+ List<GroupProgressVo> groupProgressList = new ArrayList<>();
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(projectGroups)) {
|
|
|
+ // 没有组别的项目,直接使用项目时间
|
|
|
+ progressVo.setGroups(new ArrayList<>());
|
|
|
+ progressVo.setStatus(getProjectStatus(project.getStartTime(), project.getEndTime(), currentTime));
|
|
|
+ progressVo.setStatusText(getStatusText(progressVo.getStatus()));
|
|
|
+ progressVo.setProgressPercentage(calculateProgressPercentage(project.getStartTime(), project.getEndTime(), currentTime));
|
|
|
+ } else {
|
|
|
+ // 有组别的项目,处理每个组别
|
|
|
+ for (GameEventGroupVo group : projectGroups) {
|
|
|
+ GroupProgressVo groupProgress = new GroupProgressVo();
|
|
|
+ groupProgress.setGroupId(group.getGroupId());
|
|
|
+ groupProgress.setGroupName(group.getGroupName());
|
|
|
+ groupProgress.setBeginTime(group.getBeginTime());
|
|
|
+ groupProgress.setEndTime(group.getEndTime());
|
|
|
+ groupProgress.setStatus(getProjectStatus(group.getBeginTime(), group.getEndTime(), currentTime));
|
|
|
+ groupProgress.setStatusText(getStatusText(groupProgress.getStatus()));
|
|
|
+ groupProgressList.add(groupProgress);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按组别完整开始时间排序
|
|
|
+ groupProgressList.sort((a, b) -> {
|
|
|
+ Date aTime = a.getBeginTime();
|
|
|
+ Date bTime = b.getBeginTime();
|
|
|
+ if (aTime == null && bTime == null) return 0;
|
|
|
+ if (aTime == null) return 1;
|
|
|
+ if (bTime == null) return -1;
|
|
|
+ // 使用完整的日期时间进行比较
|
|
|
+ return aTime.compareTo(bTime);
|
|
|
+ });
|
|
|
+
|
|
|
+ progressVo.setGroups(groupProgressList);
|
|
|
+
|
|
|
+ // 项目整体状态:如果所有组别都完成则为完成,如果有进行中的则为进行中,否则为未开始
|
|
|
+ String overallStatus = calculateOverallStatus(groupProgressList);
|
|
|
+ progressVo.setStatus(overallStatus);
|
|
|
+ progressVo.setStatusText(getStatusText(overallStatus));
|
|
|
+
|
|
|
+ // 计算项目整体进度
|
|
|
+ progressVo.setProgressPercentage(calculateOverallProgress(groupProgressList, currentTime));
|
|
|
+ }
|
|
|
+
|
|
|
+ progressList.add(progressVo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 按项目完整时间排序(如果有组别,按最早组别开始时间排序)
|
|
|
+ progressList.sort((a, b) -> {
|
|
|
+ Date aStartTime = getEarliestStartTime(a);
|
|
|
+ Date bStartTime = getEarliestStartTime(b);
|
|
|
+ if (aStartTime == null && bStartTime == null) return 0;
|
|
|
+ if (aStartTime == null) return 1;
|
|
|
+ if (bStartTime == null) return -1;
|
|
|
+ // 使用完整的日期时间进行比较,确保按年、月、日、时、分、秒排序
|
|
|
+ return aStartTime.compareTo(bStartTime);
|
|
|
+ });
|
|
|
+
|
|
|
+ return progressList;
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("获取赛事项目进度信息失败,eventId: {}", eventId, e);
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取项目状态
|
|
|
+ */
|
|
|
+ private String getProjectStatus(Date startTime, Date endTime, Date currentTime) {
|
|
|
+ if (startTime == null || endTime == null) {
|
|
|
+ return "0"; // 未开始
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentTime.before(startTime)) {
|
|
|
+ return "0"; // 未开始
|
|
|
+ } else if (currentTime.after(endTime)) {
|
|
|
+ return "2"; // 已完成
|
|
|
+ } else {
|
|
|
+ return "1"; // 进行中
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取状态描述
|
|
|
+ */
|
|
|
+ private String getStatusText(String status) {
|
|
|
+ switch (status) {
|
|
|
+ case "0": return "未开始";
|
|
|
+ case "1": return "进行中";
|
|
|
+ case "2": return "已完成";
|
|
|
+ default: return "未知";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算项目进度百分比
|
|
|
+ */
|
|
|
+ private Integer calculateProgressPercentage(Date startTime, Date endTime, Date currentTime) {
|
|
|
+ if (startTime == null || endTime == null || currentTime == null) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentTime.before(startTime)) {
|
|
|
+ return 0;
|
|
|
+ } else if (currentTime.after(endTime)) {
|
|
|
+ return 100;
|
|
|
+ } else {
|
|
|
+ long totalDuration = endTime.getTime() - startTime.getTime();
|
|
|
+ long elapsedDuration = currentTime.getTime() - startTime.getTime();
|
|
|
+ return (int) Math.round((double) elapsedDuration / totalDuration * 100);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算项目整体状态
|
|
|
+ */
|
|
|
+ private String calculateOverallStatus(List<GroupProgressVo> groups) {
|
|
|
+ if (CollectionUtils.isEmpty(groups)) {
|
|
|
+ return "0"; // 未开始
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean hasCompleted = false;
|
|
|
+ boolean hasInProgress = false;
|
|
|
+
|
|
|
+ for (GroupProgressVo group : groups) {
|
|
|
+ if ("2".equals(group.getStatus())) {
|
|
|
+ hasCompleted = true;
|
|
|
+ } else if ("1".equals(group.getStatus())) {
|
|
|
+ hasInProgress = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasInProgress) {
|
|
|
+ return "1"; // 进行中
|
|
|
+ } else if (hasCompleted && !hasInProgress) {
|
|
|
+ return "2"; // 已完成
|
|
|
+ } else {
|
|
|
+ return "0"; // 未开始
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算项目整体进度
|
|
|
+ */
|
|
|
+ private Integer calculateOverallProgress(List<GroupProgressVo> groups, Date currentTime) {
|
|
|
+ if (CollectionUtils.isEmpty(groups)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ int totalProgress = 0;
|
|
|
+ for (GroupProgressVo group : groups) {
|
|
|
+ if (group.getBeginTime() != null && group.getEndTime() != null) {
|
|
|
+ totalProgress += calculateProgressPercentage(group.getBeginTime(), group.getEndTime(), currentTime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return totalProgress / groups.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取项目的最早开始时间
|
|
|
+ * 优先使用组别时间,如果没有组别则使用项目时间
|
|
|
+ */
|
|
|
+ private Date getEarliestStartTime(ProjectProgressVo project) {
|
|
|
+ if (CollectionUtils.isEmpty(project.getGroups())) {
|
|
|
+ // 没有组别,直接返回项目开始时间
|
|
|
+ return project.getStartTime();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 有组别,找到最早的组别开始时间
|
|
|
+ Date earliestGroupTime = project.getGroups().stream()
|
|
|
+ .map(GroupProgressVo::getBeginTime)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .min(Date::compareTo)
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ // 如果组别时间存在,与项目时间比较,返回较早的时间
|
|
|
+ if (earliestGroupTime != null && project.getStartTime() != null) {
|
|
|
+ return earliestGroupTime.before(project.getStartTime()) ? earliestGroupTime : project.getStartTime();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果组别时间不存在,返回项目时间
|
|
|
+ return earliestGroupTime != null ? earliestGroupTime : project.getStartTime();
|
|
|
+ }
|
|
|
}
|