diff --git a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/ocr/ZipExtractor.java b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/ocr/ZipExtractor.java index 009d87d..fa1ccfe 100644 --- a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/ocr/ZipExtractor.java +++ b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/ocr/ZipExtractor.java @@ -8,6 +8,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -42,12 +43,13 @@ public class ZipExtractor log.info("zip 下载: url={} size={}B tmp={}", zipUrl, size, zipFile.getAbsolutePath()); // 优先 UTF-8 解包; 若 entry 名非 UTF-8 (常见 GBK, Windows 打包) 会抛 - // IllegalArgumentException (malformed input) → 回退 GBK 重试 + // MalformedInputException (IOException 子类, 不是 IllegalArgumentException) + // → 回退 GBK 重试 try { return doExtract(zipFile, tmpRoot, StandardCharsets.UTF_8); } - catch (IllegalArgumentException e) + catch (IllegalArgumentException | MalformedInputException e) { log.warn("zip 文件名非 UTF-8, 回退 GBK 重试: {}", e.getMessage()); return doExtract(zipFile, tmpRoot, Charset.forName("GBK")); diff --git a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingAttendeeServiceImpl.java b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingAttendeeServiceImpl.java index fa2dbfe..e580e9e 100644 --- a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingAttendeeServiceImpl.java +++ b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingAttendeeServiceImpl.java @@ -7,6 +7,7 @@ import java.io.InputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.charset.Charset; +import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; @@ -994,7 +995,9 @@ public class BizMeetingAttendeeServiceImpl implements IBizMeetingAttendeeService private LinkedHashMap parseAttendeeZip(byte[] zipBytes) throws IOException { try { return readAttendeeZip(zipBytes, StandardCharsets.UTF_8); - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | MalformedInputException e) { + // 注: ZipInputStream 用错 charset 解码 entry name 抛 MalformedInputException (IOException 子类), + // 旧 catch (IllegalArgumentException) 漏掉, GBK 回退永远是死代码 log.warn("[attendee] zip UTF-8 解析失败, 回退 GBK: {}", e.getMessage()); return readAttendeeZip(zipBytes, Charset.forName("GBK")); } diff --git a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingMaterialServiceImpl.java b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingMaterialServiceImpl.java index 11d20cb..690d7c2 100644 --- a/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingMaterialServiceImpl.java +++ b/ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizMeetingMaterialServiceImpl.java @@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.charset.MalformedInputException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.UUID; @@ -841,8 +842,10 @@ public class BizMeetingMaterialServiceImpl implements IBizMeetingMaterialService Map> folderNames = new HashMap<>(); try { readServiceZip(zipBytes, StandardCharsets.UTF_8, folderBytes, folderNames); - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | MalformedInputException e) { // 中文 Windows 打包器 (WinRAR/资源管理器) 用 GBK 编码条目名且不置 UTF-8 标志, 回退 GBK 重解析 + // 注: ZipInputStream 用错 charset 解码 entry name 抛的是 MalformedInputException (IOException 子类), + // 不是 IllegalArgumentException, 旧 catch 漏掉导致 fallback 永远不会跑 log.warn("[material] 会务材料 zip UTF-8 解析失败, 回退 GBK: {}", e.getMessage()); folderBytes.clear(); folderNames.clear(); diff --git a/ry-vue3/src/views/doctor/MeetingInvitation.vue b/ry-vue3/src/views/doctor/MeetingInvitation.vue index f764f92..ba76b43 100644 --- a/ry-vue3/src/views/doctor/MeetingInvitation.vue +++ b/ry-vue3/src/views/doctor/MeetingInvitation.vue @@ -4,7 +4,7 @@ -

尊敬的 {{ attendeeName || '专家' }}:

+

尊敬的 {{ attendeeName || '专家' }} 教授:

diff --git a/ry-vue3/src/views/meetings/MeetingDetail.vue b/ry-vue3/src/views/meetings/MeetingDetail.vue index f0c776a..2be43fc 100644 --- a/ry-vue3/src/views/meetings/MeetingDetail.vue +++ b/ry-vue3/src/views/meetings/MeetingDetail.vue @@ -1320,6 +1320,10 @@ function onBatchEsign() { /** 调后端邀请参会 (推"会议邀请"站内信 + 置 is_invited=1, 不发短信); loadingId 非空→单条行级 loading, 否则批量工具栏 loading */ async function pushInvite(ids, loadingId) { if (!ids || !ids.length) return + if (!row.value.posterUrl) { + ElMessage.warning('该会议未上传日程海报,不允许发送邀请。请先上传海报后再发送。') + return + } if (loadingId != null) inviteLoadingId.value = loadingId else inviteSending.value = true try {