2 Commity 4266a41c90 ... 3f806d5628

Autor SHA1 Wiadomość Data
  wangyongsheng 3f806d5628 损益计算调整 9 miesięcy temu
  wangyongsheng 6c8cd838da 科室损益excel 行转列 1 rok temu
100 zmienionych plików z 4367 dodań i 837 usunięć
  1. 59 31
      pom.xml
  2. 3 1
      src/main/java/com/kcim/common/constants/SQLParameter.java
  3. 54 0
      src/main/java/com/kcim/common/enums/CustomSqlTypeEnum.java
  4. 5 10
      src/main/java/com/kcim/common/enums/ErrorCodeEnum.java
  5. 19 0
      src/main/java/com/kcim/common/util/ComputeDateUtils.java
  6. 42 0
      src/main/java/com/kcim/common/util/DateUtils.java
  7. 212 0
      src/main/java/com/kcim/common/util/ListUtils.java
  8. 188 0
      src/main/java/com/kcim/common/util/TreeDepthUtil.java
  9. 270 5
      src/main/java/com/kcim/common/util/excel/ExcelPoiUtil.java
  10. 0 1
      src/main/java/com/kcim/common/util/excel/entity/ItemImportEntity.java
  11. 16 0
      src/main/java/com/kcim/dao/mapper/ComputeLastProfitDateMapper.java
  12. 16 0
      src/main/java/com/kcim/dao/mapper/ComputeMedicalDepartmentProfitMapper.java
  13. 1 0
      src/main/java/com/kcim/dao/mapper/CostCostingGroupMapper.java
  14. 7 2
      src/main/java/com/kcim/dao/mapper/CostDepartmentProfitMapper.java
  15. 16 0
      src/main/java/com/kcim/dao/mapper/CostReportIndexMapper.java
  16. 7 0
      src/main/java/com/kcim/dao/mapper/ImportPatientItemMapper.java
  17. 7 1
      src/main/java/com/kcim/dao/mapper/ReportFormMapper.java
  18. 0 2
      src/main/java/com/kcim/dao/model/Accounting.java
  19. 62 60
      src/main/java/com/kcim/dao/model/ComputeDrugCostDetail.java
  20. 74 0
      src/main/java/com/kcim/dao/model/ComputeLastProfitDate.java
  21. 124 0
      src/main/java/com/kcim/dao/model/ComputeMedicalDepartmentProfit.java
  22. 0 1
      src/main/java/com/kcim/dao/model/CostIncomeGroup.java
  23. 10 5
      src/main/java/com/kcim/dao/model/CostReport.java
  24. 88 0
      src/main/java/com/kcim/dao/model/CostReportIndex.java
  25. 4 0
      src/main/java/com/kcim/dao/model/CostShareParam.java
  26. 14 4
      src/main/java/com/kcim/dao/model/ReportForm.java
  27. 8 0
      src/main/java/com/kcim/dao/model/Responsibility.java
  28. 4 0
      src/main/java/com/kcim/dao/model/ResponsibilityDepartment.java
  29. 2 0
      src/main/java/com/kcim/dao/model/dto/CostShareParamEditDto.java
  30. 2 0
      src/main/java/com/kcim/dao/model/dto/CostShareParamSaveDto.java
  31. 4 0
      src/main/java/com/kcim/dao/model/dto/PatientItemDepartmentGroupVo.java
  32. 7 0
      src/main/java/com/kcim/dao/model/dto/ReportFormEditDTO.java
  33. 7 0
      src/main/java/com/kcim/dao/model/dto/ReportFormSaveDTO.java
  34. 9 0
      src/main/java/com/kcim/dao/model/dto/ResponsibilityEditDTO.java
  35. 8 0
      src/main/java/com/kcim/dao/model/dto/ResponsibilitySaveDTO.java
  36. 0 1
      src/main/java/com/kcim/dao/repository/AccountingProductRepository.java
  37. 13 0
      src/main/java/com/kcim/dao/repository/ComputeDrugCostDetailRepository.java
  38. 24 16
      src/main/java/com/kcim/dao/repository/ComputeDrugCostRepository.java
  39. 46 0
      src/main/java/com/kcim/dao/repository/ComputeLastProfitDateRepository.java
  40. 41 0
      src/main/java/com/kcim/dao/repository/ComputeMedicalDepartmentProfitRepository.java
  41. 0 1
      src/main/java/com/kcim/dao/repository/ComputeStandPatientProjectCostDetailRepository.java
  42. 9 0
      src/main/java/com/kcim/dao/repository/CostDepartmentProfitRepository.java
  43. 33 0
      src/main/java/com/kcim/dao/repository/CostReportIndexRepository.java
  44. 15 9
      src/main/java/com/kcim/dao/repository/ImportPatientItemRepository.java
  45. 0 2
      src/main/java/com/kcim/dao/repository/ItemNoValuationDrugMaterialMapRepository.java
  46. 4 0
      src/main/java/com/kcim/endPoint/CenterEndPoint.java
  47. 2 0
      src/main/java/com/kcim/service/AccountingService.java
  48. 2 0
      src/main/java/com/kcim/service/CenterService.java
  49. 41 0
      src/main/java/com/kcim/service/ComputeMedicalDepartmentProfitService.java
  50. 8 0
      src/main/java/com/kcim/service/CostDepartmentProfitService.java
  51. 3 0
      src/main/java/com/kcim/service/HospProfitAndLossService.java
  52. 3 0
      src/main/java/com/kcim/service/ReportFormService.java
  53. 1 0
      src/main/java/com/kcim/service/ReportService.java
  54. 0 1
      src/main/java/com/kcim/service/ResponsibilityService.java
  55. 6 0
      src/main/java/com/kcim/service/SqlService.java
  56. 1 1
      src/main/java/com/kcim/service/impl/AccountingProductServiceImpl.java
  57. 7 0
      src/main/java/com/kcim/service/impl/AccountingServiceImpl.java
  58. 26 8
      src/main/java/com/kcim/service/impl/AllocationServiceImpl.java
  59. 12 7
      src/main/java/com/kcim/service/impl/CenterServiceImpl.java
  60. 430 0
      src/main/java/com/kcim/service/impl/ComputeMedicalDepartmentProfitServiceImpl.java
  61. 10 5
      src/main/java/com/kcim/service/impl/ComputePatientCostServiceImpl.java
  62. 30 24
      src/main/java/com/kcim/service/impl/CostAccountShareServiceImpl.java
  63. 1 48
      src/main/java/com/kcim/service/impl/CostDataServiceImpl.java
  64. 1184 309
      src/main/java/com/kcim/service/impl/CostDepartmentProfitServiceImpl.java
  65. 55 7
      src/main/java/com/kcim/service/impl/CostReportServiceImpl.java
  66. 2 0
      src/main/java/com/kcim/service/impl/CostShareParamServiceImpl.java
  67. 45 53
      src/main/java/com/kcim/service/impl/DrugMaterialCalculateServiceImpl.java
  68. 379 118
      src/main/java/com/kcim/service/impl/HospProfitAndLossServiceImpl.java
  69. 4 2
      src/main/java/com/kcim/service/impl/IncomeCollectionServiceImpl.java
  70. 0 3
      src/main/java/com/kcim/service/impl/PatientItemImportServiceImpl.java
  71. 115 69
      src/main/java/com/kcim/service/impl/ProjectCostServiceImpl.java
  72. 21 0
      src/main/java/com/kcim/service/impl/ReportFormServiceImpl.java
  73. 1 1
      src/main/java/com/kcim/service/impl/ReportRelationServiceImpl.java
  74. 12 4
      src/main/java/com/kcim/service/impl/ReportServiceImpl.java
  75. 11 6
      src/main/java/com/kcim/service/impl/ResponsibilityDepartmentServiceImpl.java
  76. 13 3
      src/main/java/com/kcim/service/impl/ResponsibilityServiceImpl.java
  77. 3 1
      src/main/java/com/kcim/service/impl/ShareParamServiceImpl.java
  78. 66 3
      src/main/java/com/kcim/service/impl/SqlServiceImpl.java
  79. 18 0
      src/main/java/com/kcim/vo/AccountAmountVo.java
  80. 7 0
      src/main/java/com/kcim/vo/AllocationReportVO.java
  81. 2 0
      src/main/java/com/kcim/vo/CenterDepartmentVO.java
  82. 22 0
      src/main/java/com/kcim/vo/CommonResponsibilityReportVo.java
  83. 6 0
      src/main/java/com/kcim/vo/CostAccountShareVO.java
  84. 18 0
      src/main/java/com/kcim/vo/CostProfitRedirectAliasVo.java
  85. 30 0
      src/main/java/com/kcim/vo/CostProfitRedirectDataVo.java
  86. 7 6
      src/main/java/com/kcim/vo/CostProfitVo.java
  87. 9 0
      src/main/java/com/kcim/vo/CostResponsibilityVO.java
  88. 2 0
      src/main/java/com/kcim/vo/CostShareParamVO.java
  89. 1 1
      src/main/java/com/kcim/vo/CostingGroupStartVO.java
  90. 2 0
      src/main/java/com/kcim/vo/DepartVO.java
  91. 27 0
      src/main/java/com/kcim/vo/DepartmentProfitVo.java
  92. 77 2
      src/main/java/com/kcim/vo/HospProfitVO.java
  93. 22 0
      src/main/java/com/kcim/vo/MedicalResponsibilityVo.java
  94. 21 0
      src/main/java/com/kcim/vo/ReportFormCustomVo.java
  95. 34 0
      src/main/java/com/kcim/vo/ReportFormProfitVo.java
  96. 4 0
      src/main/java/com/kcim/vo/ReportFormVO.java
  97. 26 0
      src/main/java/com/kcim/vo/ResponsibilityVo.java
  98. 0 2
      src/main/java/com/kcim/vo/ShareParamCostVo.java
  99. 3 1
      src/main/java/com/kcim/vo/ShareParamProportionVO.java
  100. 1 0
      src/main/java/com/kcim/web/CostCostingCollectionController.java

+ 59 - 31
pom.xml

@@ -200,6 +200,10 @@
                     <artifactId>guava</artifactId>
                     <groupId>com.google.guava</groupId>
                 </exclusion>
+                <exclusion>
+                    <groupId>org.springframework.cloud</groupId>
+                    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
+                </exclusion>
             </exclusions>
         </dependency>
         <!-- 文件上传 -->
@@ -208,40 +212,45 @@
             <artifactId>httpmime</artifactId>
             <version>4.5.7</version>
         </dependency>
-        <!-- POI -->
-        <dependency>
-            <groupId>org.apache.poi</groupId>
-            <artifactId>poi-ooxml</artifactId>
-            <version>4.1.1</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>easyexcel</artifactId>
-            <version>3.2.1</version>
-        </dependency>
-        <!--导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能-->
-        <dependency>
-            <groupId>cn.afterturn</groupId>
-            <artifactId>easypoi-base</artifactId>
-            <version>${easypoi.version}</version>
-        </dependency>
-        <!--耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能-->
         <dependency>
             <groupId>cn.afterturn</groupId>
-            <artifactId>easypoi-web</artifactId>
-            <version>${easypoi.version}</version>
-        </dependency>
-        <!--基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理-->
-        <dependency>
-            <groupId>cn.afterturn</groupId>
-            <artifactId>easypoi-annotation</artifactId>
-            <version>${easypoi.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
-            <version>${nacos.version}</version>
+            <artifactId>easypoi-spring-boot-starter</artifactId>
+            <version>4.4.0</version>
         </dependency>
+        <!-- POI -->
+<!--        <dependency>-->
+<!--            <groupId>org.apache.poi</groupId>-->
+<!--            <artifactId>poi-ooxml</artifactId>-->
+<!--            <version>4.1.1</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba</groupId>-->
+<!--            <artifactId>easyexcel</artifactId>-->
+<!--            <version>3.2.1</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash;导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-base</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash;耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-web</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+<!--        &lt;!&ndash;基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-annotation</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba.cloud</groupId>-->
+<!--            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>-->
+<!--            <version>${nacos.version}</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>io.minio</groupId>
             <artifactId>minio</artifactId>
@@ -254,6 +263,18 @@
             </exclusions>
 
         </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+
         <!--        <dependency>-->
         <!--            <groupId>com.squareup.okhttp3</groupId>-->
         <!--            <artifactId>okhttp</artifactId>-->
@@ -287,6 +308,13 @@
             <version>24.0.0</version>
             <scope>compile</scope>
         </dependency>
+        <!--集成logstash-->
+        <dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <version>5.3</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 3 - 1
src/main/java/com/kcim/common/constants/SQLParameter.java

@@ -12,7 +12,9 @@ public interface SQLParameter {
     String UNIT_CODE = "#unit_code";
 
     String HOSP_ID_CODE = "#hosp_id";
-    String COMPUTE_DATE_CODE = "#compute_date";
+    String COMPUTE_DATE_CODE = "compute_date";
+
+    String REPORT_TYPE_CODE = "report_type";
 
     String USER_CODE = "#user_code";
 }

+ 54 - 0
src/main/java/com/kcim/common/enums/CustomSqlTypeEnum.java

@@ -0,0 +1,54 @@
+package com.kcim.common.enums;
+
+/**
+ * @program: CostAccount
+ * @description: 自定义sql枚举类
+ * @author: Wang.YS
+ * @create: 2024-07-30 15:20
+ **/
+public enum CustomSqlTypeEnum {
+    /**
+     * 检查数据异常
+     */
+    CHECK_DATA_EXCEPTION("CHECK_DATA_EXCEPTION","检查数据异常"),
+    /**
+     * 收入归集
+     */
+    INCOME_COLLECTION("INCOME_COLLECTION","收入归集"),
+    /**
+     * 药材成本计算
+     */
+    DRG_COST_CALC("DRG_COST_CALC","药材成本计算"),
+    /**
+     * 患者项目成本计算
+     */
+    PT_ITEM_COST_CALC("PT_ITEM_COST_CALC","患者项目成本计算"),
+    /**
+     * 患者成本计算
+     */
+    PT_COST_CALC("PT_COST_CALC","患者成本计算"),
+    /**
+     * 患者标准项目成本计算
+     */
+    PT_STAND_ITEM_COST_CALC("PT_STAND_ITEM_COST_CALC","患者标准项目成本计算"),
+    /**
+     * 科室门住损益计算
+     */
+    INTEGRATIVE_PROFIT_CALC("INTEGRATIVE_PROFIT_CALC","科室门住损益计算"),
+    ;
+    private final String code;
+    private final String description;
+
+    CustomSqlTypeEnum(String code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}

+ 5 - 10
src/main/java/com/kcim/common/enums/ErrorCodeEnum.java

@@ -1,5 +1,8 @@
 package com.kcim.common.enums;
 
+import lombok.Getter;
+
+@Getter
 public enum ErrorCodeEnum {
     DATA_NOT_EXIST(500, "数据不存在或已被移除"),
     USER_NOT_EXIST(500, "用户不存在"),
@@ -12,21 +15,13 @@ public enum ErrorCodeEnum {
 
     ;
 
-    private Integer code;
+    private final Integer code;
 
-    private String description;
+    private final String description;
 
     ErrorCodeEnum(Integer code, String description) {
         this.code = code;
         this.description = description;
     }
 
-    public Integer getCode() {
-        return code;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
 }

+ 19 - 0
src/main/java/com/kcim/common/util/ComputeDateUtils.java

@@ -85,4 +85,23 @@ public class ComputeDateUtils {
         return Integer.valueOf(stringFromDate);
 
     }
+
+    /**
+     * 获取上一年核算年月
+     * @param computeDate 当前核算年月
+     * @return 上一个核算年月
+     */
+    public static String getPreComputeDateYear(String computeDate){
+        if(StringUtils.isEmpty(computeDate)){
+            return null;
+        }
+        Date date = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM);
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.YEAR,-1);
+        return DateUtils.getStringFromDate(calendar.getTime(), DateStyleEnum.YYYY_MM.getValue());
+
+
+    }
+
 }

+ 42 - 0
src/main/java/com/kcim/common/util/DateUtils.java

@@ -1814,4 +1814,46 @@ public class DateUtils {
         return dateFormat.format(date);
     }
 
+    public static List<String> getIntervalMonthList(String start,String end){
+        Date startDate = StringToDate(start,DateStyleEnum.YYYY_MM);
+        Date endDate = StringToDate(end,DateStyleEnum.YYYY_MM);
+        List<String> list = new ArrayList<>();
+        while(startDate.getTime()<=endDate.getTime()){
+            list.add(DateToString(startDate,DateStyleEnum.YYYY_MM_EN));
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(startDate);
+            calendar.add(Calendar.MONTH,1);
+            if(calendar.getTime().getTime()>endDate.getTime()){
+                if(!startDate.equals(endDate)){
+                    list.add(DateToString(endDate,DateStyleEnum.YYYY_MM_EN));
+                }
+                startDate = calendar.getTime();
+            }else{
+                startDate = calendar.getTime();
+            }
+
+        }
+        return list;
+    }
+
+    public static List<String> getIntervalMonthList(Date startDate,Date endDate){
+        List<String> list = new ArrayList<>();
+        while(startDate.getTime()<=endDate.getTime()){
+            list.add(DateToString(startDate,DateStyleEnum.YYYY_MM));
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(startDate);
+            calendar.add(Calendar.MONTH,1);
+            if(calendar.getTime().getTime()>endDate.getTime()){
+                if(!startDate.equals(endDate)){
+                    list.add(DateToString(endDate,DateStyleEnum.YYYY_MM));
+                }
+                startDate = calendar.getTime();
+            }else{
+                startDate = calendar.getTime();
+            }
+
+        }
+        return list;
+    }
+
 }

+ 212 - 0
src/main/java/com/kcim/common/util/ListUtils.java

