Pārlūkot izejas kodu

多个标本照片url存为数组

hyy 7 mēneši atpakaļ
vecāks
revīzija
281e80fc38

+ 3 - 0
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java

@@ -23,6 +23,9 @@ public class FilePageReqVO extends PageParam {
     @Schema(description = "文件类型,模糊匹配", example = "jpg")
     private String type;
 
+    @Schema(description = "文件名称,模糊匹配", example = "image1.jpg")
+    private String name;
+
     @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;

+ 2 - 4
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java

@@ -19,6 +19,7 @@ public interface FileMapper extends BaseMapperX<FileDO> {
 
     default PageResult<FileDO> selectPage(FilePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>()
+                .likeIfPresent(FileDO::getName, reqVO.getName())
                 .likeIfPresent(FileDO::getPath, reqVO.getPath())
                 .likeIfPresent(FileDO::getType, reqVO.getType())
                 .betweenIfPresent(FileDO::getCreateTime, reqVO.getCreateTime())
@@ -28,14 +29,11 @@ public interface FileMapper extends BaseMapperX<FileDO> {
     default PageResult<FileDO> selectPageWithAnotherOne(FilePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>()
                 .eq(FileDO::getAnother, 1) // 只选择 another = 1 的文件
+                .likeIfPresent(FileDO::getName, reqVO.getName())
                 .likeIfPresent(FileDO::getPath, reqVO.getPath())
                 .likeIfPresent(FileDO::getType, reqVO.getType())
                 .betweenIfPresent(FileDO::getCreateTime, reqVO.getCreateTime())
                 .orderByDesc(FileDO::getId));
     }
 
-
-    List<FileDO> findByAnother(Integer another);
-
-
 }

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

@@ -324,18 +324,6 @@ public class SpecimenInfoController {
         return CommonResult.success(yearlySourceStatistics);
     }
 
-    //标本来源的登记情况统计
-    //不好用,准备废弃
-    @GetMapping("/statistics/so")
-    @Operation(summary = "历年标本来源增减统计")
-    @Parameter(name = "year", description = "年份", required = true, example = "2024")
-    @PreAuthorize("@ss.hasPermission('museums:specimen-info:query')")
-    public CommonResult<List<SpecimenInfoDO>> getSpecimenSourceStatistics(@RequestParam int year) {
-        List<SpecimenInfoDO> sourceStatistics = specimenInfoService.getSpecimenSourceStatistics(year);
-        return success(sourceStatistics);
-    }
-
-
     //标本库管理
     //实现对标本操作记录进行追溯查看,包括入库记录、编辑记录、出库记录、回库记录等。
     @GetMapping("/records")

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

@@ -20,4 +20,14 @@ public class SpecimenImportRespVO {
 
     @Schema(description = "导入失败的标本集合,key 为标本编号,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
     private Map<String, String> failureSpecimenNumbers;
+
+    @Schema(description = "创建成功的图片名称数组", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<String> createSpecimenImages;
+
+    @Schema(description = "更新成功的图片名称数组", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<String> updateSpecimenImages;
+
+    @Schema(description = "导入失败的图片集合,key 为图片名称,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
+    private Map<String, String> failureSpecimenImages;
+
 }

+ 1 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/dataobject/specimeninfo/SpecimenInfoDO.java

@@ -133,6 +133,7 @@ public class SpecimenInfoDO extends BaseDO {
      * 图片路径
      */
     private String imagePath;
+//    private String[] imagePath;
     /**
      * 入库操作员
      */

+ 14 - 17
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimeninfo/SpecimenInfoMapper.java

@@ -17,7 +17,7 @@ import org.apache.ibatis.annotations.Update;
 /**
  * 标本管理 Mapper
  *
- * @author 普伟
+ * @author pw
  */
 @Mapper
 public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
@@ -25,26 +25,26 @@ public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
     default PageResult<SpecimenInfoDO> selectPage(SpecimenInfoPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<SpecimenInfoDO>()
                 .eqIfPresent(SpecimenInfoDO::getSpecimenType, reqVO.getSpecimenType())
-                .eqIfPresent(SpecimenInfoDO::getSpecimenNumber, reqVO.getSpecimenNumber())
-                .eqIfPresent(SpecimenInfoDO::getAssetNumber, reqVO.getAssetNumber())
-                .eqIfPresent(SpecimenInfoDO::getStorageLocation, reqVO.getStorageLocation())
+                .likeIfPresent(SpecimenInfoDO::getSpecimenNumber, reqVO.getSpecimenNumber())
+                .likeIfPresent(SpecimenInfoDO::getAssetNumber, reqVO.getAssetNumber())
+                .likeIfPresent(SpecimenInfoDO::getStorageLocation, reqVO.getStorageLocation())
                 .likeIfPresent(SpecimenInfoDO::getChineseName, reqVO.getChineseName())
                 .likeIfPresent(SpecimenInfoDO::getEnglishName, reqVO.getEnglishName())
-                .eqIfPresent(SpecimenInfoDO::getComposition, reqVO.getComposition())
-                .eqIfPresent(SpecimenInfoDO::getOrigin, reqVO.getOrigin())
-                .eqIfPresent(SpecimenInfoDO::getEra, reqVO.getEra())
-                .eqIfPresent(SpecimenInfoDO::getPreservedLayer, reqVO.getPreservedLayer())
-                .eqIfPresent(SpecimenInfoDO::getMeteoriteType, reqVO.getMeteoriteType())
+                .likeIfPresent(SpecimenInfoDO::getComposition, reqVO.getComposition())
+                .likeIfPresent(SpecimenInfoDO::getOrigin, reqVO.getOrigin())
+                .likeIfPresent(SpecimenInfoDO::getEra, reqVO.getEra())
+                .likeIfPresent(SpecimenInfoDO::getPreservedLayer, reqVO.getPreservedLayer())
+                .likeIfPresent(SpecimenInfoDO::getMeteoriteType, reqVO.getMeteoriteType())
                 .likeIfPresent(SpecimenInfoDO::getInternationalName, reqVO.getInternationalName())
                 .eqIfPresent(SpecimenInfoDO::getPreservationType, reqVO.getPreservationType())
                 .eqIfPresent(SpecimenInfoDO::getSize, reqVO.getSize())
                 .eqIfPresent(SpecimenInfoDO::getWeight, reqVO.getWeight())
                 .eqIfPresent(SpecimenInfoDO::getSource, reqVO.getSource())
-                .eqIfPresent(SpecimenInfoDO::getProvider, reqVO.getProvider())
-                .eqIfPresent(SpecimenInfoDO::getPurpose, reqVO.getPurpose())
-                .eqIfPresent(SpecimenInfoDO::getDescription, reqVO.getDescription())
+                .likeIfPresent(SpecimenInfoDO::getProvider, reqVO.getProvider())
+                .likeIfPresent(SpecimenInfoDO::getPurpose, reqVO.getPurpose())
+                .likeIfPresent(SpecimenInfoDO::getDescription, reqVO.getDescription())
                 .eqIfPresent(SpecimenInfoDO::getCollectionStatus, reqVO.getCollectionStatus())
-                .eqIfPresent(SpecimenInfoDO::getNotes, reqVO.getNotes())
+                .likeIfPresent(SpecimenInfoDO::getNotes, reqVO.getNotes())
                 .likeIfPresent(SpecimenInfoDO::getImageName, reqVO.getImageName())
                 .eqIfPresent(SpecimenInfoDO::getImagePath, reqVO.getImagePath())
                 .eqIfPresent(SpecimenInfoDO::getOperator, reqVO.getOperator())
@@ -53,7 +53,7 @@ public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
                 .betweenIfPresent(SpecimenInfoDO::getFallTime, reqVO.getFallTime())
                 .betweenIfPresent(SpecimenInfoDO::getCreateTime, reqVO.getCreateTime())
                 .betweenIfPresent(SpecimenInfoDO::getAcquisitionTime, reqVO.getAcquisitionTime())
-                .eqIfPresent(SpecimenInfoDO::getDeletedReason, reqVO.getDeletedReason())
+                .likeIfPresent(SpecimenInfoDO::getDeletedReason, reqVO.getDeletedReason())
                 .orderByDesc(SpecimenInfoDO::getId));
     }
 
@@ -168,7 +168,4 @@ public interface SpecimenInfoMapper extends BaseMapperX<SpecimenInfoDO> {
      */
     void markAsDeletedById(@Param("id") Integer id);
 
-
-
-
 }

+ 7 - 7
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/mysql/specimenoutbound/SpecimenOutboundMapper.java

@@ -21,20 +21,20 @@ public interface SpecimenOutboundMapper extends BaseMapperX<SpecimenOutboundDO>
 
     default PageResult<SpecimenOutboundDO> selectPage(SpecimenOutboundPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<SpecimenOutboundDO>()
-                .eqIfPresent(SpecimenOutboundDO::getInfoId, reqVO.getInfoId())
+                .likeIfPresent(SpecimenOutboundDO::getInfoId, reqVO.getInfoId())
                 .likeIfPresent(SpecimenOutboundDO::getChinese, reqVO.getChinese())
-                .eqIfPresent(SpecimenOutboundDO::getNumber, reqVO.getNumber())
+                .likeIfPresent(SpecimenOutboundDO::getNumber, reqVO.getNumber())
                 .likeIfPresent(SpecimenOutboundDO::getApplicantName, reqVO.getApplicantName())
                 .betweenIfPresent(SpecimenOutboundDO::getApplicationDate, reqVO.getApplicationDate())
-                .eqIfPresent(SpecimenOutboundDO::getApplicationUsage, reqVO.getApplicationUsage())
-                .eqIfPresent(SpecimenOutboundDO::getAttachments, reqVO.getAttachments())
+                .likeIfPresent(SpecimenOutboundDO::getApplicationUsage, reqVO.getApplicationUsage())
+                .likeIfPresent(SpecimenOutboundDO::getAttachments, reqVO.getAttachments())
                 .eqIfPresent(SpecimenOutboundDO::getStatus, reqVO.getStatus())
-                .eqIfPresent(SpecimenOutboundDO::getRemarks, reqVO.getRemarks())
+                .likeIfPresent(SpecimenOutboundDO::getRemarks, reqVO.getRemarks())
                 .betweenIfPresent(SpecimenOutboundDO::getOutgoingTime, reqVO.getOutgoingTime())
-                .eqIfPresent(SpecimenOutboundDO::getSpecimenCondition, reqVO.getSpecimenCondition())
+                .likeIfPresent(SpecimenOutboundDO::getSpecimenCondition, reqVO.getSpecimenCondition())
                 .betweenIfPresent(SpecimenOutboundDO::getCreateTime, reqVO.getCreateTime())
                 .eqIfPresent(SpecimenOutboundDO::getSampleStatus, reqVO.getSampleStatus())
-                .eqIfPresent(SpecimenOutboundDO::getProcessInstanceId, reqVO.getProcessInstanceId())
+                .likeIfPresent(SpecimenOutboundDO::getProcessInstanceId, reqVO.getProcessInstanceId())
                 .eqIfPresent(SpecimenOutboundDO::getOperator, reqVO.getOperator())
                 .eqIfPresent(SpecimenOutboundDO::getReturner, reqVO.getReturner())
                 .eqIfPresent(SpecimenOutboundDO::getReceiver, reqVO.getReceiver())

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

@@ -68,7 +68,6 @@ public interface SpecimenInfoService {
      * @return 导入结果
      */
     SpecimenImportRespVO importSpecimenList(List<SpecimenImportExcelVO> importSpecimens, boolean isUpdateSupport);
-
     /**
      * 批量导入标本图片
      *
@@ -111,17 +110,6 @@ public interface SpecimenInfoService {
      */
     List<Map<String, Object>> getYearlySpecimenSourceStatistics();
 
-
-    //不好用,准备废弃
-    /**
-     * 历年标本来源增减统计
-     *
-     * @param year 年份
-     * @return 标本来源统计信息列表
-     */
-    List<SpecimenInfoDO> getSpecimenSourceStatistics(int year);
-
-
     //标本库管理
     //实现对标本操作记录进行追溯查看,包括入库记录、编辑记录、出库记录、回库记录等。
     /**

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

@@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimenoutbound.SpecimenOutboundDO;
 import cn.iocoder.yudao.module.museums.dal.mysql.specimenoutbound.SpecimenOutboundMapper;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.springframework.stereotype.Service;
@@ -169,8 +171,75 @@ 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();
+//        try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
+//            ZipEntry entry;
+//            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);
+//                        }
+//                    }
+//                }
+//            }
+//            // 处理每个图片文件
+//            File[] imageFiles = tempDir.listFiles();
+//            if (imageFiles != null) {
+//                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()));
+//                        // 获取当前的图片路径
+//                        Set<String> imagePathsSet = new HashSet<>();
+//                        String existingImagePaths = specimenInfo.getImagePath();
+//
+//                        // 如果 existingImagePaths 为空或仅包含空白字符,则不添加
+//                        if (existingImagePaths != null && !existingImagePaths.trim().isEmpty()) {
+//                            Collections.addAll(imagePathsSet, existingImagePaths.split(","));
+//                        }
+//
+//                        // 检查 imagePath 是否有效
+//                        if (imagePath != null && !imagePath.trim().isEmpty()) {
+//                            imagePathsSet.add(imagePath);
+//                        }
+//
+//                        // 转换回字符串,避免前面出现多余的逗号
+//                        String newImagePaths = String.join(",", imagePathsSet);
+//                        specimenInfo.setImagePath(newImagePaths);
+//
+//                        updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
+//                    }
+//                }
+//            }
+//        }
+//        // 清理临时文件
+//        FileUtils.deleteDirectory(tempDir);
+//        return "标本图片导入成功";
+//    }
+
     @Override
-    @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
+    @Transactional(rollbackFor = Exception.class)
     public String importSpecimenImages(MultipartFile file) throws Exception {
         // 校验文件类型
         if (!file.getOriginalFilename().endsWith(".zip")) {
@@ -194,6 +263,7 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                     }
                 }
             }
+
             // 处理每个图片文件
             File[] imageFiles = tempDir.listFiles();
             if (imageFiles != null) {
@@ -203,39 +273,64 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                         System.err.println("无效的图片格式: " + imageName);
                         continue;
                     }
+
                     // 根据图片名称查找对应的标本
                     SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageNames(imageName);
                     if (specimenInfo != null) {
-                        // 上传图片并获取URL
+                        // 上传图片并获取 URL
                         String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
+
                         // 获取当前的图片路径
-                        Set<String> imagePathsSet = new HashSet<>();
+                        List<String> imagePathsList = new ArrayList<>();
                         String existingImagePaths = specimenInfo.getImagePath();
 
-                        // 如果 existingImagePaths 为空或仅包含空白字符,则不添
+                        // 如果 existingImagePaths 为空,则加入已存在路径
                         if (existingImagePaths != null && !existingImagePaths.trim().isEmpty()) {
-                            Collections.addAll(imagePathsSet, existingImagePaths.split(","));
+                            // 解析已存在的 JSON 字符串
+                            try {
+                                List<String> existingPaths = new ObjectMapper().readValue(existingImagePaths, new TypeReference<List<String>>() {});
+                                imagePathsList.addAll(existingPaths);
+                            } catch (Exception e) {
+                                System.err.println("解析现有路径失败: " + e.getMessage());
+                            }
                         }
 
                         // 检查 imagePath 是否有效
                         if (imagePath != null && !imagePath.trim().isEmpty()) {
-                            imagePathsSet.add(imagePath);
+                            // 直接添加 URL
+                            imagePathsList.add(imagePath.trim());  // 修剪空格
                         }
 
-                        // 转换回字符串,避免前面出现多余的逗号
-                        String newImagePaths = String.join(",", imagePathsSet);
-                        specimenInfo.setImagePath(newImagePaths);
+                        // 生成有效的 JSON
+                        String newImagePathsJson = convertListToJson(imagePathsList);
+                        specimenInfo.setImagePath(newImagePathsJson);
 
+                        // 更新数据库中的标本信息
                         updateSpecimenInfo(BeanUtils.toBean(specimenInfo, SpecimenInfoSaveReqVO.class));
                     }
                 }
             }
+        } finally {
+            // 清理临时文件
+            FileUtils.deleteDirectory(tempDir);
         }
-        // 清理临时文件
-        FileUtils.deleteDirectory(tempDir);
         return "标本图片导入成功";
     }
 
+    // 将 List 转换为 JSON 格式的字符串
+    private String convertListToJson(List<String> list) {
+        try {
+            ObjectMapper objectMapper = new ObjectMapper();
+            return objectMapper.writeValueAsString(list);  // 直接将列表转换为 JSON
+        } catch (JsonProcessingException e) {
+            System.err.println("转换 List 到 JSON 失败: " + e.getMessage());
+            return "[]"; // 返回空数组的 JSON 表示
+        }
+    }
+
+
+
+
     //工作台
     //根据入库的登记情况统计本年标本入库信息
     @Override
@@ -370,14 +465,6 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         }
     }
 
-
-    //根据入馆凭证中标本来源的登记情况统计
-    //不好用,准备废弃
-    @Override
-    public List<SpecimenInfoDO> getSpecimenSourceStatistics(int year) {
-        return specimenInfoMapper.selectSpecimenSourceStatistics(year);
-    }
-
     //标本库管理
     //实现对标本操作记录进行追溯查看,包括入库记录、编辑记录、出库记录、回库记录等。
     @Override