Forráskód Böngészése

feat:导出号码对照表

wenkai 1 hete
szülő
commit
9dcca47435
24 módosított fájl, 568 hozzáadás és 613 törlés
  1. 1 0
      .gitignore
  2. 0 117
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/AppGlobalTextController.java
  3. 2 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameEventController.java
  4. 52 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/NumberController.java
  5. 0 57
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/AppGlobalText.java
  6. 0 52
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/bo/AppGlobalTextBo.java
  7. 0 67
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AppGlobalTextVo.java
  8. 30 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AthleteCodeVo.java
  9. 44 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AthleteNumberTableVO.java
  10. 0 21
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/mapper/AppGlobalTextMapper.java
  11. 0 77
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IAppGlobalTextService.java
  12. 2 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameAthleteService.java
  13. 7 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameEventProjectService.java
  14. 18 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameEventService.java
  15. 2 0
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/IGameTeamService.java
  16. 0 147
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AppGlobalTextServiceImpl.java
  17. 12 4
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameAthleteServiceImpl.java
  18. 36 18
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameEventProjectServiceImpl.java
  19. 296 20
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameEventServiceImpl.java
  20. 10 3
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameTeamServiceImpl.java
  21. 46 18
      ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/IEnrollServiceImpl.java
  22. 0 11
      ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AppGlobalTextMapper.xml
  23. 0 0
      号码对照表.xls
  24. 10 1
      本周改动.md

+ 1 - 0
.gitignore

@@ -46,3 +46,4 @@ nbdist/
 !*/build/*.xml
 
 .flattened-pom.xml
+!*/src/main/resources/*.yml

+ 0 - 117
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/AppGlobalTextController.java

@@ -1,117 +0,0 @@
-package org.dromara.system.controller;
-
-import java.util.List;
-
-import lombok.RequiredArgsConstructor;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.*;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.validation.annotation.Validated;
-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.AppGlobalTextVo;
-import org.dromara.system.domain.bo.AppGlobalTextBo;
-import org.dromara.system.service.IAppGlobalTextService;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-
-/**
- * 移动端富文本
- *
- * @author zlt
- * @date 2025-08-18
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/system/globalText")
-public class AppGlobalTextController extends BaseController {
-
-    private final IAppGlobalTextService appGlobalTextService;
-
-    /**
-     * 查询移动端富文本列表
-     */
-    @SaCheckPermission("system:globalText:list")
-    @GetMapping("/list")
-    public TableDataInfo<AppGlobalTextVo> list(AppGlobalTextBo bo, PageQuery pageQuery) {
-        return appGlobalTextService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 导出移动端富文本列表
-     */
-    @SaCheckPermission("system:globalText:export")
-    @Log(title = "移动端富文本", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(AppGlobalTextBo bo, HttpServletResponse response) {
-        List<AppGlobalTextVo> list = appGlobalTextService.queryList(bo);
-        ExcelUtil.exportExcel(list, "移动端富文本", AppGlobalTextVo.class, response);
-    }
-
-    /**
-     * 获取移动端富文本详细信息
-     *
-     * @param id 主键
-     */
-    @SaCheckPermission("system:globalText:query")
-    @GetMapping("/{id}")
-    public R<AppGlobalTextVo> getInfo(@NotNull(message = "主键不能为空")
-                                     @PathVariable Long id) {
-        return R.ok(appGlobalTextService.queryById(id));
-    }
-
-    /**
-     * 新增移动端富文本
-     */
-    @SaCheckPermission("system:globalText:add")
-    @Log(title = "移动端富文本", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody AppGlobalTextBo bo) {
-        return toAjax(appGlobalTextService.insertByBo(bo));
-    }
-
-    /**
-     * 修改移动端富文本
-     */
-    @SaCheckPermission("system:globalText:edit")
-    @Log(title = "移动端富文本", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody AppGlobalTextBo bo) {
-        return toAjax(appGlobalTextService.updateByBo(bo));
-    }
-
-    /**
-     * 删除移动端富文本
-     *
-     * @param ids 主键串
-     */
-    @SaCheckPermission("system:globalText:remove")
-    @Log(title = "移动端富文本", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "主键不能为空")
-                          @PathVariable Long[] ids) {
-        return toAjax(appGlobalTextService.deleteWithValidByIds(List.of(ids), true));
-    }
-
-    /**
-     * 根据事件id和类型获取富文本
-     *
-     * @param eventId 事件id
-     * @param type    类型
-     */
-    @Log(title = "根据事件id和类型获取富文本", businessType = BusinessType.DELETE)
-    @GetMapping("/getTextByEventAndType")
-    public R<List<AppGlobalTextVo>> getTextByEventAndType(@RequestParam Long eventId, @RequestParam Long type) {
-        return R.ok(appGlobalTextService.getTextByEventAndType(eventId, type));
-    }
-}

+ 2 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/GameEventController.java

@@ -151,4 +151,6 @@ public class GameEventController extends BaseController {
     public R<Long> count(@PathVariable Long type) {
         return R.ok(gameEventService.countGameEvent(type));
     }
+
+
 }

+ 52 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/controller/NumberController.java

@@ -0,0 +1,52 @@
+package org.dromara.system.controller;
+
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.system.domain.constant.GameEventConstant;
+import org.dromara.system.domain.vo.AthleteNumberTableVO;
+import org.dromara.system.service.IGameEventService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/system/number")
+public class NumberController {
+
+    private final IGameEventService gameEventService;
+
+    /**
+     *
+     * @return key:队伍名称 value:队伍运动员
+     */
+    @GetMapping("/generateTable")
+    public List<AthleteNumberTableVO> generateNumberTable() {
+        Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
+        Long eventId = Long.valueOf(cacheObject.toString());
+        return gameEventService.getNumberTable(eventId);
+    }
+
+
+    /**
+     *
+     * @return key:队伍名称 value:队伍运动员
+     */
+    @PostMapping("/export")
+    public void exportNumberTable(HttpServletRequest request, HttpServletResponse response) {
+        Object cacheObject = RedisUtils.getCacheObject(GameEventConstant.DEFAULT_EVENT_ID);
+        Long eventId = Long.valueOf(cacheObject.toString());
+        gameEventService.exportNumberTable(request, response, eventId);
+    }
+}

