Browse Source

feat:线上
fix:修复bug,添加校验
perf:优化

wenkai 3 days ago
parent
commit
4d2c600f02

+ 20 - 20
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameTeamController.java

@@ -1,34 +1,35 @@
 package org.dromara.system.controller;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import lombok.RequiredArgsConstructor;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.excel.core.ExcelResult;
-import org.dromara.system.domain.GameTeam;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.validation.annotation.Validated;
+import org.dromara.common.excel.utils.ExcelUtil;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.log.annotation.Log;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.excel.utils.ExcelUtil;
-import org.dromara.system.domain.vo.GameTeamVo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.system.domain.GameTeam;
 import org.dromara.system.domain.bo.GameTeamBo;
+import org.dromara.system.domain.request.UpdateTeamAthletesRequest;
+import org.dromara.system.domain.vo.GameTeamVo;
 import org.dromara.system.service.IGameTeamService;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
-import org.dromara.system.domain.request.UpdateTeamAthletesRequest;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 参赛队伍
@@ -65,7 +66,6 @@ public class GameTeamController extends BaseController {
         try {
             excelResult = ExcelUtil.importExcel(file.getInputStream(), GameTeamVo.class, true);
             List<GameTeam> list = MapstructUtils.convert(excelResult.getList(), GameTeam.class);
-            log.info("转换后的列表:", list);
             gameTeamService.saveBatch(list);
         } catch (IOException e) {
             e.printStackTrace();

+ 0 - 1
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/ActivityController.java

@@ -2,7 +2,6 @@ package org.dromara.system.controller.app;
 
 import cn.dev33.satoken.annotation.SaIgnore;
 import lombok.RequiredArgsConstructor;
-import org.dromara.system.domain.bo.ArticleBo;
 import org.dromara.system.domain.constant.GameEventConstant;
 import org.dromara.system.domain.vo.ArticleVo;
 import org.dromara.system.service.IArticleService;

+ 33 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AppEnrollController.java

@@ -0,0 +1,33 @@
+package org.dromara.system.controller.app;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.system.domain.bo.EnrollBo;
+import org.dromara.system.service.IEnrollService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@SaIgnore
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/app/enroll")
+public class AppEnrollController {
+
+    private final IEnrollService enrollService;
+
+    @RepeatSubmit
+    @PostMapping
+    public R<String> enroll(
+        @Validated
+        @RequestBody
+        EnrollBo enrollBo
+    ) {
+        Boolean result = enrollService.enroll(enrollBo);
+        return R.ok(result ? "报名成功" : "报名失败");
+    }
+}

+ 0 - 1
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/app/AppMarkdownController.java

@@ -1,7 +1,6 @@
 package org.dromara.system.controller.app;
 
 
-import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;

+ 35 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/EnrollBo.java

@@ -0,0 +1,35 @@
+package org.dromara.system.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class EnrollBo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotNull(message = "赛事不能为空")
+    private Long eventId;
+
+    @NotNull(message = "项目不能为空")
+    private Long projectId;
+
+    @NotNull(message = "名称不能为空")
+    private String name;
+
+    @NotNull(message = "队伍名称不能为空")
+    private String teamName;
+
+    @NotNull(message = "性别不能为空")
+    private Integer gender;
+
+    @NotNull(message = "年龄不能为空")
+    private Integer age;
+
+    @NotNull(message = "电话不能为空")
+    private String phone;
+
+    @NotNull(message = "身份证不能为空")
+    private String idCard;
+}

+ 8 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/GameTeamMapper.java

@@ -1,5 +1,6 @@
 package org.dromara.system.mapper;
 
+import org.apache.ibatis.annotations.Select;
 import org.dromara.system.domain.GameTeam;
 import org.dromara.system.domain.vo.GameTeamVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -12,4 +13,11 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  */
 public interface GameTeamMapper extends BaseMapperPlus<GameTeam, GameTeamVo> {
 
+    @Select("""
+                SELECT * FROM game_team
+        WHERE del_flag='0' AND event_id = #{eventId} AND number_range IS NOT NULL
+        ORDER BY CAST(SUBSTR(number_range, 1, 4) AS SIGNED) DESC
+        LIMIT 1
+        """)
+    GameTeam selectMaxNumber(Long eventId);
 }

+ 3 - 3
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IEnrollService.java

@@ -2,11 +2,9 @@ package org.dromara.system.service;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.http.ResponseEntity;
+import org.dromara.system.domain.bo.EnrollBo;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.util.Map;
-
 public interface IEnrollService {
 
     /**
@@ -23,4 +21,6 @@ public interface IEnrollService {
      * @return
      */
     Boolean importDataForPoi(MultipartFile file, Long eventId);
+
+    Boolean enroll(EnrollBo enrollBo);
 }

+ 5 - 5
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameAthleteService.java

@@ -1,16 +1,14 @@
 package org.dromara.system.service;
 
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.GameAthlete;
+import org.dromara.system.domain.bo.GameAthleteBo;
 import org.dromara.system.domain.vo.AthleteScoreVo;
 import org.dromara.system.domain.vo.GameAthleteVo;
-import org.dromara.system.domain.bo.GameAthleteBo;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Optional;
-import java.util.Set;
 
 /**
  * 参赛队员Service接口
@@ -97,4 +95,6 @@ public interface IGameAthleteService {
      * @return 运动员列表
      */
     List<GameAthleteVo> queryListByEventIdAndProjectId(Long eventId, Long projectId, String searchValue);
+
+    String queryMaxNumber(Long teamId);
 }

