Bläddra i källkod

批量上传记录了导入成功的图片名

hyy 4 månader sedan
förälder
incheckning
df508419ae

+ 0 - 1
yudao-module-museums/yudao-module-museums-api/src/main/java/cn/iocoder/yudao/module/museums/enums/ErrorCodeConstants.java

@@ -15,7 +15,6 @@ public class ErrorCodeConstants {
     public static final ErrorCode INVALID_IMAGE_FORMAT = new ErrorCode(1-016-000-003, "图片格式不符合要求");
     public static final ErrorCode SPECIMEN_NUMBER_ALREADY_EXISTS_CANNOT_ADDED = new ErrorCode(1-016-000-004, "标本编号已存在,无法新增");
     public static final ErrorCode SPECIMEN_NUMBER_NOT_EXISTS = new ErrorCode(1-016-000-005, "标本编号无效或不存在");
-    public static final ErrorCode SPECIMEN_FILE_OR_IMAGE_REQUIRED = new ErrorCode(1-016-000-006, "请至少上传一个标本文件或一个图片文件");
 
     // ========== 标本出库回库信息 1-016-001-000 ==========
     public static final ErrorCode SPECIMEN_OUTBOUND_NOT_EXISTS = new ErrorCode(1-016-001-000, "标本出库回库信息不存在");

+ 9 - 9
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/SpecimenInfoController.java

@@ -165,14 +165,14 @@ public class SpecimenInfoController {
     @PostMapping("/import-specimen-with-images")
     @Operation(summary = "导入标本及其图片")
     @Parameters({
-            @Parameter(name = "file", description = "Excel 文件", required = false), // 将 required 设置为 false
-            @Parameter(name = "imageFile", description = "压缩包文件", required = false), // 将 required 设置为 false
+            @Parameter(name = "file", description = "Excel 文件", required = false),
+            @Parameter(name = "imageFile", description = "压缩包文件", required = false),
             @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
     })
     @PreAuthorize("@ss.hasPermission('museums:specimen-info:import')")
     public CommonResult<SpecimenImportRespVO> importSpecimenWithImages(
-            @RequestParam(value = "file", required = false) MultipartFile file, // 将 required 设置为 false
-            @RequestParam(value = "imageFile", required = false) MultipartFile imageFile, // 将 required 设置为 false
+            @RequestParam(value = "file", required = false) MultipartFile file,
+            @RequestParam(value = "imageFile", required = false) MultipartFile imageFile,
             @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
 
         SpecimenImportRespVO importResult = null;
@@ -185,18 +185,18 @@ public class SpecimenInfoController {
 
         // 处理标本图片的导入(如果存在)
         if (imageFile != null && !imageFile.isEmpty()) {
-            String imageResult = specimenInfoService.importSpecimenImages(imageFile);
-            if (imageResult == null) {
+//            SpecimenImportRespVO imageResult = specimenInfoService.importSpecimenImages(imageFile);
+            importResult = specimenInfoService.importSpecimenImages(imageFile);
+            if (importResult == null) {
                 throw exception(INVALID_IMAGE_FORMAT);
             }
         }
-//        System.gc();
+        System.gc();
         return success(importResult);
     }
 
-
     //工作台
-    //根据入库的登记情况统计本年标本入库信息。
+    //统计本年标本每月入库数量
     @GetMapping("/statistics/entry/{year}")
     @Operation(summary = "统计本年标本每月入库数量")
     @Parameter(name = "year", description = "年份", required = true, example = "2024")

+ 7 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimeninfo/vo/SpecimenImportRespVO.java

@@ -26,4 +26,11 @@ public class SpecimenImportRespVO {
 
     @Schema(description = "成功导入的标本id", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<Long> createdSpecimenIds; // 新增字段
+
+    @Schema(description = "创建成功的图片名称数组", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<String> createSpecimenImages;
+
+    @Schema(description = "导入失败的图片集合,key 为图片名称,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, String> failureSpecimenImages;
+
 }

+ 0 - 11
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/controller/admin/specimenoutbound/SpecimenOutboundController.java

@@ -232,17 +232,6 @@ public class SpecimenOutboundController {
     }
 
     //获取出库单,方便操作员查看标本编号、图片及标本存放位置等。
-//    @GetMapping("/specimenInfo")
-//    @Operation(summary = "获得标本出库单")
-//    @Parameter(name = "id", description = "编号", required = true, example = "1024")
-//    @PreAuthorize("@ss.hasPermission('museums:specimen-outbound:query')")
-//    public CommonResult<SpecimenOutboundWithInfoRespVO> getSpecimen(@RequestParam("id") Long id) {
-//        SpecimenOutboundWithInfoRespVO specimenOutbound = specimenOutboundService.getSpecimenOutboundWithInfo(id);
-//        if (specimenOutbound == null) {
-//            throw exception(SPECIMEN_OUTBOUND_ORDER_NOT_EXISTS);
-//        }
-//        return success(specimenOutbound);
-//    }
     @GetMapping("/specimenInfo")
     @Operation(summary = "获得标本出库单及分页的关联标本信息")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")

+ 1 - 1
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/service/specimeninfo/SpecimenInfoService.java

@@ -74,7 +74,7 @@ public interface SpecimenInfoService {
      * @param file 压缩包文件
      * @return 导入结果
      */
-    String importSpecimenImages(MultipartFile file) throws Exception;
+    SpecimenImportRespVO importSpecimenImages(MultipartFile file) throws Exception;
 
     //工作台
     /**

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

@@ -166,6 +166,11 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                 return;
             }
 
+            // 处理文献资料字段,如果为空就赋值 <br>
+            if (importSpecimen.getDescription() == null || importSpecimen.getDescription().trim().isEmpty()) {
+                importSpecimen.setDescription("<p><br></p>");
+            }
+
             if (existSpecimen == null) {
                 // 2.2.1 不存在则插入
                 SpecimenInfoDO newSpecimen = BeanUtils.toBean(importSpecimen, SpecimenInfoDO.class);
@@ -212,9 +217,86 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         return true;
     }
 
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public String importSpecimenImages(MultipartFile file) throws Exception {
+//        // 校验文件类型
+//        if (!file.getOriginalFilename().toLowerCase().endsWith(".zip")) {
+//            throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
+//        }
+//
+//        // 创建临时目录存放解压后的文件
+//        File tempDir = Files.createTempDirectory("specimen_images").toFile();
+//
+//        try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream())) {
+//            ZipArchiveEntry entry;
+//            Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 来去重
+//
+//            while ((entry = zipInputStream.getNextEntry()) != null) {
+//                if (!entry.isDirectory()) {
+//                    File newFile = new File(tempDir, entry.getName());
+//                    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);
+//                        }
+//                    }
+//
+//                    String imageName = newFile.getName();
+//                    if (!isValidImageName(imageName)) {
+//
+//                        System.err.println("无效的图片格式: " + imageName);
+//                        continue;
+//                    }
+//
+//                    // 根据图片名称查找对应的标本
+//                    SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
+//                    if (specimenInfo != null) {
+//                        // 上传图片并获取 URL
+//                        String imagePath = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+//
+//                        // 确保 imagePath 有效且不为空
+//                        if (imagePath != null && !imagePath.trim().isEmpty()) {
+//                            // 添加新上传的路径
+//                            imagePathsSet.add(imagePath.trim());  // 使用 Set 来去重
+//
+//                            // 获取已存在的路径,并处理空值或无效的路径
+//                            String existingImagePaths = specimenInfo.getImagePath();
+//                            if (existingImagePaths != null && !existingImagePaths.trim().isEmpty()) {
+//                                // 清理已有路径中的方括号(如果有)
+//                                existingImagePaths = existingImagePaths.replaceAll("^\\[|\\]$", "").trim();
+//                                // 如果原路径是有效的且不是空数组,则拆分并添加到 Set 中
+//                                String[] existingPaths = existingImagePaths.split(",\\s*");
+//                                Collections.addAll(imagePathsSet, existingPaths);  // 也用 Set 来去重
+//                            }
+//                        }
+//                    }
+//                }
+//            }
+//
+//            // 将 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));
+//                }
+//            }
+//
+//        } finally {
+//            // 清理临时文件
+//            FileUtils.deleteDirectory(tempDir);
+//        }
+//        return "标本图片导入成功";
+//    }
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public String importSpecimenImages(MultipartFile file) throws Exception {
+    public SpecimenImportRespVO importSpecimenImages(MultipartFile file) throws Exception {
         // 校验文件类型
         if (!file.getOriginalFilename().toLowerCase().endsWith(".zip")) {
             throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
@@ -223,10 +305,16 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         // 创建临时目录存放解压后的文件
         File tempDir = Files.createTempDirectory("specimen_images").toFile();
 
+        // 创建存储成功导入和更新图片名称的集合
+        SpecimenImportRespVO respVO = SpecimenImportRespVO.builder()
+                .createSpecimenImages(new ArrayList<>())  // 成功导入的图片
+                .failureSpecimenImages(new LinkedHashMap<>())  // 失败的图片及错误信息
+                .build();
+
+        Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 来去重
+
         try (ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(file.getInputStream())) {
             ZipArchiveEntry entry;
-            Set<String> imagePathsSet = new HashSet<>();  // 使用 Set 来去重
-
             while ((entry = zipInputStream.getNextEntry()) != null) {
                 if (!entry.isDirectory()) {
                     File newFile = new File(tempDir, entry.getName());
@@ -240,7 +328,7 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
 
                     String imageName = newFile.getName();
                     if (!isValidImageName(imageName)) {
-                        System.err.println("无效的图片格式: " + imageName);
+                        respVO.getFailureSpecimenImages().put(imageName, "无效的图片格式");
                         continue;
                     }
 
@@ -264,21 +352,30 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                                 String[] existingPaths = existingImagePaths.split(",\\s*");
                                 Collections.addAll(imagePathsSet, existingPaths);  // 也用 Set 来去重
                             }
+
+                            // 更新标本信息的图片路径
+                            specimenInfo.setImagePath("[" + String.join(", ", imagePathsSet) + "]");
+                            updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
                         }
+                    } else {
+                        // 如果没有找到对应标本,记录失败
+                        respVO.getFailureSpecimenImages().put(imageName, "没有找到对应的标本");
                     }
                 }
             }
-
             // 将 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));
+
+                    // 记录创建成功的图片名称
+                    respVO.getCreateSpecimenImages().add(imageName);
                 }
             }
 
@@ -286,7 +383,7 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
             // 清理临时文件
             FileUtils.deleteDirectory(tempDir);
         }
-        return "标本图片导入成功";
+        return respVO;
     }
 
     //工作台