+ 0 - 57
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/AppGlobalText.java

@@ -1,57 +0,0 @@
-package org.dromara.system.domain;
-
-import org.dromara.common.tenant.core.TenantEntity;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 移动端富文本对象 app_global_text
- *
- * @author zlt
- * @date 2025-08-18
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("app_global_text")
-public class AppGlobalText extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     *
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 赛事id
-     */
-    private Long eventId;
-
-    /**
-     * 标题
-     */
-    private String title;
-
-    /**
-     * 内容
-     */
-    private String content;
-
-    /**
-     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
-     6:赛事分组 7:运动员号码簿 8:项目场地
-     */
-    private Long type;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-
-}

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

@@ -1,52 +0,0 @@
-package org.dromara.system.domain.bo;
-
-import org.dromara.system.domain.AppGlobalText;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 移动端富文本业务对象 app_global_text
- *
- * @author zlt
- * @date 2025-08-18
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = AppGlobalText.class, reverseConvertGenerate = false)
-public class AppGlobalTextBo extends BaseEntity {
-
-    /**
-     *
-     */
-    private Long id;
-
-    /**
-     * 赛事id
-     */
-    private Long eventId;
-
-    /**
-     * 标题
-     */
-    private String title;
-
-    /**
-     * 内容
-     */
-    private String content;
-
-    /**
-     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
-  6:赛事分组 7:运动员号码簿 8:项目场地
-     */
-    private Long type;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-
-}

+ 0 - 67
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AppGlobalTextVo.java

@@ -1,67 +0,0 @@
-package org.dromara.system.domain.vo;
-
-import org.dromara.common.excel.annotation.ExcelDictFormat;
-import org.dromara.system.domain.AppGlobalText;
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 移动端富文本视图对象 app_global_text
- *
- * @author zlt
- * @date 2025-08-18
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = AppGlobalText.class)
-public class AppGlobalTextVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 主键
-     */
-    @ExcelProperty(value = "主键")
-    private Long id;
-
-    /**
-     * 赛事id
-     */
-    @ExcelProperty(value = "赛事id")
-    private Long eventId;
-
-    /**
-     * 标题
-     */
-    @ExcelProperty(value = "标题")
-    private String title;
-
-    /**
-     * 内容
-     */
-    @ExcelProperty(value = "内容")
-    private String content;
-
-    /**
-     * 类型 1:竞赛流程 2:竞赛项目 3:活动议程 4:项目介绍 5:竞赛流程
-  6:赛事分组 7:运动员号码簿 8:项目场地
-     */
-    @ExcelProperty(value = "活动类型")
-    @ExcelDictFormat(dictType = "markdown_location")
-    private Long type;
-
-    /**
-     * 备注
-     */
-    @ExcelProperty(value = "备注")
-    private String remark;
-
-
-}

+ 30 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AthleteCodeVo.java

@@ -0,0 +1,30 @@
+package org.dromara.system.domain.vo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+public class AthleteCodeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    private Long id;
+
+    /**
+     * 运动员编号
+     */
+    private String code;
+    /**
+     * 姓名
+     */
+    @ExcelProperty(value = "姓名")
+    private String name;
+
+}

+ 44 - 0
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/domain/vo/AthleteNumberTableVO.java

@@ -0,0 +1,44 @@
+package org.dromara.system.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.system.domain.Advice;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * 用户反馈建议视图对象 advice
+ *
+ * @author wenkai
+ * @date 2025-08-18
+ */
+@Data
+public class AthleteNumberTableVO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 队伍名称
+     */
+    private String teamName;
+
+    /**
+     * 人数
+     */
+    private Long memberCount;
+
+    /**
+     * 号码段
+     */
+    private String numberRange;
+
+    List<AthleteCodeVo> athleteCodeVos;
+
+}
+

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

@@ -1,21 +0,0 @@
-package org.dromara.system.mapper;
-
-import org.dromara.system.domain.AppGlobalText;
-import org.dromara.system.domain.vo.AppGlobalTextVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-import java.util.List;
-
-/**
- * 移动端富文本Mapper接口
- *
- * @author zlt
- * @date 2025-08-18
- */
-public interface AppGlobalTextMapper extends BaseMapperPlus<AppGlobalText, AppGlobalTextVo> {
-
-    /**
-     * 根据赛事id和类型查询富文本数据
-     */
-    List<AppGlobalTextVo> getTextByEventAndType(Long eventId, Long type);
-}

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

@@ -1,77 +0,0 @@
-package org.dromara.system.service;
-
-import org.dromara.system.domain.vo.AppGlobalTextVo;
-import org.dromara.system.domain.bo.AppGlobalTextBo;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 移动端富文本Service接口
- *
- * @author zlt
- * @date 2025-08-18
- */
-public interface IAppGlobalTextService {
-
-    /**
-     * 查询移动端富文本
-     *
-     * @param id 主键
-     * @return 移动端富文本
-     */
-    AppGlobalTextVo queryById(Long id);
-
-    /**
-     * 分页查询移动端富文本列表
-     *
-     * @param bo        查询条件
-     * @param pageQuery 分页参数
-     * @return 移动端富文本分页列表
-     */
-    TableDataInfo<AppGlobalTextVo> queryPageList(AppGlobalTextBo bo, PageQuery pageQuery);
-
-    /**
-     * 查询符合条件的移动端富文本列表
-     *
-     * @param bo 查询条件
-     * @return 移动端富文本列表
-     */
-    List<AppGlobalTextVo> queryList(AppGlobalTextBo bo);
-
-    /**
-     * 新增移动端富文本
-     *
-     * @param bo 移动端富文本
-     * @return 是否新增成功
-     */
-    Boolean insertByBo(AppGlobalTextBo bo);
-
-    /**
-     * 修改移动端富文本
-     *
-     * @param bo 移动端富文本
-     * @return 是否修改成功
-     */
-    Boolean updateByBo(AppGlobalTextBo bo);
-
-    /**
-     * 校验并批量删除移动端富文本信息
-     *
-     * @param ids     待删除的主键集合
-     * @param isValid 是否进行有效性校验
-     * @return 是否删除成功
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    /**
-     * 获取移动端富文本列表
-     *
-     * @param eventId 赛事id
-     * @param type    类型
-     * @return 移动端富文本列表
-     */
-    List<AppGlobalTextVo> getTextByEventAndType(Long eventId, Long type);
-}

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