+ 4 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameTeamService.java

@@ -115,4 +115,8 @@ public interface IGameTeamService {
      * @return
      */
     Map<Long, String> queryTeamIdAndName(Set<Long> teamIds);
+
+    GameTeam queryByName(String teamName, Long eventId);
+
+    GameTeam queryMaxNumber(Long eventId);
 }

+ 27 - 11
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameAthleteServiceImpl.java

@@ -3,31 +3,36 @@ package org.dromara.system.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+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.*;
+import org.dromara.system.domain.GameAthlete;
+import org.dromara.system.domain.GameEventProject;
+import org.dromara.system.domain.GameScore;
+import org.dromara.system.domain.GameTeam;
+import org.dromara.system.domain.bo.GameAthleteBo;
 import org.dromara.system.domain.bo.GameEventBo;
-import org.dromara.system.domain.bo.GameEventGroupBo;
 import org.dromara.system.domain.bo.GameTeamBo;
 import org.dromara.system.domain.constant.GameEventConstant;
 import org.dromara.system.domain.vo.*;
+import org.dromara.system.mapper.GameAthleteMapper;
 import org.dromara.system.mapper.GameEventProjectMapper;
 import org.dromara.system.mapper.GameScoreMapper;
 import org.dromara.system.mapper.GameTeamMapper;
-import org.dromara.system.service.*;
+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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.dromara.system.domain.bo.GameAthleteBo;
-import org.dromara.system.mapper.GameAthleteMapper;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -477,4 +482,15 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
                 .eq(GameAthlete::getEventId, eventId)
         );
     }
+
+    @Override
+    public String queryMaxNumber(Long teamId) {
+        return baseMapper.selectOne(
+            Wrappers.lambdaQuery(GameAthlete.class)
+                .eq(GameAthlete::getTeamId, teamId)
+                .orderByDesc(GameAthlete::getAthleteCode)
+                .select(GameAthlete::getAthleteCode)
+                .last("limit 1")
+        ).getAthleteCode();
+    }
 }

+ 31 - 21
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameEventServiceImpl.java

