package com.kcim.service.impl;

import cn.hutool.core.util.StrUtil;
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;
import com.kcim.common.util.UserContext;
import com.kcim.dao.model.*;
import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
import com.kcim.dao.repository.*;
import com.kcim.service.*;
import com.kcim.vo.*;
import com.kcim.web.reponse.ShareParamCostResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.kcim.common.enums.DefaultComputeColumnEnum.*;
import static com.kcim.service.impl.DrugMaterialCalculateServiceImpl.getVisitNoResponsibilityMaps;

/**
 * @program: CostAccount
 * @description:
 * @author: Wang.YS
 * @create: 2024-01-15 20:40
 **/
@Service("ShareParamService")
@Slf4j
public class ShareParamServiceImpl implements ShareParamService {
    /**
     * 项目分摊参数主表
     */
    ComputeShareParamRepository repository;
    /**
     * 项目分摊参数明细表
     */
    ComputeShareParamDetailRepository detailRepository;
    /**
     * 项目导入数据
     */
    ImportPatientItemRepository importPatientItemRepository;
    /**
     * 医疗服务项目字典
     */
    ItemRepository itemRepository;

    ItemEmpMapRepository itemEmpMapRepository;

    ItemEquipmentMapRepository itemEquipmentMapRepository;

    ItemSpaceMapRepository itemSpaceMapRepository;

    StandItemEmpMapRepository standItemEmpMapRepository;

    StandItemEquipmentMapRepository standItemEquipmentMapRepository;

    StandItemSpaceMapRepository standItemSpaceMapRepository;

    ShareParamTypeMapRepository shareParamTypeMapRepository;
    ResponsibilityDepartmentRepository responsibilityDepartmentRepository;

    CenterService centerService;

    ComputeStandShareParamRepository computeStandShareParamRepository;

    ComputeStandShareParamDetailRepository computeStandShareParamDetailRepository;

    StandItemService standItemService;
    SqlService sqlService;
    ResponsibilityDepartmentService  responsibilityDepartmentService;

    public ShareParamServiceImpl(ComputeShareParamRepository repository, ComputeShareParamDetailRepository detailRepository, ImportPatientItemRepository importPatientItemRepository, ItemRepository itemRepository, ItemEmpMapRepository itemEmpMapRepository, ItemEquipmentMapRepository itemEquipmentMapRepository, ItemSpaceMapRepository itemSpaceMapRepository, ShareParamTypeMapRepository shareParamTypeMapRepository, ResponsibilityDepartmentRepository responsibilityDepartmentRepository, CenterService centerService, ComputeStandShareParamRepository computeStandShareParamRepository, ComputeStandShareParamDetailRepository computeStandShareParamDetailRepository, StandItemService standItemService,SqlService sqlService,ResponsibilityDepartmentService  responsibilityDepartmentService
    ,StandItemEmpMapRepository standItemEmpMapRepository,StandItemEquipmentMapRepository standItemEquipmentMapRepository,StandItemSpaceMapRepository standItemSpaceMapRepository) {
        this.repository = repository;
        this.detailRepository = detailRepository;
        this.importPatientItemRepository = importPatientItemRepository;
        this.itemRepository = itemRepository;
        this.standItemEmpMapRepository = standItemEmpMapRepository;
        this.standItemEquipmentMapRepository = standItemEquipmentMapRepository;
        this.standItemSpaceMapRepository = standItemSpaceMapRepository;
        this.itemEmpMapRepository = itemEmpMapRepository;
        this.itemEquipmentMapRepository = itemEquipmentMapRepository;
        this.itemSpaceMapRepository = itemSpaceMapRepository;
        this.shareParamTypeMapRepository = shareParamTypeMapRepository;
        this.responsibilityDepartmentRepository = responsibilityDepartmentRepository;
        this.centerService = centerService;
        this.computeStandShareParamRepository = computeStandShareParamRepository;
        this.computeStandShareParamDetailRepository = computeStandShareParamDetailRepository;
        this.standItemService = standItemService;
        this.sqlService=sqlService;
        this.responsibilityDepartmentService=responsibilityDepartmentService;
    }

    /**
     * 获取项目分摊参数
     *
     * @param current        当前页
     * @param pageSize       页容量
     * @param computeDate    核算年月
     * @param itemType       项目类型
     * @param responsibility 责任中心
     * @param itemFilter     项目过滤条件
     * @return 分页数据
     */
    @Override
    public Object getShareParamCostList(Integer current, Integer pageSize, String computeDate, String itemType, String responsibility, String itemFilter) {

        Page<ComputeShareParam> page = repository.getPage(current, pageSize, computeDate, itemType, responsibility, itemFilter);
        List<ComputeShareParam> records = page.getRecords();
        ShareParamCostResponse response = new ShareParamCostResponse();
        List<CommonTitleVo> titleVos = getCommonTitleVos();
        response.setTitle(titleVos);
        if (CollectionUtils.isEmpty(records)) {
            response.setPageData(new PageUtils(new ArrayList<>(), NumberConstant.ZERO, pageSize, current));
            return response;
        }
        List<Integer> collect1 = records.stream().map(ComputeShareParam::getId).collect(Collectors.toList());
        List<ComputeDateShareParamVo> shareParamDetails = detailRepository.getByShareParamId(computeDate, collect1);
        Map<String, String> typeNameMap = getTypeNameDict();
        shareParamDetails.forEach(record -> record.setItemTypeName(typeNameMap.get(record.getItemType())));
        Map<String, List<ComputeDateShareParamVo>> collect = shareParamDetails.stream().collect(Collectors.groupingBy(ComputeDateShareParamVo::getCode));
        List<List<ReportVo>> returnList = new ArrayList<>();
        //按报表头组装值
        for (ComputeShareParam itemCode : records) {
            setResultData(titleVos, collect, returnList, itemCode.getCode());
        }
        PageUtils pageUtils = new PageUtils(returnList, Math.toIntExact(page.getTotal()), pageSize, current);
        response.setPageData(pageUtils);
        return response;
    }

    /**
     * 完全法项目分摊参数计算
     * @param computeDate
     */
    @Override
    public void computeShareParamCost(String computeDate){
        String parameterValue = centerService.getParameterValueByIndex(ParameterConstant.ITEM_CALC_TYPE,NumberConstant.ZERO);
        //走系统计算逻辑
        if(StringUtils.isEmpty(parameterValue)|| NumberConstant.ONE_S.equals(parameterValue)||NumberConstant.THREE_S.equals(parameterValue)) {
            //根据参数判断是否走新的计算流程
            if (NumberConstant.ONE_S.equals(centerService.getParameterValue(ParameterConstant.USER_HOSP_ITEM_CALC))) {
                //完全法项目分摊参数计算
                calcShareParamCost(computeDate);
            } else {
                computeShareParamCostAction(computeDate);
            }
        }
        //走自定义SQL计算逻辑
        if(NumberConstant.TWO_S.equals(parameterValue)||NumberConstant.THREE_S.equals(parameterValue)) {
            //执行完全法项目分摊参数计算后续处理脚本
            execShareParamCostSQL(computeDate);
        }
    }