@@ -86,4 +86,6 @@ public interface IGameAthleteService {
      * @return
      */
     List<GameAthleteVo> listByIds(Collection<Long> athleteIds);
+
+    Long countByEventId(Long eventId);
 }

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

@@ -87,4 +87,11 @@ public interface IGameEventProjectService {
      * @return
      */
     List<GameEventProjectVo> queryListByEventId(Long eventId);
+
+    /**
+     * 查询当前赛事下项目名称和id的映射关系
+     * @param eventId
+     * @return
+     */
+    Map<String, Long> mapProjectAndProjectId(Long eventId);
 }

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

@@ -1,6 +1,10 @@
 package org.dromara.system.service;
 
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.dromara.common.core.domain.R;
+import org.dromara.system.domain.vo.AthleteCodeVo;
+import org.dromara.system.domain.vo.AthleteNumberTableVO;
 import org.dromara.system.domain.vo.GameEventVo;
 import org.dromara.system.domain.bo.GameEventBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -100,4 +104,18 @@ public interface IGameEventService {
      * @return
      */
     Long countGameEvent(Long type);
+
+    /**
+     * 获取默认赛事的号码对照表
+     * @return
+     */
+    List<AthleteNumberTableVO> getNumberTable(Long eventId);
+
+    /**
+     * 导出号码对照表
+     * @param request
+     * @param response
+     * @param eventId
+     */
+    void exportNumberTable(HttpServletRequest request, HttpServletResponse response, Long eventId);
 }

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

@@ -106,4 +106,6 @@ public interface IGameTeamService {
      * @return 是否更新成功
      */
     Boolean updateTeamAthletes(Long teamId, List<Long> athleteIds);
+
+    Long countByEventId(Long eventId);
 }

+ 0 - 147
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AppGlobalTextServiceImpl.java

