package com.diagbot.facade;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diagbot.aggregate.AverageStatisticsAggregate;
import com.diagbot.aggregate.MrStatisticsAggregate;
import com.diagbot.aggregate.ResultStatisticsAggregate;
import com.diagbot.dto.AverageStatisticsDTO;
import com.diagbot.dto.AverageStatisticsFeeDTO;
import com.diagbot.dto.CaseScoreDTO;
import com.diagbot.dto.ColumnDTO;
import com.diagbot.dto.DeptNumDTO;
import com.diagbot.dto.EntryNumDTO;
import com.diagbot.dto.EntryNumGroupDTO;
import com.diagbot.dto.EntryStatisticsDTO;
import com.diagbot.dto.HomePageImproveDTO;
import com.diagbot.dto.HomePageNumDTO;
import com.diagbot.dto.LevelStatisticsDTO;
import com.diagbot.dto.LevelStatisticsTZDTO;
import com.diagbot.dto.MedManageParamsDTO;
import com.diagbot.dto.MedicalCheckDTO;
import com.diagbot.dto.MedicalCheckExportDTO;
import com.diagbot.dto.NumDTO;
import com.diagbot.dto.QcResultPercentDTO;
import com.diagbot.dto.QcResultShortDTO;
import com.diagbot.dto.QualityControlDTO;
import com.diagbot.dto.QualityControlNullDTO;
import com.diagbot.dto.ReBeHosDTO;
import com.diagbot.dto.ReBeHosDetailDTO;
import com.diagbot.dto.ReBeHosMergeDTO;
import com.diagbot.dto.SjcfStatisticsDTO;
import com.diagbot.dto.UnModifyMRDTO;
import com.diagbot.dto.UnModifyMRDetailDTO;
import com.diagbot.entity.BehospitalInfo;
import com.diagbot.entity.MedIndexRelevance;
import com.diagbot.entity.MedIndexResult;
import com.diagbot.entity.MedManagementInfo;
import com.diagbot.entity.QcCasesEntry;
import com.diagbot.entity.SysHospitalSet;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.enums.QualityContent;
import com.diagbot.enums.TimeContent;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.MedManagementInfoService;
import com.diagbot.util.BeanUtil;
import com.diagbot.util.BigDecimalUtil;
import com.diagbot.util.ClassUtil;
import com.diagbot.util.DateUtil;
import com.diagbot.util.EntityUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.util.ObjectUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.util.SysUserUtils;
import com.diagbot.vo.AlgorithmVO;
import com.diagbot.vo.BehospitalPageVO;
import com.diagbot.vo.CaseScoreVO;
import com.diagbot.vo.EntryStatisticsVO;
import com.diagbot.vo.FilterMedicalCheckVO;
import com.diagbot.vo.FilterOrderVO;
import com.diagbot.vo.FilterPageByAverageVO;
import com.diagbot.vo.FilterPageVO;
import com.diagbot.vo.FilterUnModifyMRVO;
import com.diagbot.vo.FilterVO;
import com.diagbot.vo.IndexTimeVO;
import com.diagbot.vo.MedIndexFilterVO;
import com.diagbot.vo.QcResultAlgVO;
import com.diagbot.vo.QcResultPageVO;
import com.diagbot.vo.QcResultShortPageVO;
import com.diagbot.vo.ReBeHosPageVO;
import com.google.common.collect.Lists;

import io.github.lvyahui8.spring.aggregate.facade.DataBeanAggregateQueryFacade;

/**
 * @Description:
 * @Author:zhaops
 * @time: 2024/4/13 16:45
 */
@Component
public class ConsoleFacade {
    @Autowired
    private FilterFacade filterFacade;
    @Autowired
    private DataBeanAggregateQueryFacade dataBeanAggregateQueryFacade;

    @Autowired
    private AverageStatisticsAggregate averageStatisticsAggregate;
    @Autowired
    private MrStatisticsAggregate mrStatisticsAggregate;
    @Autowired
    private ResultStatisticsAggregate resultStatisticsAggregate;
    @Autowired
    private QcresultInfoFacade qcresultInfoFacade;
    @Autowired
    private HomePageFacade homePageFacade;
    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;
    @Autowired
    private SysHospitalSetFacade sysHospitalSetFacade;
    @Autowired
    private QcCasesEntryFacade qcCasesEntryFacade;
    @Autowired
    @Qualifier("medManagementInfoServiceImpl")
    private MedManagementInfoService medManagementInfoService;
    @Autowired
    private MedIndexResultFacade medIndexResultFacade;
    @Autowired
    private MedIndexRelevanceFacade medIndexRelevanceFacade;
    //region-----------------------聚合接口开始-------------------------------

    /**
     * 病历相关统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> mrStatistics(FilterVO filterVO) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            retMap
                    = dataBeanAggregateQueryFacade.get("setAllMr", invokeParams, Map.class);
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        return retMap;
    }

    /**
     * 缺陷相关统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> resultStatistics(FilterVO filterVO) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            retMap
                    = dataBeanAggregateQueryFacade.get("setAllResult", invokeParams, Map.class);
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        return retMap;
    }

    /**
     * 平局值相关统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> averageStatistics(FilterVO filterVO) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            retMap
                    = dataBeanAggregateQueryFacade.get("setAllAverage", invokeParams, Map.class);
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        return retMap;
    }

    //endregion-----------------------聚合接口结束-------------------------------

    //region-----------------------单独接口开始-------------------------------

    /**
     * 平均住院天数
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> getAverageDayNum(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<AverageStatisticsDTO> averageDayNumList = averageStatisticsAggregate.getAverageDayNum(filterVO);
        if (ListUtil.isNotEmpty(averageDayNumList)) {
            retMap.put("平均住院日", averageDayNumList);
        }
        return retMap;
    }

    /**
     * 平均住院费用
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> getAverageFee(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<AverageStatisticsDTO> averageFeeList = averageStatisticsAggregate.getAverageFee(filterVO);
        if (ListUtil.isNotEmpty(averageFeeList)) {
            retMap.put("平均住院费用", averageFeeList);
        }
        return retMap;
    }

    /**
     * 质控平均分按科室统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> getAverageScore(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSame(filterVO);
        List<AverageStatisticsDTO> averageScoreList = averageStatisticsAggregate.getAverageScore(filterVO);

        AverageStatisticsDTO item = getGlobleAverageTitle(averageScoreList);
        if (item != null) {
            averageScoreList.add(0, item);
        }

        if (ListUtil.isNotEmpty(averageScoreList)) {
            retMap.put("各科室质控平均分", averageScoreList);
        }
        return retMap;
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public AverageStatisticsDTO getGlobleAverageTitle(List<AverageStatisticsDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        AverageStatisticsDTO item = new AverageStatisticsDTO();
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //数量
        Integer num = records
                .stream()
                .map(AverageStatisticsDTO::getNum)
                .reduce(0, Integer::sum);

        //同期数量
        Integer sameNum = records
                .stream()
                .map(AverageStatisticsDTO::getSameNum)
                .reduce(0, Integer::sum);

        Double totleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        Double sameTotleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getSameTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        Double averageValue = 0d;
        if (0 != num) {
            averageValue = BigDecimal.valueOf(totleValue)
                    .divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }
        Double lastYearAverageValue = 0d;
        if (0 != sameNum) {
            lastYearAverageValue = BigDecimal.valueOf(sameTotleValue)
                    .divide(BigDecimal.valueOf(sameNum), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }

        item.setName("全院");
        item.setNum(num);
        item.setSameNum(sameNum);
        item.setAverageValue(averageValue);
        item.setTotleValue(totleValue);
        item.setSameTotleValue(sameTotleValue);
        item.setLastYearAverageValue(lastYearAverageValue);
        return item;
    }


    /**
     * 各科室质控平均分（首页）-根据内外科系统统计
     *
     * @param filterVO
     * @return
     */
    public List<AverageStatisticsDTO> getAverageScoreByDeptClass(FilterVO filterVO) {
        filterFacade.filterVOSame(filterVO);
        List<AverageStatisticsDTO> retAverageScoreList = Lists.newLinkedList();
        List<AverageStatisticsDTO> averageScoreList = qcresultInfoFacade.getAverageScoreByDeptClass(filterVO);
        Integer limitCount = filterVO.getLimitCount();
        //质控平均分
        if (ListUtil.isNotEmpty(averageScoreList)) {
            retAverageScoreList = averageStatisticsAggregate.getLimitAverageList(averageScoreList, limitCount);
        }
        AverageStatisticsDTO item = getGlobleInOutTitle(retAverageScoreList, filterVO);
        if (item != null) {
            retAverageScoreList.add(0, item);
        }
        return retAverageScoreList;
    }