@@ -55,6 +55,8 @@ 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;
@@ -81,6 +83,8 @@ public class GameEventServiceImpl implements IGameEventService {
     private IGameEventProjectService gameEventProjectService;
     @Resource
     private IGameEventGroupService gameEventGroupService;
+    private static final ExecutorService PDF_GENERATION_EXECUTOR =
+        Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
 
     /**
      * 查询赛事基本信息
@@ -624,6 +628,7 @@ public class GameEventServiceImpl implements IGameEventService {
 
         byte[] backgroundImageBytes;
         byte[] logoImageBytes = null;
+
         //1.读取图片文件
         try {
             if (backgroundImage == null || backgroundImage.isEmpty()) {
@@ -658,6 +663,12 @@ public class GameEventServiceImpl implements IGameEventService {
             float pageWidth = bgImage.getWidth();
             float pageHeight = bgImage.getHeight();
 
+            // 3.1 验证背景图片比例是否为3:2横屏
+            float ratio = pageWidth / pageHeight;
+            if (Math.abs(ratio - 1.5f) > 0.1f) { // 允许0.1的误差
+                throw new IllegalArgumentException("背景图片比例不是3:2横屏比例,当前比例: " + String.format("%.2f", ratio));
+            }
+
             Integer finalFontSize = fontSize;
             // 4. 并行生成所有 PDF
             byte[] finalLogoImageBytes = logoImageBytes;
@@ -676,13 +687,11 @@ public class GameEventServiceImpl implements IGameEventService {
                         document.add(bg);
 
                         // 添加 Logo(如果存在)
-                        if (finalLogoImageBytes != null) {
+                        if (finalLogoImageBytes != null && logoX != null && logoY != null) {
                             Image img = Image.getInstance(finalLogoImageBytes);
                             img.scaleToFit(80, 80);
-                            float logoPositionX = logoX != null ? logoX.floatValue() : 50f;
-                            float logoPositionY = logoY != null ? logoY.floatValue() : pageHeight - 130f;
-                            logoPositionX += 10;  // 微调
-                            logoPositionY -= 50;
+                            float logoPositionX = logoX.floatValue();
+                            float logoPositionY = logoY.floatValue();
                             img.setAbsolutePosition(logoPositionX, logoPositionY);
                             cb.addImage(img);
                         }
@@ -694,30 +703,31 @@ public class GameEventServiceImpl implements IGameEventService {
                         float textPositionY = (pageHeight / 2) + (textHeight / 2);
                         addText(cb, baseFont, finalFontSize, textColor, textPositionX, textPositionY, athlete.getAthleteCode());
 
-                        // 添加赛事名称
+                        // 添加赛事名称(在3:2横屏比例下调整位置)
                         if (eventName != null && !eventName.trim().isEmpty()) {
-                            int eventNameFontSize = 64;
+                            int eventNameFontSize = Math.min(64, (int) (pageHeight * 0.08)); // 根据页面高度调整字体大小
                             cb.beginText();
                             cb.setFontAndSize(baseFont, eventNameFontSize);
                             cb.setColorFill(BaseColor.BLACK);
                             float textWidth2 = baseFont.getWidthPoint(eventName, eventNameFontSize);
                             float textX = (pageWidth - textWidth2) / 2;
-                            float textY = pageHeight - eventNameFontSize - 10;
+                            float textY = pageHeight - eventNameFontSize - 20; // 增加边距
                             cb.setTextMatrix(textX, textY);
                             cb.showText(eventName);
                             cb.endText();
                         }
 
-                        // 生成二维码
-                        String qrDataStr = getQrDataStr(eventName, groupName, teamNameMap, projectMap, athlete);
-                        byte[] qrBytes = generateQRCode(qrDataStr, 150, 150);
-                        Image qrImage = Image.getInstance(qrBytes);
-                        float qrX = qRCodeX != null ? qRCodeX.floatValue() : pageWidth - 170f;
-                        float qrY = qRCodeY != null ? qRCodeY.floatValue() : 50f;
-                        qrX += 15;
-                        qrY -= 55;
-                        qrImage.setAbsolutePosition(qrX, qrY);
-                        cb.addImage(qrImage);
+                        // 生成二维码(在3:2横屏比例下调整尺寸)
+                        if (qRCodeX != null && qRCodeY != null) {
+                            String qrDataStr = getQrDataStr(eventName, groupName, teamNameMap, projectMap, athlete);
+                            int qrSize = Math.min(150, (int) (Math.min(pageWidth, pageHeight) * 0.15)); // 根据页面尺寸调整二维码大小
+                            byte[] qrBytes = generateQRCode(qrDataStr, qrSize, qrSize);
+                            Image qrImage = Image.getInstance(qrBytes);
+                            float qrX = qRCodeX.floatValue();
+                            float qrY = qRCodeY.floatValue();
+                            qrImage.setAbsolutePosition(qrX, qrY);
+                            cb.addImage(qrImage);
+                        }
 
                         document.close();
                         byte[] pdfBytes = pdfStream.toByteArray();
@@ -732,8 +742,8 @@ public class GameEventServiceImpl implements IGameEventService {
                         System.err.println("生成 PDF 失败: " + athlete.getName() + " - " + e.getMessage());
                         throw new RuntimeException("生成 PDF 失败: " + athlete.getName(), e);
                     }
-                }))
-              .toList();
+                }, PDF_GENERATION_EXECUTOR))
+                .toList();
 
             // 等待所有任务完成
             List<PdfEntry> pdfEntries = pdfFutures.stream()
@@ -759,9 +769,9 @@ public class GameEventServiceImpl implements IGameEventService {
         }
     }
 
-
     /**
      * 生成二维码数据
+     *
      * @param eventName
      * @param groupName
      * @param teamNameMap

+ 45 - 5
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameTeamServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -54,10 +55,10 @@ public class GameTeamServiceImpl implements IGameTeamService {
     @Override
     public GameTeamVo queryById(Long teamId) {
         GameTeamVo vo = baseMapper.selectVoById(teamId);
-        if(vo==null){
+        if (vo == null) {
             return null;
         }
-        if(vo.getAthleteValue()!=null){
+        if (vo.getAthleteValue() != null) {
             log.info("teamId:{}, athleteValue:{}", teamId, vo.getAthleteValue());
             vo.setAthleteList(JSONUtil.toList(vo.getAthleteValue(), String.class));
         }
@@ -210,11 +211,20 @@ public class GameTeamServiceImpl implements IGameTeamService {
                 bo.setEventId((Long) cacheObject);
             }
         }
-        if(bo.getAthleteList()!=null){
+        if (bo.getAthleteList() != null) {
             bo.setAthleteValue(JSONUtil.toJsonStr(bo.getAthleteList()));
         }
         GameTeam add = MapstructUtils.convert(bo, GameTeam.class);
         validEntityBeforeSave(add);
+        //查询是否重复
+        Long count = baseMapper.selectCount(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getEventId, add.getEventId())
+                .eq(GameTeam::getTeamName, add.getTeamName())
+        );
+        if (count > 0) {
+            throw new ServiceException("队伍名称重复");
+        }
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setTeamId(add.getTeamId());
@@ -238,7 +248,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
                 bo.setEventId((Long) cacheObject);
             }
         }
-        if(bo.getAthleteList()!=null){
+        if (bo.getAthleteList() != null) {
             bo.setAthleteValue(JSONUtil.toJsonStr(bo.getAthleteList()));
         }
         GameTeam update = MapstructUtils.convert(bo, GameTeam.class);
@@ -275,6 +285,22 @@ public class GameTeamServiceImpl implements IGameTeamService {
      */
     @Override
     public Boolean saveBatch(List<GameTeam> list) {
+        if (CollectionUtils.isEmpty(list)) {
+            throw new ServiceException("导入信息为空");
+        }
+        Long eventId = list.get(0).getEventId();
+        Set<String> names = list.stream()
+            .map(GameTeam::getTeamName)
+            .collect(Collectors.toSet());
+        //查询是否重复
+        Long count = baseMapper.selectCount(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getEventId, eventId)
+                .in(GameTeam::getTeamName, names)
+        );
+        if (count > 0) {
+            throw new ServiceException("导入失败,有队伍名称重复");
+        }
         return baseMapper.insertBatch(list);
     }
 
@@ -309,7 +335,7 @@ public class GameTeamServiceImpl implements IGameTeamService {
     /**
      * 更新队伍中的运动员列表
      *
-     * @param teamId 队伍ID
+     * @param teamId     队伍ID
      * @param athleteIds 运动员ID列表
      * @return 是否更新成功
      */
@@ -369,4 +395,18 @@ public class GameTeamServiceImpl implements IGameTeamService {
             .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
         return map;
     }
+
+    @Override
+    public GameTeam queryByName(String teamName, Long eventId) {
+        return baseMapper.selectOne(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getTeamName, teamName)
+                .eq(GameTeam::getEventId, eventId)
+        );
+    }
+
+    @Override
+    public GameTeam queryMaxNumber(Long eventId) {
+        return baseMapper.selectMaxNumber(eventId);
+    }
 }

+ 90 - 17
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/IEnrollServiceImpl.java

@@ -1,43 +1,34 @@
 package org.dromara.system.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.lang.Snowflake;
-import cn.hutool.core.lang.UUID;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
-import cn.idev.excel.annotation.ExcelProperty;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import lombok.val;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.ObjectUtils;
-import org.dromara.system.controller.TestPoi;
+import org.dromara.system.domain.GameTeam;
+import org.dromara.system.domain.bo.EnrollBo;
 import org.dromara.system.domain.bo.GameAthleteBo;
-import org.dromara.system.domain.bo.GameEventProjectBo;
 import org.dromara.system.domain.bo.GameTeamBo;
 import org.dromara.system.domain.vo.EnrollProjectVo;
