Просмотр исходного кода

添加按会计科目计算科室损益报表数据

JammeyJiang 1 месяц назад
Родитель
Сommit
3fee003b1e

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

@@ -0,0 +1,16 @@
+package com.kcim.dao.mapper;
+
+import com.kcim.dao.model.CostDepartmentProfitAccount;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 科室损益的会计科目金额表
+ * 
+ * @author Wang.YS
+ * @date 2025-09-19 14:14:25
+ */
+@Mapper
+public interface CostDepartmentProfitAccountMapper extends BaseMapper<CostDepartmentProfitAccount> {
+	
+}

+ 11 - 4
src/main/java/com/kcim/dao/mapper/CostIncomeGroupMapper.java

@@ -1,14 +1,13 @@
 package com.kcim.dao.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.kcim.dao.model.CostIncomeGroup;
-import com.kcim.vo.CollectionVO;
-import com.kcim.vo.CommonDepartVo;
-import com.kcim.vo.CostIncomeGroupAllAmountBO;
-import com.kcim.vo.CostIncomeGroupAllAmountVO;
+import com.kcim.vo.*;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -58,4 +57,12 @@ public interface CostIncomeGroupMapper extends BaseMapper<CostIncomeGroup> {
     List<CostIncomeGroup> selectHistoryList(@Param("hospId") Long hospId,@Param("id") Long id);
 
     void reducingHistory(@Param("id") Long id,@Param("hospId") Long hospId,@Param("list") List<Long> list);
+
+    List<CostIncomeGroup>  getOrderDeptProductList(Page<PatientInfoVo> page, @Param("year") Integer year, @Param("month") Integer month, @Param("departmentCode") String departmentCode, @Param("hospId") Long hospId, @Param("filter") String filter);
+
+    List<CostIncomeGroup> getExecDeptProductList(@Param("page") Page<PatientInfoVo> page, @Param("year") Integer year, @Param("month") Integer month, @Param("departmentCode") String departmentCode, @Param("hospId") Long hospId, @Param("filter") String filter);
+
+    BigDecimal getTotalAmount(@Param("year") Integer year, @Param("month") Integer month, @Param("departmentCode") String departmentCode, @Param("hospId") Long hospId);
+
+    BigDecimal getDeptTotalAmount(@Param("year") Integer year, @Param("month") Integer month, @Param("departmentCode") String departmentCode, @Param("hospId") Long hospId);
 }

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

@@ -11,6 +11,7 @@ import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * 科室损益计算
@@ -145,5 +146,11 @@ public class CostDepartmentProfit implements Serializable {
 	 */
 	private BigDecimal yoyRate;
 
+	/**
+	 * 会计科目金额列表
+	 */
+	@TableField(exist = false)
+	private List<CostDepartmentProfitAccount> costDepartmentProfitAccounts;
+
 
 }

+ 87 - 0
src/main/java/com/kcim/dao/model/CostDepartmentProfitAccount.java

@@ -0,0 +1,87 @@
+package com.kcim.dao.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+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;
+import java.util.Date;
+
+/**
+ * 科室损益的会计科目金额表
+ * 
+ * @author Wang.YS
+
+ * @date 2025-09-19 14:14:25
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("cost_department_profit_account")
+public class CostDepartmentProfitAccount implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@TableId
+	private Integer id;
+	/**
+	 * 医院id
+	 */
+	private Long hospId;
+	/**
+	 * 核算年月
+	 */
+	private String computeDate;
+	/**
+	 * 项目成本主键
+	 */
+	private Long deptProfitId;
+	/**
+	 * 成本类别
+	 */
+	private String costType;
+	/**
+	 * 会计科目类别
+	 */
+	private String accountType;
+	/**
+	 * 金额
+	 */
+	private BigDecimal amount;
+	/**
+	 * 创建人
+	 */
+	private String createUser;
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+	/**
+	 * 更新人
+	 */
+	private String updateUser;
+	/**
+	 * 更新时间
+	 */
+	private Date updateTime;
+	/**
+	 * 删除人
+	 */
+	private String deleteUser;
+	/**
+	 * 删除时间
+	 */
+	private Date deleteTime;
+	/**
+	 * 删除标志  0正常 1作废
+	 */
+	private Integer delFlag;
+
+}

+ 26 - 0
src/main/java/com/kcim/dao/repository/CostDepartmentProfitAccountRepository.java

@@ -0,0 +1,26 @@
+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.CostDepartmentProfitAccountMapper;
+import com.kcim.dao.model.CostDepartmentProfitAccount;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-11-27 17:52
+ **/
+@Repository
+public class CostDepartmentProfitAccountRepository extends ServiceImpl<CostDepartmentProfitAccountMapper, CostDepartmentProfitAccount> {
+    public List<CostDepartmentProfitAccount> getList(String computeDate) {
+        LambdaQueryWrapper<CostDepartmentProfitAccount> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(CostDepartmentProfitAccount::getHospId, UserContext.getHospId());
+        queryWrapper.eq(CostDepartmentProfitAccount::getComputeDate, computeDate);
+        return this.list(queryWrapper);
+    }
+}

+ 695 - 23
src/main/java/com/kcim/service/impl/CostDepartmentProfitServiceImpl.java

@@ -31,13 +31,16 @@ import com.kcim.common.util.excel.entity.TitleEntity;
 import com.kcim.dao.mapper.CostDepartmentProfitMapper;
 import com.kcim.dao.model.*;
 import com.kcim.dao.repository.ComputeLastProfitDateRepository;
+import com.kcim.dao.repository.CostDepartmentProfitAccountRepository;
 import com.kcim.dao.repository.CostDepartmentProfitRepository;
+import com.kcim.dao.repository.ResponsibilityRepository;
 import com.kcim.service.*;
 import com.kcim.vo.*;
 import com.kcim.web.reponse.BatchCostProfitResponse;
 import com.kcim.web.reponse.ComputeProfitCollectResponse;
 import com.kcim.web.reponse.CostProfitRedirectResponse;
 import com.kcim.web.reponse.ProfitReportResponse;
+import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.FileItemFactory;
@@ -75,6 +78,7 @@ import static com.kcim.common.constants.ParameterConstant.MEDICAL_TECHNIQUES_SHA
 
 @Service("costDepartmentProfitService")
 @Slf4j
