Browse Source

refactor(game-event): 优化移动端富文本服务实现

- 添加了 hutool 日期工具类导入并统一使用 DateUtil
- 移除废弃的 BO 类导入并新增必要的 VO 和 Mapper 依赖
- 注入运动员竞赛分组相关服务和映射器实例
- 修复代码注释格式统一添加空格
- 优化查询逻辑将异步查询改为同步以避免 SaToken 线程上下文丢失
- 重构项目分组查询改为批量查询提升性能
- 使用 Stream API 优化集合排序和分组操作
- 重构运动员信息展示逻辑从数据库查询改为内存映射
- 优化 Word 文档导出的文件名编码和响应头设置
- 移除不必要的异常消息传递简化错误处理
zhou 3 ngày trước cách đây
mục cha
commit
aadd58898a

+ 138 - 106
ruoyi-modules/ruoyi-game-event/src/main/java/org/dromara/system/service/impl/AppEventMdServiceImpl.java

@@ -1,5 +1,6 @@
 package org.dromara.system.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.deepoove.poi.XWPFTemplate;
 import com.deepoove.poi.data.RowRenderData;
@@ -18,13 +19,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.dromara.system.domain.bo.GameEventGroupBo;
-import org.dromara.system.domain.bo.GameEventProjectBo;
 import org.dromara.system.domain.vo.*;
 import org.dromara.system.service.IGameEventGroupService;
 import org.dromara.system.service.IGameEventProjectService;
 import org.dromara.system.service.IGameEventService;
 import org.dromara.system.service.ISysDictTypeService;
+import org.dromara.system.service.IGameAthleteCompetitionGroupService;
+import org.dromara.system.domain.vo.GameAthleteCompetitionGroupVo;
+
+import org.dromara.system.mapper.GameEventProjectMapper;
+import org.dromara.system.mapper.GameEventGroupMapper;
+import org.dromara.system.mapper.GameAthleteCompetitionGroupMapper;
+import org.dromara.system.domain.GameEventProject;
+import org.dromara.system.domain.GameEventGroup;
+import org.dromara.system.domain.GameAthleteCompetitionGroup;
+
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
 import org.springframework.stereotype.Service;
 import org.dromara.system.domain.bo.AppEventMdBo;
@@ -54,6 +63,10 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
     private final IGameEventProjectService gameEventProjectService;
     private final IGameEventGroupService gameEventGroupService;
     private final ISysDictTypeService dictTypeService;