    /**
     * 项目分摊参数计算
     *
     * @param computeDate 核算年月
     */
    public void computeShareParamCostAction(String computeDate) {
        SessionUserVO currentUser = UserContext.getCurrentUser();
        //获取收费项目数据（项目）
        checkItemCount(computeDate, currentUser);
        //作废上次计算记录
        repository.removeByComputeDate(computeDate, currentUser);
        detailRepository.removeByComputeDate(computeDate, currentUser);
        //获到科室与责任中心对照
        List<VisitNoResponsibilityMap> patientResponsibility = getPatientResponsibility(currentUser);
        Map<String, String> responsibilityCodeMap = new HashMap<>();
        Map<String, String> responsibilityNameMap = new HashMap<>();

        patientResponsibility.forEach(visitNoResponsibilityMap -> {
            responsibilityCodeMap.put(visitNoResponsibilityMap.getDepartmentCode(), visitNoResponsibilityMap.getResponsibilityCode());
            responsibilityNameMap.put(visitNoResponsibilityMap.getDepartmentCode(), visitNoResponsibilityMap.getResponsibilityName());
        });
        //医疗服务项目字典
        Map<String, Map<String, Item>> itemMap = getItemMap();
        //获取计算列
        List<ShareParamTypeMap> shareParamType = shareParamTypeMapRepository.getList();
        //主表公共对象
        ComputeShareParam computeShareCost = new ComputeShareParam();
        computeShareCost.setComputeDate(computeDate);
        computeShareCost.setHospId(currentUser.getHospId());
        computeShareCost.setCreateUser(String.valueOf(currentUser.getId()));
        computeShareCost.setCreateTime(new Date());
        //明细表公共对象
        ComputeShareParamDetail costDetail = new ComputeShareParamDetail();
        costDetail.setComputeDate(computeDate);
        costDetail.setHospId(currentUser.getHospId());
        costDetail.setCreateUser(String.valueOf(currentUser.getId()));
        costDetail.setCreateTime(new Date());
//        long count = (itemSize + LIMIT - 1) / LIMIT;
//        for (int j = 0; j < count; j++) {





        List<PatientItemDepartmentGroupVo> items = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
        List<ComputeShareParamDetail> saveDetails = new ArrayList<>();
        List<ComputeShareParam> saveCost = new ArrayList<>();
        if (!CollectionUtils.isEmpty(items)) {
            for (int i = 0; i < items.size(); i++) {
                PatientItemDepartmentGroupVo item = items.get(i);
                ComputeShareParam itemCost = BeanUtil.convertObj(computeShareCost, ComputeShareParam.class);
                itemCost.setCode(item.getItemCode());
                itemCost.setName(item.getItemName());
                itemCost.setNum(item.getNum());
                Map<String, Item> departmentItem = itemMap.get(item.getExecuteDepartmentCode());
                if (CollectionUtils.isEmpty(departmentItem)) {
                    continue;
                }
                Item itemData = departmentItem.get(item.getItemCode());
                if (Objects.isNull(itemData)) {
                    continue;
                }
                itemCost.setItemType(itemData.getItemType());
                itemCost.setResponsibilityCode(responsibilityCodeMap.get(item.getExecuteDepartmentCode()));
                itemCost.setResponsibilityName(responsibilityNameMap.get(item.getExecuteDepartmentCode()));
                itemCost.setIndex(i);
                saveCost.add(itemCost);
                costDetail.setIndex(i);
                saveDetails.addAll(setDetails(costDetail, item, shareParamType, itemMap));
            }
            if (!CollectionUtils.isEmpty(saveCost)) {
                //作废当前核算年月已有数据
                repository.saveBatch(saveCost, 500);
                if (!CollectionUtils.isEmpty(saveDetails)) {
                    Map<Integer, Integer> indexId = saveCost.stream().collect(Collectors.toMap(ComputeShareParam::getIndex, ComputeShareParam::getId, (a, b) -> b));
                    Map<Integer, List<ComputeShareParamDetail>> collect = saveDetails.stream().collect(Collectors.groupingBy(ComputeShareParamDetail::getIndex));
                    List<ComputeShareParamDetail> saveCostDetails = new ArrayList<>();
                    collect.forEach((k, v) -> {
                        v.forEach(detail -> detail.setShareParamId(indexId.get(k)));
                        saveCostDetails.addAll(v);
                    });
                    detailRepository.saveBatch(saveCostDetails, 500);
                }
            }
        }
    }

    /**
     * 项目分摊参数计算
     * @param computeDate
     */
    public void calcShareParamCost(String computeDate){
        SessionUserVO currentUser = UserContext.getCurrentUser();
        //获取收费项目数据（项目）
        checkItemCount(computeDate, currentUser);
        //作废上次计算记录
        repository.removeByComputeDate(computeDate, currentUser);
        detailRepository.removeByComputeDate(computeDate, currentUser);
        //医疗服务项目字典
        List<Item> itemList = itemRepository.getList();
        if (CollectionUtils.isEmpty(itemList)) {
            throw new CostException("医疗服务项目未维护，请先添加医疗服务项目再进行计算，当前计算中止");
        }
        //医疗服务项目的参与人员信息
        List<ItemEmpMap> itemEmpMaps = itemEmpMapRepository.getList();
        //医疗服务项目的使用设备信息
        List<ItemEquipmentMap> itemEquipmentMaps = itemEquipmentMapRepository.getList();
        //医疗服务项目的使用空间信息
        List<ItemSpaceMap> itemSpaceMaps = itemSpaceMapRepository.getList();
        //标准项目字典人员对照
        List<StandItemEmpMap> standItemEmpMaps = standItemEmpMapRepository.getList();
        //标准项目字典设备对照
        List<StandItemEquipmentMap> standItemEquipmentMaps = standItemEquipmentMapRepository.getList();
        //标准项目字典空间对照
        List<StandItemSpaceMap> standItemSpaceMaps = standItemSpaceMapRepository.getList();

        //科室责任中心对照信息
        List<ResponsibilityDepartIdVO> responsibilityDeptMaps = responsibilityDepartmentService.getResponsibilityDepart();
        //分摊参数设置信息
        List<ShareParamTypeMap> shareParamTypeMaps = shareParamTypeMapRepository.getList();
        //医疗服务项目分类字典
        DictDataVo itemTypeDict = centerService.getDict(Constant.MED_SERVICE_ITEM_TYPE);
        //月度患者收费项目信息(按执行科室+收费项目代码汇总过)
        List<PatientItemDepartmentGroupVo> ptChargeItems = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
        if (CollectionUtils.isEmpty(ptChargeItems)){
            throw new CostException("没有可计算的收费项目");
        }
//        //筛选出字典维护了的项目
//        List<PatientItemDepartmentGroupVo> activePtChargeItems = ptChargeItems.stream().filter(ptItem -> {
//            //科室项目字典维护了的数据
//            if (itemList.stream().anyMatch(item -> item.getCode().equals(ptItem.getItemCode()) && item.getDepartmentCode().equals(ptItem.getExecuteDepartmentCode()))) {
//                return true;
//            }
//            //全院项目字典维护了的数据
//            if (itemList.stream().anyMatch(item -> item.getCode().equals(ptItem.getItemCode()) && item.getDepartmentCode().equals(NumberConstant.ZERO))) {
//                return true;
//            }
//            return false;
//        }).collect(Collectors.toList());
//        if (CollectionUtils.isEmpty(activePtChargeItems)){
//            throw new CostException("所有收费项目都没有对应的字典数据，请联系管理员");
//        }
        //绑定收费项目对应的医疗服务型项目字典对象
        ptChargeItems.stream().forEach(ptItem->{
            Item item = getDicItem(ptItem,itemList);
            ptItem.setDicItem(item);
        });
        List<ComputeShareParam> computeShareParamList = new ArrayList();
        List<ComputeShareParamDetail> ComputeShareParamDetailList = new ArrayList();
        ptChargeItems.stream().forEach(ptItem->{
            //只处理字典有项目
            if(!Objects.isNull(ptItem.getDicItem())) {
                //根据收费项目创建分摊参数主表对象
                ComputeShareParam computeShareCost = creatComputeShareParam(currentUser, computeDate, ptItem, itemTypeDict, responsibilityDeptMaps);
                computeShareParamList.add(computeShareCost);
                //创建分摊参数主表对象对应的明细对象
                shareParamTypeMaps.stream().forEach(shareParamType -> {
                    ComputeShareParamDetail computeShareParamDetail = createComputeShareParamDetail(currentUser, computeDate, ptItem, computeShareCost, shareParamType, itemEmpMaps, itemEquipmentMaps, itemSpaceMaps,standItemEmpMaps, standItemEquipmentMaps, standItemSpaceMaps);
                    ComputeShareParamDetailList.add(computeShareParamDetail);
                });
            }
        });
        //没有任何可保存的数据
        if (CollectionUtils.isEmpty(computeShareParamList)) {
            throw new CostException("没有任何可保存的数据");
        }
        //保存分摊参数主表对象数据
        repository.saveBatch(computeShareParamList, 500);
        if (CollectionUtils.isEmpty(ComputeShareParamDetailList)) {
            return;
        }
        //保存分摊参数明细表对象数据
        ComputeShareParamDetailList.stream().forEach(shareParamDetailL->shareParamDetailL.setShareParamId(shareParamDetailL.getComputeShareCost().getId()));
        detailRepository.saveBatch(ComputeShareParamDetailList, 500);
    }

    /**
     * 获取收费项目对应的医疗服务项目字典对象
     * @param ptItem
     * @param itemList
     * @return
     */
    public Item getDicItem(PatientItemDepartmentGroupVo ptItem,List<Item> itemList){
        //优先取科室项目字典的记录
        Optional<Item> first = itemList.stream().filter(dicItem -> dicItem.getCode().equals(ptItem.getItemCode()) && dicItem.getDepartmentCode().equals(ptItem.getExecuteDepartmentCode())).findFirst();
        if(first.isPresent()) {
            return first.get();
        }
        //取全院通用的字典记录
        first = itemList.stream().filter(dicItem -> dicItem.getCode().equals(ptItem.getItemCode()) && dicItem.getDepartmentCode().equals(NumberConstant.ZERO)).findFirst();
        if(first.isPresent()) {
            return first.get();
        }
        return null;
    }