@@ -1,147 +0,0 @@
-package org.dromara.system.service.impl;
-
-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.Wrappers;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.dromara.system.domain.bo.AppGlobalTextBo;
-import org.dromara.system.domain.vo.AppGlobalTextVo;
-import org.dromara.system.domain.AppGlobalText;
-import org.dromara.system.mapper.AppGlobalTextMapper;
-import org.dromara.system.service.IAppGlobalTextService;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
-
-/**
- * 移动端富文本Service业务层处理
- *
- * @author zlt
- * @date 2025-08-18
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class AppGlobalTextServiceImpl implements IAppGlobalTextService {
-
-    private final AppGlobalTextMapper baseMapper;
-
-    /**
-     * 查询移动端富文本
-     *
-     * @param id 主键
-     * @return 移动端富文本
-     */
-    @Override
-    public AppGlobalTextVo queryById(Long id){
-        return baseMapper.selectVoById(id);
-    }
-
-    /**
-     * 分页查询移动端富文本列表
-     *
-     * @param bo        查询条件
-     * @param pageQuery 分页参数
-     * @return 移动端富文本分页列表
-     */
-    @Override
-    public TableDataInfo<AppGlobalTextVo> queryPageList(AppGlobalTextBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<AppGlobalText> lqw = buildQueryWrapper(bo);
-        Page<AppGlobalTextVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    /**
-     * 查询符合条件的移动端富文本列表
-     *
-     * @param bo 查询条件
-     * @return 移动端富文本列表
-     */
-    @Override
-    public List<AppGlobalTextVo> queryList(AppGlobalTextBo bo) {
-        LambdaQueryWrapper<AppGlobalText> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<AppGlobalText> buildQueryWrapper(AppGlobalTextBo bo) {
-        Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<AppGlobalText> lqw = Wrappers.lambdaQuery();
-        lqw.orderByAsc(AppGlobalText::getId);
-        lqw.eq(bo.getEventId() != null, AppGlobalText::getEventId, bo.getEventId());
-        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), AppGlobalText::getTitle, bo.getTitle());
-        lqw.eq(StringUtils.isNotBlank(bo.getContent()), AppGlobalText::getContent, bo.getContent());
-        lqw.eq(bo.getType() != null, AppGlobalText::getType, bo.getType());
-        return lqw;
-    }
-
-    /**
-     * 新增移动端富文本
-     *
-     * @param bo 移动端富文本
-     * @return 是否新增成功
-     */
-    @Override
-    public Boolean insertByBo(AppGlobalTextBo bo) {
-        AppGlobalText add = MapstructUtils.convert(bo, AppGlobalText.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    /**
-     * 修改移动端富文本
-     *
-     * @param bo 移动端富文本
-     * @return 是否修改成功
-     */
-    @Override
-    public Boolean updateByBo(AppGlobalTextBo bo) {
-        AppGlobalText update = MapstructUtils.convert(bo, AppGlobalText.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 保存前的数据校验
-     */
-    private void validEntityBeforeSave(AppGlobalText entity){
-        //TODO 做一些数据校验,如唯一约束
-    }
-
-    /**
-     * 校验并批量删除移动端富文本信息
-     *
-     * @param ids     待删除的主键集合
-     * @param isValid 是否进行有效性校验
-     * @return 是否删除成功
-     */
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
-            //TODO 做一些业务上的校验,判断是否需要校验
-        }
-        return baseMapper.deleteByIds(ids) > 0;
-    }
-
-    /**
-     * 根据赛事ID和类型获取富文本内容
-     *
-     * @param eventId 赛事ID
-     * @param type    类型
-     * @return 富文本内容
-     */
-    @Override
-    public List<AppGlobalTextVo> getTextByEventAndType(Long eventId, Long type) {
-        return baseMapper.getTextByEventAndType(eventId, type);
-    }
-}

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

@@ -176,7 +176,7 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
                     .ifPresent(projectValue -> {
 //                        String[] projectIds = projectValue.split(",");
                         List<String> projectIds = JSONUtil.toList(projectValue, String.class);
-                        if(CollUtil.isNotEmpty(projectIds)){
+                        if (CollUtil.isNotEmpty(projectIds)) {
                             List<GameEventProjectVo> projects =
                                 gameEventProjectService.listProjectsByEventIdAndProjectIndex(
                                     vo.getEventId(), projectIds);
@@ -216,7 +216,7 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
             }
         }
         LambdaQueryWrapper<GameAthlete> lqw = buildQueryWrapper(bo);
-        List<GameAthleteVo> athleteList =baseMapper.selectVoList(lqw);
+        List<GameAthleteVo> athleteList = baseMapper.selectVoList(lqw);
         athleteList.forEach(vo -> {
             Optional.ofNullable(vo.getProjectValue())
                 .filter(StringUtils::isNotBlank)
@@ -293,7 +293,7 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
         }
         GameAthlete add = MapstructUtils.convert(bo, GameAthlete.class);
         validEntityBeforeSave(add);
-        if(CollectionUtils.isNotEmpty(bo.getProjectList())){
+        if (CollectionUtils.isNotEmpty(bo.getProjectList())) {
             add.setProjectValue(JSONUtil.toJsonStr(bo.getProjectList()));
         }
         boolean flag = baseMapper.insert(add) > 0;
@@ -320,7 +320,7 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
             }
         }
         GameAthlete update = MapstructUtils.convert(bo, GameAthlete.class);
-        if(CollectionUtils.isNotEmpty(bo.getProjectList())){
+        if (CollectionUtils.isNotEmpty(bo.getProjectList())) {
             update.setProjectValue(JSONUtil.toJsonStr(bo.getProjectList()));
         }
         validEntityBeforeSave(update);
@@ -416,4 +416,12 @@ public class GameAthleteServiceImpl implements IGameAthleteService {
         });
         return list;
     }
+
+    @Override
+    public Long countByEventId(Long eventId) {
+        return baseMapper.selectCount(
+            Wrappers.lambdaQuery(GameAthlete.class)
+                .eq(GameAthlete::getEventId, eventId)
+        );
+    }
 }

+ 36 - 18
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/GameEventProjectServiceImpl.java

@@ -84,22 +84,22 @@ public class GameEventProjectServiceImpl implements IGameEventProjectService {
         // 使用 forEach 直接修改原对象
         result.getRecords()
             .forEach(vo -> {
-            Optional.ofNullable(vo.getEventId())
-                .filter(ObjectUtil::isNotEmpty)
-                .ifPresent(eventId -> {
-                    GameEvent gameEvent = gameEventMapper.selectById(eventId);
-                    if (gameEvent != null) {
-                        vo.setEventName(gameEvent.getEventName());
-                    }
-                });
+                Optional.ofNullable(vo.getEventId())
+                    .filter(ObjectUtil::isNotEmpty)
+                    .ifPresent(eventId -> {
+                        GameEvent gameEvent = gameEventMapper.selectById(eventId);
+                        if (gameEvent != null) {
+                            vo.setEventName(gameEvent.getEventName());
+                        }
+                    });
 
-            Optional.ofNullable(vo.getRefereeGroup())
-                .filter(ObjectUtil::isNotEmpty)
-                .ifPresent(refereeIdStr -> {
-                    List<String> refereeList = JSONUtil.toList(refereeIdStr.toString(), String.class);
-                    vo.setRefereeGroups(refereeList);
-                });
-        });
+                Optional.ofNullable(vo.getRefereeGroup())
+                    .filter(ObjectUtil::isNotEmpty)
+                    .ifPresent(refereeIdStr -> {
+                        List<String> refereeList = JSONUtil.toList(refereeIdStr.toString(), String.class);
+                        vo.setRefereeGroups(refereeList);
+                    });
+            });
 
         return TableDataInfo.build(result);
     }