+    private final IGameAthleteCompetitionGroupService gameAthleteCompetitionGroupService;
+    private final GameEventProjectMapper gameEventProjectMapper;
+    private final GameEventGroupMapper gameEventGroupMapper;
+    private final GameAthleteCompetitionGroupMapper gameAthleteCompetitionGroupMapper;
 
     /**
      * 查询移动端富文本
@@ -137,7 +150,7 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
      * 保存前的数据校验
      */
     private void validEntityBeforeSave(AppEventMd entity) {
-        //TODO 做一些数据校验,如唯一约束
+        // TODO 做一些数据校验,如唯一约束
     }
 
     /**
@@ -150,7 +163,7 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
         if (isValid) {
-            //TODO 做一些业务上的校验,判断是否需要校验
+            // TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
@@ -165,10 +178,9 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
     @Override
     public AppEventMdVo queryByEventIdAndType(Long eventId, Integer type) {
         return baseMapper.selectVoOne(
-            Wrappers.lambdaQuery(AppEventMd.class)
-                .eq(AppEventMd::getEventId, eventId)
-                .eq(AppEventMd::getType, type)
-        );
+                Wrappers.lambdaQuery(AppEventMd.class)
+                        .eq(AppEventMd::getEventId, eventId)
+                        .eq(AppEventMd::getType, type));
     }
 
     /**
@@ -185,7 +197,7 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
         if (StrUtil.isBlank(bo.getContent())) {
             throw new ServiceException("内容不能为空");
         }
-        //查询是否存在
+        // 查询是否存在
         AppEventMdVo vo = this.queryByEventIdAndType(bo.getEventId(), bo.getType());
         if (Optional.ofNullable(vo).isPresent()) {
             bo.setId(vo.getId());
@@ -204,7 +216,7 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
      */
     @Override
     public int deleteByEventIdAndType(Long eventId, Integer type) {
-        //并不是删除  而是情况所有内容
+        // 并不是删除 而是情况所有内容
         AppEventMd appEventMd = new AppEventMd();
         appEventMd.setEventId(eventId);
         appEventMd.setTitle("");
@@ -212,21 +224,21 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
         appEventMd.setType(type);
         appEventMd.setRemark("");
         return baseMapper.update(appEventMd, Wrappers.lambdaQuery(AppEventMd.class)
-            .eq(AppEventMd::getEventId, eventId)
-            .eq(AppEventMd::getType, type));
+                .eq(AppEventMd::getEventId, eventId)
+                .eq(AppEventMd::getType, type));
     }
 
     /**
      * 导出秩序册 Word 文档
      *
      * @param response 响应
-     * @param eventId 赛事ID
+     * @param eventId  赛事ID
      */
     @Override
     public void exportEventWord(HttpServletResponse response, Long eventId) {
         try {
             // 1. 基本信息
-            org.dromara.system.domain.vo.GameEventVo eventVo = gameEventService.queryById(eventId);
+            GameEventVo eventVo = gameEventService.queryById(eventId);
             if (eventVo == null) {
                 throw new ServiceException("赛事不存在");
             }
@@ -234,24 +246,46 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
             Map<String, Object> data = new HashMap<>();
             data.put("eventName", eventVo.getEventName() != null ? eventVo.getEventName() : "");
 
-            // 2. 日程预览数据
-            GameEventProjectBo projectBo = new GameEventProjectBo();
-            projectBo.setEventId(eventId);
-            List<GameEventProjectVo> allProjects = gameEventProjectService.queryList(projectBo);
-            // 过滤掉没有开始时间的项目
-            List<GameEventProjectVo> scheduleProjects = new ArrayList<>();
-            for (GameEventProjectVo p : allProjects) {
-                if (p.getStartTime() != null) {
-                    scheduleProjects.add(p);
-                }
+            // 提前获取各项数据(取消异步,避免SaToken线程上下文丢失)
+            // 1. 获取所有项目(按需查询)
+            List<GameEventProject> projectList = gameEventProjectMapper.selectList(Wrappers.<GameEventProject>lambdaQuery()
+                    .select(GameEventProject::getProjectId, GameEventProject::getProjectName,
+                            GameEventProject::getProjectType, GameEventProject::getStartTime,
+                            GameEventProject::getEndTime, GameEventProject::getLocation,
+                            GameEventProject::getGroupNum, GameEventProject::getParticipateNum,
+                            GameEventProject::getRoundType)
+                    .eq(GameEventProject::getEventId, eventId));
+            List<GameEventProjectVo> allProjects = MapstructUtils.convert(projectList, GameEventProjectVo.class);
+            if (allProjects == null) {
+                allProjects = new ArrayList<>();
             }
-            // 排序
-            scheduleProjects.sort((a, b) -> {
-                if (a.getStartTime() == null) return 1;
-                if (b.getStartTime() == null) return -1;
-                return a.getStartTime().compareTo(b.getStartTime());
-            });
-            // 获取项目类型字典
+
+            // 2. 获取所有分组(按需查询)
+            List<GameEventGroup> eventGroupList = gameEventGroupMapper.selectList(Wrappers.<GameEventGroup>lambdaQuery()
+                    .select(GameEventGroup::getGroupId, GameEventGroup::getProjectId,
+                            GameEventGroup::getGroupName, GameEventGroup::getIncludeGroupNum,
+                            GameEventGroup::getTrackNum)
+                    .eq(GameEventGroup::getEventId, eventId));
+            List<GameEventGroupVo> allGroups = MapstructUtils.convert(eventGroupList, GameEventGroupVo.class);
+            Map<Long, List<GameEventGroupVo>> groupsByProjectId = allGroups == null ? new HashMap<>()
+                    : allGroups.stream().collect(Collectors.groupingBy(GameEventGroupVo::getProjectId));
+
+            // 3. 获取所有参赛排道信息(按需查询)
+            List<GameAthleteCompetitionGroup> compGroupList = gameAthleteCompetitionGroupMapper
+                    .selectList(Wrappers.<GameAthleteCompetitionGroup>lambdaQuery()
+                            .select(GameAthleteCompetitionGroup::getGroupId,
+                                    GameAthleteCompetitionGroup::getGroupIndex,
+                                    GameAthleteCompetitionGroup::getTrackIndex,
+                                    GameAthleteCompetitionGroup::getAthleteCode,
+                                    GameAthleteCompetitionGroup::getAthleteName,
+                                    GameAthleteCompetitionGroup::getTeamName)
+                            .eq(GameAthleteCompetitionGroup::getEventId, eventId));
+            List<GameAthleteCompetitionGroupVo> allCompGroups = MapstructUtils.convert(compGroupList, GameAthleteCompetitionGroupVo.class);
+            Map<Long, List<GameAthleteCompetitionGroupVo>> compGroupsByGroupId = allCompGroups == null ? new HashMap<>()
+                    : allCompGroups.stream().filter(c -> c.getGroupId() != null)
+                            .collect(Collectors.groupingBy(GameAthleteCompetitionGroupVo::getGroupId));
+
+            // 4. 获取项目类型字典
             List<SysDictDataVo> projectTypes = dictTypeService.selectDictDataByType("game_project_type");
             Map<String, String> projectTypeMap = new HashMap<>();
             if (projectTypes != null) {
@@ -260,36 +294,47 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
                 }
             }
 
-            // 表头
+            // 5. 获取号码对照表
+            List<AthleteNumberTableVO> numberTableList = gameEventService.getNumberTable(eventId);
+
+            // 2. 日程预览数据
+            List<GameEventProjectVo> scheduleProjects = new ArrayList<>();
+            for (GameEventProjectVo p : allProjects) {
+                if (p.getStartTime() != null) {
+                    scheduleProjects.add(p);
+                }
+            }
+            scheduleProjects.sort(Comparator.comparing(GameEventProjectVo::getStartTime));
+
             RowRenderData scheduleHeader = Rows.of("日期", "时间", "项目名称", "项目类型", "比赛场地", "分组数", "每组人数").create();
             TableRenderData scheduleTable = Tables.create(scheduleHeader);
             for (GameEventProjectVo p : scheduleProjects) {
-                String date = p.getStartTime() != null ? cn.hutool.core.date.DateUtil.format(p.getStartTime(), "yyyy-MM-dd") : "";
-                String time = p.getStartTime() != null ? cn.hutool.core.date.DateUtil.format(p.getStartTime(), "HH:mm") : "";
-                if(p.getEndTime() != null) {
-                    time += "-" + cn.hutool.core.date.DateUtil.format(p.getEndTime(), "HH:mm");
+                String date = p.getStartTime() != null ? DateUtil.format(p.getStartTime(), "yyyy-MM-dd") : "";
+                String time = p.getStartTime() != null ? DateUtil.format(p.getStartTime(), "HH:mm") : "";
+                if (p.getEndTime() != null) {
+                    time += "-" + DateUtil.format(p.getEndTime(), "HH:mm");
                 }
                 scheduleTable.addRow(Rows.of(
-                    date,
-                    time,
-                    p.getProjectName() != null ? p.getProjectName() : "",
-                    projectTypeMap.getOrDefault(p.getProjectType(), p.getProjectType() != null ? p.getProjectType() : ""),
-                    p.getLocation() != null ? p.getLocation() : "",
-                    String.valueOf(p.getGroupNum() != null ? p.getGroupNum() : 0),
-                    String.valueOf(p.getParticipateNum() != null ? p.getParticipateNum() : 0)
-                ).create());
+                        date,
+                        time,
+                        p.getProjectName() != null ? p.getProjectName() : "",
+                        projectTypeMap.getOrDefault(p.getProjectType(),
+                                p.getProjectType() != null ? p.getProjectType() : ""),
+                        p.getLocation() != null ? p.getLocation() : "",
+                        String.valueOf(p.getGroupNum() != null ? p.getGroupNum() : 0),
+                        String.valueOf(p.getParticipateNum() != null ? p.getParticipateNum() : 0)).create());
             }
             data.put("scheduleTable", scheduleTable);
 
             // 3. 各项目分组详情
-            // 按照 projectType 分组,保持原有顺序
             Map<String, List<GameEventProjectVo>> projectsByType = allProjects.stream()
-                .filter(p -> p.getProjectType() != null)
-                .collect(Collectors.groupingBy(GameEventProjectVo::getProjectType, LinkedHashMap::new, Collectors.toList()));
+                    .filter(p -> p.getProjectType() != null)
+                    .collect(Collectors.groupingBy(GameEventProjectVo::getProjectType, LinkedHashMap::new,
+                            Collectors.toList()));
 
             List<Map<String, Object>> projectTypeList = new ArrayList<>();
             int typeIndex = 1;
-            String[] cnNums = {"", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
+            String[] cnNums = { "", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" };
 
             for (Map.Entry<String, List<GameEventProjectVo>> entry : projectsByType.entrySet()) {
                 String projectType = entry.getKey();
@@ -311,41 +356,40 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
                 int groupIndex = 1;
 
                 for (GameEventProjectVo p : entry.getValue()) {
-                    GameEventGroupBo groupBo = new GameEventGroupBo();
-                    groupBo.setProjectId(p.getProjectId());
-                    List<GameEventGroupVo> groups = gameEventGroupService.queryList(groupBo);
+                    List<GameEventGroupVo> groups = groupsByProjectId.getOrDefault(p.getProjectId(), new ArrayList<>());
+                    if (groups.isEmpty())
+                        continue;
 
-                    if (groups == null || groups.isEmpty()) continue;
-
-                    for(GameEventGroupVo group : groups) {
+                    for (GameEventGroupVo group : groups) {
                         Map<String, Object> groupMap = new HashMap<>();
-
                         String bracketIdx = String.valueOf(groupIndex);
-                        if (groupIndex <= 10) {
+                        if (groupIndex <= 10)
                             bracketIdx = cnNums[groupIndex];
-                        } else if (groupIndex < 20) {
+                        else if (groupIndex < 20)
                             bracketIdx = "十" + cnNums[groupIndex % 10];
-                        } else if (groupIndex < 100) {
-                            bracketIdx = cnNums[groupIndex / 10] + "十" + (groupIndex % 10 == 0 ? "" : cnNums[groupIndex % 10]);
+                        else if (groupIndex < 100)
+                            bracketIdx = cnNums[groupIndex / 10] + "十"
+                                    + (groupIndex % 10 == 0 ? "" : cnNums[groupIndex % 10]);
+
+                        List<GameAthleteCompetitionGroupVo> compGroups = compGroupsByGroupId
+                                .getOrDefault(group.getGroupId(), new ArrayList<>());
+                        int totalAthletes = compGroups.size();
+                        Map<String, GameAthleteCompetitionGroupVo> compMap = new HashMap<>();
+                        for (GameAthleteCompetitionGroupVo cg : compGroups) {
+                            compMap.put(cg.getGroupIndex() + "-" + cg.getTrackIndex(), cg);
                         }
 
-                        Map<String, Object> dbResult = gameEventGroupService.getGroupResultFromDB(group.getGroupId());
-                        Map<String, Object> groupResultMap = dbResult != null && dbResult.get("groupResult") != null ?
-                            (Map<String, Object>) dbResult.get("groupResult") : new HashMap<>();
-                        List<Map<String, Object>> teamsList = dbResult != null && dbResult.get("teams") != null ?
-                            (List<Map<String, Object>>) dbResult.get("teams") : new ArrayList<>();
-                        int totalAthletes = dbResult != null && dbResult.get("totalAthletes") != null ?
-                            Integer.parseInt(dbResult.get("totalAthletes").toString()) : 0;
-
                         String pName = p.getProjectName() != null ? p.getProjectName() : "";
                         String gName = group.getGroupName() != null ? group.getGroupName() : "";
                         String eCount = String.valueOf(totalAthletes);
-                        String iGroupNum = group.getIncludeGroupNum() != null ? String.valueOf(group.getIncludeGroupNum()) : "0";
+                        String iGroupNum = group.getIncludeGroupNum() != null
+                                ? String.valueOf(group.getIncludeGroupNum())
+                                : "0";
                         String rType = p.getRoundType() != null ? p.getRoundType() : "0";
 
-                        String groupTitle = "(" + bracketIdx + ")" + pName + " " + gName + "  " + eCount + "人  " + iGroupNum + "组  取前" + rType + "名";
+                        String groupTitle = "(" + bracketIdx + ")" + pName + " " + gName + "  " + eCount + "人  "
+                                + iGroupNum + "组  取前" + rType + "名";
                         groupMap.put("groupTitle", groupTitle);
-                        // 预留单独的变量供模板单独调用
                         groupMap.put("projectName", pName);
                         groupMap.put("groupName", gName);
                         groupMap.put("eligibleAthleteCount", eCount);
@@ -355,7 +399,6 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
                         long includeGroupNumVal = group.getIncludeGroupNum() != null ? group.getIncludeGroupNum() : 0L;
                         long trackNum = group.getTrackNum() != null ? group.getTrackNum() : 0L;
 
-                        // 动态表头
                         List<String> trackHeaders = new ArrayList<>();
                         trackHeaders.add("道/组");
                         for (int t = 1; t <= trackNum; t++) {
@@ -366,27 +409,17 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
 
                         for (int g = 1; g <= includeGroupNumVal; g++) {
                             List<String> rowData = new ArrayList<>();
-                            rowData.add(String.valueOf(g)); // 组别序号
+                            rowData.add(String.valueOf(g));
                             for (int t = 1; t <= trackNum; t++) {
                                 String key = g + "-" + t;
-                                Object athleteObj = groupResultMap.get(key);
-                                if (athleteObj instanceof Map) {
-                                    Map<String, Object> athlete = (Map<String, Object>) athleteObj;
-                                    String aCode = athlete.get("athleteCode") != null ? athlete.get("athleteCode").toString() : "";
-                                    String aName = athlete.get("name") != null ? athlete.get("name").toString() : "";
-                                    String aTeam = athlete.get("teamName") != null ? athlete.get("teamName").toString() : "";
-                                    if (aTeam.isEmpty() && athlete.get("teamId") != null) {
-                                        String tId = athlete.get("teamId").toString();
-                                        for(Map<String, Object> tm : teamsList) {
-                                            if(tId.equals(String.valueOf(tm.get("teamId")))) {
-                                                aTeam = tm.get("teamName") != null ? tm.get("teamName").toString() : "";
-                                                break;
-                                            }
-                                        }
-                                    }
+                                GameAthleteCompetitionGroupVo cg = compMap.get(key);
+                                if (cg != null) {
+                                    String aCode = cg.getAthleteCode() != null ? cg.getAthleteCode() : "";
+                                    String aName = cg.getAthleteName() != null ? cg.getAthleteName() : "";
+                                    String aTeam = cg.getTeamName() != null ? cg.getTeamName() : "";
                                     rowData.add(aCode + "\n" + aName + "\n" + aTeam);
                                 } else {
-                                    rowData.add("-");
+                                    rowData.add("");
                                 }
                             }
                             gTable.addRow(Rows.of(rowData.toArray(new String[0])).create());
@@ -405,26 +438,25 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
             data.put("projectTypeList", projectTypeList);
 
             // 4. 号码对照表
-            List<AthleteNumberTableVO> numberTableList = gameEventService.getNumberTable(eventId);
             List<Map<String, Object>> numberTableRenderList = new ArrayList<>();
             if (numberTableList != null) {
                 int index = 1;
-                for(AthleteNumberTableVO nt : numberTableList) {
+                for (AthleteNumberTableVO nt : numberTableList) {
                     Map<String, Object> ntMap = new HashMap<>();
                     ntMap.put("teamName", nt.getTeamName() != null ? nt.getTeamName() : "");
                     ntMap.put("numberRange", nt.getNumberRange() != null ? nt.getNumberRange() : "");
 
                     String chineseIdx = String.valueOf(index);
-                    if (index <= 10) {
+                    if (index <= 10)
                         chineseIdx = cnNums[index];
-                    } else if (index < 20) {
+                    else if (index < 20)
                         chineseIdx = "十" + cnNums[index % 10];
-                    } else if (index < 100) {
+                    else if (index < 100)
                         chineseIdx = cnNums[index / 10] + "十" + (index % 10 == 0 ? "" : cnNums[index % 10]);
-                    }
+
                     ntMap.put("chineseIndex", chineseIdx);
-                    // 提供完整的标题参数,方便直接渲染
-                    ntMap.put("title", chineseIdx + "、" + (nt.getTeamName() != null ? nt.getTeamName() : "") + "(" + ntMap.get("numberRange") + ")");
+                    ntMap.put("title", chineseIdx + "、" + (nt.getTeamName() != null ? nt.getTeamName() : "") + "("
+                            + ntMap.get("numberRange") + ")");
 
                     List<RowRenderData> rowsList = new ArrayList<>();
                     if (nt.getAthleteCodeVos() != null && !nt.getAthleteCodeVos().isEmpty()) {
@@ -472,8 +504,8 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
             for (XWPFTable table : document.getTables()) {
                 if (!table.getRows().isEmpty()) {
                     XWPFTableCell firstCell = table.getRow(0).getCell(0);
-                    if (firstCell != null && firstCell.getText() != null && firstCell.getText().replaceAll("\\s", "").contains("道/组")) {
-                        // poi-tl 原生不支持直接绘制对角线,通过 POI 底层操作实现
+                    if (firstCell != null && firstCell.getText() != null
+                            && firstCell.getText().replaceAll("\\s", "").contains("道/组")) {
                         CTTc ctTc = firstCell.getCTTc();
                         CTTcPr tcPr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
                         CTTcBorders borders = tcPr.isSetTcBorders() ? tcPr.getTcBorders() : tcPr.addNewTcBorders();
@@ -483,7 +515,6 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
                         border.setSpace(new java.math.BigInteger("0"));
                         border.setColor("auto");
 
-                        // 为了美观,将单元格文本重新排版以适配对角线
                         firstCell.removeParagraph(0);
                         XWPFParagraph p1 = firstCell.addParagraph();
                         p1.setAlignment(ParagraphAlignment.RIGHT);
@@ -496,17 +527,18 @@ public class AppEventMdServiceImpl implements IAppEventMdService {
             }
 
             response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
-            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(eventVo.getEventName() + "_秩序册.docx", "utf-8"));
-
-            OutputStream out = response.getOutputStream();
-            template.write(out);
-            out.flush();
-            out.close();
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode(eventVo.getEventName() + "-秩序册", "UTF-8").replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".docx");
+            OutputStream os = response.getOutputStream();
+            template.write(os);
+            os.flush();
+            os.close();
             template.close();
 
         } catch (Exception e) {
             log.error("导出秩序册失败", e);
-            throw new ServiceException("导出秩序册失败: " + e.getMessage());
+            throw new ServiceException("导出秩序册失败");
         }
     }
 }

BIN
ruoyi-modules/ruoyi-game-event/src/main/resources/template/event_template.docx