瀏覽代碼

批量上传

hyy 4 月之前
父節點
當前提交
ea195bbb9b

+ 8 - 2
yudao-module-museums/yudao-module-museums-biz/pom.xml

@@ -41,18 +41,24 @@
             <artifactId>jackson-databind</artifactId>
             <version>2.15.0</version> <!-- 使用最新版本 -->
         </dependency>
-        <!-- Jackson Core (通常也需要) -->
+        <!-- Jackson Core  -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-core</artifactId>
             <version>2.15.0</version>
         </dependency>
-        <!-- Jackson Annotations (如果需要的话) -->
+        <!-- Jackson Annotations  -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
             <version>2.15.0</version>
         </dependency>
+        <!-- ZIP文件中文处理  -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.26.1</version>
+        </dependency>
 
         <!-- Web 相关 -->
         <dependency>

+ 138 - 36
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoServiceImpl.java

@@ -12,6 +12,8 @@ import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.starter.annotation.LogRecord;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
@@ -240,43 +242,138 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         return true;
     }
 
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public String importSpecimenImages(MultipartFile file) throws Exception {
+//        // 校验文件类型
+//        if (!file.getOriginalFilename().endsWith(".zip")) {
+//            throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
+//        }
+//        // 创建临时目录存放解压后的文件
+//        File tempDir = Files.createTempDirectory("specimen_images").toFile();
+//        // 创建一个临时文件用于存储上传的 ZIP 文件
+//        File tempZipFile = File.createTempFile("uploaded_", ".zip");
+//        // 将 MultipartFile 的内容复制到临时文件
+//        file.transferTo(tempZipFile);
+////        try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(tempZipFile.toPath()))) {
+////            ZipEntry entry;
+////            while ((entry = zipInputStream.getNextEntry()) != null) {
+////                if (!entry.isDirectory()) {
+////                    File newFile = new File(tempDir, entry.getName());
+////                    // 确保目录存在
+////                    newFile.getParentFile().mkdirs();
+////                    // 进行解压
+////                    try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(newFile.toPath()))) {
+////                        byte[] buffer = new byte[1024];
+////                        int len;
+////                        while ((len = zipInputStream.read(buffer)) > 0) {
+////                            bos.write(buffer, 0, len);
+////                        }
+////                    }
+////                }
+////                zipInputStream.closeEntry();
+////            }
+//        try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(Files.newInputStream(tempZipFile.toPath()))) {
+//            ZipArchiveEntry entry;
+//            while ((entry = zipInputStream.getNextEntry()) != null) {
+//                if (!entry.isDirectory()) {
+//                    // 获取解压后的文件名,Commons Compress 会自动处理编码
+//                    String entryName = entry.getName();
+//                    File newFile = new File(tempDir, entryName);
+//                    newFile.getParentFile().mkdirs();  // 确保目录存在
+//                    try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(newFile.toPath()))) {
+//                        byte[] buffer = new byte[1024];
+//                        int len;
+//                        while ((len = zipInputStream.read(buffer)) > 0) {
+//                            bos.write(buffer, 0, len);
+//                        }
+//                    }
+//                }
+//                zipInputStream.close();
+//            }
+//            // 处理每个图片文件
+//            File[] imageFiles = tempDir.listFiles();
+//            if (imageFiles != null) {
+//                Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 防止重复
+//                for (File imageFile : imageFiles) {
+//                    String imageName = imageFile.getName();
+//                    if (!isValidImageName(imageName)) {
+//                        System.err.println("无效的图片格式: " + imageName);
+//                        continue;
+//                    }
+//
+//                    // 根据图片名称查找对应的标本
+//                    SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
+//                    if (specimenInfo != null) {
+//                        // 上传图片并获取 URL
+//                        String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
+//
+//                        // 确保 imagePath 有效且不为空
+//                        if (imagePath != null && !imagePath.trim().isEmpty()) {
+//                            // 添加新上传的路径
+//                            imagePathsSet.add(imagePath.trim());
+//
+//                            // 添加已存在的路径
+//                            String existingImagePaths = specimenInfo.getImagePath();
+//                            if (existingImagePaths != null && !existingImagePaths.trim().isEmpty()&& !existingImagePaths.equals("[]")) {
+//                                String[] existingPaths = existingImagePaths.split(",\\s*");
+//                                Collections.addAll(imagePathsSet, existingPaths);
+//                            }
+//                        }
+//                    }
+//                }
+//
+//                // 生成最终的逗号分隔的字符串
+//                String newImagePaths = String.join(", ", imagePathsSet);
+//                // 更新所有标本的信息,确保只更新一次
+//                for (File imageFile : imageFiles) {
+//                    String imageName = imageFile.getName();
+//                    SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
+//                    if (specimenInfo != null) {
+//                        specimenInfo.setImagePath(newImagePaths);
+//                        updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
+//                    }
+//                }
+//            }
+//            zipInputStream.close();
+//            System.gc();
+//        } finally {
+//            // 清理临时文件
+//            FileUtils.deleteDirectory(tempDir);
+//        }
+//        return "标本图片导入成功";
+//    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String importSpecimenImages(MultipartFile file) throws Exception {
         // 校验文件类型
-        if (!file.getOriginalFilename().endsWith(".zip")) {
+        if (!file.getOriginalFilename().toLowerCase().endsWith(".zip")) {
             throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
         }
+
         // 创建临时目录存放解压后的文件
         File tempDir = Files.createTempDirectory("specimen_images").toFile();
-        // 创建一个临时文件用于存储上传的 ZIP 文件
-        File tempZipFile = File.createTempFile("uploaded_", ".zip");
-        // 将 MultipartFile 的内容复制到临时文件
-        file.transferTo(tempZipFile);
-        try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(tempZipFile.toPath()))) {
-            ZipEntry entry;
+
+        // 使用 ZipArchiveInputStream 代替 ZipInputStream,并设置字符编码为 UTF-8
+        try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream())) {
+            ZipArchiveEntry entry;
+            Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 来去重
+
             while ((entry = zipInputStream.getNextEntry()) != null) {
                 if (!entry.isDirectory()) {
+                    // 处理中文文件名问题,使用 entry.getName() 获取文件名,默认是 UTF-8 编码
                     File newFile = new File(tempDir, entry.getName());
-                    // 确保目录存在
-                    newFile.getParentFile().mkdirs();
                     // 进行解压
-                    try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(newFile.toPath()))) {
+                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
                         byte[] buffer = new byte[1024];
                         int len;
                         while ((len = zipInputStream.read(buffer)) > 0) {
                             bos.write(buffer, 0, len);
                         }
                     }
-                }
-                zipInputStream.closeEntry();
-            }
-            // 处理每个图片文件
-            File[] imageFiles = tempDir.listFiles();
-            if (imageFiles != null) {
-                Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 防止重复
-                for (File imageFile : imageFiles) {
-                    String imageName = imageFile.getName();
+
+                    String imageName = newFile.getName();
                     if (!isValidImageName(imageName)) {
                         System.err.println("无效的图片格式: " + imageName);
                         continue;
@@ -286,37 +383,40 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                     SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
                     if (specimenInfo != null) {
                         // 上传图片并获取 URL
-                        String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
+                        String imagePath = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
 
                         // 确保 imagePath 有效且不为空
                         if (imagePath != null && !imagePath.trim().isEmpty()) {
                             // 添加新上传的路径
-                            imagePathsSet.add(imagePath.trim());
+                            imagePathsSet.add(imagePath.trim());  // 使用 Set 来去重
 
-                            // 添加已存在的路径
+                            // 获取已存在的路径,并处理空值或无效的路径
                             String existingImagePaths = specimenInfo.getImagePath();
-                            if (existingImagePaths != null && !existingImagePaths.trim().isEmpty()) {
+                            if (existingImagePaths != null && !existingImagePaths.trim().isEmpty() && !existingImagePaths.equals("[]")) {
+                                // 清理已有路径中的方括号(如果有)
+                                existingImagePaths = existingImagePaths.replaceAll("^\\[|\\]$", "").trim();
+                                // 如果原路径是有效的且不是空数组,则拆分并添加到 Set 中
                                 String[] existingPaths = existingImagePaths.split(",\\s*");
-                                Collections.addAll(imagePathsSet, existingPaths);
+                                Collections.addAll(imagePathsSet, existingPaths);  // 也用 Set 来去重
                             }
                         }
                     }
                 }
+            }
 
-                // 生成最终的逗号分隔的字符串
-                String newImagePaths = String.join(", ", imagePathsSet);
-                // 更新所有标本的信息,确保只更新一次
-                for (File imageFile : imageFiles) {
-                    String imageName = imageFile.getName();
-                    SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
-                    if (specimenInfo != null) {
-                        specimenInfo.setImagePath(newImagePaths);
-                        updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
-                    }
+            // 将 Set 中的路径重新拼接成逗号分隔的字符串
+            String newImagePaths = String.join(", ", imagePathsSet);
+
+            // 更新所有标本的信息,确保只更新一次
+            for (File imageFile : tempDir.listFiles()) {
+                String imageName = imageFile.getName();
+                SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
+                if (specimenInfo != null) {
+                    specimenInfo.setImagePath("[" + newImagePaths + "]"); // 设置多个图片路径的字符串,外面加上方括号
+                    updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
                 }
             }
-            zipInputStream.close();
-            System.gc();
+
         } finally {
             // 清理临时文件
             FileUtils.deleteDirectory(tempDir);
@@ -324,6 +424,8 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         return "标本图片导入成功";
     }
 
+
+
     //工作台
     //根据入库的登记情况统计本年标本入库信息
     @Override