@@ -0,0 +1,212 @@
+package com.kcim.common.util;
+
+/*
+  @author wangyongsheng
+ * @instruction
+ * @create 2019/9/8
+ */
+
+
+import java.lang.reflect.Field;
+import java.text.Collator;
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * @author
+ * 在数据库中查出来的列表中,往往需要对不同的字段重新排序。 一般的做法都是使用排序的字段,重新到数据库中查询。
+ * 如果不到数据库查询,直接在第一次查出来的list中排序,无疑会提高系统的性能。 下面就写一个通用的方法,对list排序,
+
+ * 至少需要满足以下5点:
+
+ * ①.list元素对象类型任意
+ *         ---->使用泛型解决
+
+ * ②.可以按照list元素对象的任意多个属性进行排序,即可以同时指定多个属性进行排序
+ *         --->使用java的可变参数解决
+
+ * ③.list元素对象属性的类型可以是数字(byte、short、int、long、float、double等,包括正数、负数、0)、字符串(char、String)、日期(java.util.Date)
+ *         --->对于数字:统一转换为固定长度的字符串解决,比如数字3和123,转换为"003"和"123" ;再比如"-15"和"7"转换为"-015"和"007"
+ *         --->对于日期:可以先把日期转化为long类型的数字,数字的解决方法如上
+
+ * ④.list元素对象的属性可以没有相应的getter和setter方法
+ *         --->可以使用java反射进行获取private和protected修饰的属性值
+
+ * ⑤.list元素对象的对象的每个属性都可以指定是升序还是降序
+ *           -->使用2个重写的方法(一个方法满足所有属性都按照升序(降序),另外一个方法满足每个属性都能指定是升序(降序))
+ *
+ *
+ */
+public class ListUtils {
+    /**
+     * 对list的元素按照多个属性名称排序,
+     * list元素的属性可以是数字(byte、short、int、long、float、double等,支持正数、负数、0)、char、String、java.util.Date
+     *
+     *
+     *  @param  list
+     *  @param  sortnameArr
+     *            list元素的属性名称
+     * @param isAsc
+     *            true升序,false降序
+     */
+    public static <E> void sort(List<E> list, final boolean isAsc, final String... sortnameArr) {
+        Collections.sort(list, new Comparator<E>() {
+
+            public int compare(E a, E b) {
+                int ret = 0;
+                try {
+                    for (int i = 0; i < sortnameArr.length; i++) {
+                        ret = ListUtils.compareObject(sortnameArr[i], isAsc, a, b);
+                        if (0 != ret) {
+                            break;
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return ret;
+            }
+        });
+    }
+
+    /**
+     * 给list的每个属性都指定是升序还是降序
+     *
+     * @param list
+     * @param sortnameArr  参数数组
+     * @param typeArr      每个属性对应的升降序数组, true升序,false降序
+     */
+
+    public static <E> void sort(List<E> list, final String[] sortnameArr, final boolean[] typeArr) {
+        if (sortnameArr.length != typeArr.length) {
+            throw new RuntimeException("属性数组元素个数和升降序数组元素个数不相等");
+        }
+        Collections.sort(list, new Comparator<E>() {
+            public int compare(E a, E b) {
+                int ret = 0;
+                try {
+                    for (int i = 0; i < sortnameArr.length; i++) {
+                        ret = ListUtils.compareObject(sortnameArr[i], typeArr[i], a, b);
+                        if (0 != ret) {
+                            break;
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return ret;
+            }
+        });
+    }
+
+    /**
+     * 对2个对象按照指定属性名称进行排序
+     *
+     * @param sortname
+     *            属性名称
+     * @param isAsc
+     *            true升序,false降序
+     * @param a
+     * @param b
+     * @return
+     * @throws Exception
+     */
+    private static <E> int compareObject(final String sortname, final boolean isAsc, E a, E b) throws Exception {
+        int ret;
+        Object value1 = ListUtils.forceGetFieldValue(a, sortname);
+        Object value2 = ListUtils.forceGetFieldValue(b, sortname);
+        String str1 = value1.toString();
+        String str2 = value2.toString();
+        if (value1 instanceof Number && value2 instanceof Number) {
+            int maxlen = Math.max(str1.length(), str2.length());
+            str1 = ListUtils.addZero2Str((Number) value1, maxlen);
+            str2 = ListUtils.addZero2Str((Number) value2, maxlen);
+        } else if (value1 instanceof Date && value2 instanceof Date) {
+            long time1 = ((Date) value1).getTime();
+            long time2 = ((Date) value2).getTime();
+            int maxlen = Long.toString(Math.max(time1, time2)).length();
+            str1 = ListUtils.addZero2Str(time1, maxlen);
+            str2 = ListUtils.addZero2Str(time2, maxlen);
+        }
+        if (isAsc) {
+            ret = str1.compareTo(str2);
+        } else {
+            ret = str2.compareTo(str1);
+        }
+        return ret;
+    }
+
+    /**
+     * 给数字对象按照指定长度在左侧补0.
+     *
+     * 使用案例: addZero2Str(11,4) 返回 "0011", addZero2Str(-18,6)返回 "-000018"
+     *
+     * @param numObj
+     *            数字对象
+     * @param length
+     *            指定的长度
+     * @return
+     */
+    public static String addZero2Str(Number numObj, int length) {
+        NumberFormat nf = NumberFormat.getInstance();
+        // 设置是否使用分组
+        nf.setGroupingUsed(false);
+        // 设置最大整数位数
+        nf.setMaximumIntegerDigits(length);
+        // 设置最小整数位数
+        nf.setMinimumIntegerDigits(length);
+        return nf.format(numObj);
+    }
+
+    /**
+     * 获取指定对象的指定属性值(去除private,protected的限制)
+     *
+     * @param obj
+     *            属性名称所在的对象
+     * @param fieldName
+     *            属性名称
+     * @return
+     * @throws Exception
+     */
+    public static Object forceGetFieldValue(Object obj, String fieldName) throws Exception {
+        Field field = obj.getClass().getDeclaredField(fieldName);
+        Object object = null;
+        boolean accessible = field.isAccessible();
+        if (!accessible) {
+            // 如果是private,protected修饰的属性,需要修改为可以访问的
+            field.setAccessible(true);
+            object = field.get(obj);
+            // 还原private,protected属性的访问性质
+            field.setAccessible(accessible);
+            return object;
+        }
+        object = field.get(obj);
+        return object;
+    }
+    private static final Comparator<Object> CHINESE_COMPARATOR = Collator.getInstance(Locale.CHINA);
+
+    /**
+     * 中文排序
+     * @param keyExtractor
+     * @param <T>
+     * @return
+     */
+    public static <T> Comparator<T> wrapComparator(Function<? super T, String> keyExtractor) {
+        return Comparator.comparing(keyExtractor, CHINESE_COMPARATOR);
+    }
+
+    public static void sort(List<String> data) {
+        data.sort(wrapComparator(Function.identity()));
+    }
+
+    public static <T> void sort(List<T> data, Function<? super T, String> keyExtractor) {
+        data.sort(wrapComparator(keyExtractor));
+    }
+
+
+
+
+
+
+}

+ 188 - 0
src/main/java/com/kcim/common/util/TreeDepthUtil.java

@@ -0,0 +1,188 @@
+package com.kcim.common.util;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-08-13 18:28
+ **/
+
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import java.util.stream.Collectors;
+
+/**
+ * 获取树深度
+ * 注:若最深一层只有null元素,该层不计入深度
+ */
+public class TreeDepthUtil {
+    private static final Byte FLAG = 1;
+
+    /**
+     * dfs的递归实现获取树深度
+     *
+     * @param root       根节点
+     * @param childField 子节点列表字段名称
+     * @param <T>        节点类型
+     * @return 树深度
+     */
+    public static <T> int getTreeDepthByDfsWithRecursion(T root, String childField) {
+        if (root == null || !StringUtils.hasText(childField)) {
+            return 0;
+        }
+        List<Integer> depth = new ArrayList<>(1);
+        depth.add(0);
+        // 这里只是需要一个标志,表示当前路径上的点,所以用byte减少内存占用
+        Stack<Byte> stack = new Stack<>();
+        doGetTreeDepthByDfs(root, childField, stack, depth);
+        return depth.get(0);
+    }
+
+    private static <T> void doGetTreeDepthByDfs(T parent, String childField, Stack<Byte> stack, List<Integer> depth) {
+        stack.push(FLAG);
+        depth.set(0, Math.max(depth.get(0), stack.size()));
+        Collection<T> childs = (Collection<T>) getFieldValue(parent, childField);
+        if (CollectionUtils.isEmpty(childs)) {
+            stack.pop();
+            return;
+        }
+        for (T child : childs) {
+            if (child == null) {
+                continue;
+            }
+            doGetTreeDepthByDfs(child, childField, stack, depth);
+        }
+        stack.pop();
+    }
+
+    /**
+     * dfs的非递归(循环)实现获取树深度
+     *
+     * @param root       根节点
+     * @param childField 子节点列表字段名称
+     * @param <T>        节点类型
+     * @return 树深度
+     */
+    public static <T> int getTreeDepthByDfsWithLoop(T root, String childField) {
+        if (root == null || !StringUtils.hasText(childField)) {
+            return 0;
+        }
+        Stack<Iterator> stack = new Stack<>();
+        List<T> list = new ArrayList<>();
+        list.add(root);
+        Iterator<T> iterator = list.iterator();
+        Iterator<T> emptyIterator = (Iterator<T>) Collections.emptyList().iterator();
+        int depth = 0;
+        while (true) {
+            while (!iterator.hasNext() && !stack.isEmpty()) {
+                iterator = stack.pop();
+            }
+            if (!iterator.hasNext() && stack.isEmpty()) {
+                break;
+            }
+            stack.push(iterator);
+            depth = Math.max(depth, stack.size());
+            T next = iterator.next();
+            Collection<T> childs = (Collection<T>) getFieldValue(next, childField);
+            if (childs != null) {
+                childs = childs.stream().filter(o -> o != null).collect(Collectors.toList());
+            }
+            iterator = childs == null ? emptyIterator : childs.iterator();
+        }
+        return depth;
+    }
+
+    /**
+     * bfs的递归实现获取树深度
+     *
+     * @param root       根节点
+     * @param childField 子节点列表字段名称
+     * @param <T>        节点类型
+     * @return 树深度
+     */
+    public static <T> int getTreeDepthByBfsWithRecursion(T root, String childField) {
+        if (root == null || !StringUtils.hasText(childField)) {
+            return 0;
+        }
+        List<T> parents = new ArrayList<>();
+        parents.add(root);
+        List<Integer> depth = new ArrayList<>(1);
+        depth.add(0);
+        doGetTreeDepthByBfs(parents, childField, depth);
+        return depth.get(0);
+    }
+
+    private static <T> void doGetTreeDepthByBfs(Collection<T> parents, String childField, List<Integer> depth) {
+        if (parents.isEmpty()) {
+            return;
+        }
+        depth.set(0, depth.get(0) + 1);
+        readChilds(parents, childField);
+        doGetTreeDepthByBfs(parents, childField, depth);
+    }
+
+    /**
+     * bfs的非递归(循环)实现获取树深度
+     *
+     * @param root       根节点
+     * @param childField 子节点列表字段名称
+     * @param <T>        节点类型
+     * @return 树深度
+     */
+    public static <T> int getTreeDepthByBfsWithLoop(T root, String childField) {
+        if (root == null || !StringUtils.hasText(childField)) {
+            return 0;
+        }
+        List<T> parents = new ArrayList<>();
+        parents.add(root);
+        int depth = 0;
+        while (!parents.isEmpty()) {
+            depth++;
+            readChilds(parents, childField);
+        }
+        return depth;
+    }
+
+
+    private static <T> void readChilds(Collection<T> parents, String childField) {
+        List<T> allChilds = new ArrayList<>();
+        for (T parent : parents) {
+            Collection<T> childs = (Collection<T>) getFieldValue(parent, childField);
+            if (childs == null) {
+                continue;
+            }
+            allChilds.addAll(childs.stream().filter(o -> o != null).collect(Collectors.toList()));
+        }
+        parents.clear();
+        parents.addAll(allChilds);
+    }
+
+    /**
+     * 获取字段值
+     *
+     * @param element   待获取值的对象
+     * @param fieldName 字段名称
+     * @param <T>       对象类型
+     * @return 字段值
+     */
+    private static <T> Object getFieldValue(T element, String fieldName) {
+        try {
+            Field field = element.getClass().getDeclaredField(fieldName);
+            field.setAccessible(true);
+            return field.get(element);
+        } catch (IllegalAccessException exception) {
+            throw new RuntimeException("no permission to read field [" + fieldName + "]!");
+        } catch (NoSuchFieldException e) {
+            throw new RuntimeException("field [" + fieldName + "] not exists!");
+        }
+    }
+}

+ 270 - 5
src/main/java/com/kcim/common/util/excel/ExcelPoiUtil.java

@@ -6,6 +6,7 @@ import org.apache.poi.ss.usermodel.BorderStyle;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.RegionUtil;
+import org.apache.poi.xssf.usermodel.*;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -26,6 +27,8 @@ public class ExcelPoiUtil<T> {
     /**
      * excel 对象
      */
+    private XSSFWorkbook xssfWorkbook;
+
     private HSSFWorkbook workbook;
     /**
      * 表格标题
@@ -84,25 +87,38 @@ public class ExcelPoiUtil<T> {
         this.sdf = sdf;
     }
 
+
+    public XSSFWorkbook getXssfWorkbook() {
+        return xssfWorkbook;
+    }
+
+    public void setXssfWorkbook(XSSFWorkbook xssfWorkbook) {
+        this.xssfWorkbook = xssfWorkbook;
+    }
+
     /**
      * 无参数 初始化 对象
      */
     public ExcelPoiUtil() {
         this.title = "sheet1";
         this.workbook = new HSSFWorkbook();
-        init();
+        initHssf();
     }
 
+
     public ExcelPoiUtil(String title) {
         this.title = title;
-        this.workbook = new HSSFWorkbook();
+        this.xssfWorkbook = new XSSFWorkbook();
         init();
     }
-
     /**
      * 内部统一调用的样式初始化
      */
     private void init() {
+        this.styleHead = EasyExcelStyleUtil.getStyles(xssfWorkbook,2);
+        this.styleBody = EasyExcelStyleUtil.getStyles(xssfWorkbook,3);
+    }
+    private void initHssf() {
         this.styleHead = EasyExcelStyleUtil.getStyles(workbook,2);
         this.styleBody = EasyExcelStyleUtil.getStyles(workbook,3);
     }
@@ -130,6 +146,17 @@ public class ExcelPoiUtil<T> {
         return this.workbook;
     }
 
+    /**
+     * 返回workbook
+     * @param listTpamsColEntity 表头数据
+     * @param datas           行内数据
+     * @param mergeIndex      需要纵向合并的单元格列号(默认有横向合并)
+     */
+    public XSSFWorkbook exportXssfWorkbook(List<ColEntity> listTpamsColEntity, List<T> datas,List<Integer> mergeIndex) throws Exception {
+        splitXssfDataToSheets(this.title,datas, listTpamsColEntity, mergeIndex,false);
+        EasyExcelStyleUtil.setStyleByType(this.xssfWorkbook,null,0,null);
+        return this.xssfWorkbook;
+    }
     /**
      * 返回workbook
      * @param listTpamsColEntity 表头数据
@@ -202,7 +229,7 @@ public class ExcelPoiUtil<T> {
      * @param workbook
      * @param filePath
      */
-    public void save(HSSFWorkbook workbook, String filePath) {
+    public void save(XSSFWorkbook workbook, String filePath) {
         File file = new File(filePath);
         if (!file.getParentFile().exists()) {
             file.getParentFile().mkdirs();
@@ -237,6 +264,26 @@ public class ExcelPoiUtil<T> {
         writeSheetContent(headerCellList, data, sheet, headerCellList.get(0).getTotalRow(),mergeIndex, rowFlag);
     }
 
+    /**
+     * 导出Excel,适用于web导出excel
+     * @param sheet           excel
+     * @param data            行内数据
+     * @param headerCellList 表头数据
+     * @param mergeIndex      需要纵向合并的单元格列号(默认有横向合并)
+     * @param rowFlag         输出展示数据的结构(表头下面行的数据)
+     */
+    private void writeXssfSheet(XSSFSheet sheet, List<T> data, List<ColEntity> headerCellList,List<Integer> mergeIndex,boolean rowFlag) throws Exception {
+        sheet = createXssfHead(sheet, headerCellList.get(0).getTotalRow(), headerCellList.get(0).getTotalCol());
+        createXssfHead(headerCellList, sheet, 0);
+        writeXssfSheetContent(headerCellList, data, sheet, headerCellList.get(0).getTotalRow(),mergeIndex, rowFlag);
+    }
+
+
+
+
+
+
+
     /**
      * 拆分sheet,因为每个sheet不能超过65535,否则会报异常
      * @param sheetName       sheet名称
@@ -258,6 +305,26 @@ public class ExcelPoiUtil<T> {
         writeSheet(sheet, data.subList(pieces * maxColEntity, dataCount), headerCellList,mergeIndex,rowFlag);
     }
 
+    /**
+     * 拆分sheet,因为每个sheet不能超过65535,否则会报异常
+     * @param sheetName       sheet名称
+     * @param data            行内数据
+     * @param headerCellList 表头数据
+     * @param mergeIndex      需要纵向合并的单元格列号(默认有横向合并)
+     * @param rowFlag         输出展示数据的结构(表头下面行的数据)
+     */
+    private void splitXssfDataToSheets(String sheetName,List<T> data, List<ColEntity> headerCellList,List<Integer> mergeIndex,boolean rowFlag) throws Exception {
+        int dataCount = data.size();
+        int maxColEntity = 65535;
+        int pieces = dataCount / maxColEntity;
+        for (int i = 1; i <= pieces; i++) {
+            XSSFSheet sheet = this.xssfWorkbook.createSheet(sheetName + i);
+            List<T> subList = data.subList((i - 1) * maxColEntity, i * maxColEntity);
+            writeXssfSheet(sheet, subList, headerCellList,mergeIndex,rowFlag);
+        }
+        XSSFSheet sheet = this.xssfWorkbook.createSheet(sheetName);
+        writeXssfSheet(sheet, data.subList(pieces * maxColEntity, dataCount), headerCellList,mergeIndex,rowFlag);
+    }
     /**
      * 把数据写入到单元格
      * @param headerCellList 表头数据
@@ -307,6 +374,55 @@ public class ExcelPoiUtil<T> {
             if (isMerge) mergedCells(mergeMaps,sheet);
         }
     }
+    /**
+     * 把数据写入到单元格
+     * @param headerCellList 表头数据
+     * @param datas           行内数据
+     * @param sheet           工作表(excel分页)
+     * @param mergeIndex      需要纵向合并的单元格列号(默认有横向合并)
+     * @throws Exception void
+     */
+    private void writeXssfSheetContent(List<ColEntity> headerCellList, List<T> datas, XSSFSheet sheet, int rowIndex,List<Integer> mergeIndex, boolean rowFlag) throws Exception {
+        boolean isMerge = false;// 是否纵向合并单元格
+        if (mergeIndex != null && !mergeIndex.isEmpty()) isMerge = true;
+        XSSFRow row = null;
+        List<ColEntity> listCol = new ArrayList<>();
+        rowFlag = false;
+        if (rowFlag) {//暂时没有用 后面扩展用
+            for (int i = 0, index = rowIndex; i < datas.size(); i++, index++) {
+                row = sheet.createRow(index);//创建行
+                for (int j = 0; j < headerCellList.size(); j++) {
+                    createXssfColl(row, j, headerCellList.get(j).getFieldName(), datas.get(i));
+                }
+            }
+        } else {
+            getColEntityList(headerCellList, listCol);
+            Map<Integer,  Map<Integer, String>> mergeMaps = new HashMap<>();// 需要合并的列:key 列号,value为单元格内容
+            Map<Integer, String> mergeMap = null;// 需要合并的行:key 行号 value 为单元格内容
+            for (int i = 0, index = rowIndex; i < datas.size(); i++, index++) {
+                row = sheet.createRow(index);//创建行
+                for (int j = 0; j < listCol.size(); j++) {
+                    ColEntity c = listCol.get(j);
+                    //数据列
+                    XSSFCell col = createXssfCol(row, c, datas.get(i));
+                    if (col.toString().length()>0){
+                        // 需要合并 并且 当前单元格所在的列包含在要合并的列中
+                        if (isMerge && mergeIndex.contains(c.getCol())){
+                            if (mergeMaps.get(c.getCol()) != null){ // 如果要合并的列已经有了,则直接去拿该列的数据
+                                mergeMap = mergeMaps.get(c.getCol());
+                            }else {
+                                mergeMap = new HashMap<>();
+                            }
+                            // 当前行号为key,当前单元格内容为value
+                            mergeMap.put(index,col.toString()); // 将当前单元格的内容添加到当前行号中
+                            mergeMaps.put(c.getCol(),mergeMap);
+                        }
+                    }
+                }
+            }
+            if (isMerge) mergedXssfCells(mergeMaps,sheet);
+        }
+    }
 
     /**
      * 纵向合并单元格
@@ -333,6 +449,31 @@ public class ExcelPoiUtil<T> {
         }
     }
 
+    /**
+     * 纵向合并单元格
+     * @param mergeMaps 需要合并的列:key 要合并的列号,value为单元格内容
+     * @param sheet
+     */
+    private void mergedXssfCells(Map<Integer,  Map<Integer, String>> mergeMaps,XSSFSheet sheet){
+        for (Integer colNum : mergeMaps.keySet()) { // 遍历要合并的列,获取每一列的每一行
+            Map<Integer, String> mergeMap = mergeMaps.get(colNum);// 当前这列每一行的内容:key为行号,value为单元格内容
+            // 根据mergeMap的value,也就是单元格内容进行分组,每一组都是需要合并在一起的单元格(要合并的区域)
+            Map<String, List<Map.Entry<Integer,String>>>result = mergeMap.entrySet().stream().collect(Collectors.groupingBy(c -> c.getValue()));
+            System.out.println("\n合并的列号:"+colNum);
+            System.out.println("合并的区域:"+result);
+            for (String key : result.keySet()) {
+                // list为这一组要合并的几个单元格
+                List<Map.Entry<Integer, String>> list = result.get(key);
+                int start = list.get(0).getKey(); // 开始合并的行号
+                int end = list.get(list.size()-1).getKey(); // 结束合并的行号
+                System.out.println("第"+colNum+"列开始合并的行号:"+start+"\t第"+colNum+"列结束合并的行号:"+"\t"+end+"。");
+                if (start < end){ // 开始合并的行号必须小于结束合并的行号
+                    sheet.addMergedRegion(new CellRangeAddress(start, end, colNum,colNum));
+                }
+            }
+        }
+    }
+
     /**
      * 根据list 来创建单元格 暂时没有用
      * @param row
@@ -354,7 +495,27 @@ public class ExcelPoiUtil<T> {
         HSSFRichTextString richString = new HSSFRichTextString(text);
         cell.setCellValue(richString);
     }
-
+    /**
+     * 根据list 来创建单元格 暂时没有用
+     * @param row
+     * @param j
+     * @param finame
+     * @param t
+     */
+    private void createXssfColl(XSSFRow row, int j, String finame, T t) {
+        XSSFCell cell = row.createCell(j);  //创建单元格
+        cell.setCellStyle(this.styleBody); //设置单元格样式
+        String text = "";
+        if (t instanceof List) {
+            List<Map> temp = (List<Map>) t;
+            if (j >= temp.size()) {
+                return;
+            }
+            text = String.valueOf(temp.get(j).get(finame) == null ? "" : temp.get(j).get(finame));
+        }
+        HSSFRichTextString richString = new HSSFRichTextString(text);
+        cell.setCellValue(richString);
+    }
     /**
      * 把ColEntity的ColEntityList整理成一个list<ColEntity> 过滤表头的脏数据
      * @param list    表头数据
@@ -432,6 +593,47 @@ public class ExcelPoiUtil<T> {
         return cell;
     }
 
+    /**
+     * 创建单元格
+     * @param row         Excel对应的行
+     * @param colEntity 当前单元格对象
+     * @param v
+     * @throws Exception
+     */
+    public XSSFCell createXssfCol(XSSFRow row, ColEntity colEntity, T v) throws Exception {
+        XSSFCell cell = row.createCell(colEntity.getCol());  //创建单元格
+        cell.setCellStyle(this.styleBody); //设置单元格样式
+        final Object[] value = {null};
+        if (v instanceof Map) {
+            Map m = (Map) v;
+            m.forEach((k, val) -> {
+                if (k.equals(colEntity.getFieldName()) && !colEntity.isHasChildren()) {
+                    value[0] = val;
+                }
+            });
+        } else {
+            Class<?> cls = v.getClass();// 拿到该类
+            Field[] fields = cls.getDeclaredFields();// 获取实体类的所有属性,返回Field数组
+            for (int i = 0; i < fields.length; i++) {
+                Field f = fields[i];
+                f.setAccessible(true); // 设置些属性是可以访问的
+                if (colEntity.getFieldName().equals(f.getName()) && !colEntity.isHasChildren()){
+                    value[0] = f.get(v);
+                }
+                if (value[0] instanceof Date) {
+                    value[0] = parseDate((Date) value[0]);
+                }
+            }
+        }
+        if (value[0] != null) {
+//            HSSFRichTextString richString = new HSSFRichTextString(value[0].toString());
+            XSSFRichTextString richString = new XSSFRichTextString(value[0].toString());
+
+            cell.setCellValue(richString);
+        }
+        return cell;
+    }
+
     /**
      * 时间转换
      * @param date
@@ -465,6 +667,22 @@ public class ExcelPoiUtil<T> {
         return sheetCo;
     }
 
+    /**
+     * 根据数据的行数和列数,在excel创建单元格cell
+     * @param sheetCo excel分页
+     * @param r       excel 行数
+     * @param c       excel 列数
+     * @return
+     */
+    public XSSFSheet createXssfHead(XSSFSheet sheetCo, int r, int c) {
+        for (int i = 0; i < r; i++) {
+            XSSFRow row = sheetCo.createRow(i);
+            for (int j = 0; j < c; j++) {
+                XSSFCell cell = row.createCell(j);
+            }
+        }
+        return sheetCo;
+    }
     /**
      * 使用递归 在excel写入表头数据 支持单级,多级表头的创建
      * @param cellList 表头数据
@@ -512,6 +730,53 @@ public class ExcelPoiUtil<T> {
         }
     }
 
+    /**
+     * 使用递归 在excel写入表头数据 支持单级,多级表头的创建
+     * @param cellList 表头数据
+     * @param sheetCo  哪个分页
+     * @param rowIndex 当前Excel的第几行
+     */
+    public void createXssfHead(List<ColEntity> cellList, XSSFSheet sheetCo, int rowIndex) {
+        XSSFRow row = sheetCo.getRow(rowIndex);
+        int len = cellList.size();//当前行 有多少列
+        for (int i = 0; i < len; i++) {//i是headers的索引,n是Excel的索引 多级表头
+            ColEntity colEntity = cellList.get(i);
+            //创建这一行的第几列单元格
+            int r = colEntity.getRow();
+            int rLen = colEntity.getRLen();
+            int c = colEntity.getCol();
+            int cLen = colEntity.getCLen();
+            int endR = r + rLen;
+            //解决表头导出时多一行问题
+            if(endR > r){
+                endR--;
+            }
+            int endC = c + cLen;
+            if (endC > c) {
+                endC--;
+            }
+            XSSFCell cell = row.getCell(c);
+            XSSFRichTextString text = new XSSFRichTextString(colEntity.getContent());
+            cell.setCellStyle(this.styleHead); //设置表头样式
+            cell.setCellValue(text);
+            // 合并单元格
+            CellRangeAddress cra = new CellRangeAddress(r, endR, c, endC);
+            //todo debug
+            if (cra.getNumberOfCells() > 1) {
+                sheetCo.addMergedRegion(cra);
+            }
+            sheetCo.setColumnWidth(c,colEntity.getWidth()*256);// 设置列宽
+            // 使用RegionUtil类为合并后的单元格添加边框
+            RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheetCo); // 下边框
+            RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheetCo); // 左边框
+            RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheetCo); // 有边框
+            if (colEntity.isHasChildren()) {
+                rowIndex = r + 1;
+                createXssfHead(colEntity.getCellList(), sheetCo, rowIndex);
+            }
+        }
+    }
+
     /**
      * 转换成ColEntity对象
      * 支持List<T>的数据结构:map String ,只能是单级的数据

+ 0 - 1
src/main/java/com/kcim/common/util/excel/entity/ItemImportEntity.java

@@ -8,7 +8,6 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.math.BigDecimal;
-import java.util.Date;
 
 /**
  * @program: CostAccount

+ 16 - 0
src/main/java/com/kcim/dao/mapper/ComputeLastProfitDateMapper.java

@@ -0,0 +1,16 @@
+package com.kcim.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kcim.dao.model.ComputeLastProfitDate;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 最后一次损益计算日期记录表
+ * 
+ * @author Wang.YS
+ * @date 2024-09-04 17:55:38
+ */
+@Mapper
+public interface ComputeLastProfitDateMapper extends BaseMapper<ComputeLastProfitDate> {
+	
+}

+ 16 - 0
src/main/java/com/kcim/dao/mapper/ComputeMedicalDepartmentProfitMapper.java

@@ -0,0 +1,16 @@
+package com.kcim.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kcim.dao.model.ComputeMedicalDepartmentProfit;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 科室门住损益计算
+ * 
+ * @author Wang.YS
+ * @date 2024-09-25 15:21:23
+ */
+@Mapper
+public interface ComputeMedicalDepartmentProfitMapper extends BaseMapper<ComputeMedicalDepartmentProfit> {
+	
+}

+ 1 - 0
src/main/java/com/kcim/dao/mapper/CostCostingGroupMapper.java

@@ -86,6 +86,7 @@ public interface CostCostingGroupMapper extends BaseMapper<CostCostingGroup> {
      * @param startIndex 开始索引
      * @param pageSize 每页数据大小
      * @param year 年
+     *
      * @param month 月
      * @param hospId 医院id
      * @return 列表

+ 7 - 2
src/main/java/com/kcim/dao/mapper/CostDepartmentProfitMapper.java

@@ -1,8 +1,9 @@
 package com.kcim.dao.mapper;
 
-import com.kcim.dao.model.CostDepartmentProfit;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.kcim.dao.model.CostDepartmentProfit;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 科室损益计算
@@ -12,5 +13,9 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface CostDepartmentProfitMapper extends BaseMapper<CostDepartmentProfit> {
-	
+
+
+    Integer getMaxYear(@Param("hospId") Long hospId);
+
+    Integer getMaxMonth(@Param("hospId") Long hospId, @Param("year") Integer year);
 }

+ 16 - 0
src/main/java/com/kcim/dao/mapper/CostReportIndexMapper.java

@@ -0,0 +1,16 @@
+package com.kcim.dao.mapper;
+
+import com.kcim.dao.model.CostReportIndex;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 成本报表索引管理
+ * 
+ * @author Wang.YS
+ * @date 2024-11-05 14:23:24
+ */
+@Mapper
+public interface CostReportIndexMapper extends BaseMapper<CostReportIndex> {
+	
+}

+ 7 - 0
src/main/java/com/kcim/dao/mapper/ImportPatientItemMapper.java

@@ -57,4 +57,11 @@ public interface ImportPatientItemMapper extends BaseMapper<ImportPatientItem> {
 
     List<PatientItemDepartmentGroupVo>  getDepartAmountGroup(@Param("computeDate") String computeDate,
                               @Param("hospId") Long hospId);
+
+    long getDrugCount(@Param("computeDate") String computeDate,
+                      @Param("hospId") Long hospId);
+
+    List<PatientItemDepartmentGroupVo> getByNoCalculateComputeDateDrugMaterial(@Param("page") Page<PatientItemDepartmentGroupVo> page,
+                                                                               @Param("computeDate") String computeDate,
+                                                                               @Param("hospId") Long hospId);
 }

+ 7 - 1
src/main/java/com/kcim/dao/mapper/ReportFormMapper.java

@@ -3,6 +3,9 @@ package com.kcim.dao.mapper;
 import com.kcim.dao.model.ReportForm;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 报表项目
@@ -12,5 +15,8 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface ReportFormMapper extends BaseMapper<ReportForm> {
-	
+
+    ReportForm getByReportId(@Param("hospId") Long hospId, @Param("reportType") String reportType, @Param("reportId") Long reportId);
+
+    List<ReportForm> getByReportType(@Param("hospId") Long hospId, @Param("reportType") String reportType);
 }

+ 0 - 2
src/main/java/com/kcim/dao/model/Accounting.java

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.kcim.vo.AccountVO;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -17,7 +16,6 @@ import java.util.List;
  * 会计科目管理表
  * 
  * @author huangrui
- * @email 
  * @date 2021-07-28 13:52:24
  */
 @Data

+ 62 - 60
src/main/java/com/kcim/dao/model/ComputeDrugCostDetail.java

@@ -4,21 +4,19 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-
-import java.math.BigDecimal;
-import java.io.Serializable;
-import java.util.Date;
-
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * 药材成本计算明细表
- * 
+ *
  * @author Wang.YS
-
  * @date 2024-01-11 19:57:43
  */
 @Data
@@ -27,60 +25,64 @@ import lombok.experimental.Accessors;
 @NoArgsConstructor
 @TableName("compute_drug_cost_detail")
 public class ComputeDrugCostDetail implements Serializable {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	/**
-	 * 主键
-	 */
-	@TableId
-	private Integer id;
-	/**
-	 * 医院id
-	 */
-	private Long hospId;
-	/**
-	 * 收费项目成本主键
-	 */
-	private Integer drugCostId;
-	/**
-	 * 报表项目类别
-	 */
-	private String type;
-	/**
-	 * 计算结果
-	 */
-	private BigDecimal computeResult;
-	/**
-	 * 创建人
-	 */
-	private String createUser;
-	/**
-	 * 创建时间
-	 */
-	private Date createTime;
-	/**
-	 * 更新人
-	 */
-	private String updateUser;
-	/**
-	 * 更新时间
-	 */
-	private Date updateTime;
-	/**
-	 * 删除人
-	 */
-	private String deleteUser;
-	/**
-	 * 删除时间
-	 */
-	private Date deleteTime;
-	/**
-	 * 删除标志  0正常 1作废
-	 */
-	@TableLogic(value = "0",delval = "1")
-	private Integer delFlag;
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer id;
+    /**
+     * 医院id
+     */
+    private Long hospId;
+    /*
+     * 核算年月
+     */
+    private String computeDate;
+    /**
+     * 收费项目成本主键
+     */
+    private Integer drugCostId;
+    /**
+     * 报表项目类别
+     */
+    private String type;
+    /**
+     * 计算结果
+     */
+    private BigDecimal computeResult;
+    /**
+     * 创建人
+     */
+    private String createUser;
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 更新人
+     */
+    private String updateUser;
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+    /**
+     * 删除人
+     */
+    private String deleteUser;
+    /**
+     * 删除时间
+     */
+    private Date deleteTime;
+    /**
+     * 删除标志  0正常 1作废
+     */
+    @TableLogic(value = "0", delval = "1")
+    private Integer delFlag;
 
-	@TableField(exist = false)
-	private Integer index;
+    @TableField(exist = false)
+    private Integer index;
 
 }

+ 74 - 0
src/main/java/com/kcim/dao/model/ComputeLastProfitDate.java

@@ -0,0 +1,74 @@
+package com.kcim.dao.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 最后一次损益计算日期记录表
+ * 
+ * @author Wang.YS
+
+ * @date 2024-09-04 17:55:38
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("compute_last_profit_date")
+public class ComputeLastProfitDate implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@TableId
+	private Integer id;
+	/**
+	 * 院区id
+	 */
+	private Long hospId;
+	/**
+	 * 核算年月
+	 */
+	private String computeDate;
+	/**
+	 * 创建人
+	 */
+	private String createUser;
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+	/**
+	 * 修改人
+	 */
+	private String updateUser;
+	/**
+	 * 修改时间
+	 */
+	private Date updateTime;
+	/**
+	 * 删除人
+	 */
+	private String deleteUser;
+	/**
+	 * 删除时间
+	 */
+	private Date deleteTime;
+	/**
+	 * 作废标志 0正常1作废
+	 */
+	@JsonIgnore
+	@TableLogic(value = "0",delval = "1")
+	private Integer delFlag;
+
+}

+ 124 - 0
src/main/java/com/kcim/dao/model/ComputeMedicalDepartmentProfit.java

@@ -0,0 +1,124 @@
+package com.kcim.dao.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 科室门住损益计算
+ * 
+ * @author Wang.YS
+
+ * @date 2024-09-25 15:21:23
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("compute_medical_department_profit")
+public class ComputeMedicalDepartmentProfit implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@TableId
+	private Long id;
+	/**
+	 * 核算年月
+	 */
+	private String computeDate;
+	/**
+	 * 医院id
+	 */
+	private Long hospId;
+	/**
+	 * 报表项目父层级Id
+	 */
+	private Long reportParentId;
+	/**
+	 * 报表Id
+	 */
+	private Long reportId;
+	/**
+	 * 报表项目编号
+	 */
+	private Integer reportNum;
+	/**
+	 * 报表项目名称
+	 */
+	private String reportName;
+	/**
+	 * 金额
+	 */
+	private BigDecimal amount;
+	/**
+	 * 0 综合 1 门诊 2住院
+	 */
+	private Integer medicalType;
+	/**
+	 * 责任中心代码
+	 */
+	private String responsibilityCode;
+	/**
+	 * 责任中心名称
+	 */
+	private String responsibilityName;
+	/**
+	 * 是否门住一体责任中心 1是 0否
+	 */
+	private Integer responsibilityType;
+
+	private String reportType;
+	/**
+	 * 创建人
+	 */
+	@JsonIgnore
+	private String createUser;
+	/**
+	 * 创建时间
+	 */
+	@JsonIgnore
+	private Date createTime;
+	/**
+	 * 更新人
+	 */
+	@JsonIgnore
+	private String updateUser;
+	/**
+	 * 更新时间
+	 */
+	@JsonIgnore
+	private Date updateTime;
+	/**
+	 * 删除人
+	 */
+	@JsonIgnore
+	private String deleteUser;
+	/**
+	 * 删除时间
+	 */
+	@JsonIgnore
+	private Date deleteTime;
+	/**
+	 * 删除标志  0正常 1作废
+	 */
+	@JsonIgnore
+	@TableLogic(value = "0",delval = "1")
+	private Integer delFlag;
+	@TableField(exist = false)
+	private Integer sort;
+	@TableField(exist = false)
+	private Integer hide;
+
+}

+ 0 - 1
src/main/java/com/kcim/dao/model/CostIncomeGroup.java

@@ -16,7 +16,6 @@ import java.util.Date;
  * 收入归集
  * 
  * @author KCYG
- * @email KCYG@xinxicom
  * @date 2021-08-10 13:50:52
  */
 @Data

+ 10 - 5
src/main/java/com/kcim/dao/model/CostReport.java

@@ -4,16 +4,16 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-
-import java.io.Serializable;
-import java.util.Date;
-
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
 /**
  * 成本报表管理
  * 
@@ -95,5 +95,10 @@ public class CostReport implements Serializable {
 	@JsonIgnore
 	@TableLogic(value = "0",delval = "1")
 	private Integer delFlag;
-
+	@TableField(exist = false)
+	private List<CostReportIndex> reportIndex;
+	/**
+	 * 0无 1 列检索 2主键检索
+	 */
+	private Integer indexType;
 }

+ 88 - 0
src/main/java/com/kcim/dao/model/CostReportIndex.java

@@ -0,0 +1,88 @@
+package com.kcim.dao.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 成本报表索引管理
+ * 
+ * @author Wang.YS
+
+ * @date 2024-11-05 14:23:24
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("com_cost_report_index")
+public class CostReportIndex implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@TableId
+	private Integer id;
+	/**
+	 * 医院id
+	 */
+	private Long hospId;
+	/**
+	 * 报表代码
+	 */
+	private Long reportCode;
+	/**
+	 * 报表列
+	 */
+	private String columnIndex;
+	/**
+	 * 提示文案
+	 */
+	private String tips;
+	/**
+	 * 创建人
+	 */
+	@JsonIgnore
+	private String createUser;
+	/**
+	 * 创建时间
+	 */
+	@JsonIgnore
+	private Date createTime;
+	/**
+	 * 更新人
+	 */
+	@JsonIgnore
+	private String updateUser;
+	/**
+	 * 更新时间
+	 */
+	@JsonIgnore
+	private Date updateTime;
+	/**
+	 * 删除人
+	 */
+	@JsonIgnore
+	private String deleteUser;
+	/**
+	 * 删除时间
+	 */
+	@JsonIgnore
+	private Date deleteTime;
+	/**
+	 * 删除标志  0正常 1作废
+	 */
+	@JsonIgnore
+	@TableLogic(value = "0",delval = "1")
+	private Integer delFlag;
+
+}

+ 4 - 0
src/main/java/com/kcim/dao/model/CostShareParam.java

@@ -63,5 +63,9 @@ CostShareParam implements Serializable {
 	 */
 	@TableLogic(value = "0",delval = "UNIX_TIMESTAMP(NOW()) * 1000")
 	private Long deleteTime;
+	/**
+	 * 启用标志 0未启用 1启用
+	 */
+	private Integer status;
 
 }

+ 14 - 4
src/main/java/com/kcim/dao/model/ReportForm.java

@@ -1,17 +1,17 @@
 package com.kcim.dao.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-
-import java.io.Serializable;
-import java.util.Date;
-
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.util.List;
+
 /**
  * 报表项目
  *
@@ -92,5 +92,15 @@ public class ReportForm implements Serializable {
     private Integer costType;
 
     private Integer fraction;
+    @TableField(exist = false)
+    private List<ReportForm> child;
+    /**
+     * 说明
+     */
+    private String description;
+    /**
+     * 0 隐藏 1显示  默认显示
+     */
+    private Integer hide;
 
 }

+ 8 - 0
src/main/java/com/kcim/dao/model/Responsibility.java

@@ -107,5 +107,13 @@ public class Responsibility implements Serializable {
 	private String type;
 	@TableField(exist = false)
 	private String typeName;
+	/**
+	 * 排序
+	 */
+	private Integer sort;
+	/**
+	 * 启用标志 0未启用 1启用
+	 */
+	private Integer status;
 
 }

+ 4 - 0
src/main/java/com/kcim/dao/model/ResponsibilityDepartment.java

@@ -52,4 +52,8 @@ public class ResponsibilityDepartment implements Serializable {
 	@TableLogic(value = "0",delval = "UNIX_TIMESTAMP(NOW()) * 1000")
 	private Long deleteTime;
 
+	private String responsibilityCode;
+
+	private String departmentCode;
+
 }

+ 2 - 0
src/main/java/com/kcim/dao/model/dto/CostShareParamEditDto.java

@@ -33,4 +33,6 @@ public class CostShareParamEditDto {
     @ApiModelProperty(name = "calcType",value = "分摊参数的计算方式")
     @NotNull(message = "分摊参数计算方式不能为空")
     private Integer calcType;
+
+    private Integer status;
 }

+ 2 - 0
src/main/java/com/kcim/dao/model/dto/CostShareParamSaveDto.java

@@ -29,4 +29,6 @@ public class CostShareParamSaveDto {
     @ApiModelProperty(name = "calcType",value = "分摊参数的计算方式")
     @NotNull(message = "分摊参数计算方式不能为空")
     private Integer calcType;
+
+    private Integer status;
 }

+ 4 - 0
src/main/java/com/kcim/dao/model/dto/PatientItemDepartmentGroupVo.java

@@ -33,4 +33,8 @@ public class PatientItemDepartmentGroupVo {
 
     private String responsibilityCode;
 
+    private String itemTypeCode;
+
+    private String itemType;
+
 }

+ 7 - 0
src/main/java/com/kcim/dao/model/dto/ReportFormEditDTO.java

@@ -45,5 +45,12 @@ public class ReportFormEditDTO {
 
     private Integer fraction;
 
+    private String description;
+
+    /**
+     * 0 隐藏 1显示  默认显示
+     */
+    private Integer hide;
+
 
 }

+ 7 - 0
src/main/java/com/kcim/dao/model/dto/ReportFormSaveDTO.java

@@ -41,5 +41,12 @@ public class ReportFormSaveDTO {
 
     private Integer fraction;
 
+    private String description;
+
+    /**
+     * 0 隐藏 1显示  默认显示
+     */
+    private Integer hide;
+
 
 }

+ 9 - 0
src/main/java/com/kcim/dao/model/dto/ResponsibilityEditDTO.java

@@ -60,4 +60,13 @@ public class ResponsibilityEditDTO {
      */
     private String type;
 
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 启用标志 0未启用 1启用
+     */
+    private Integer status;
+
 }

+ 8 - 0
src/main/java/com/kcim/dao/model/dto/ResponsibilitySaveDTO.java

@@ -56,4 +56,12 @@ public class ResponsibilitySaveDTO {
      * 责任中心类型
      */
     private String type;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 启用标志 0未启用 1启用
+     */
+    private Integer status;
 }

+ 0 - 1
src/main/java/com/kcim/dao/repository/AccountingProductRepository.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.common.util.UserContext;
 import com.kcim.dao.mapper.AccountingProductMapper;
 import com.kcim.dao.model.AccountingProduct;
-import com.kcim.dao.model.CostResponsibilityDepartment;
 import com.kcim.vo.ProductMapVO;
 import org.springframework.stereotype.Repository;
 

+ 13 - 0
src/main/java/com/kcim/dao/repository/ComputeDrugCostDetailRepository.java

@@ -9,6 +9,7 @@ import org.springframework.stereotype.Repository;
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -46,4 +47,16 @@ public class ComputeDrugCostDetailRepository extends ServiceImpl<ComputeDrugCost
             }
         }
     }
