修复解压问题

This commit is contained in:
2026-09-08 11:54:46 +08:00
parent a3eeb24f4f
commit b4a9e30287
@@ -49,8 +49,12 @@ import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -247,8 +251,12 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
int imageCount = 0; int imageCount = 0;
int matchedImageCount = 0; int matchedImageCount = 0;
Set<Long> relatedWaybillIds = new HashSet<>(); Set<Long> relatedWaybillIds = new HashSet<>();
try (InputStream source = openSourceFile(voucher.getFileUrl()); Path archivePath = downloadSourceFile(voucher.getFileUrl());
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(source), StandardCharsets.UTF_8)) { try {
Charset archiveCharset = detectArchiveCharset(archivePath);
log.info("[凭证处理] 已识别压缩包文件名编码 voucherId={}, charset={}", voucherId, archiveCharset.name());
try (InputStream source = Files.newInputStream(archivePath);
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(source), archiveCharset)) {
ZipEntry entry; ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) { while ((entry = zipInputStream.getNextEntry()) != null) {
if (entry.isDirectory()) { if (entry.isDirectory()) {
@@ -322,17 +330,20 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
} }
} }
} }
log.info("[凭证处理] 进度 90%:文件解压上传完成 voucherId={}, fileCount={}, imageCount={}, matchedImageCount={}", log.info("[凭证处理] 进度 90%:文件解压上传完成 voucherId={}, fileCount={}, imageCount={}, matchedImageCount={}",
voucherId, fileCount, imageCount, matchedImageCount); voucherId, fileCount, imageCount, matchedImageCount);
VoucherManage update = new VoucherManage(); VoucherManage update = new VoucherManage();
update.setId(voucher.getId()); update.setId(voucher.getId());
update.setVoucherCount(imageCount); update.setVoucherCount(imageCount);
update.setRelatedWaybillCount(relatedWaybillIds.size()); update.setRelatedWaybillCount(relatedWaybillIds.size());
update.setUnRelatedWaybillCount(Math.max(waybills.size() - relatedWaybillIds.size(), 0)); update.setUnRelatedWaybillCount(Math.max(waybills.size() - relatedWaybillIds.size(), 0));
update.setProcessStatus("处理完成"); update.setProcessStatus("处理完成");
updateById(update); updateById(update);
log.info("[凭证处理] 进度 100%:处理完成 voucherId={}, voucherBatchNo={}, fileCount={}, imageCount={}, relatedWaybillCount={}, unrelatedWaybillCount={}", log.info("[凭证处理] 进度 100%:处理完成 voucherId={}, voucherBatchNo={}, fileCount={}, imageCount={}, relatedWaybillCount={}, unrelatedWaybillCount={}",
voucherId, voucher.getVoucherBatchNo(), fileCount, imageCount, relatedWaybillIds.size(), Math.max(waybills.size() - relatedWaybillIds.size(), 0)); voucherId, voucher.getVoucherBatchNo(), fileCount, imageCount, relatedWaybillIds.size(), Math.max(waybills.size() - relatedWaybillIds.size(), 0));
} finally {
deleteTempArchive(archivePath);
}
} catch (Exception exception) { } catch (Exception exception) {
VoucherManage update = new VoucherManage(); VoucherManage update = new VoucherManage();
update.setId(voucher.getId()); update.setId(voucher.getId());
@@ -396,6 +407,43 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
return connection.getInputStream(); return connection.getInputStream();
} }
private Path downloadSourceFile(String fileUrl) throws Exception {
Path archivePath = Files.createTempFile("voucher-source-", ".zip");
try (InputStream source = openSourceFile(fileUrl);
OutputStream target = Files.newOutputStream(archivePath)) {
source.transferTo(target);
return archivePath;
} catch (Exception exception) {
try {
Files.deleteIfExists(archivePath);
} catch (Exception cleanupException) {
exception.addSuppressed(cleanupException);
}
throw exception;
}
}
private Charset detectArchiveCharset(Path archivePath) throws Exception {
try (InputStream source = Files.newInputStream(archivePath);
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(source), StandardCharsets.UTF_8)) {
while (zipInputStream.getNextEntry() != null) {
zipInputStream.closeEntry();
}
return StandardCharsets.UTF_8;
} catch (IllegalArgumentException | java.io.IOException exception) {
log.warn("[凭证处理] 压缩包文件名不是有效 UTF-8,回退使用 GB18030archivePath={}", archivePath, exception);
return Charset.forName("GB18030");
}
}
private void deleteTempArchive(Path archivePath) {
try {
Files.deleteIfExists(archivePath);
} catch (Exception exception) {
log.warn("[凭证处理] 删除临时压缩包失败,archivePath={}", archivePath, exception);
}
}
private String stripZipSuffixParameters(String fileUrl) { private String stripZipSuffixParameters(String fileUrl) {
if (Func.isEmpty(fileUrl)) { if (Func.isEmpty(fileUrl)) {
return fileUrl; return fileUrl;