+@AllArgsConstructor
 public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentProfitMapper, CostDepartmentProfit> implements CostDepartmentProfitService {
 
 //    @Value("${file.filelocal}")
@@ -115,6 +119,9 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
 
     private final UserResponsibilityRightService userResponsibilityRightService;
 
+    ResponsibilityRepository responsibilityRepository;
+
+    CostDepartmentProfitAccountRepository costDepartmentProfitAccountRepository;
 
     private final SqlService sqlService;
     private final String AMOUNT = "金额";
@@ -124,26 +131,26 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
     private final String AMOUNT_FIELD = "amount";
 
     private final String PERCENT_FIELD = "percent";
-
-    public CostDepartmentProfitServiceImpl(ReportFormService reportFormService, IncomeCollectionService incomeCollectionService, CostShareLevelService costShareLevelService, ResponsibilityService responsibilityService, ReportRelationService reportRelationService, AllocationService allocationService, AllocationQueryService allocationQueryService, FileRecordService fileRecordService, MinioConfig minioConfig, MinioFileUtil minioFileUtil, CenterService centerService, CostDepartmentProfitRepository costDepartmentProfitRepository, ComputeLastProfitDateRepository computeLastProfitDateRepository, AccountingService accountingService, CostAccountShareService costAccountShareService, SqlService sqlService, UserResponsibilityRightService userResponsibilityRightService) {
-        this.reportFormService = reportFormService;
-        this.incomeCollectionService = incomeCollectionService;
-        this.costShareLevelService = costShareLevelService;
-        this.responsibilityService = responsibilityService;
-        this.reportRelationService = reportRelationService;
-        this.allocationService = allocationService;
-        this.allocationQueryService = allocationQueryService;
-        this.fileRecordService = fileRecordService;
-        this.minioConfig = minioConfig;
-        this.minioFileUtil = minioFileUtil;
-        this.centerService = centerService;
-        this.costDepartmentProfitRepository = costDepartmentProfitRepository;
-        this.computeLastProfitDateRepository = computeLastProfitDateRepository;
-        this.accountingService = accountingService;
-        this.costAccountShareService = costAccountShareService;
-        this.sqlService = sqlService;
-        this.userResponsibilityRightService = userResponsibilityRightService;
-    }
+//
+//    public CostDepartmentProfitServiceImpl(ReportFormService reportFormService, IncomeCollectionService incomeCollectionService, CostShareLevelService costShareLevelService, ResponsibilityService responsibilityService, ReportRelationService reportRelationService, AllocationService allocationService, AllocationQueryService allocationQueryService, FileRecordService fileRecordService, MinioConfig minioConfig, MinioFileUtil minioFileUtil, CenterService centerService, CostDepartmentProfitRepository costDepartmentProfitRepository, ComputeLastProfitDateRepository computeLastProfitDateRepository, AccountingService accountingService, CostAccountShareService costAccountShareService, SqlService sqlService, UserResponsibilityRightService userResponsibilityRightService) {
+//        this.reportFormService = reportFormService;
+//        this.incomeCollectionService = incomeCollectionService;
+//        this.costShareLevelService = costShareLevelService;
+//        this.responsibilityService = responsibilityService;
+//        this.reportRelationService = reportRelationService;
+//        this.allocationService = allocationService;
+//        this.allocationQueryService = allocationQueryService;
+//        this.fileRecordService = fileRecordService;
+//        this.minioConfig = minioConfig;
+//        this.minioFileUtil = minioFileUtil;
+//        this.centerService = centerService;
+//        this.costDepartmentProfitRepository = costDepartmentProfitRepository;
+//        this.computeLastProfitDateRepository = computeLastProfitDateRepository;
+//        this.accountingService = accountingService;
+//        this.costAccountShareService = costAccountShareService;
+//        this.sqlService = sqlService;
+//        this.userResponsibilityRightService = userResponsibilityRightService;
+//    }
 
     /**
      * 查询科室损益数据
@@ -348,7 +355,7 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
                 i.setAmount(setSubtotal(i, costShareLevelList, listMap, list, incomeList, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
             } else if (NumberConstant.FOUR.equals(calcType)) {
                 // TODO 按照计算公式进行计算
-//                i.setAmount(setCalculation(i, list, costShareLevelList, listMap, incomeList, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
+                i.setAmount(setCalculation(i, list, costShareLevelList, listMap, incomeList, allocationQueryReportVOList, reportRelationMap, allocationList, allList));
             } else if (NumberConstant.FIVE.equals(calcType)) {
                 // TODO  按照责任中心进行计算
                 i.setAmount(setResponsibilityCode(i, reportRelationMap, allocationList, allList));
@@ -1117,8 +1124,14 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
     public void computeProfit(String computeDate, Long hospId, String reportType) {
         //需要用代码计算时
         if(IsNeedCalc(reportType)){
-            //计算科室损益
-            computeProfitAction(computeDate, hospId, reportType);
+            String parameterValue = centerService.getParameterValue(ParameterConstant.ALLOCATION_TYPE);
+            if (NumberConstant.ONE_S.equals(parameterValue)) {
+                //按责任中心分摊的科室损益计算
+                computeProfitAction(computeDate, hospId, reportType);
+            }else if (NumberConstant.TWO_S.equals(parameterValue)) {
+                //按会计科目分摊的科室损益计算
+                calcDeptProfit(computeDate, hospId, reportType);
+            }
             //计算同环比
             handleSpecificMonthsCalculation(hospId, computeDate, reportType);
         }
@@ -3661,4 +3674,663 @@ public class CostDepartmentProfitServiceImpl extends ServiceImpl<CostDepartmentP
         return rate.setScale(4, RoundingMode.HALF_UP);
     }
 
+    /**
+     * 计算科室损益
+     * @param computeDate
+     * @param hospId
+     * @param reportType
+     */
+    private void calcDeptProfit(String computeDate, Long hospId, String reportType) {
+        //获取科室损益计算所需的数据
+        ProfitCalculationDataVo profitCalculationData = getProfitCalculationData(computeDate, hospId, reportType);
+        //计算科室损益
+        List<CostDepartmentProfitVO> costDepartmentProfitVOS = calcDeptProfit(profitCalculationData);
+        // 删除这个年月的数据
+        deleteDeptProfit(profitCalculationData.getYear(),profitCalculationData.getMonth(),reportType  );
+        // 添加数据
+        List<CostDepartmentProfit> costDepartmentProfits = BeanUtil.convertList(costDepartmentProfitVOS, CostDepartmentProfit.class);
+        //统一创建时间
+        long l = System.currentTimeMillis();
+        costDepartmentProfits.forEach(i -> {
+            i.setCreateTime(l);
+        });
+        //保存科室损益数据
+        this.saveBatch(costDepartmentProfits);
+        //处理科室损益的会计科目金额数据
+        List<CostDepartmentProfitAccount> costDepartmentProfitAccounts=new ArrayList<>();
+        for (CostDepartmentProfit deptProfit : costDepartmentProfits) {
+            deptProfit.getCostDepartmentProfitAccounts().forEach(account -> {
+                account.setDeptProfitId(deptProfit.getId());
+                account.setComputeDate(computeDate);
+                account.setHospId(hospId);
+            });
+            costDepartmentProfitAccounts.addAll(deptProfit.getCostDepartmentProfitAccounts());
+        }
+        //保存科室损益的会计科目金额数据
+        costDepartmentProfitAccountRepository.saveBatch(costDepartmentProfitAccounts);
+        //记录最后一次 损益计算日期
+        computeLastProfitDateRepository.saveLastComputeDate(hospId, computeDate);
+    }
+
+    /**
+     * 获取科室损益计算所需的数据
+     * @param computeDate
+     * @param hospId
+     * @param reportType
+     * @return
+     */
+    public ProfitCalculationDataVo getProfitCalculationData(String computeDate, Long hospId, String reportType) {
+        ProfitCalculationDataVo profitCalculationData = new ProfitCalculationDataVo();
+        Integer year = ComputeDateUtils.getComputeYear(computeDate);
+        Integer month = ComputeDateUtils.getComputeMonth(computeDate);
+
+        // 获取指定类型的报表配置
+        List<ReportForm> reportFormList = getReportForm(reportType);
+        if (CollUtil.isEmpty(reportFormList)) {
+            throw new CostException(500, "损益表未找到");
+        }
+        //获取报表设置明细
+        List<ReportRelation> reportRelation = getReportRelation();
+        Map<Long, List<ReportRelation>> reportRelationMap = reportRelation.stream().collect(Collectors.groupingBy(ReportRelation::getReportId));
+
+        // 查询最后一个层级的责任中心
+        List<CostShareLevel> costShareLevelList = getCostShareLevelList();
+        if (CollUtil.isEmpty(costShareLevelList)) {
+            throw new CostException(500, "分摊层级未设置");
+        }
+
+        //获取指定报表对应的责任中心
+        List<Responsibility> responsibilityList = getReportResponsibilityList(reportType);
+
+        // 获取归集后的收入数据
+        List<IncomeCollection> incomeList = getIncomeCollectionList(year,month);
+        if (CollUtil.isEmpty(incomeList)) {
+            throw new CostException(500, "归集后数据不存在");
+        }
+
+        // 获取分摊后数据
+        List<AllocationQuery> allocationQueryList = allocationQueryService.getAllByDate(hospId,year,month);
+        if (CollUtil.isEmpty(allocationQueryList)) {
+            throw new CostException(500, "分摊后数据不存在");
+        }
+
+        // 封装数据
+        List<AllocationQueryReportVO> allocationQueryReportVOList = BeanUtil.convertList(allocationQueryList, AllocationQueryReportVO.class);
+        allocationQueryReportVOList.forEach(i -> {
+            i.setAccountingCodes(Arrays.asList(i.getAccountingCode().split(StrUtil.COMMA)));
+            i.setAccountingNames(Arrays.asList(i.getAccountingName().split(StrUtil.COMMA)));
+        });
+
+        // 查询分摊的报表数据 后面的计算方式需要使用 小计等需要使用
+        List<Allocation> allocationList = allocationService.getByDate( year, month, hospId);
+        if (CollUtil.isEmpty(allocationList)) {
+            throw new CostException(500, "分摊报表数据不存在");
+        }
+        profitCalculationData.setComputeDate(computeDate);
+        profitCalculationData.setYear(year);
+        profitCalculationData.setMonth(month);
+        profitCalculationData.setHospId(hospId);
+        profitCalculationData.setReportType(reportType);
+        profitCalculationData.setReportFormList(reportFormList);
+        profitCalculationData.setReportRelationList(reportRelation);
+        profitCalculationData.setReportRelationMap(reportRelationMap);
+        profitCalculationData.setCostShareLevelList(costShareLevelList);
+        profitCalculationData.setResponsibilityList(responsibilityList);
+        return profitCalculationData;
+    }
+
+    /**
+     * 计算科室损益
+     * @param profitCalculationData
+     * @return
+     */
+    private List<CostDepartmentProfitVO> calcDeptProfit(ProfitCalculationDataVo profitCalculationData) {
+        List<ReportForm> firstLevelReports = profitCalculationData.getReportFormList().stream().filter(i -> i.getParentId().equals(NumberConstant.ZERO)).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(firstLevelReports)){
+            throw new CostException(500, "未找到第一层报表项目,请检查报表配置");
+        }
+        //按顺序号排序
+        firstLevelReports.sort(Comparator.comparing(ReportForm::getSort, Comparator.nullsLast(Integer::compareTo)));
+        Map<Long, List<ReportForm>> reportParentGroup = profitCalculationData.getReportFormList().stream().collect(Collectors.groupingBy(ReportForm::getParentId));
+        List<CostDepartmentProfitVO> costDepartmentProfitVOList = new ArrayList<>();
+        //循环设置子级报表项目
+        for (ReportForm reportForm : firstLevelReports) {
+            setChildReport(reportForm,reportParentGroup);
+        }
+        //按责任中心计算科室损益
+        for (Responsibility responsibility : profitCalculationData.getResponsibilityList()) {
+            Map<Integer,CostDepartmentProfitVO> costDepartmentProfitMap=new HashMap<>();
+            //计算责任中心的所有报表项目
+            for (ReportForm reportForm : firstLevelReports) {
+                calcRespReportAmount(responsibility, reportForm,profitCalculationData, costDepartmentProfitMap);
+            }
+            //添加到结果集合
+            costDepartmentProfitVOList.addAll(costDepartmentProfitMap.values());
+        }
+        return null;
+    }
+
+    /**
+     * 循环设置子级报表项目
+     * @param reportForm
+     * @param reportParentGroup
+     */
+    public void setChildReport(ReportForm reportForm ,Map<Long, List<ReportForm>> reportParentGroup){
+        List<ReportForm> childReportForms = reportParentGroup.get(reportForm.getId());
+        if(CollUtil.isEmpty(childReportForms)){
+            return;
+        }
+        reportForm.setChild(childReportForms);
+        for (ReportForm cildReportForm : childReportForms) {
+            setChildReport(cildReportForm,reportParentGroup);
+        }
+    }
+
+
+    /**
+     * 计算指定责任中心指定报表项目的金额(优先计算子级,再按顺序号计算非公式项,最后计算公式项)
+     * @param profitCalculationData
+     * @param costDepartmentProfitMap
+     * @param parentReport
+     * @param responsibility
+     */
+    public void calcRespReportAmount(Responsibility responsibility,
+                                 ReportForm parentReport ,
+                                 ProfitCalculationDataVo profitCalculationData,
+                                 Map<Integer,CostDepartmentProfitVO> costDepartmentProfitMap){
+        //有子级的优先计算子级
+        if(!CollUtil.isEmpty(parentReport.getChild())){
+            //计算报表项目的金额
+            for (ReportForm reportForm : parentReport.getChild()) {
+                //计算子级的金额
+                calcRespReportAmount(responsibility,reportForm,profitCalculationData,costDepartmentProfitMap);
+            }
+            //找出所有类型不是计算公式且不是不设置的报表项
+            List<ReportForm> calcReportList = parentReport.getChild().stream().filter(i ->!NumberConstant.ZERO.equals(i.getCalcType())&& !NumberConstant.THREE.equals(i.getCalcType())).collect(Collectors.toList());
+            //优先计算类型为非计算公式的报表项
+            if (!CollUtil.isEmpty(calcReportList)){
+                for (ReportForm reportForm : calcReportList) {
+                    calcReportAmount(responsibility,reportForm,profitCalculationData,costDepartmentProfitMap);
+                }
+            }
+            //找出所有类型为计算公式的报表项
+            List<ReportForm> formulaReportList = parentReport.getChild().stream().filter(i -> NumberConstant.THREE.equals(i.getCalcType())).collect(Collectors.toList());
+            //再计算类型为计算公式的报表项
+            if (!CollUtil.isEmpty(formulaReportList)){
+                for (ReportForm reportForm : formulaReportList) {
+                    calcReportAmount(responsibility,reportForm,profitCalculationData,costDepartmentProfitMap);
+                }
+            }
+        }else{
+            //没有子级项目的只要计算自己
+            calcReportAmount(responsibility,parentReport,profitCalculationData,costDepartmentProfitMap);
+        }
+    }
+
+
+    /**
+     * 计算一个报表项目的金额
+     * @param profitCalculationData
+     * @param costDepartmentProfitMap
+     * @param reportForm
+     */
+    public void calcReportAmount(Responsibility responsibility,ReportForm reportForm,ProfitCalculationDataVo profitCalculationData,Map<Integer,CostDepartmentProfitVO> costDepartmentProfitMap){
+        Integer calcType = reportForm.getCalcType();
+        CostDepartmentProfitVO costDepartmentProfitVO = createCostDepartmentProfitVO(responsibility,reportForm,profitCalculationData);
+        switch (calcType){
+            case 1:
+                if(NumberConstant.ONE.equals(reportForm.getCostType())){
+                    //按收入会计科目计算
+                    setIncomeAccountReportValue(costDepartmentProfitVO,profitCalculationData,responsibility,reportForm);
+                }else{
+                    //按成本会计科目计算
+                    setCostAccountReportValue(costDepartmentProfitVO,profitCalculationData, responsibility, reportForm);
+                }
+                break;
+            case 2:
+                //按分摊层级计算
+                setShareLevelReportValue(costDepartmentProfitVO,profitCalculationData,responsibility,reportForm);
+                break;
+            case 4:
+                //按公式计算
+                setFormulaReportValue(costDepartmentProfitVO,costDepartmentProfitMap,responsibility,reportForm);
+                break;
+            case 5:
+                //按责任中心计算
+                setResponsibilityReportValue(costDepartmentProfitVO,profitCalculationData,costDepartmentProfitMap,responsibility,reportForm);
+                break;
+        }
+        //记录下已计算好的报表项目
+        if(!costDepartmentProfitMap.containsKey(reportForm.getNum())){
+            costDepartmentProfitMap.put(reportForm.getNum(),costDepartmentProfitVO);
+        }
+    }
+
+    /**
+     * 创建一个科室损益计算结果对象
+     * @param responsibility
+     * @param reportForm
+     * @param profitCalculationData
+     * @return
+     */
+    public CostDepartmentProfitVO createCostDepartmentProfitVO(Responsibility responsibility,ReportForm reportForm,ProfitCalculationDataVo profitCalculationData){
+        CostDepartmentProfitVO costDepartmentProfitVO = new CostDepartmentProfitVO();
+        costDepartmentProfitVO.setYear(profitCalculationData.getYear());
+        costDepartmentProfitVO.setMonth(profitCalculationData.getMonth());
+        costDepartmentProfitVO.setReportId(reportForm.getId());
+        costDepartmentProfitVO.setReportNum(reportForm.getNum());
+        costDepartmentProfitVO.setCalcType(reportForm.getCalcType());
+        costDepartmentProfitVO.setReportName(reportForm.getReportName());
+        costDepartmentProfitVO.setCalcFormula(reportForm.getCalcFormula());
+        costDepartmentProfitVO.setReportParentId(reportForm.getParentId());
+        costDepartmentProfitVO.setResponsibilityCode(responsibility.getResponsibilityCode());
+        costDepartmentProfitVO.setResponsibilityName(responsibility.getResponsibilityName());
+        costDepartmentProfitVO.setCostType(NumberConstant.ONE);
+        costDepartmentProfitVO.setIncomeType(NumberConstant.ONE);
+        costDepartmentProfitVO.setHospId(UserContext.getHospId());
+        costDepartmentProfitVO.setShareType(Integer.valueOf(profitCalculationData.getReportType()));
+        costDepartmentProfitVO.setType(reportForm.getCostType());
+        costDepartmentProfitVO.setFraction(reportForm.getFraction());
+        costDepartmentProfitVO.setAmount(BigDecimal.ZERO);
+        costDepartmentProfitVO.setCostDepartmentProfitAccounts(new ArrayList<>());
+        return costDepartmentProfitVO;
+    }
+
+    /**
+     * 获取按责任中心计算结果
+     * @param profitCalculationData
+     * @param costDepartmentProfitMap
+     * @param reportForm
+     * @return
+     */
+    private void setResponsibilityReportValue(CostDepartmentProfitVO costDepartmentProfitVO, ProfitCalculationDataVo profitCalculationData, Map<Integer, CostDepartmentProfitVO> costDepartmentProfitMap, Responsibility responsibility, ReportForm reportForm) {
+        List<ReportRelation> reportRelationList = profitCalculationData.getReportRelationMap().get(reportForm.getId());
+        if(CollectionUtils.isEmpty(reportRelationList)){
+            return ;
+        }
+        // 获取对应的会计科目信息  筛选会计科目的Code
+        List<String> responsibilityCodeList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
+        //类型是收入时取分摊结果表单的数据计算
+        // 需要查询分摊后的表
+        List<AllocationQueryReportVO> reportVOList = profitCalculationData.getAllocationQueryReportVOList().stream().filter(m ->
+                m.getTargetResponsibilityCode().equals(responsibility.getResponsibilityCode())
+                        &&NumberConstant.TWO.equals(m.getOriginType().intValue())
+                        && responsibilityCodeList.contains(m.getResponsibilityCode())).collect(Collectors.toList());
+        if (CollUtil.isEmpty(reportVOList)) {
+            return ;
+        }
+        List<CostDepartmentProfitAccount> costDepartmentProfitAccounts = calculateCostByTypeAndAccount(reportVOList);
+        BigDecimal totalAmount = costDepartmentProfitAccounts.stream()
+                .map(CostDepartmentProfitAccount::getAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        costDepartmentProfitVO.setAmount(totalAmount);
+        costDepartmentProfitVO.setCostDepartmentProfitAccounts(costDepartmentProfitAccounts);
+    }
+
+    /**
+     * 获取按公式计算结果
+     * @param responsibility
+     * @param costDepartmentProfitMap
+     * @param reportForm
+     * @return
+     */
+    private void setFormulaReportValue(CostDepartmentProfitVO costDepartmentProfitVO,Map<Integer, CostDepartmentProfitVO> costDepartmentProfitMap,Responsibility responsibility, ReportForm reportForm) {
+        // 获取当前报表的计算方式  [1]+[2]类型/ [1]-[2] [1]*[2] [1]/[2]
+        String formula = reportForm.getCalcFormula();
+        if (StrUtil.isBlank(formula)) {
+            costDepartmentProfitVO.setAmount(BigDecimal.ZERO);
+            costDepartmentProfitVO.setCostDepartmentProfitAccounts(new ArrayList<>());
+            return ;
+        }
+
+        String responsibilityCode = responsibility.getResponsibilityCode();
+
+        // 找出公式当中所有代码
+        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<>(BigDecimal.ZERO);
+        List<CostDepartmentProfitAccount> baseDeptProfitAccounts=new ArrayList<>();
+        for (int i = 0; i < codes.size(); i++) {
+            // 编号
+            String code = codeMap.get(i);
+            CostDepartmentProfitVO reportData = costDepartmentProfitMap.get(Integer.valueOf(code));
+
+            // 检查报表数据是否存在且属于当前责任中心
+            if (reportData == null || !responsibilityCode.equals(reportData.getResponsibilityCode())) {
+                continue;
+            }
+
+            BigDecimal amount = reportData.getAmount();
+            if (amount == null) {
+                amount = BigDecimal.ZERO;
+            }
+
+            String str = expressionMap.get(i);
+            if (str.equals("+")) {
+                baseDeptProfitAccounts=calculateAccountAmounts(baseDeptProfitAccounts,reportData.getCostDepartmentProfitAccounts(),NumberConstant.ONE);
+                totalAmount.set(totalAmount.get().add(amount));
+            } else if (str.contains("-")) {
+                baseDeptProfitAccounts=calculateAccountAmounts(baseDeptProfitAccounts,reportData.getCostDepartmentProfitAccounts(),NumberConstant.NEGATIVE);
+                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) == 0) {
+                    log.error("报表项【" + reportForm.getReportName() + "】公式除数为0,报表编号为【" + code + "】");
+                    totalAmount.set(BigDecimal.ZERO);
+                    break;
+                } else {
+                    totalAmount.set(totalAmount.get().divide(amount, 6, RoundingMode.HALF_UP));
+                }
+            }
+        }
+        //有乘除算法的只要赋值,不用设置会计科目金额
+        if(formula.contains("*")||formula.contains("/")){
+            costDepartmentProfitVO.setAmount(totalAmount.get());
+            costDepartmentProfitVO.setCostDepartmentProfitAccounts(new ArrayList<>());
+        }else{
+            costDepartmentProfitVO.setAmount(totalAmount.get());
+            costDepartmentProfitVO.setCostDepartmentProfitAccounts(baseDeptProfitAccounts);
+        }
+
+    }
+
+    /**
+     * 对两个CostDepartmentProfitVO对象的costDepartmentProfitAccounts列表进行加减运算
+     * 按照相同的costType和accountType进行合并计算,只处理amount字段
+     *
+     * @param firstList 第一个CostDepartmentProfitVO对象
+     * @param secondList 第二个CostDepartmentProfitVO对象
+     * @param operation 运算符,1表示加法,-1表示减法
+     * @return 运算结果列表
+     */
+    public List<CostDepartmentProfitAccount> calculateAccountAmounts(
+            List<CostDepartmentProfitAccount> firstList,
+            List<CostDepartmentProfitAccount> secondList,
+            int operation) {
+
+        // 处理空列表情况
+        firstList = firstList != null ?firstList : new ArrayList<>();
+        secondList = secondList != null ?secondList: new ArrayList<>();
+
+        // 创建结果列表,先复制第一个列表的所有元素
+        List<CostDepartmentProfitAccount> result = firstList.stream()
+                .map(account -> {
+                    CostDepartmentProfitAccount copy = new CostDepartmentProfitAccount();
+                    copy.setCostType(account.getCostType());
+                    copy.setAccountType(account.getAccountType());
+                    copy.setAmount(account.getAmount() != null ? account.getAmount() : BigDecimal.ZERO);
+                    return copy;
+                })
+                .collect(Collectors.toList());
+
+        // 处理第二个列表中的每个元素
+        for (CostDepartmentProfitAccount secondAccount : secondList) {
+            if (secondAccount.getAmount() == null) {
+                continue; // 跳过金额为空的记录
+            }
+
+            // 查找是否在结果列表中已有相同costType和accountType的记录
+            boolean found = false;
+            for (CostDepartmentProfitAccount resultAccount : result) {
+                if (Objects.equals(resultAccount.getCostType(), secondAccount.getCostType()) &&
+                        Objects.equals(resultAccount.getAccountType(), secondAccount.getAccountType())) {
+
+                    // 找到匹配项,进行加减运算
+                    BigDecimal firstAmount = resultAccount.getAmount() != null ? resultAccount.getAmount() : BigDecimal.ZERO;
+                    BigDecimal secondAmount = secondAccount.getAmount() != null ? secondAccount.getAmount() : BigDecimal.ZERO;
+
+                    if (operation == 1) {
+                        resultAccount.setAmount(firstAmount.add(secondAmount));
+                    } else if (operation == -1) {
+                        resultAccount.setAmount(firstAmount.subtract(secondAmount));
+                    }
+
+                    found = true;
+                    break;
+                }
+            }
+
+            // 如果未找到匹配项,则添加新记录
+            if (!found) {
+                CostDepartmentProfitAccount newAccount = new CostDepartmentProfitAccount();
+                newAccount.setCostType(secondAccount.getCostType());
+                newAccount.setAccountType(secondAccount.getAccountType());
+
+                // 加法直接添加金额,减法添加负金额
+                if (operation == 1) {
+                    newAccount.setAmount(secondAccount.getAmount() != null ? secondAccount.getAmount() : BigDecimal.ZERO);
+                } else if (operation == -1) {
+                    BigDecimal amount = secondAccount.getAmount() != null ? secondAccount.getAmount() : BigDecimal.ZERO;
+                    newAccount.setAmount(amount.negate()); // 设置为负值
+                }
+                result.add(newAccount);
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * 获取按分摊层级计算结果
+     * @param profitCalculationData
+     * @param reportForm
+     * @return
+     */
+    private void setShareLevelReportValue(CostDepartmentProfitVO costDepartmentProfitVO, ProfitCalculationDataVo profitCalculationData, Responsibility responsibility, ReportForm reportForm) {
+        List<ReportRelation> reportRelationList = profitCalculationData.getReportRelationMap().get(reportForm.getId());
+        if(CollectionUtils.isEmpty(reportRelationList)){
+            return ;
+        }
+        // 获取对应的会计科目信息  筛选会计科目的Code
+        List<String> shareLevelIdList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
+        //类型是收入时取分摊结果表单的数据计算
+        // 需要查询分摊后的表
+        List<AllocationQueryReportVO> reportVOList = profitCalculationData.getAllocationQueryReportVOList().stream().filter(m ->
+                m.getTargetResponsibilityCode().equals(responsibility.getResponsibilityCode())
+                        &&NumberConstant.TWO.equals(m.getOriginType().intValue())
+                        && shareLevelIdList.contains(m.getShareLevelId())).collect(Collectors.toList());
+        if (CollUtil.isEmpty(reportVOList)) {
+            return ;
+        }
+        List<CostDepartmentProfitAccount> costDepartmentProfitAccounts = calculateCostByTypeAndAccount(reportVOList);
+        BigDecimal totalAmount = costDepartmentProfitAccounts.stream()
+                .map(CostDepartmentProfitAccount::getAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        costDepartmentProfitVO.setAmount(totalAmount);
+        costDepartmentProfitVO.setCostDepartmentProfitAccounts(costDepartmentProfitAccounts);
+    }
+
+
+    /**
+     * 按收入会计科目计算
+     * @param costDepartmentProfitVO
+     * @param profitCalculationData
+     * @param responsibility
+     * @param reportForm
+     */
+    private void setIncomeAccountReportValue(CostDepartmentProfitVO costDepartmentProfitVO,ProfitCalculationDataVo profitCalculationData, Responsibility responsibility,ReportForm reportForm) {
+        List<ReportRelation> reportRelationList = profitCalculationData.getReportRelationMap().get(reportForm.getId());
+        if(CollectionUtils.isEmpty(reportRelationList)){
+            return ;
+        }
+        // 获取对应的会计科目信息  筛选会计科目的Code
+        List<String> accountList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
+        // 查找在归集数据里面当前责任中心对应的这些会计科目的金额
+        List<IncomeCollection> incomeCollectionList = profitCalculationData.getIncomeList().stream().filter(income ->
+                        income.getResponsibilityCode().equals(responsibility.getResponsibilityCode())
+                        && accountList.contains(income.getAccountingCode())).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(incomeCollectionList)){
+            return ;
+        }
+        BigDecimal totalAmount = incomeCollectionList.stream()
+                .map(IncomeCollection::getAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        costDepartmentProfitVO.setAmount(totalAmount);
+    }
+
+    /**
+     *获取按成本会计科目计算的结果
+     * @param profitCalculationData
+     * @param responsibility
+     * @param reportForm
+     * @return
+     */
+    private void setCostAccountReportValue(CostDepartmentProfitVO costDepartmentProfitVO, ProfitCalculationDataVo profitCalculationData, Responsibility responsibility, ReportForm reportForm) {
+        List<ReportRelation> reportRelationList = profitCalculationData.getReportRelationMap().get(reportForm.getId());
+        if(CollectionUtils.isEmpty(reportRelationList)){
+            return ;
+        }
+        // 获取对应的会计科目信息  筛选会计科目的Code
+        List<String> accountList = reportRelationList.stream().map(ReportRelation::getRelationCode).collect(Collectors.toList());
+        //类型是收入时取分摊结果表单的数据计算
+        // 需要查询分摊后的表
+        List<AllocationQueryReportVO> reportVOList = profitCalculationData.getAllocationQueryReportVOList().stream().filter(m ->
+                        m.getTargetResponsibilityCode().equals(responsibility.getResponsibilityCode())
+                        &&(NumberConstant.ZERO.equals(reportForm.getCostType())||reportForm.getCostType().equals(m.getOriginType().intValue()))
+                        &&accountList.contains(m.getAccountingCode())).collect(Collectors.toList());
+        if (CollUtil.isEmpty(reportVOList)) {
+            return ;
+        }
+        List<CostDepartmentProfitAccount> costDepartmentProfitAccounts = calculateCostByTypeAndAccount(reportVOList);
+        BigDecimal totalAmount = costDepartmentProfitAccounts.stream()
+                .map(CostDepartmentProfitAccount::getAmount)
+                .filter(Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        costDepartmentProfitVO.setAmount(totalAmount);
+        costDepartmentProfitVO.setCostDepartmentProfitAccounts(costDepartmentProfitAccounts);
+    }
+
+    /**
+     * 将分摊结果按会计科目类别+成本类别分组汇总
+     * @param reportVOList
+     * @return
+     */
+    public List<CostDepartmentProfitAccount> calculateCostByTypeAndAccount(List<AllocationQueryReportVO> reportVOList) {
+        // 按costType+accountType分组计算各组的金额amount
+        Map<String, BigDecimal> groupedAmounts = reportVOList.stream()
+                .collect(Collectors.groupingBy(
+                        vo -> vo.getCostType() + "_" + vo.getAccountType(),
+                        Collectors.reducing(
+                                BigDecimal.ZERO,
+                                AllocationQueryReportVO::getAmount,
+                                BigDecimal::add
+                        )
+                ));
+
+        // 按组生成CostDepartmentProfitAccount对象
+        return groupedAmounts.entrySet().stream()
+                .map(entry -> {
+                    String[] keys = entry.getKey().split("_", 2);
+                    CostDepartmentProfitAccount account = new CostDepartmentProfitAccount();
+                    account.setCostType(keys[0]);
+                    account.setAccountType(keys[1]);
+                    account.setAmount(entry.getValue());
+                    return account;
+                })
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 获取指定类型的报表配置
+     * @param reportType
+     * @return
+     */
+    public List<ReportForm> getReportForm(String reportType){
+        List<ReportForm> reportFormList = reportFormService.list(new QueryWrapper<ReportForm>().lambda()
+                .eq(ReportForm::getHospId,  UserContext.getHospId())
+                .eq(ReportForm::getReportType, reportType));
+        return reportFormList;
+    }
+
+    /**
+     * 获取报表关系
+     * @return
+     */
+    public List<ReportRelation> getReportRelation(){
+        List<ReportRelation> list = reportRelationService.list(new QueryWrapper<ReportRelation>().lambda().eq(ReportRelation::getHospId, UserContext.getHospId()));
+        return list;
+    }
+
+    /**
+     * 获取指定报表对应的责任中心
+     * @param reportType
+     * @return
+     */
+    public List<Responsibility> getReportResponsibilityList(String reportType){
+        DictDataVo dataVo = getDictDataVo(reportType);
+        Long id = Long.valueOf(dataVo.getExpandOne());
+        List<Responsibility> list = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
+                .eq(Responsibility::getHospId, UserContext.getHospId())
+                .eq(Responsibility::getIsGatherCenter, 2)
+                .eq(Responsibility::getDeleteTime, 0)
+                .eq(Responsibility::getShareId, id));
+        return list;
+    }
+
+
+    /**
+     * 获取分摊层级字典
+     * @return
+     */
+    public List<CostShareLevel> getCostShareLevelList(){
+        List<CostShareLevel> costShareLevelList =  costShareLevelService.list(new QueryWrapper<CostShareLevel>().lambda()
+                .eq(CostShareLevel::getHospId, UserContext.getHospId()).orderByDesc(CostShareLevel::getLeverSort));
+        return costShareLevelList;
+    }
+
+    /**
+     * 获取归集后的收入数据
+     * @param year
+     * @param month
+     * @return
+     */
+    public List<IncomeCollection> getIncomeCollectionList(Integer year, Integer month) {
+        List<IncomeCollection> list = incomeCollectionService.list(new QueryWrapper<IncomeCollection>().lambda()
+                .eq(IncomeCollection::getHospId, UserContext.getHospId())
+                .eq(year > 0, IncomeCollection::getYear, year).eq(month > 0, IncomeCollection::getMonth, month));
+        return list;
+    }
+
+
+    /**
+     * 删除指定月份的科室损益数据
+     * @param year
+     * @param month
+     * @param reportType
+     */
+    public void deleteDeptProfit(Integer year, Integer month,String reportType) {
+        // 删除这个年月的数据
+        this.remove(new QueryWrapper<CostDepartmentProfit>().lambda().eq(CostDepartmentProfit::getHospId, UserContext.getHospId())
+                .eq(CostDepartmentProfit::getYear, year).eq(CostDepartmentProfit::getMonth, month).eq(CostDepartmentProfit::getShareType, Integer.valueOf(reportType)));
+    }
+
 }

+ 30 - 6
src/main/java/com/kcim/service/impl/CostIncomeGroupServiceImpl.java

@@ -18,10 +18,7 @@ import com.kcim.common.util.*;
 import com.kcim.dao.mapper.CostIncomeGroupMapper;
 import com.kcim.dao.model.*;
 import com.kcim.service.*;
-import com.kcim.vo.CommonDepartVo;
-import com.kcim.vo.CostIncomeGroupAllAmountVO;
-import com.kcim.vo.CostIncomeGroupBeforeVO;
-import com.kcim.vo.IncomeErrorMessage;
+import com.kcim.vo.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -96,6 +93,12 @@ public class CostIncomeGroupServiceImpl extends ServiceImpl<CostIncomeGroupMappe
      */
     @Override
     public PageUtils queryList(Integer current, Integer pageSize, String dateTime, String responsibilityCode, String productCode, Long hospId, Integer type, String filter, String departmentCode) {
+//       return getDeptIncomeList(current, pageSize, dateTime, responsibilityCode, productCode, hospId, type, filter, departmentCode);
+        return getDeptProductList(current, pageSize, dateTime, departmentCode, productCode, hospId, type, filter);
+    }
+
+
+    public PageUtils getDeptIncomeList(Integer current, Integer pageSize, String dateTime, String responsibilityCode, String productCode, Long hospId, Integer type, String filter, String departmentCode) {
         // 先检验当前年月是否存在数据
         int year = 0;
         int month = 0;
@@ -107,7 +110,7 @@ public class CostIncomeGroupServiceImpl extends ServiceImpl<CostIncomeGroupMappe
         Page<CostIncomeGroup> costIncomeGroupPage = new Page<>(current, pageSize);
         Page<CostIncomeGroup> pages = new Page<>();
         if(type.equals(NumberConstant.ONE)){
-             pages = this.page(costIncomeGroupPage, new QueryWrapper<CostIncomeGroup>().lambda()
+            pages = this.page(costIncomeGroupPage, new QueryWrapper<CostIncomeGroup>().lambda()
                     .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                     .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                     .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
@@ -138,7 +141,7 @@ public class CostIncomeGroupServiceImpl extends ServiceImpl<CostIncomeGroupMappe
         }
         List<CostIncomeGroup> list = new ArrayList<>();
         if(type.equals(NumberConstant.ONE)) {
-             list = this.list(new QueryWrapper<CostIncomeGroup>().lambda()
+            list = this.list(new QueryWrapper<CostIncomeGroup>().lambda()
                     .eq(Objects.nonNull(hospId), CostIncomeGroup::getHospId, hospId)
                     .eq(!NumberConstant.ZERO.equals(year), CostIncomeGroup::getDateYear, year)
                     .eq(!NumberConstant.ZERO.equals(month), CostIncomeGroup::getDateMonth, month)
@@ -185,6 +188,27 @@ public class CostIncomeGroupServiceImpl extends ServiceImpl<CostIncomeGroupMappe
         return pageUtils;
     }
 
+
+    public PageUtils getDeptProductList(Integer current, Integer pageSize, String computeDate, String departmentCode, String productCode, Long hospId, Integer type, String filter) {
+        Integer year = ComputeDateUtils.getComputeYear(computeDate);
+        Integer month = ComputeDateUtils.getComputeMonth(computeDate);
+
+        Page<PatientInfoVo> page = new Page<>(current,pageSize);
+        List<CostIncomeGroup> orderDeptProductList;
+        //按开单科室查询
+        if(NumberConstant.ONE.equals( type)){
+            orderDeptProductList = this.baseMapper.getOrderDeptProductList(page, year, month, departmentCode, hospId, filter);
+        }else{
+            orderDeptProductList = this.baseMapper.getExecDeptProductList(page, year, month, departmentCode, hospId, filter);
+        }
+        BigDecimal totalAmount=this.baseMapper.getTotalAmount(year, month, departmentCode, hospId);
+        BigDecimal departmentAmount=this.baseMapper.getDeptTotalAmount(year, month, departmentCode, hospId);
+        PageUtils pageUtils = new PageUtils(page);
+        pageUtils.setList(orderDeptProductList);
+        pageUtils.setTotalAmount(totalAmount);
+        pageUtils.setDepartmentAmount(departmentAmount);
+        return pageUtils;
+    }
     private static AtomicReference<BigDecimal> setAmount(List<CostIncomeGroupAllAmountVO> costIncomeGroupAllAmountVoS) {
         AtomicReference<BigDecimal> totalAmount = new AtomicReference<>(new BigDecimal("0.0000"));
         costIncomeGroupAllAmountVoS.forEach(i -> {

+ 14 - 0
src/main/java/com/kcim/vo/AllocationQueryReportVO.java

@@ -67,4 +67,18 @@ public class AllocationQueryReportVO {
      * 会计科目名称集合
      */
     private List<String> accountingNames;
+
+    /**
+     * 成本类别
+     */
+    private String costType;
+    /**
+     * 会计科目类别
+     */
+    private String accountType;
+
+    /**
+     * 来源分摊层级ID
+     */
+    private Long shareLevelId;
 }

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

@@ -1,10 +1,12 @@
 package com.kcim.vo;
 
+import com.kcim.dao.model.CostDepartmentProfitAccount;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * @author 李加喜
@@ -72,4 +74,9 @@ public class CostDepartmentProfitVO {
     private Integer type;
 
     private Integer fraction;
+
+    /**
+     * 会计科目金额列表
+     */
+    private List<CostDepartmentProfitAccount> costDepartmentProfitAccounts;
 }

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

@@ -0,0 +1,27 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2024-09-19 16:29
+ **/
+@Data
+public class DynMultiLevelVo {
+
+    private String itemCode ;
+
+    private String itemName;
+
+    private BigDecimal itemValue ;
+
+    private List<ReportVo> data;
+
+    private List<DynMultiLevelVo> children;
+
+}

+ 84 - 0
src/main/java/com/kcim/vo/ProfitCalculationDataVo.java

@@ -0,0 +1,84 @@
+package com.kcim.vo;
+
+import com.kcim.dao.model.*;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 科室损益计算数据封装类
+ * 用于封装计算科室损益所需的所有数据
+ */
+@Data
+public class ProfitCalculationDataVo {
+    /**
+     * 计算日期
+     */
+    private String computeDate;
+    
+    /**
+     * 年份
+     */
+    private Integer year;
+    
+    /**
+     * 月份
+     */
+    private Integer month;
+    
+    /**
+     * 医院ID
+     */
+    private Long hospId;
+    
+    /**
+     * 报表类型
+     */
+    private String reportType;
+    
+    /**
+     * 报表配置列表
+     */
+    private List<ReportForm> reportFormList;
+    
+    /**
+     * 报表关系列表
+     */
+    private List<ReportRelation> reportRelationList;
+    
+    /**
+     * 报表关系映射(按报表ID分组)
+     */
+    private Map<Long, List<ReportRelation>> reportRelationMap;
+    
+    /**
+     * 分摊层级列表
+     */
+    private List<CostShareLevel> costShareLevelList;
+    
+    /**
+     * 责任中心列表
+     */
+    private List<Responsibility> responsibilityList;
+    
+    /**
+     * 收入归集数据列表
+     */
+    private List<IncomeCollection> incomeList;
+    
+    /**
+     * 分摊后查询数据列表
+     */
+    private List<AllocationQuery> allocationQueryList;
+    
+    /**
+     * 分摊后查询数据VO列表
+     */
+    private List<AllocationQueryReportVO> allocationQueryReportVOList;
+    
+    /**
+     * 分摊数据列表
+     */
+    private List<Allocation> allocationList;
+}

+ 78 - 0
src/main/resources/mapper/CostIncomeGroupMapper.xml

@@ -139,6 +139,84 @@
         and delete_time != 0
         and file_id = #{id}
     </select>
+    <select id="getOrderDeptProductList" resultType="com.kcim.dao.model.CostIncomeGroup">
+        SELECT
+            product_code,
+            product_name,
+            account_code,
+            account_name,
+            open_department_code,
+            open_department_name,
+            start_department_code,
+            start_department_name,
+            SUM( amount ) AS amount
+        FROM
+            cost_income_group
+        WHERE
+            hosp_id = #{hospId}
+          AND delete_time = 0
+          AND date_year = #{year}
+          AND date_month = #{month}
+          AND open_department_code = #{departmentCode}
+        <if test="filter != null and filter != ''">
+            and (product_code like concat('%',#{filter,jdbcType=VARCHAR},'%') or `product_name` like
+            concat('%',#{filter,jdbcType=VARCHAR},'%') )
+        </if>
+        GROUP BY
+            product_code,
+            start_department_code
+    </select>
+
+    <select id="getExecDeptProductList" resultType="com.kcim.dao.model.CostIncomeGroup">
+        SELECT
+        product_code,
+        product_name,
+        account_code,
+        account_name,
+        open_department_code,
+        open_department_name,
+        start_department_code,
+        start_department_name,
+        SUM( amount ) AS amount
+        FROM
+        cost_income_group
+        WHERE
+        hosp_id = #{hospId}
+        AND delete_time = 0
+        AND date_year = #{year}
+        AND date_month = #{month}
+        AND start_department_code = #{departmentCode}
+        <if test="filter != null and filter != ''">
+            and (product_code like concat('%',#{filter,jdbcType=VARCHAR},'%') or `product_name` like
+            concat('%',#{filter,jdbcType=VARCHAR},'%') )
+        </if>
+        GROUP BY
+        product_code,
+        open_department_code
+    </select>
+    <select id="getTotalAmount" resultType="java.math.BigDecimal">
+        SELECT
+        SUM( amount ) AS amount
+        FROM
+        cost_income_group
+        WHERE
+        hosp_id = #{hospId}
+        AND delete_time = 0
+        AND date_year = #{year}
+        AND date_month = #{month}
+    </select>
+    <select id="getDeptTotalAmount" resultType="java.math.BigDecimal">
+        SELECT
+        SUM( amount ) AS amount
+        FROM
+        cost_income_group
+        WHERE
+        hosp_id = #{hospId}
+        AND delete_time = 0
+        AND date_year = #{year}
+        AND date_month = #{month}
+        AND open_department_code = #{departmentCode}
+    </select>
 
 
 </mapper>