+
+    public void removeByComputeDate(String computeDate, SessionUserVO currentUser) {
+        UpdateWrapper<ComputeDrugCostDetail> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(ComputeDrugCostDetail::getDelFlag, 0)
+                .eq(ComputeDrugCostDetail::getHospId, currentUser.getHospId())
+                .eq(ComputeDrugCostDetail::getComputeDate, computeDate)
+                .set(ComputeDrugCostDetail::getDeleteTime,new Date())
+                .set(ComputeDrugCostDetail::getDeleteUser,String.valueOf(currentUser.getId()))
+                .set(ComputeDrugCostDetail::getDelFlag, 1);
+
+        this.update(updateWrapper);
+    }
 }

+ 24 - 16
src/main/java/com/kcim/dao/repository/ComputeDrugCostRepository.java

@@ -1,21 +1,18 @@
 package com.kcim.dao.repository;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.common.util.UserContext;
 import com.kcim.dao.mapper.ComputeDrugCostMapper;
 import com.kcim.dao.model.ComputeDrugCost;
-import com.kcim.dao.model.ComputeItemCost;
 import com.kcim.dao.model.dto.ComputeDrugCostPageDto;
-import com.kcim.dao.model.dto.ComputeItemCostPageDto;
 import com.kcim.vo.SessionUserVO;
 import org.springframework.stereotype.Repository;
 import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * @program: CostAccount
@@ -25,17 +22,28 @@ import java.util.stream.Collectors;
  **/
 @Repository
 public class ComputeDrugCostRepository extends ServiceImpl<ComputeDrugCostMapper, ComputeDrugCost> {
-    public List<Integer> removeByComputeDate(String computeDate, SessionUserVO currentUser) {
-        LambdaQueryWrapper<ComputeDrugCost> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(ComputeDrugCost::getHospId, currentUser.getHospId());
-        queryWrapper.eq(ComputeDrugCost::getComputeDate,computeDate);
-        List<ComputeDrugCost> list = this.list(queryWrapper);
-        if(!CollectionUtils.isEmpty(list)){
-            List<Integer> collect = list.stream().map(ComputeDrugCost::getId).collect(Collectors.toList());
-            this.removeBatchByIds(collect,500);
-            return collect;
-        }
-        return new ArrayList<>();
+    public void removeByComputeDate(String computeDate, SessionUserVO currentUser) {
+//        LambdaQueryWrapper<ComputeDrugCost> queryWrapper = new LambdaQueryWrapper<>();
+//        queryWrapper.eq(ComputeDrugCost::getHospId, currentUser.getHospId());
+//        queryWrapper.eq(ComputeDrugCost::getComputeDate,computeDate);
+//        List<ComputeDrugCost> list = this.list(queryWrapper);
+//        if(!CollectionUtils.isEmpty(list)){
+//            List<Integer> collect = list.stream().map(ComputeDrugCost::getId).collect(Collectors.toList());
+//            this.removeBatchByIds(collect,500);
+//            return collect;
+//        }
+//        return new ArrayList<>();
+
+        UpdateWrapper<ComputeDrugCost> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(ComputeDrugCost::getDelFlag, 0)
+                .eq(ComputeDrugCost::getHospId, currentUser.getHospId())
+                .eq(ComputeDrugCost::getComputeDate, computeDate)
+                .set(ComputeDrugCost::getDeleteTime,new Date())
+                .set(ComputeDrugCost::getDeleteUser,String.valueOf(currentUser.getId()))
+                .set(ComputeDrugCost::getDelFlag, 1);
+
+        this.update(updateWrapper);
+
     }
 
     public Page<ComputeDrugCostPageDto> getByPage(Integer current, Integer pageSize, String computeDate, String responsibilityCode, String filter) {

+ 46 - 0
src/main/java/com/kcim/dao/repository/ComputeLastProfitDateRepository.java

@@ -0,0 +1,46 @@
+package com.kcim.dao.repository;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kcim.common.util.UserContext;
+import com.kcim.dao.mapper.ComputeLastProfitDateMapper;
+import com.kcim.dao.model.ComputeLastProfitDate;
+import org.springframework.stereotype.Repository;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-04 17:59
+ **/
+@Repository
+public class ComputeLastProfitDateRepository extends ServiceImpl<ComputeLastProfitDateMapper, ComputeLastProfitDate> {
+    public ComputeLastProfitDate getLastComputeDate(Long hospId) {
+        LambdaQueryWrapper<ComputeLastProfitDate> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ComputeLastProfitDate::getHospId, hospId);
+        return this.getOne(queryWrapper);
+    }
+
+
+    public void saveLastComputeDate(Long hospId,String computeDate) {
+        ComputeLastProfitDate lastComputeDate = getLastComputeDate(hospId);
+        if(Objects.nonNull(lastComputeDate)){
+            //当前院区已有记录 更新
+            lastComputeDate.setComputeDate(computeDate);
+            lastComputeDate.setUpdateTime(new Date());
+            lastComputeDate.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+            this.updateById(lastComputeDate);
+        }else {
+            //当前院区无记录 新增
+            ComputeLastProfitDate computeLastProfitDate = new ComputeLastProfitDate();
+            computeLastProfitDate.setHospId(hospId);
+            computeLastProfitDate.setComputeDate(computeDate);
+            computeLastProfitDate.setCreateTime(new Date());
+            computeLastProfitDate.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+            this.save(computeLastProfitDate);
+        }
+    }
+}

+ 41 - 0
src/main/java/com/kcim/dao/repository/ComputeMedicalDepartmentProfitRepository.java

@@ -0,0 +1,41 @@
+package com.kcim.dao.repository;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kcim.common.constants.NumberConstant;
+import com.kcim.dao.mapper.ComputeMedicalDepartmentProfitMapper;
+import com.kcim.dao.model.ComputeMedicalDepartmentProfit;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @program: performance
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-25 15:26
+ **/
+@Repository
+public class ComputeMedicalDepartmentProfitRepository extends ServiceImpl<ComputeMedicalDepartmentProfitMapper, ComputeMedicalDepartmentProfit> {
+    public List<ComputeMedicalDepartmentProfit> getByComputeDate(String computeDate, Long hospId, String reportType) {
+        LambdaQueryWrapper<ComputeMedicalDepartmentProfit> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getComputeDate, computeDate);
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getHospId, hospId);
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getReportType, reportType);
+
+        return list(queryWrapper);
+
+    }
+
+    public List<ComputeMedicalDepartmentProfit> getByResponsibilityCode(String computeDate, Long hospId, String reportType, String responsibilityCode, Integer responsibilityType) {
+        LambdaQueryWrapper<ComputeMedicalDepartmentProfit> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getComputeDate, computeDate);
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getHospId, hospId);
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getReportType, reportType);
+        queryWrapper.eq(ComputeMedicalDepartmentProfit::getResponsibilityCode, responsibilityCode);
+        if(responsibilityType.equals(NumberConstant.ZERO)){
+            queryWrapper.eq(ComputeMedicalDepartmentProfit::getMedicalType, NumberConstant.ZERO);
+        }
+        return list(queryWrapper);
+    }
+}

+ 0 - 1
src/main/java/com/kcim/dao/repository/ComputeStandPatientProjectCostDetailRepository.java

@@ -3,7 +3,6 @@ package com.kcim.dao.repository;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.dao.mapper.ComputeStandPatientProjectCostDetailMapper;
-import com.kcim.dao.model.ComputeStandPatientProjectCost;
 import com.kcim.dao.model.ComputeStandPatientProjectCostDetail;
 import com.kcim.vo.SessionUserVO;
 import org.springframework.stereotype.Repository;

+ 9 - 0
src/main/java/com/kcim/dao/repository/CostDepartmentProfitRepository.java

@@ -45,4 +45,13 @@ public class CostDepartmentProfitRepository extends ServiceImpl<CostDepartmentPr
 
         return this.list(queryWrapper);
     }
+
+    public Integer getMaxYear(Long hospId) {
+
+        return this.baseMapper.getMaxYear(hospId);
+    }
+    public Integer getMaxMonth(Long hospId,Integer year) {
+
+        return this.baseMapper.getMaxMonth(hospId,year);
+    }
 }

+ 33 - 0
src/main/java/com/kcim/dao/repository/CostReportIndexRepository.java

@@ -0,0 +1,33 @@
+package com.kcim.dao.repository;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kcim.common.util.UserContext;
+import com.kcim.dao.mapper.CostReportIndexMapper;
+import com.kcim.dao.model.CostReportIndex;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-11-05 14:25
+ **/
+@Repository
+public class CostReportIndexRepository extends ServiceImpl<CostReportIndexMapper,CostReportIndex> {
+    public void removeByReportCode(Long code) {
+        LambdaQueryWrapper<CostReportIndex> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(CostReportIndex::getReportCode, code);
+        queryWrapper.eq(CostReportIndex::getHospId, UserContext.getHospId());
+        this.remove(queryWrapper);
+    }
+
+    public List<CostReportIndex> getByReportCode(List<Long> collect) {
+        LambdaQueryWrapper<CostReportIndex> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(CostReportIndex::getReportCode, collect);
+        queryWrapper.eq(CostReportIndex::getHospId, UserContext.getHospId());
+        return this.list(queryWrapper);
+    }
+}

+ 15 - 9
src/main/java/com/kcim/dao/repository/ImportPatientItemRepository.java

@@ -44,7 +44,7 @@ public class ImportPatientItemRepository extends ServiceImpl<ImportPatientItemMa
             queryWrapper.like(ImportPatientItem::getOrderDepartmentName, departmentName);
         }
         if (!StringUtils.isEmpty(patientNo)) {
-            queryWrapper.like(ImportPatientItem::getPatientNo, patientNo);
+            queryWrapper.eq(ImportPatientItem::getPatientNo, patientNo);
         }
         if (!StringUtils.isEmpty(filter)) {
             queryWrapper.and(q -> q.like(ImportPatientItem::getItemCode, filter).or().like(ImportPatientItem::getItemName, filter));
@@ -126,6 +126,11 @@ public class ImportPatientItemRepository extends ServiceImpl<ImportPatientItemMa
         return this.list(queryWrapper);
     }
 
+    public List<PatientItemDepartmentGroupVo> getByNoCalculateComputeDateDrugMaterial(Integer current, Integer pageSize,String computeDate, SessionUserVO currentUser) {
+        return baseMapper.getByNoCalculateComputeDateDrugMaterial(new Page<>(current, pageSize), computeDate, currentUser.getHospId());
+
+    }
+
     @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
     public void updateCalculateFlag(List<ImportPatientItem> items) {
         items.forEach(f -> f.setCalculateFlag(NumberConstant.ONE));
@@ -135,14 +140,15 @@ public class ImportPatientItemRepository extends ServiceImpl<ImportPatientItemMa
     }
 
     public long getDrugCount(String computeDate, SessionUserVO currentUser) {
-        List<Integer> list = new ArrayList<>();
-        list.add(1);
-        list.add(2);
-        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
-        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
-        queryWrapper.in(ImportPatientItem::getItemTypeCode, list);
-        return this.count(queryWrapper);
+//        List<Integer> list = new ArrayList<>();
+//        list.add(1);
+//        list.add(2);
+//        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
+//        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
+//        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
+//        queryWrapper.in(ImportPatientItem::getItemTypeCode, list);
+//        return this.count(queryWrapper);
+        return this.baseMapper.getDrugCount(computeDate,currentUser.getHospId());
     }
 
     public long getItemCount(String computeDate, SessionUserVO currentUser) {

+ 0 - 2
src/main/java/com/kcim/dao/repository/ItemNoValuationDrugMaterialMapRepository.java

@@ -6,8 +6,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.common.util.UserContext;
 import com.kcim.dao.mapper.ItemNoValuationDrugMaterialMapMapper;
 import com.kcim.dao.model.ItemNoValuationDrugMaterialMap;
-import com.kcim.dao.model.ItemSpaceMap;
-import com.kcim.dao.model.ItemValuationDrugMaterialMap;
 import org.springframework.stereotype.Repository;
 
 import java.util.Date;

+ 4 - 0
src/main/java/com/kcim/endPoint/CenterEndPoint.java

@@ -5,6 +5,8 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 /**
  * @program: pfm_manager
  * @description: 中台方法调用
@@ -47,4 +49,6 @@ public interface CenterEndPoint {
 
     @GetMapping("/api/getKCClass")
     Object getKCClass(@RequestParam(required = false,name = "className") String className);
+    @GetMapping("/sysdepartment/getDepartmentByDepartmentIds")
+    Object getDepartmentByDepartmentIds(@RequestParam(required = false,name = "departmentIds")List<Long> departmentIds);
 }

+ 2 - 0
src/main/java/com/kcim/service/AccountingService.java

@@ -65,5 +65,7 @@ public interface AccountingService extends IService<Accounting> {
     Accounting getByCode(String accountCode,Long hospId);
 
     Object getAccountTypeDict(Integer type);
+
+    List<Accounting> getAccountList(Long hospId, List<String> accountList);
 }
 

+ 2 - 0
src/main/java/com/kcim/service/CenterService.java

@@ -33,4 +33,6 @@ public interface CenterService {
     CommonParameterVo getParameter(Long parameterCode);
 
     List<KCClassVo>  getKCClass();
+
+    List<SysDepartment>  getDepartmentByDepartmentIds(List<Long> departmentIds);
 }

+ 41 - 0
src/main/java/com/kcim/service/ComputeMedicalDepartmentProfitService.java

@@ -0,0 +1,41 @@
+package com.kcim.service;
+
+/**
+ * 科室门住损益计算
+ *
+ * @author Wang.YS
+ * @date 2024-09-25 15:21:23
+ */
+public interface ComputeMedicalDepartmentProfitService {
+    /**
+     * 科室门住损益计算
+     *
+     * @param computeDate 核算年月
+     * @param hospId      院区id
+     * @param reportType 报表类型
+     */
+    void calcMedicalProfit(String computeDate, Long hospId, String reportType);
+
+    /**
+     * 获取科室门住损益计算列表
+     *
+     * @param computeDate        核算年月
+     * @param hospId             院区id
+     * @param reportType         报表类型
+     * @param responsibilityCode 责任中心代码
+     * @param responsibilityType 责任中心类型
+     * @return 列表
+     */
+    Object getMedicalProfit(String computeDate, Long hospId, String reportType, String responsibilityCode, Integer responsibilityType);
+
+    /**
+     * 获取责任中心列表
+     *
+     * @param computeDate 核算年月
+     * @param hospId      院区id
+     * @param reportType  报表类型
+     * @return 责任中心列表
+     */
+    Object getMedicalResponsibility(String computeDate, Long hospId, String reportType);
+}
+

+ 8 - 0
src/main/java/com/kcim/service/CostDepartmentProfitService.java

@@ -63,5 +63,13 @@ public interface CostDepartmentProfitService extends IService<CostDepartmentProf
     Object getProfitResponsibility(String reportType, String responsibilityName);
 
     Object getComputeProfitList(String computeDate, Long hospId, String reportType, String responsibilityCode);
+
+    Object getLastComputeDate();
+
+    Object getBatchComputeProfitList(String beginComputeDate, String endComputeDate, Long hospId, String reportType, String responsibilityCode);
+
+    Object getRedirectData(String computeDate, Long reportId, Long hospId, String reportType, String responsibilityCode);
+
+    Object getComputeProfitCollect(String computeDate, Long hospId, String reportType);
 }
 

+ 3 - 0
src/main/java/com/kcim/service/HospProfitAndLossService.java

@@ -48,5 +48,8 @@ public interface HospProfitAndLossService extends IService<HospProfitAndLoss> {
 
     PageUtils hospProfitReports(Integer current, Integer pageSize, Long hospId, String date);
 
+    Object getHospProfitResponsibilities(String responsibilityName);
+
+    Object getHospProfitList(String computeDate, Long hospId, String reportType);
 }
 

+ 3 - 0
src/main/java/com/kcim/service/ReportFormService.java

@@ -76,5 +76,8 @@ public interface ReportFormService extends IService<ReportForm> {
     public void checkExistLoss(Long hospId);
 
     Object getResponsibilities(String reportType, Long reportId);
+
+    ReportForm getByReportId(Long hospId, String reportType, Long reportId);
+    List<ReportForm> getByReportType(Long hospId, String reportType);
 }
 

+ 1 - 0
src/main/java/com/kcim/service/ReportService.java

@@ -12,4 +12,5 @@ import java.util.Map;
 public interface ReportService {
     Object getReportData(Integer current, Integer pageSize, String reportCode, Map<String, String> parameter);
 
+    Object getReportIndex(Long reportCode);
 }

+ 0 - 1
src/main/java/com/kcim/service/ResponsibilityService.java

