Ver Fonte

按照标本类型统计库存数3.0

hyy há 8 meses atrás
pai
commit
6b35d37f27

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

@@ -142,30 +142,50 @@ public class SpecimenInfoController {
     }
 
 
-    @PostMapping("/import-specimen")
-    @Operation(summary = "导入标本")
-    @Parameters({
-            @Parameter(name = "file", description = "Excel 文件", required = true),
-            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
-    })
-    @PreAuthorize("@ss.hasPermission('museums:specimen-info:import')")
-    public CommonResult<SpecimenImportRespVO> importSpecimenExcel(@RequestParam("file") MultipartFile file,
-                                                                  @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
-        List<SpecimenImportExcelVO> list = ExcelUtils.read(file, SpecimenImportExcelVO.class);
-        return success(specimenInfoService.importSpecimenList(list, updateSupport));
-    }
+//    @PostMapping("/import-specimen")
+//    @Operation(summary = "导入标本")
+//    @Parameters({
+//            @Parameter(name = "file", description = "Excel 文件", required = true),
+//            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
+//    })
+//    @PreAuthorize("@ss.hasPermission('museums:specimen-info:import')")
+//    public CommonResult<SpecimenImportRespVO> importSpecimenExcel(@RequestParam("file") MultipartFile file,
+//                                                                  @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
+//        List<SpecimenImportExcelVO> list = ExcelUtils.read(file, SpecimenImportExcelVO.class);
+//        return success(specimenInfoService.importSpecimenList(list, updateSupport));
+//    }
+//
+//    @PostMapping("/import-specimen-images")
+//    @Operation(summary = "导入标本图片")
+//    @Parameters({
+//            @Parameter(name = "file", description = "压缩包文件", required = true)
+//    })
+//    @PreAuthorize("@ss.hasPermission('museums:specimen-info:import-images')")
+//    public CommonResult<String> importSpecimenImages(@RequestParam("file") MultipartFile file) throws Exception {
+//        // 解压文件并处理图片
+//        return success(specimenInfoService.importSpecimenImages(file));
+//    }
 
-    @PostMapping("/import-specimen-images")
-    @Operation(summary = "导入标本图片")
-    @Parameters({
-            @Parameter(name = "file", description = "压缩包文件", required = true)
-    })
-    @PreAuthorize("@ss.hasPermission('museums:specimen-info:import-images')")
-    public CommonResult<String> importSpecimenImages(@RequestParam("file") MultipartFile file) throws Exception {
-        // 解压文件并处理图片
-        return success(specimenInfoService.importSpecimenImages(file));
-    }
+//    @PostMapping("/import-specimen-data")
+//    @Operation(summary = "导入标本及其图片")
+//    @Parameters({
+//            @Parameter(name = "excelFile", description = "Excel 文件", required = true),
+//            @Parameter(name = "imageFile", description = "压缩包文件", required = true),
+//            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
+//    })
+//    @PreAuthorize("@ss.hasPermission('museums:specimen-info:import')")
+//    public CommonResult<String> importSpecimenData(@RequestParam("excelFile") MultipartFile excelFile,
+//                                                   @RequestParam("imageFile") MultipartFile imageFile,
+//                                                   @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) {
+//        try {
+//            specimenInfoService.importSpecimenData(excelFile, imageFile, updateSupport);
+//            return CommonResult.success("标本及图片导入成功");
+//        } catch (Exception e) {
+//            return CommonResult.error(500, "导入过程中发生错误: " + e.getMessage());
+//        }
+//    }
 
+    //测试
     @PostMapping("/import-specimen-data")
     @Operation(summary = "导入标本及其图片")
     @Parameters({
@@ -263,15 +283,21 @@ public class SpecimenInfoController {
 
 
 
-
     //根据出、回、入库的登记信息统计本馆标本历年增减情况。
+//    @GetMapping("/statistics/yearly")
+//    @Operation(summary = "根据出、回、入库登记统计标本历年增减情况")
+//    public CommonResult<Map<Integer, Map<String, Integer>>> getYearlySpecimenStatistics() {
+//        Map<Integer, Map<String, Integer>> yearlyStatistics = specimenInfoService.getYearlySpecimenStatistics();
+//        return CommonResult.success(yearlyStatistics);
+//    }
     @GetMapping("/statistics/yearly")
     @Operation(summary = "根据出、回、入库登记统计标本历年增减情况")
-    public CommonResult<Map<Integer, Map<String, Integer>>> getYearlySpecimenStatistics() {
-        Map<Integer, Map<String, Integer>> yearlyStatistics = specimenInfoService.getYearlySpecimenStatistics();
+    public CommonResult<Map<String, Object>> getYearlySpecimenStatistics() {
+        Map<String, Object> yearlyStatistics = specimenInfoService.getYearlySpecimenStatistics();
         return CommonResult.success(yearlyStatistics);
     }
 
+
     //根据入馆凭证中标本来源的登记情况统计
     @GetMapping("/statistics/source")
     @Operation(summary = "根据标本来源统计历年标本登记情况")

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

@@ -52,6 +52,7 @@ public class SpecimenInfoDO extends BaseDO {
     /**
      * 存放位置
      */
+
     private String storageLocation;
     /**
      * 中文名称
@@ -134,7 +135,8 @@ public class SpecimenInfoDO extends BaseDO {
     /**
      * 图片路径
      */
-    private String imagePath;
+//    private String imagePath;
+    List<String> imagePath;
     /**
      * 入库操作员
      */

+ 5 - 0
yudao-module-museums/yudao-module-museums-biz/src/main/java/cn/iocoder/yudao/module/museums/dal/dataobject/specimenoutbound/SpecimenOutboundDO.java

@@ -110,22 +110,27 @@ public class SpecimenOutboundDO extends BaseDO {
     /**
      * 存放位置
      */
+    @TableField(exist = false)
     private String storageLocation;
     /**
      * 中文名称
      */
+    @TableField(exist = false)
     private String chineseName;
     /**
      * 图片路径
      */
+    @TableField(exist = false)
     private String imagePath;
     /**
      * 标本类型
      */
+    @TableField(exist = false)
     private Integer specimenType;
     /**
      * 标本编号
      */
+    @TableField(exist = false)
     private String specimenNumber;
 
 }

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

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.museums.controller.admin.specimeninfo.vo.*;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimeninfo.SpecimenInfoDO;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.museums.dal.dataobject.specimenoutbound.SpecimenOutboundDO;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -62,17 +63,21 @@ public interface SpecimenInfoService {
      */
     SpecimenImportRespVO importSpecimenList(List<SpecimenImportExcelVO> importSpecimens, boolean isUpdateSupport);
 
-    /**
-     * 批量导入标本图片
-     *
-     * @param file 压缩包文件
-     * @return 导入结果
-     */
-    String importSpecimenImages(MultipartFile file) throws Exception;
+//    /**
+//     * 批量导入标本图片
+//     *
+//     * @param file 压缩包文件
+//     * @return 导入结果
+//     */
+//    String importSpecimenImages(MultipartFile file) throws Exception;
 
     void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception;
 
     //工作台
+
+    @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
+    void importSpecimenImages(MultipartFile file, List<String> createdSpecimens, List<String> updatedSpecimens) throws Exception;
+
     /**
      * 统计本年标本入库信息
      *
@@ -99,7 +104,9 @@ public interface SpecimenInfoService {
      *
      * @return 年份与标本统计信息的映射
      */
-    Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics();
+//    Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics();
+
+    Map <String, Object> getYearlySpecimenStatistics();
     /**
      * 根据标本来源统计历年标本登记情况
      *

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

@@ -13,7 +13,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.io.*;
-import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.util.*;
 import java.util.zip.ZipEntry;
@@ -29,7 +28,6 @@ import org.springframework.web.multipart.MultipartFile;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.*;
-import cn.hutool.core.io.IoUtil;
 
 /**
  * 标本管理 Service 实现类
@@ -151,13 +149,96 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         return imageName != null && imageName.matches(".*\\.(jpg|jpeg|png|gif)$"); // 检查格式
     }
 
+//    @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; // 或者 throw new Exception("无效的图片格式: " + imageName);
+//                }
+//                // 根据图片名称查找对应的标本
+//                SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageName(imageName);
+//                if (specimenInfo != null) {
+//                    // 上传图片并获取URL
+//                    String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
+//                    // 更新标本信息中的图片路径
+//                    specimenInfo.setImagePath(imagePath);
+//                    specimenInfoMapper.updateById(specimenInfo);
+//                }
+//            }
+//        }
+//
+//        // 清理临时文件
+//        FileUtils.deleteDirectory(tempDir);
+//        return "标本图片导入成功";
+//    }
+
+//    @Override
+//    @Transactional(rollbackFor = Exception.class) // 事务管理
+//    public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
+//        // 1. 导入标本
+//        List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
+//        SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
+//
+//        // 2. 导入图片
+//        String imageImportResult = importSpecimenImages(imageFile);
+//
+//        // 可以根据需要记录导入结果
+//        System.out.println("标本导入结果: " + importRespVO);
+//        System.out.println("标本图片导入结果: " + imageImportResult);
+//    }
+
+    //测试
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
+    public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
+        // 1. 导入标本
+        List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
+        SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
+
+        // 2. 导入图片
+        importSpecimenImages(imageFile, importRespVO.getCreateSpecimenNumbers(), importRespVO.getUpdateSpecimenNumbers());
+
+        // 可以根据需要记录导入结果
+        System.out.println("标本导入结果: " + importRespVO);
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
-    public String importSpecimenImages(MultipartFile file) throws Exception {
+    public void importSpecimenImages(MultipartFile file, List<String> createdSpecimens, List<String> updatedSpecimens) 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())) {
@@ -176,15 +257,15 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                 }
             }
         }
+
         // 处理每个图片文件
         File[] imageFiles = tempDir.listFiles();
         if (imageFiles != null) {
             for (File imageFile : imageFiles) {
                 String imageName = imageFile.getName();
                 if (!isValidImageName(imageName)) {
-                    // 如果不符合格式,抛出异常或记录日志
                     System.err.println("无效的图片格式: " + imageName);
-                    continue; // 或者 throw new Exception("无效的图片格式: " + imageName);
+                    continue;
                 }
                 // 根据图片名称查找对应的标本
                 SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageName(imageName);
@@ -192,33 +273,28 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
                     // 上传图片并获取URL
                     String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
                     // 更新标本信息中的图片路径
-                    specimenInfo.setImagePath(imagePath);
-                    specimenInfoMapper.updateById(specimenInfo);
+                    updateSpecimenImages(specimenInfo, imagePath);
                 }
             }
         }
 
         // 清理临时文件
         FileUtils.deleteDirectory(tempDir);
-        return "标本图片导入成功";
     }
 
-    @Override
-    @Transactional(rollbackFor = Exception.class) // 事务管理
-    public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
-        // 1. 导入标本
-        List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
-        SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
-
-        // 2. 导入图片
-        String imageImportResult = importSpecimenImages(imageFile);
-
-        // 可以根据需要记录导入结果
-        System.out.println("标本导入结果: " + importRespVO);
-        System.out.println("标本图片导入结果: " + imageImportResult);
+    private void updateSpecimenImages(SpecimenInfoDO specimenInfo, String imagePath) {
+        // 假设 SpecimenInfoDO 有一个 List<String> 类型的 imagePaths 字段
+        List<String> imagePaths = specimenInfo.getImagePath(); // 获取现有的图片路径
+        if (imagePaths == null) {
+            imagePaths = new ArrayList<>();
+        }
+        imagePaths.add(imagePath); // 添加新图片路径
+        specimenInfo.setImagePath(imagePaths); // 更新标本对象
+        specimenInfoMapper.updateById(specimenInfo); // 更新数据库
     }
 
 
+
     //工作台
     //根据入库的登记情况统计本年标本入库信息
     @Override
@@ -238,16 +314,68 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
 
 
     //根据出、回、入库登记统计标本历年增减情况
+//    @Override
+//    public Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics() {
+//        // 年份与标本统计信息的映射
+//        Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
+//
+//        // 获取入库记录
+//        List<SpecimenInfoDO> inStockRecords = specimenInfoMapper.getInStockRecords();
+//        if (inStockRecords == null) {
+//            inStockRecords = new ArrayList<>(); // 初始化为空列表
+//        }
+//        for (SpecimenInfoDO record : inStockRecords) {
+//            if (record.getCreateTime() != null) { // 检查时间字段
+//                int year = record.getCreateTime().getYear(); // 获取年份
+//                yearlyDataMap.putIfAbsent(year, new HashMap<>());
+//                yearlyDataMap.get(year).put("inStockCount", yearlyDataMap.get(year).getOrDefault("inStockCount", 0) + 1);
+//            }
+//        }
+//
+//        // 获取出库记录
+//        List<SpecimenOutboundDO> outboundRecords = specimenOutboundMapper.getOutboundRecords();
+//        if (outboundRecords == null) {
+//            outboundRecords = new ArrayList<>(); // 初始化为空列表
+//        }
+//        for (SpecimenOutboundDO record : outboundRecords) {
+//            if (record.getOutgoingTime() != null) { // 检查时间字段
+//                int year = record.getOutgoingTime().getYear(); // 获取年份
+//                yearlyDataMap.putIfAbsent(year, new HashMap<>());
+//                yearlyDataMap.get(year).put("outStockCount", yearlyDataMap.get(year).getOrDefault("outStockCount", 0) + 1);
+//            }
+//        }
+//
+//        // 获取回库记录
+//        List<SpecimenOutboundDO> inboundRecords = specimenOutboundMapper.getOutboundRecords();
+//        if (inboundRecords == null) {
+//            inboundRecords = new ArrayList<>(); // 初始化为空列表
+//        }
+//        for (SpecimenOutboundDO record : inboundRecords) {
+//            if (record.getReturnDate() != null) { // 检查时间字段
+//                int year = record.getReturnDate().getYear(); // 获取年份
+//                yearlyDataMap.putIfAbsent(year, new HashMap<>());
+//                yearlyDataMap.get(year).put("returnCount", yearlyDataMap.get(year).getOrDefault("returnCount", 0) + 1);
+//            }
+//        }
+//
+//        return yearlyDataMap;
+//    }
+
     @Override
-    public Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics() {
-        // 年份与标本统计信息的映射
-        Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
+    public Map<String, Object> getYearlySpecimenStatistics() {
+        // 创建一个列表来存放每年的统计数据
+        List<Map<String, Object>> yearlyStatisticsList = new ArrayList<>();
 
         // 获取入库记录
         List<SpecimenInfoDO> inStockRecords = specimenInfoMapper.getInStockRecords();
         if (inStockRecords == null) {
             inStockRecords = new ArrayList<>(); // 初始化为空列表
         }
+
+        // 用于存储每年的统计数据
+        Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
+
+        // 统计入库数量
         for (SpecimenInfoDO record : inStockRecords) {
             if (record.getCreateTime() != null) { // 检查时间字段
                 int year = record.getCreateTime().getYear(); // 获取年份
@@ -261,6 +389,8 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         if (outboundRecords == null) {
             outboundRecords = new ArrayList<>(); // 初始化为空列表
         }
+
+        // 统计出库数量
         for (SpecimenOutboundDO record : outboundRecords) {
             if (record.getOutgoingTime() != null) { // 检查时间字段
                 int year = record.getOutgoingTime().getYear(); // 获取年份
@@ -274,6 +404,8 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
         if (inboundRecords == null) {
             inboundRecords = new ArrayList<>(); // 初始化为空列表
         }
+
+        // 统计回库数量
         for (SpecimenOutboundDO record : inboundRecords) {
             if (record.getReturnDate() != null) { // 检查时间字段
                 int year = record.getReturnDate().getYear(); // 获取年份
@@ -282,9 +414,24 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
             }
         }
 
-        return yearlyDataMap;
+        // 将统计结果转化为列表格式
+        for (Map.Entry<Integer, Map<String, Integer>> entry : yearlyDataMap.entrySet()) {
+            Map<String, Object> yearData = new HashMap<>();
+            yearData.put("year", entry.getKey().toString());
+            yearData.putAll(entry.getValue()); // 添加对应的数量
+            yearlyStatisticsList.add(yearData);
+        }
+
+        // 构建最终的返回结果
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("code", 200);
+        resultMap.put("data", yearlyStatisticsList);
+        resultMap.put("msg", "各年入库出库回库标本数");
+
+        return resultMap;
     }
 
+
     @Override
     public Map<Integer, Map<String, Integer>> getYearlySpecimenSourceStatistics() {
         // 年份与标本来源统计信息的映射