فهرست منبع

1、添加月累计的数值计算及样式组装 2、多sheet页导入无法关闭文件流的问题处理

JammeyJiang 1 ماه پیش
والد
کامیت
2008351c9d

+ 74 - 0
src/main/java/com/kcim/service/impl/CostDepartmentProfitServiceImpl.java

@@ -2081,6 +2081,7 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
                 throw new CostException("开始日期不能大于结束日期");
             }
             List<String> intervalMonthList = DateUtils.getIntervalMonthList(date, endDate);
+            List<CostProfitVo> allCostProfitVo=new ArrayList<>();
             if (!CollectionUtils.isEmpty(intervalMonthList)) {
                 for (String computeDates : intervalMonthList) {
                     Integer year = ComputeDateUtils.getComputeYear(computeDates);
@@ -2129,6 +2130,8 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
                             profitVo.setPermil(NumberConstant.ONE);
                         }
                     });
+                    //记录所有月份的科室损益数据
+                    allCostProfitVo.addAll(costProfitVos);
                     Map<Long, List<CostProfitVo>> collect = costProfitVos.stream().collect(Collectors.groupingBy(CostProfitVo::getReportParentId));
                     List<CostProfitVo> costProfitParentVos = collect.get(NumberConstant.ZERO_L);
                     collect.remove(NumberConstant.ZERO_L);
@@ -2146,6 +2149,14 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
                     response.setProfitVoList(costProfitParentVos);
                     responses.add(response);
                 }
+                //获取月度汇总数据
+                List<CostProfitVo> costProfitVos = generateSummaryForMultipleMonths(allCostProfitVo);
+                if(!CollectionUtils.isEmpty(costProfitVos)){
+                    BatchCostProfitResponse response = new BatchCostProfitResponse();
+                    response.setComputeDate(String.format("%s至%s", beginComputeDate, endComputeDate));
+                    response.setProfitVoList(costProfitVos);
+                    responses.add(NumberConstant.ZERO,response);
+                }
                 return responses;
 
             } else {
@@ -2154,6 +2165,69 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
         }
     }
 
+    /**
+     * 获取树状结构的科室损益数据
+     * @param costProfitVos
+     * @return
+     */
+    public List<CostProfitVo> getCostProfitVoTree(List<CostProfitVo> costProfitVos){
+        // 参数校验
+        if (CollectionUtils.isEmpty(costProfitVos)) {
+            return Collections.emptyList();
+        }
+        Map<Long, List<CostProfitVo>> collect = costProfitVos.stream().collect(Collectors.groupingBy(CostProfitVo::getReportParentId));
+        List<CostProfitVo> costProfitParentVos = collect.get(NumberConstant.ZERO_L);
+        collect.remove(NumberConstant.ZERO_L);
+        for (CostProfitVo costProfitVo : costProfitParentVos) {
+            List<CostProfitVo> costProfitVo1 = collect.get(costProfitVo.getReportId());
+            if (!CollectionUtils.isEmpty(costProfitVo1)) {
+                costProfitVo.setChildren(setChildren(costProfitVo1, collect));
+            }
+        }
+        if (!CollectionUtils.isEmpty(costProfitParentVos)) {
+            costProfitParentVos.sort(Comparator.comparing(CostProfitVo::getSort, Comparator.nullsLast(Integer::compareTo)));
+        }
+        return  costProfitParentVos;
+    }
+
+    /**
+     * 生成多月份汇总的科室损益数据
+     *
+     * @param allCostProfitVo 原始数据列表
+     * @return 汇总后的科室损益数据
+     */
+    private List<CostProfitVo> generateSummaryForMultipleMonths(List<CostProfitVo> allCostProfitVo){
+        // 参数校验
+        if (CollectionUtils.isEmpty(allCostProfitVo)) {
+            return Collections.emptyList();
+        }
+        List<CostProfitVo> profitVoList=new ArrayList<>() ;
+        Map<Long, List<CostProfitVo>> reportGroup = allCostProfitVo.stream().collect(Collectors.groupingBy(CostProfitVo::getReportId));
+        reportGroup.forEach((reportId, profitVos) -> {
+            CostProfitVo costProfitVo = BeanUtil.convertObj(profitVos.get(NumberConstant.ZERO), CostProfitVo.class);
+            BigDecimal totalAmount = profitVos.stream().map(vo -> Optional.ofNullable(vo.getAmount()).orElse(BigDecimal.ZERO))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal totalBudgetAmount = profitVos.stream().map(vo -> Optional.ofNullable(vo.getBudgetAmount()).orElse(BigDecimal.ZERO))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal totalPrevPeriodAmount = profitVos.stream().map(vo -> Optional.ofNullable(vo.getPrevPeriodAmount()).orElse(BigDecimal.ZERO))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal totalSamePeriodAmount = profitVos.stream().map(vo -> Optional.ofNullable(vo.getSamePeriodAmount()).orElse(BigDecimal.ZERO))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            costProfitVo.setAmount(totalAmount);
+            costProfitVo.setBudgetAmount(totalBudgetAmount);
+            costProfitVo.setPrevPeriodAmount(totalPrevPeriodAmount);
+            costProfitVo.setSamePeriodAmount(totalSamePeriodAmount);
+            costProfitVo.setCompletionRate(calculateRate(costProfitVo.getAmount(), costProfitVo.getBudgetAmount()));
+            costProfitVo.setMomRate(calculateRate(costProfitVo.getAmount().subtract(costProfitVo.getPrevPeriodAmount()), costProfitVo.getPrevPeriodAmount()));
+            costProfitVo.setYoyRate(calculateRate(costProfitVo.getAmount().subtract(costProfitVo.getSamePeriodAmount()), costProfitVo.getSamePeriodAmount()));
+            profitVoList.add(costProfitVo);
+        });
+        //转成树状结构
+        List<CostProfitVo> costProfitVoTree = getCostProfitVoTree(profitVoList);
+        return costProfitVoTree;
+    }
+
+
     @Override
     public Object getRedirectData(String computeDate, Long reportId, Long hospId, String reportType, String responsibilityCode) {
         //查询报表项目

+ 27 - 15
src/main/java/com/kcim/service/impl/KpiComputeImportServiceImpl.java

@@ -38,6 +38,8 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
@@ -167,7 +169,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
             assert fileName != null;
             File file1 = new File(fileName);
             FileUtils.copyInputStreamToFile(file.getInputStream(), file1);
-            String excelSql = readExcelSql(file1, tableName, id,computeDate);
+            String excelSql = readExcelSql(file1, tableName, id, computeDate);
             SqlRunner sqlRunner = new SqlRunner(getConnection());
             sqlRunner.insert(excelSql);
 
@@ -248,8 +250,14 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
         String uploadFileUrl = uploadFile(file, fileName);
         List<SheetImportResultVO> sheetResults = new ArrayList<>();
         try {
-            File tempFile = File.createTempFile("excel-", ".tmp");
-            file.transferTo(tempFile);
+            // 使用系统临时目录显式创建临时文件
+            File tempDir = new File(System.getProperty("java.io.tmpdir"));
+            File tempFile = new File(tempDir, "excel-" + UUID.randomUUID() + ".tmp");
+
+            // 确保文件存在并正确关闭流
+            try (InputStream inputStream = file.getInputStream()) {
+                Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+            }
 
             try (Workbook workbook = WorkbookFactory.create(tempFile)) {
                 for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
@@ -265,7 +273,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                             .findFirst();
 
                     if (!mapping.isPresent()) {
-                        log.warn("未找到sheet页 '{}' 对应的数据表配置,跳过导入", sheetName);
+                        log.warn("未找到sheet页 '{%s}' 对应的数据表配置,跳过导入", sheetName);
                         resultItem.setSuccess(false);
                         resultItem.setErrorMessage("未找到对应的数据库表配置");
                         sheetResults.add(resultItem);
@@ -296,28 +304,32 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                         resultItem.setImportTime(kpiComputeImport.getCreateTime());
 
                     } catch (Exception e) {
-                        log.error(String.format("sheet页 '{ %s}' 导入失败: %s", sheetName, e.getMessage()));
+                        log.error(String.format("sheet页 '%s' 导入失败: %s", sheetName, e.getMessage()));
                         resultItem.setSuccess(false);
                         resultItem.setErrorMessage("导入失败: " + e.getMessage());
                     }
                     sheetResults.add(resultItem);
                 }
+            } finally {
+                // 删除临时文件
+                if (tempFile.exists()) {
+                    tempFile.delete();
+                }
             }
-            // 删除临时文件
-            tempFile.delete();
         } catch (Exception e) {
-            throw new RuntimeException("导入发生异常" + e.getMessage());
+            throw new RuntimeException("导入发生异常: " + e.getMessage(), e);
         }
         return sheetResults;
     }
 
+
     @SneakyThrows
     private void insertExcelDataForSheet(Integer id, String tableName, MultipartFile file, String fileName, String computeDate, Sheet sheet) {
         // 将MultipartFile转换为InputStream
         InputStream inputStream = file.getInputStream();
 
         // 这里假设有一个方法可以从给定的InputStream和sheet对象中读取SQL语句
-        List<String> excelSql = readExcelSqlFromSheet(inputStream, sheet, tableName, id,computeDate);
+        List<String> excelSql = readExcelSqlFromSheet(inputStream, sheet, tableName, id, computeDate);
 
         // 执行SQL插入操作
         SqlRunner sqlRunner = new SqlRunner(getConnection());
@@ -329,7 +341,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
         String updateSql = "UPDATE `" + tableName + "` SET " +
                 "`create_user` = '" + UserContext.getCurrentUser().getId() + "', " +
                 "`create_time` = '" + DateUtils.formatDate2String(new Date()) + "' " +
-                "WHERE `import_id` = '"+id+"';";
+                "WHERE `import_id` = '" + id + "';";
         sqlRunner.run(updateSql);
     }
 
@@ -391,7 +403,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
 
             // 添加 import_id 和 hosp_id
             valueSb.append(", ").append(id)
-                   .append(", ").append(UserContext.getCurrentLoginHospId());
+                    .append(", ").append(UserContext.getCurrentLoginHospId());
 
             // 如果字段中没有 compute_date,才手动添加
             if (!hasComputeDateField) {
@@ -518,7 +530,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                     i++;
                 }
                 //组装记录表和hospId
-                setCommonData(id, dataList,computeDate);
+                setCommonData(id, dataList, computeDate);
                 sql = insertFromMap(dataList, tableName);
 
             }
@@ -559,7 +571,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                     }
                     i++;
                 }
-                setCommonData(id, dataList,computeDate);
+                setCommonData(id, dataList, computeDate);
                 sql = insertFromMap(dataList, tableName);
             }
         }
@@ -571,7 +583,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
             dataList.forEach(stringObjectMap -> {
                 stringObjectMap.put("hosp_id", UserContext.getCurrentLoginHospId());
                 //Excel字段里没有传核算年月的,用传入的核算年月
-                if(!stringObjectMap.containsKey("compute_date")) {
+                if (!stringObjectMap.containsKey("compute_date")) {
                     stringObjectMap.put("compute_date", computeDate);
                 }
                 stringObjectMap.put("import_id", id);
@@ -675,5 +687,5 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
     private Connection getConnection() throws ClassNotFoundException, SQLException {
         Class.forName(driver);
         return DriverManager.getConnection(url, username, password);
-    }    
+    }
 }