@@ -23,7 +23,6 @@ public interface ResponsibilityService extends IService<Responsibility> {
     /**
      * 责任中心列表不分页
      *
-     * @param user 当前登录人员
      * @return
      */
     List<CostResponsibilityVO> getList();

+ 6 - 0
src/main/java/com/kcim/service/SqlService.java

@@ -3,6 +3,7 @@ package com.kcim.service;
 import com.kcim.dao.model.Sql;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @program: CostAccount
@@ -24,4 +25,9 @@ public interface SqlService {
     void sortSql(List<Sql> sql);
 
     List<Sql> getSqlBySqlType(String sqlType);
+
+    void autoExecuteSql(String sqlType, Map<String,String> parameter) ;
+
+
+
 }

+ 1 - 1
src/main/java/com/kcim/service/impl/AccountingProductServiceImpl.java

@@ -180,7 +180,7 @@ public class AccountingProductServiceImpl extends ServiceImpl<AccountingProductM
         Long hospId = UserContext.getCurrentLoginHospId();
         List<Long> products = accountProductSaveDTO.getProducts();
         // 如果是空表示解绑,不处理更新保存逻辑
-        if (Objects.isNull(products)) {
+        if (CollectionUtils.isEmpty(products)) {
             return;
         }
         List<AccountingProduct> accountingProducts = products.stream().map(i -> {

+ 7 - 0
src/main/java/com/kcim/service/impl/AccountingServiceImpl.java

@@ -437,4 +437,11 @@ public class AccountingServiceImpl extends ServiceImpl<AccountingMapper, Account
             return dataVoList.stream().filter(f -> f.getValue().equals(NumberConstant.TWO_S)).collect(Collectors.toList());
         }
     }
+
+    public List<Accounting> getAccountList(Long hospId, List<String> accountList){
+        return this.list(
+                new LambdaQueryWrapper<Accounting>().select(Accounting::getId,Accounting::getAccountingCode, Accounting::getAccountingName)
+                        .eq(Accounting::getHospId, hospId).in(Accounting::getAccountingCode,accountList)
+        );
+    }
 }

+ 26 - 8
src/main/java/com/kcim/service/impl/AllocationServiceImpl.java

@@ -138,7 +138,10 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
             // 得到该分摊层级下责任中心列表,如果不存在,下一个
             List<Responsibility> responsibilities = responsibilityShareIdMap.get(levelId);
 //            List<Responsibility> responsibilities = responsibilityService.getLevelIdByCode(levelId, hospId);
-            if (responsibilities.isEmpty()) {
+//            if (responsibilities.isEmpty()) {
+//                continue;
+//            }
+            if(CollectionUtils.isEmpty(responsibilities)){
                 continue;
             }
             // 优化
@@ -157,7 +160,7 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                     String paramList = accountShare.getParamList();
                     // 如果分摊比例未设置直接报错
                     if (StrUtil.isBlank(paramList)) {
-                        throw new CostException("责任中心:" + accountShare.getResponsibilityName() + ";会计中心为:" + accountShare.getAccountingNames() + ";未设置分摊参数比例");
+                        throw new CostException("责任中心:" + accountShare.getResponsibilityName() + ";会计科目为:" + accountShare.getAccountingNames() + ";未设置分摊参数比例");
                     }
                     List<AccountShareVO> accountShareVOs = JacksonUtil.str2ObjList(paramList, List.class, AccountShareVO.class);
 //                    List<CostCostingGroup> groups = responsibilityCodeMap.get(responsibilityCode);
@@ -174,10 +177,12 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                         for (AccountShareVO accountShareVO : accountShareVOs) {
 //                            String paramCode = accountShareVO.getShareParamCode();
                             String shareParamPopout = accountShareVO.getShareParamPopout();
-                            BigDecimal rate = new BigDecimal("1");
-                            if (!"100".equals(shareParamPopout)) {
-                                rate = new BigDecimal("0." + shareParamPopout);
-                            }
+                            BigDecimal bigDecimal = new BigDecimal(shareParamPopout);
+                            BigDecimal rate = bigDecimal.divide(new BigDecimal(100), 4, RoundingMode.HALF_UP);
+//                            BigDecimal rate = new BigDecimal("1");
+//                            if (!"100".equals(shareParamPopout)) {
+//                                rate = new BigDecimal("0." + shareParamPopout);
+//                            }
                             // 本次的分摊比例计算
                             BigDecimal thisAmount = rate.multiply(totalAmount);
                             // 得到目标层级责任中心列表
@@ -214,8 +219,7 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                                         .setResponsibilityName(responsibility.getResponsibilityName()).setAccountShareId(accountShareId).setAmount(targetAmount)
                                         .setCreateTime(timeMillis).setTargetResponsibilityCode(valueResponsibilityCode).setTargetResponsibilityName(targetRespName)
                                         .setShareParamCode(paramValue.getShareParamCode()).setShareParamName(shareParamName).setTotalAmount(totalAmount).setShareParamValueNum(paramValue.getValueNum())
-                                        .setShareParamRate(percent).setShareLevelId(levelId).setTargetShareLevelId(targetShareLevelId)
-                                ;
+                                        .setShareParamRate(percent).setShareLevelId(levelId).setTargetShareLevelId(targetShareLevelId);
 
                                 // todo 目标分摊层级责任中心 就是当前列个表中的责任中心
                                 allocations.add(targetAllocation);
@@ -361,6 +365,7 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
         List<CostCostingGroup> costingGroups = map.get(responsibilityCode);
         if (CollUtil.isEmpty(costingGroups)) {
             List<Allocation> all = costList.stream().filter(i -> i.getTargetResponsibilityCode().equals(responsibilityCode)).collect(Collectors.toList());
+
             if (CollUtil.isEmpty(all) || isShareCost == 0) {
                 return BigDecimal.ZERO;
             }
@@ -764,8 +769,12 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
                 .eq(CostAccountShare::getHospId, hospId));
         Map<Long, CostAccountShare> accountShareMap = costAccountShareList.stream().collect(Collectors.toMap(CostAccountShare::getId, synOne -> synOne));
         List<AllocationReportVO> allocationReportVOList = BeanUtil.convertList(allocationList, AllocationReportVO.class);
+        List<CostShareParamVO> shareParamVOList = shareParamService.getAll(hospId);
+        Map<String,Integer> shareParamStatusMap = shareParamVOList.stream().collect(Collectors.toMap(CostShareParamVO::getShareParamCode, paramVO -> paramVO.getStatus() == null ? NumberConstant.ONE : paramVO.getStatus(), (a, b) -> b));
+        List<AllocationReportVO> removeList = new ArrayList<>();
         // 设置会计科目的
         allocationReportVOList.forEach(i -> {
+
             Long accountShareId = i.getAccountShareId();
             CostAccountShare costAccountShare = accountShareMap.get(accountShareId);
             if (Objects.isNull(costAccountShare)) {
@@ -810,8 +819,17 @@ public class AllocationServiceImpl extends ServiceImpl<AllocationMapper, Allocat
             i.setShareParamValueNums(i.getShareParamValueNum().toString());
             i.setShareParamRates(i.getShareParamRate().toString());
             i.setAmounts(i.getAmount().toString());
+            //校验是否有分摊参数未启用
+            Integer status = shareParamStatusMap.get(i.getShareParamCode());
+            if(status != null&&status.equals(NumberConstant.ZERO)){
+                removeList.add(i);
+            }
         });
+        //校验是否有分摊参数未启用 未启用分摊参数 移除
 
+        if(!CollectionUtils.isEmpty(removeList)){
+            allocationReportVOList.removeAll(removeList);
+        }
         return allocationReportVOList;
     }
 

+ 12 - 7
src/main/java/com/kcim/service/impl/CenterServiceImpl.java

@@ -13,10 +13,8 @@ import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static com.kcim.common.constants.Constant.CENTER_SYSTEM_ID;
 import static com.kcim.common.constants.Constant.LOCAL_SYSTEM_ID;
@@ -61,8 +59,11 @@ public class CenterServiceImpl implements CenterService {
 
     @Override
     public Map<String, String> getDepartment() {
-        Object dict = endPoint.getDepartment();
-        return  (Map<String, String>) dict;
+        Object departmentFilter = endPoint.getDepartmentFilter(null);
+        List<SysDepartment> sysDepartments = JSON.parseArray(JSON.toJSONString(departmentFilter), SysDepartment.class);
+        return sysDepartments.stream().collect(Collectors.toMap(SysDepartment::getCode, SysDepartment::getName, (a, b) -> b));
+
+//        return  (Map<String, String>) dict;
 
     }
 
@@ -93,5 +94,9 @@ public class CenterServiceImpl implements CenterService {
         return new ArrayList<>();
     }
 
-
+    @Override
+    public List<SysDepartment> getDepartmentByDepartmentIds(List<Long> departmentIds) {
+        Object departmentByDepartmentIds = endPoint.getDepartmentByDepartmentIds(departmentIds);
+        return JSON.parseArray(JSON.toJSONString(departmentByDepartmentIds), SysDepartment.class);
+    }
 }

+ 430 - 0
src/main/java/com/kcim/service/impl/ComputeMedicalDepartmentProfitServiceImpl.java

@@ -0,0 +1,430 @@
+package com.kcim.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.kcim.common.constants.NumberConstant;
+import com.kcim.common.constants.SQLParameter;
+import com.kcim.common.enums.CustomSqlTypeEnum;
+import com.kcim.common.exception.CostException;
+import com.kcim.common.util.ComputeDateUtils;
+import com.kcim.dao.model.ComputeMedicalDepartmentProfit;
+import com.kcim.dao.model.ReportForm;
+import com.kcim.dao.model.Responsibility;
+import com.kcim.dao.repository.ComputeMedicalDepartmentProfitRepository;
+import com.kcim.dao.repository.CostDepartmentProfitRepository;
+import com.kcim.service.ComputeMedicalDepartmentProfitService;
+import com.kcim.service.ReportFormService;
+import com.kcim.service.ResponsibilityService;
+import com.kcim.service.SqlService;
+import com.kcim.vo.MedicalResponsibilityVo;
+import com.kcim.vo.ReportFormProfitVo;
+import com.kcim.web.reponse.MedicalProfitResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-25 15:35
+ **/
+@Service("ComputeMedicalDepartmentProfitService")
+@Slf4j
+public class ComputeMedicalDepartmentProfitServiceImpl implements ComputeMedicalDepartmentProfitService {
+
+
+    SqlService sqlService;
+    ComputeMedicalDepartmentProfitRepository repository;
+    ResponsibilityService responsibilityService ;
+    ReportFormService reportFormService;
+    CostDepartmentProfitRepository costDepartmentProfitRepository;
+
+    public ComputeMedicalDepartmentProfitServiceImpl(SqlService sqlService, ComputeMedicalDepartmentProfitRepository repository, ResponsibilityService responsibilityService, ReportFormService reportFormService, CostDepartmentProfitRepository costDepartmentProfitRepository) {
+        this.sqlService = sqlService;
+        this.repository = repository;
+        this.responsibilityService = responsibilityService;
+        this.reportFormService = reportFormService;
+        this.costDepartmentProfitRepository = costDepartmentProfitRepository;
+    }
+
+    /**
+     * 科室门住损益计算
+     *
+     * @param computeDate 核算年月
+     * @param hospId      院区id
+     * @param reportType  报表类型
+     */
+    @Override
+    public void calcMedicalProfit(String computeDate, Long hospId, String reportType) {
+//        Integer year = ComputeDateUtils.getComputeYear(computeDate);
+//        Integer month = ComputeDateUtils.getComputeMonth(computeDate);
+//        List<CostDepartmentProfit> departmentProfits = costDepartmentProfitRepository.getCurrentByReportType(year, month, hospId, reportType);
+//        if (CollectionUtils.isEmpty(departmentProfits)) {
+//            throw new CostException(500, "未进行科室损益计算");
+//        }
+        Map<String,String> sqlParameter = new HashMap<>();
+        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+        sqlParameter.put(SQLParameter.REPORT_TYPE_CODE,reportType);
+        sqlService.autoExecuteSql(CustomSqlTypeEnum.INTEGRATIVE_PROFIT_CALC.getCode(),sqlParameter);
+    }
+
+    /**
+     * 获取科室门住损益计算列表
+     *
+     * @param computeDate        核算年月
+     * @param hospId             院区id
+     * @param reportType         报表类型
+     * @param responsibilityCode 责任中心代码
+     * @param responsibilityType 责任中心类型
+     * @return 列表
+     */
+    @Override
+    public Object getMedicalProfit(String computeDate, Long hospId, String reportType, String responsibilityCode, Integer responsibilityType) {
+        List<ComputeMedicalDepartmentProfit> medicalProfitList = repository.getByResponsibilityCode(computeDate, hospId,reportType,responsibilityCode,responsibilityType);
+        if(CollectionUtils.isEmpty(medicalProfitList)){
+            throw new CostException(reportType+"未进行科室门住损益计算,请先进行损益计算");
+        }
+        List<ComputeMedicalDepartmentProfit> model = medicalProfitList.stream().filter(distinctByKey(ComputeMedicalDepartmentProfit::getReportId)).collect(Collectors.toList());
+        List<ComputeMedicalDepartmentProfit> collect = medicalProfitList.stream().filter(f -> f.getMedicalType() == null).collect(Collectors.toList());
+        if(!CollectionUtils.isEmpty(collect)){
+            throw new CostException("数据类型medicalType不能为空!");
+        }
+        List<ReportForm> byReportType = reportFormService.getByReportType(hospId, reportType);
+        if(CollectionUtils.isEmpty(byReportType)){
+            throw new CostException("未找到【"+reportType+"】对应的报表项目");
+        }
+        Map<Long,Integer> sortMap = new HashMap<>();
+        Map<Long,Integer> hideMap = new HashMap<>();
+        for (ReportForm reportForm : byReportType) {
+            if(reportForm.getSort() != null){
+                sortMap.put(reportForm.getId(), reportForm.getSort());
+            }
+            if(reportForm.getHide() != null){
+                hideMap.put(reportForm.getId(), reportForm.getHide());
+            }
+        }
+
+        if(!CollectionUtils.isEmpty(sortMap)){
+            for (ComputeMedicalDepartmentProfit profit : model) {
+                profit.setSort(sortMap.get(profit.getReportId()));
+            }
+        }
+        if(!CollectionUtils.isEmpty(hideMap)){
+            for (ComputeMedicalDepartmentProfit profit : model) {
+                if(hideMap.get(profit.getReportId())!= null){
+                    profit.setHide(hideMap.get(profit.getReportId()));
+                }else{
+                    profit.setHide(NumberConstant.ONE);
+                }
+            }
+        }else {
+            model.forEach(profit -> profit.setHide(NumberConstant.ONE));
+        }
+
+        Map<Integer, List<ComputeMedicalDepartmentProfit>> profitGroup = medicalProfitList.stream().collect(Collectors.groupingBy(ComputeMedicalDepartmentProfit::getMedicalType));
+        Map<Integer,Map<Long, BigDecimal>> profitAmountMap = new HashMap<>();
+        profitGroup.forEach((k,v)->{
+            Map<Long, BigDecimal> map = new HashMap<>();
+            v.forEach(f->
+                    map.put(f.getReportId(), f.getAmount())
+                    );
+            profitAmountMap.put(k,map);
+        });
+        DecimalFormat df = new DecimalFormat("0.00%");
+        //获取上个月数据
+        String preComputeDate = ComputeDateUtils.getPreComputeDate(computeDate);
+        List<ComputeMedicalDepartmentProfit> preMonthMedicalProfitList = repository.getByResponsibilityCode(preComputeDate, hospId,reportType,responsibilityCode,responsibilityType);
+        Map<Integer,Map<Long, BigDecimal>> preProfitAmountMap = new HashMap<>();
+        Map<Integer,Map<Long, String>> preProfitPercentMap = new HashMap<>();
+        handleData(profitAmountMap, df, preProfitAmountMap, preProfitPercentMap, preMonthMedicalProfitList);
+        //获取上一年数据
+        Map<Integer,Map<Long, BigDecimal>> preYearProfitAmountMap = new HashMap<>();
+        Map<Integer,Map<Long, String>> preYearProfitPercentMap = new HashMap<>();
+        String preComputeDateYear = ComputeDateUtils.getPreComputeDateYear(computeDate);
+        List<ComputeMedicalDepartmentProfit> preYearMedicalProfitList = repository.getByResponsibilityCode(preComputeDateYear, hospId,reportType,responsibilityCode,responsibilityType);
+        handleData(profitAmountMap, df, preYearProfitAmountMap, preYearProfitPercentMap, preYearMedicalProfitList);
+        //todo:因报表项目调整存在找不到报表项目的情况,所以以本月所有数据为准作为模版
+        List<ReportFormProfitVo> reportFormProfitVos = new ArrayList<>();
+        List<ComputeMedicalDepartmentProfit> departmentProfits = model.stream().filter(f -> f.getHide().equals(NumberConstant.ONE)).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(departmentProfits)){
+            throw new CostException("未找到需要显示的报表项目");
+        }
+        for (ComputeMedicalDepartmentProfit profit : departmentProfits) {
+            ReportFormProfitVo vo = new ReportFormProfitVo();
+            vo.setId(profit.getReportId());
+            vo.setParentId(profit.getReportParentId());
+            vo.setReportName(profit.getReportName());
+            vo.setNum(profit.getReportNum());
+            vo.setReportType(Integer.valueOf(reportType));
+            vo.setSort(profit.getSort());
+            reportFormProfitVos.add(vo);
+        }
+
+
+//        List<ReportFormProfitVo> reportFormProfitVos = BeanUtil.convertList(reportFormList, ReportFormProfitVo.class);
+        Map<Integer,List<ReportFormProfitVo>> responses = new HashMap<>();
+        profitAmountMap.forEach((medicalType,amountMap)->{
+            Map<Long, BigDecimal> preMonthAmount = new HashMap<>();
+            if(!CollectionUtils.isEmpty(preProfitAmountMap)){
+                preMonthAmount = preProfitAmountMap.get(medicalType);
+            }
+            Map<Long, String> preMonthPercent = new HashMap<>();
+            if(!CollectionUtils.isEmpty(preProfitPercentMap)){
+                preMonthPercent = preProfitPercentMap.get(medicalType);
+            }
+            Map<Long, BigDecimal> preYearAmount = new HashMap<>();
+            if(!CollectionUtils.isEmpty(preYearProfitAmountMap)){
+                preYearAmount = preYearProfitAmountMap.get(medicalType);
+            }
+            Map<Long, String> preYearPercent = new HashMap<>();
+            if(!CollectionUtils.isEmpty(preYearProfitPercentMap)){
+                preYearPercent = preYearProfitPercentMap.get(medicalType);
+            }
+            for (ReportFormProfitVo reportFormProfitVo : reportFormProfitVos) {
+                reportFormProfitVo.setMedicalType(medicalType);
+
+                BigDecimal bigDecimal = amountMap.get(reportFormProfitVo.getId());
+                reportFormProfitVo.setCurrentAmount(bigDecimal);
+                if(!CollectionUtils.isEmpty(preMonthAmount)){
+                    BigDecimal value = preMonthAmount.get(reportFormProfitVo.getId());
+                    if(value != null){
+                        reportFormProfitVo.setPreMonthAmount(value);
+                    }
+                }
+                if(!CollectionUtils.isEmpty(preMonthPercent)){
+                    String value = preMonthPercent.get(reportFormProfitVo.getId());
+                    if(!StringUtils.isEmpty(value)){
+                        reportFormProfitVo.setPreMonthPercent(value);
+                    }
+                }
+                if(!CollectionUtils.isEmpty(preYearAmount)){
+                    BigDecimal value = preYearAmount.get(reportFormProfitVo.getId());
+                    if(value != null){
+                        reportFormProfitVo.setPreYearAmount(value);
+                    }
+                }
+                if(!CollectionUtils.isEmpty(preYearPercent)){
+                    String value  = preYearPercent.get(reportFormProfitVo.getId());
+                    if(!StringUtils.isEmpty(value)){
+                        reportFormProfitVo.setPreYearPercent(value);
+                    }
+                }
+            }
+            Map<Long, List<ReportFormProfitVo>> collectGroup = reportFormProfitVos.stream().collect(Collectors.groupingBy(ReportFormProfitVo::getParentId));
+            List<ReportFormProfitVo> costProfitVos = collectGroup.get(NumberConstant.ZERO_L);
+            collectGroup.remove(NumberConstant.ZERO_L);
+            for (ReportFormProfitVo costProfitVo : costProfitVos) {
+                List<ReportFormProfitVo> costProfitVo1 = collectGroup.get(costProfitVo.getId());
+                if (!CollectionUtils.isEmpty(costProfitVo1)) {
+                    costProfitVo.setChildren(setChildren(costProfitVo1, collectGroup));
+                }
+            }
+            reportFormProfitSort(costProfitVos);
+            responses.put(medicalType, costProfitVos);
+        });
+        if(!CollectionUtils.isEmpty(responses)){
+            List<MedicalProfitResponse> returnList = new ArrayList<>();
+            responses.forEach((k,v)->{
+                MedicalProfitResponse response = new MedicalProfitResponse();
+                response.setMedicalType(k);
+                if(k.equals(NumberConstant.ONE)){
+                    response.setMedicalTypeName("门诊");
+                } else if (k.equals(NumberConstant.TWO)) {
+                    response.setMedicalTypeName("住院");
+                }else {
+                    response.setMedicalTypeName("总计");
+                }
+                response.setData(v);
+                returnList.add(response);
+            });
+            return returnList;
+        }
+        return new ArrayList<>();
+    }
+    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
+        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;}
+    /**
+     * 计算同比 环比占比
+     * @param profitAmountMap 当月数据
+     * @param df 占比格式
+     * @param preYearProfitAmountMap  数据值
+     * @param preYearProfitPercentMap 数据占比
+     * @param preYearMedicalProfitList 出参
+     */
+    private void handleData(Map<Integer, Map<Long, BigDecimal>> profitAmountMap, DecimalFormat df, Map<Integer, Map<Long, BigDecimal>> preYearProfitAmountMap, Map<Integer, Map<Long, String>> preYearProfitPercentMap, List<ComputeMedicalDepartmentProfit> preYearMedicalProfitList) {
+        if(!CollectionUtils.isEmpty(preYearMedicalProfitList)){
+            Map<Integer, List<ComputeMedicalDepartmentProfit>> preYearProfitGroup = preYearMedicalProfitList.stream().collect(Collectors.groupingBy(ComputeMedicalDepartmentProfit::getMedicalType));
+            preYearProfitGroup.forEach((k,v)->{
+                Map<Long, BigDecimal> map = new HashMap<>();
+                v.forEach(f->
+                        map.put(f.getReportId(), f.getAmount())
+                );
+                preYearProfitAmountMap.put(k,map);
+            });
+            profitAmountMap.forEach((medicalType,amountMap)->{
+                Map<Long, BigDecimal> map = preYearProfitAmountMap.get(medicalType);
+                if(CollectionUtils.isEmpty(map)){
+                    return;
+                }
+                Map<Long, String> percent = new HashMap<>();
+                amountMap.forEach((reportId,amount)->{
+                    BigDecimal bigDecimal = map.get(reportId);
+                    if(bigDecimal != null){
+                        if(bigDecimal.compareTo(BigDecimal.ZERO.setScale(6, RoundingMode.HALF_UP)) != 0){
+                            BigDecimal divide = amount.subtract(bigDecimal).divide(bigDecimal, 4, RoundingMode.HALF_UP);
+                            percent.put(reportId,df.format(divide));
+                        }
+
+                    }
+                });
+                preYearProfitPercentMap.put(medicalType, percent);
+            });
+        }
+    }
+
+    private List<ReportFormProfitVo> setChildren(List<ReportFormProfitVo> child, Map<Long, List<ReportFormProfitVo>> collect) {
+        for (ReportFormProfitVo costProfitVo : child) {
+            if (!CollectionUtils.isEmpty(collect.get(costProfitVo.getId()))) {
+                costProfitVo.setChildren(setChildren(collect.get(costProfitVo.getId()), collect));
+            }
+        }
+        if (!CollectionUtils.isEmpty(child)) {
+            child.sort(Comparator.comparing(ReportFormProfitVo::getSort, Comparator.nullsLast(Integer::compareTo)));
+        }
+        return child;
+    }
+
+
+    /**
+     * 获取责任中心列表
+     *
+     * @param computeDate 核算年月
+     * @param hospId      院区id
+     * @param reportType  报表类型
+     * @return 责任中心列表
+     */
+    @Override
+    public Object getMedicalResponsibility(String computeDate, Long hospId, String reportType) {
+        //获取当月所有数据 提取核算单元数据
+        List<ComputeMedicalDepartmentProfit> medicalProfitList = repository.getByComputeDate(computeDate, hospId,reportType);
+        if(CollectionUtils.isEmpty(medicalProfitList)){
+            throw new CostException(reportType+"未进行科室门住损益计算");
+        }
+        //获取当前院区所有的责任中心
+        List<Responsibility> responsibilityAllList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
+                .eq(Responsibility::getHospId, hospId));
+        Map<Long, Responsibility> responsibilityIdMap = responsibilityAllList.stream().collect(Collectors.toMap(Responsibility::getId, responsibility -> responsibility, (a, b) -> b));
+        Map<String, Responsibility> responsibilityCodeMap = responsibilityAllList.stream().collect(Collectors.toMap(Responsibility::getResponsibilityCode, responsibility -> responsibility, (a, b) -> b));
+        //提取责任中心数据
+        List<MedicalResponsibilityVo> computeResponsibityList = new ArrayList<>();
+        for (ComputeMedicalDepartmentProfit profit : medicalProfitList) {
+            if(!CollectionUtils.isEmpty(computeResponsibityList)){
+                boolean match = computeResponsibityList.stream().anyMatch(f -> f.getResponsibilityCode().equals(profit.getResponsibilityCode()));
+                if (match){
+                    continue;
+                }
+            }
+            MedicalResponsibilityVo vo = new MedicalResponsibilityVo();
+            vo.setResponsibilityCode(profit.getResponsibilityCode());
+            vo.setResponsibilityName(profit.getResponsibilityName());
+            vo.setResponsibilityType(profit.getResponsibilityType());
+            Responsibility responsibility = responsibilityCodeMap.get(profit.getResponsibilityCode());
+            if(Objects.nonNull(responsibility)){
+                vo.setResponsibilityId(responsibility.getId());
+                vo.setParentId(responsibility.getParentId());
+                vo.setSort(responsibility.getSort());
+            }
+            computeResponsibityList.add(vo);
+        }
+        //通过查询的最下层责任中心 找到其所有父类责任中心
+        List<MedicalResponsibilityVo> parentResponseList = new ArrayList<>();
+        for (MedicalResponsibilityVo responsibility : computeResponsibityList) {
+            if (responsibility.getParentId().equals(NumberConstant.ZERO_L)) {
+                parentResponseList.add(responsibility);
+            } else {
+                Responsibility responsibility1 = responsibilityIdMap.get(responsibility.getParentId());
+                if (Objects.nonNull(responsibility1)) {
+                    parentResponseList.add(converResponsibilityToMedicalResponsibilityVo(responsibility1));
+                    if (!responsibility1.getParentId().equals(NumberConstant.ZERO_L)) {
+                        getResponsibilityParent(responsibility1, responsibilityIdMap, parentResponseList);
+                    }
+                }
+            }
+        }
+        //去除重复组装数据
+        if (!CollectionUtils.isEmpty(parentResponseList)) {
+            //去重
+            List<MedicalResponsibilityVo> collect = parentResponseList.stream().distinct().collect(Collectors.toList());
+            computeResponsibityList.addAll(collect);
+        }
+        List<MedicalResponsibilityVo> collectDistinct = computeResponsibityList.stream().distinct().collect(Collectors.toList());
+
+        Map<Long, List<MedicalResponsibilityVo>> collect = collectDistinct.stream().collect(Collectors.groupingBy(MedicalResponsibilityVo::getParentId));
+        List<MedicalResponsibilityVo> responsibilities = collect.get(NumberConstant.ZERO_L);
+        collect.remove(NumberConstant.ZERO_L);
+        for (MedicalResponsibilityVo responsibility : responsibilities) {
+            List<MedicalResponsibilityVo> responsibilities1 = collect.get(responsibility.getResponsibilityId());
+            if (!CollectionUtils.isEmpty(responsibilities1)) {
+                responsibility.setChild(setResponsibilityChildren(responsibilities1, collect));
+            }
+        }
+
+        responsibilitySort(responsibilities);
+        return responsibilities;
+    }
+    private List<MedicalResponsibilityVo> setResponsibilityChildren(List<MedicalResponsibilityVo> child, Map<Long, List<MedicalResponsibilityVo>> collect) {
+        for (MedicalResponsibilityVo responsibility : child) {
+            if (!CollectionUtils.isEmpty(collect.get(responsibility.getResponsibilityId()))) {
+                responsibility.setChild(setResponsibilityChildren(collect.get(responsibility.getResponsibilityId()), collect));
+            }
+        }
+        return child;
+    }
+    private MedicalResponsibilityVo converResponsibilityToMedicalResponsibilityVo(Responsibility responsibility){
+        MedicalResponsibilityVo vo = new MedicalResponsibilityVo();
+        vo.setResponsibilityCode(responsibility.getResponsibilityCode());
+        vo.setResponsibilityName(responsibility.getResponsibilityName());
+        vo.setResponsibilityId(responsibility.getId());
+        vo.setParentId(responsibility.getParentId());
+        vo.setSort(responsibility.getSort());
+        return vo;
+    }
+    private void getResponsibilityParent(Responsibility responsibility, Map<Long, Responsibility> collect, List<MedicalResponsibilityVo> addList) {
+        Responsibility responsibility1 = collect.get(responsibility.getParentId());
+        if (Objects.nonNull(responsibility1)) {
+            addList.add(converResponsibilityToMedicalResponsibilityVo(responsibility1));
+            if (!responsibility1.getParentId().equals(NumberConstant.ZERO_L)) {
+                getResponsibilityParent(responsibility1, collect, addList);
+            }
+        }
+    }
+
+    private void responsibilitySort(List<MedicalResponsibilityVo> responsibilityList) {
+        for (MedicalResponsibilityVo responsibility : responsibilityList) {
+            if (!CollectionUtils.isEmpty(responsibility.getChild())) {
+                responsibilitySort(responsibility.getChild());
+            }
+        }
+        responsibilityList.sort(Comparator.comparing(MedicalResponsibilityVo::getSort, Comparator.nullsLast(Integer::compareTo)));
+    }
+
+    private void reportFormProfitSort(List<ReportFormProfitVo> T) {
+        for (ReportFormProfitVo reportFormProfitVo : T) {
+            if (!CollectionUtils.isEmpty(reportFormProfitVo.getChildren())) {
+                reportFormProfitSort(reportFormProfitVo.getChildren());
+            }
+        }
+        T.sort(Comparator.comparing(ReportFormProfitVo::getSort, Comparator.nullsLast(Integer::compareTo)));
+    }
+}