    /**
     * 增加内外科记录
     *
     * @param records
     * @return
     */
    public AverageStatisticsDTO getGlobleInOutTitle(List<AverageStatisticsDTO> records, FilterVO filterVO) {
        DecimalFormat df = new DecimalFormat("#0.00");
        AverageStatisticsDTO item = new AverageStatisticsDTO();
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //数量
        Integer num = records
                .stream()
                .map(AverageStatisticsDTO::getNum)
                .reduce(0, Integer::sum);

        //同期数量
        Integer sameNum = records
                .stream()
                .map(AverageStatisticsDTO::getSameNum)
                .reduce(0, Integer::sum);

        Double totleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        Double sameTotleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getSameTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        Double averageValue = 0d;
        if (0 != num) {
            averageValue = BigDecimal.valueOf(totleValue)
                    .divide(BigDecimal.valueOf(num), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }
        Double lastYearAverageValue = 0d;
        if (0 != sameNum) {
            lastYearAverageValue = BigDecimal.valueOf(sameTotleValue)
                    .divide(BigDecimal.valueOf(sameNum), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }

        if ("内科".equals(filterVO.getDeptClass())) {
            item.setName("内科系统");
        } else {
            item.setName("外科系统");
        }
        item.setNum(num);
        item.setSameNum(sameNum);
        item.setAverageValue(averageValue);
        item.setTotleValue(totleValue);
        item.setSameTotleValue(sameTotleValue);
        item.setLastYearAverageValue(lastYearAverageValue);
        return item;
    }

    /**
     * 各科室甲级病历占比
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> getLevelResultDept(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<QcResultPercentDTO> levelResults = mrStatisticsAggregate.getLevelResultDept(filterVO);
        if (ListUtil.isNotEmpty(levelResults)) {
            retMap.put("各科室甲级病历占比", levelResults);
        }
        return retMap;
    }

    /**
     * 出院人数统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> leaveHosCount(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        Map<String, Object> leaveHosMap = new HashMap<>();
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            leaveHosMap = dataBeanAggregateQueryFacade.get("setAllLeaveHos", invokeParams, Map.class);
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        if (leaveHosMap != null) {
            retMap.put("出院人数统计", leaveHosMap);
        }
        return retMap;
    }
    public String handleTime(String startDate){
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = dateFormat.parse(startDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return (dateFormat.format(parse)+" 23:59:59");
    };

    /**
     * 病案指标
     * @param filterVO
     * @return
     */
    public List<Map<String,String>> medicalRecordIndicator(FilterVO filterVO){
        filterFacade.filterSet(filterVO);
        List<Map<String, String>> hashMapArrayList = new ArrayList<>();
        String indexName = filterVO.getIndexName();
        //各指标未完成人数情况 ---分子
        Map<String, Long> triggeringRulesMap = behospitalInfoFacade.triggeringRules(filterVO);
        Long operationCount = triggeringRulesMap.get(QualityContent.SSJLWCC_24H);
        Long InHospitalRecords = triggeringRulesMap.get(QualityContent.RYJLWWC_24H);
        Long OutHospitalRecords = triggeringRulesMap.get(QualityContent.CYJLWWC_24H);
        Long recordHomePage = triggeringRulesMap.get(QualityContent.BASYWWC_24H);
        //病理手术
        Long operationPathologyFee = triggeringRulesMap.get("operationPathologyFee");
        //CT
        Long ct = triggeringRulesMap.get("CT");
        //MR
        Long mr = triggeringRulesMap.get("MR");
        //细菌培养
        Long bacterialCulture = triggeringRulesMap.get("bacterialCulture");
        //抗菌药物
        Long antibiosis = triggeringRulesMap.get("antibiosis");
        //恶性肿瘤化学治疗
        Long chemotherapyMalignantTumors = triggeringRulesMap.get("chemotherapyMalignantTumors");

        Map<String, Double> medicalRecordIndicator = medIndexResultFacade.medicalRecordIndicator(filterVO);
        Double startCount = medicalRecordIndicator.get("startCount");
        Double operationFeeNum = medicalRecordIndicator.get("operationFeeNum");
        Double CTNum = medicalRecordIndicator.get("CTNum");
        Double MRNum = medicalRecordIndicator.get("MRNum");
        Double operationPathologyFeeNum = medicalRecordIndicator.get("operationPathologyFeeNum");
        Double bacterialCultureNum = medicalRecordIndicator.get("bacterialCultureNum");
        Double antibiosisFeeNum = medicalRecordIndicator.get("antibiosisFeeNum");
        Double chemotherapyMalignantTumorsNum = medicalRecordIndicator.get("chemotherapyMalignantTumorsNum");
        MedIndexFilterVO timeVo = new MedIndexFilterVO();
        BeanUtils.copyProperties(filterVO,timeVo);
        timeTrans(timeVo);
        Map<String, Object> baseIndex = behospitalInfoFacade.getBaseIndex(timeVo);
        //指标一、二、三
        if (QualityContent.FOURSTR.contains(indexName)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = ManageIndexMethod(indexName, hashMapArrayList, baseIndex, timeVo);
        }
        //入院记录24小时完成率
        if(indexName.equals(QualityContent.RYJL_24H_WCL)||indexName.equals(QualityContent.QB)) {
            if (InHospitalRecords != null && startCount != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.RYJL_24H_WCL);
                stringStringHashMap.put("notCopiedStr", getResult(startCount - InHospitalRecords, startCount.doubleValue()));
                stringStringHashMap.put("num", Double.valueOf(startCount).toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //手术记录完成率
        if (indexName.equals(QualityContent.SSJL_24H_WCL)||indexName.equals(QualityContent.QB)) {
            if (operationFeeNum != null && operationCount != null) {
                LinkedHashMap<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.SSJL_24H_WCL);
                stringStringHashMap.put("notCopiedStr", getResult(operationFeeNum - operationCount, operationFeeNum));
                stringStringHashMap.put("num", operationFeeNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //出院记录24小时完成率
        if(indexName.equals(QualityContent.CYJL_24H_WCL)||indexName.equals(QualityContent.QB)) {
            if (OutHospitalRecords != null && startCount != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.CYJL_24H_WCL);
                stringStringHashMap.put("notCopiedStr", getResult(startCount - OutHospitalRecords, startCount.doubleValue()));
                stringStringHashMap.put("num", Double.valueOf(startCount).toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //病案首页24小时完成率
        if(indexName.equals(QualityContent.BASY_24H_WCL)||indexName.equals(QualityContent.QB)) {
            if (recordHomePage != null && startCount != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.BASY_24H_WCL);
                stringStringHashMap.put("notCopiedStr", getResult(startCount - recordHomePage, startCount.doubleValue()));
                stringStringHashMap.put("num", Double.valueOf(startCount).toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //CT完成率
        if (indexName.equals(QualityContent.CT_JCJL_FHL)||indexName.equals(QualityContent.QB)) {
            if (CTNum != null && ct != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.CT_JCJL_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(CTNum - ct, CTNum));
                stringStringHashMap.put("num", CTNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //MRI完成率
        if (indexName.equals(QualityContent.MR_JCJL_FHL)||indexName.equals(QualityContent.QB)) {
            if (MRNum != null && mr != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.MR_JCJL_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(MRNum - mr, MRNum));
                stringStringHashMap.put("num", MRNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //病理完成率为
        if (indexName.equals(QualityContent.BL_JCJL_FHL)||indexName.equals(QualityContent.QB)) {
            if (operationPathologyFeeNum != null && operationPathologyFee != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.BL_JCJL_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(operationPathologyFeeNum - operationPathologyFee, operationPathologyFeeNum));
                stringStringHashMap.put("num", operationPathologyFeeNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //细菌培养
        if (indexName.equals(QualityContent.XJPY_JCJL_FHL)||indexName.equals(QualityContent.QB)) {
            if (bacterialCultureNum != null && bacterialCulture != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.XJPY_JCJL_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(bacterialCultureNum - bacterialCulture, bacterialCultureNum));
                stringStringHashMap.put("num", bacterialCultureNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //抗菌
        if (indexName.equals(QualityContent.KJYW_SY_FHL)||indexName.equals(QualityContent.QB)) {
            if (antibiosisFeeNum != null && antibiosis != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.KJYW_SY_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(antibiosisFeeNum - antibiosis, antibiosisFeeNum));
                stringStringHashMap.put("num", antibiosisFeeNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //恶性肿瘤化学治疗
        if (indexName.equals(QualityContent.EXZL_HXZL_FHL)||indexName.equals(QualityContent.QB)) {
            if (chemotherapyMalignantTumorsNum != null && chemotherapyMalignantTumors != null) {
                Map<String, String> stringStringHashMap = new LinkedHashMap<>();
                stringStringHashMap.put("name", QualityContent.EXZL_HXZL_FHL);
                stringStringHashMap.put("notCopiedStr", getResult(chemotherapyMalignantTumorsNum - chemotherapyMalignantTumors, chemotherapyMalignantTumorsNum));
                stringStringHashMap.put("num", chemotherapyMalignantTumorsNum.toString());
                hashMapArrayList.add(stringStringHashMap);
            }
        }
        //指标十四 恶性肿瘤放射治疗
        if (indexName.equals(QualityContent.EXZL_FSZL_FHL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = tumorRadiationMethod(medicalRecordIndicator,hashMapArrayList,triggeringRulesMap);
        }

        //指标十五 手术记录
        if (indexName.equals(QualityContent.SS_XGJL_WCL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = operationMethod(medicalRecordIndicator,hashMapArrayList,triggeringRulesMap);
        }

        //指标十六 植入物相关记录符合率
        if (indexName.equals(QualityContent.ZRW_XGJL_WCL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = implantsMethod(medicalRecordIndicator,hashMapArrayList,triggeringRulesMap);
        }

        //指标十七  临床用血相关记录符合率
        if (indexName.equals(QualityContent.LCYX_XGJL_WCL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = bloodMethod(hashMapArrayList,medicalRecordIndicator,triggeringRulesMap);
        }

        //指标十八 医师查房记录
        if (indexName.equals(QualityContent.YSCF_JL_WCL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = WardRoundMethod(hashMapArrayList, baseIndex, triggeringRulesMap);
        }

        //指标十九 抢救记录
        if (indexName.equals(QualityContent.HZQJ_JLJS_WCL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = rescueMethod(medicalRecordIndicator,hashMapArrayList,triggeringRulesMap);
        }

        //指标二十 出院患者病历2日归档
        if (indexName.equals(QualityContent.CCHZ_2DAY_GDL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = getfileSecAmount(medicalRecordIndicator,hashMapArrayList, baseIndex);
        }

        //指标二十一 出院患者病历归档完整率
        if (indexName.equals(QualityContent.CCHZ_GD_WZL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = fileCompleteMethod(medicalRecordIndicator,hashMapArrayList, baseIndex);
        }

        //指标二十二 不合理复制病历发生率
        if (indexName.equals(QualityContent.BHL_FZ_FSL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = unreasonedCopyMethod(hashMapArrayList, baseIndex, triggeringRulesMap);
        }

        //指标二十三 知情同意书规范签署率
        if (indexName.equals(QualityContent.ZQTYS_GF_QSL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = contentSignMethod(hashMapArrayList, baseIndex, triggeringRulesMap);
        }

        //指标二十四 甲级率
        if (indexName.equals(QualityContent.JJBLL)||indexName.equals(QualityContent.QB)) {
            hashMapArrayList = firMethod(hashMapArrayList,baseIndex);
        }
        return hashMapArrayList;
    }



    /**
     * 病案指标数据保存
     *
     * @param IndexTimeVO
     * @return 2170
     */
    @Transactional
    public Boolean saveMedicaIndicator(IndexTimeVO IndexTimeVO){
        FilterVO filterVO = new FilterVO();
        BeanUtils.copyProperties(IndexTimeVO,filterVO);
        List<String> timeList = filterFacade.getTimeList(filterVO);
        QueryWrapper<MedIndexResult> qw = new QueryWrapper<>();
        qw.eq("hospital_id",filterVO.getHospitalId());
        qw.ge("start_date",filterVO.getStartDate()+" 00:00:00");
        qw.le("end_date", handleTime(filterVO.getEndDate()));
        medIndexResultFacade.remove(qw);
        QueryWrapper<MedIndexRelevance> qwa = new QueryWrapper<>();
        qwa.eq("hospital_id",filterVO.getHospitalId());
        qwa.ge("start_date",filterVO.getStartDate()+" 00:00:00");
        qwa.le("end_date", handleTime(filterVO.getEndDate()));
        medIndexRelevanceFacade.remove(qwa);
        for (String startTime : timeList) {
            filterVO.setStartDate(startTime);
            filterVO.setEndDate( handleTime(startTime));
            getMedicaIndicator(filterVO);
        }
        return true;
    }

    /**
     * 病案指标数据保存
     *
     * @param filterVO
     * @return 2170
     */
    public void getMedicaIndicator(FilterVO filterVO){
        MedIndexResult medIndexResult = new MedIndexResult();
       List<Map<String, String>> selectOperationNumMap = behospitalInfoFacade.selectOperationNum(filterVO);
            Set<String> outHospitalCode = new CopyOnWriteArraySet<>();
            Set<String> operationCode = new CopyOnWriteArraySet<>();
            Set<String> operationPathologyCode = new CopyOnWriteArraySet<>();
            Set<String> antibiosisCode = new CopyOnWriteArraySet<>();
            List<String> adviceVerify = adviceVerify(filterVO);
            Long operationFeeNum = 0L;
            filterVO.setFlagStr("2");
            List<MedManageParamsDTO> doctorAdviceMedManageParams = behospitalInfoFacade.getMedManageParams(filterVO);
         Map<String, Set<String>> adviceNum = getAdviceNum(filterVO, doctorAdviceMedManageParams);
        if(ListUtil.isNotEmpty(selectOperationNumMap)) {
            for (Map<String, String> stringStringMap : selectOperationNumMap) {
                String behospitalCode = stringStringMap.get("behospitalCode");
                //出院code
                outHospitalCode.add(behospitalCode);
                String operationFee = stringStringMap.get("operationFee");
                String pathologyFee = stringStringMap.get("pathologyFee");
                String antibiosisFee = stringStringMap.get("antibiosisFee");
                if(StringUtil.isNotEmpty(operationFee)) {
                    double of = 0.0;
                    try {
                        of = Double.parseDouble(operationFee);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (of > 0) {
                        //手术code
                        operationCode.add(behospitalCode);
                    }
                }
                if(StringUtil.isNotEmpty(operationFee)&&StringUtil.isNotEmpty(pathologyFee)) {
                    double of = 0.0;
                    double pf = 0.0;
                    try {
                        of = Double.parseDouble(operationFee);
                        pf = Double.parseDouble(pathologyFee);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    if (of > 0 && pf > QualityContent.pathologyFee) {
                        //病理code
                        operationPathologyCode.add(behospitalCode);
                    }
                }
                    if(StringUtil.isNotEmpty(antibiosisFee)) {
                        double af = 0.0;
                        try {
                            af = Double.parseDouble(antibiosisFee);
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                        if (af > 0) {
                        //抗菌code
                        antibiosisCode.add(behospitalCode);
                    }
            }
            }
        }
                if(ListUtil.isNotEmpty(adviceVerify)){
                    for (String code : adviceVerify) {
                        outHospitalCode.add(code);
                    }
                }
            Long startCount = Long.valueOf(outHospitalCode.size());
            //手术人
                Set<String> operationList = adviceNum.get("operation");
                if(operationList!=null&&operationList.size()>0){
                    for (String s : operationList) {
                        operationCode.add(s);
                    }
                }
                if(operationCode.size()>0&&operationCode!=null) {
                    operationFeeNum = Long.valueOf(operationCode.size());
                }
                //CT人数
                  Set<String> ctList = adviceNum.get("CT");
                Long CTNum=0L;
                if(ctList!=null&&ctList.size()>0) {
                    CTNum = Long.valueOf(ctList.size());
                }
                //MR人数
                  Set<String> mrList = adviceNum.get("MR");
                Long MRNum=0L;
                if(mrList!=null&&mrList.size()>0) {
                    MRNum = Long.valueOf(mrList.size());
                }
                //手术病理人数
                Long operationPathologyFeeNum=0L;
                   Set<String> operationPathologyList = adviceNum.get("operationPathology");
                if(operationPathologyList!=null&&operationPathologyList.size()>0){
                    for (String s : operationPathologyList) {
                        operationPathologyCode.add(s);
                    }
                }
                if(operationPathologyCode.size()>0&&operationPathologyCode!=null) {
                    operationPathologyFeeNum = Long.valueOf(operationPathologyCode.size());
                }
                //细菌培养人数
                  Set<String> bacterialCultureList = adviceNum.get("bacterialCulture");
                Long bacterialCultureNum=0L;
                if(bacterialCultureList!=null&&bacterialCultureList.size()>0) {
                    bacterialCultureNum = Long.valueOf(bacterialCultureList.size());
                }
                //抗菌药物人数
                  Set<String> antibiosisList = adviceNum.get("antibiosis");
                if(antibiosisList!=null&&antibiosisList.size()>0) {
                    for (String s : antibiosisList) {
                        antibiosisCode.add(s);
                    }
                }
                Long antibiosisFeeNum =0L;
                if(antibiosisCode.size()>0&&antibiosisCode!=null) {
                    antibiosisFeeNum = Long.valueOf(antibiosisCode.size());
                }
                //恶性肿瘤化学治疗人数
                Set<String> chemotherapyMalignantTumorsList = adviceNum.get("chemotherapyMalignantTumors");
                Long chemotherapyMalignantTumorsNum =0L;
                if(chemotherapyMalignantTumorsList!=null&&chemotherapyMalignantTumorsList.size()>0) {
                    chemotherapyMalignantTumorsNum=Long.valueOf(chemotherapyMalignantTumorsList.size());
                }
                //出院人数
                    if(startCount!=null){
                        medIndexResult.setAdmissionResult(Double.valueOf(startCount));
                    }
                //手术完成人数为
                    if (operationFeeNum != null) {
                        medIndexResult.setOperationResult(Double.valueOf(operationFeeNum));
                    }
                //CT人数
                    if (CTNum != null) {
                        medIndexResult.setCtResult(Double.valueOf(CTNum));
                    }
                //MRI人数
                    if (MRNum != null ) {
                        medIndexResult.setMriResult(Double.valueOf(MRNum));
                    }
                 //病理人数
                    if (operationPathologyFeeNum != null) {
                        medIndexResult.setPathologyResult(Double.valueOf(operationPathologyFeeNum));
                    }
                 //细菌培养人数
                    if (bacterialCultureNum != null) {
                        medIndexResult.setGermResult(Double.valueOf(bacterialCultureNum));
                    }
                //抗菌人数
                    if (antibiosisFeeNum != null ) {
                        medIndexResult.setAntibiosisResult(Double.valueOf(antibiosisFeeNum));
                    }
                //恶性肿瘤化学治疗人数
                    if (chemotherapyMalignantTumorsNum != null ) {
                        medIndexResult.setTumorChemistryResult(Double.valueOf(chemotherapyMalignantTumorsNum));
                    }

        /**
         * ================================保存数据-标示线========================================
         */
        MedIndexFilterVO timeVo = new MedIndexFilterVO();
        BeanUtils.copyProperties(filterVO,timeVo);
        timeTrans(timeVo);
            Set<String> rescueCode = new CopyOnWriteArraySet<>();
            Set<String> bloodCode = new CopyOnWriteArraySet<>();
        //指标二十七
        //指标14--恶性肿瘤放射治疗记录符合率
        Set<String> tumorRadiationSet = tumorRadiationMethods(adviceNum, medIndexResult);

        //指标15 手术记录
        medIndexResult.setOperationCompleteResult(Double.parseDouble(operationFeeNum+""));

        //指标16--植入物相关记录符合率
        Set<String> implantsCode = implantsMethods(filterVO, medIndexResult);

        //指标17  临床用血相关记录符合率
        bloodMethods(doctorAdviceMedManageParams, filterVO,medIndexResult,bloodCode);

        //指标18 医师查房记录 查询直接返回 -code需要加载

        //指标19 抢救记录
        rescueMethods(doctorAdviceMedManageParams,medIndexResult,rescueCode);

        //指标20 出院患者病历2日归档
        getfileSecAmounts(filterVO,medIndexResult);

        //指标21 出院患者病历归档完整率
        fileCompleteMethods(filterVO,medIndexResult);

        //指标22 不合理复制病历发生率 查询直接返回

        //指标23  知情同意书规范签署率 //分子通过规则
       // contentSignMethods(contentFile,medIndexResult);

        //指标24 甲级率 查询直接返回


        medIndexResult.setHospitalId(filterVO.getHospitalId());
        medIndexResult.setStartDate(filterVO.getStartDate());
        medIndexResult.setEndDate(filterVO.getEndDate());
        medIndexResult.setGmtCreate(new Date());
        medIndexResultFacade.save(medIndexResult);
        Integer id = medIndexResult.getId();
        MedIndexRelevance medIndexRelevance = new MedIndexRelevance();
        medIndexRelevance.setIndexResultId(id);
        medIndexRelevance.setHospitalId(filterVO.getHospitalId());
        medIndexRelevance.setStartDate(filterVO.getStartDate());
        medIndexRelevance.setEndDate(filterVO.getEndDate());
        medIndexRelevance.setGmtCreate(new Date());
            if(outHospitalCode.size()>0&&outHospitalCode!=null) {
                medIndexRelevance.setRelevanceType(4);
                for (String Code : outHospitalCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
                medIndexRelevance.setRelevanceType(6);
                for (String Code : outHospitalCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
                medIndexRelevance.setRelevanceType(7);
                for (String Code : outHospitalCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(operationCode.size()>0&&operationCode!=null) {
                medIndexRelevance.setRelevanceType(5);
                for (String Code : operationCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
        if(ctList!=null&&ctList.size()>0) {
            medIndexRelevance.setRelevanceType(8);
            for (String CTCode : ctList) {
                medIndexRelevance.setBehospitalCode(CTCode);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
        if(mrList!=null&&mrList.size()>0) {
            medIndexRelevance.setRelevanceType(9);
            for (String MrCode : mrList) {
                medIndexRelevance.setBehospitalCode(MrCode);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
            if(operationPathologyCode.size()>0&&operationPathologyCode!=null) {
                medIndexRelevance.setRelevanceType(10);
                for (String Code : operationPathologyCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(bacterialCultureList!=null&&bacterialCultureList.size()>0) {
                medIndexRelevance.setRelevanceType(11);
                for (String Code : bacterialCultureList) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(antibiosisCode.size()>0&&antibiosisCode!=null) {
                medIndexRelevance.setRelevanceType(12);
                for (String Code : antibiosisCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(chemotherapyMalignantTumorsList!=null&&chemotherapyMalignantTumorsList.size()>0) {
                medIndexRelevance.setRelevanceType(13);
                for (String Code : chemotherapyMalignantTumorsList) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
        if(tumorRadiationSet.size()>0 && tumorRadiationSet != null) {
            medIndexRelevance.setRelevanceType(14);
            for (String Code : tumorRadiationSet) {
                medIndexRelevance.setBehospitalCode(Code);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
            if(operationCode.size() > 0 && operationCode != null) {
                medIndexRelevance.setRelevanceType(15);
                for (String Code : operationCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
        if(implantsCode.size() > 0 && implantsCode != null) {
            medIndexRelevance.setRelevanceType(16);
            for (String Code : implantsCode) {
                medIndexRelevance.setBehospitalCode(Code);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
            if(bloodCode.size() > 0 && bloodCode != null) {
                medIndexRelevance.setRelevanceType(17);
                for (String Code : bloodCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(outHospitalCode.size() > 0 && outHospitalCode != null) {
                medIndexRelevance.setRelevanceType(18);
                for (String Code : outHospitalCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
            if(rescueCode.size() > 0 && rescueCode != null) {
                medIndexRelevance.setRelevanceType(19);
                for (String Code : rescueCode) {
                    medIndexRelevance.setBehospitalCode(Code);
                    medIndexRelevanceFacade.save(medIndexRelevance);
                }
            }
        if(outHospitalCode.size() > 0 && outHospitalCode != null) {
            medIndexRelevance.setRelevanceType(22);
            for (String Code : outHospitalCode) {
                medIndexRelevance.setBehospitalCode(Code);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
        if(outHospitalCode.size() > 0 && outHospitalCode != null) {
            medIndexRelevance.setRelevanceType(23);
            for (String Code : outHospitalCode) {
                medIndexRelevance.setBehospitalCode(Code);
                medIndexRelevanceFacade.save(medIndexRelevance);
            }
        }
        }
    /**
     * 两数据相除得到百分比
     * @param i
     * @param y
     * @return
     */
    public String getResult(double i , Double y){
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);
        if(String.valueOf(y).equals("0.0")){
            return "0.00%";
        }
        String k= df.format((i * 100.00) / y) + "%";
        return k;
    }
    /**
     * 获取无病案首页病人code
     * @param filterVO
     * @return
     */
    public List<String>  adviceVerify(FilterVO filterVO){
        List<Map<String, String>> medicalRecords = behospitalInfoFacade.getMedicalRecords(filterVO);
        List<String> behospitalCodeList = new CopyOnWriteArrayList<>();
        for (Map<String, String> medicalRecord : medicalRecords) {
            String behospitalCode = medicalRecord.get("behospital_code");
                behospitalCodeList.add(behospitalCode);
        }
        return behospitalCodeList;
    }
    /**
     * 医嘱二级条件判断 或且
     * @param name
     * @param arg
     * @return
     */
    public Boolean  secondLevelCondition(String name,String[][] arg){
        for (int i = 0; i < arg.length; i++) {
            String[] strings = arg[i];
            int z=0;
            for (int y = 0; y < strings.length; y++) {
                if(name.contains(strings[y])){
                    z++;
                }
            }
            if(z==strings.length){
                return  false;
            }else {
               continue;
            }
        }
        return true;
    }
    /**
     * 一级条件判断 或且
     * @param name
     * @param arg
     * @return
     */
    public Boolean  stairCondition(String name,String[][] arg){
        for (int i = 0; i < arg.length; i++) {
            String[] strings = arg[i];
            int z=0;
            for (int y = 0; y < strings.length; y++) {
                if(name.contains(strings[y])){
                    z++;
                }
            }
            if(z==strings.length){
                return true;
            }else {
                continue;
            }
        }
        return false;
    }
    /**
     * 遍历医嘱信息存入相关数据
     */
    public Map<String,Set<String>> getAdviceNum(FilterVO filterVO, List<MedManageParamsDTO> doctorAdviceMedManageParamsList) {
        CopyOnWriteArrayList<MedManageParamsDTO> doctorAdviceMedManageParams = new CopyOnWriteArrayList<>(doctorAdviceMedManageParamsList);
        String indexName = filterVO.getIndexName();
        Map mapCode = new HashMap<String,List<String>>();
        Set<String> CTBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> operationPathologyBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> MRBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> operationBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> pathologyBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> bacterialCultureCode = new CopyOnWriteArraySet<>();
        Set<String> antibiosisBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> chemotherapyMalignantTumorsBehospitalCode = new CopyOnWriteArraySet<>();
        Set<String> tumorRadiationBehospitalCode = new CopyOnWriteArraySet<>();
        //无首页code
        List<String> behospitalCodeList = adviceVerify(filterVO);
        //首页为肿瘤code
        List<String> malignancyCodeList = getMalignancyCode(filterVO);
        ForkJoinPool myPool = new ForkJoinPool(6);
        try {
            myPool.submit(() ->
            doctorAdviceMedManageParams.parallelStream().forEach(adviceMedManageParam->{
                String daItemName = adviceMedManageParam.getDaItemName();
                String behospitalCode = adviceMedManageParam.getBehospitalCode();
                String doctorAdviceType = adviceMedManageParam.getDoctorAdviceType();
                String daStatus = adviceMedManageParam.getDaStatus();
                if(StringUtil.isEmpty(daStatus) || (!daStatus.equals(QualityContent.CANCELLATION_ORDER) && StringUtil.isNotEmpty(daStatus))){
                    //得到与手术相关
                    if (StringUtil.isNotEmpty(daItemName)) {
                        if (QualityContent.NORecord_NEED_MEDICAL_ADVICE.contains(indexName)) {
                            //当code存在于无首页code集合中
                            if (behospitalCodeList.contains(behospitalCode)) {
                                //code也不存在于以保存的code集合
                                //手术
                                if (indexName.equals(QualityContent.SSJL_24H_WCL) || indexName.equals(QualityContent.BL_JCJL_FHL) || indexName.equals(QualityContent.QB)) {
                                    if (!operationBehospitalCode.contains(behospitalCode)) {
                                        String[][] operationList = QualityContent.OPERATION_LIST;
                                        Boolean stair = stairCondition(daItemName, operationList);
                                        if (stair) {
                                            String[][] operationArg = QualityContent.OPERATION_ARG;
                                            Boolean levelCondition = secondLevelCondition(daItemName, operationArg);
                                            if (levelCondition) {
                                                operationBehospitalCode.add(behospitalCode);
                                            }
                                        }
                                    }
                                }
                                //手术病理
                                if (indexName.equals(QualityContent.BL_JCJL_FHL) || indexName.equals(QualityContent.QB)) {
                                    if (!pathologyBehospitalCode.contains(behospitalCode)) {
                                        Boolean condition = stairCondition(daItemName, QualityContent.BL_LIST);
                                        if (condition) {
                                            pathologyBehospitalCode.add(behospitalCode);
                                        }
                                    }
                                }
                                //取临时和长期
                                if (doctorAdviceType.equals(QualityContent.STAT_ORDER) || doctorAdviceType.equals(QualityContent.STANDING_ORDER)) {
                                    //抗菌药物
                                    if (indexName.equals(QualityContent.KJYW_SY_FHL) || indexName.equals(QualityContent.QB)) {
                                        if (!antibiosisBehospitalCode.contains(behospitalCode)) {
                                            List<String> antimicrobialDrugList = QualityContent.Antimicrobial_Drug_List;
                                            for (String antimicrobialDrug : antimicrobialDrugList) {
                                                if (daItemName.contains(antimicrobialDrug)) {
                                                    //包含抗菌药物
                                                    antibiosisBehospitalCode.add(behospitalCode);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //得到为临时医嘱
                        if (StringUtil.isNotEmpty(doctorAdviceType)) {
                            if (doctorAdviceType.equals(QualityContent.STAT_ORDER)) {
                                if (indexName.equals(QualityContent.CT_JCJL_FHL) || indexName.equals(QualityContent.QB)) {
                                    if (!CTBehospitalCode.contains(behospitalCode)) {
                                        //筛选与CT相关
                                        //一级条件
                                        String[][] ctList = QualityContent.CT_LIST;
                                        Boolean stair = stairCondition(daItemName, ctList);
                                        if (stair) {
                                            String[][] ctRegulation = QualityContent.CT_REGULATION;
                                            Boolean levelCondition = secondLevelCondition(daItemName, ctRegulation);
                                            if (levelCondition) {
                                                CTBehospitalCode.add(behospitalCode);
                                            }
                                        }
                                    }
                                }
                                //与MR相关
                                if (indexName.equals(QualityContent.MR_JCJL_FHL) || indexName.equals(QualityContent.QB)) {
                                    if (!MRBehospitalCode.contains(behospitalCode)) {
                                        String[][] mrList = QualityContent.MR_LIST;
                                        Boolean stair = stairCondition(daItemName, mrList);
                                        if (stair) {
                                            String[][] mrRegulation = QualityContent.MR_REGULATION;
                                            Boolean levelCondition = secondLevelCondition(daItemName, mrRegulation);
                                            if (levelCondition) {
                                                MRBehospitalCode.add(behospitalCode);
                                            }
                                        }
                                    }
                                }
                                //细菌培养
                                if (indexName.equals(QualityContent.XJPY_JCJL_FHL) || indexName.equals(QualityContent.QB)) {
                                    if(!bacterialCultureCode.contains(behospitalCode)){
                                        if(daItemName.contains(QualityContent.BACTERIAL_CULTURE)){
                                            bacterialCultureCode.add(behospitalCode);
                                        }
                                    }
                                }
                            }
                        }
                        //获取为长期医嘱或临时医嘱的医嘱
                        if (StringUtil.isNotEmpty(doctorAdviceType)) {
                            if (indexName.equals(QualityContent.EXZL_HXZL_FHL) || indexName.equals(QualityContent.QB)) {
                                if (ListUtil.isNotEmpty(malignancyCodeList)) {
                                    if (malignancyCodeList.contains(behospitalCode)) {
                                        if (!chemotherapyMalignantTumorsBehospitalCode.contains(behospitalCode)) {
                                            if (doctorAdviceType.equals(QualityContent.STAT_ORDER) || doctorAdviceType.equals(QualityContent.STANDING_ORDER)) {
                                                List<String> chemotherapyDrugList = QualityContent.Chemotherapy_Drug_List;
                                                for (String chemotherapyDrug : chemotherapyDrugList) {
                                                    if (daItemName.contains(chemotherapyDrug)) {
                                                        //医嘱含有化疗药物
                                                        chemotherapyMalignantTumorsBehospitalCode.add(behospitalCode);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            if (indexName.equals(QualityContent.EXZL_FSZL_FHL) || indexName.equals(QualityContent.QB)) {
                                if (ListUtil.isNotEmpty(malignancyCodeList)) {
                                    if (malignancyCodeList.contains(behospitalCode)) {
                                        if (!tumorRadiationBehospitalCode.contains(behospitalCode)) {
                                            if (doctorAdviceType.equals(QualityContent.STAT_ORDER) || doctorAdviceType.equals(QualityContent.STANDING_ORDER)) {
                                                List<String> tumorRadiationDrugList = QualityContent.radiotherapyDrugList;
                                                for (String tumorRadiationDrug : tumorRadiationDrugList) {
                                                    if (daItemName.contains(tumorRadiationDrug)) {
                                                        //医嘱含有放射治疗药物
                                                        tumorRadiationBehospitalCode.add(behospitalCode);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        })).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            myPool.shutdown();

            if(CTBehospitalCode !=null && CTBehospitalCode.size()>0){
                mapCode.put("CT",CTBehospitalCode);
            }else {
                mapCode.put("CT",null);
            }
            if(MRBehospitalCode!=null && MRBehospitalCode.size()>0){
                mapCode.put("MR",MRBehospitalCode);
            }else {
                mapCode.put("MR",null);
            }
            if(operationBehospitalCode!=null && operationBehospitalCode.size()>0){
                mapCode.put("operation",operationBehospitalCode);
            }else {
                mapCode.put("operation",null);
            }
            if((operationBehospitalCode!=null)&&(pathologyBehospitalCode!=null&&pathologyBehospitalCode.size()>0)){
                for (String operation : operationBehospitalCode) {
                    if(pathologyBehospitalCode.contains(operation)){
                        operationPathologyBehospitalCode.add(operation);
                    }
                }
                mapCode.put("operationPathology",operationPathologyBehospitalCode);
            }else {
                mapCode.put("operationPathology",null);
            }
            if(bacterialCultureCode!=null && bacterialCultureCode.size()>0){
                mapCode.put("bacterialCulture",bacterialCultureCode);

            }else {
                mapCode.put("bacterialCulture",null);
            }
            if(antibiosisBehospitalCode!=null && antibiosisBehospitalCode.size()>0){
                mapCode.put("antibiosis",antibiosisBehospitalCode);
            }else {
                mapCode.put("antibiosis",null);
            }
            if(chemotherapyMalignantTumorsBehospitalCode!=null && chemotherapyMalignantTumorsBehospitalCode.size()>0){
                mapCode.put("chemotherapyMalignantTumors",chemotherapyMalignantTumorsBehospitalCode);
            }else {
                mapCode.put("chemotherapyMalignantTumors",null);
            }
            if(tumorRadiationBehospitalCode!=null && tumorRadiationBehospitalCode.size()>0){
                mapCode.put("tumorRadiationSecNum",tumorRadiationBehospitalCode);
            }else {
                mapCode.put("tumorRadiationSecNum",null);
            }
            return mapCode;
        }
    }
    /**
     * 获取首页为恶性肿瘤病历code
     */
    public List<String> getMalignancyCode(FilterVO filterVO){
        List<Map<String,String>> malignancyCodeList = behospitalInfoFacade.malignancy(filterVO);
        ArrayList<String> arrayList = new ArrayList<>();
        if(ListUtil.isNotEmpty(malignancyCodeList)) {
            for (Map<String, String> map : malignancyCodeList) {
                String behospitalCode = map.get("behospital_code");
                arrayList.add(behospitalCode);
            }
        }
        return arrayList;
    }

    /**
     * 质控病历统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> mrCount(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> mrCountList = mrStatisticsAggregate.mrCount(filterVO);
        if (ListUtil.isNotEmpty(mrCountList)) {
            retMap.put("病历数统计", mrCountList);
        }
        return retMap;
    }

    /**
     * 各模块缺陷占比排行
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> entryCountGroupByCase(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> caseList = resultStatisticsAggregate.entryCountGroupByCase(filterVO);
        if (ListUtil.isNotEmpty(caseList)) {
            retMap.put("各模块缺陷占比排行", caseList);
        }
        return retMap;
    }

    /**
     * 条目缺陷占比
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> entryCountGroupByEntry(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> entryList = resultStatisticsAggregate.entryCountGroupByEntry(filterVO);
        if (ListUtil.isNotEmpty(entryList)) {
            retMap.put("条目缺陷占比", entryList);
        }
        return retMap;
    }

    /**
     * 单项否决缺陷占比
     *
     * @param filterVO
     * @return
     */
    public List<EntryNumDTO> entryRejectPercent(FilterVO filterVO) {
        List<EntryNumDTO> retList = Lists.newLinkedList();
        filterFacade.filterVOSet(filterVO);
        Integer limitCount = filterVO.getLimitCount();
        List<EntryNumDTO> numDTOList = qcresultInfoFacade.entryRejectPercent(filterVO);
        if (ListUtil.isNotEmpty(numDTOList)) {
            if (numDTOList.size() <= limitCount) {
                retList = numDTOList;
            } else {
                retList = numDTOList.subList(0, limitCount);
            }
        }
        return retList;
    }

    /**
     * 各科室甲/乙/丙级病历占比
     *
     * @param filterVO
     * @return
     */
    public List<DeptNumDTO> qcResultLevelPercent(FilterVO filterVO) {
        if (StringUtil.isBlank(filterVO.getLevel())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "请输入病历等级");
        }
        List<DeptNumDTO> retList = Lists.newLinkedList();
        filterFacade.filterVOSet(filterVO);
        Integer limitCount = filterVO.getLimitCount();
        List<DeptNumDTO> numDTOList = qcresultInfoFacade.qcResultLevelPercent(filterVO);
        if (ListUtil.isNotEmpty(numDTOList)) {
            if (numDTOList.size() <= limitCount) {
                retList = numDTOList;
            } else {
                retList = numDTOList.subList(0, limitCount);
            }
        }
        return retList;
    }

    /**
     * 各科室缺陷占比
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> entryByDept(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> deptList = resultStatisticsAggregate.entryByDept(filterVO);
        if (ListUtil.isNotEmpty(deptList)) {
            retMap.put("各科室缺陷占比", deptList);
        }
        return retMap;
    }
    //endregion-----------------------单独接口结束-------------------------------

    //region_______________________分页接口开始-------------------------------


    /**
     * 各模块缺陷占比（分页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<NumDTO> entryCountGroupByCasePage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        IPage<NumDTO> page = qcresultInfoFacade.entryCountGroupByCasePage(filterPageVO);
        return page;
    }

    /**
     * 缺陷详情（分页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<EntryNumGroupDTO> entryCountGroupByEntryPage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        if (filterPageVO.getDeptName().equals("全院")) {
            filterPageVO.setDeptName("");
        }
        IPage<EntryNumGroupDTO> page = qcresultInfoFacade.entryCountGroupByEntryPage(filterPageVO);
        return page;
    }

    /**
     * 按科室统计平均住院天数（分页）
     *
     * @param filterPageByAverageVO
     * @return
     */
    public IPage<AverageStatisticsDTO> getAverageDayNumPage(FilterPageByAverageVO filterPageByAverageVO) {
        filterFacade.filterPageByAverageVOSet(filterPageByAverageVO);
        IPage<AverageStatisticsDTO> page = homePageFacade.getAverageDayNumPage(filterPageByAverageVO);
        return page;
    }

    /**
     * 按科室统计平均住院费用（分页）
     *
     * @param filterPageByAverageVO
     * @return
     */
    public IPage<AverageStatisticsFeeDTO> getAverageFeePage(FilterPageByAverageVO filterPageByAverageVO) {
        filterFacade.filterPageByAverageVOSet(filterPageByAverageVO);
        IPage<AverageStatisticsFeeDTO> page = homePageFacade.getAverageFeePage(filterPageByAverageVO);
        return page;
    }

    /**
     * 各科室质控平均分（分页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<AverageStatisticsDTO> getAverageScoreByDeptPage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        IPage<AverageStatisticsDTO> page = qcresultInfoFacade.getAverageScoreByDeptPage(filterPageVO);
        return page;
    }

    /**
     * 各科室缺陷占比排行（分页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<NumDTO> resultStatisticsByDeptPage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        IPage<NumDTO> page = behospitalInfoFacade.resultStatisticsByDeptPage(filterPageVO);
        return page;
    }

    /**
     * 各科室甲级病历占比排行（分页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<QcResultPercentDTO> levelPercentGroupByDeptPage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        IPage<QcResultPercentDTO> page = qcresultInfoFacade.levelPercentGroupByDeptPage(filterPageVO);
        return page;
    }

    /**
     * 条目缺陷占比（内页）
     *
     * @param filterPageVO
     * @return
     */
    public IPage<EntryNumDTO> entryGroupByEntryInnerPage(FilterPageVO filterPageVO) {
        filterFacade.filterPageVOSet(filterPageVO);
        IPage<EntryNumDTO> page = qcresultInfoFacade.entryGroupByEntryInnerPage(filterPageVO);
        return page;
    }
    //endregion-----------------------分页接口结束-------------------------------

    /**
     * 各科室缺陷占比（组合）
     *
     * @param filterOrderVO
     * @return
     */
    public List<LevelStatisticsDTO> levelStatistics(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSame(filterOrderVO);
        List<LevelStatisticsDTO> records = behospitalInfoFacade.levelStatistics(filterOrderVO);
        //没有科室过滤时增加全院数据
        if (StringUtil.isBlank(filterOrderVO.getDeptName()) || filterOrderVO.getDeptName().equals("全院")) {
            LevelStatisticsDTO item = getGlobleTitle(records);
            if (item != null) {
                records.add(0, item);
            }
        }
        if (ListUtil.isNotEmpty(records)) {
            for (LevelStatisticsDTO record : records) {
                BigDecimalMethod(record);
            }
        }
        return records;
    }

    /**
     * 各科室缺陷占比（组合）-导出
     *
     * @param filterOrderVO
     * @return
     */
    public List<LevelStatisticsDTO> levelStatisticsStr(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSame(filterOrderVO);
        List<LevelStatisticsDTO> records = behospitalInfoFacade.levelStatistics(filterOrderVO);
        //没有科室过滤时增加全院数据
        if (StringUtil.isBlank(filterOrderVO.getDeptName()) || filterOrderVO.getDeptName().equals("全院")) {
            LevelStatisticsDTO item = getGlobleTitle(records);
            if (item != null) {
                records.add(0, item);
            }
        }
        if (ListUtil.isNotEmpty(records)) {
            for (LevelStatisticsDTO record : records) {
                BigDecimalStrExport(record);
            }
        }
        return records;
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public LevelStatisticsDTO getGlobleTitle(List<LevelStatisticsDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        LevelStatisticsDTO item = new LevelStatisticsDTO();
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //缺陷总数
        Integer entryNum = records
                .stream()
                .map(LevelStatisticsDTO::getEntryNum)
                .reduce(0, Integer::sum);
        if (entryNum == null || entryNum == 0) {
            return null;
        }
        //同比总数
        Integer sameNum = records
                .stream()
                .map(LevelStatisticsDTO::getSameNum)
                .reduce(0, Integer::sum);

        //质控病历数
        Integer mrNum = records
                .stream()
                .map(LevelStatisticsDTO::getMrNum)
                .reduce(0, Integer::sum);
        //同比病历数
        Integer sameMrNum = records
                .stream()
                .map(LevelStatisticsDTO::getSameMrNum)
                .reduce(0, Integer::sum);

        //质控评分
        Double totleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();
        //同比质控评分
        Double sameTotleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getSameTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        //质控平均分
        Double averageValue = BigDecimal.valueOf(totleValue)
                .divide(BigDecimal.valueOf(mrNum), 2, RoundingMode.HALF_UP)
                .doubleValue();

        Double sameAvgValue = 0d;
        //同比平均分
        if (0d != sameTotleValue) {
            sameAvgValue = BigDecimal.valueOf(sameTotleValue)
                    .divide(BigDecimal.valueOf(sameMrNum), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }


        //甲级病历数
        Integer firstLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getFirstLevelNum)
                .reduce(0, Integer::sum);

        //同比甲级病历数
        Integer sameFirstLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getSameFirstLevelNum)
                .reduce(0, Integer::sum);


        //乙级病历数
        Integer secondLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getSecondLevelNum)
                .reduce(0, Integer::sum);

        //同比乙级病历数
        Integer sameSecondLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getSameSecondLevelNum)
                .reduce(0, Integer::sum);


        //丙级病历数
        Integer thirdLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getThirdLevelNum)
                .reduce(0, Integer::sum);

        //同比丙级病历数
        Integer sameThirdLevelNum = records
                .stream()
                .map(LevelStatisticsDTO::getSameThirdLevelNum)
                .reduce(0, Integer::sum);


        //甲级病历占比
        Double firstLevelPercent = BigDecimal.valueOf(firstLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String firstLevelPercentStr
                = df.format(BigDecimal.valueOf(firstLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //同比甲级病历占比
        Double sameFirstLevelPercent = 0d;
        String sameFirstLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameFirstLevelPercent = BigDecimal.valueOf(sameFirstLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameFirstLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameFirstLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }


        //乙级病历占比
        Double secondLevelPercent = BigDecimal.valueOf(secondLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String secondLevelPercentStr
                = df.format(BigDecimal.valueOf(secondLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";

        //同比乙级病历占比
        Double sameSecondLevelPercent = 0d;
        String sameSecondLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameSecondLevelPercent = BigDecimal.valueOf(sameSecondLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameSecondLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameSecondLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }
        //丙级病历占比
        Double thirdLevelPercent = BigDecimal.valueOf(thirdLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String thirdLevelPercentStr
                = df.format(BigDecimal.valueOf(thirdLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";

        //同比丙级病历占比
        Double sameThirdLevelPercent = 0d;
        String sameThirdLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameThirdLevelPercent = BigDecimal.valueOf(sameThirdLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameThirdLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameThirdLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }
        item.setDeptName("全院");
        item.setEntryNum(entryNum);
        item.setSameNum(sameNum);
        item.setMrNum(mrNum);
        item.setSameMrNum(sameMrNum);
        item.setTotleValue(totleValue);
        item.setSameTotleValue(sameTotleValue);
        item.setAverageValue(averageValue);
        item.setSameAvgValue(sameAvgValue);
        item.setFirstLevelNum(firstLevelNum);
        item.setSameFirstLevelNum(sameFirstLevelNum);
        item.setFirstLevelPercent(firstLevelPercent);
        item.setSameFirstLevelPercent(sameFirstLevelPercent);
        item.setFirstLevelPercentStr(firstLevelPercentStr);
        item.setSameFirstLevelPercentStr(sameFirstLevelPercentStr);
        item.setSecondLevelNum(secondLevelNum);
        item.setSameSecondLevelNum(sameSecondLevelNum);
        item.setSecondLevelPercent(secondLevelPercent);
        item.setSameSecondLevelPercent(sameSecondLevelPercent);
        item.setSecondLevelPercentStr(secondLevelPercentStr);
        item.setSameSecondLevelPercentStr(sameSecondLevelPercentStr);
        item.setThirdLevelNum(thirdLevelNum);
        item.setSameThirdLevelNum(sameThirdLevelNum);
        item.setThirdLevelPercent(thirdLevelPercent);
        item.setSameThirdLevelPercent(sameThirdLevelPercent);
        item.setThirdLevelPercentStr(thirdLevelPercentStr);
        item.setSameThirdLevelPercentStr(sameThirdLevelPercentStr);
        return item;
    }

    /**
     * 各科室缺陷占比（组合）-全院-根据内外科系统统计（台州）-导出
     *
     * @param filterOrderVO
     * @return
     */
    public List<LevelStatisticsTZDTO> levelStatisticsByDeptStr_TZ(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSame(filterOrderVO);
        List<LevelStatisticsTZDTO> records = behospitalInfoFacade.levelStatisticsByDeptClass_TZ(filterOrderVO);
        if (StringUtil.isBlank(filterOrderVO.getDeptName())) {
            LevelStatisticsTZDTO item = getGlobleRecords(records, filterOrderVO);
            if (item != null) {
                records.add(0, item);
            }
        }
        if (ListUtil.isNotEmpty(records)) {
            for (LevelStatisticsTZDTO record : records) {
                BigDecimalStrExport(record);
            }
        }

        return records;
    }

    /**
     * 各科室缺陷占比（组合）-全院-根据内外科系统统计（台州）
     *
     * @param filterOrderVO
     * @return
     */
    public List<LevelStatisticsTZDTO> levelStatisticsByDeptClass_TZ(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSame(filterOrderVO);
        List<LevelStatisticsTZDTO> records = behospitalInfoFacade.levelStatisticsByDeptClass_TZ(filterOrderVO);
        if (StringUtil.isBlank(filterOrderVO.getDeptName())) {
            LevelStatisticsTZDTO item = getGlobleRecords(records, filterOrderVO);
            if (item != null) {
                records.add(0, item);
            }
        }


        if (ListUtil.isNotEmpty(records)) {
            for (LevelStatisticsTZDTO record : records) {
                BigDecimalMethod(record);
            }
        }

        return records;
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public LevelStatisticsTZDTO getGlobleRecords(List<LevelStatisticsTZDTO> records, FilterOrderVO filterOrderVO) {
        DecimalFormat df = new DecimalFormat("#0.00");
        LevelStatisticsTZDTO item = new LevelStatisticsTZDTO();
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //缺陷总数
        Integer entryNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getEntryNum)
                .reduce(0, Integer::sum);
        if (entryNum == null || entryNum == 0) {
            return null;
        }
        //同比总数
        Integer sameNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSameNum)
                .reduce(0, Integer::sum);

        //质控病历数
        Integer mrNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getMrNum)
                .reduce(0, Integer::sum);
        //同比病历数
        Integer sameMrNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSameMrNum)
                .reduce(0, Integer::sum);

        //质控评分
        Double totleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();
        //同比质控评分
        Double sameTotleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getSameTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();

        //质控平均分
        Double averageValue = BigDecimal.valueOf(totleValue)
                .divide(BigDecimal.valueOf(mrNum), 2, RoundingMode.HALF_UP)
                .doubleValue();

        Double sameAvgValue = 0d;
        //同比平均分
        if (0d != sameTotleValue) {
            sameAvgValue = BigDecimal.valueOf(sameTotleValue)
                    .divide(BigDecimal.valueOf(sameMrNum), 2, RoundingMode.HALF_UP)
                    .doubleValue();
        }


        //甲级病历数
        Integer firstLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getFirstLevelNum)
                .reduce(0, Integer::sum);

        //同比甲级病历数
        Integer sameFirstLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSameFirstLevelNum)
                .reduce(0, Integer::sum);


        //乙级病历数
        Integer secondLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSecondLevelNum)
                .reduce(0, Integer::sum);

        //同比乙级病历数
        Integer sameSecondLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSameSecondLevelNum)
                .reduce(0, Integer::sum);


        //丙级病历数
        Integer thirdLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getThirdLevelNum)
                .reduce(0, Integer::sum);

        //同比丙级病历数
        Integer sameThirdLevelNum = records
                .stream()
                .map(LevelStatisticsTZDTO::getSameThirdLevelNum)
                .reduce(0, Integer::sum);


        //甲级病历占比
        Double firstLevelPercent = BigDecimal.valueOf(firstLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String firstLevelPercentStr
                = df.format(BigDecimal.valueOf(firstLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //同比甲级病历占比
        Double sameFirstLevelPercent = 0d;
        String sameFirstLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameFirstLevelPercent = BigDecimal.valueOf(sameFirstLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameFirstLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameFirstLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }


        //乙级病历占比
        Double secondLevelPercent = BigDecimal.valueOf(secondLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String secondLevelPercentStr
                = df.format(BigDecimal.valueOf(secondLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";

        //同比乙级病历占比
        Double sameSecondLevelPercent = 0d;
        String sameSecondLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameSecondLevelPercent = BigDecimal.valueOf(sameSecondLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameSecondLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameSecondLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }
        //丙级病历占比
        Double thirdLevelPercent = BigDecimal.valueOf(thirdLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String thirdLevelPercentStr
                = df.format(BigDecimal.valueOf(thirdLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";

        //同比丙级病历占比
        Double sameThirdLevelPercent = 0d;
        String sameThirdLevelPercentStr = "0.00%";
        if (0 != sameFirstLevelNum) {
            sameThirdLevelPercent = BigDecimal.valueOf(sameThirdLevelNum)
                    .divide(BigDecimal.valueOf(sameMrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            sameThirdLevelPercentStr
                    = df.format(BigDecimal.valueOf(sameThirdLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        }
        if (StringUtil.isBlank(filterOrderVO.getDeptClass()) || filterOrderVO.getDeptClass().equals("全院")) {
            item.setDeptName("全院");
        } else if ("内科".equals(filterOrderVO.getDeptClass())) {
            item.setDeptClassId("01");
            item.setDeptClass("内科");
            item.setDeptName("全部科室");
        } else if ("外科".equals(filterOrderVO.getDeptClass())) {
            item.setDeptClassId("1030000");
            item.setDeptClass("外科");
            item.setDeptName("全部科室");
        }
        item.setEntryNum(entryNum);
        item.setSameNum(sameNum);
        item.setMrNum(mrNum);
        item.setSameMrNum(sameMrNum);
        item.setTotleValue(totleValue);
        item.setSameTotleValue(sameTotleValue);
        item.setAverageValue(averageValue);
        item.setSameAvgValue(sameAvgValue);
        item.setFirstLevelNum(firstLevelNum);
        item.setSameFirstLevelNum(sameFirstLevelNum);
        item.setFirstLevelPercent(firstLevelPercent);
        item.setSameFirstLevelPercent(sameFirstLevelPercent);
        item.setFirstLevelPercentStr(firstLevelPercentStr);
        item.setSameFirstLevelPercentStr(sameFirstLevelPercentStr);
        item.setSecondLevelNum(secondLevelNum);
        item.setSameSecondLevelNum(sameSecondLevelNum);
        item.setSecondLevelPercent(secondLevelPercent);
        item.setSameSecondLevelPercent(sameSecondLevelPercent);
        item.setSecondLevelPercentStr(secondLevelPercentStr);
        item.setSameSecondLevelPercentStr(sameSecondLevelPercentStr);
        item.setThirdLevelNum(thirdLevelNum);
        item.setSameThirdLevelNum(sameThirdLevelNum);
        item.setThirdLevelPercent(thirdLevelPercent);
        item.setSameThirdLevelPercent(sameThirdLevelPercent);
        item.setThirdLevelPercentStr(thirdLevelPercentStr);
        item.setSameThirdLevelPercentStr(sameThirdLevelPercentStr);
        return item;
    }


    public void BigDecimalStrExport(LevelStatisticsDTO record) {

        BigDecimal entrySameBigDecimal = getSubtract(new BigDecimal(record.getEntryNum()), new BigDecimal(record.getSameNum() == null ? 0 : record.getSameNum()));

        if (entrySameBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setEntryStrNum(record.getEntryNum() + "↑");
        } else if (entrySameBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setEntryStrNum(record.getEntryNum() + "↓");
        }

        BigDecimal sameMrNumBigDecimal = getSubtract(new BigDecimal(record.getMrNum()), new BigDecimal(record.getSameMrNum() == null ? 0 : record.getSameMrNum()));
        if (sameMrNumBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setMrStrNum(record.getMrNum() + "↑");
        } else if (sameMrNumBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setMrStrNum(record.getMrNum() + "↓");
        }

        BigDecimal sameAvgValueDecimal = getSubtract(new BigDecimal(record.getAverageValue()), new BigDecimal(record.getSameAvgValue() == null ? 0 : record.getSameAvgValue()));
        if (sameAvgValueDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setAverageStrValue(record.getAverageValue() + "↑");
        } else if (sameAvgValueDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setAverageStrValue(record.getAverageValue() + "↓");
        }

        BigDecimal SameFirstLevelBigDecimal = getSubtract(new BigDecimal(record.getFirstLevelNum()), new BigDecimal(record.getSameFirstLevelNum() == null ? 0 : record.getSameFirstLevelNum()));
        if (SameFirstLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setFirstLevelStrNum(record.getFirstLevelNum() + "↑");
        } else if (SameFirstLevelBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setFirstLevelStrNum(record.getFirstLevelNum() + "↓");
        }

        BigDecimal SameSecondLevelBigDecimal = getSubtract(new BigDecimal(record.getSecondLevelNum()), new BigDecimal(record.getSameSecondLevelNum() == null ? 0 : record.getSameSecondLevelNum()));
        if (SameSecondLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setSecondLevelStrNum(record.getSecondLevelNum() + "↑");
        } else if (SameSecondLevelBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setSecondLevelStrNum(record.getSecondLevelNum() + "↓");
        }

        BigDecimal SameThirdLevelBigDecimal = getSubtract(new BigDecimal(record.getThirdLevelNum()), new BigDecimal(record.getSameThirdLevelNum() == null ? 0 : record.getSameThirdLevelNum()));
        if (SameThirdLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setThirdLevelStrNum(record.getThirdLevelNum() + "↑");
        } else if (SameThirdLevelBigDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setThirdLevelStrNum(record.getThirdLevelNum() + "↓");
        }

        BigDecimal SameFirstLevelPeDecimal = getSubtract(new BigDecimal(record.getFirstLevelPercent()), new BigDecimal(record.getSameFirstLevelPercent() == null ? 0 : record.getSameFirstLevelPercent()));
        if (SameFirstLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setFirstLevelPercentStr(record.getFirstLevelPercentStr() + "↑");
        } else if (SameFirstLevelPeDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setFirstLevelPercentStr(record.getFirstLevelPercentStr() + "↓");
        }

        BigDecimal SameSecondLevelPeDecimal = getSubtract(new BigDecimal(record.getSecondLevelPercent()), new BigDecimal(record.getSameSecondLevelPercent() == null ? 0 : record.getSameSecondLevelPercent()));
        if (SameSecondLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setSecondLevelPercentStr(record.getSecondLevelPercentStr() + "↑");
        } else if (SameSecondLevelPeDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setSecondLevelPercentStr(record.getSecondLevelPercentStr() + "↓");
        }

        BigDecimal SameThirdLevelPeDecimal = getSubtract(new BigDecimal(record.getThirdLevelPercent()), new BigDecimal(record.getSameThirdLevelPercent() == null ? 0 : record.getSameThirdLevelPercent()));
        if (SameThirdLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setThirdLevelPercentStr(record.getThirdLevelPercentStr() + "↑");
        } else if (SameThirdLevelPeDecimal.compareTo(BigDecimal.ZERO) < 0) {
            record.setThirdLevelPercentStr(record.getThirdLevelPercentStr() + "↓");
        }
    }

    ;

    public void BigDecimalMethod(LevelStatisticsDTO record) {
        BigDecimal entrySameBigDecimal = getSubtract(new BigDecimal(record.getEntryNum()), new BigDecimal(record.getSameNum() == null ? 0 : record.getSameNum()));

        if (entrySameBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setEntrySameNum(1);
        } else if (entrySameBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setEntrySameNum(0);
        } else {
            record.setEntrySameNum(-1);
        }

        BigDecimal sameMrNumBigDecimal = getSubtract(new BigDecimal(record.getMrNum()), new BigDecimal(record.getSameMrNum() == null ? 0 : record.getSameMrNum()));
        if (sameMrNumBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setMrSameNum(1);
        } else if (sameMrNumBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setMrSameNum(0);
        } else {
            record.setMrSameNum(-1);
        }

        BigDecimal sameAvgValueDecimal = getSubtract(new BigDecimal(record.getAverageValue()), new BigDecimal(record.getSameAvgValue() == null ? 0 : record.getSameAvgValue()));
        if (sameAvgValueDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setAvSameValue(1);
        } else if (sameAvgValueDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setAvSameValue(0);
        } else {
            record.setAvSameValue(-1);
        }

        BigDecimal SameFirstLevelBigDecimal = getSubtract(new BigDecimal(record.getFirstLevelNum()), new BigDecimal(record.getSameFirstLevelNum() == null ? 0 : record.getSameFirstLevelNum()));
        if (SameFirstLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setFirSameLevelNum(1);
        } else if (SameFirstLevelBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setFirSameLevelNum(0);
        } else {
            record.setFirSameLevelNum(-1);
        }

        BigDecimal SameSecondLevelBigDecimal = getSubtract(new BigDecimal(record.getSecondLevelNum()), new BigDecimal(record.getSameSecondLevelNum() == null ? 0 : record.getSameSecondLevelNum()));
        if (SameSecondLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setSecSameLevelNum(1);
        } else if (SameSecondLevelBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setSecSameLevelNum(0);
        } else {
            record.setSecSameLevelNum(-1);
        }

        BigDecimal SameThirdLevelBigDecimal = getSubtract(new BigDecimal(record.getThirdLevelNum()), new BigDecimal(record.getSameThirdLevelNum() == null ? 0 : record.getSameThirdLevelNum()));
        if (SameThirdLevelBigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setThiSameLevelNum(1);
        } else if (SameThirdLevelBigDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setThiSameLevelNum(0);
        } else {
            record.setThiSameLevelNum(-1);
        }

        BigDecimal SameFirstLevelPeDecimal = getSubtract(new BigDecimal(record.getFirstLevelPercent()), new BigDecimal(record.getSameFirstLevelPercent() == null ? 0 : record.getSameFirstLevelPercent()));
        if (SameFirstLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setFirSameLevelPercent(1);
        } else if (SameFirstLevelPeDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setFirSameLevelPercent(0);
        } else {
            record.setFirSameLevelPercent(-1);
        }

        BigDecimal SameSecondLevelPeDecimal = getSubtract(new BigDecimal(record.getSecondLevelPercent()), new BigDecimal(record.getSameSecondLevelPercent() == null ? 0 : record.getSameSecondLevelPercent()));
        if (SameSecondLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setSecSameLevelPercent(1);
        } else if (SameSecondLevelPeDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setSecSameLevelPercent(0);
        } else {
            record.setSecSameLevelPercent(-1);
        }

        BigDecimal SameThirdLevelPeDecimal = getSubtract(new BigDecimal(record.getThirdLevelPercent()), new BigDecimal(record.getSameThirdLevelPercent() == null ? 0 : record.getSameThirdLevelPercent()));
        if (SameThirdLevelPeDecimal.compareTo(BigDecimal.ZERO) > 0) {
            record.setThiSameLevelPercent(1);
        } else if (SameThirdLevelPeDecimal.compareTo(BigDecimal.ZERO) == 0) {
            record.setThiSameLevelPercent(0);
        } else {
            record.setThiSameLevelPercent(-1);
        }
    }

    ;


    /**
     * 差值计算
     *
     * @param bigDecimalOne
     * @param bigDecimalTwo
     * @return
     */
    private BigDecimal getSubtract(BigDecimal bigDecimalOne, BigDecimal bigDecimalTwo) {
        BigDecimal newBigDecimal = new BigDecimal(0);
        if (null == bigDecimalOne && null != bigDecimalTwo) {
            newBigDecimal = newBigDecimal.subtract(bigDecimalTwo);
        } else if (null != bigDecimalOne && null == bigDecimalTwo) {
            newBigDecimal = bigDecimalOne.subtract(newBigDecimal);
        } else if (null != bigDecimalOne && null != bigDecimalTwo) {
            newBigDecimal = bigDecimalOne.subtract(bigDecimalTwo);
        }
        return newBigDecimal;
    }

    /**
     * 病案首页合格率占比
     *
     * @param filterOrderVO
     * @return
     */
    public List<HomePageNumDTO> homePageLevelStatistics(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSet(filterOrderVO);
        List<HomePageNumDTO> records = behospitalInfoFacade.homePageLevelStatistics(filterOrderVO);
        //没有科室过滤时增加全院数据
        if (StringUtil.isBlank(filterOrderVO.getDeptName()) || filterOrderVO.getDeptName().equals("全院")) {
            HomePageNumDTO item = getGlobleRecord(records);
            if (item != null) {
                records.add(0, item);
            }
        }
        return records;
    }

    /**
     * 病历质控报表-科室
     *
     * @param behospitalPageVO
     * @return
     */
    public IPage<QualityControlDTO> getQualityControlExport(BehospitalPageVO behospitalPageVO) {
        behospitalPageSet(behospitalPageVO);
        IPage<QualityControlDTO> records = behospitalInfoFacade.getQualityControl(behospitalPageVO);
        List<QualityControlDTO> qualityControlDTOs = records.getRecords();
        CaseScoreVO caseScoreVO = new CaseScoreVO();
        BeanUtil.copyProperties(behospitalPageVO, caseScoreVO);
        List<CaseScoreDTO> caseScoreDTOS = behospitalInfoFacade.getQualityCaseSorce(caseScoreVO);
        if (ListUtil.isNotEmpty(qualityControlDTOs)) {
            qualityControlDTOs.forEach(qualityControlDTO -> {
                if (ListUtil.isNotEmpty(caseScoreDTOS)) {
                    AlgorithmVO algorithmVO = new AlgorithmVO();
                    BeanUtil.copyProperties(behospitalPageVO, algorithmVO);
                    algorithmVO.setType(0);
                    List<QcResultAlgVO> qcResultAlgVOList = new ArrayList<QcResultAlgVO>();
                    for (CaseScoreDTO caseScoreDTO : caseScoreDTOS) {
                        if (StringUtils.isNotEmpty(qualityControlDTO.getBehospitalCode()) &&
                                StringUtils.isNotEmpty(caseScoreDTO.getBehospitalCode()) &&
                                qualityControlDTO.getBehospitalCode().equals(caseScoreDTO.getBehospitalCode())) {
                            QcResultAlgVO qcResultAlgVO = new QcResultAlgVO();
                            BeanUtil.copyProperties(caseScoreDTO, qcResultAlgVO);
                            qcResultAlgVO.setIsReject(Integer.valueOf(caseScoreDTO.getIsReject()));
                            qcResultAlgVO.setScore(new BigDecimal(caseScoreDTO.getScore()));
                            qcResultAlgVO.setCasesScore(new BigDecimal(caseScoreDTO.getCasesScore()));
                            qcResultAlgVOList.add(qcResultAlgVO);
                        }
                    }
                    algorithmVO.setType(0);
                    algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
                    getScoreForCx(algorithmVO, qualityControlDTO);
                }
                if (qualityControlDTO.getLevel().equals("未评分")) {
                    QualityControlNullDTO qualityControlNullDTO = new QualityControlNullDTO();
                    BeanUtil.copyProperties(qualityControlNullDTO, qualityControlDTO);
                }
            });
        }
        ;
        return records;
    }

    private void behospitalPageSet(BehospitalPageVO behospitalPageVO) {
        //入参验证
        //入院时间
        if (null != behospitalPageVO && null != behospitalPageVO.getBehosDateStart()) {
            behospitalPageVO.setBehosDateStart(DateUtil.getFirstTimeOfDay(behospitalPageVO.getBehosDateStart()));
        }
        if (null != behospitalPageVO && null != behospitalPageVO.getBehosDateEnd()) {
            behospitalPageVO.setBehosDateEnd(DateUtil.getFirstTimeOfDay(DateUtil.addDay(behospitalPageVO.getBehosDateEnd(), 1)));
        }
        if (null != behospitalPageVO && null != behospitalPageVO.getBehosDateStart() && null != behospitalPageVO.getBehosDateEnd()) {
            if (DateUtil.after(behospitalPageVO.getBehosDateStart(), behospitalPageVO.getBehosDateEnd())) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "入院时间的开始时间必须小于结束时间！");
            }
        }
        //出院时间
        if (null != behospitalPageVO && null != behospitalPageVO.getLeaveHosDateStart()) {
            behospitalPageVO.setLeaveHosDateStart(DateUtil.getFirstTimeOfDay(behospitalPageVO.getLeaveHosDateStart()));
        }
        if (null != behospitalPageVO && null != behospitalPageVO.getLeaveHosDateEnd()) {
            behospitalPageVO.setLeaveHosDateEnd(DateUtil.getFirstTimeOfDay(DateUtil.addDay(behospitalPageVO.getLeaveHosDateEnd(), 1)));
        }
        if (null != behospitalPageVO && null != behospitalPageVO.getLeaveHosDateStart() && null != behospitalPageVO.getLeaveHosDateEnd()) {
            if (DateUtil.after(behospitalPageVO.getLeaveHosDateStart(), behospitalPageVO.getLeaveHosDateEnd())) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "出院时间的开始时间必须小于结束时间！");
            }
        }
        behospitalPageVO.setHospitalId(Long.parseLong(SysUserUtils.getCurrentHospitalID()));
//        behospitalPageVO.setIsPlacefile("1");
//        if (null != behospitalPageVO.getStatisticsType()
//                && null == behospitalPageVO.getLeaveHosDateStart()
//                && null == behospitalPageVO.getLeaveHosDateEnd()) {
//            String startDate = filterFacade.getStartDateStr(behospitalPageVO.getStatisticsType(), null);
//            String endDate = filterFacade.getEndDateStr(behospitalPageVO.getStatisticsType(), null);
//            behospitalPageVO.setLeaveHosDateStart(DateUtil.parseDate(startDate));
//            behospitalPageVO.setLeaveHosDateEnd(DateUtil.parseDate(endDate));
//        }
    }

    /**
     * 病案首页合格率占比
     *
     * @param filterOrderVO
     * @return
     */
    public List<HomePageNumDTO> homePageLevelLimit(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSet(filterOrderVO);
        List<HomePageNumDTO> records = behospitalInfoFacade.homePageLevelStatistics(filterOrderVO);
        HomePageNumDTO item = getGlobleRecord(records);
        if (item != null) {
            records.add(0, item);
        }
        records = records
                .stream()
                .limit(filterOrderVO.getLimitCount())
                .collect(Collectors.toList());
        return records;
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public HomePageNumDTO getGlobleRecord(List<HomePageNumDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        HomePageNumDTO item = new HomePageNumDTO();

        if (ListUtil.isEmpty(records)) {
            return null;
        }

        //总病历数
        Integer mrNum = records
                .stream()
                .map(HomePageNumDTO::getMrNum)
                .reduce(0, Integer::sum);
        if (mrNum == null || mrNum == 0) {
            return null;
        }
        //总缺陷数
        Integer entryNum = records
                .stream()
                .map(HomePageNumDTO::getEntryNum)
                .reduce(0, Integer::sum);
        //总分
        Double totleValue = records
                .stream()
                .map(i -> BigDecimal.valueOf(i.getTotleValue()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .doubleValue();
        //平均分
        Double averageValue = BigDecimal.valueOf(totleValue)
                .divide(BigDecimal.valueOf(mrNum), 2, RoundingMode.HALF_UP)
                .doubleValue();
        //合格病历总数
        Integer firstLevelNum = records
                .stream()
                .map(HomePageNumDTO::getFirstLevelNum)
                .reduce(0, Integer::sum);
        //合格病历占比
        Double firstLevelPercent = BigDecimal.valueOf(firstLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String firstLevelPercentStr
                = df.format(BigDecimal.valueOf(firstLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //不合格病历数
        Integer secondLevelNum = records
                .stream()
                .map(HomePageNumDTO::getSecondLevelNum)
                .reduce(0, Integer::sum);
        //不合格病历占比
        Double secondLevelPercent = BigDecimal.valueOf(secondLevelNum)
                .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String secondLevelPercentStr
                = df.format(BigDecimal.valueOf(secondLevelPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //条目缺陷总数（模块下条目*病历数）
        Integer entryTotleNum = records
                .stream()
                .map(HomePageNumDTO::getEntryTotleNum)
                .reduce(0, Integer::sum);
        //空项总数
        Integer emptyNum = records
                .stream()
                .map(HomePageNumDTO::getEmptyNum)
                .reduce(0, Integer::sum);
        Double emptyPercent = BigDecimal.valueOf(entryTotleNum - emptyNum)
                .divide(BigDecimal.valueOf(entryTotleNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String emptyPercentStr
                = df.format(BigDecimal.valueOf(emptyPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //错误项总数
        Integer errorNum = records
                .stream()
                .map(HomePageNumDTO::getErrorNum)
                .reduce(0, Integer::sum);
        Double errorPercent = BigDecimal.valueOf(entryTotleNum - errorNum)
                .divide(BigDecimal.valueOf(entryTotleNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String errorPercentStr
                = df.format(BigDecimal.valueOf(errorPercent).multiply(BigDecimal.valueOf(100))) + "%";

        item.setDeptName("全院");
        item.setEntryNum(entryNum);
        item.setMrNum(mrNum);
        item.setTotleValue(totleValue);
        item.setAverageValue(averageValue);
        item.setFirstLevelNum(firstLevelNum);
        item.setFirstLevelPercent(firstLevelPercent);
        item.setFirstLevelPercentStr(firstLevelPercentStr);
        item.setSecondLevelNum(secondLevelNum);
        item.setSecondLevelPercent(secondLevelPercent);
        item.setSecondLevelPercentStr(secondLevelPercentStr);
        item.setEntryTotleNum(entryTotleNum);
        item.setEmptyNum(emptyNum);
        item.setEmptyPercent(emptyPercent);
        item.setEmptyPercentStr(emptyPercentStr);
        item.setErrorNum(errorNum);
        item.setErrorPercent(errorPercent);
        item.setErrorPercentStr(errorPercentStr);
        return item;
    }

    /**
     * 条目缺陷质控评分页（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> qcResultShortPage(QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        IPage<QcResultShortDTO> page = behospitalInfoFacade.qcResultShortPage(qcResultShortPageVO);
        return page;
    }

    /**
     * 关键条目缺陷占比统计
     *
     * @param entryStatisticsVO
     * @return
     */
    public List<EntryStatisticsDTO> entryStatistics(EntryStatisticsVO entryStatisticsVO) {
        filterFacade.entryStatisticsVOSet(entryStatisticsVO);
        if (entryStatisticsVO.getDeptName().equals("全院")) {
            entryStatisticsVO.setDeptName("");
        }
        List<EntryStatisticsDTO> records = behospitalInfoFacade.entryStatistics(entryStatisticsVO);
        //增加全院数据
        if (entryStatisticsVO.getDeptName().equals("")) {
            EntryStatisticsDTO record = getEntryGlobleRecord(records);
            if (record != null) {
                records.add(0, record);
            }
        }
        return records;
    }
    
    
	public List<SjcfStatisticsDTO> sjcfStatistics(@Valid EntryStatisticsVO entryStatisticsVO) {
		filterFacade.entryStatisticsVOSet(entryStatisticsVO);
        if (entryStatisticsVO.getDeptName().equals("全院")) {
            entryStatisticsVO.setDeptName("");
        }
        List<SjcfStatisticsDTO> records = behospitalInfoFacade.sjcfStatistics(entryStatisticsVO);
        //增加全院数据
        if (entryStatisticsVO.getDeptName().equals("")) {
        	SjcfStatisticsDTO record = getSjcfGlobleRecord(records);
            if (record != null) {
                records.add(0, record);
            }
        }
        return records;
	}

	 /**
     * 关键条目缺陷占比统计增加全院记录
     *
     * @param records
     * @return
     */
    private SjcfStatisticsDTO getSjcfGlobleRecord(List<SjcfStatisticsDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        SjcfStatisticsDTO record = new SjcfStatisticsDTO();
        record.setDeptName("全院");
       
        //首次病程未在患者入院8小时内完成
        Integer scbc8xsNum = records.stream().map(SjcfStatisticsDTO::getScbc8xsNum).reduce(0, Integer::sum);
        record.setScbc8xsNum(scbc8xsNum);
        record.setScbc8xsEntryId(records.get(0).getScbc8xsEntryId());
        Integer scbc8xsMRNum = records.stream().map(SjcfStatisticsDTO::getScbc8xsMRNum).reduce(0, Integer::sum);
        record.setScbc8xsMRNum(scbc8xsMRNum);
        if (scbc8xsNum != null && !scbc8xsMRNum.equals(0)) {
            Double scbc8xsPercent = BigDecimal.valueOf(scbc8xsNum).divide(BigDecimal.valueOf(scbc8xsMRNum), 4, RoundingMode.HALF_UP).doubleValue();
            record.setScbc8xsPercent(scbc8xsPercent);
            record.setScbc8xsPercentStr(df.format(BigDecimal.valueOf(scbc8xsPercent).multiply(BigDecimal.valueOf(100))) + "%");
        }
        
        //主治医师首次查房未在患者入院48小时内完成
        Integer zzsccf48xsNum = records.stream().map(SjcfStatisticsDTO::getZzsccf48xsNum).reduce(0, Integer::sum);
        record.setZzsccf48xsNum(zzsccf48xsNum);
        record.setZzsccf48xsEntryId(records.get(0).getZzsccf48xsEntryId());
        Integer zzsccf48xsMRNum = records.stream().map(SjcfStatisticsDTO::getZzsccf48xsMRNum).reduce(0, Integer::sum);
        record.setZzsccf48xsMRNum(zzsccf48xsMRNum);
        if (zzsccf48xsMRNum != null && !zzsccf48xsMRNum.equals(0)) {
            Double zzsccf48xsPercent = BigDecimal.valueOf(zzsccf48xsNum).divide(BigDecimal.valueOf(zzsccf48xsMRNum), 4, RoundingMode.HALF_UP).doubleValue();
            record.setZzsccf48xsPercent(zzsccf48xsPercent);
            record.setZzsccf48xsPercentStr(df.format(BigDecimal.valueOf(zzsccf48xsPercent).multiply(BigDecimal.valueOf(100))) + "%");
        }
        
        //副主任医师/主任医师首次查房未在患者入院72h内完成
        Integer fzzsccf72xsNum = records.stream().map(SjcfStatisticsDTO::getFzzsccf72xsNum).reduce(0, Integer::sum);
        record.setFzzsccf72xsNum(fzzsccf72xsNum);
        record.setFzzsccf72xsEntryId(records.get(0).getFzzsccf72xsEntryId());
        Integer fzzsccf72xsMRNum = records.stream().map(SjcfStatisticsDTO::getFzzsccf72xsMRNum).reduce(0, Integer::sum);
        record.setFzzsccf72xsMRNum(fzzsccf72xsMRNum);
        if (fzzsccf72xsMRNum != null && !fzzsccf72xsMRNum.equals(0)) {
            Double fzzsccf72xsPercent = BigDecimal.valueOf(fzzsccf72xsNum).divide(BigDecimal.valueOf(fzzsccf72xsMRNum), 4, RoundingMode.HALF_UP).doubleValue();
            record.setFzzsccf72xsPercent(fzzsccf72xsPercent);
            record.setFzzsccf72xsPercentStr(df.format(BigDecimal.valueOf(fzzsccf72xsPercent).multiply(BigDecimal.valueOf(100))) + "%");
        }

        //每周无2次副主任医师/主任医师查房记录率
        Integer mzf2cNum = records.stream().map(SjcfStatisticsDTO::getMzf2cNum).reduce(0, Integer::sum);
        record.setMzf2cNum(mzf2cNum);
        record.setMzf2cEntryId(records.get(0).getMzf2cEntryId());
        Integer mzf2cMRNum = records.stream().map(SjcfStatisticsDTO::getMzf2cMRNum).reduce(0, Integer::sum);
        record.setMzf2cMRNum(mzf2cMRNum);
        if (mzf2cMRNum != null && !mzf2cMRNum.equals(0)) {
            Double mzf2cPercent = BigDecimal.valueOf(mzf2cNum).divide(BigDecimal.valueOf(mzf2cMRNum), 4, RoundingMode.HALF_UP).doubleValue();
            record.setMzf2cPercent(mzf2cPercent);
            record.setMzf2cPercentStr(df.format(BigDecimal.valueOf(mzf2cPercent).multiply(BigDecimal.valueOf(100))) + "%");
        }
        
        //每周无3次主治医师查房记录率
        Integer mzw3cNum = records.stream().map(SjcfStatisticsDTO::getMzw3cNum).reduce(0, Integer::sum);
        record.setMzw3cNum(mzw3cNum);
        record.setMzw3cEntryId(records.get(0).getMzw3cEntryId());
        Integer mzw3cMRNum = records.stream().map(SjcfStatisticsDTO::getMzw3cMRNum).reduce(0, Integer::sum);
        record.setMzw3cMRNum(mzw3cMRNum);
        if (mzw3cMRNum != null && !mzw3cMRNum.equals(0)) {
            Double mzw3cPercent = BigDecimal.valueOf(mzw3cNum).divide(BigDecimal.valueOf(mzw3cMRNum), 4, RoundingMode.HALF_UP).doubleValue();
            record.setMzw3cPercent(mzw3cPercent);
            record.setMzw3cPercentStr(df.format(BigDecimal.valueOf(mzw3cPercent).multiply(BigDecimal.valueOf(100))) + "%");
        }
        
        return record;
    }
	
    /**
     * 关键条目缺陷占比统计增加全院记录
     *
     * @param records
     * @return
     */
    private EntryStatisticsDTO getEntryGlobleRecord(List<EntryStatisticsDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        if (ListUtil.isEmpty(records)) {
            return null;
        }

        EntryStatisticsDTO record = new EntryStatisticsDTO();
        record.setDeptName("全院");
        //未在24小时内完成会诊
        Integer consultationNum = records
                .stream()
                .map(EntryStatisticsDTO::getConsultationNum)
                .reduce(0, Integer::sum);
        record.setConsultationNum(consultationNum);
        record.setConsultationEntryId(records.get(0).getConsultationEntryId());
        Integer consultationMRNum = records
                .stream()
                .map(EntryStatisticsDTO::getConsultationMRNum)
                .reduce(0, Integer::sum);
        record.setConsultationMRNum(consultationMRNum);
        if (consultationMRNum != null && !consultationMRNum.equals(0)) {
            Double consultationPercent = BigDecimal.valueOf(consultationNum)
                    .divide(BigDecimal.valueOf(consultationMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String consultationPercentStr
                    = df.format(BigDecimal.valueOf(consultationPercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setConsultationPercent(consultationPercent);
            record.setConsultationPercentStr(consultationPercentStr);
        }
        //手术记录名称不匹配
        Integer operationNameNum = records
                .stream()
                .map(EntryStatisticsDTO::getOperationNameNum)
                .reduce(0, Integer::sum);
        record.setOperationNameNum(operationNameNum);
        record.setOperationNameEntryId(records.get(0).getOperationNameEntryId());
        Integer operationMRNum = records
                .stream()
                .map(EntryStatisticsDTO::getOperationMRNum)
                .reduce(0, Integer::sum);
        record.setOperationMRNum(operationMRNum);
        if (operationMRNum != null && !operationMRNum.equals(0)) {
            Double operationNamePercent = BigDecimal.valueOf(operationNameNum)
                    .divide(BigDecimal.valueOf(operationMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String operationNamePercentStr
                    = df.format(BigDecimal.valueOf(operationNamePercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setOperationNamePercent(operationNamePercent);
            record.setOperationNamePercentStr(operationNamePercentStr);
        }
        //术后首程未在15分钟内完成
        Integer operation15MinuteNum = records
                .stream()
                .map(EntryStatisticsDTO::getOperation15MinuteNum)
                .reduce(0, Integer::sum);
        record.setOperation15MinuteNum(operation15MinuteNum);
        record.setOperation15MinuteEntryId(records.get(0).getOperation15MinuteEntryId());
        if (operationMRNum != null && !operationMRNum.equals(0)) {
            Double operation15MinutePercent = BigDecimal.valueOf(operation15MinuteNum)
                    .divide(BigDecimal.valueOf(operationMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String operation15MinutePercentStr
                    = df.format(BigDecimal.valueOf(operation15MinutePercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setOperation15MinutePercent(operation15MinutePercent);
            record.setOperation15MinutePercentStr(operation15MinutePercentStr);
        }
        //病案首页手术时间不匹配
        Integer operationTimeNum = records
                .stream()
                .map(EntryStatisticsDTO::getOperationTimeNum)
                .reduce(0, Integer::sum);
        record.setOperationTimeNum(operationTimeNum);
        record.setOperationTimeEntryId(records.get(0).getOperationTimeEntryId());
        if (operationMRNum != null && !operationMRNum.equals(0)) {
            Double operationTimePercent = BigDecimal.valueOf(operationTimeNum)
                    .divide(BigDecimal.valueOf(operationMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String operationTimePercentStr
                    = df.format(BigDecimal.valueOf(operationTimePercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setOperationTimePercent(operationTimePercent);
            record.setOperationTimePercentStr(operationTimePercentStr);
        }
        //未在6小时内书写危机值记录
        Integer crisisNum = records
                .stream()
                .map(EntryStatisticsDTO::getCrisisNum)
                .reduce(0, Integer::sum);
        record.setCrisisNum(crisisNum);
        record.setCrisisEntryId(records.get(0).getCrisisEntryId());
        Integer crisisMRNum = records
                .stream()
                .map(EntryStatisticsDTO::getCrisisMRNum)
                .reduce(0, Integer::sum);
        record.setCrisisMRNum(crisisMRNum);
        if (crisisMRNum != null && !crisisMRNum.equals(0)) {
            Double crisisPercent = BigDecimal.valueOf(crisisNum)
                    .divide(BigDecimal.valueOf(crisisMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String crisisPercentStr
                    = df.format(BigDecimal.valueOf(crisisPercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setCrisisPercent(crisisPercent);
            record.setCrisisPercentStr(crisisPercentStr);
        }
        //病人住院超过30天，阶段小节书写
        Integer stageSummaryNum = records
                .stream()
                .map(EntryStatisticsDTO::getStageSummaryNum)
                .reduce(0, Integer::sum);
        record.setStageSummaryNum(stageSummaryNum);
        record.setStageSummaryEntryId(records.get(0).getStageSummaryEntryId());
        Integer stageSummaryMRNum = records
                .stream()
                .map(EntryStatisticsDTO::getStageSummaryMRNum)
                .reduce(0, Integer::sum);
        record.setStageSummaryMRNum(stageSummaryMRNum);
        if (stageSummaryMRNum != null && !stageSummaryMRNum.equals(0)) {
            Double stageSummaryPercent = BigDecimal.valueOf(stageSummaryNum)
                    .divide(BigDecimal.valueOf(stageSummaryMRNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String stageSummaryPercentStr
                    = df.format(BigDecimal.valueOf(stageSummaryPercent).multiply(BigDecimal.valueOf(100))) + "%";
            record.setStageSummaryPercent(stageSummaryPercent);
            record.setStageSummaryPercentStr(stageSummaryPercentStr);
        }
        //住院超过31日病人数
        Integer beHosGT31DaysMRNum = records
                .stream()
                .map(EntryStatisticsDTO::getBeHosGT31DaysMRNum)
                .reduce(0, Integer::sum);
        record.setBeHosGT31DaysMRNum(beHosGT31DaysMRNum);

        return record;
    }

    /**
     * 病案首页合格率、完整率、改善率统计
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> homePageMRCount(FilterVO filterVO) {
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("合格率", null);
        retMap.put("不合格率", null);
        retMap.put("完整率", null);
        retMap.put("改善率", null);
        filterFacade.filterVOSet(filterVO);
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            retMap
                    = dataBeanAggregateQueryFacade.get("setAllHomePage", invokeParams, Map.class);
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        return retMap;
    }

    /**
     * 离院病人质控评分详情页
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> leaveHosMRPage(QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        IPage<QcResultShortDTO> page = behospitalInfoFacade.leaveHosMRPage(qcResultShortPageVO);
        return page;
    }

    /**
     * 质控核查统计（内页）
     *
     * @param filterOrderVO
     * @return
     */
    public List<HomePageImproveDTO> qcCheckStatistics(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSet(filterOrderVO);
        List<HomePageImproveDTO> records = behospitalInfoFacade.qcCheckStatistics(filterOrderVO);
        //增加全院数据
        if (StringUtil.isBlank(filterOrderVO.getDeptName()) || filterOrderVO.getDeptName().equals("全院")) {
            HomePageImproveDTO item = getGlobleRecord_improve(records);
            if (item != null) {
                records.add(0, item);
            }
        }
        return records;
    }

    /**
     * 增加全院记录
     *
     * @param records
     * @return
     */
    public HomePageImproveDTO getGlobleRecord_improve(List<HomePageImproveDTO> records) {
        DecimalFormat df = new DecimalFormat("#0.00");
        HomePageImproveDTO item = new HomePageImproveDTO();

        if (ListUtil.isEmpty(records)) {
            return null;
        }

        item.setDeptName("全院");

        //总病历数
        Integer mrNum = records
                .stream()
                .map(HomePageImproveDTO::getMrNum)
                .reduce(0, Integer::sum);
        if (mrNum == null || mrNum == 0) {
            return null;
        }
        item.setMrNum(mrNum);
        //核查病历数
        Integer checkedNum = records
                .stream()
                .map(HomePageImproveDTO::getCheckedNum)
                .reduce(0, Integer::sum);
        item.setCheckedNum(checkedNum);
        if (mrNum != null && !mrNum.equals(0)) {
            //核查病历占比
            Double checkedPercent = BigDecimal.valueOf(checkedNum)
                    .divide(BigDecimal.valueOf(mrNum), 4, RoundingMode.HALF_UP)
                    .doubleValue();
            String checkedPercentStr
                    = df.format(BigDecimal.valueOf(checkedPercent).multiply(BigDecimal.valueOf(100))) + "%";
            item.setCheckedPercent(checkedPercent);
            item.setCheckedPercentStr(checkedPercentStr);
        }
        //带病案首页的病历数
        Integer homePageMRNum = records
                .stream()
                .map(HomePageImproveDTO::getHomePageMRNum)
                .reduce(0, Integer::sum);
        item.setHomePageMRNum(homePageMRNum);
        if (homePageMRNum == null || homePageMRNum.equals(0)) {
            return item;
        }
        //改善病历数
        Integer improveNum = records
                .stream()
                .map(HomePageImproveDTO::getImproveNum)
                .reduce(0, Integer::sum);
        //改善率
        Double improvePercent = BigDecimal.valueOf(improveNum)
                .divide(BigDecimal.valueOf(homePageMRNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String improvePercentStr
                = df.format(BigDecimal.valueOf(improvePercent).multiply(BigDecimal.valueOf(100))) + "%";
        //改善至合格病历数
        Integer improveToPassNum = records
                .stream()
                .map(HomePageImproveDTO::getImproveToPassNum)
                .reduce(0, Integer::sum);
        //改善至合格占比
        Double improveToPassPercent = BigDecimal.valueOf(improveToPassNum)
                .divide(BigDecimal.valueOf(homePageMRNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String improveToPassPercentStr
                = df.format(BigDecimal.valueOf(improveToPassPercent).multiply(BigDecimal.valueOf(100))) + "%";
        //改善至满分病历数
        Integer improveToFullNum = records
                .stream()
                .map(HomePageImproveDTO::getImproveToFullNum)
                .reduce(0, Integer::sum);
        //改善至满分占比
        Double improveToFullPercent = BigDecimal.valueOf(improveToFullNum)
                .divide(BigDecimal.valueOf(homePageMRNum), 4, RoundingMode.HALF_UP)
                .doubleValue();
        String improveToFullPercentStr
                = df.format(BigDecimal.valueOf(improveToFullPercent).multiply(BigDecimal.valueOf(100))) + "%";

        item.setImproveNum(improveNum);
        item.setImprovePercent(improvePercent);
        item.setImprovePercentStr(improvePercentStr);
        item.setImproveToPassNum(improveToPassNum);
        item.setImproveToPassPercent(improveToPassPercent);
        item.setImproveToPassPercentStr(improveToPassPercentStr);
        item.setImproveToFullNum(improveToFullNum);
        item.setImproveToFullPercent(improveToFullPercent);
        item.setImproveToFullPercentStr(improveToFullPercentStr);
        return item;
    }

    /**
     * 未整改病历统计
     *
     * @param filterUnModifyMRVO
     * @return
     */
    public UnModifyMRDTO unModifyMRStatistics(FilterUnModifyMRVO filterUnModifyMRVO) {
        UnModifyMRDTO unModifyMRDTO = new UnModifyMRDTO();
        List<Object> retList = Lists.newLinkedList();
        filterFacade.filterUnModifyMRVOSet(filterUnModifyMRVO);

        //colums
        QueryWrapper<SysHospitalSet> hospitalSetQueryWrapper = new QueryWrapper<>();
        hospitalSetQueryWrapper.eq("is_deleted", 'N')
                .eq("hospital_id", filterUnModifyMRVO.getHospitalId())
                .eq("code", "unmodify_mr_entry");
        SysHospitalSet hospitalSet = sysHospitalSetFacade.getOne(hospitalSetQueryWrapper);
        if (hospitalSet == null || StringUtil.isBlank(hospitalSet.getValue())) {
            return unModifyMRDTO;
        }

        //表头生成
        List<String> columnSet = Arrays.asList(hospitalSet.getValue().split(","));
        List<ColumnDTO> columns = Lists.newLinkedList();
        Integer orderNo = 1;
        ColumnDTO columnDeptId = new ColumnDTO();
        columnDeptId.setOrderNo(orderNo);
        columnDeptId.setFieldName("deptId");
        columnDeptId.setColumnName("科室编码");
        columnDeptId.setIsShow(0);
        columns.add(columnDeptId);
        orderNo++;
        ColumnDTO columnDeptName = new ColumnDTO();
        columnDeptName.setOrderNo(orderNo);
        columnDeptName.setFieldName("deptName");
        columnDeptName.setColumnName("科室");
        columnDeptName.setIsShow(1);
        columns.add(columnDeptName);
        orderNo++;
        List<Long> casesEntryIds = Lists.newArrayList();
        for (String valueStr : columnSet) {
            if (StringUtil.isBlank(valueStr)) {
                continue;
            }
            String[] keyValue = valueStr.split("--");
            if (keyValue != null || keyValue.length > 1) {
                casesEntryIds.add(Long.valueOf(keyValue[0]));
                ColumnDTO columnId = new ColumnDTO();
                columnId.setOrderNo(orderNo);
                columnId.setId(Long.valueOf(keyValue[0]));
                columnId.setFieldName("entry_" + keyValue[0] + "_id");
                columnId.setColumnName(keyValue[1] + "id");
                columnId.setIsShow(0);
                columns.add(columnId);
                orderNo++;
                ColumnDTO columnName = new ColumnDTO();
                columnName.setOrderNo(orderNo);
                columnName.setId(Long.valueOf(keyValue[0]));
                columnName.setFieldName("entry_" + keyValue[0] + "_name");
                columnName.setColumnName(keyValue[1] + "name");
                columnName.setIsShow(0);
                columns.add(columnName);
                orderNo++;
                ColumnDTO columnNum = new ColumnDTO();
                columnNum.setOrderNo(orderNo);
                columnNum.setId(Long.valueOf(keyValue[0]));
                columnNum.setFieldName("entry_" + keyValue[0] + "_num");
                columnNum.setColumnName(keyValue[1]);
                columnNum.setIsShow(1);
                columns.add(columnNum);
                orderNo++;
            }
        }
        //条目未维护
        if (ListUtil.isEmpty(casesEntryIds)) {
            return unModifyMRDTO;
        }

        //casesEntryIds
        filterUnModifyMRVO.setCasesEntryIds(casesEntryIds);
        QueryWrapper<QcCasesEntry> qcCasesEntryQueryWrapper = new QueryWrapper<>();
        qcCasesEntryQueryWrapper.eq("is_deleted", "N")
                .in("id", casesEntryIds);
        List<QcCasesEntry> casesEntryList = qcCasesEntryFacade.list(qcCasesEntryQueryWrapper);
        // 实体类中将实体类转化为map形式，其中条目id对应目标条目名称
        Map<Long, String> basCasesEntryMap = EntityUtil.makeMapWithKeyValue(casesEntryList, "id", "name");

        List<UnModifyMRDetailDTO> records = behospitalInfoFacade.unModifyMRStatistics(filterUnModifyMRVO);
        //以科室分组，将符合科室的每条数据以map形式存储
        Map<String, List<UnModifyMRDetailDTO>> deptMap = EntityUtil.makeEntityListMap(records, "deptName");
        //科室对应科室id
        Map<String, String> deptInfoMap = EntityUtil.makeMapWithKeyValue(records, "deptName", "deptId");
        Map<String, Map<Long, UnModifyMRDetailDTO>> deptEntryMap = new LinkedHashMap<>();
        for (Map.Entry<String, List<UnModifyMRDetailDTO>> entry : deptMap.entrySet()) {
            Map<Long, UnModifyMRDetailDTO> entryMap = EntityUtil.makeEntityMap(entry.getValue(), "casesEntryId");
            deptEntryMap.put(entry.getKey(), entryMap);
        }

        try {
            for (Map.Entry<String, Map<Long, UnModifyMRDetailDTO>> entry : deptEntryMap.entrySet()) {
                Object obj = new Object();
                HashMap addMap = new HashMap();
                HashMap addValMap = new HashMap();

                addMap.put("deptName", Class.forName("java.lang.String"));
                addValMap.put("deptName", entry.getKey());
                addMap.put("deptId", Class.forName("java.lang.String"));
                addValMap.put("deptId", deptInfoMap.get(entry.getKey()));

                for (ColumnDTO item : columns) {
                    if (item.getFieldName().lastIndexOf("_id") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.Long"));
                        if (item.getId() != null) {
                            addValMap.put(item.getFieldName(), item.getId());
                        } else {
                            addValMap.put(item.getFieldName(), null);
                        }
                    } else if (item.getFieldName().lastIndexOf("_name") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.String"));
                        if (basCasesEntryMap.containsKey(item.getId())) {
                            addValMap.put(item.getFieldName(), basCasesEntryMap.get(item.getId()));
                        } else {
                            addValMap.put(item.getFieldName(), "");
                        }
                    } else if (item.getFieldName().lastIndexOf("_num") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.Integer"));
                        if (entry.getValue().containsKey(item.getId())) {
                            addValMap.put(item.getFieldName(), entry.getValue().get(item.getId()).getCasesEntryNum());
                        } else {
                            addValMap.put(item.getFieldName(), 0);
                        }
                    }
                }
                obj = new ClassUtil().dynamicClass(obj, addMap, addValMap);
                retList.add(obj);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        //排序
        Collections.sort(retList, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {

                if (StringUtil.isNotBlank(filterUnModifyMRVO.getAsc())) {
                    //升序
                    Object o1Val = ObjectUtil.getValueByKey(o1, filterUnModifyMRVO.getAsc());
                    Object o2Val = ObjectUtil.getValueByKey(o2, filterUnModifyMRVO.getAsc());
                    if (filterUnModifyMRVO.getAsc().lastIndexOf("_num") > 1) {
                        return ((Integer) o1Val).compareTo((Integer) o2Val);
                    }
                    if (filterUnModifyMRVO.getAsc().lastIndexOf("_id") > 1) {
                        return ((Long) o1Val).compareTo((Long) o2Val);
                    } else {
                        return ((String) o1Val).compareTo((String) o2Val);
                    }
                } else if (StringUtil.isNotBlank(filterUnModifyMRVO.getDesc())) {
                    //降序
                    Object o1Val = ObjectUtil.getValueByKey(o1, filterUnModifyMRVO.getDesc());
                    Object o2Val = ObjectUtil.getValueByKey(o2, filterUnModifyMRVO.getDesc());
                    if (filterUnModifyMRVO.getDesc().lastIndexOf("_num") > 1) {
                        return ((Integer) o2Val).compareTo((Integer) o1Val);
                    }
                    if (filterUnModifyMRVO.getDesc().lastIndexOf("_id") > 1) {
                        return ((Long) o2Val).compareTo((Long) o1Val);
                    } else {
                        return ((String) o2Val).compareTo((String) o1Val);
                    }
                } else {
                    return 0;
                }
            }
        });
        //增加全院数据
        if (ListUtil.isNotEmpty(retList) &&
                (StringUtil.isBlank(filterUnModifyMRVO.getDeptName())
                        || filterUnModifyMRVO.getDeptName().equals("全院"))) {
            try {

                Object globleObj = new Object();
                HashMap addMap = new HashMap();
                HashMap addValMap = new HashMap();
                addMap.put("deptId", Class.forName("java.lang.String"));
                addValMap.put("deptId", "");
                addMap.put("deptName", Class.forName("java.lang.String"));
                addValMap.put("deptName", "全院");

                for (ColumnDTO item : columns) {
                    if (item.getFieldName().lastIndexOf("_id") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.Long"));
                        if (item.getId() != null) {
                            addValMap.put(item.getFieldName(), item.getId());
                        } else {
                            addValMap.put(item.getFieldName(), null);
                        }

                    } else if (item.getFieldName().lastIndexOf("_name") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.String"));
                        if (basCasesEntryMap.containsKey(item.getId())) {
                            addValMap.put(item.getFieldName(), basCasesEntryMap.get(item.getId()));
                        } else {
                            addValMap.put(item.getFieldName(), "");
                        }

                    } else if (item.getFieldName().lastIndexOf("_num") > 0) {
                        addMap.put(item.getFieldName(), Class.forName("java.lang.Integer"));
                        Integer entryNum = retList
                                .stream()
                                .map(i -> ObjectUtil.getValueByKey(i, item.getFieldName()))
                                .filter(i -> i != null)
                                .map(i -> (Integer) i)
                                .reduce(0, Integer::sum);
                        addValMap.put(item.getFieldName(), entryNum);
                    }
                }
                globleObj = new ClassUtil().dynamicClass(globleObj, addMap, addValMap);
                retList.add(0, globleObj);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        unModifyMRDTO.setColumns(columns);
        unModifyMRDTO.setData(retList);
        return unModifyMRDTO;
    }


    /**
     * 未整改病历质控评分页（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> unModifyMRPage(QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.unModifyMRPage(qcResultShortPageVO);
    }

    /**
     * 不合格/合格数病历号（内页）
     *
     * @param qcResultPageVO
     * @return
     */
    public IPage<QcResultShortDTO> badLevelPage(QcResultPageVO qcResultPageVO) {
        filterFacade.badLevelPageVOSet(qcResultPageVO);
        return behospitalInfoFacade.badLevelPage(qcResultPageVO);
    }

    /**
     * 31天再入院详情页
     *
     * @param reBeHosPageVO
     * @return
     */
    public IPage<ReBeHosDTO> reHos31DaysPage(ReBeHosPageVO reBeHosPageVO) {
        filterFacade.reBeHosPageVOSet(reBeHosPageVO);
        long size = reBeHosPageVO.getSize();
        long current = reBeHosPageVO.getCurrent();
        reBeHosPageVO.setCurrent(1L);
        reBeHosPageVO.setSize(Long.MAX_VALUE);
        IPage<ReBeHosMergeDTO> page = behospitalInfoFacade.reHos31DaysPage(reBeHosPageVO);
        List<ReBeHosMergeDTO> records = page.getRecords();
        IPage<ReBeHosDTO> retPage = new Page<>();
        if (ListUtil.isNotEmpty(records)) {
            BeanUtil.copyProperties(page, retPage);
            List<ReBeHosDTO> retRecords = Lists.newLinkedList();
            Iterator<ReBeHosMergeDTO> iterator = records.iterator();
            while(iterator.hasNext()){
                ReBeHosMergeDTO record = iterator.next();
                Boolean flag = isContainDiagnose(record);
                if(!flag){
                    iterator.remove();
                    continue;
                }
                ReBeHosDTO retRecord = new ReBeHosDTO();
                BeanUtil.copyProperties(record, retRecord);
                List<ReBeHosDetailDTO> details = Lists.newLinkedList();
                ReBeHosDetailDTO detailRecord = new ReBeHosDetailDTO();
                BeanUtil.copyProperties(record, detailRecord);
                details.add(detailRecord);
                ReBeHosDetailDTO lastDetailRecord = new ReBeHosDetailDTO();
                lastDetailRecord.setName(record.getName());
                lastDetailRecord.setAge(record.getLastAge());
                lastDetailRecord.setDiagnose(record.getLastDiagnose());
                lastDetailRecord.setDiagnoseName(record.getLastDiagnoseName());
                lastDetailRecord.setBehDeptId(record.getLastBehDeptId());
                lastDetailRecord.setBehDeptName(record.getLastBehDeptName());
                lastDetailRecord.setBehospitalCode(record.getLastBehospitalCode());
                lastDetailRecord.setBehospitalDate(record.getLastBehospitalDate());
                lastDetailRecord.setLeaveHospitalDate(record.getLastLeaveHospitalDate());
                lastDetailRecord.setLevel(record.getLastLevel());
                lastDetailRecord.setScoreRes(record.getLastScoreRes());
                lastDetailRecord.setBehospitalDayNum(record.getLastBehospitalDayNum());
                lastDetailRecord.setTotleFee(record.getLastTotleFee());
                details.add(lastDetailRecord);
                retRecord.setDetails(details);
                retRecords.add(retRecord);
            }
            //首页返回全部数据
        if(reBeHosPageVO.getFlag()==31){
            retPage.setRecords(retRecords);
            return retPage;
        }
        //导出操作
        if(reBeHosPageVO.getFlag()==1){
            size = retRecords.size();
        }
        retPage.setSize(size);
        retPage.setTotal(retRecords.size());
        retPage.setCurrent(current);
        //数据返回索引处理
        if(0 == current){
            current = 1;
        }
        int startIndex = ((int)current -1)*10;
        int endIndex = startIndex + (int) size;

        if(retRecords.size()>1){
            if( retRecords.size()-startIndex<(int)size){
                retRecords = retRecords.subList(startIndex,retRecords.size());
            }else{
                retRecords = retRecords.subList(startIndex,endIndex );
            }
        }
        retPage.setRecords(retRecords);
        }
        return retPage;
    }


   static Boolean isContainDiagnose(ReBeHosMergeDTO record){
       // String lastDiagnoseName = replace(record.getLastDiagnoseName());本身使用,分隔
        String diagnose =replace(record.getDiagnose());//手动分隔
        String lastDiagnose = replace(record.getLastDiagnose());
        record.setDiagnose(diagnose);
        record.setLastDiagnose(lastDiagnose);
        Set lastDiagnoseNames = strTranListMethod(record.getLastDiagnoseName());
        Set diagnoses = strTranListMethod(record.getDiagnose());
        long count = diagnoses.stream().filter(obj ->null != lastDiagnoseNames && null != obj && lastDiagnoseNames.contains(obj)).count();
        if(count<=0){
            return false;
        }
        return true;
    };

    static String replace(String str){
        if(StringUtils.isEmpty(str)){
            return null;
        }
        str = str.trim().replace("；", ",").replace(";", ",")
                        .replace("、", ",").replace("，", ",")
                        .replace("|", ",").replace(" ", ",")
                        .replace(":", ",") .replace("：", ",");
        if(str.startsWith(",")){
            str = str.substring(1);
        }
        if(str.endsWith(",")){
            str = str.substring(0,str.length()-1);
        }

       return str;
    }
    static Set<String> strTranListMethod(String str){
        Set<String> names = new HashSet<>();
        if(StringUtils.isNotEmpty(str)){
        if(str.contains(",") && str.length()>1){
            for (String diagnoseName : str.split(",")) {
                names.add(diagnoseName);
            }
        }else{
            names.add(str);
             }
        }
        return names;
    };

    /**
     * 入院人数统计（首页）
     *
     * @param filterVO
     * @return
     */
    public List<NumDTO> beHosCount(FilterVO filterVO) {
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> records = behospitalInfoFacade.beHosCount(filterVO);

        if (ListUtil.isNotEmpty(records)) {
            NumDTO globleRecord = new NumDTO();
            globleRecord.setName("全院");
            Integer num = records.stream()
                    .map(NumDTO::getNum)
                    .reduce(0, Integer::sum);
            globleRecord.setNum(num);
            records.add(0, globleRecord);
        }

        if (ListUtil.isNotEmpty(records) && records.size() > filterVO.getLimitCount()) {
            records = records.subList(0, 10);
        }
        return records;
    }

    /**
     * 单条条目缺陷统计（首页）
     *
     * @param filterVO
     * @return
     */
    public List<NumDTO> casesEntryStatisticsById(FilterVO filterVO) {
        filterFacade.filterVOSet(filterVO);
        List<NumDTO> records = behospitalInfoFacade.casesEntryStatisticsById(filterVO);

        if (ListUtil.isNotEmpty(records)) {
            NumDTO globleRecord = new NumDTO();
            globleRecord.setName("全院");
            Integer num = records.stream()
                    .map(NumDTO::getNum)
                    .reduce(0, Integer::sum);
            globleRecord.setNum(num);
            records.add(0, globleRecord);
        }

        if (ListUtil.isNotEmpty(records) && records.size() > filterVO.getLimitCount()) {
            records = records.subList(0, 10);
        }
        return records;
    }

    /**
     * 病案首页改善率质控评分页（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> hmImproveMRPage(@Param("qcResultShortPageVO") QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.hmImproveMRPage(qcResultShortPageVO);
    }


    //指标十四 恶性肿瘤放射治疗
    private List<Map<String, String>> tumorRadiationMethod(Map<String, Double> medManageParams,List<Map<String, String>> retList, Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        //接受肿瘤放射治疗的质控病历总数
        Double count = medManageParams.get("tumorRadiationResult");
        String num = null;
        if( null == count){
            count = 0d;
        }
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            double tumorRadiationDo = currencyCal(count, triggeringRulesMap.get("tumorRadiationNum"));//triggeringRules(filterVO)
            num = String.valueOf(tumorRadiationDo);
            if(tumorRadiationDo<0d){
                num = null;
            }
        };

        firMap.put("name","恶性肿瘤放射治疗记录符合率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        firMap.put("num",String.valueOf(count));
        retList.add(firMap);
        return retList;
    }

    //指标十六 植入物相关记录符合率
    private List<Map<String, String>> implantsMethod(Map<String, Double> medManageParams,List<Map<String, String>> retList, Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        //使用植入物的质控病历总数
        Double count = medManageParams.get("implantsResult");
        if( null == count){
            count = 0d;
        }
        String num = null;
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            double implantsDo = currencyCal(count, triggeringRulesMap.get("implantsNum"));//triggeringRules(filterVO)
            num = String.valueOf(implantsDo);
            if(implantsDo<0d){
                num = null;
            }
        };

        firMap.put("name","植入物相关记录符合率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        firMap.put("num",String.valueOf(count));
        retList.add(firMap);
        return retList;
    }

    //指标十八 抢救记录
    private  List<Map<String, String>> rescueMethod( Map<String, Double> medManageParams, List<Map<String, String>> retList,Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        //接受抢救的质控病历总数
        Double count = medManageParams.get("rescueResult");
        if( null == count){
            count = 0d;
        }
        String num = null;
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            double rescueDo = currencyCal(count, triggeringRulesMap.get("rescueNum"));
            num = String.valueOf(rescueDo);
            if(rescueDo<0d){
                num = null;
            }
        };

        firMap.put("name","患者抢救记录及时完成率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        firMap.put("num",String.valueOf(count));
        retList.add(firMap);
        return retList;
    };

    //指标十七 医师查房记录
    private List<Map<String, String>> WardRoundMethod( List<Map<String, String>> retList, Map<String, Object> baseIndex, Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        String num = null;
        Object forWorkNum = baseIndex.get("forWorkNum");
        if( triggeringRulesMap.containsKey("WardRoundNum") && baseIndex.containsKey("forWorkNum") && !baseIndex.get("forWorkNum").toString().equals("0")){
            double wardRoundDo = currencyCal(baseIndex.get("forWorkNum"), triggeringRulesMap.get("WardRoundNum"));
            num = String.valueOf(wardRoundDo);
            if(wardRoundDo<0d){
                num = null;
            }
        };
        firMap.put("name","医师查房记录完成率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        if(null == forWorkNum){
            firMap.put("num","0");
        }else{
            firMap.put("num",baseIndex.get("forWorkNum").toString());
        }
        retList.add(firMap);
        return retList;
    }


    //指标二十二 不合理复制病历发生率
    private List<Map<String, String>> unreasonedCopyMethod( List<Map<String, String>> retList, Map<String, Object> baseIndex, Map<String, Long> triggeringRulesMap){
       LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
       String num = null;
        Object forWorkNum = baseIndex.get("forWorkNum");
        if( triggeringRulesMap.containsKey("unreasonedCopyNum") && baseIndex.containsKey("forWorkNum") && !baseIndex.get("forWorkNum").toString().equals("0")){
           double wardRoundDo = currencyCal(baseIndex.get("forWorkNum"), triggeringRulesMap.get("unreasonedCopyNum"));
           num = String.valueOf(wardRoundDo);
           if(wardRoundDo<0d){
               num = null;
           }
       };
       firMap.put("name","不合理复制病历发生率");
       firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        if(null == forWorkNum){
            firMap.put("num","0");
        }else{
            firMap.put("num",baseIndex.get("forWorkNum").toString());
        }
       retList.add(firMap);
        return retList;
        };


    //指标二十三 知情同意书规范签署率
    private List<Map<String, String>> contentSignMethod(List<Map<String, String>> retList, Map<String, Object> baseIndex, Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        Object forWorkNum = baseIndex.get("forWorkNum");
        String num = null;
        if( triggeringRulesMap.containsKey("InformedNum") && baseIndex.containsKey("forWorkNum") && !baseIndex.get("forWorkNum").toString().equals("0")){
            double InformedDo = currencyCal(baseIndex.get("forWorkNum"), triggeringRulesMap.get("InformedNum"));
            num = String.valueOf(InformedDo);
            if(InformedDo<0d){
                num = null;
            }
        }
        firMap.put("name","知情同意书规范签署率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        if(null == forWorkNum){
            firMap.put("num","0");
        }else{
            firMap.put("num",baseIndex.get("forWorkNum").toString());
        }

        retList.add(firMap);
        return retList;
    }

    //指标十四 手术记录
    private  List<Map<String, String>> operationMethod(Map<String, Double> medManageParams, List<Map<String, String>>retList, Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        String operationFeeNum = medManageParams.get("operationFeeNum")+"";
        if(StringUtils.isEmpty(operationFeeNum)){
            operationFeeNum = "0";
        }
        String num = null;
        if( triggeringRulesMap.containsKey("operationRecordNum") && StringUtils.isNotEmpty(operationFeeNum) && ! operationFeeNum.equals("0")){
            double operationRecordDo = currencyCal(operationFeeNum, triggeringRulesMap.get("operationRecordNum"));
            num = String.valueOf(operationRecordDo);
            if(operationRecordDo<0d){
                num = null;
            }
        };
        firMap.put("name","手术相关记录完成率");
        if("0.0".equals(num)){
            num = "0.00";
        }
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        firMap.put("num",operationFeeNum);

        retList.add(firMap);
        return retList;
    }

    //指标十六  临床用血相关记录符合率
    private  List<Map<String, String>> bloodMethod( List<Map<String, String>>retList,Map<String, Double> bloodRes,Map<String, Long> triggeringRulesMap){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        Double count = bloodRes.get("bloodResult");
        if( null == count){
            count = 0d;
        }
        String num = null;
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            //指标十七
            double bloodDo = currencyCal(count, triggeringRulesMap.get("bloodNum"));
            num = String.valueOf(bloodDo);
            if(bloodDo<0d){
                num = null;
            }
        }

        firMap.put("name","临床用血相关记录符合率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        firMap.put("num",String.valueOf(count));
        retList.add(firMap);
        return retList;
    }

    private double currencyCal(Object objFir,Object objSec){
        DecimalFormat df = new DecimalFormat("#0.00");
        double firDouble = Double.parseDouble(objFir.toString()) - Double.parseDouble(objSec.toString());
        double thrWorkNum = Double.parseDouble(objFir.toString());
        double retData = 0d;
        if(thrWorkNum != 0){
              retData = Double.parseDouble(df.format(firDouble * 100 / thrWorkNum));
        }
        return retData;
    };

    //指标十九 出院患者病历2日归档
    private List<Map<String, String>> getfileSecAmount(Map<String, Double> medManageParams, List<Map<String, String>>retList, Map<String, Object> baseIndex){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        DecimalFormat df = new DecimalFormat("#0.00");
        Double count = medManageParams.get("secFileResult");
        Object forWorkNum = baseIndex.get("forWorkNum");
        if( null == count){
            count = 0d;
        }
        String num = null;
        if(StringUtils.isNotEmpty( baseIndex.get("forWorkNum").toString()) && ! baseIndex.get("forWorkNum").toString().equals("0") ){
            double retNum =count* 100/Double.parseDouble(baseIndex.get("forWorkNum").toString());
            double firGradeStr = Double.parseDouble(df.format(retNum));
            num = String.valueOf(firGradeStr);

        }

        firMap.put("name","出院患者病历2日归档率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        if(null == forWorkNum){
            firMap.put("num","0");
        }else{
            firMap.put("num",baseIndex.get("forWorkNum").toString());
        }
        retList.add(firMap);
        return retList;
    };

    //指标21 --出院患者病历归档完整率
    private  List<Map<String, String>> fileCompleteMethod(Map<String, Double> medManageParams, List<Map<String, String>>retList, Map<String, Object> baseIndex){
        LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
        Double count = medManageParams.get("fileCompleteResult");
        Object forWorkNum = baseIndex.get("forWorkNum");
        if( null == count){
            count = 0d;
        }
        String num = null;
        if(StringUtils.isNotEmpty( baseIndex.get("forWorkNum").toString()) && ! baseIndex.get("forWorkNum").toString().equals("0") ){
            double retNum = currencyCal( baseIndex.get("forWorkNum").toString(),count);
            num = String.valueOf(retNum);
        }

        firMap.put("name","出院患者病历归档完整率");
        firMap.put("notCopiedStr",StringUtils.isEmpty(num) ? "0.00%":(num+"%"));
        if(null == forWorkNum){
            firMap.put("num","0");
        }else{
            firMap.put("num",baseIndex.get("forWorkNum").toString());
        }
        retList.add(firMap);
        return retList;
    }


    private List<Map<String, String>> ManageIndexMethod(String indexName,List<Map<String, String>> retList, Map<String, Object> baseIndex, MedIndexFilterVO timeVo){
        QueryWrapper<MedManagementInfo> query = new QueryWrapper<>();
        query.eq("hospital_id", timeVo.getHospitalId())
                .eq("is_deleted", IsDeleteEnum.N)
                .isNotNull("start_date")
                .isNotNull("end_date")
                .ge("start_date",timeVo.getLastStartDate())
                .le("end_date",timeVo.getLastEndDate())
                .select("position_id","work_person");
        List<MedManagementInfo> list = medManagementInfoService.list(query);


        //单位时间同期住院病案管理人员实际工作总月数
        if(indexName.equals(QualityContent.ZYBA_CYHZ)||indexName.equals(QualityContent.QB)) {
            Optional<Double> secOp = list.stream().filter(obj->obj.getPositionId().equals("1")).map(MedManagementInfo::getWorkPerson).reduce(Double::sum);
            Double secMouth = 0d;
            if(secOp.isPresent()){
                secMouth = secOp.get();
            }
            if(secMouth == 0d){
                secMouth = 5d;
            }
            //指标一
            String num1 = "0";
            if(secMouth != 0d && secMouth != null && StringUtils.isNotEmpty( baseIndex.get("firWorkNum").toString())){
                num1 = String.valueOf(Math.round(Double.parseDouble(baseIndex.get("firWorkNum").toString()) / secMouth));
            }
            LinkedHashMap<String, String> firMap = new LinkedHashMap<>();
            firMap.put("name","住院病案管理人员月均负担出院患者病历数");
            firMap.put("notCopiedStr",num1);
            retList.add(firMap);
        }

        //单位时间同期门诊病案管理人员实际工作总月数
        if(indexName.equals(QualityContent.MZBA_CYHZ)||indexName.equals(QualityContent.QB)) {
            Optional<Double> firOp = list.stream().filter(obj -> obj.getPositionId().equals("3")).map(MedManagementInfo::getWorkPerson).reduce(Double::sum);
            Double firMouth = 0d;
            if(firOp.isPresent()){
                firMouth = firOp.get();
            }
            if(firMouth == 0d){
                firMouth = 5d;
            }
            String num3 = "0";
            if(firMouth != 0d && firMouth != null  && StringUtils.isNotEmpty( baseIndex.get("secWorkNum").toString())){
                //指标二
                num3 = String.valueOf(Math.round(Double.parseDouble(baseIndex.get("secWorkNum").toString())/firMouth));
            }
            LinkedHashMap<String, String> thrMap = new LinkedHashMap<>();
            thrMap.put("name","门诊病案管理人员月均负担门诊患者病历数");
            thrMap.put("notCopiedStr",num3);
            retList.add(thrMap);
        }

        //单位时间同期病案编码管理人员实际工作总月数
        if(indexName.equals(QualityContent.BABM_CYHZ)||indexName.equals(QualityContent.QB)) {
            Optional<Double> thrOp = list.stream().filter(obj->obj.getPositionId().equals("2")).map(MedManagementInfo::getWorkPerson).reduce(Double::sum);
            Double thrMouth = 0d;
            if(thrOp.isPresent()){
                thrMouth = thrOp.get();
            }
            if(thrMouth == 0d){
                thrMouth = 5d;
            }
            //指标三
            String num2 = "0";
            if(thrMouth != 0d && thrMouth != null && StringUtils.isNotEmpty( baseIndex.get("firWorkNum").toString())){
                num2 = String.valueOf(Math.round(Double.parseDouble(baseIndex.get("firWorkNum").toString())/thrMouth));

            }
            LinkedHashMap<String, String> secMap = new LinkedHashMap<>();
            secMap.put("name","病案编码人员月均负担出院患者病历数");
            secMap.put("notCopiedStr",num2);
            retList.add(secMap);
        }
        return retList;
    };


    private List<Map<String, String>> firMethod(List<Map<String, String>> retList, Map<String, Object> baseIndex){
        DecimalFormat df = new DecimalFormat("0.00");
            //指标二十七 -甲级病历率
        LinkedHashMap<String, String> fouMap = new LinkedHashMap<>();
            Double firRecord = 0d;
            String num4= null;
            if(StringUtils.isNotEmpty( baseIndex.get("forWorkNum").toString())){
                firRecord =Double.parseDouble(baseIndex.get("forWorkNum").toString());
            }
            if( firRecord != 0d && StringUtils.isNotEmpty( baseIndex.get("sixWorkNum").toString()) ){
                double retNum = Double.parseDouble(baseIndex.get("sixWorkNum").toString()) * 100 / firRecord;
                double firGradeStr = Double.parseDouble(df.format(retNum));
                num4 = String.valueOf(firGradeStr);
            }
            fouMap.put("name","甲级病历率");
            fouMap.put("notCopiedStr",StringUtils.isEmpty(num4) ? "0.00%":(num4+"%"));
        fouMap.put("num",String.valueOf(firRecord));
            retList.add(fouMap);
        return retList;
    };


    /**
     * ==============================后台维护===============================
     */
    private  Set<String> tumorRadiationMethods( Map<String, Set<String>> adviceNum,MedIndexResult medIndexResult){
        Set<String> tumorRadiationSecNum = new CopyOnWriteArraySet<>();
        if(adviceNum.containsKey("tumorRadiationSecNum")&& adviceNum.get("tumorRadiationSecNum") != null && adviceNum.get("tumorRadiationSecNum").size()>0){
            tumorRadiationSecNum = adviceNum.get("tumorRadiationSecNum");
            double count = tumorRadiationSecNum.size();
            if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
                medIndexResult.setTumorRadiationResult(count);
            }
        }
        return tumorRadiationSecNum;
    }
    //指标19 抢救记录
    private  void rescueMethods(List<MedManageParamsDTO> medManageParams,MedIndexResult medIndexResult, Set<String> rescueCode){
        List<MedManageParamsDTO> manageList= new ArrayList<>();
        List<String> rescueDrugList = QualityContent.RESCUEDRUGLIST;
        for (int i = 0; i < medManageParams.size(); i++) {
            String daItemName = medManageParams.get(i).getDaItemName();
            String doctorAdviceType = medManageParams.get(i).getDoctorAdviceType();
            String da_status = medManageParams.get(i).getDaStatus();
            for (String str : rescueDrugList) {
                if(StringUtils.isNotEmpty(daItemName) && daItemName.contains(str) && StringUtils.isNotEmpty(doctorAdviceType) && doctorAdviceType.equals(QualityContent.STAT_ORDER) && (StringUtils.isEmpty(da_status) || (StringUtils.isNotEmpty(da_status) && ! da_status.equals(QualityContent.CANCELLATION_ORDER)))){
                    manageList.add(medManageParams.get(i));
                    rescueCode.add(medManageParams.get(i).getBehospitalCode());
                }
            }
        }
        //接受抢救的质控病历总数
        double count = manageList.stream().map(MedManageParamsDTO::getBehospitalCode).distinct().count();
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            medIndexResult.setRescueResult(count);
        }
    }

    //指标17  临床用血相关记录符合率
    private void bloodMethods(List<MedManageParamsDTO> doctorAdviceList,FilterVO filterVO,MedIndexResult medIndexResult, Set<String> bloodCode){
        filterVO.setFlagStr("1");
        List<MedManageParamsDTO> medManageParams = behospitalInfoFacade.getMedManageParams(filterVO);
        Set<String> manageList= new CopyOnWriteArraySet<>();
        List<String> blood_list = QualityContent.BLOODLIST;
        //lis项目存在用血住院病历号
        long xx1 = System.currentTimeMillis();
        List<String> beCode = medManageParams.stream()
                .filter(obj -> StringUtils.isNotEmpty(obj.getRepName()) && blood_list.contains(obj.getRepName()))
                .map(MedManageParamsDTO::getBehospitalCode).distinct()
                .collect(Collectors.toList());
        long xx2= System.currentTimeMillis();
        System.out.println("lis项目存在用血住院病历号 = " + (xx2-xx1));
        //advice体现lis项目存在用血的住院病历号
        doctorAdviceList.parallelStream()
                .filter(obj -> beCode.contains(obj.getBehospitalCode()) && StringUtils.isNotEmpty(obj.getDoctorAdviceType()) && obj.getDoctorAdviceType()
                        .equals(QualityContent.STAT_ORDER) && blood_list.contains(obj.getDaItemName()) &&
                        (StringUtils.isEmpty(obj.getDaStatus()) || (StringUtils.isNotEmpty(obj.getDaStatus()) && ! obj.getDaStatus()
                        .equals(QualityContent.CANCELLATION_ORDER))))
                .distinct()
                .map(obj -> {manageList.add(obj.getBehospitalCode());return bloodCode.add(obj.getBehospitalCode());})
                .collect(Collectors.toList());
        long xx3= System.currentTimeMillis();
        System.out.println("advice体现lis项目存在用血的住院病历号 = " + (xx3-xx2));

        //临床用血的质控病历总数
        double count = manageList.size();
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            //指标十七
            medIndexResult.setBloodResult(count);
        }
    }


    //指标20 出院患者病历2日归档
    private void getfileSecAmounts(FilterVO filterVO,MedIndexResult medIndexResult){
        QueryWrapper<BehospitalInfo> query = new QueryWrapper<>();
        query.eq("hospital_id", filterVO.getHospitalId())
                .eq("is_deleted", IsDeleteEnum.N)
                .ne("qc_type_id", 0)
                .eq("is_placefile", 1)
                // .eq("is_placefile", filterVO.getIsPlacefile())
                .isNotNull("leave_hospital_date")
                .ge("leave_hospital_date",filterVO.getStartDate())
                .le("leave_hospital_date",filterVO.getEndDate());
        List<BehospitalInfo> list = behospitalInfoFacade.list(query);
        Iterator<BehospitalInfo> iterator = list.iterator();
        while (iterator.hasNext()){
            BehospitalInfo beh = iterator.next();
            Boolean flag = getTrueSecFile(beh.getLeaveHospitalDate(), beh.getPlacefileDate(), TimeContent.HolidaysTimeList);
            //时间截止则删除元素
            if(!flag){
                iterator.remove();
            }
        }
        double count = list.stream().distinct().map(BehospitalInfo::getBedCode).count();
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            medIndexResult.setSecFileResult(count);
        }

    }

    private Boolean getTrueSecFile(Date date1,Date date2, List<String> holidaysTimeList){
        if(date1.after(date2)){
            return false;
        }
        Date date = date1;
        Date dateSec = date2;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat simpleDateFormatRe = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = null;
        int count = 0;
        try {
            date1 = simpleDateFormatRe.parse(simpleDateFormatRe.format(date1));
            date2 = simpleDateFormatRe.parse(simpleDateFormatRe.format(date2));
            cal = Calendar.getInstance();
            cal.setTime(date);
            count = 0;
            for (String str : holidaysTimeList) {
                Date date3 = simpleDateFormatRe.parse(str);
                if(date3.after(date1) && date3.before(date2)){
                    count++;
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        cal.add(Calendar.DAY_OF_YEAR,count+2);
        String endTime = simpleDateFormat.format(cal.getTime());
        LocalDateTime ldt = LocalDateTime.parse(endTime,dateTimeFormatter);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = ldt.atZone(zone).toInstant();
        Date endDate = Date.from(instant);
        if(endDate.after(dateSec)){
            return true;
        }
        return false;
    }


    private void timeTrans( MedIndexFilterVO  filterVO){
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        try {
            cal1.setTime(myFormatter.parse(filterVO.getStartDate()));
            cal2.setTime(myFormatter.parse(filterVO.getEndDate()));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        cal1.set(Calendar.DAY_OF_MONTH, 1);//当月的第一天
        cal2.set(Calendar.DAY_OF_MONTH, 1);
        cal2.set(Calendar.DATE, 1);//设为当前月的1号
        cal2.roll(Calendar.DATE, -1);
        String startTime = myFormatter.format(cal1.getTime())+" 00:00:00";
        String endTime = myFormatter.format(cal2.getTime())+" 23:59:59";
        filterVO.setLastStartDate(startTime);
        filterVO.setLastEndDate(endTime);
    };

    //指标 16--植入物相关记录符合率
    private Set<String> implantsMethods(FilterVO filterVO,MedIndexResult medIndexResult){
        filterVO.setFlagStr("4");
        List<MedManageParamsDTO> fileLists = behospitalInfoFacade.getMedManageParams(filterVO);
        Set<String> collect = fileLists.parallelStream().filter(obj -> {
            String content = obj.getContent();
            Map contenMap = JSON.parseObject(content, Map.class);
            return contenMap.containsKey("使用植入性材料") && StringUtils.isNotEmpty(contenMap.get("使用植入性材料").toString())
                    && "true".equals(contenMap.get("使用植入性材料").toString());
        }).map(MedManageParamsDTO::getBehospitalCode).collect(Collectors.toSet());
        double count = collect.size();
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            medIndexResult.setImplantsResult(count);
        }
        return collect;
    }

    //指标21 出院患者病历归档完整率
    private void fileCompleteMethods(FilterVO filterVO,MedIndexResult medIndexResult){
        filterVO.setFlagStr("3");
        List<MedManageParamsDTO> fileLists = behospitalInfoFacade.getMedManageParams(filterVO);
        double count = fileLists.stream().map(MedManageParamsDTO::getBehospitalCode).distinct().count();
        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
            medIndexResult.setFileCompleteResult(count);
        }
    }

    //指标23  知情同意书规范签署率
//    private void contentSignMethods(List<MedManageParamsDTO>fileLists,MedIndexResult medIndexResult){
//        Set<String> collect = fileLists.parallelStream().filter(obj -> {
//            String content = obj.getContent();
//            Map contenMap = JSON.parseObject(content, Map.class);
//            return contenMap.containsKey("签署") && StringUtils.isNotEmpty(contenMap.get("签署").toString());
//        }).map(MedManageParamsDTO::getBehospitalCode).collect(Collectors.toSet());
//        double count = collect.size();
//        if(StringUtils.isNotEmpty(String.valueOf(count)) &&  count != 0d){
//            medIndexResult.setRecordSignResult(count);
//        }
//    }


    /**
     * 质控核查质控评分页（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> qcCheckMRPage(@Param("qcResultShortPageVO") QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.qcCheckMRPage(qcResultShortPageVO);
    }


    /**
     * 病历稽查表导出（首页）
     *
     * @param filterVO
     * @return
     */


    public List<MedicalCheckExportDTO> medicalCheckExport(@Param("filterVO") FilterMedicalCheckVO filterVO) {
        filterFacade.getMedicalCheckVOSet(filterVO);
        List<MedicalCheckExportDTO> medicalCheck = behospitalInfoFacade.getMedicalCheckExport(filterVO);
        return medicalCheck;
    }


    /**
     * 病历稽查表（title）
     *
     * @param
     * @return
     */
    public List<ColumnDTO> getMedicalCheckTitle() {
        //病历稽查入参拼接
        String hospitalId = SysUserUtils.getCurrentHospitalID();
        //colums
        QueryWrapper<SysHospitalSet> hospitalSetQueryWrapper = new QueryWrapper<>();
        hospitalSetQueryWrapper.eq("is_deleted", 'N')
                .eq("hospital_id", hospitalId)
                .eq("code", "medical_check_form");
        List<ColumnDTO> columns = Lists.newLinkedList();
        SysHospitalSet hospitalSet = sysHospitalSetFacade.getOne(hospitalSetQueryWrapper);
        if (hospitalSet == null || StringUtil.isBlank(hospitalSet.getValue())) {
            return columns;
        }

        //表头生成
        List<String> columnSet = Arrays.asList(hospitalSet.getValue().split(","));
        Integer orderNo = 1;
        ColumnDTO columnDeptId = new ColumnDTO();
        columnDeptId.setOrderNo(orderNo);
        columnDeptId.setFieldName("deptId");
        columnDeptId.setColumnName("科室编码");
        columnDeptId.setIsShow(0);
        columns.add(columnDeptId);
        orderNo++;
        ColumnDTO columnDeptName = new ColumnDTO();
        columnDeptName.setOrderNo(orderNo);
        columnDeptName.setFieldName("deptName");
        columnDeptName.setColumnName("科室");
        columnDeptName.setIsShow(1);
        columns.add(columnDeptName);
        orderNo++;
        ColumnDTO columnMedicalName = new ColumnDTO();
        columnMedicalName.setOrderNo(orderNo);
        columnMedicalName.setFieldName("doctorName");
        columnMedicalName.setColumnName("医疗组");
        columnMedicalName.setIsShow(1);
        columns.add(columnMedicalName);
        orderNo++;
        for (String valueStr : columnSet) {
            String[] keyValue = valueStr.split("--");
            if (keyValue != null && keyValue.length > 1) {
                ColumnDTO columnNum = new ColumnDTO();
                columnNum.setOrderNo(orderNo);
                columnNum.setId(Long.valueOf(keyValue[0]));
                columnNum.setFieldName("entry_" + keyValue[0] + "_name");
                columnNum.setColumnName(keyValue[1]);
                columnNum.setIsShow(1);
                columns.add(columnNum);
                orderNo++;
            }
        }

        return columns;
    }

    /**
     * 评结果分数(长兴)
     *
     * @param algorithmVO 操作条目的所有信息
     * @return 评结果分数
     */
    private void getScoreForCx(AlgorithmVO algorithmVO, QualityControlDTO qualityControlDTO) {
        List<QcResultAlgVO> qcResultAlgHomePage = new ArrayList<>();
        List<QcResultAlgVO> qcResultAlgHomePageExt = new ArrayList<>();
        for (QcResultAlgVO qcResultAlgVO : algorithmVO.getQcResultAlgVOList()) {
            //首页的情况
            if (qcResultAlgVO.getCasesId().equals(243L)) {
                qcResultAlgHomePage.add(qcResultAlgVO);
            } else {
                //非首页
                qcResultAlgHomePageExt.add(qcResultAlgVO);
            }
        }

        //病案首页
        AlgorithmVO homePage = new AlgorithmVO();
        BeanUtil.copyProperties(algorithmVO, homePage);
        homePage.setQcResultAlgVOList(qcResultAlgHomePage);
        homePage.setIsHomePage(true);
        cal(homePage, qualityControlDTO);

        //病案首页以外
        AlgorithmVO homePageExt = new AlgorithmVO();
        BeanUtil.copyProperties(algorithmVO, homePageExt);
        homePageExt.setQcResultAlgVOList(qcResultAlgHomePageExt);
        cal(homePageExt, qualityControlDTO);
    }

    /**
     * 计算分数
     *
     * @param algorithmVO 操作条目的所有信息
     * @return 评分分数
     */
    private void cal(AlgorithmVO algorithmVO, QualityControlDTO qualityControlDTO) {

        //模块总分
        Map<Long, BigDecimal> casesMap = new HashMap<>();
        //单票否决计分
        Map<Long, BigDecimal> rejectScoreMap = new HashMap<>();
        //模块计分
        Map<Long, BigDecimal> casesScoreMap = new HashMap<>();
        //模块缺陷统计
        Map<Long, String> casesNameMap = new HashMap<>();
        //扣分统计
        Map<Long, BigDecimal> scoreMap = new HashMap<>();

        List<QcResultAlgVO> qcResultAlgVOList = algorithmVO.getQcResultAlgVOList();
        if (ListUtil.isNotEmpty(qcResultAlgVOList)) {
            for (QcResultAlgVO qcResultAlgVO : qcResultAlgVOList) {
                if (!casesMap.containsKey(qcResultAlgVO.getCasesId())) {
                    //模块总分
                    casesMap.put(qcResultAlgVO.getCasesId(), qcResultAlgVO.getCasesScore());
                }
                if (!casesScoreMap.containsKey(qcResultAlgVO.getCasesId())) {
                    casesScoreMap.put(qcResultAlgVO.getCasesId(), BigDecimal.ZERO);
                    rejectScoreMap.put(qcResultAlgVO.getCasesId(), BigDecimal.ZERO);
                    casesNameMap.put(qcResultAlgVO.getCasesId(), "");
                }
                //单票否决计分
                if (qcResultAlgVO.getIsReject().equals(1)) {
                    if (rejectScoreMap.containsKey(qcResultAlgVO.getCasesId())) {
                        BigDecimal casesScore = rejectScoreMap.get(qcResultAlgVO.getCasesId());
                        casesScore = casesScore.add(qcResultAlgVO.getScore());
                        rejectScoreMap.put(qcResultAlgVO.getCasesId(), casesScore);
                    }
                } else {
                    //非单票否决计分
                    if (casesScoreMap.containsKey(qcResultAlgVO.getCasesId())) {
                        BigDecimal casesScore = casesScoreMap.get(qcResultAlgVO.getCasesId());
                        casesScore = casesScore.add(qcResultAlgVO.getScore());
                        casesScoreMap.put(qcResultAlgVO.getCasesId(), casesScore);
                    }
                }
                String casesName = casesNameMap.get(qcResultAlgVO.getCasesId());
                if (StringUtils.isEmpty(casesName)) {
                    casesName = casesName + qcResultAlgVO.getMsg();
                } else {
                    casesName = casesName + ";" + qcResultAlgVO.getMsg();
                }
                casesNameMap.put(qcResultAlgVO.getCasesId(), casesName);
            }


            //模块计分
            for (Map.Entry<Long, BigDecimal> casesScore : casesScoreMap.entrySet()) {
                BigDecimal allSccore = casesMap.get(casesScore.getKey());
                if (BigDecimalUtil.le(allSccore, casesScore.getValue())) {
                    //模块标准分小于等于模块减分总和就用模块标准分
                    allSccore = allSccore.add(rejectScoreMap.get(casesScore.getKey()));
                } else {
                    //模块标准分大于模块减分总和就用模块减分总和
                    allSccore = casesScore.getValue().add(rejectScoreMap.get(casesScore.getKey()));

                }
                if (BigDecimalUtil.lt(allSccore, BigDecimal.ZERO)) {
                    allSccore = BigDecimal.ZERO;
                }
                scoreMap.put(casesScore.getKey(), allSccore);
            }


            DecimalFormat df = new DecimalFormat("0.0");

            if (StringUtils.isNotEmpty(casesNameMap.get(237L))) {
                qualityControlDTO.setAdmissionNote(casesNameMap.get(237L));
            }
            if (scoreMap.get(237L) != null) {
                qualityControlDTO.setAdmissionNoteScore(Double.valueOf(df.format(scoreMap.get(237L))));
            }


            if (StringUtils.isNotEmpty(casesNameMap.get(238L))) {
                qualityControlDTO.setFirstCourseNote(casesNameMap.get(238L));
            }
            if (scoreMap.get(238L) != null) {
                qualityControlDTO.setFirstCourseNoteScore(Double.valueOf(df.format(scoreMap.get(238L))));
            }


            if (StringUtils.isNotEmpty(casesNameMap.get(242L))) {
                qualityControlDTO.setDischargeNote(casesNameMap.get(242L));
            }
            if (scoreMap.get(242L) != null) {
                qualityControlDTO.setDischargeNoteScore(Double.valueOf(df.format(scoreMap.get(242L))));
            }


            if (StringUtils.isNotEmpty(casesNameMap.get(243L))) {
                qualityControlDTO.setMedHomePage(casesNameMap.get(243L));
            }
            if (scoreMap.get(243L) != null) {
                qualityControlDTO.setMedHomePageScore(Double.valueOf(df.format(scoreMap.get(243L))));
            }


            if (StringUtils.isNotEmpty(casesNameMap.get(280L))) {
                qualityControlDTO.setDocAdviceNote(casesNameMap.get(280L));
            }
            if (scoreMap.get(280L) != null) {
                qualityControlDTO.setDocAdviceNoteScore(Double.valueOf(df.format(scoreMap.get(280L))));
            }


            String operationInfo = "";
            if (StringUtils.isNotEmpty(casesNameMap.get(248L))) {
                operationInfo = "围手术期病历讨论:" + casesNameMap.get(248L);
            }
            if (StringUtils.isNotEmpty(casesNameMap.get(249L))) {
                operationInfo = operationInfo + ";" + "术前讨论制度:" + casesNameMap.get(249L);
            }
            if (operationInfo.contains(";")) {
                String[] split = operationInfo.split(";");
                if (StringUtils.isEmpty(split[0])) {
                    operationInfo = operationInfo.substring(operationInfo.indexOf(split[1]));
                }
            }

            qualityControlDTO.setOperationInfo(StringUtils.isEmpty(operationInfo) == true ? "无缺陷" : operationInfo);

            Double score_248 = 0d;
            Double score_11 = 0d;
            Double score_249 = 0d;
            if (scoreMap.get(248L) != null) {
                score_248 = Double.valueOf(df.format(scoreMap.get(248L)));
            }
            if (scoreMap.get(11L) != null) {
                score_11 = Double.valueOf(df.format(scoreMap.get(11L)));
            }
            if (scoreMap.get(249L) != null) {
                score_249 = Double.valueOf(df.format(scoreMap.get(249L)));
            }
            qualityControlDTO.setOperationInfoScore(score_248 + score_11 + score_249);
        }

        String courseRecord = "";
        if (StringUtils.isNotEmpty(casesNameMap.get(239L))) {
            courseRecord = "死亡病例讨论制度:" + casesNameMap.get(239L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(240L))) {
            courseRecord = courseRecord + ";" + "疑难病例讨论制度:" + casesNameMap.get(240L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(241L))) {
            courseRecord = courseRecord + ";" + "三级查房制度:" + casesNameMap.get(241L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(244L))) {
            courseRecord = courseRecord + ";" + "会诊制度:" + casesNameMap.get(244L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(245L))) {
            courseRecord = courseRecord + ";" + "分级护理制度:" + casesNameMap.get(245L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(246L))) {
            courseRecord = courseRecord + ";" + "值班及交接班制度:" + casesNameMap.get(246L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(247L))) {
            courseRecord = courseRecord + ";" + "临床用血审核制度:" + casesNameMap.get(247L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(250L))) {
            courseRecord = courseRecord + ";" + "死亡记录:" + casesNameMap.get(250L);
        }
        if (courseRecord.contains(";")) {
            String[] courseRecordSplit = courseRecord.split(";");
            if (StringUtils.isEmpty(courseRecordSplit[0])) {
                courseRecord = courseRecord.substring(courseRecord.indexOf(courseRecordSplit[1]));
            }
        }
        qualityControlDTO.setCourseRecord(StringUtils.isEmpty(courseRecord) == true ? "无缺陷" : courseRecord);


        Double score_239 = 0d;
        Double score_240 = 0d;
        Double score_241 = 0d;
        Double score_244 = 0d;
        Double score_245 = 0d;
        Double score_246 = 0d;
        Double score_247 = 0d;
        Double score_250 = 0d;
        DecimalFormat df = new DecimalFormat("0.0");
        if (scoreMap.get(239L) != null) {
            score_239 = Double.valueOf(df.format(scoreMap.get(239L)));
        }
        if (scoreMap.get(240L) != null) {
            score_240 = Double.valueOf(df.format(scoreMap.get(240L)));
        }
        if (scoreMap.get(241L) != null) {
            score_241 = Double.valueOf(df.format(scoreMap.get(241L)));
        }
        if (scoreMap.get(244L) != null) {
            score_244 = Double.valueOf(df.format(scoreMap.get(244L)));
        }
        if (scoreMap.get(245L) != null) {
            score_245 = Double.valueOf(df.format(scoreMap.get(245L)));
        }
        if (scoreMap.get(246L) != null) {
            score_246 = Double.valueOf(df.format(scoreMap.get(246L)));
        }
        if (scoreMap.get(247L) != null) {
            score_247 = Double.valueOf(df.format(scoreMap.get(247L)));
        }
        if (scoreMap.get(250L) != null) {
            score_250 = Double.valueOf(df.format(scoreMap.get(250L)));

        }
        qualityControlDTO.setCourseRecordScore(score_239 + score_240 + score_241 + score_244 + score_245 + score_246 + score_247 + score_250);
                  /*  qualityControlDTO.setCourseRecord(name_239+";"+name_240
                                    +";"+name_241+";"+name_244+";"+name_245
                                    +";"+name_246+";"+name_247+";"+name_250);
                    qualityControlDTO.setCourseRecordScore(score_239+score_240+score_241+score_244+score_245+score_246
                            +score_247+score_250);*/


        Double score_262 = 0d;
        Double score_281 = 0d;
        Double score_282 = 0d;
        Double score_283 = 0d;
        Double score_284 = 0d;
        if (scoreMap.get(262L) != null) {
            score_262 = Double.valueOf(df.format(scoreMap.get(262L)));
        }
        if (scoreMap.get(281L) != null) {
            score_281 = Double.valueOf(df.format(scoreMap.get(281L)));
        }
        if (scoreMap.get(282L) != null) {
            score_282 = Double.valueOf(df.format(scoreMap.get(282L)));
        }
        if (scoreMap.get(283L) != null) {
            score_283 = Double.valueOf(df.format(scoreMap.get(283L)));
        }
        if (scoreMap.get(284L) != null) {
            score_284 = Double.valueOf(df.format(scoreMap.get(284L)));

        }

        String otherCase = "";
        if (StringUtils.isNotEmpty(casesNameMap.get(262L))) {
            otherCase = "危急值报告制度:" + casesNameMap.get(262L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(281L))) {
            otherCase = otherCase + ";" + "危急值报告制度:" + casesNameMap.get(281L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(282L))) {
            otherCase = otherCase + ";" + "危急值报告制度:" + casesNameMap.get(282L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(283L))) {
            otherCase = otherCase + ";" + "危急值报告制度:" + casesNameMap.get(283L);
        }
        if (StringUtils.isNotEmpty(casesNameMap.get(284L))) {
            otherCase = otherCase + ";" + "危急值报告制度:" + casesNameMap.get(284L);
        }
        if (otherCase.contains(";")) {
            String[] otherCaseSplit = otherCase.split(";");
            if (StringUtils.isEmpty(otherCaseSplit[0])) {
                otherCase = otherCase.substring(otherCase.indexOf(otherCaseSplit[1]));
            }
        }
        qualityControlDTO.setOtherCase(StringUtils.isEmpty(otherCase) == true ? "无缺陷" : otherCase);
        qualityControlDTO.setOtherCaseScore(score_262 + score_281 + score_282 + score_283 + score_284);

    }


}