    /**
     * 根据收费项目创建分摊参数主表对象
     * @param currentUser
     * @param computeDate
     * @param itemTypeDict
     * @param ptItem
     * @param responsibilityDeptMaps
     * @return
     */
    public ComputeShareParam creatComputeShareParam(SessionUserVO currentUser,String computeDate,PatientItemDepartmentGroupVo ptItem,DictDataVo itemTypeDict, List<ResponsibilityDepartIdVO> responsibilityDeptMaps){
        ComputeShareParam computeShareCost = new ComputeShareParam();
        computeShareCost.setComputeDate(computeDate);
        computeShareCost.setHospId(currentUser.getHospId());
        computeShareCost.setCreateUser(String.valueOf(currentUser.getId()));
        computeShareCost.setCreateTime(new Date());
        computeShareCost.setCode(ptItem.getItemCode());
        computeShareCost.setName(ptItem.getItemName());
        computeShareCost.setNum(ptItem.getNum());
        //获取执行科室对应的责任中心
        Optional<ResponsibilityDepartIdVO> firstResponsibilityDepartIdVO = responsibilityDeptMaps.stream().filter(respDeptmap -> !Objects.isNull(respDeptmap.getDepartmentCode())&& respDeptmap.getDepartmentCode().equals(ptItem.getExecuteDepartmentCode())).findFirst();
        if(!firstResponsibilityDepartIdVO.isPresent()){
            String errMsg = String.format("【%s(%s)】没有对应的责任中心，计算中止", ptItem.getExecuteDepartmentName(), ptItem.getExecuteDepartmentCode());
            throw new CostException(errMsg);
        }
        ResponsibilityDepartIdVO responsibilityDepartIdVO=firstResponsibilityDepartIdVO.get();
        computeShareCost.setResponsibilityCode(responsibilityDepartIdVO.getResponsibilityCode());
        computeShareCost.setResponsibilityName(responsibilityDepartIdVO.getResponsibilityName());
//        computeShareCost.setItemType(getChargeItemType(itemTypeDict,responsibilityDepartIdVO.getShareId()));
        computeShareCost.setItemType(ptItem.getDicItem().getItemType());
        return computeShareCost;

    }

    /**
     * 根据收费项目创建分摊参数明细表对象
     * @param currentUser
     * @param computeDate
     * @param ptItem
     * @param computeShareCost
     * @param shareParamType
     * @param itemEmpMaps
     * @param itemEquipmentMaps
     * @param itemSpaceMaps
     * @return
     */
    public  ComputeShareParamDetail createComputeShareParamDetail( SessionUserVO currentUser,String computeDate,PatientItemDepartmentGroupVo ptItem,ComputeShareParam computeShareCost,ShareParamTypeMap shareParamType,
                                                                   List<ItemEmpMap> itemEmpMaps,List<ItemEquipmentMap> itemEquipmentMaps ,List<ItemSpaceMap> itemSpaceMaps,
                                                                   List<StandItemEmpMap> standItemEmpMaps,List<StandItemEquipmentMap> standItemEquipmentMaps ,List<StandItemSpaceMap> standItemSpaceMaps){
        //明细表公共对象
        ComputeShareParamDetail costDetail = new ComputeShareParamDetail();
        costDetail.setComputeDate(computeDate);
        costDetail.setHospId(currentUser.getHospId());
        costDetail.setCreateUser(String.valueOf(currentUser.getId()));
        costDetail.setCreateTime(new Date());
        costDetail.setShareParamCode(shareParamType.getShareParamCode());
        if(shareParamType.getSourceType().equals(NumberConstant.ONE_S)){
            //计算参与人员的参数值
            BigDecimal computeSingleResult = calcEmpParamValue(shareParamType, ptItem, itemEmpMaps);
            costDetail.setComputeSingleResult(computeSingleResult);
            costDetail.setComputeResult(computeSingleResult.multiply(ptItem.getNum()));
            //计算标准法参与人员的参数值
            BigDecimal standComputeSingleResult = calcStandEmpParamValue(shareParamType, ptItem, standItemEmpMaps);
            costDetail.setStandComputeSingleResult(standComputeSingleResult);
            costDetail.setStandComputeResult(standComputeSingleResult.multiply(ptItem.getNum()));
        }else if(shareParamType.getSourceType().equals(NumberConstant.TWO_S)){
            //计算使用设备的参数值
            BigDecimal computeSingleResult = calcEquipmentParamValue(shareParamType, ptItem, itemEquipmentMaps);
            costDetail.setComputeSingleResult(computeSingleResult);
            costDetail.setComputeResult(computeSingleResult.multiply(ptItem.getNum()));
            //计算标准法使用设备的参数值
            BigDecimal standComputeSingleResult =  calcStandEquipmentParamValue(shareParamType, ptItem, standItemEquipmentMaps);
            costDetail.setStandComputeSingleResult(standComputeSingleResult);
            costDetail.setStandComputeResult(standComputeSingleResult.multiply(ptItem.getNum()));
        }else if(shareParamType.getSourceType().equals(NumberConstant.THREE_S)){
            //计算使用空间的参数值
            BigDecimal computeSingleResult = calcSpaceParamValue(shareParamType, ptItem, itemSpaceMaps);
            costDetail.setComputeSingleResult(computeSingleResult);
            costDetail.setComputeResult(computeSingleResult.multiply(ptItem.getNum()));
            //计算标准法使用空间的参数值
            BigDecimal standComputeSingleResult = calcStandSpaceParamValue(shareParamType, ptItem,standItemSpaceMaps);
            costDetail.setStandComputeSingleResult(standComputeSingleResult);
            costDetail.setStandComputeResult(standComputeSingleResult.multiply(ptItem.getNum()));
        }else if(shareParamType.getSourceType().equals(NumberConstant.FOUR_S)){
            //计算项目收入的参数值
            BigDecimal computeResult = ptItem.getAmount();
            if (!ptItem.getNum().equals(BigDecimal.ZERO.setScale(NumberConstant.TWO, RoundingMode.HALF_UP))) {
                costDetail.setComputeSingleResult(computeResult.divide(ptItem.getNum(), NumberConstant.FOUR, RoundingMode.HALF_UP));
                costDetail.setStandComputeSingleResult(computeResult.divide(ptItem.getNum(), NumberConstant.FOUR, RoundingMode.HALF_UP));
            } else {
                costDetail.setComputeSingleResult(BigDecimal.ZERO.setScale(NumberConstant.FOUR, RoundingMode.HALF_UP));
                costDetail.setStandComputeSingleResult(BigDecimal.ZERO.setScale(NumberConstant.FOUR, RoundingMode.HALF_UP));
            }
            costDetail.setComputeResult(computeResult);
            costDetail.setStandComputeResult(computeResult);
        }else if(shareParamType.getSourceType().equals(NumberConstant.FIVE_S)){
            //计算项目数量的参数值
            BigDecimal computeResult = ptItem.getNum();
            costDetail.setComputeSingleResult(BigDecimal.ONE.setScale(NumberConstant.FOUR, RoundingMode.HALF_UP));
            costDetail.setComputeResult(computeResult);
            //计算标准法项目数量的参数值
            costDetail.setStandComputeSingleResult(BigDecimal.ONE.setScale(NumberConstant.FOUR, RoundingMode.HALF_UP));
            costDetail.setStandComputeResult(computeResult);
        }
        costDetail.setComputeShareCost(computeShareCost);
        return costDetail;
    }