@@ -149,18 +149,18 @@ public class GameEventProjectServiceImpl implements IGameEventProjectService {
         lqw.eq(bo.getEventId() != null, GameEventProject::getEventId, bo.getEventId());
         // 通过名称模糊查询
         Optional.ofNullable(bo.getEventName())
-            .ifPresent(eventName->{
+            .ifPresent(eventName -> {
                 List<GameEvent> gameEvents = gameEventMapper.selectList(
                     Wrappers.lambdaQuery(GameEvent.class)
                         .like(GameEvent::getEventName, bo.getEventName())
                         .select(GameEvent::getEventId)
                 );
-                if(CollectionUtils.isNotEmpty(gameEvents)){
+                if (CollectionUtils.isNotEmpty(gameEvents)) {
                     List<Long> ids = gameEvents.stream()
                         .map(GameEvent::getEventId)
                         .collect(Collectors.toList());
                     lqw.in(GameEventProject::getEventId, ids);
-                }else{
+                } else {
                     lqw.apply("1=0");
                 }
             });
@@ -316,4 +316,22 @@ public class GameEventProjectServiceImpl implements IGameEventProjectService {
         );
         return projects;
     }
+
+    /**
+     * 查询当前赛事下项目名称和id的映射关系
+     *
+     * @param eventId
+     * @return
+     */
+    @Override
+    public Map<String, Long> mapProjectAndProjectId(Long eventId) {
+        List<GameEventProject> projects = baseMapper.selectList(
+            Wrappers.lambdaQuery(GameEventProject.class)
+                .eq(GameEventProject::getEventId, eventId)
+                .select(GameEventProject::getProjectId, GameEventProject::getProjectName)
+        );
+        return projects.isEmpty() ?
+            Map.of() :
+            projects.stream().collect(Collectors.toMap(GameEventProject::getProjectName, GameEventProject::getProjectId));
+    }
 }

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

@@ -2,6 +2,14 @@ package org.dromara.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+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.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.json.utils.JsonUtils;
@@ -13,7 +21,16 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.system.domain.bo.GameAthleteBo;
+import org.dromara.system.domain.bo.GameTeamBo;
 import org.dromara.system.domain.constant.GameEventConstant;
+import org.dromara.system.domain.vo.AthleteCodeVo;
+import org.dromara.system.domain.vo.AthleteNumberTableVO;
+import org.dromara.system.domain.vo.GameAthleteVo;
+import org.dromara.system.domain.vo.GameTeamVo;
+import org.dromara.system.service.IGameAthleteService;
+import org.dromara.system.service.IGameTeamService;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.dromara.system.domain.bo.GameEventBo;
 import org.dromara.system.domain.vo.GameEventVo;
@@ -21,10 +38,14 @@ import org.dromara.system.domain.GameEvent;
 import org.dromara.system.mapper.GameEventMapper;
 import org.dromara.system.service.IGameEventService;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
 /**
@@ -34,11 +55,16 @@ import java.util.stream.Collectors;
  * @date 2025-07-30
  */
 @Slf4j
-@RequiredArgsConstructor
 @Service
 public class GameEventServiceImpl implements IGameEventService {
 
-    private final GameEventMapper baseMapper;
+    @Resource
+    private GameEventMapper baseMapper;
+    @Resource
+    private IGameTeamService gameTeamService;
+    @Lazy
+    @Resource
+    private IGameAthleteService gameAthleteService;
 
     /**
      * 查询赛事基本信息
@@ -191,12 +217,8 @@ public class GameEventServiceImpl implements IGameEventService {
      */
     @Override
     public Map<String, Long> getEventIdNameMap() {
-        List<GameEvent> idNameList = this.baseMapper.selectList(
-            new LambdaQueryWrapper<GameEvent>()
-                .select(GameEvent::getEventId, GameEvent::getEventName)
-        );
-        Map<String, Long> idNameMap = idNameList.stream()
-            .collect(Collectors.toMap(GameEvent::getEventName, GameEvent::getEventId));
+        List<GameEvent> idNameList = this.baseMapper.selectList(new LambdaQueryWrapper<GameEvent>().select(GameEvent::getEventId, GameEvent::getEventName));
+        Map<String, Long> idNameMap = idNameList.stream().collect(Collectors.toMap(GameEvent::getEventName, GameEvent::getEventId));
         return idNameMap;
     }
 
@@ -253,8 +275,7 @@ public class GameEventServiceImpl implements IGameEventService {
     public int updateEventDefault(GameEventBo bo) {
         GameEvent event = MapstructUtils.convert(bo, GameEvent.class);
         // 先将所有赛事设置为非默认
-        int row = baseMapper.update(null, new LambdaUpdateWrapper<GameEvent>()
-            .set(GameEvent::getIsDefault, "1"));
+        int row = baseMapper.update(null, new LambdaUpdateWrapper<GameEvent>().set(GameEvent::getIsDefault, "1"));
         // 再将指定赛事设置为默认
         row += baseMapper.updateById(event);
         if (row > 0) {
@@ -274,12 +295,267 @@ public class GameEventServiceImpl implements IGameEventService {
      */
     @Override
     public Long countGameEvent(Long type) {
-        return this.baseMapper.selectCount(
-            Wrappers.lambdaQuery(GameEvent.class)
-                .apply(type == 0, "1=1")
-                .apply(type == 1, "start_time > now()")
-                .apply(type == 2, "start_time <= now() and end_time >= now()")
-                .apply(type == 3, "end_time < now()")
-        );
+        return this.baseMapper.selectCount(Wrappers.lambdaQuery(GameEvent.class).apply(type == 0, "1=1").apply(type == 1, "start_time > now()").apply(type == 2, "start_time <= now() and end_time >= now()").apply(type == 3, "end_time < now()"));
+    }
+
+    /**
+     * 获取默认赛事的号码对照表
+     *
+     * @param eventId
+     * @return
+     */
+    @Override
+    public List<AthleteNumberTableVO> getNumberTable(Long eventId) {
+        //1.查询当前赛事下的所有队伍
+        GameTeamBo bo = new GameTeamBo();
+        bo.setEventId(eventId);
+        List<GameTeamVo> gameTeam = gameTeamService.queryList(bo);
+        //2.查询当前赛事下所有运动员
+        GameAthleteBo gameAthleteBo = new GameAthleteBo();
+        gameAthleteBo.setEventId(eventId);
+        Map<Long, GameAthleteVo> athleteVoMap = gameAthleteService.queryList(gameAthleteBo).stream().collect(Collectors.toMap(GameAthleteVo::getAthleteId, v -> v));
+        //3.组装map
+        List<AthleteNumberTableVO> numberTable = new ArrayList<>();
+        for (GameTeamVo vo : gameTeam) {
+            List<AthleteCodeVo> athleteCodeVos = new ArrayList<>();
+            AtomicLong memberCount = new AtomicLong(0);
+            AthleteNumberTableVO athleteNumberTableVO = new AthleteNumberTableVO();
+            vo.getAthleteList().forEach(athleteId -> {
+                GameAthleteVo athleteVo = athleteVoMap.get(Long.valueOf(athleteId));
+                if (athleteVo != null) {
+                    AthleteCodeVo athleteCodeVo = new AthleteCodeVo();
+                    athleteCodeVo.setId(memberCount.incrementAndGet());
+                    athleteCodeVo.setCode(athleteVo.getAthleteCode());
+                    athleteCodeVo.setName(athleteVo.getName());
+                    athleteCodeVos.add(athleteCodeVo);
+                }
+            });
+            athleteNumberTableVO.setNumberRange(vo.getNumberRange());
+            athleteNumberTableVO.setTeamName(vo.getTeamName());
+            athleteNumberTableVO.setMemberCount(memberCount.get());
+            athleteNumberTableVO.setAthleteCodeVos(athleteCodeVos);
+            numberTable.add(athleteNumberTableVO);
+        }
+        return numberTable;
+    }
+
+
+    /**
+     * 使用poi生成号码对照表
+     *
+     * @param response
+     * @param eventId
+     */
+    /**
+     * 使用poi生成号码对照表
+     *
+     * @param request
+     * @param response
+     * @param eventId
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void exportNumberTable(HttpServletRequest request, HttpServletResponse response, Long eventId) {
+
+        // 获取当前赛事的队伍信息
+        List<AthleteNumberTableVO> numberTable = this.getNumberTable(eventId);
+        if (CollectionUtils.isEmpty(numberTable)) {
+            throw new ServiceException("该赛事无队伍数据");
+        }
+
+        // 1. 创建Excel表格
+        Workbook wb = new XSSFWorkbook();
+
+        // 1.2 创建公共样式:边框 + 居中 + 加粗
+        CellStyle style = wb.createCellStyle();
+        style.setBorderTop(BorderStyle.THIN);
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setBorderRight(BorderStyle.THIN);
+        style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+        style.setRightBorderColor(IndexedColors.BLACK.getIndex());
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        // 字体加粗
+        Font font = wb.createFont();
+        font.setBold(true);
+        style.setFont(font);
+
+        // 创建带浅灰色背景的样式(用于序号行)
+        CellStyle backgroundFillStyle = wb.createCellStyle();
+        backgroundFillStyle.cloneStyleFrom(style);
+        backgroundFillStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+        backgroundFillStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+
+        // 定义1-8列的样式(当前统一使用style,未来可差异化)
+        CellStyle[] columnStyles = new CellStyle[8];
+        for (int i = 0; i < 8; i++) {
+            columnStyles[i] = style;
+        }
+
+        try {
+            for (AthleteNumberTableVO teamNumberTable : numberTable) {
+                if(teamNumberTable.getMemberCount()==0){
+                    continue;
+                }
+                // 2. 遍历队伍信息,为每个队伍创建一个工作簿
+                Sheet sheet = wb.createSheet(teamNumberTable.getTeamName());
+                // 3. 按照规定的格式渲染
+                // 3.1 创建表头(号码对照表) 第一行 合并8个单元格 即0行7列
+                Row headerTitleRow = sheet.createRow(0);
+                Cell headerTitleCell = headerTitleRow.createCell(0);
+                headerTitleCell.setCellValue("号码对照表");
+                CellRangeAddress headerTitleRegion = new CellRangeAddress(0, 0, 0, 7);
+                sheet.addMergedRegion(headerTitleRegion);
+                // 应用样式到合并区域的所有单元格
+                for (int i = headerTitleRegion.getFirstColumn(); i <= headerTitleRegion.getLastColumn(); i++) {
+                    Cell cell = headerTitleRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                    cell.setCellStyle(backgroundFillStyle);
+                }
+
+                // 3.2 创建表头(队伍名称、人数、号码段) 第二行,按照指定格式:AB列合并、C列空白、DE列合并、F列空白、GH列合并
+                Row teamInfoRow = sheet.createRow(1);
+
+                // 设置队伍名称,并合并AB列(0-1列)
+                Cell teamNameInfoCell = teamInfoRow.createCell(0);
+                teamNameInfoCell.setCellValue(teamNumberTable.getTeamName());
+                CellRangeAddress teamNameInfoRegion = new CellRangeAddress(1, 1, 0, 1); // 合并AB列
+                sheet.addMergedRegion(teamNameInfoRegion);
+                teamNameInfoCell.setCellStyle(style); // 应用样式
+
+                // C列保持空白,但需创建单元格并应用样式
+                Cell cBlankCell = teamInfoRow.createCell(2);
+                cBlankCell.setCellStyle(style); // 应用样式
+
+                // 设置人数,并合并DE列(3-4列)
+                Cell teamMemberInfoCell = teamInfoRow.createCell(3);
+                teamMemberInfoCell.setCellValue(teamNumberTable.getMemberCount() + "人");
+                CellRangeAddress teamMemberInfoRegion = new CellRangeAddress(1, 1, 3, 4); // 合并DE列
+                sheet.addMergedRegion(teamMemberInfoRegion);
+                teamMemberInfoCell.setCellStyle(style); // 应用样式
+
+                // F列保持空白,但需创建单元格并应用样式
+                Cell fBlankCell = teamInfoRow.createCell(5);
+                fBlankCell.setCellStyle(style); // 应用样式
+
+                // 设置号码段,并合并GH列(6-7列)
+                Cell teamNumberInfoCell = teamInfoRow.createCell(6);
+                teamNumberInfoCell.setCellValue(teamNumberTable.getNumberRange());
+                CellRangeAddress teamNumberInfoRegion = new CellRangeAddress(1, 1, 6, 7); // 合并GH列
+                sheet.addMergedRegion(teamNumberInfoRegion);
+                Cell teamNumberInfoCell1 = teamInfoRow.createCell(7);
+                teamNumberInfoCell.setCellStyle(style); // 应用样式
+                teamNumberInfoCell1.setCellStyle(style); // 应用样式
+
+                // 确保所有列都应用了样式
+                for (int i = 0; i <= 7; i++) {
+                    Cell cell = teamInfoRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                    if (cell != null && cell.getCellStyle() == null) { // 如果当前单元格没有样式,则应用默认样式
+                        cell.setCellStyle(style);
+                    }
+                }
+
+                // 3.3 渲染运动员数据(序号、号码、姓名),每8人为一组,每组3行
+                AtomicLong cellCount = new AtomicLong(0);
+                List<AthleteCodeVo> athletes = teamNumberTable.getAthleteCodeVos();
+
+                for (AthleteCodeVo athlete : athletes) {
+                    int groupIndex = Math.toIntExact(cellCount.get() / 8); // 第几组
+                    int colIndex = Math.toIntExact(cellCount.get() % 8);   // 第几列 (0-7)
+
+                    int idRowIdx = groupIndex * 3 + 2;     // 序号行索引
+                    int codeRowIdx = idRowIdx + 1;         // 号码行索引
+                    int nameRowIdx = idRowIdx + 2;         // 姓名行索引
+
+                    // 获取或创建行
+                    Row idRow = sheet.getRow(idRowIdx);
+                    if (idRow == null) idRow = sheet.createRow(idRowIdx);
+
+                    Row codeRow = sheet.getRow(codeRowIdx);
+                    if (codeRow == null) codeRow = sheet.createRow(codeRowIdx);
+
+                    Row nameRow = sheet.getRow(nameRowIdx);
+                    if (nameRow == null) nameRow = sheet.createRow(nameRowIdx);
+
+                    // 创建并设置序号单元格(带灰色背景)
+                    Cell idCell = idRow.createCell(colIndex);
+                    idCell.setCellValue(athlete.getId());
+                    idCell.setCellStyle(backgroundFillStyle);
+
+                    // 创建并设置号码单元格
+                    Cell codeCell = codeRow.createCell(colIndex);
+                    codeCell.setCellValue(athlete.getCode());
+                    codeCell.setCellStyle(columnStyles[colIndex]);
+
+                    // 创建并设置姓名单元格
+                    Cell nameCell = nameRow.createCell(colIndex);
+                    nameCell.setCellValue(athlete.getName());
+                    nameCell.setCellStyle(columnStyles[colIndex]);
+
+                    cellCount.incrementAndGet();
+                }
+
+                // 补全最后一组的空列(确保1-8列都有样式)
+                if (!athletes.isEmpty()) {
+                    int lastGroupIndex = Math.toIntExact((cellCount.get() - 1) / 8);
+                    int lastFilledCol = Math.toIntExact((cellCount.get() - 1) % 8);
+
+                    if (lastFilledCol < 7) {
+                        int idRowIdx = lastGroupIndex * 3 + 2;
+                        int codeRowIdx = idRowIdx + 1;
+                        int nameRowIdx = idRowIdx + 2;
+
+                        Row idRow = sheet.getRow(idRowIdx);
+                        Row codeRow = sheet.getRow(codeRowIdx);
+                        Row nameRow = sheet.getRow(nameRowIdx);
+
+                        for (int col = lastFilledCol + 1; col < 8; col++) {
+                            // 补序号(空但有背景)
+                            Cell idCell = idRow.createCell(col);
+                            idCell.setCellStyle(backgroundFillStyle);
+
+                            // 补号码(空)
+                            Cell codeCell = codeRow.createCell(col);
+                            codeCell.setCellStyle(columnStyles[col]);
+
+                            // 补姓名(空)
+                            Cell nameCell = nameRow.createCell(col);
+                            nameCell.setCellStyle(columnStyles[col]);
+                        }
+                    }
+                }
+
+                // 自动调整列宽
+                for (int i = 0; i < 8; i++) {
+                    sheet.setColumnWidth(i,14*256);
+                }
+            }
+
+            // 4. 渲染完所有队伍信息后返回Excel文件
+            response.reset();
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("UTF-8");
+            String fileName = "号码对照表.xlsx";
+            response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
+            String origin = request.getHeader("Origin");
+            if (origin != null) {
+                response.addHeader("Access-Control-Allow-Origin", origin);
+            }
+
+            // 写入输出流
+            wb.write(response.getOutputStream());
+
+        } catch (IOException e) {
+            log.error("导出号码对照表异常:", e);
+            throw new ServiceException("导出失败:" + e.getMessage());
+        } finally {
+            try {
+                wb.close();
+            } catch (IOException e) {
+                log.error("关闭Workbook失败:", e);
+            }
+        }
     }
 }

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

@@ -147,7 +147,6 @@ public class GameTeamServiceImpl implements IGameTeamService {
             }
         }
         LambdaQueryWrapper<GameTeam> lqw = buildQueryWrapper(bo);
-        lqw.like(GameTeam::getTeamName, bo.getTeamName());
         List<GameTeamVo> list = baseMapper.selectVoList(lqw);
         list.forEach(vo -> {
             if (vo.getAthleteValue() != null) {
@@ -318,11 +317,11 @@ public class GameTeamServiceImpl implements IGameTeamService {
         if (team == null) {
             throw new RuntimeException("队伍不存在");
         }
-        
+
         // 将运动员ID列表转换为JSON字符串
         String athleteValue = JSONUtil.toJsonStr(athleteIds);
         team.setAthleteValue(athleteValue);
-        
+
         // 更新队伍信息
         return baseMapper.updateById(team) > 0;
     }
@@ -343,4 +342,12 @@ public class GameTeamServiceImpl implements IGameTeamService {
             .collect(Collectors.toMap(GameTeamVo::getTeamId, GameTeamVo::getTeamName));
         return map;
     }
+
+    @Override
+    public Long countByEventId(Long eventId) {
+        return baseMapper.selectCount(
+            Wrappers.lambdaQuery(GameTeam.class)
+                .eq(GameTeam::getEventId, eventId)
+        );
+    }
 }

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

@@ -1,5 +1,8 @@
 package org.dromara.system.service.impl;
 
+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;
@@ -11,8 +14,11 @@ 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.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;
@@ -51,6 +57,7 @@ public class IEnrollServiceImpl implements IEnrollService {
      * @param eventId
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void downloadTemplateForPoi(HttpServletRequest request, HttpServletResponse response, Long eventId) {
         //1.加载Excel模板文件
         String template = "template/enroll_template.xlsx";
@@ -176,6 +183,15 @@ public class IEnrollServiceImpl implements IEnrollService {
      */
     @Override
     public Boolean importDataForPoi(MultipartFile file, Long eventId) {
+        //查询赛事下是否已经有报名信息,如果有就禁止导入
+        Long count = gameAthleteService.countByEventId(eventId);
+        if (count > 0) {
+            throw new ServiceException("该赛事下已经有报名信息,禁止导入");
+        }
+        count = gameTeamService.countByEventId(eventId);
+        if (count > 0) {
+            throw new ServiceException("该赛事下已经有报名信息,禁止导入");
+        }
         //1.解析报名信息
         List<EnrollProjectVo> enrollList = parseData(file);
         //2.保存报名信息
@@ -375,11 +391,14 @@ public class IEnrollServiceImpl implements IEnrollService {
         // 1. 根据队伍分类成Map
         Map<String, List<EnrollProjectVo>> groupedByTeam = dataList.stream()
             .collect(Collectors.groupingBy(EnrollProjectVo::getTeamName));
-
+        // 查询当前赛事下的项目 名称和id映射关系
+        Map<String, Long> projectList = gameEventProjectService.mapProjectAndProjectId(eventId);
         // 1.2 根据队伍生成号码段
         Map<String, String> numberRanges = new HashMap<>();
         Map<String, AtomicInteger> currentNumbers = new HashMap<>(); // 记录每个队伍当前分配到的号码
         AtomicInteger teamIndex = new AtomicInteger(1);
+        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
+
         for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
             String teamName = entry.getKey();
             String range = generateNumberRange(dataList.size(), teamIndex.getAndIncrement());
@@ -389,37 +408,23 @@ public class IEnrollServiceImpl implements IEnrollService {
             int startNum = Integer.parseInt(range.split("-")[0]);
             currentNumbers.put(teamName, new AtomicInteger(startNum));
         }
-
         // 2. 保存参赛队伍 & 队员
         for (Map.Entry<String, List<EnrollProjectVo>> entry : groupedByTeam.entrySet()) {
             String teamName = entry.getKey();
             List<EnrollProjectVo> athletes = entry.getValue();
-            //todo 判断是否存在该队伍 存在就更新 人数为原本+1 号码段无需重新分配
             GameTeamBo gameTeamBo = new GameTeamBo();
-            gameTeamBo.setEventId(eventId);
-            gameTeamBo.setTeamName(teamName);
-            // gameTeamBo.setTeamCode("");
-            gameTeamBo.setLeader(athletes.get(0).getLeader());
-            gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(athletes.stream().map(EnrollProjectVo::getName).collect(Collectors.toList())));
-            gameTeamBo.setAthleteNum(Long.valueOf(athletes.size()));
-            gameTeamBo.setNumberRange(numberRanges.get(teamName));
-            gameTeamBo.setStatus("0");
-            gameTeamService.insertByBo(gameTeamBo);
-
+            gameTeamBo.setTeamId(snowflake.nextId());
             Long teamId = gameTeamBo.getTeamId();
-
             // 获取该队伍的当前编号计数器
             AtomicInteger currentNumber = currentNumbers.get(teamName);
             int width = (dataList.size() > 100) ? 5 : 4; // 决定格式化宽度
-
+            List<Long> athletesId = new ArrayList<>();
             // 3. 保存参赛队员
             for (EnrollProjectVo enrollInfo : athletes) {
                 GameAthleteBo gameAthleteBo = new GameAthleteBo();
                 gameAthleteBo.setEventId(eventId);
                 gameAthleteBo.setTeamId(teamId);
                 gameAthleteBo.setTeamName(teamName);
-                //todo 如果存在队伍 即续分配
-
                 // 分配编号:从当前计数器获取并递增
                 int assignedNumber = currentNumber.getAndIncrement();
                 String formattedCode = String.format("%0" + width + "d", assignedNumber);
@@ -430,11 +435,34 @@ public class IEnrollServiceImpl implements IEnrollService {
                 gameAthleteBo.setAge(Long.valueOf(enrollInfo.getAge()));
                 gameAthleteBo.setPhone(enrollInfo.getPhone());
                 gameAthleteBo.setUnit(teamName);
-                gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(enrollInfo.getProjectSelections()));
+                Map<String, Boolean> selectProjects = enrollInfo.getProjectSelections();
+                //查询出对应的赛事id
+                List<Long> selectionProjectIds = new ArrayList<>();
+                for (Map.Entry<String, Boolean> selectProject : selectProjects.entrySet()) {
+                    Long projectId = projectList.get(selectProject.getKey());
+                    if (ObjectUtils.isNotEmpty(projectId)) {
+                        selectionProjectIds.add(projectId);
+                    }
+                }
+                gameAthleteBo.setProjectValue(JSONUtil.toJsonStr(selectionProjectIds));
+
                 gameAthleteBo.setStatus("0");
 
                 gameAthleteService.insertByBo(gameAthleteBo);
+                athletesId.add(gameAthleteBo.getAthleteId());
             }
+
+            gameTeamBo.setEventId(eventId);
+            gameTeamBo.setTeamName(teamName);
+            // gameTeamBo.setTeamCode("");
+            gameTeamBo.setLeader(athletes.get(0).getLeader());
+            gameTeamBo.setAthleteValue(JSONUtil.toJsonStr(athletesId));
+            gameTeamBo.setAthleteNum(Long.valueOf(athletes.size()));
+            gameTeamBo.setNumberRange(numberRanges.get(teamName));
+            gameTeamBo.setStatus("0");
+            gameTeamService.insertByBo(gameTeamBo);
+
+
         }
         return true;
     }

+ 0 - 11
ruoyi-modules/ruoyi-game-event/src/main/resources/mapper/system/AppGlobalTextMapper.xml

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.system.mapper.AppGlobalTextMapper">
-
-    <select id="getTextByEventAndType" resultType="AppGlobalText">
-        SELECT * FROM app_global_text
-        WHERE event_id = #{eventId} AND type = #{type}
-    </select>
-</mapper>

+ 0 - 0
号码对照表.xls


+ 10 - 1
本周改动.md

@@ -20,7 +20,16 @@
 <li>修改赛事列表操作列位置</li>
 <li>修改菜单栏图标显示</li>
 <li>还原赛事-备份、恢复</li>
-<li>活动预热与默认赛事关联</li>
 <li>补充数据测试功能</li>
 <li>修改各模块列表项映射格式,方便后期维护</li>
 <li>修复成绩模块显示逻辑bug</li>
+
+
+
+<h2>8.20</h2>
+
+<li>完善运动员模块与队伍的关联</li>
+<li>优化赛事界面布局和操作流程</li>
+<li>添加组别详细信息,如人数、组数、道数等</li>
+<li>实现分组自动计算和时间验证功能</li>
+