+ 10 - 5
src/main/java/com/kcim/service/impl/ComputePatientCostServiceImpl.java

@@ -2,12 +2,12 @@ package com.kcim.service.impl;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.kcim.common.constants.NumberConstant;
+import com.kcim.common.constants.SQLParameter;
+import com.kcim.common.enums.CustomSqlTypeEnum;
 import com.kcim.common.enums.ReportItemTypeEnum;
-import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.PageUtils;
-import com.kcim.common.util.UserContext;
-import com.kcim.dao.model.*;
+import com.kcim.dao.model.ComputePatientCostDetail;
 import com.kcim.dao.model.dto.ComputeItemGroupByVisitNoDto;
 import com.kcim.dao.model.dto.ComputePatientCostPageDto;
 import com.kcim.dao.repository.ComputeItemCostRepository;
@@ -16,6 +16,7 @@ import com.kcim.dao.repository.ComputePatientCostRepository;
 import com.kcim.dao.repository.ImportPatientInfoRepository;
 import com.kcim.service.ComputeItemCostService;
 import com.kcim.service.ComputePatientCostService;
+import com.kcim.service.SqlService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -25,7 +26,6 @@ import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @program: CostAccount
@@ -55,7 +55,7 @@ public class ComputePatientCostServiceImpl implements ComputePatientCostService
     ComputeItemCostRepository computeItemCostRepository;
 
     ComputeItemCostService computeItemCostService;
-
+    SqlService sqlService;
 
     /**
      * 成本核算-病人成本计算-获取列表
@@ -84,6 +84,10 @@ public class ComputePatientCostServiceImpl implements ComputePatientCostService
     @Override
     @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
     public void patientCostCalculate(String computeDate) {
+        Map<String,String> sqlParameter = new HashMap<>();
+        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+        sqlService.autoExecuteSql(CustomSqlTypeEnum.PT_COST_CALC.getCode(),sqlParameter);
+/*      暂时更换成自定义sql 执行 下面代码留用
         try {
             //获取导入的患者信息
             List<ImportPatientInfo> patientInfos = importPatientInfoRepository.getByComputeDate(computeDate);
@@ -146,6 +150,7 @@ public class ComputePatientCostServiceImpl implements ComputePatientCostService
             log.error(e.getMessage());
             throw new CostException(e.getMessage());
         }
+*/
 
     }
 

+ 30 - 24
src/main/java/com/kcim/service/impl/CostAccountShareServiceImpl.java

@@ -6,12 +6,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.core.type.TypeReference;
+import com.kcim.common.constants.NumberConstant;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.JacksonUtil;
 import com.kcim.common.util.PageUtils;
 import com.kcim.common.util.UserContext;
-import com.kcim.common.constants.NumberConstant;
 import com.kcim.dao.mapper.CostAccountShareMapper;
 import com.kcim.dao.model.Accounting;
 import com.kcim.dao.model.CostAccountShare;
@@ -22,10 +22,7 @@ import com.kcim.dao.model.dto.CostAccountShareEditDto;
 import com.kcim.dao.model.dto.CostAccountShareSaveDto;
 import com.kcim.dao.model.dto.ShareParamEditDto;
 import com.kcim.service.*;
-import com.kcim.vo.CostAccountShareVO;
-import com.kcim.vo.CostShareParamStatusVO;
-import com.kcim.vo.CostShareParamVO;
-import com.kcim.vo.ShareParamProportionVO;
+import com.kcim.vo.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -33,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
@@ -81,8 +79,8 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
                         .orderByDesc(Responsibility::getCreateTime)
         );
 
-        Map<Long,String> map = new HashMap<>();
-        if(!CollectionUtils.isEmpty(responsibilities)){
+        Map<Long, String> map = new HashMap<>();
+        if (!CollectionUtils.isEmpty(responsibilities)) {
             map = responsibilities.stream().collect(Collectors.toMap(Responsibility::getId, Responsibility::getShareName, (a, b) -> b));
         }
 
@@ -98,6 +96,16 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
             if (!CollectionUtils.isEmpty(map)) {
                 i.setShareName(map.get(i.getResponsibilityId()));
             }
+            if (!StringUtils.isEmpty(i.getParamList())) {
+                List<AccountShareVO> accountShareVOs = JacksonUtil.str2ObjList(i.getParamList(), List.class, AccountShareVO.class);
+                if (!CollectionUtils.isEmpty(accountShareVOs)) {
+                    StringBuilder shareParamBuilder = new StringBuilder();
+                    for (AccountShareVO accountShareVO : accountShareVOs) {
+                        shareParamBuilder.append(accountShareVO.getShareParamName()).append("x").append(accountShareVO.getShareParamPopout()).append("%").append("|");
+                    }
+                    i.setShareParamMap(org.apache.commons.lang3.StringUtils.removeEnd(shareParamBuilder.toString(), "|"));
+                }
+            }
         }
 //        getMessage(hospId, costAccountShareVOList);
         PageUtils pageUtils = new PageUtils(pages);
@@ -236,18 +244,14 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         if (Objects.isNull(costAccountShare)) {
             throw new CostException(500, "成本分摊参数对应数据不存在");
         }
-        baseMapper.deleteById(id);
+//        baseMapper.deleteById(id);
         // 新增责任中心成本对照数据
         CostAccountShareSaveDto costAccountShareSaveDto = BeanUtil.convertObj(costAccountShareEditDto, CostAccountShareSaveDto.class);
         // 检验输入的数据是否符合规则
         checkAccountShare(costAccountShareSaveDto, hospId);
         CostAccountShareEditDto accountShareEditDto = BeanUtil.convertObj(costAccountShareSaveDto, CostAccountShareEditDto.class);
-        CostAccountShare costAccountShareRequest = BeanUtil.convertObj(accountShareEditDto, CostAccountShare.class);
-        costAccountShareRequest.setId(null);
-        costAccountShareRequest.setHospId(hospId);
-        costAccountShareRequest.setParamList(costAccountShare.getParamList());
-        costAccountShareRequest.setCreateTime(System.currentTimeMillis());
-        baseMapper.insert(costAccountShareRequest);
+        BeanUtil.convertObj(accountShareEditDto, costAccountShare);
+        baseMapper.updateById(costAccountShare);
     }
 
 
@@ -279,12 +283,11 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
                 }
             });
             // 检验输入的数据的和是否是100
-            AtomicReference<Integer> sum = new AtomicReference<>(0);
+            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.00"));
             shareParamProportionVOList.forEach(i -> {
-                sum.updateAndGet(v -> v + i.getShareParamPopout());
+                sum.updateAndGet(v -> v.add(i.getShareParamPopout()));
             });
-            int max = Integer.parseInt(sum.toString());
-            if (!NumberConstant.ONE_HUNDRED.equals(max)) {
+            if (sum.get().compareTo(new BigDecimal("100.00"))!=0) {
                 throw new CostException(500, "分摊比例的和不是100");
             }
 
@@ -300,6 +303,7 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
             //
 //            String paramList = JsonUtil.toJSONString(shareParamProportionVOList);
             String paramList = JacksonUtil.obj2StrPretty(shareParamProportionVOList);
+
             costAccountShare.setParamList(paramList);
         } else {
             costAccountShare.setParamList(null);
@@ -325,7 +329,8 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         String paramList = costAccountShare.getParamList();
 //        return JsonUtil.toList(paramList, ShareParamProportionVO.class);
 //        return JacksonUtil.string2ObjList(paramList, List.class, ShareParamProportionVO.class);
-        return JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {});
+        return JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {
+        });
     }
 
     /**
@@ -346,7 +351,8 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         List<CostShareParamStatusVO> costShareParamStatusVOList = BeanUtil.convertList(costShareParamServiceAll, CostShareParamStatusVO.class);
         if (!StringUtils.isEmpty(paramList)) {
 //            List<ShareParamProportionVO> shareParamProportionVOList = JsonUtil.toList(paramList, ShareParamProportionVO.class);
-            List<ShareParamProportionVO> shareParamProportionVOList = JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {});
+            List<ShareParamProportionVO> shareParamProportionVOList = JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {
+            });
             Map<Long, List<ShareParamProportionVO>> map = shareParamProportionVOList.stream().collect(Collectors.groupingBy(ShareParamProportionVO::getId));
             costShareParamStatusVOList.forEach(i -> {
                 Long paramId = i.getId();
@@ -415,7 +421,7 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
 //        List<Long> responsibilityIds = this.list(new QueryWrapper<CostAccountShare>().lambda().eq(CostAccountShare::getHospId, hospId)).stream().map(CostAccountShare::getResponsibilityId).distinct().collect(Collectors.toList());
         // 执行类型的分摊级别的Id的集合
         List<Long> costShareIds = costShareLevelService.list(new QueryWrapper<CostShareLevel>().lambda()
-                .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getCalcType, calcType))
+                        .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getCalcType, calcType))
                 .stream().map(CostShareLevel::getId).distinct().collect(Collectors.toList());
         String accountingIds = costAccountShare.getAccountingIds();
 //        List<Long> responsibilityIdList=null;
@@ -426,8 +432,8 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
         // 筛选指定类型的责任中心 并且当前没有设置的责任中心
 //        List<Long> finalResponsibilityIdList = responsibilityIdList;
         List<Responsibility> responsibilityList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
-                .eq(Responsibility::getHospId, hospId)
-                .ne(Responsibility::getShareId,NumberConstant.ZERO))
+                        .eq(Responsibility::getHospId, hospId)
+                        .ne(Responsibility::getShareId, NumberConstant.ZERO))
                 .stream().filter(i -> costShareIds.contains(i.getShareId()) && !responsibilityId.equals(i.getId())).collect(Collectors.toList());
 //        && (CollUtil.isNotEmpty(finalResponsibilityIdList) && !finalResponsibilityIdList.contains(i.getId()))
         return responsibilityList;
@@ -465,7 +471,7 @@ public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMap
      * @param idList id集合
      */
     @Override
-    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     public void deleteByIds(List<Long> idList) {
         this.removeByIds(idList);
     }

+ 1 - 48
src/main/java/com/kcim/service/impl/CostDataServiceImpl.java

@@ -3,28 +3,19 @@ package com.kcim.service.impl;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.kcim.common.constants.Constant;
 import com.kcim.common.constants.NumberConstant;
-import com.kcim.common.constants.SQLParameter;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.PageUtils;
-import com.kcim.common.util.UserContext;
 import com.kcim.dao.model.ComputeCheckResult;
-import com.kcim.dao.model.Sql;
 import com.kcim.dao.repository.ComputeCheckResultRepository;
 import com.kcim.service.CenterService;
 import com.kcim.service.CostDataService;
 import com.kcim.service.SqlService;
 import com.kcim.vo.DictDataVo;
-import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.jdbc.SqlRunner;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
 import java.util.*;
 
 /**
@@ -152,47 +143,9 @@ public class CostDataServiceImpl implements CostDataService {
 
 
     public void autoExecuteSql(String sqlType, Map<String,String> parameter) {
-        List<Sql> sqlList = sqlService.getSqlBySqlType(sqlType);
-
-        //取出需要执行的sql
-        if(!CollectionUtils.isEmpty(sqlList)){
-            sqlList.sort(Comparator.comparing(Sql::getSort,Comparator.nullsLast(Integer::compareTo)));
-            for(Sql sql:sqlList){
-                String executeSql = sql.getSql();
-                executeSql = MatchSystemParameter(executeSql);
-                //替换传参
-                if(!CollectionUtils.isEmpty(parameter)){
-                    for(String s:parameter.keySet()){
-                        //拼接 #
-                        String sqlFilter = "#" + s;
-                        if (executeSql.contains(sqlFilter)) {
-                            executeSql = executeSql.replace(sqlFilter, parameter.get(s));
-                        }
-                    }
-                }
-                try {
-                    SqlRunner sqlRunner = new SqlRunner(getConnection());
-                    sqlRunner.run(executeSql);
-                } catch (SQLException | ClassNotFoundException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        }
+        sqlService.autoExecuteSql(sqlType,parameter);
 
     }
 
-    private Connection getConnection() throws SQLException, ClassNotFoundException {
-        Class.forName(driver);
-        return DriverManager.getConnection(url, username, password);
-    }
-    private static String MatchSystemParameter(String sql) {
-        if(StringUtils.isEmpty(sql)){
-            throw new CostException("无效自定义sql语句");
-        }
-        if (sql.contains(SQLParameter.HOSP_ID_CODE)) {
-            sql = sql.replace(SQLParameter.HOSP_ID_CODE, String.valueOf(UserContext.getCurrentLoginHospId()));
-        }
 
-        return sql;
-    }
 }

Plik diff jest za duży
+ 1184 - 309
src/main/java/com/kcim/service/impl/CostDepartmentProfitServiceImpl.java


+ 55 - 7
src/main/java/com/kcim/service/impl/CostReportServiceImpl.java

@@ -1,14 +1,14 @@
 package com.kcim.service.impl;
 
-import com.kcim.common.constants.Constant;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.UserContext;
 import com.kcim.dao.model.CostReport;
+import com.kcim.dao.model.CostReportIndex;
+import com.kcim.dao.repository.CostReportIndexRepository;
 import com.kcim.dao.repository.CostReportRepository;
 import com.kcim.service.CenterService;
 import com.kcim.service.CostReportService;
-import com.kcim.vo.DictDataVo;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -25,6 +25,8 @@ public class CostReportServiceImpl implements CostReportService {
     CostReportRepository repository;
     CenterService centerService;
 
+    CostReportIndexRepository costReportIndexRepository;
+
     /**
      * 获取报表列表
      * @param reportName 报表名称
@@ -37,10 +39,24 @@ public class CostReportServiceImpl implements CostReportService {
         if(CollectionUtils.isEmpty(list)){
             return new ArrayList<>();
         }
-        DictDataVo dict = centerService.getDict(Constant.REPORT_TYPE);
-        List<DictDataVo> dataVoList = dict.getDataVoList();
-        Map<String,String> map = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
-        list.forEach(costReport -> costReport.setTypeName(map.get(costReport.getType())));
+        //查询检索条件
+        List<Long> collect = list.stream().map(CostReport::getCode).collect(Collectors.toList());
+        List<CostReportIndex> byReportCode = costReportIndexRepository.getByReportCode(collect);
+        if(!CollectionUtils.isEmpty(byReportCode)){
+            Map<Long, List<CostReportIndex>> collect1 = byReportCode.stream().collect(Collectors.groupingBy(CostReportIndex::getReportCode));
+            for (CostReport costReport : list) {
+                List<CostReportIndex> costReportIndices = collect1.get(costReport.getCode());
+                if(!CollectionUtils.isEmpty(costReportIndices)){
+                    costReport.setReportIndex(costReportIndices);
+                }
+            }
+        }
+
+
+//        DictDataVo dict = centerService.getDict(Constant.REPORT_TYPE);
+//        List<DictDataVo> dataVoList = dict.getDataVoList();
+//        Map<String,String> map = dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
+//        list.forEach(costReport -> costReport.setTypeName(map.get(costReport.getType())));
         return list;
     }
 
@@ -54,7 +70,21 @@ public class CostReportServiceImpl implements CostReportService {
         report.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
         report.setCreateTime(new Date());
         report.setCode(repository.getCode());
+
         repository.save(report);
+        List<CostReportIndex> reportIndex = report.getReportIndex();
+        if(!CollectionUtils.isEmpty(reportIndex)){
+            reportIndex.forEach(f->f.setReportCode(report.getCode())
+                    .setHospId(UserContext.getHospId())
+                    .setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()))
+                    .setCreateTime(new Date()));
+            costReportIndexRepository.saveBatch(reportIndex);
+        }
+
+
+
+
+
 
     }
 
@@ -70,10 +100,26 @@ public class CostReportServiceImpl implements CostReportService {
             throw new CostException("编辑报表时,主键id必传");
         }
         CostReport costReport = repository.getById(id);
+        Long code = costReport.getCode();
         BeanUtil.convertObj(report, costReport);
         costReport.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
         costReport.setUpdateTime(new Date());
         repository.updateById(costReport);
+        List<CostReportIndex> reportIndex = report.getReportIndex();
+        if(!CollectionUtils.isEmpty(reportIndex)){
+            costReportIndexRepository.removeByReportCode(code);
+
+            reportIndex.forEach(f->f.setReportCode(code)
+                    .setHospId(UserContext.getHospId())
+                    .setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()))
+                    .setCreateTime(new Date()));
+            costReportIndexRepository.saveBatch(reportIndex);
+        }else {
+            //走一下删除逻辑有可能是全部去除
+            costReportIndexRepository.removeByReportCode(code);
+
+        }
+
 
     }
 
@@ -83,8 +129,10 @@ public class CostReportServiceImpl implements CostReportService {
      */
     @Override
     public void deleteReport(Integer id) {
-        repository.deleteReport(id);
         //删除对照相关数据
+        CostReport costReport = repository.getById(id);
+        repository.deleteReport(id);
+        costReportIndexRepository.removeByReportCode(costReport.getCode());
 
     }
 }

+ 2 - 0
src/main/java/com/kcim/service/impl/CostShareParamServiceImpl.java

@@ -60,6 +60,7 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
         // 封装会计科目Id的集合
         costShareParamVOList.forEach(i -> {
             String accountingId = i.getAccountingId();
+
             if (StrUtil.isNotBlank(accountingId)) {
                 i.setAccountingIds(Arrays.asList(accountingId.split(StrUtil.COMMA)));
             } else {
@@ -67,6 +68,7 @@ public class CostShareParamServiceImpl extends ServiceImpl<CostShareParamMapper,
             }
         });
         PageUtils pageUtils = new PageUtils(pages);
+        costShareParamVOList.sort(Comparator.comparing(CostShareParamVO::getShareParamCode));
         pageUtils.setList(costShareParamVOList);
         return pageUtils;
     }

+ 45 - 53
src/main/java/com/kcim/service/impl/DrugMaterialCalculateServiceImpl.java

@@ -2,20 +2,21 @@ package com.kcim.service.impl;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.kcim.common.constants.NumberConstant;
-import com.kcim.common.constants.RedisKeyConstant;
+import com.kcim.common.constants.SQLParameter;
+import com.kcim.common.enums.CustomSqlTypeEnum;
 import com.kcim.common.enums.ItemTypeEnum;
 import com.kcim.common.enums.ReportItemTypeEnum;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.PageUtils;
-import com.kcim.common.util.UserContext;
-import com.kcim.dao.model.*;
+import com.kcim.dao.model.ComputeDrugCostDetail;
 import com.kcim.dao.model.dto.ComputeDrugCostPageDto;
-import com.kcim.dao.model.dto.ComputeItemCostPageDto;
+import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
 import com.kcim.dao.model.dto.SysDepartment;
 import com.kcim.dao.repository.*;
 import com.kcim.service.CenterService;
 import com.kcim.service.DrugMaterialCalculateService;
+import com.kcim.service.SqlService;
 import com.kcim.vo.ResponsibilityDepartIdVO;
 import com.kcim.vo.SessionUserVO;
 import com.kcim.vo.VisitNoResponsibilityMap;
@@ -29,7 +30,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -72,16 +72,18 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
 
     CenterService centerService;
 
+    SqlService sqlService;
 