    /**
     * 计算参与人员的参数值
     * @param ptItem
     * @param itemEmpMaps
     * @return
     */
    public BigDecimal calcEmpParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<ItemEmpMap> itemEmpMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(itemEmpMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的参与人员配置
        List<ItemEmpMap> itemEmpList = itemEmpMaps.stream().filter(itemEmp -> itemEmp.getItemCode().equals(ptItem.getDicItem().getCode()) && itemEmp.getDepartmentCode().equals(ptItem.getDicItem().getDepartmentCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemEmpList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemEmpList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<ItemEmpMap> activeItemEmpList = itemEmpList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getEmpTypeCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemEmpList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemEmpList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }

    /**
     * 计算标准项目参与人员的参数值
     * @param ptItem
     * @param standItemEmpMaps
     * @return
     */
    public BigDecimal calcStandEmpParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<StandItemEmpMap> standItemEmpMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(standItemEmpMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的标准项目的参与人员配置
        List<StandItemEmpMap> itemEmpList = standItemEmpMaps.stream().filter(itemEmp ->!ObjectUtils.isEmpty(ptItem.getDicItem())&& ptItem.getDicItem().getStandItemCode().equals(itemEmp.getStandItemCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemEmpList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemEmpList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<StandItemEmpMap> activeItemEmpList = itemEmpList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getEmpTypeCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemEmpList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemEmpList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }


    /**
     * 计算使用设备参数值
     * @param shareParamType
     * @param ptItem
     * @param itemEquipmentMaps
     * @return
     */
    public BigDecimal calcEquipmentParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<ItemEquipmentMap> itemEquipmentMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(itemEquipmentMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的使用设备配置
        List<ItemEquipmentMap> itemEquipmentList = itemEquipmentMaps.stream().filter(itemEmp -> itemEmp.getItemCode().equals(ptItem.getDicItem().getCode()) && itemEmp.getDepartmentCode().equals(ptItem.getDicItem().getDepartmentCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemEquipmentList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemEquipmentList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<ItemEquipmentMap> activeItemEquipmentList = itemEquipmentList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getEquipmentCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemEquipmentList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemEquipmentList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }

    /**
     * 计算标准项目使用设备参数值
     * @param shareParamType
     * @param ptItem
     * @param standItemEquipmentMaps
     * @return
     */
    public BigDecimal calcStandEquipmentParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<StandItemEquipmentMap> standItemEquipmentMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(standItemEquipmentMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的标准项目的使用设备配置
        List<StandItemEquipmentMap> itemEquipmentList = standItemEquipmentMaps.stream().filter(itemEmp ->!ObjectUtils.isEmpty(ptItem.getDicItem())&& itemEmp.getStandItemCode().equals(ptItem.getDicItem().getStandItemCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemEquipmentList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemEquipmentList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<StandItemEquipmentMap> activeItemEquipmentList = itemEquipmentList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getEquipmentCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemEquipmentList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemEquipmentList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }

    /**
     * 计算使用空间参数值
     * @param shareParamType
     * @param ptItem
     * @param itemSpaceMaps
     * @return
     */
    public BigDecimal calcSpaceParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<ItemSpaceMap> itemSpaceMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(itemSpaceMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的使用空间配置
        List<ItemSpaceMap> itemSpaceList = itemSpaceMaps.stream().filter(itemEmp -> itemEmp.getItemCode().equals(ptItem.getDicItem().getCode()) && itemEmp.getDepartmentCode().equals(ptItem.getDicItem().getDepartmentCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemSpaceList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemSpaceList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<ItemSpaceMap> activeItemSpaceList = itemSpaceList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getSpaceCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemSpaceList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemSpaceList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }

    /**
     * 计算标准项目使用空间参数值
     * @param shareParamType
     * @param ptItem
     * @param standItemSpaceMaps
     * @return
     */
    public BigDecimal calcStandSpaceParamValue(ShareParamTypeMap shareParamType,PatientItemDepartmentGroupVo ptItem,List<StandItemSpaceMap> standItemSpaceMaps){
        //没有人员配置
        if(CollectionUtils.isEmpty(standItemSpaceMaps)){
            return  BigDecimal.ZERO;
        }
        String sourceCode = shareParamType.getSourceCode();
        //没有维护对应的来源代码
        if(Objects.isNull(sourceCode)||sourceCode.equals(Constant.EMPTY_STR)){
            return  BigDecimal.ZERO;
        }
        //获取项目对应的使用空间配置
        List<StandItemSpaceMap> itemSpaceList = standItemSpaceMaps.stream().filter(itemEmp ->!ObjectUtils.isEmpty(ptItem.getDicItem())&&itemEmp.getStandItemCode().equals(ptItem.getDicItem().getStandItemCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(itemSpaceList)){
            return  BigDecimal.ZERO;
        }
        BigDecimal paramValue=BigDecimal.ZERO;
        //全部项目
        if(sourceCode.equals(NumberConstant.ZERO_S)){
            paramValue = itemSpaceList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
            return paramValue;
        }
        //不是全部的项目时，有可能会是多个
        List<String> sourceCodeList = StrUtil.split(sourceCode, "|");
        //获取符合条件的项目
        List<StandItemSpaceMap> activeItemSpaceList = itemSpaceList.stream().filter(itemEmp -> sourceCodeList.contains(itemEmp.getSpaceCode())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(activeItemSpaceList)){
            return paramValue;
        }
        //只统计符合条件的项目
        paramValue = activeItemSpaceList.stream().map(itemEmp -> itemEmp.getExecuteTime().multiply(itemEmp.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add);
        return  paramValue;
    }

    /**
     * 根据责任中心获取医疗服务项目分类
     * @param dict
     * @param shareLevelId
     * @return
     */
    public String getChargeItemType(DictDataVo dict,Long shareLevelId){
        List<DictDataVo> dataVoList= dict.getDataVoList();
        if(CollectionUtils.isEmpty(dataVoList)){
            return NumberConstant.ONE_S;
        }
        DictDataVo dictDataVo = dataVoList.stream().filter(dataVo -> dataVo.getValue().equals(shareLevelId.toString())).findFirst().get();
        return  NumberConstant.ONE_S;
    }


    /**
     * 执行完全法项目分摊参数计算后续处理脚本
     * @param computeDate
     */
    public void execShareParamCostSQL(String computeDate){
        Map<String,String> sqlParameter = new HashMap<>();
        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
        sqlService.autoExecuteSql(CustomSqlTypeEnum.FULL_PROJECT_PARAM_CALC.getCode(),sqlParameter);
    }






    /**
     * 获取标准项目分摊参数
     *
     * @param current        当前页
     * @param pageSize       页容量
     * @param computeDate    核算年月
     * @param itemType       项目类型
     * @param responsibility 责任中心
     * @param itemFilter     项目过滤条件
     * @return 分页数据
     */
    @Override
    public Object getStandShareParamCostList(Integer current, Integer pageSize, String computeDate, String itemType, String responsibility, String itemFilter) {
        Page<ComputeStandShareParam> page = computeStandShareParamRepository.getPage(current, pageSize, computeDate, itemType, responsibility, itemFilter);
        List<ComputeStandShareParam> records = page.getRecords();
        ShareParamCostResponse response = new ShareParamCostResponse();
        List<CommonTitleVo> titleVos = getCommonTitleVos();
        response.setTitle(titleVos);
        if (CollectionUtils.isEmpty(records)) {
            response.setPageData(new PageUtils(new ArrayList<>(), NumberConstant.ZERO, pageSize, current));
            return response;
        }
        List<Integer> collect1 = records.stream().map(ComputeStandShareParam::getId).collect(Collectors.toList());
        List<ComputeDateShareParamVo> shareParamDetails = computeStandShareParamDetailRepository.getByShareParamId(computeDate, collect1);
        Map<String, String> typeNameMap = getTypeNameDict();
        shareParamDetails.forEach(record -> record.setItemTypeName(typeNameMap.get(record.getItemType())));
        List<List<ReportVo>> returnList = new ArrayList<>();
        //按报表头组装值
        Map<String, List<ComputeDateShareParamVo>> collect = shareParamDetails.stream().collect(Collectors.groupingBy(ComputeDateShareParamVo::getCode));
        for (ComputeStandShareParam itemCode : records) {
            setResultData(titleVos, collect, returnList, itemCode.getCode());
        }
        PageUtils pageUtils = new PageUtils(returnList, Math.toIntExact(page.getTotal()), pageSize, current);
        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));
    }

    private @NotNull List<CommonTitleVo> getCommonTitleVos() {
        List<CommonTitleVo> titleVos = new ArrayList<>();
        titleVos.add(new CommonTitleVo(RESPONSIBILITY_CODE.getCode(), RESPONSIBILITY_CODE.getName()));
        titleVos.add(new CommonTitleVo(RESPONSIBILITY_NAME.getCode(), RESPONSIBILITY_NAME.getName()));
        titleVos.add(new CommonTitleVo(ITEM_CODE.getCode(), ITEM_CODE.getName()));
        titleVos.add(new CommonTitleVo(ITEM_NAME.getCode(), ITEM_NAME.getName()));
        titleVos.add(new CommonTitleVo(ITEM_TYPE.getCode(), ITEM_TYPE.getName()));
        List<ShareParamTypeMap> shareParamType = shareParamTypeMapRepository.getList();
        for (ShareParamTypeMap shareParamTypeMap : shareParamType) {
            titleVos.add(getTitle(shareParamTypeMap.getShareParamCode(), shareParamTypeMap.getShareParamName()));
        }
        return titleVos;
    }

    private void setResultData(List<CommonTitleVo> titleVos, Map<String, List<ComputeDateShareParamVo>> collect, List<List<ReportVo>> returnList, String code) {
        List<ComputeDateShareParamVo> computeDateShareParamVos = collect.get(code);
        Map<String, BigDecimal> computeResultMap = computeDateShareParamVos.stream().collect(Collectors.toMap(ComputeDateShareParamVo::getShareParamCode, ComputeDateShareParamVo::getComputeResult, (a, b) -> b));
        List<ReportVo> dataList = new ArrayList<>();
        for (CommonTitleVo titleVo : titleVos) {
            if (titleVo.getCode().equals(RESPONSIBILITY_CODE.getCode())) {
                dataList.add(getData(titleVo.getCode(), computeDateShareParamVos.get(0).getResponsibilityCode()));
            } else if (titleVo.getCode().equals(RESPONSIBILITY_NAME.getCode())) {
                dataList.add(getData(titleVo.getCode(), computeDateShareParamVos.get(0).getResponsibilityName()));
            } else if (titleVo.getCode().equals(ITEM_CODE.getCode())) {
                dataList.add(getData(titleVo.getCode(), code));
            } else if (titleVo.getCode().equals(ITEM_NAME.getCode())) {
                dataList.add(getData(titleVo.getCode(), computeDateShareParamVos.get(0).getName()));
            } else if (titleVo.getCode().equals(ITEM_TYPE.getCode())) {
                dataList.add(getData(titleVo.getCode(), computeDateShareParamVos.get(0).getItemTypeName()));
            } else {
                dataList.add(getData(titleVo.getCode(), computeResultMap.get(titleVo.getCode())));
            }
        }
        returnList.add(dataList);
    }

    /**
     * 标准法项目分摊参数计算
     * @param computeDate
     */
    @Override
    public void computeStandShareParamCost(String computeDate){
        String parameterValue = centerService.getParameterValueByIndex(ParameterConstant.ITEM_CALC_TYPE,NumberConstant.TWO);
        //走系统计算逻辑
        if(StringUtils.isEmpty(parameterValue)|| NumberConstant.ONE_S.equals(parameterValue)||NumberConstant.THREE_S.equals(parameterValue)) {
            //标准法项目分摊参数计算
            computeStandShareParamCostAction(computeDate);
        }
        //走自定义SQL计算逻辑
        if(NumberConstant.TWO_S.equals(parameterValue)||NumberConstant.THREE_S.equals(parameterValue)) {
            //执行标准法项目分摊参数计算后续处理脚本
            execStandShareParamCostSQL(computeDate);
        }
    }

    /**
     * 计算标准项目分摊参数
     *
     * @param computeDate 核算年月
     */
    public void computeStandShareParamCostAction(String computeDate) {
        SessionUserVO currentUser = UserContext.getCurrentUser();
        //把当月需要计算数据置成0
//        importPatientItemRepository.updateGroupCalculateFlag(computeDate, currentUser);

        //获取收费项目数据（项目）
        checkItemCount(computeDate, currentUser);
        //获取计算列
        List<ShareParamTypeMap> shareParamType = shareParamTypeMapRepository.getList();
        if (CollectionUtils.isEmpty(shareParamType)) {
            throw new CostException("分摊参数来源项目未对照【com_share_param_type_map】表无数据");
        }
        //作废上次计算记录
        computeStandShareParamRepository.removeByComputeDate(computeDate, currentUser);
        computeStandShareParamDetailRepository.removeByComputeDate(computeDate, currentUser);
        //获到科室与责任中心对照
        List<VisitNoResponsibilityMap> patientResponsibility = getPatientResponsibility(currentUser);
        Map<String, String> responsibilityCodeMap = new HashMap<>();
        Map<String, String> responsibilityNameMap = new HashMap<>();

        patientResponsibility.forEach(visitNoResponsibilityMap -> {
            responsibilityCodeMap.put(visitNoResponsibilityMap.getDepartmentCode(), visitNoResponsibilityMap.getResponsibilityCode());
            responsibilityNameMap.put(visitNoResponsibilityMap.getDepartmentCode(), visitNoResponsibilityMap.getResponsibilityName());
        });
        //医疗服务项目字典
        Map<String, Map<String, Item>> itemMap = getStandItemMap();

        //主表公共对象
        ComputeStandShareParam computeShareCost = new ComputeStandShareParam();
        computeShareCost.setComputeDate(computeDate);
        computeShareCost.setHospId(currentUser.getHospId());
        computeShareCost.setCreateUser(String.valueOf(currentUser.getId()));
        computeShareCost.setCreateTime(new Date());
        //明细表公共对象
        ComputeStandShareParamDetail costDetail = new ComputeStandShareParamDetail();
        costDetail.setComputeDate(computeDate);
        costDetail.setHospId(currentUser.getHospId());
        costDetail.setCreateUser(String.valueOf(currentUser.getId()));
        costDetail.setCreateTime(new Date());
        List<PatientItemDepartmentGroupVo> items = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
        List<ComputeStandShareParamDetail> saveDetails = new ArrayList<>();
        List<ComputeStandShareParam> saveCost = new ArrayList<>();
        if (!CollectionUtils.isEmpty(items)) {
            for (int i = 0; i < items.size(); i++) {
                PatientItemDepartmentGroupVo item = items.get(i);
                ComputeStandShareParam itemCost = BeanUtil.convertObj(computeShareCost, ComputeStandShareParam.class);
                itemCost.setCode(item.getItemCode());
                itemCost.setName(item.getItemName());
                itemCost.setNum(item.getNum());
                Map<String, Item> departmentItem = itemMap.get(item.getExecuteDepartmentCode());
                if (CollectionUtils.isEmpty(departmentItem)) {
                    continue;
                }
                Item itemData = departmentItem.get(item.getItemCode());
                if (Objects.isNull(itemData)) {
                    continue;
                }
                itemCost.setItemType(itemData.getItemType());
                itemCost.setResponsibilityCode(responsibilityCodeMap.get(item.getExecuteDepartmentCode()));
                itemCost.setResponsibilityName(responsibilityNameMap.get(item.getExecuteDepartmentCode()));
                itemCost.setIndex(i);
                saveCost.add(itemCost);
                costDetail.setIndex(i);
                saveDetails.addAll(setStandDetails(costDetail, item, shareParamType, itemMap));
            }
            if (!CollectionUtils.isEmpty(saveCost)) {
                //作废当前核算年月已有数据
                computeStandShareParamRepository.saveBatch(saveCost, 500);
                if (!CollectionUtils.isEmpty(saveDetails)) {
                    Map<Integer, Integer> indexId = saveCost.stream().collect(Collectors.toMap(ComputeStandShareParam::getIndex, ComputeStandShareParam::getId, (a, b) -> b));
                    Map<Integer, List<ComputeStandShareParamDetail>> collect = saveDetails.stream().collect(Collectors.groupingBy(ComputeStandShareParamDetail::getIndex));
                    List<ComputeStandShareParamDetail> saveCostDetails = new ArrayList<>();
                    collect.forEach((k, v) -> {
                        v.forEach(detail -> detail.setShareParamId(indexId.get(k)));
                        saveCostDetails.addAll(v);
                    });
                    computeStandShareParamDetailRepository.saveBatch(saveCostDetails, 500);
                }
            }
        }
    }

    /**
     * 执行标准法项目分摊参数计算后续处理脚本
     * @param computeDate
     */
    public void execStandShareParamCostSQL(String computeDate){
        Map<String,String> sqlParameter = new HashMap<>();
        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
        sqlService.autoExecuteSql(CustomSqlTypeEnum.STAND_PROJECT_PARAM_CALC.getCode(),sqlParameter);
    }

    private void checkItemCount(String computeDate, SessionUserVO currentUser) {
        long itemSize = importPatientItemRepository.getItemCount(computeDate, currentUser);
        if (Objects.equals(itemSize, NumberConstant.ZERO_L)) {
            log.error("当前核算年月【{}】未导入收费项目数据，计算中止", computeDate);
            throw new CostException("当前核算年月【" + computeDate + "】未导入收费项目数据，计算中止");
        }
    }

    private @NotNull Map<String, Map<String, Item>> getStandItemMap() {
        List<Item> itemList = itemRepository.getList();
        if (CollectionUtils.isEmpty(itemList)) {
            throw new CostException("医疗服务项目未维护，请先添加医疗服务项目再进行计算，当前计算中止");
        }
        //去除未对照标准项目的数据
        //获取标准项目字典
        List<StandItem> standItemDict = standItemService.getStandItemDict();
        if (CollectionUtils.isEmpty(standItemDict)) {
            log.error("当前院区未找到标准项目数据，计算中止");
            throw new CostException("当前院区未找到标准项目数据，计算中止");
        }
        Map<String, StandItem> standItemMap = standItemDict.stream().collect(Collectors.toMap(StandItem::getCode, standItem -> standItem, (a, b) -> b));

        for (Item item1 : itemList) {
            String standItemCode = item1.getStandItemCode();
            if (!StringUtils.isEmpty(standItemCode)) {
                if (Objects.nonNull(standItemMap.get(standItemCode))) {
                    item1.setStandItem(standItemMap.get(standItemCode));
                }
            }
        }

        Map<String, Map<String, Item>> itemMap = new HashMap<>();
        Map<String, List<Item>> collect = itemList.stream().collect(Collectors.groupingBy(Item::getDepartmentCode));
        collect.forEach((k, v) -> itemMap.put(k, v.stream().collect(Collectors.toMap(Item::getCode, item -> item, (a, b) -> b))));
        return itemMap;
    }

    private CommonTitleVo getTitle(String code, String name) {
        return new CommonTitleVo(code, name);
    }

    private ReportVo getData(String code, Object name) {
        ReportVo vo = new ReportVo();
        vo.setCode(code);
        vo.setValue(name);
        return vo;
    }

    private List<ComputeShareParamDetail> setDetails(ComputeShareParamDetail costDetail, PatientItemDepartmentGroupVo patientItem, List<ShareParamTypeMap> shareParamType,
                                                     Map<String, Map<String, Item>> itemMap) {
        List<ComputeShareParamDetail> details = new ArrayList<>();
        Item item = itemMap.get(patientItem.getExecuteDepartmentCode()).get(patientItem.getItemCode());
//        Item item = itemMap.get(patientItem.getItemCode());

        for (ShareParamTypeMap shareParam : shareParamType) {
            ComputeShareParamDetail result = BeanUtil.convertObj(costDetail, ComputeShareParamDetail.class);
            switch (shareParam.getSourceType()) {
                case NumberConstant.ONE_S: {
                    //参与人员、
                    List<ItemEmpMap> empMaps = item.getEmpMaps();
                    if (!CollectionUtils.isEmpty(empMaps)) {
                        Map<String, List<ItemEmpMap>> collect = empMaps.stream().collect(Collectors.groupingBy(ItemEmpMap::getEmpTypeCode));
//                        Map<String, ItemEmpMap> map = empMaps.stream().collect(Collectors.toMap(ItemEmpMap::getEmpTypeCode, empMap -> empMap, (a, b) -> b));
                        String sourceCode = shareParam.getSourceCode();
                        if (sourceCode.equals(NumberConstant.ZERO_S)) {
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (ItemEmpMap empMap : empMaps) {
                                BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                sum.updateAndGet(v -> v.add(multiply));
                                singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                            }
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        } else if (sourceCode.contains("|")) {
                            List<String> split = StrUtil.split(sourceCode, "|");
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (String s : split) {
                                List<ItemEmpMap> itemEmpMaps = collect.get(s);
                                if (!CollectionUtils.isEmpty(itemEmpMaps)) {
                                    for (ItemEmpMap itemEmpMap : itemEmpMaps) {
                                        if (Objects.nonNull(itemEmpMap)) {
                                            BigDecimal multiply = patientItem.getNum().multiply(itemEmpMap.getExecuteTime()).multiply(itemEmpMap.getNum());
                                            sum.updateAndGet(v -> v.add(multiply));
                                            singleSum.updateAndGet(v -> v.add(itemEmpMap.getExecuteTime().multiply(itemEmpMap.getNum())));
                                        } 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));
                                }
                            }
                            result.setShareParamCode(shareParam.getShareParamCode());
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            details.add(result);
                        } else {
                            List<ItemEmpMap> itemEmpMaps = collect.get(sourceCode);
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            if (!CollectionUtils.isEmpty(itemEmpMaps)) {
                                for (ItemEmpMap itemEmpMap : itemEmpMaps) {
                                    if (Objects.nonNull(itemEmpMap)) {
                                        BigDecimal multiply = patientItem.getNum().multiply(itemEmpMap.getExecuteTime()).multiply(itemEmpMap.getNum());
                                        sum.updateAndGet(v -> v.add(multiply));
                                        singleSum.updateAndGet(v -> v.add(itemEmpMap.getExecuteTime().multiply(itemEmpMap.getNum())));
                                    } 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));
                            }
                            result.setComputeResult(sum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            result.setComputeSingleResult(singleSum.get());
                            details.add(result);
                        }
                    } else {
                        result.setComputeResult(BigDecimal.ZERO);
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        result.setShareParamCode(shareParam.getShareParamCode());
                        details.add(result);
                    }
                    break;
                }
                case NumberConstant.TWO_S: {
                    //使用设备
                    List<ItemEquipmentMap> equipmentMaps = item.getEquipmentMaps();
                    if (!CollectionUtils.isEmpty(equipmentMaps)) {
                        Map<String, List<ItemEquipmentMap>> collect = equipmentMaps.stream().collect(Collectors.groupingBy(ItemEquipmentMap::getEquipmentCode));
//                        Map<String, ItemEquipmentMap> map = equipmentMaps.stream().collect(Collectors.toMap(ItemEquipmentMap::getEquipmentCode, empMap -> empMap, (a, b) -> b));
                        String sourceCode = shareParam.getSourceCode();
                        if (sourceCode.equals(NumberConstant.ZERO_S)) {
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (ItemEquipmentMap empMap : equipmentMaps) {
                                BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                sum.updateAndGet(v -> v.add(multiply));
                                singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                            }
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        } else if (sourceCode.contains("|")) {
                            List<String> split = StrUtil.split(sourceCode, "|");
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (String s : split) {
                                List<ItemEquipmentMap> itemEquipmentMaps = collect.get(s);
                                if (!CollectionUtils.isEmpty(itemEquipmentMaps)) {
                                    for (ItemEquipmentMap equipmentMap : itemEquipmentMaps) {
                                        if (Objects.nonNull(equipmentMap)) {
                                            BigDecimal multiply = patientItem.getNum().multiply(equipmentMap.getExecuteTime()).multiply(equipmentMap.getNum());
                                            sum.updateAndGet(v -> v.add(multiply));
                                            singleSum.updateAndGet(v -> v.add(equipmentMap.getExecuteTime().multiply(equipmentMap.getNum())));
                                        } 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));
                                }
                            }
                            result.setShareParamCode(shareParam.getShareParamCode());
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            details.add(result);
                        } else {
                            List<ItemEquipmentMap> itemEquipmentMaps = collect.get(sourceCode);
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (ItemEquipmentMap equipmentMap : itemEquipmentMaps) {
                                if (Objects.nonNull(equipmentMap)) {
                                    BigDecimal multiply = patientItem.getNum().multiply(equipmentMap.getExecuteTime()).multiply(equipmentMap.getNum());
                                    sum.updateAndGet(v -> v.add(multiply));
                                    singleSum.updateAndGet(v -> v.add(equipmentMap.getExecuteTime().multiply(equipmentMap.getNum())));
                                } else {
                                    sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                    singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                }
                            }
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        }
                    } else {
                        result.setComputeResult(BigDecimal.ZERO);
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        result.setShareParamCode(shareParam.getShareParamCode());
                        details.add(result);
                    }
                    break;
                }
                case NumberConstant.THREE_S: {
                    //使用空间
                    List<ItemSpaceMap> spaceMaps = item.getSpaceMaps();
                    if (!CollectionUtils.isEmpty(spaceMaps)) {
//                        Map<String, ItemSpaceMap> map = spaceMaps.stream().collect(Collectors.toMap(ItemSpaceMap::getSpaceCode, f -> f, (a, b) -> b));
                        Map<String, List<ItemSpaceMap>> collect = spaceMaps.stream().collect(Collectors.groupingBy(ItemSpaceMap::getSpaceCode));

                        String sourceCode = shareParam.getSourceCode();
                        if (sourceCode.equals(NumberConstant.ZERO_S)) {
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (ItemSpaceMap empMap : spaceMaps) {
                                BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                sum.updateAndGet(v -> v.add(multiply));
                                singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                            }
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        } else if (sourceCode.contains("|")) {
                            List<String> split = StrUtil.split(sourceCode, "|");
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            for (String s : split) {
                                List<ItemSpaceMap> itemSpaceMaps = collect.get(s);
                                if (!CollectionUtils.isEmpty(itemSpaceMaps)) {
                                    for (ItemSpaceMap spaceMap : itemSpaceMaps) {
                                        if (Objects.nonNull(spaceMap)) {
                                            BigDecimal multiply = patientItem.getNum().multiply(spaceMap.getExecuteTime()).multiply(spaceMap.getNum());
                                            sum.updateAndGet(v -> v.add(multiply));
                                            singleSum.updateAndGet(v -> v.add(spaceMap.getExecuteTime().multiply(spaceMap.getNum())));

                                        } 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));
                                }
                            }
                            result.setShareParamCode(shareParam.getShareParamCode());
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            details.add(result);
                        } else {
                            List<ItemSpaceMap> itemSpaceMaps = collect.get(sourceCode);
                            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                            AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                            if (!CollectionUtils.isEmpty(itemSpaceMaps)) {
                                for (ItemSpaceMap spaceMap : itemSpaceMaps) {
                                    if (Objects.nonNull(spaceMap)) {
                                        BigDecimal multiply = patientItem.getNum().multiply(spaceMap.getExecuteTime()).multiply(spaceMap.getNum());
                                        sum.updateAndGet(v -> v.add(multiply));
                                        singleSum.updateAndGet(v -> v.add(spaceMap.getExecuteTime().multiply(spaceMap.getNum())));
                                    } 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));
                            }
                            result.setComputeResult(sum.get());
                            result.setComputeSingleResult(singleSum.get());
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        }
                    } else {
                        result.setShareParamCode(shareParam.getShareParamCode());
                        result.setComputeResult(BigDecimal.ZERO);
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        details.add(result);
                    }
                    break;
                }
                case NumberConstant.FOUR_S:
                    //项目收入
                    result.setShareParamCode(shareParam.getShareParamCode());
                    result.setComputeResult(patientItem.getAmount());
                    if (!patientItem.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
                        result.setComputeSingleResult(patientItem.getAmount().divide(patientItem.getNum(), 4, RoundingMode.HALF_UP));
                    } else {
                        result.setComputeSingleResult(BigDecimal.ZERO);
                    }
                    details.add(result);
                    break;
                case NumberConstant.FIVE_S:
                    result.setShareParamCode(shareParam.getShareParamCode());
                    result.setComputeResult(patientItem.getNum());
                    details.add(result);
                    break;
            }
        }
        return details;

    }

    private List<ComputeStandShareParamDetail> setStandDetails(ComputeStandShareParamDetail costDetail, PatientItemDepartmentGroupVo patientItem, List<ShareParamTypeMap> shareParamType,
                                                               Map<String, Map<String, Item>> itemMap) {
        List<ComputeStandShareParamDetail> details = new ArrayList<>();
        Item item = itemMap.get(patientItem.getExecuteDepartmentCode()).get(patientItem.getItemCode());
        StandItem standItem = item.getStandItem();
        for (ShareParamTypeMap shareParam : shareParamType) {
            ComputeStandShareParamDetail result = BeanUtil.convertObj(costDetail, ComputeStandShareParamDetail.class);
            switch (shareParam.getSourceType()) {
                case NumberConstant.ONE_S: {
                    //参与人员、
                    if (Objects.nonNull(standItem)) {
                        List<StandItemEmpMap> empMaps = standItem.getEmpMaps();
                        if (!CollectionUtils.isEmpty(empMaps)) {
                            Map<String, List<StandItemEmpMap>> collect = empMaps.stream().collect(Collectors.groupingBy(StandItemEmpMap::getEmpTypeCode));
                            String sourceCode = shareParam.getSourceCode();
                            if (sourceCode.equals(NumberConstant.ZERO_S)) {
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (StandItemEmpMap empMap : empMaps) {
                                    BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                    sum.updateAndGet(v -> v.add(multiply));
                                    singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                                }
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                details.add(result);
                            } else if (sourceCode.contains("|")) {
                                List<String> split = StrUtil.split(sourceCode, "|");
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (String s : split) {
                                    List<StandItemEmpMap> itemEmpMaps = collect.get(s);
                                    if (!CollectionUtils.isEmpty(itemEmpMaps)) {
                                        for (StandItemEmpMap itemEmpMap : itemEmpMaps) {
                                            if (Objects.nonNull(itemEmpMap)) {
                                                BigDecimal multiply = patientItem.getNum().multiply(itemEmpMap.getExecuteTime()).multiply(itemEmpMap.getNum());
                                                sum.updateAndGet(v -> v.add(multiply));
                                                singleSum.updateAndGet(v -> v.add(itemEmpMap.getExecuteTime().multiply(itemEmpMap.getNum())));
                                            } 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));
                                    }
                                }
                                result.setShareParamCode(shareParam.getShareParamCode());
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                details.add(result);
                            } else {
                                List<StandItemEmpMap> itemEmpMaps = collect.get(sourceCode);
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                if (!CollectionUtils.isEmpty(itemEmpMaps)) {
                                    for (StandItemEmpMap itemEmpMap : itemEmpMaps) {
                                        if (Objects.nonNull(itemEmpMap)) {
                                            BigDecimal multiply = patientItem.getNum().multiply(itemEmpMap.getExecuteTime()).multiply(itemEmpMap.getNum());
                                            sum.updateAndGet(v -> v.add(multiply));
                                            singleSum.updateAndGet(v -> v.add(itemEmpMap.getExecuteTime().multiply(itemEmpMap.getNum())));
                                        } 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));
                                }
                                result.setComputeResult(sum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                result.setComputeSingleResult(singleSum.get());
                                details.add(result);
                            }
                        } else {
                            result.setComputeResult(BigDecimal.ZERO);
                            result.setComputeSingleResult(BigDecimal.ZERO);
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        }
                    } else {
                        if (result != null) {
                            result.setComputeResult(BigDecimal.ZERO);
                        }
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        result.setShareParamCode(shareParam.getShareParamCode());
                        details.add(result);
                    }
                    break;
                }
                case NumberConstant.TWO_S: {
                    //使用设备
                    if (Objects.nonNull(standItem)) {
                        List<StandItemEquipmentMap> equipmentMaps = standItem.getEquipmentMaps();
                        if (!CollectionUtils.isEmpty(equipmentMaps)) {
                            Map<String, List<StandItemEquipmentMap>> collect = equipmentMaps.stream().collect(Collectors.groupingBy(StandItemEquipmentMap::getEquipmentCode));
//                        Map<String, ItemEquipmentMap> map = equipmentMaps.stream().collect(Collectors.toMap(ItemEquipmentMap::getEquipmentCode, empMap -> empMap, (a, b) -> b));
                            String sourceCode = shareParam.getSourceCode();
                            if (sourceCode.equals(NumberConstant.ZERO_S)) {
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (StandItemEquipmentMap empMap : equipmentMaps) {
                                    BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                    sum.updateAndGet(v -> v.add(multiply));
                                    singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                                }
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                details.add(result);
                            } else if (sourceCode.contains("|")) {
                                List<String> split = StrUtil.split(sourceCode, "|");
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (String s : split) {
                                    List<StandItemEquipmentMap> itemEquipmentMaps = collect.get(s);
                                    if (!CollectionUtils.isEmpty(itemEquipmentMaps)) {
                                        for (StandItemEquipmentMap equipmentMap : itemEquipmentMaps) {
                                            if (Objects.nonNull(equipmentMap)) {
                                                BigDecimal multiply = patientItem.getNum().multiply(equipmentMap.getExecuteTime()).multiply(equipmentMap.getNum());
                                                sum.updateAndGet(v -> v.add(multiply));
                                                singleSum.updateAndGet(v -> v.add(equipmentMap.getExecuteTime().multiply(equipmentMap.getNum())));
                                            } 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));
                                    }
                                }
                                result.setShareParamCode(shareParam.getShareParamCode());
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                details.add(result);
                            } else {
                                List<StandItemEquipmentMap> itemEquipmentMaps = collect.get(sourceCode);
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (StandItemEquipmentMap equipmentMap : itemEquipmentMaps) {
                                    if (Objects.nonNull(equipmentMap)) {
                                        BigDecimal multiply = patientItem.getNum().multiply(equipmentMap.getExecuteTime()).multiply(equipmentMap.getNum());
                                        sum.updateAndGet(v -> v.add(multiply));
                                        singleSum.updateAndGet(v -> v.add(equipmentMap.getExecuteTime().multiply(equipmentMap.getNum())));
                                    } else {
                                        sum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                        singleSum.updateAndGet(v -> v.add(BigDecimal.ZERO));
                                    }
                                }
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                details.add(result);
                            }
                        } else {
                            result.setComputeResult(BigDecimal.ZERO);
                            result.setComputeSingleResult(BigDecimal.ZERO);
                            result.setShareParamCode(shareParam.getShareParamCode());
                            details.add(result);
                        }
                    } else {
                        result.setComputeResult(BigDecimal.ZERO);
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        result.setShareParamCode(shareParam.getShareParamCode());
                        details.add(result);
                    }


                    break;
                }
                case NumberConstant.THREE_S: {
                    //使用空间
                    if (Objects.nonNull(standItem)) {
                        List<StandItemSpaceMap> spaceMaps = standItem.getSpaceMaps();
                        if (!CollectionUtils.isEmpty(spaceMaps)) {
//                        Map<String, ItemSpaceMap> map = spaceMaps.stream().collect(Collectors.toMap(ItemSpaceMap::getSpaceCode, f -> f, (a, b) -> b));
                            Map<String, List<StandItemSpaceMap>> collect = spaceMaps.stream().collect(Collectors.groupingBy(StandItemSpaceMap::getSpaceCode));

                            String sourceCode = shareParam.getSourceCode();
                            if (sourceCode.equals(NumberConstant.ZERO_S)) {
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (StandItemSpaceMap empMap : spaceMaps) {
                                    BigDecimal multiply = patientItem.getNum().multiply(empMap.getExecuteTime()).multiply(empMap.getNum());
                                    sum.updateAndGet(v -> v.add(multiply));
                                    singleSum.updateAndGet(v -> v.add(empMap.getExecuteTime().multiply(empMap.getNum())));
                                }
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                details.add(result);
                            } else if (sourceCode.contains("|")) {
                                List<String> split = StrUtil.split(sourceCode, "|");
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                for (String s : split) {
                                    List<StandItemSpaceMap> itemSpaceMaps = collect.get(s);
                                    if (!CollectionUtils.isEmpty(itemSpaceMaps)) {
                                        for (StandItemSpaceMap spaceMap : itemSpaceMaps) {
                                            if (Objects.nonNull(spaceMap)) {
                                                BigDecimal multiply = patientItem.getNum().multiply(spaceMap.getExecuteTime()).multiply(spaceMap.getNum());
                                                sum.updateAndGet(v -> v.add(multiply));
                                                singleSum.updateAndGet(v -> v.add(spaceMap.getExecuteTime().multiply(spaceMap.getNum())));

                                            } 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));
                                    }
                                }
                                result.setShareParamCode(shareParam.getShareParamCode());
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                details.add(result);
                            } else {
                                List<StandItemSpaceMap> itemSpaceMaps = collect.get(sourceCode);
                                AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.0000"));
                                AtomicReference<BigDecimal> singleSum = new AtomicReference<>(new BigDecimal("0.0000"));
                                if (!CollectionUtils.isEmpty(itemSpaceMaps)) {
                                    for (StandItemSpaceMap spaceMap : itemSpaceMaps) {
                                        if (Objects.nonNull(spaceMap)) {
                                            BigDecimal multiply = patientItem.getNum().multiply(spaceMap.getExecuteTime()).multiply(spaceMap.getNum());
                                            sum.updateAndGet(v -> v.add(multiply));
                                            singleSum.updateAndGet(v -> v.add(spaceMap.getExecuteTime().multiply(spaceMap.getNum())));
                                        } 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));
                                }
                                result.setComputeResult(sum.get());
                                result.setComputeSingleResult(singleSum.get());
                                result.setShareParamCode(shareParam.getShareParamCode());
                                details.add(result);
                            }
                        } else {
                            result.setShareParamCode(shareParam.getShareParamCode());
                            result.setComputeResult(BigDecimal.ZERO);
                            result.setComputeSingleResult(BigDecimal.ZERO);
                            details.add(result);
                        }
                    } else {
                        result.setShareParamCode(shareParam.getShareParamCode());
                        result.setComputeResult(BigDecimal.ZERO);
                        result.setComputeSingleResult(BigDecimal.ZERO);
                        details.add(result);
                    }

                    break;
                }
                case NumberConstant.FOUR_S:
                    //项目收入
                    result.setShareParamCode(shareParam.getShareParamCode());
                    result.setComputeResult(patientItem.getAmount());
                    if (!patientItem.getNum().equals(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP))) {
                        result.setComputeSingleResult(patientItem.getAmount().divide(patientItem.getNum(), 4, RoundingMode.HALF_UP));
                    } else {
                        result.setComputeSingleResult(BigDecimal.ZERO);
                    }
                    details.add(result);
                    break;
                case NumberConstant.FIVE_S:
                    result.setShareParamCode(shareParam.getShareParamCode());
                    result.setComputeResult(patientItem.getNum());
                    details.add(result);
                    break;
            }


        }
        return details;

    }

    private Map<String, Map<String, Item>> getItemMap() {
        List<Item> list = itemRepository.getList();
        if (CollectionUtils.isEmpty(list)) {
            throw new CostException("医疗服务项目未维护，请先添加医疗服务项目再进行计算，当前计算中止");
        }
        List<ItemEmpMap> list1 = itemEmpMapRepository.getList();
        //医疗服务项目字典人员对照
        Map<String, Map<String, List<ItemEmpMap>>> empMapGroup = new HashMap<>();
        if (!CollectionUtils.isEmpty(list1)) {
            Map<String, List<ItemEmpMap>> collect = list1.stream().collect(Collectors.groupingBy(ItemEmpMap::getDepartmentCode));
            collect.forEach((k, v) -> {
                Map<String, List<ItemEmpMap>> collect1 = v.stream().collect(Collectors.groupingBy(ItemEmpMap::getItemCode));
                empMapGroup.put(k, collect1);
            });
//            empMapGroup = list1.stream().collect(Collectors.groupingBy(ItemEmpMap::getItemCode));
        }
        List<ItemEquipmentMap> list2 = itemEquipmentMapRepository.getList();
        //医疗服务项目字典设备对照
//        Map<String, List<ItemEquipmentMap>> equipmentGroup = new HashMap<>();
        Map<String, Map<String, List<ItemEquipmentMap>>> equipmentGroup = new HashMap<>();
        if (!CollectionUtils.isEmpty(list2)) {
            Map<String, List<ItemEquipmentMap>> collect = list2.stream().collect(Collectors.groupingBy(ItemEquipmentMap::getDepartmentCode));
            collect.forEach((k, v) -> {
                Map<String, List<ItemEquipmentMap>> collect1 = v.stream().collect(Collectors.groupingBy(ItemEquipmentMap::getItemCode));
                equipmentGroup.put(k, collect1);
            });
//            equipmentGroup = list2.stream().collect(Collectors.groupingBy(ItemEquipmentMap::getItemCode));
        }
        List<ItemSpaceMap> list3 = itemSpaceMapRepository.getList();
        //医疗服务项目字典设备对照
//        Map<String, List<ItemSpaceMap>> spaceGroup = new HashMap<>();
        Map<String, Map<String, List<ItemSpaceMap>>> spaceGroup = new HashMap<>();

        if (!CollectionUtils.isEmpty(list3)) {
            Map<String, List<ItemSpaceMap>> collect = list3.stream().collect(Collectors.groupingBy(ItemSpaceMap::getDepartmentCode));
            collect.forEach((k, v) -> {
                Map<String, List<ItemSpaceMap>> collect1 = v.stream().collect(Collectors.groupingBy(ItemSpaceMap::getItemCode));
                spaceGroup.put(k, collect1);
            });
//            spaceGroup = list3.stream().collect(Collectors.groupingBy(ItemSpaceMap::getItemCode));
        }
        Map<String, Map<String, Item>> map = new HashMap<>();
        Map<String, List<Item>> collect = list.stream().collect(Collectors.groupingBy(Item::getDepartmentCode));
        collect.forEach((k, v) -> {
            Map<String, List<ItemEmpMap>> empMap = empMapGroup.get(k);
            Map<String, List<ItemEquipmentMap>> equipmentMap = equipmentGroup.get(k);
            Map<String, List<ItemSpaceMap>> spaceMap = spaceGroup.get(k);
            Map<String, Item> itemCodeMap = new HashMap<>();
            for (Item item : v) {
                if (!CollectionUtils.isEmpty(empMap)) {
                    item.setEmpMaps(empMap.get(item.getCode()));
                }
                if (!CollectionUtils.isEmpty(equipmentMap)) {
                    item.setEquipmentMaps(equipmentMap.get(item.getCode()));
                }
                if (!CollectionUtils.isEmpty(spaceMap)) {
                    item.setSpaceMaps(spaceMap.get(item.getCode()));
                }
                itemCodeMap.put(item.getCode(), item);
            }
            map.put(k, itemCodeMap);
        });
        return map;
    }

    private List<VisitNoResponsibilityMap> getPatientResponsibility(SessionUserVO currentUser) {
        return getVisitNoResponsibilityMaps(currentUser, responsibilityDepartmentRepository, centerService, log);
    }


    private @NotNull Map<String, Map<String, PatientItemDepartmentGroupVo>> getPatientItemGroup(String computeDate, SessionUserVO currentUser, Map<String, String> responsibilityCodeMap) {
        List<PatientItemDepartmentGroupVo> items = importPatientItemRepository.getByDepartGroupComputeDateItem(computeDate, currentUser);
        //移除执行科室为空的
        List<PatientItemDepartmentGroupVo> removeDepartmentList = new ArrayList<>();
        for (PatientItemDepartmentGroupVo item : items) {
            if(StringUtils.isEmpty(item.getExecuteDepartmentCode())){
                removeDepartmentList.add(item);
            }
        }
        if(!CollectionUtils.isEmpty(removeDepartmentList)){
            List<String> logs = new ArrayList<>();
            for (PatientItemDepartmentGroupVo patientItemDepartmentGroupVo : removeDepartmentList) {
                logs.add(patientItemDepartmentGroupVo.getItemCode());
            }
            List<String> collect2 = logs.stream().distinct().collect(Collectors.toList());
            log.info("以下项目数据【{}】执行科室为空", collect2);
            items.removeAll(removeDepartmentList);
        }

        items.forEach(item -> item.setResponsibilityCode(responsibilityCodeMap.get(item.getExecuteDepartmentCode())));
        //移除责任中心为空的
        List<PatientItemDepartmentGroupVo> removeList = new ArrayList<>();
        for (PatientItemDepartmentGroupVo item : items) {
            if(StringUtils.isEmpty(item.getResponsibilityCode())){
                removeList.add(item);
            }
        }
        if(!CollectionUtils.isEmpty(removeList)){
            List<String> logs = new ArrayList<>();
            for (PatientItemDepartmentGroupVo patientItemDepartmentGroupVo : removeList) {
                logs.add(patientItemDepartmentGroupVo.getExecuteDepartmentCode());
            }
            List<String> collect2 = logs.stream().distinct().collect(Collectors.toList());
            log.info("以下执行科室【{}】科室代码未对照责任中心", collect2);
            items.removeAll(removeList);
        }


        Map<String, List<PatientItemDepartmentGroupVo>> collect2 = items.stream().collect(Collectors.groupingBy(PatientItemDepartmentGroupVo::getResponsibilityCode));
        Map<String,Map<String,PatientItemDepartmentGroupVo>> responsibilityItemGroupMap = new HashMap<>();
        collect2.forEach((k,v)->{
            Map<String, List<PatientItemDepartmentGroupVo>> collect3 = v.stream().collect(Collectors.groupingBy(PatientItemDepartmentGroupVo::getItemCode));
            if(!CollectionUtils.isEmpty(collect3)){
                Map<String,PatientItemDepartmentGroupVo> itemGroupMap = new HashMap<>();
                collect3.forEach((itemCode,itemList)->{
                    PatientItemDepartmentGroupVo vo = new PatientItemDepartmentGroupVo();
                    vo.setItemCode(itemCode);
                    vo.setItemName(itemList.get(0).getItemName());
                    vo.setResponsibilityCode(k);
                    AtomicReference<BigDecimal> sumNum = new AtomicReference<>(new BigDecimal("0.00"));
                    AtomicReference<BigDecimal> sumAmount  = new AtomicReference<>(new BigDecimal("0.0000"));
                    for (PatientItemDepartmentGroupVo vo1 : itemList) {
                        sumNum.updateAndGet(s -> s.add(vo1.getNum()));
                        sumAmount.updateAndGet(s -> s.add(vo1.getAmount()));
                    }
                    vo.setNum(sumNum.get());
                    vo.setAmount(sumAmount.get());
                    vo.setExecuteDepartmentCode(itemList.get(0).getExecuteDepartmentCode());
                    itemGroupMap.put(itemCode,vo);
                });
                responsibilityItemGroupMap.put(k,itemGroupMap);
            }

        });
        return responsibilityItemGroupMap;
    }


}