-import org.dromara.system.service.IEnrollService;
-import org.dromara.system.service.IGameAthleteService;
-import org.dromara.system.service.IGameEventProjectService;
-import org.dromara.system.service.IGameTeamService;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-import org.springframework.http.ResponseEntity;
+import org.dromara.system.service.*;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.*;
-import java.lang.reflect.Field;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
@@ -49,6 +40,7 @@ public class IEnrollServiceImpl implements IEnrollService {
     private final IGameEventProjectService gameEventProjectService;
     private final IGameTeamService gameTeamService;
     private final IGameAthleteService gameAthleteService;
+    private final IGameEventService gameEventService;
 
     /**
      * 使用poi生成报名表模板
@@ -198,6 +190,85 @@ public class IEnrollServiceImpl implements IEnrollService {
         return this.saveEnrollData(enrollList, eventId);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean enroll(EnrollBo enrollBo) {
+        Long eventId = enrollBo.getEventId();
+        Long projectId = enrollBo.getProjectId();
+        String name = enrollBo.getName();
+        String teamName = enrollBo.getTeamName();
+        Integer gender = enrollBo.getGender();
+        Integer age = enrollBo.getAge();
+        String phone = enrollBo.getPhone();
+        String idCard = enrollBo.getIdCard();
+        // 1.查询队伍是否存在 如果存在就更新成员
+        GameTeam team = gameTeamService.queryByName(teamName, eventId);
+        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
+        Long teamId = snowflake.nextId();
+        Long athleteId = snowflake.nextId();
+        String athleteCode = "";
+        if (team == null) {
+            // 1.1 如果队伍不存在就创建队伍并且生成号码段
+            //查询当前赛事号码段最大的
+            GameTeam maxNumberTeam = gameTeamService.queryMaxNumber(eventId);
+            // 生成新的队伍号码段 numberRange
+            // start=maxNumberTeam.getNumberRange.endNumber+1
+            String[] maxNumberRange = maxNumberTeam.getNumberRange().split("-");
+            String startNumber = String.valueOf(Integer.parseInt(maxNumberRange[1]) + 1);
+            // end=maxNumberTeam.getNumberRange.endNumber+300
+            String endNumber = String.valueOf(Integer.parseInt(maxNumberRange[1]) + 300);
+            GameTeamBo gameTeamBo = new GameTeamBo();
+            gameTeamBo.setTeamId(teamId);
+            gameTeamBo.setEventId(eventId);
+            gameTeamBo.setTeamName(teamName);
+            gameTeamBo.setLeader(name);
+            gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(Arrays.asList(athleteId)));
+            gameTeamBo.setAthleteNum(1L);
+            gameTeamBo.setNumberRange(startNumber + "-" + endNumber);
+            gameTeamBo.setCreateDept(-1L);
+            gameTeamBo.setCreateBy(-1L);
+            gameTeamBo.setCreateTime(DateTime.now());
+            gameTeamBo.setUpdateBy(null);
+            gameTeamBo.setUpdateTime(null);
+            athleteCode = startNumber;
+            gameTeamService.insertByBo(gameTeamBo);
+        } else {
+            // 1.2 查询当前队伍中号码段最大的 继续号码
+            teamId = team.getTeamId();
+            String maxNumber = gameAthleteService.queryMaxNumber(teamId);
+            athleteCode = String.valueOf(Integer.parseInt(maxNumber) + 1);
+            // 1.3 更新运动员成员
+            List<Long> ids = JSONUtil.toList(team.getAthleteValue(), Long.class);
+            ids.add(athleteId);
+            team.setAthleteValue(JSONUtil.toJsonStr(ids));
+
+            GameTeamBo bo = new GameTeamBo();
+            BeanUtil.copyProperties(team, bo);
+            gameTeamService.updateByBo(bo);
+        }
+        // 2.加入运动员表
+        GameAthleteBo gameAthleteBo = new GameAthleteBo();
+        gameAthleteBo.setAthleteId(athleteId);
+        gameAthleteBo.setEventId(eventId);
+        gameAthleteBo.setTeamId(teamId);
+        gameAthleteBo.setAthleteCode(athleteCode);
+        gameAthleteBo.setName(name);
+        gameAthleteBo.setGender(String.valueOf(gender));
+        gameAthleteBo.setAge(Long.valueOf(age));
+        gameAthleteBo.setUnit(teamName);
+        gameAthleteBo.setIdCard(idCard);
+        gameAthleteBo.setPhone(phone);
+        gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(Arrays.asList(projectId)));
+        gameAthleteBo.setCreateDept(-1L);
+        gameAthleteBo.setCreateBy(-1L);
+        gameAthleteBo.setCreateTime(DateTime.now());
+        gameAthleteBo.setUpdateBy(null);
+        gameAthleteBo.setUpdateTime(null);
+        return gameAthleteService.insertByBo(gameAthleteBo);
+    }
+
+    // region 辅助方法
+
     private List<EnrollProjectVo> parseData(MultipartFile file) {
         try {
             List<EnrollProjectVo> enrolls = new ArrayList<>();
@@ -495,4 +566,6 @@ public class IEnrollServiceImpl implements IEnrollService {
 
         return startStr + "-" + endStr;
     }
+
+    // endregion 辅助方法
 }