-    private static final Integer LIMIT = 1000;
+    private static final Integer LIMIT = 5000;
 
     /**
-     * @param current
-     * @param pageSize
-     * @param computeDate
-     * @param responsibilityCode
-     * @param filter
-     * @return
+     * 查询药材成本
+     * @param current 当前页
+     * @param pageSize 页容量
+     * @param computeDate 核算年月
+     * @param responsibilityCode 责任中心
+     * @param filter 过滤条件
+     * @return 药材成本列表
      */
     @Override
     public Object drugMaterialCostCalculateList(Integer current, Integer pageSize, String computeDate, String responsibilityCode, String filter) {
@@ -95,27 +97,35 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
         return new PageUtils(records, Math.toIntExact(page.getTotal()), pageSize, current);    }
 
     /**
-     * @param computeDate
+     * 计算药材成本
+     * @param computeDate 核算年月
      */
     @Override
     @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
     public void drugMaterialCostCalculate(String computeDate) {
-        SessionUserVO currentUser = UserContext.getCurrentUser();
+//        SessionUserVO currentUser = UserContext.getCurrentUser();
+
+        Map<String,String> sqlParameter = new HashMap<>();
+        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+        sqlService.autoExecuteSql(CustomSqlTypeEnum.DRG_COST_CALC.getCode(),sqlParameter);
+/*  目前更换成自定义sql 下面代码保存留用
+
+
+        long l = System.currentTimeMillis();
 
 
         //获取收费项目数据(药材)
         long itemSize = importPatientItemRepository.getDrugCount(computeDate, currentUser);
         if (Objects.equals(itemSize, NumberConstant.ZERO_L)) {
-            log.error("当前核算年月【" + computeDate + "】未导入收费项目数据,计算中止");
+            log.error("当前核算年月【{}】未导入收费项目数据,计算中止", computeDate);
             throw new CostException("当前核算年月【" + computeDate + "】未导入收费项目数据,计算中止");
         }
         //把当月需要计算数据置成0
-        importPatientItemRepository.updateCalculateFlag(computeDate, currentUser);
+//        importPatientItemRepository.updateCalculateFlag(computeDate, currentUser);
         //作废上次计算记录
-        List<Integer> integers = repository.removeByComputeDate(computeDate, currentUser);
-        if (!CollectionUtils.isEmpty(integers)) {
-            detailRepository.removeByItemCostId(integers, currentUser);
-        }
+        repository.removeByComputeDate(computeDate, currentUser);
+        detailRepository.removeByComputeDate(computeDate, currentUser);
+
         //获到科室与责任中心对照
         List<VisitNoResponsibilityMap> patientResponsibility = getPatientResponsibility( currentUser);
         Map<String,String> responsibilityCodeMap = new HashMap<>();
@@ -141,17 +151,18 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
         //明细表公共对象
         ComputeDrugCostDetail costDetail = new ComputeDrugCostDetail();
         costDetail.setHospId(currentUser.getHospId());
+        costDetail.setComputeDate(computeDate);
         costDetail.setCreateUser(String.valueOf(currentUser.getId()));
         costDetail.setCreateTime(new Date());
         long count = (itemSize + LIMIT - 1) / LIMIT;
 //        long l = 0;
-        for (int j = 0; j < count; j++) {
-            List<ImportPatientItem> items = importPatientItemRepository.getByNoCalculateComputeDateDrugMaterial(computeDate, currentUser);
+        for (int j = 1; j <= count; j++) {
+            List<PatientItemDepartmentGroupVo> items = importPatientItemRepository.getByNoCalculateComputeDateDrugMaterial(j, LIMIT, computeDate, currentUser);
             List<ComputeDrugCostDetail> saveDetails = new ArrayList<>();
             List<ComputeDrugCost> saveCost = new ArrayList<>();
             if (!CollectionUtils.isEmpty(items)) {
                 for (int i = 0; i < items.size(); i++) {
-                    ImportPatientItem item = items.get(i);
+                    PatientItemDepartmentGroupVo item = items.get(i);
                     ComputeDrugCost itemCost = BeanUtil.convertObj(computeDrugCost, ComputeDrugCost.class);
                     itemCost.setVisitNo(item.getVisitNo());
                     itemCost.setCode(item.getItemCode());
@@ -159,8 +170,6 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
                     String typeCode = item.getItemTypeCode();
                     itemCost.setItemTypeCode(typeCode);
                     itemCost.setItemType(item.getItemType());
-                    itemCost.setOrderCode(item.getOrderCode());
-                    itemCost.setOrderName(item.getOrderName());
                     itemCost.setResponsibilityCode(responsibilityCodeMap.get(item.getExecuteDepartmentCode()));
                     itemCost.setResponsibilityName(responsibilityNameMap.get(item.getExecuteDepartmentCode()));
                     itemCost.setIndex(i);
@@ -170,30 +179,10 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
                     if (!CollectionUtils.isEmpty(details)) {
                         saveDetails.addAll(details);
                     }
-//                    double percent = (l + 1) / (double) itemSize * 100;
-//                    //这里对小数采用向下取整,例如99.5会取整为99
-//                    percent = Math.floor(percent / 2 + 25.0);
-//                    if (l == itemSize - 1) {
-//                        redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, 98.0);
-//                    } else {
-//                        redisUtil.set(RedisKeyConstant.PROGRESS + progressKey, percent);
-//                    }
-//                    System.out.println(l + "-" + itemSize);
-//                    l++;
-
                 }
                 if (!CollectionUtils.isEmpty(saveCost)) {
-                    //把责任中心加载到主表数据
-//                    for (ComputeDrugCost drugCost : saveCost) {
-//                        VisitNoResponsibilityMap responsibilityMap = patientResponsibility.get(drugCost.getVisitNo());
-//                        if(Objects.nonNull(responsibilityMap)){
-//                            drugCost.setResponsibilityCode(responsibilityMap.getResponsibilityCode());
-//                            drugCost.setResponsibilityName(responsibilityMap.getResponsibilityName());
-//                        }
-//                    }
 
-
-                    repository.saveBatch(saveCost, 100);
+                    repository.saveBatch(saveCost, 1000);
                     if (!CollectionUtils.isEmpty(saveDetails)) {
                         Map<Integer, Integer> indexId = saveCost.stream().collect(Collectors.toMap(ComputeDrugCost::getIndex, ComputeDrugCost::getId, (a, b) -> b));
                         Map<Integer, List<ComputeDrugCostDetail>> collect = saveDetails.stream().collect(Collectors.groupingBy(ComputeDrugCostDetail::getIndex));
@@ -204,14 +193,17 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
                             details.forEach(detail -> detail.setDrugCostId(costId));
                             saveCostDetails.addAll(details);
                         });
-                        detailRepository.saveBatch(saveCostDetails, 100);
+                        detailRepository.saveBatch(saveCostDetails, 1000);
                     }
                 }
                 //保存完把已计算过的置1
-                importPatientItemRepository.updateCalculateFlag(items);
-//                    connection.commit();
+//                importPatientItemRepository.updateCalculateFlag(items);
+
             }
         }
+        long end = System.currentTimeMillis();
+        log.info("{}ms", end - l);
+*/
     }
 
     private List<VisitNoResponsibilityMap> getPatientResponsibility(SessionUserVO currentUser) {
@@ -246,7 +238,7 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
 
     private List<ComputeDrugCostDetail> setDetails(Map<String, BigDecimal> drugCostMap, Map<String, BigDecimal> materialCostMap,
                                                    ComputeDrugCostDetail costDetail,
-                                                   ImportPatientItem item, String typeCode ) {
+                                                   PatientItemDepartmentGroupVo item, String typeCode ) {
         List<ComputeDrugCostDetail> details = new ArrayList<>();
         if (typeCode.equals(ItemTypeEnum.DRUG.getCode())) {
             // 药品  取药品收入 药品成本
@@ -281,7 +273,7 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
      * @param item   导入项目
      * @return 收入对象
      */
-    private ComputeDrugCostDetail getIncome(ComputeDrugCostDetail detail, ImportPatientItem item) {
+    private ComputeDrugCostDetail getIncome(ComputeDrugCostDetail detail, PatientItemDepartmentGroupVo item) {
         ComputeDrugCostDetail result = BeanUtil.convertObj(detail, ComputeDrugCostDetail.class);
         result.setComputeResult(item.getAmount());
         return result;
@@ -295,14 +287,14 @@ public class DrugMaterialCalculateServiceImpl implements DrugMaterialCalculateSe
      * @param costMap 成本字典
      * @return 成本对象
      */
-    private ComputeDrugCostDetail getCost(ComputeDrugCostDetail detail, ImportPatientItem item, Map<String, BigDecimal> costMap) {
+    private ComputeDrugCostDetail getCost(ComputeDrugCostDetail detail, PatientItemDepartmentGroupVo item, Map<String, BigDecimal> costMap) {
         ComputeDrugCostDetail result = BeanUtil.convertObj(detail, ComputeDrugCostDetail.class);
         BigDecimal bigDecimal = costMap.get(item.getItemCode());
         BigDecimal num = item.getNum();
         if (bigDecimal != null && num != null) {
             result.setComputeResult(bigDecimal.multiply(num));
         } else {
-            log.info("【" + item.getItemName() + "】未找到成本信息,默认为 0");
+            log.info("【{}】未找到成本信息,默认为 0", item.getItemName());
             result.setComputeResult(BigDecimal.ZERO);
         }
         return result;

+ 379 - 118
src/main/java/com/kcim/service/impl/HospProfitAndLossServiceImpl.java

@@ -30,17 +30,18 @@ import com.kcim.dao.model.*;
 import com.kcim.service.*;
 import com.kcim.vo.AllocationQueryReportVO;
 import com.kcim.vo.HospProfitAndLossVo;
+import com.kcim.vo.HospProfitVO;
 import com.kcim.vo.RelationVO;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.FileItemFactory;
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
@@ -53,6 +54,7 @@ import java.text.DecimalFormat;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -357,7 +359,6 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
     private void calcByAccount(Long hospId, ReportForm reportForm, List<IncomeCollection> incomes, List<HospProfitAndLoss> list, List<AllocationQuery> allocationQueries, int month, int year) {
         // check 这个医院是否有对应的损益标识
         reportFormService.checkExistLoss(hospId);
-
         // 报表项目关联的会计科目对象
         List<RelationVO> accountRelations = reportRelationService.getAccountRelation(reportForm.getId(), hospId);
         if (accountRelations.isEmpty()) {
@@ -393,7 +394,6 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
     @Override
     public PageUtils getHospProfits(Integer current, Integer pageSize, String date, Long hospId) {
         reportFormService.checkExistLoss(hospId);
-
         DateTime parse = DateUtil.parse(date);
         int year = DateUtil.year(parse);
         int month = DateUtil.month(parse) + 1;
@@ -557,7 +557,8 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
         setHospRowList(hospAllList, titleEntities, rowList);
 
         try {
-            ExcelPoiUtil excelTool = new ExcelPoiUtil("全院损益");
+            ExcelPoiUtil excelTool = new ExcelPoiUtil();
+            excelTool.setTitle("全院损益");
             Map<String, String> param = ImmutableMap.<String, String>builder().put("id", "id").put("pid", "pid")
                     .put("content", "content").put("fieldName", "fieldName").put("width", "width").build();
 
@@ -732,43 +733,43 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
         }
         //相 同key 的数值 进行汇总
 //        for (int i = 0; i < 2; i++) {
-            Map<String, String> hospMap = new HashMap<>();
-            for (TitleEntity titleEntity : titleEntities) {
-                AtomicReference<BigDecimal> total = new AtomicReference<>(new BigDecimal("0.00"));
-                for (Map<String, String> map : amountRowList) {
-                    String s = map.get(titleEntity.getFieldName());
-                    if (!titleEntity.getFieldName().equals("child") && !titleEntity.getFieldName().equals("parent") && !titleEntity.getFieldName().equals("itemType")) {
+        Map<String, String> hospMap = new HashMap<>();
+        for (TitleEntity titleEntity : titleEntities) {
+            AtomicReference<BigDecimal> total = new AtomicReference<>(new BigDecimal("0.00"));
+            for (Map<String, String> map : amountRowList) {
+                String s = map.get(titleEntity.getFieldName());
+                if (!titleEntity.getFieldName().equals("child") && !titleEntity.getFieldName().equals("parent") && !titleEntity.getFieldName().equals("itemType")) {
 //                       if(StringUtils.isEmpty(s)){
 //                           total.updateAndGet(v -> v.add(BigDecimal.ZERO));
 //                       }else {
-                           total.updateAndGet(v -> v.add(new BigDecimal(s)));
+                    total.updateAndGet(v -> v.add(new BigDecimal(s)));
 //                       }
-                    }
                 }
-                if (titleEntity.getFieldName().equals("parent")) {
-                    hospMap.put("parent", "全院");
-                } else if (titleEntity.getFieldName().equals("child")) {
-                    hospMap.put("child", "全院");
-                } else if (titleEntity.getFieldName().equals("itemType")) {
+            }
+            if (titleEntity.getFieldName().equals("parent")) {
+                hospMap.put("parent", "全院");
+            } else if (titleEntity.getFieldName().equals("child")) {
+                hospMap.put("child", "全院");
+            } else if (titleEntity.getFieldName().equals("itemType")) {
 //                    if (i == 0) {
-                        hospMap.put("itemType", "金额");
+                hospMap.put("itemType", "金额");
 //                    } else {
 //                        hospMap.put("itemType", "占比");
 //                    }
-                } else {
+            } else {
 //                    if (i == 0) {
-                        hospMap.put(titleEntity.getFieldName(), total.get().toString());
-                        if(!CollectionUtils.isEmpty(hospAllList)){
-                            for (HospProfitAndLoss data : hospAllList) {
-                                hospMap.put(data.getReportNum().toString(), data.getAmount().setScale(2, RoundingMode.HALF_UP).toString());
-                            }
-                        }
+                hospMap.put(titleEntity.getFieldName(), total.get().toString());
+                if (!CollectionUtils.isEmpty(hospAllList)) {
+                    for (HospProfitAndLoss data : hospAllList) {
+                        hospMap.put(data.getReportNum().toString(), data.getAmount().setScale(2, RoundingMode.HALF_UP).toString());
+                    }
+                }
 //                    } else {
 //                        hospMap.put(titleEntity.getFieldName(), "");
 //                    }
-                }
             }
-            rowList.add(hospMap);
+        }
+        rowList.add(hospMap);
 //        }
     }
 
@@ -923,6 +924,177 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
         return new PageUtils(pageUtils);
     }
 
+    @Override
+    public Object getHospProfitResponsibilities(String responsibilityName) {
+        List<Responsibility> responsibilityList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
+                .eq(Responsibility::getHospId, UserContext.getHospId())
+                .and(q -> q.eq(Responsibility::getStatus, NumberConstant.ONE).or().eq(Responsibility::getStatus, null))
+                .like(StrUtil.isNotBlank(responsibilityName), Responsibility::getResponsibilityName, responsibilityName));
+        List<Responsibility> responsibilityAllList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
+                .eq(Responsibility::getHospId, UserContext.getHospId()));
+        Map<Long, Responsibility> map = responsibilityAllList.stream().collect(Collectors.toMap(Responsibility::getId, responsibility -> responsibility, (a, b) -> b));
+        List<Responsibility> addList = new ArrayList<>();
+        for (Responsibility responsibility : responsibilityList) {
+            Responsibility responsibility1 = map.get(responsibility.getParentId());
+            if (Objects.nonNull(responsibility1)) {
+                addList.add(responsibility1);
+                if (!responsibility1.getParentId().equals(NumberConstant.ZERO_L)) {
+                    getResponsibilityParent(responsibility1, map, addList);
+                }
+            }
+        }
+        if (!CollectionUtils.isEmpty(addList)) {
+            //去重
+            List<Responsibility> collect = addList.stream().distinct().collect(Collectors.toList());
+            responsibilityList.addAll(collect);
+        }
+
+
+        Map<Long, List<Responsibility>> collect = responsibilityList.stream().collect(Collectors.groupingBy(Responsibility::getParentId));
+        List<Responsibility> responsibilities = collect.get(NumberConstant.ZERO_L);
+        collect.remove(NumberConstant.ZERO_L);
+        for (Responsibility responsibility : responsibilities) {
+            List<Responsibility> responsibilities1 = collect.get(responsibility.getId());
+            if (!CollectionUtils.isEmpty(responsibilities1)) {
+                responsibility.setChildren(setResponsibilityChildren(responsibilities1, collect));
+            }
+        }
+        responsibilitySort(responsibilities);
+        return responsibilities;
+    }
+
+    @Override
+    public Object getHospProfitList(String computeDate, Long hospId, String reportType) {
+        DateTime parse = DateUtil.parse(computeDate);
+        int year = DateUtil.year(parse);
+        int month = DateUtil.month(parse) + 1;
+//        Integer year = ComputeDateUtils.getComputeYear(computeDate);
+//        Integer month = ComputeDateUtils.getComputeMonth(computeDate);
+        // 查询所有的全院损益数据  内存溢出问题
+        List<HospProfitAndLoss> hospProfitAndLosses = getAllDataByDate(year, month, hospId);
+        if (CollectionUtils.isEmpty(hospProfitAndLosses)) {
+            throw new CostException(500, "未进行全院损益计算");
+        }
+        //判断是否有全院的数据  有单独取出另算
+        List<HospProfitAndLoss> hospAllList = hospProfitAndLosses.stream().filter(f -> f.getResponsibilityCode().equals("-1")).collect(Collectors.toList());
+        if (!CollectionUtils.isEmpty(hospAllList)) {
+            hospProfitAndLosses.removeAll(hospAllList);
+        }
+        //查询全院损益报表配置
+        Integer integerReportType = Integer.valueOf(reportType);
+        List<ReportForm> reportFormList = reportFormService.list(new QueryWrapper<ReportForm>().lambda()
+                .eq(ReportForm::getHospId, hospId)
+                .eq(ReportForm::getReportType, integerReportType).eq(ReportForm::getHide, NumberConstant.ONE));
+        if (CollUtil.isEmpty(reportFormList)) {
+            throw new CostException(500, "未找到全院损益表配置");
+        }
+
+        List<HospProfitVO> costProfitVos = BeanUtil.convertList(reportFormList, HospProfitVO.class);
+        //把所有数据按报表项目汇总
+        Map<Integer, List<HospProfitAndLoss>> reportNumGroup = hospProfitAndLosses.stream().collect(Collectors.groupingBy(HospProfitAndLoss::getReportNum));
+        Map<Integer, BigDecimal> reportNumSumMap = new HashMap<>();
+        reportNumGroup.forEach((reportNum, hospProfitAndLossList) -> {
+            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.000000"));
+            hospProfitAndLossList.stream().<UnaryOperator<BigDecimal>>map(hospProfitAndLoss -> f -> f.add(hospProfitAndLoss.getAmount())).forEach(sum::updateAndGet);
+            reportNumSumMap.put(reportNum, sum.get());
+        });
+
+        for (HospProfitVO costProfitVo : costProfitVos) {
+            BigDecimal bigDecimal = reportNumSumMap.get(costProfitVo.getNum());
+            if (bigDecimal != null) {
+                costProfitVo.setAmount(bigDecimal);
+            } else {
+                costProfitVo.setAmount(BigDecimal.ZERO.setScale(6, RoundingMode.HALF_UP));
+            }
+        }
+        //判断有无其他全院数据  有组装进去
+        if (!CollectionUtils.isEmpty(hospAllList)) {
+            //全院其他收支
+            HospProfitVO hospProfitVO = new HospProfitVO();
+            hospProfitVO.setId(-1L);
+            hospProfitVO.setNum(-1);
+            hospProfitVO.setParentId(0L);
+            hospProfitVO.setReportName("全院其他收支");
+            hospProfitVO.setSort(costProfitVos.size());
+            hospProfitVO.setReportType(3);
+            hospProfitVO.setFraction(3);
+            costProfitVos.add(hospProfitVO);
+            for (int i = 0, hospAllListSize = hospAllList.size(); i < hospAllListSize; i++) {
+                costProfitVos.add(getHospProfitVO(hospAllList, i));
+            }
+        }
+
+        //取出所有成本项目
+        List<HospProfitVO> costFractionList = costProfitVos.stream().filter(f -> f.getCostType() != null && f.getCostType().equals(NumberConstant.TWO) && f.getFraction().equals(NumberConstant.TWO)).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(costFractionList)) {
+            throw new CostException("全院损益未配置成本占比计算分母");
+        } else {
+            if (costFractionList.size() > 1) {
+                throw new CostException("全院损益成本占比计算分母有且只能有一个");
+            }
+        }
+        List<HospProfitVO> inComeFractionList = costProfitVos.stream().filter(f -> f.getCostType() != null && f.getCostType().equals(NumberConstant.ONE) && f.getFraction().equals(NumberConstant.TWO)).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(inComeFractionList)) {
+            throw new CostException("全院损益未配置收入占比计算分母");
+        } else {
+            if (inComeFractionList.size() > 1) {
+                throw new CostException("全院损益收入占比计算分母有且只能有一个");
+            }
+        }
+        HospProfitVO inComeFraction = inComeFractionList.get(0);
+        HospProfitVO costFraction = costFractionList.get(0);
+        for (HospProfitVO costProfitVo : costProfitVos) {
+            if (costProfitVo.getCostType() != null) {
+                if (costProfitVo.getCostType().equals(NumberConstant.ONE) && costProfitVo.getFraction().equals(NumberConstant.ONE)) {
+                    //收入
+                    BigDecimal denominator = inComeFraction.getAmount();
+                    //收入分子
+                    if (denominator.compareTo(BigDecimal.ZERO) == 0) {
+                        costProfitVo.setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
+                    } else {
+                        costProfitVo.setPercent(costProfitVo.getAmount().divide(denominator, 4, RoundingMode.HALF_UP));
+                    }
+                } else if (costProfitVo.getCostType().equals(NumberConstant.TWO) && costProfitVo.getFraction().equals(NumberConstant.ONE)) {
+                    //成本
+                    BigDecimal denominator = costFraction.getAmount();
+                    if (denominator.compareTo(BigDecimal.ZERO) == 0) {
+                        costProfitVo.setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
+                    } else {
+                        costProfitVo.setPercent(costProfitVo.getAmount().divide(denominator, 4, RoundingMode.HALF_UP));
+                    }
+                }
+            }
+        }
+        Map<Long, List<HospProfitVO>> collect = costProfitVos.stream().collect(Collectors.groupingBy(HospProfitVO::getParentId));
+        List<HospProfitVO> costProfitParentVos = collect.get(NumberConstant.ZERO_L);
+        collect.remove(NumberConstant.ZERO_L);
+        for (HospProfitVO costProfitVo : costProfitParentVos) {
+            List<HospProfitVO> costProfitVo1 = collect.get(costProfitVo.getId());
+            if (!CollectionUtils.isEmpty(costProfitVo1)) {
+                costProfitVo.setChild(setChildren(costProfitVo1, collect));
+            }
+        }
+        if (!CollectionUtils.isEmpty(costProfitParentVos)) {
+            costProfitParentVos.sort(Comparator.comparing(HospProfitVO::getSort, Comparator.nullsLast(Integer::compareTo)));
+        }
+        return costProfitParentVos;
+
+    }
+
+    private static @NotNull HospProfitVO getHospProfitVO(List<HospProfitAndLoss> hospAllList, int i) {
+        HospProfitAndLoss hospProfitAndLoss = hospAllList.get(i);
+        HospProfitVO hospProfitVO1 = new HospProfitVO();
+        hospProfitVO1.setId(Long.valueOf(hospProfitAndLoss.getReportNum()));
+        hospProfitVO1.setNum(hospProfitAndLoss.getReportNum());
+        hospProfitVO1.setParentId(-1L);
+        hospProfitVO1.setReportName(hospProfitAndLoss.getReportName());
+        hospProfitVO1.setSort(i);
+        hospProfitVO1.setReportType(3);
+        hospProfitVO1.setAmount(hospProfitAndLoss.getAmount());
+        hospProfitVO1.setFraction(3);
+        return hospProfitVO1;
+    }
+
     private List<HospProfitAndLoss> getAllDataByDate(int year, int month, Long hospId) {
         return this.list(
                 new LambdaQueryWrapper<HospProfitAndLoss>()
@@ -1029,85 +1201,74 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
                 i.setAmount(setSubtotal(i, costShareLevelList, listMap, listVo, incomes, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
             } else if (NumberConstant.FOUR.equals(calcType)) {
                 // TODO 按照计算公式进行计算
-                i.setAmount(setCalculation(i, listVo, costShareLevelList, listMap, incomes, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
+//                i.setAmount(setCalculation(i, listVo, costShareLevelList, listMap, incomes, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
             } else if (NumberConstant.FIVE.equals(calcType)) {
                 // TODO  按照责任中心进行计算
                 i.setAmount(setResponsibilityCode(i, reportRelationMap, allocationList, allList));
             } else {
-                i.setAmount(new BigDecimal("0.0000"));
+                i.setAmount(new BigDecimal("0.000000"));
             }
         });
-//
-//
-//
-//        listVo.forEach(i -> {
-//            Integer calcType = i.getCalcType();
-//            if (calcType == CalcTypeEnum.BY_ACCOUNT.getType()) {
-//                // 按会计科目计算单的话
-//                calcByAccountByResp(hospId, i);
-//            } else if (calcType == CalcTypeEnum.BY_SHARE_LEVEL.getType()) {
-//                // 分摊层级计算
-//                calcByShareLevelResp(hospId, i);
-//            } else if (calcType == CalcTypeEnum.LITTER_COUNT.getType()) {
-//                // 处理小计 todo  默认认为 小计都是在同一个下面最后一个
-//                calcByLitterCountResp(i,listParentMap, listVo,hospId);
-//            } else if (calcType == CalcTypeEnum.CALC_FORMULA.getType()) {
-//                // 按公式 (要保证总合计放到最后呀)
-//                calcByFormulaResp(i,listVo);
-//            } else if (calcType == CalcTypeEnum.BY_RESPONSIBILITY.getType()) {
-//                // 责任中心
-//                calcByResponsibilityResp(hospId, i);
-//            } else if (calcType == CalcTypeEnum.NO_CONFIG.getType()) {
-//                // 不设置不计算
-//                i.setAmount(new BigDecimal("0.0000"));
-//            } else {
-//                i.setAmount(new BigDecimal("0.0000"));
-//            }
-//        });
-//        for (Responsibility responsibility : leafResp) {
-//            for (ReportForm parentForm : reportForms) {
-//                Long parentId = parentForm.getId();
-//                List<ReportForm> children = reportForms.stream().filter(i -> i.getParentId().equals(parentId)).collect(Collectors.toList());
-//                for (ReportForm child : children) {
-//                    Integer calcType = child.getCalcType();
-//                    if (calcType == CalcTypeEnum.BY_ACCOUNT.getType()) {
-//                        // 按会计科目计算单的话
-//                        calcByAccountByResp(hospId, child, list, month, year, responsibility);
-//                    } else if (calcType == CalcTypeEnum.BY_SHARE_LEVEL.getType()) {
-//                        // 分摊层级计算
-//                        calcByShareLevelResp(hospId, child, list, year, month, responsibility);
-//                    } else if (calcType == CalcTypeEnum.LITTER_COUNT.getType()) {
-//                        // 处理小计 todo  默认认为 小计都是在同一个下面最后一个
-//                        calcByLitterCountResp(year, month, child, children, list, hospId, responsibility);
-//                    } else if (calcType == CalcTypeEnum.CALC_FORMULA.getType()) {
-//                        // 按公式 (要保证总合计放到最后呀)
-//                        calcByFormulaResp(year, month, child, list, responsibility);
-//                    } else if (calcType == CalcTypeEnum.BY_RESPONSIBILITY.getType()) {
-//                        // 责任中心
-//                        calcByResponsibilityResp(hospId, child, list, year, month, responsibility);
-//                    } else if (calcType == CalcTypeEnum.NO_CONFIG.getType()) {
-//                        // 不设置不计算
-//                    } else {
-//
-//                    }
-//                }
-//            }
-//        }
-
         //计算占比
         if (CollectionUtils.isEmpty(listVo)) {
             return;
         }
+
+        List<HospProfitAndLossVo> listSum = new ArrayList<>();
+
+        //把所有数据按报表项目汇总
+        for (ReportForm j : reportForms) {
+            HospProfitAndLossVo hospProfitAndLossVo = new HospProfitAndLossVo();
+            hospProfitAndLossVo.setDateYear(finalYear);
+            hospProfitAndLossVo.setDateMonth(finalMonth);
+            hospProfitAndLossVo.setReportNum(j.getNum());
+            hospProfitAndLossVo.setReportName(j.getReportName());
+            hospProfitAndLossVo.setCostType(NumberConstant.ZERO);
+            hospProfitAndLossVo.setIncomeType(NumberConstant.ZERO);
+            hospProfitAndLossVo.setHospId(hospId);
+            hospProfitAndLossVo.setType(j.getCostType());
+            hospProfitAndLossVo.setFraction(j.getFraction());
+            hospProfitAndLossVo.setReportId(j.getId());
+            hospProfitAndLossVo.setReportNum(j.getNum());
+            hospProfitAndLossVo.setCalcType(j.getCalcType());
+            hospProfitAndLossVo.setReportName(j.getReportName());
+            hospProfitAndLossVo.setCalcFormula(j.getCalcFormula());
+            hospProfitAndLossVo.setReportParentId(j.getParentId());
+            listSum.add(hospProfitAndLossVo);
+        }
+        Map<Integer, List<HospProfitAndLossVo>> reportNumGroup = listVo.stream().collect(Collectors.groupingBy(HospProfitAndLossVo::getReportNum));
+        Map<Integer, BigDecimal> reportNumSumMap = new HashMap<>();
+        reportNumGroup.forEach((reportNum, hospProfitAndLossList) -> {
+            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.000000"));
+            for (HospProfitAndLossVo hospProfitAndLoss : hospProfitAndLossList) {
+                if (hospProfitAndLoss.getAmount() != null) {
+                    sum.updateAndGet(f -> f.add(hospProfitAndLoss.getAmount()));
+                }
+            }
+            reportNumSumMap.put(reportNum, sum.get());
+        });
+
+        for (HospProfitAndLossVo costProfitVo : listSum) {
+            BigDecimal bigDecimal = reportNumSumMap.get(costProfitVo.getReportNum());
+            if (bigDecimal != null) {
+                costProfitVo.setAmount(bigDecimal);
+
+            } else {
+                costProfitVo.setAmount(BigDecimal.ZERO.setScale(6, RoundingMode.HALF_UP));
+            }
+        }
+        //单独计算计算公式数据
+        setCalculationAmount(listSum);
         //收入
-        List<HospProfitAndLossVo> profitIncomeList = listVo.stream().filter(f -> f.getType().equals(NumberConstant.ONE)).collect(Collectors.toList());
+        List<HospProfitAndLossVo> profitIncomeList = listSum.stream().filter(f -> f.getType().equals(NumberConstant.ONE)).collect(Collectors.toList());
         List<HospProfitAndLossVo> profitIncome = costPercent(profitIncomeList);
         //成本
-        List<HospProfitAndLossVo> profitCostList = listVo.stream().filter(f -> f.getType().equals(NumberConstant.TWO)).collect(Collectors.toList());
+        List<HospProfitAndLossVo> profitCostList = listSum.stream().filter(f -> f.getType().equals(NumberConstant.TWO)).collect(Collectors.toList());
 
         List<HospProfitAndLossVo> profitCost = costPercent(profitCostList);
 
         //不计算项目
-        List<HospProfitAndLossVo> noCompute = listVo.stream().filter(f -> f.getFraction().equals(NumberConstant.THREE)).collect(Collectors.toList());
+        List<HospProfitAndLossVo> noCompute = listSum.stream().filter(f -> f.getFraction().equals(NumberConstant.THREE)).collect(Collectors.toList());
         noCompute.forEach(profitVO -> profitVO.setPercent(null));
 
         List<HospProfitAndLossVo> listAllVo = new ArrayList<>();
@@ -1135,18 +1296,81 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
                 HospProfitAndLoss loss = new HospProfitAndLoss();
                 loss.setDateYear(year).setDateMonth(month).setReportName(ele.getPaymentsName()).setReportNum((int) (-ele.getId()))
                         .setCreateTime(System.currentTimeMillis()).setAmount(ele.getTotalAmount()).setHospId(hospId)
-                        .setResponsibilityName("全院").setResponsibilityCode("-1").setPercent(null)
-                ;
+                        .setResponsibilityName("全院").setResponsibilityCode("-1").setPercent(null);
                 list.add(loss);
             });
         }
-
         long l = System.currentTimeMillis();
         list.forEach(i -> {
             i.setCreateTime(l);
         });
-
         this.saveBatch(list);
+    }
+
+    private void setCalculationAmount(List<HospProfitAndLossVo> listVo) {
+        Map<Integer, List<HospProfitAndLossVo>> collect = listVo.stream().collect(Collectors.groupingBy(HospProfitAndLossVo::getCalcType));
+        //取出所有计算公式数据
+        List<HospProfitAndLossVo> costDepartmentProfitVOS = collect.get(NumberConstant.FOUR);
+
+        costDepartmentProfitVOS.sort(Comparator.comparing(HospProfitAndLossVo::getReportNum, Comparator.nullsLast(Integer::compareTo)));
+        for (HospProfitAndLossVo profitVO : costDepartmentProfitVOS) {
+            // 获取当前报表的计算方式  [1]+[2]类型/ [1]-[2] [1]*[2] [1]/[2]
+            String formula = profitVO.getCalcFormula();
+            //找出公式当中所有代码
+            String replace = formula.replace("[", "")
+                    .replace("]", "")
+                    .replace("-", ",")
+                    .replace("+", ",")
+                    .replace("*", ",")
+                    .replace("/", ",");
+            ArrayList<String> codeList = CollUtil.newArrayList(replace.split(","));
+            Map<Integer, String> codeMap = new ConcurrentHashMap<>();
+            for (int j = 0; j < codeList.size(); j++) {
+                codeMap.put(j, codeList.get(j));
+            }
+            List<String> expressions = ReUtil.findAll("[^0-9]", "+" + formula.replace("[", "")
+                            .replace("]", "").trim(), 0)
+                    .stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
+            // 得到预算表达式 得到所有表达式的Map  +  -  相关的
+            Map<Integer, String> expressionMap = new ConcurrentHashMap<>();
+            for (int k = 0; k < expressions.size(); k++) {
+                expressionMap.put(k, expressions.get(k));
+            }
+            // 数字的索引和表达式的索引累加计算
+            Set<Integer> codeSet = codeMap.keySet();
+            List<Integer> codes = new ArrayList<>(codeSet);
+            AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(new BigDecimal("0.000000"));
+            for (int i = 0; i < codes.size(); i++) {
+                // 编号
+                String code = codeMap.get(i);
+                BigDecimal amount = null;
+                for (HospProfitAndLossVo costDepartmentProfitVO : listVo) {
+                    if (costDepartmentProfitVO.getReportNum().equals(Integer.valueOf(code))) {
+                        amount = costDepartmentProfitVO.getAmount();
+                    }
+                }
+                if (amount == null) {
+                    continue;
+                }
+//                    BigDecimal amount = new BigDecimal(o.toString());
+                String str = expressionMap.get(i);
+                if (str.equals("+")) {
+                    totalAmount.set(totalAmount.get().add(amount));
+                } else if (str.contains("-")) {
+                    totalAmount.set(totalAmount.get().subtract(amount));
+                } else if (str.contains("*")) {
+                    totalAmount.set(totalAmount.get().multiply(amount));
+                } else if (str.contains("/")) {
+                    if (amount.compareTo(BigDecimal.ZERO.setScale(6, RoundingMode.HALF_UP)) == 0) {
+                        totalAmount.set(BigDecimal.ZERO);
+                        break;
+                    } else {
+                        totalAmount.set(totalAmount.get().divide(amount, 6, RoundingMode.HALF_UP));
+                    }
+                }
+            }
+            profitVO.setAmount(totalAmount.get());
+        }
 
     }
 
@@ -1358,35 +1582,31 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
 
     private List<HospProfitAndLossVo> costPercent(List<HospProfitAndLossVo> profitIncomeList) {
         List<HospProfitAndLossVo> list = new ArrayList<>();
-        Map<String, List<HospProfitAndLossVo>> responsibilityGroup = profitIncomeList.stream().collect(Collectors.groupingBy(HospProfitAndLossVo::getResponsibilityCode));
-
-        for (String s : responsibilityGroup.keySet()) {
-            List<HospProfitAndLossVo> costDepartmentProfitVOS = responsibilityGroup.get(s);
-            Map<Integer, List<HospProfitAndLossVo>> collect = costDepartmentProfitVOS.stream().collect(Collectors.groupingBy(HospProfitAndLossVo::getFraction));
-            //分母只有一个
-            List<HospProfitAndLossVo> denominatorList = collect.get(NumberConstant.TWO);
-            if (denominatorList.size() > 1) {
-                throw new CostException("收入项目分母大于一个,请查证后再计算科室损益");
+        Map<Integer, List<HospProfitAndLossVo>> collect = profitIncomeList.stream().collect(Collectors.groupingBy(HospProfitAndLossVo::getFraction));
+        //分母只有一个
+        List<HospProfitAndLossVo> denominatorList = collect.get(NumberConstant.TWO);
+        if (denominatorList.size() > 1) {
+            throw new CostException("收入项目分母大于一个,请查证后再计算科室损益");
+        }
+        BigDecimal denominator = denominatorList.get(0).getAmount();
+        //收入分子
+        List<HospProfitAndLossVo> numeratorList = collect.get(NumberConstant.ONE);
+        if (denominator.compareTo(BigDecimal.ZERO) == 0) {
+            for (HospProfitAndLossVo profitVO : numeratorList) {
+                profitVO.setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
             }
-            BigDecimal denominator = denominatorList.get(0).getAmount();
-            //收入分子
-            List<HospProfitAndLossVo> numeratorList = collect.get(NumberConstant.ONE);
-            if (denominator.compareTo(BigDecimal.ZERO) == 0) {
-                for (HospProfitAndLossVo profitVO : numeratorList) {
-                    profitVO.setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
-                }
-                denominatorList.get(0).setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
+            denominatorList.get(0).setPercent(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP));
 
-            } else {
-                for (HospProfitAndLossVo profitVO : numeratorList) {
-                    profitVO.setPercent(profitVO.getAmount().divide(denominator, 4, RoundingMode.HALF_UP));
-                }
-                denominatorList.get(0).setPercent(BigDecimal.ONE.setScale(4, RoundingMode.HALF_UP));
+        } else {
+            for (HospProfitAndLossVo profitVO : numeratorList) {
+                profitVO.setPercent(profitVO.getAmount().divide(denominator, 4, RoundingMode.HALF_UP));
             }
-            list.add(denominatorList.get(0));
-            list.addAll(numeratorList);
-
+            denominatorList.get(0).setPercent(BigDecimal.ONE.setScale(4, RoundingMode.HALF_UP));
         }
+        list.add(denominatorList.get(0));
+        list.addAll(numeratorList);
+
+
 
         return list;
 
@@ -1687,4 +1907,45 @@ public class HospProfitAndLossServiceImpl extends ServiceImpl<HospProfitAndLossM
         ;
         list.add(loss);
     }
+
+    private void responsibilitySort(List<Responsibility> responsibilityList) {
+        for (Responsibility responsibility : responsibilityList) {
+            if (!CollectionUtils.isEmpty(responsibility.getChildren())) {
+                responsibilitySort(responsibility.getChildren());
+            }
+        }
+        responsibilityList.sort(Comparator.comparing(Responsibility::getSort, Comparator.nullsLast(Integer::compareTo)));
+    }
+
+    private List<Responsibility> setResponsibilityChildren(List<Responsibility> child, Map<Long, List<Responsibility>> collect) {
+        for (Responsibility responsibility : child) {
+            if (!CollectionUtils.isEmpty(collect.get(responsibility.getId()))) {
+                responsibility.setChildren(setResponsibilityChildren(collect.get(responsibility.getId()), collect));
+            }
+        }
+        return child;
+    }
+
+    private void getResponsibilityParent(Responsibility responsibility, Map<Long, Responsibility> collect, List<Responsibility> addList) {
+        Responsibility responsibility1 = collect.get(responsibility.getParentId());
+        if (Objects.nonNull(responsibility1)) {
+            addList.add(responsibility1);
+            if (!responsibility1.getParentId().equals(NumberConstant.ZERO_L)) {
+                getResponsibilityParent(responsibility1, collect, addList);
+            }
+        }
+    }
+
+    private List<HospProfitVO> setChildren(List<HospProfitVO> child, Map<Long, List<HospProfitVO>> collect) {
+        for (HospProfitVO costProfitVo : child) {
+            if (!CollectionUtils.isEmpty(collect.get(costProfitVo.getId()))) {
+                costProfitVo.setChild(setChildren(collect.get(costProfitVo.getId()), collect));
+            }
+        }
+        if (!CollectionUtils.isEmpty(child)) {
+            child.sort(Comparator.comparing(HospProfitVO::getSort, Comparator.nullsLast(Integer::compareTo)));
+        }
+        return child;
+    }
+
 }

+ 4 - 2
src/main/java/com/kcim/service/impl/IncomeCollectionServiceImpl.java

@@ -6,6 +6,8 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.kcim.common.constants.NumberConstant;
+import com.kcim.common.constants.SQLParameter;
+import com.kcim.common.enums.CustomSqlTypeEnum;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.JacksonUtil;
@@ -115,8 +117,8 @@ public class IncomeCollectionServiceImpl
         }else {
             String computeDate = month < 10 ? year + "-0" + month : year + "-" + month;
             Map<String,String> sqlParameter = new HashMap<>();
-            sqlParameter.put("compute_date",computeDate);
-            costDataService.autoExecuteSql("INCOME_COLLECTION",sqlParameter);
+            sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+            costDataService.autoExecuteSql(CustomSqlTypeEnum.INCOME_COLLECTION.getCode(),sqlParameter);
         }
 
     }

+ 0 - 3
src/main/java/com/kcim/service/impl/PatientItemImportServiceImpl.java

@@ -81,9 +81,6 @@ public class PatientItemImportServiceImpl implements PatientItemImportService {
         Page<ImportPatientItem> page = repository.getPage(current, pageSize, computeDate, itemType, departmentName,patientNo,filter);
         List<ImportPatientItem> records = page.getRecords();
         if(!CollectionUtils.isEmpty(records)){
-
-
-
             return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current);
         }
         return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);

+ 115 - 69
src/main/java/com/kcim/service/impl/ProjectCostServiceImpl.java

@@ -1,8 +1,11 @@
 package com.kcim.service.impl;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.kcim.common.constants.Constant;
 import com.kcim.common.constants.NumberConstant;
 import com.kcim.common.constants.ParameterConstant;
+import com.kcim.common.constants.SQLParameter;
+import com.kcim.common.enums.CustomSqlTypeEnum;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.BeanUtil;
 import com.kcim.common.util.PageUtils;
@@ -12,6 +15,7 @@ import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
 import com.kcim.dao.repository.*;
 import com.kcim.service.CenterService;
 import com.kcim.service.ProjectCostService;
+import com.kcim.service.SqlService;
 import com.kcim.vo.*;
 import com.kcim.web.reponse.ProjectCostResponse;
 import lombok.extern.slf4j.Slf4j;
@@ -95,9 +99,13 @@ public class ProjectCostServiceImpl implements ProjectCostService {
 
     ComputeStandPatientProjectGroupCostDetailRepository computeStandPatientProjectGroupCostDetailRepository;
 
-    public ProjectCostServiceImpl(ResponsibilityRepository responsibilityRepository, ComputeProjectCostRepository repository, ComputeProjectCostDetailRepository detailRepository, ComputeProjectGroupCostDetailRepository groupDetailRepository, ImportPatientItemRepository importPatientItemRepository, ShareParamCostRepository shareParamCostRepository, ShareParamCostDetailRepository shareParamCostDetailRepository, CostDepartmentProfitRepository costDepartmentProfitRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ComputeShareParamRepository computeShareParamRepository, ItemRepository itemRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputePatientProjectCostRepository computePatientProjectCostRepository, ComputePatientProjectCostDetailRepository computePatientProjectCostDetailRepository, ComputePatientProjectGroupCostDetailRepository computePatientProjectGroupCostDetailRepository, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandProjectCostRepository standProjectCostRepository, ComputeStandProjectCostDetailRepository standProjectCostDetailRepository, ComputeStandProjectGroupCostDetailRepository standProjectGroupCostDetailRepository, ComputeStandPatientProjectCostRepository computeStandPatientProjectCostRepository, ComputeStandPatientProjectCostDetailRepository computeStandPatientProjectCostDetailRepository, ComputeStandPatientProjectGroupCostDetailRepository computeStandPatientProjectGroupCostDetailRepository) {
+    SqlService sqlService;
+
+    public ProjectCostServiceImpl(SqlService sqlService,ResponsibilityRepository responsibilityRepository, ComputeProjectCostRepository repository, ComputeProjectCostDetailRepository detailRepository, ComputeProjectGroupCostDetailRepository groupDetailRepository, ImportPatientItemRepository importPatientItemRepository, ShareParamCostRepository shareParamCostRepository, ShareParamCostDetailRepository shareParamCostDetailRepository, CostDepartmentProfitRepository costDepartmentProfitRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ComputeShareParamRepository computeShareParamRepository, ItemRepository itemRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputePatientProjectCostRepository computePatientProjectCostRepository, ComputePatientProjectCostDetailRepository computePatientProjectCostDetailRepository, ComputePatientProjectGroupCostDetailRepository computePatientProjectGroupCostDetailRepository, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandProjectCostRepository standProjectCostRepository, ComputeStandProjectCostDetailRepository standProjectCostDetailRepository, ComputeStandProjectGroupCostDetailRepository standProjectGroupCostDetailRepository, ComputeStandPatientProjectCostRepository computeStandPatientProjectCostRepository, ComputeStandPatientProjectCostDetailRepository computeStandPatientProjectCostDetailRepository, ComputeStandPatientProjectGroupCostDetailRepository computeStandPatientProjectGroupCostDetailRepository) {
         this.responsibilityRepository = responsibilityRepository;
         this.repository = repository;
+        this.sqlService = sqlService;
+
         this.detailRepository = detailRepository;
         this.groupDetailRepository = groupDetailRepository;
         this.importPatientItemRepository = importPatientItemRepository;
@@ -175,13 +183,17 @@ public class ProjectCostServiceImpl implements ProjectCostService {
             computeResultResponsibilityMap.put(k, computeResultItemMap);
             computeSingleResultResponsibilityMap.put(k, computeSingleResultItemMap);
         });
-        for (ComputeProjectCost record : records) {
-            if (record.getItemType().equals(NumberConstant.ONE_S)) {
-                record.setItemTypeName("医师项目");
-            } else {
-                record.setItemTypeName("医技项目");
-            }
-        }
+
+
+        Map<String, String> typeNameMap = getTypeNameDict();
+        records.forEach(record -> record.setItemTypeName(typeNameMap.get(record.getItemType())));
+//        for (ComputeProjectCost record : records) {
+//            if (record.getItemType().equals(NumberConstant.ONE_S)) {
+//                record.setItemTypeName("医师项目");
+//            } else {
+//                record.setItemTypeName("医技项目");
+//            }
+//        }
         for (ComputeProjectCost itemCode : records) {
             List<ReportVo> dataList = new ArrayList<>();
             for (CommonTitleVo titleVo : titleVos) {
@@ -229,6 +241,11 @@ public class ProjectCostServiceImpl implements ProjectCostService {
         response.setPageData(pageUtils);
         return response;
     }
+    private @NotNull Map<String, String> getTypeNameDict() {
+        DictDataVo centerDict = centerService.getCenterDict(Constant.MED_SERVICE_ITEM_TYPE);
+        List<DictDataVo> dataVoList = centerDict.getDataVoList();
+        return dataVoList.stream().collect(Collectors.toMap(DictDataVo::getCode, DictDataVo::getName, (a, b) -> b));
+    }
 
     /**
      * 计算项目成本     *
@@ -289,6 +306,11 @@ public class ProjectCostServiceImpl implements ProjectCostService {
         for (PatientItemDepartmentGroupVo departmentGroupVo : departAmountGroup) {
             departmentGroupVo.setResponsibilityCode(responsibilityCodeMap.get(departmentGroupVo.getExecuteDepartmentCode()));
         }
+        List<PatientItemDepartmentGroupVo> collect2 = departAmountGroup.stream().filter(f -> StringUtils.isEmpty(f.getResponsibilityCode())).collect(Collectors.toList());
+        if(!CollectionUtils.isEmpty(collect2)){
+            log.info("未对照执行科室代码列表:"+collect2.stream().map(PatientItemDepartmentGroupVo::getExecuteDepartmentCode).collect(Collectors.toList()).toString());
+            throw new CostException("存在执行科室与责任中心未对照数据");
+        }
         Map<String, List<PatientItemDepartmentGroupVo>> collect = departAmountGroup.stream().collect(Collectors.groupingBy(PatientItemDepartmentGroupVo::getResponsibilityCode));
         Map<String, BigDecimal> responsibilitySum = new HashMap<>();
 
@@ -560,8 +582,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
         for (ShareParamCostVo costVo : paramCost) {
             List<CostDepartmentProfit> profitData = collect.get(Long.valueOf(costVo.getProfitId()));
             Map<Long, Map<String, BigDecimal>> profitMap = new HashMap<>();
-            profitMap.put(Long.valueOf(costVo.getProfitId()), profitData.stream().collect(Collectors.toMap(CostDepartmentProfit::getResponsibilityCode, CostDepartmentProfit::getAmount, (a, b) -> b)));
-            costVo.setProfitData(profitMap);
+            if(!CollectionUtils.isEmpty(profitData)){
+                profitMap.put(Long.valueOf(costVo.getProfitId()), profitData.stream().collect(Collectors.toMap(CostDepartmentProfit::getResponsibilityCode, CostDepartmentProfit::getAmount, (a, b) -> b)));
+                costVo.setProfitData(profitMap);
+            }else{
+                log.info("分摊参数:{}profitId:{}在损益计算中未找到任何数据", costVo.getShareParamName(), costVo.getProfitId());
+            }
         }
         //按项目分类-分摊参数代码-分摊参数汇总
         Map<String, List<ShareParamCostVo>> collect4 = paramCost.stream().collect(Collectors.groupingBy(ShareParamCostVo::getItemType));
@@ -575,6 +601,11 @@ public class ProjectCostServiceImpl implements ProjectCostService {
     @Override
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
     public void computePatientItemCost(String computeDate) {
+
+//        Map<String,String> sqlParameter = new HashMap<>();
+//        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+//        sqlService.autoExecuteSql(CustomSqlTypeEnum.PT_ITEM_COST_CALC.getCode(),sqlParameter);
+//      暂时更换成自定义sql 执行 下面代码留用
         SessionUserVO currentUser = UserContext.getCurrentUser();
         //获取收费项目数据(项目)
         checkImportItem(computeDate, currentUser);
@@ -693,6 +724,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                 }
             }
         }
+
     }
 
     @Override
@@ -1001,6 +1033,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                     Item itemData = departmentMap.get(item.getItemCode());
                     if (Objects.isNull(itemData)) {
                         return;
+
                     }
                     itemCost.setItemType(itemData.getItemType());
                     itemCost.setResponsibilityCode(responsibilityCodeMap.get(item.getExecuteDepartmentCode()));
@@ -1246,6 +1279,12 @@ public class ProjectCostServiceImpl implements ProjectCostService {
      */
     @Override
     public void computeStandPatientItemCost(String computeDate) {
+
+        Map<String,String> sqlParameter = new HashMap<>();
+        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
+        sqlService.autoExecuteSql(CustomSqlTypeEnum.PT_STAND_ITEM_COST_CALC.getCode(),sqlParameter);
+
+/*     暂时更换成自定义sql 执行 下面代码留用
         SessionUserVO currentUser = UserContext.getCurrentUser();
         //获取收费项目数据(项目)
         checkImportItem(computeDate, currentUser);
@@ -1372,6 +1411,7 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                 }
             }
         }
+*/
     }
 
     private void handleDictTitle(List<CommonTitleVo> titleVos) {
@@ -1560,36 +1600,41 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                         ComputeProjectCostDetail detail = BeanUtil.convertObj(computeProjectCostDetail, ComputeProjectCostDetail.class);
                         detail.setCostColumnType(shareParamCostVo.getColumnType());
                         Map<Long, Map<String, BigDecimal>> profitData = shareParamCostVo.getProfitData();
-                        Map<String, BigDecimal> map = profitData.get(Long.valueOf(shareParamCostVo.getProfitId()));
-                        String shareParamCode = shareParamCostVo.getShareParamCode();
-                        BigDecimal percent = shareParamCostVo.getPercent();
-                        if (!CollectionUtils.isEmpty(map)) {
-                            //项目总额
-                            BigDecimal amount = map.get(responsibilityCode);
-                            if (amount != null) {
-                                //获取分摊参数占比
-                                Map<String, Map<String, Map<String, List<ComputeShareParamDetailVo>>>> itemTypeSharePercentGroup = sharePercent.get(k);
-                                if (!CollectionUtils.isEmpty(itemTypeSharePercentGroup)) {
-                                    Map<String, Map<String, List<ComputeShareParamDetailVo>>> responsibilityCodeMap = itemTypeSharePercentGroup.get(responsibilityCode);
-                                    Map<String, Map<String, BigDecimal>> itemTypeShareSumGroup = shareSum.get(k);
-                                    if (!CollectionUtils.isEmpty(itemTypeShareSumGroup)) {
-                                        Map<String, BigDecimal> shareSumTotal = itemTypeShareSumGroup.get(responsibilityCode);
-                                        if (!CollectionUtils.isEmpty(shareSumTotal)) {
-                                            //项目分摊参数加总
-                                            BigDecimal totalPercent = shareSumTotal.get(shareParamCode);
-                                            if (!totalPercent.equals(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP))) {
-                                                if (!CollectionUtils.isEmpty(responsibilityCodeMap)) {
-                                                    Map<String, List<ComputeShareParamDetailVo>> itemCodeMap = responsibilityCodeMap.get(itemCost.getCode());
-                                                    if (!CollectionUtils.isEmpty(itemCodeMap)) {
-                                                        List<ComputeShareParamDetailVo> computeShareParamDetailVos = itemCodeMap.get(shareParamCode);
-                                                        if (!CollectionUtils.isEmpty(computeShareParamDetailVos)) {
-                                                            for (ComputeShareParamDetailVo vo : computeShareParamDetailVos) {
-                                                                //成本总额*项目分摊参数数值1*权重1/项目分摊参数数值加总1
-                                                                BigDecimal multiply = amount.multiply(vo.getComputeResult()).multiply(percent).divide(totalPercent, 4, RoundingMode.HALF_UP);
-                                                                sum.updateAndGet(v -> v.add(multiply));
-                                                                if (!vo.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
-                                                                    singleSum.updateAndGet(v -> v.add(multiply.divide(vo.getNum(), 4, RoundingMode.HALF_UP)));
+                        if(!CollectionUtils.isEmpty(profitData)){
+                            Map<String, BigDecimal> map = profitData.get(Long.valueOf(shareParamCostVo.getProfitId()));
+                            String shareParamCode = shareParamCostVo.getShareParamCode();
+                            BigDecimal percent = shareParamCostVo.getPercent();
+                            if (!CollectionUtils.isEmpty(map)) {
+                                //项目总额
+                                BigDecimal amount = map.get(responsibilityCode);
+                                if (amount != null) {
+                                    //获取分摊参数占比
+                                    Map<String, Map<String, Map<String, List<ComputeShareParamDetailVo>>>> itemTypeSharePercentGroup = sharePercent.get(k);
+                                    if (!CollectionUtils.isEmpty(itemTypeSharePercentGroup)) {
+                                        Map<String, Map<String, List<ComputeShareParamDetailVo>>> responsibilityCodeMap = itemTypeSharePercentGroup.get(responsibilityCode);
+                                        Map<String, Map<String, BigDecimal>> itemTypeShareSumGroup = shareSum.get(k);
+                                        if (!CollectionUtils.isEmpty(itemTypeShareSumGroup)) {
+                                            Map<String, BigDecimal> shareSumTotal = itemTypeShareSumGroup.get(responsibilityCode);
+                                            if (!CollectionUtils.isEmpty(shareSumTotal)) {
+                                                //项目分摊参数加总
+                                                BigDecimal totalPercent = shareSumTotal.get(shareParamCode);
+                                                if (!totalPercent.equals(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP))) {
+                                                    if (!CollectionUtils.isEmpty(responsibilityCodeMap)) {
+                                                        Map<String, List<ComputeShareParamDetailVo>> itemCodeMap = responsibilityCodeMap.get(itemCost.getCode());
+                                                        if (!CollectionUtils.isEmpty(itemCodeMap)) {
+                                                            List<ComputeShareParamDetailVo> computeShareParamDetailVos = itemCodeMap.get(shareParamCode);
+                                                            if (!CollectionUtils.isEmpty(computeShareParamDetailVos)) {
+                                                                for (ComputeShareParamDetailVo vo : computeShareParamDetailVos) {
+                                                                    //成本总额*项目分摊参数数值1*权重1/项目分摊参数数值加总1
+                                                                    BigDecimal multiply = amount.multiply(vo.getComputeResult()).multiply(percent).divide(totalPercent, 4, RoundingMode.HALF_UP);
+                                                                    sum.updateAndGet(v -> v.add(multiply));
+                                                                    if (!vo.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
+                                                                        singleSum.updateAndGet(v -> v.add(multiply.divide(vo.getNum(), 4, RoundingMode.HALF_UP)));
+                                                                    }
                                                                 }
+                                                            } else {
+                                                                sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
+                                                                singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                             }
                                                         } else {
                                                             sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
@@ -1600,29 +1645,29 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                                                         singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                     }
                                                 } else {
-                                                    sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
-                                                    singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
-                                                }
-                                            } else {
-                                                //项目分摊汇总为0 按项目收入进行计算
-                                                if (!CollectionUtils.isEmpty(responsibilityCodeMap)) {
-                                                    Map<String, List<ComputeShareParamDetailVo>> itemCodeMap = responsibilityCodeMap.get(itemCost.getCode());
-                                                    BigDecimal totalAmount = responsibilitySum.get(responsibilityCode);
-                                                    if (!CollectionUtils.isEmpty(itemCodeMap)) {
-                                                        List<ComputeShareParamDetailVo> computeShareParamDetailVos = itemCodeMap.get(shareParamCode);
-                                                        if (!CollectionUtils.isEmpty(computeShareParamDetailVos)) {
-                                                            for (ComputeShareParamDetailVo vo : computeShareParamDetailVos) {
-                                                                //成本总额*项目分摊参数数值1*权重1/项目分摊参数数值加总1
-                                                                if(!totalAmount.equals(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP))){
-                                                                    BigDecimal multiply = amount.multiply(item.getAmount()).multiply(percent).divide(totalAmount, 4, RoundingMode.HALF_UP);
-                                                                    sum.updateAndGet(v -> v.add(multiply));
-                                                                    if (!vo.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
-                                                                        singleSum.updateAndGet(v -> v.add(multiply.divide(vo.getNum(), 4, RoundingMode.HALF_UP)));
+                                                    //项目分摊汇总为0 按项目收入进行计算
+                                                    if (!CollectionUtils.isEmpty(responsibilityCodeMap)) {
+                                                        Map<String, List<ComputeShareParamDetailVo>> itemCodeMap = responsibilityCodeMap.get(itemCost.getCode());
+                                                        BigDecimal totalAmount = responsibilitySum.get(responsibilityCode);
+                                                        if (!CollectionUtils.isEmpty(itemCodeMap)) {
+                                                            List<ComputeShareParamDetailVo> computeShareParamDetailVos = itemCodeMap.get(shareParamCode);
+                                                            if (!CollectionUtils.isEmpty(computeShareParamDetailVos)) {
+                                                                for (ComputeShareParamDetailVo vo : computeShareParamDetailVos) {
+                                                                    //成本总额*项目分摊参数数值1*权重1/项目分摊参数数值加总1
+                                                                    if(!totalAmount.equals(BigDecimal.ZERO.setScale(4, RoundingMode.HALF_UP))){
+                                                                        BigDecimal multiply = amount.multiply(item.getAmount()).multiply(percent).divide(totalAmount, 4, RoundingMode.HALF_UP);
+                                                                        sum.updateAndGet(v -> v.add(multiply));
+                                                                        if (!vo.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
+                                                                            singleSum.updateAndGet(v -> v.add(multiply.divide(vo.getNum(), 4, RoundingMode.HALF_UP)));
+                                                                        }
+                                                                    }else {
+                                                                        sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
+                                                                        singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                                     }
-                                                                }else {
-                                                                    sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
-                                                                    singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                                 }
+                                                            } else {
+                                                                sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
+                                                                singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                             }
                                                         } else {
                                                             sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
@@ -1632,10 +1677,10 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                                                         sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                         singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                     }
-                                                } else {
-                                                    sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
-                                                    singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                                 }
+                                            } else {
+                                                sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
+                                                singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                             }
                                         } else {
                                             sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
@@ -1645,21 +1690,22 @@ public class ProjectCostServiceImpl implements ProjectCostService {
                                         sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                         singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                     }
+                                    detail.setComputeResult(sum.get());
+                                    detail.setComputeSingleResult(singleSum.get());
+
                                 } else {
-                                    sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
-                                    singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
+                                    detail.setComputeResult(BigDecimal.ZERO);
+                                    detail.setComputeSingleResult(BigDecimal.ZERO);
                                 }
-                                detail.setComputeResult(sum.get());
-                                detail.setComputeSingleResult(singleSum.get());
-
                             } else {
                                 detail.setComputeResult(BigDecimal.ZERO);
                                 detail.setComputeSingleResult(BigDecimal.ZERO);
                             }
-                        } else {
+                        }else {
                             detail.setComputeResult(BigDecimal.ZERO);
                             detail.setComputeSingleResult(BigDecimal.ZERO);
                         }
+
                         saveList.add(detail);
                     }
                 });

+ 21 - 0
src/main/java/com/kcim/service/impl/ReportFormServiceImpl.java

@@ -534,4 +534,25 @@ public class ReportFormServiceImpl extends ServiceImpl<ReportFormMapper, ReportF
 
         return null;
     }
+
+    /**
+     * 此方法查询的数据包括已作废的数据,调用时需要区分
+     * @param hospId 院区id
+     * @param reportType 报表类型
+     * @param reportId 报表id
+     * @return 报表项目配置
+     */
+    @Override
+    public ReportForm getByReportId(Long hospId, String reportType, Long reportId) {
+        return this.baseMapper.getByReportId(hospId,reportType,reportId);
+
+
+    }
+
+    @Override
+    public List<ReportForm> getByReportType(Long hospId, String reportType) {
+        return this.baseMapper.getByReportType(hospId,reportType);
+
+
+    }
 }

+ 1 - 1
src/main/java/com/kcim/service/impl/ReportRelationServiceImpl.java

@@ -179,7 +179,7 @@ public class ReportRelationServiceImpl extends ServiceImpl<ReportRelationMapper,
                 return reportRelation;
             }).collect(Collectors.toList());
             // 校验 关联关系的id 是否已绑定过其他的报表项目
-            checkIfExist(hospId, relation, relationCodes,reportType);
+//            checkIfExist(hospId, relation, relationCodes,reportType);
             this.saveBatch(reportRelations);
         }
 

+ 12 - 4
src/main/java/com/kcim/service/impl/ReportServiceImpl.java

@@ -11,10 +11,7 @@ import com.kcim.common.exception.CostException;
 import com.kcim.common.util.PageUtils;
 import com.kcim.common.util.UserContext;
 import com.kcim.dao.model.*;
-import com.kcim.dao.repository.CostColumnRepository;
-import com.kcim.dao.repository.CostReportColumnRepository;
-import com.kcim.dao.repository.CostReportRedirectRepository;
-import com.kcim.dao.repository.CostReportRepository;
+import com.kcim.dao.repository.*;
 import com.kcim.service.CenterService;
 import com.kcim.service.ReportService;
 import com.kcim.vo.*;
@@ -51,6 +48,8 @@ public class ReportServiceImpl implements ReportService {
     CostReportRedirectRepository costReportRedirectRepository;
 
     CenterService centerService;
+
+    CostReportIndexRepository costReportIndexRepository;
     @Override
     public Object getReportData(Integer current, Integer pageSize, String reportCode, Map<String, String> parameter) {
         CostReport report = repository.getReportByReportCode(Long.valueOf(reportCode));
@@ -325,6 +324,15 @@ public class ReportServiceImpl implements ReportService {
         return response;
     }
 
+    @Override
+    public Object getReportIndex(Long reportCode) {
+        CostReport report = repository.getReportByReportCode(reportCode);
+        List<CostReportIndex> byReportCode = costReportIndexRepository.getByReportCode(Collections.singletonList(reportCode));
+        if(!CollectionUtils.isEmpty(byReportCode)){
+            report.setReportIndex(byReportCode);
+        }
+        return report;
+    }
 
 
     private BigDecimal getFormulaData(String formula, List<ReportVo> dataVo, CostReportColumn column) {

+ 11 - 6
src/main/java/com/kcim/service/impl/ResponsibilityDepartmentServiceImpl.java

@@ -9,15 +9,16 @@ import com.kcim.dao.mapper.ResponsibilityDepartmentMapper;
 import com.kcim.dao.model.Responsibility;
 import com.kcim.dao.model.ResponsibilityDepartment;
 import com.kcim.dao.model.dto.DepartDTO;
-import com.kcim.vo.CenterDepartmentVO;
+import com.kcim.dao.model.dto.SysDepartment;
+import com.kcim.service.CenterService;
 import com.kcim.service.ResponsibilityDepartmentService;
 import com.kcim.service.ResponsibilityService;
+import com.kcim.vo.CenterDepartmentVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -29,13 +30,15 @@ public class ResponsibilityDepartmentServiceImpl
 
     private ResponsibilityService responsibilityService;
 
-    public ResponsibilityDepartmentServiceImpl(ResponsibilityService responsibilityService) {
+    private CenterService centerService;
+
+    public ResponsibilityDepartmentServiceImpl(ResponsibilityService responsibilityService, CenterService centerService) {
         this.responsibilityService = responsibilityService;
+        this.centerService = centerService;
     }
 
     /**
      * 获取责任中心对照列表
-     *
      * @return
      */
     @Override
@@ -74,10 +77,12 @@ public class ResponsibilityDepartmentServiceImpl
         if (byId.getIsGatherCenter() == 1) {
             throw new CostException(500, "汇总中心不允许添加对照关系,请先修改");
         }
-        List<ResponsibilityDepartment> data = departmentIds.stream().map(item -> {
+
+        List<SysDepartment> departmentByDepartmentIds = centerService.getDepartmentByDepartmentIds(departmentIds);
+        List<ResponsibilityDepartment> data = departmentByDepartmentIds.stream().map(item -> {
             ResponsibilityDepartment centerDepart = new ResponsibilityDepartment();
             return centerDepart.setResponsibilityId(responsibilityId).setCreateTime(System.currentTimeMillis()).setHospId(hospId)
-                    .setDepartmentId(item);
+                    .setDepartmentId(Long.valueOf(item.getId())).setDepartmentCode(item.getCode()).setResponsibilityCode(byId.getResponsibilityCode());
         }).collect(Collectors.toList());
 
         this.saveBatch(data);

+ 13 - 3
src/main/java/com/kcim/service/impl/ResponsibilityServiceImpl.java

@@ -73,10 +73,11 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
             }
         }
 
-
-        return costResponsibilityVOS.stream().filter(i -> i.getParentId() == 0)
+        List<CostResponsibilityVO> collect = costResponsibilityVOS.stream().filter(i -> i.getParentId() == 0)
                 .peek(i -> i.setChild(this.getResponsibilityChildren(i, costResponsibilityVOS)))
                 .collect(Collectors.toList());
+        responsibilitySort(collect);
+        return collect;
 //        List<CostResponsibilityVO> parentCostResponsibility = costResponsibilityVOS.stream()
 //                .filter(i -> i.getParentId() == 0).collect(Collectors.toList());
 //        // 多层结构
@@ -88,7 +89,14 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
 //        }
 //        return all;
     }
-
+    private void responsibilitySort(List<CostResponsibilityVO> responsibilityList){
+        for (CostResponsibilityVO responsibility :responsibilityList){
+            if(!CollectionUtils.isEmpty(responsibility.getChild())){
+                responsibilitySort(responsibility.getChild());
+            }
+        }
+        responsibilityList.sort(Comparator.comparing(CostResponsibilityVO::getSort,Comparator.nullsLast(Integer::compareTo)));
+    }
     private List<CostResponsibilityVO> getCostResponsibilityVO() {
         List<Responsibility> list = this.list(
                 new LambdaQueryWrapper<Responsibility>()
@@ -389,6 +397,7 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
         List<CenterDepartmentVO> centerDepartmentVOS = costResponsibilityVOS.stream().map(i -> {
             CenterDepartmentVO vo = BeanUtil.convertObj(i, CenterDepartmentVO.class);
             vo.setResponsibilityId(i.getId());
+            vo.setResponsibilityCode(i.getResponsibilityCode());
             return vo;
         }).collect(Collectors.toList());
 
@@ -409,6 +418,7 @@ public class ResponsibilityServiceImpl extends ServiceImpl<ResponsibilityMapper,
                     if(!StringUtils.isEmpty(departName)){
                         vo.setDepartmentId(department.getDepartmentId());
                         vo.setDepartmentName(departName +departmentCodeMap.get(department.getDepartmentId()));
+                        vo.setDepartmentCode(department.getDepartmentCode());
                     }
                     departVOS.add(vo);
                 }

+ 3 - 1
src/main/java/com/kcim/service/impl/ShareParamServiceImpl.java

@@ -789,7 +789,9 @@ public class ShareParamServiceImpl implements ShareParamService {
                             details.add(result);
                         }
                     } else {
-                        result.setComputeResult(BigDecimal.ZERO);
+                        if (result != null) {
+                            result.setComputeResult(BigDecimal.ZERO);
+                        }
                         result.setComputeSingleResult(BigDecimal.ZERO);
                         result.setShareParamCode(shareParam.getShareParamCode());
                         details.add(result);

+ 66 - 3
src/main/java/com/kcim/service/impl/SqlServiceImpl.java

@@ -1,6 +1,7 @@
 package com.kcim.service.impl;
 
 import com.kcim.common.constants.NumberConstant;
+import com.kcim.common.constants.SQLParameter;
 import com.kcim.common.exception.CostException;
 import com.kcim.common.util.SnowflakeUtil;
 import com.kcim.common.util.UserContext;
@@ -9,11 +10,16 @@ import com.kcim.dao.repository.SqlRepository;
 import com.kcim.service.CenterService;
 import com.kcim.service.SqlService;
 import com.kcim.vo.DictDataVo;
-import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.jdbc.SqlRunner;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -26,10 +32,23 @@ import static com.kcim.common.constants.Constant.CUSTOMIZE_SQL_TYPE;
  * @create: 2024-03-19 11:10
  **/
 @Service("SqlService")
-@AllArgsConstructor
 @Slf4j
 public class SqlServiceImpl implements SqlService {
 
+    @Value("${spring.datasource.driver-class-name}")
+    private String driver;
+    @Value("${spring.datasource.url}")
+    private String url;
+    @Value("${spring.datasource.username}")
+    private String username;
+    @Value("${spring.datasource.password}")
+    private String password;
+
+    public SqlServiceImpl(SqlRepository repository, CenterService centerService) {
+        this.repository = repository;
+        this.centerService = centerService;
+    }
+
     SqlRepository repository;
 
     CenterService centerService;
@@ -133,7 +152,51 @@ public class SqlServiceImpl implements SqlService {
 
     @Override
     public List<Sql> getSqlBySqlType(String sqlType) {
-
         return repository.getSqlBySqlType(sqlType);
     }
+
+    @Override
+    public void autoExecuteSql(String sqlType, Map<String, String> parameter) {
+        List<Sql> sqlList = getSqlBySqlType(sqlType);
+        //取出需要执行的sql
+        if(!CollectionUtils.isEmpty(sqlList)){
+            sqlList.sort(Comparator.comparing(Sql::getSort,Comparator.nullsLast(Integer::compareTo)));
+            for(Sql sql:sqlList){
+                String executeSql = sql.getSql();
+                executeSql = MatchSystemParameter(executeSql);
+                //替换传参
+                if(!CollectionUtils.isEmpty(parameter)){
+                    for(String s:parameter.keySet()){
+                        //拼接 #
+                        String sqlFilter = "#" + s;
+                        if (executeSql.contains(sqlFilter)) {
+                            executeSql = executeSql.replace(sqlFilter, parameter.get(s));
+                        }
+                    }
+                }
+                try {
+                    SqlRunner sqlRunner = new SqlRunner(getConnection());
+                    log.info("执行的语句"+sqlType+":"+executeSql);
+                    sqlRunner.run(executeSql);
+                } catch (SQLException | ClassNotFoundException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+    private Connection getConnection() throws SQLException, ClassNotFoundException {
+        Class.forName(driver);
+        return DriverManager.getConnection(url, username, password);
+    }
+    private static String MatchSystemParameter(String sql) {
+        if(StringUtils.isEmpty(sql)){
+            throw new CostException("无效自定义sql语句");
+        }
+        if (sql.contains(SQLParameter.HOSP_ID_CODE)) {
+            sql = sql.replace(SQLParameter.HOSP_ID_CODE, String.valueOf(UserContext.getCurrentLoginHospId()));
+        }
+
+        return sql;
+    }
 }

+ 18 - 0
src/main/java/com/kcim/vo/AccountAmountVo.java

@@ -0,0 +1,18 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-10 17:38
+ **/
+@Data
+public class AccountAmountVo {
+    private BigDecimal amount;
+    private String accountCode;
+    private String accountName;
+}

+ 7 - 0
src/main/java/com/kcim/vo/AllocationReportVO.java

@@ -94,4 +94,11 @@ public class AllocationReportVO {
     private String amounts;
 
     private Map<String,List<String>> targetTotalMoneys;
+    /**
+     * 分摊参数代码
+     */
+    private String shareParamCode;
+
+    private BigDecimal shareParamPercent;
+
 }

+ 2 - 0
src/main/java/com/kcim/vo/CenterDepartmentVO.java

@@ -16,6 +16,8 @@ public class CenterDepartmentVO {
 
     private Long responsibilityId;
 
+    private String responsibilityCode;
+
     private String responsibilityName;
 
 //    @JsonInclude(JsonInclude.Include.NON_EMPTY)

+ 22 - 0
src/main/java/com/kcim/vo/CommonResponsibilityReportVo.java

@@ -0,0 +1,22 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-13 15:20
+ **/
+@Data
+public class CommonResponsibilityReportVo {
+    private String responsibilityCode;
+
+    private String responsibilityName;
+
+    private Integer sort;
+
+    private List<CommonResponsibilityReportVo> child;
+}

+ 6 - 0
src/main/java/com/kcim/vo/CostAccountShareVO.java

@@ -56,4 +56,10 @@ public class CostAccountShareVO {
      */
     private String alias;
     private String allParentIds;
+
+    private String paramList;
+
+    private String shareParamMap;
+
+
 }

+ 18 - 0
src/main/java/com/kcim/vo/CostProfitRedirectAliasVo.java

@@ -0,0 +1,18 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-12 16:23
+ **/
+@Data
+public class CostProfitRedirectAliasVo {
+    private String alias;
+
+    private List<CostProfitRedirectDataVo> shareParamData;
+}

+ 30 - 0
src/main/java/com/kcim/vo/CostProfitRedirectDataVo.java

@@ -0,0 +1,30 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-12 16:23
+ **/
+@Data
+public class CostProfitRedirectDataVo {
+
+    private String shareParamCode;
+
+    private String shareParamName;
+
+    private BigDecimal shareParamAmount;
+
+    private BigDecimal shareParamValue;
+
+    private String shareParamRate;
+
+    private BigDecimal shareParamNum;
+
+    private BigDecimal percent;
+
+}

+ 7 - 6
src/main/java/com/kcim/vo/CostProfitVo.java

@@ -1,13 +1,7 @@
 package com.kcim.vo;
 
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -103,4 +97,11 @@ public class CostProfitVo implements Serializable {
 
 	private Integer sort;
 
+	/**
+	 * 说明
+	 */
+	private String description;
+
+	private List<ReportVo> data;
+
 }

+ 9 - 0
src/main/java/com/kcim/vo/CostResponsibilityVO.java

@@ -73,4 +73,13 @@ public class CostResponsibilityVO {
     @TableField(exist = false)
     private String typeName;
 
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 启用标志 0未启用 1启用
+     */
+    private Integer status;
+
 }

+ 2 - 0
src/main/java/com/kcim/vo/CostShareParamVO.java

@@ -34,4 +34,6 @@ public class CostShareParamVO {
      * 会计科目集合
      */
     private List<String> accountingIds;
+
+    private  Integer status;
 }

+ 1 - 1
src/main/java/com/kcim/vo/CostingGroupStartVO.java

@@ -9,7 +9,7 @@ import java.io.Serializable;
 import java.math.BigDecimal;
 
 @Data
-@ApiModel("成本分摊前查询列表")
+@ApiModel("成本分摊前查询列表")
 public class CostingGroupStartVO implements Serializable {
     private static final long serialVersionUID = 1L;
 

+ 2 - 0
src/main/java/com/kcim/vo/DepartVO.java

@@ -10,4 +10,6 @@ public class DepartVO {
     private String departmentName;
 
     private Integer departmentStatus;
+
+    private String departmentCode;
 }

+ 27 - 0
src/main/java/com/kcim/vo/DepartmentProfitVo.java

@@ -0,0 +1,27 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-26 16:09
+ **/
+@Data
+public class DepartmentProfitVo {
+
+    private BigDecimal currentAmount;
+
+    private BigDecimal preMonthAmount;
+
+    private String preMonthPercent;
+
+    private BigDecimal preYearAmount;
+
+    private String preYearPercent;
+
+
+}

+ 77 - 2
src/main/java/com/kcim/vo/HospProfitVO.java

@@ -1,19 +1,94 @@
 package com.kcim.vo;
 
-import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 @Data
 public class HospProfitVO {
 
+
+    /**
+     * 主键
+     */
+    @TableId
     private Long id;
+    /**
+     * 年
+     */
     private Integer dateYear;
+    /**
+     * 月
+     */
     private Integer dateMonth;
-    private Integer reportNum;
 
+    /**
+     * 报表项目名称
+     */
     private String reportName;
+    /**
+     * 成本类型
+     */
+    private Integer costType;
+    /**
+     * 收入类型
+     */
+    private Integer incomeType;
 
+    // 0. 报表项目 1. 全院其他收支
+    private Integer originType;
+    /**
+     * 金额
+     */
     private BigDecimal amount;
+    private Long hospId;
+
+
+    private BigDecimal percent;
+
+    @TableField(exist = false)
+    private Integer type;
+
+    @TableField(exist = false)
+    private Integer fraction;
+
+    /**
+     * 报表项目编号一个医院中同一个类型必须唯一
+     */
+    private Integer num;
+
+    /**
+     * 父级id
+     */
+    private Long parentId;
+    /**
+     * 计算类型 0.不设置,1.对应会计科目,2.对应分摊层级,3.小计,4.计算公式,5.按责任中心
+     */
+    private Integer calcType;
+    /**
+     * 报表类型:0.损益表、1.完全成本法表、2.变动成本表、3.全院损益表、4.全成本报表
+     */
+    private Integer reportType;
+    /**
+     * 计算公式,当计算类型为计算公式的时候必传
+     */
+    private String calcFormula;
+    /**
+     * 排序字段
+     */
+    private Integer sort;
+    /**
+     * 比率基数,默认100%,后续再进行修改
+     */
+    private String ratioBase;
+
+    /**
+     * 说明
+     */
+    private String description;
+
+    private List<HospProfitVO> child;
 }

+ 22 - 0
src/main/java/com/kcim/vo/MedicalResponsibilityVo.java

@@ -0,0 +1,22 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-25 15:53
+ **/
+@Data
+public class MedicalResponsibilityVo extends ResponsibilityVo{
+    private Integer ResponsibilityType;
+
+    private List<MedicalResponsibilityVo> child;
+
+    private Long responsibilityId;
+
+    private Long parentId;
+}

+ 21 - 0
src/main/java/com/kcim/vo/ReportFormCustomVo.java

@@ -0,0 +1,21 @@
+package com.kcim.vo;
+
+import com.kcim.dao.model.ReportForm;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-19 16:29
+ **/
+@Data
+public class ReportFormCustomVo extends ReportForm {
+
+    private List<ReportVo> data;
+
+    private List<ReportFormCustomVo> children;
+
+}

+ 34 - 0
src/main/java/com/kcim/vo/ReportFormProfitVo.java

@@ -0,0 +1,34 @@
+package com.kcim.vo;
+
+import com.kcim.dao.model.ReportForm;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-26 16:07
+ **/
+@Data
+public class ReportFormProfitVo extends ReportForm {
+
+    private Integer medicalType;
+
+    private BigDecimal currentAmount;
+
+    private BigDecimal preMonthAmount;
+
+    private String preMonthPercent;
+
+    private BigDecimal preYearAmount;
+
+    private String preYearPercent;
+
+    private List<ReportFormProfitVo> children;
+
+
+
+}

+ 4 - 0
src/main/java/com/kcim/vo/ReportFormVO.java

@@ -51,6 +51,10 @@ public class ReportFormVO {
 
     private Integer fraction;
 
+    private String description;
+
+    private Integer hide;
+
     /**
      * 报表与诊次床日关联的状态
      */

+ 26 - 0
src/main/java/com/kcim/vo/ResponsibilityVo.java

@@ -0,0 +1,26 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-08-13 16:01
+ **/
+@Data
+public class ResponsibilityVo {
+
+    private String responsibilityCode;
+
+    private String responsibilityName;
+
+    private String parentResponsibilityCode;
+
+    private String parentResponsibilityName;
+
+    private Integer sort;
+
+
+
+}

+ 0 - 2
src/main/java/com/kcim/vo/ShareParamCostVo.java

@@ -1,10 +1,8 @@
 package com.kcim.vo;
 
-import com.kcim.dao.model.CostDepartmentProfit;
 import lombok.Data;
 
 import java.math.BigDecimal;
-import java.util.List;
 import java.util.Map;
 
 /**

+ 3 - 1
src/main/java/com/kcim/vo/ShareParamProportionVO.java

@@ -3,6 +3,8 @@ package com.kcim.vo;
 import io.swagger.annotations.ApiModel;
 import lombok.Data;
 
+import java.math.BigDecimal;
+
 /**
  * @author 李加喜
  * @Package com.imed.costaccount.model.vo
@@ -26,5 +28,5 @@ public class ShareParamProportionVO {
     /**
      * 分摊比例
      */
-    private Integer shareParamPopout;
+    private BigDecimal shareParamPopout;
 }

+ 1 - 0
src/main/java/com/kcim/web/CostCostingCollectionController.java

@@ -18,6 +18,7 @@ import java.util.Arrays;
 @RequestMapping("costcostingcollection")
 public class CostCostingCollectionController {
 
+
     private final CostCostingCollectionService costCostingCollectionService;
 
     public CostCostingCollectionController(CostCostingCollectionService costCostingCollectionService) {

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików