package com.diagbot.facade;

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.dto.*;
import com.diagbot.entity.QcCasesEntry;
import com.diagbot.entity.SysHospitalSet;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.util.*;
import com.diagbot.vo.*;
import com.google.common.collect.Lists;
import io.github.lvyahui8.spring.aggregate.facade.DataBeanAggregateQueryFacade;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description:主任医生相关首页
 * @Author:zhaops
 * @time: 2020/5/8 17:05
 */
@Component
public class ConsoleByDeptFacade {
    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;
    @Autowired
    private QcresultInfoFacade qcresultInfoFacade;
    @Autowired
    private BasDeptInfoFacade basDeptInfoFacade;
    @Autowired
    private FilterFacade filterFacade;
    @Autowired
    private QcCasesFacade qcCasesFacade;
    @Autowired
    private SysHospitalSetFacade sysHospitalSetFacade;
    @Autowired
    private QcCasesEntryFacade qcCasesEntryFacade;
    @Autowired
    private DataBeanAggregateQueryFacade dataBeanAggregateQueryFacade;


    /**
     * 出院人数统计-按科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> leaveHosCountByDept(FilterVO filterVO) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        //关联科室
        Map<String, Object> deptMap = getDeptByUser(filterVO);
        if (deptMap == null) {
            return retMap;
        }
        try {
            Map<String, Object> invokeParams = new HashMap<>();
            invokeParams.put("filterVO", filterVO);
            retMap  = dataBeanAggregateQueryFacade.get("setAllLeaveHosCount", invokeParams, Map.class);
            long L2 = System.currentTimeMillis();
        } catch (Exception e) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR);
        }
        return retMap;
    }


    /**
     * 入院人数统计-按科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, List<AdmissionCountDTO>> admissionHosCountByDept(FilterVO filterVO) {
        filterFacade.filterVOSet(filterVO);
        List<AdmissionCountDTO> totleNumList = behospitalInfoFacade.admissionHosCountByDept(filterVO);
        Map<String, List<AdmissionCountDTO>> resourceData = mapResource(filterVO, totleNumList);
        return resourceData;
    }


    /**
     * 病历数统计-按科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> mrCountByDept(FilterVO filterVO) {
        DecimalFormat df = new DecimalFormat("#0.00");
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        //关联科室
        Map<String, Object> deptMap = getDeptByUser(filterVO);
        if (deptMap == null) {
            return retMap;
        }
        QcresultFilterVO qcresultFilterVO = new QcresultFilterVO();
        BeanUtil.copyProperties(filterVO, qcresultFilterVO);
        //质控病历数
        List<Map<String,Object>> maps = qcresultInfoFacade.resultMrCountByDept(qcresultFilterVO);
        if(ListUtil.isEmpty(maps)){
            return retMap;
        }
        for (Map<String, Object> map : maps) {
            if(null != map.get("NAME") && StringUtils.isNotBlank(map.get("NAME").toString()) && deptMap.containsKey(map.get("NAME").toString())){
                List<NumDTO> retList = Lists.newLinkedList();
                int totleNum = 0;
                int firstLevelNum = 0;
                int secondLevelNum = 0;
                int thirdLevelNum = 0;
                if(null != map.get("num")){
                    totleNum = Integer.parseInt(map.get("num").toString());
                }
                if(null != map.get("firNum")){
                    firstLevelNum = Integer.parseInt(map.get("firNum").toString());
                }
                if(null != map.get("secNum")){
                    secondLevelNum = Integer.parseInt(map.get("secNum").toString());
                }
                if(null != map.get("thrNum")){
                    thirdLevelNum = Integer.parseInt(map.get("thrNum").toString());
                }

                NumDTO totleNumDTO = new NumDTO();
                totleNumDTO.setName("累计质控病历数");
                totleNumDTO.setTotleNum(totleNum);
                totleNumDTO.setNum(totleNum);
                NumDTO firstLevelNumDTO = new NumDTO();
                firstLevelNumDTO.setName("甲级病历");
                firstLevelNumDTO.setNum(firstLevelNum);
                firstLevelNumDTO.setTotleNum(totleNum);
                Double firstPercent = BigDecimal.valueOf(firstLevelNum)
                        .divide(BigDecimal.valueOf(totleNum), 4, RoundingMode.HALF_UP)
                        .doubleValue();
                String firstPercentStr = df.format(BigDecimal.valueOf(firstPercent).multiply(BigDecimal.valueOf(100))) + "%";
                firstLevelNumDTO.setPercent(firstPercent);
                firstLevelNumDTO.setPercentStr(firstPercentStr);
                NumDTO secondLevelNumDTO = new NumDTO();
                secondLevelNumDTO.setName("乙级病历");
                secondLevelNumDTO.setNum(secondLevelNum);
                secondLevelNumDTO.setTotleNum(totleNum);
                Double secondPercent = BigDecimal.valueOf(secondLevelNum)
                        .divide(BigDecimal.valueOf(totleNum), 4, RoundingMode.HALF_UP)
                        .doubleValue();
                String secondPercentStr = df.format(BigDecimal.valueOf(secondPercent).multiply(BigDecimal.valueOf(100))) + "%";
                secondLevelNumDTO.setPercent(secondPercent);
                secondLevelNumDTO.setPercentStr(secondPercentStr);
                NumDTO thirdLevelNumDTO = new NumDTO();
                thirdLevelNumDTO.setName("丙级病历");
                thirdLevelNumDTO.setNum(thirdLevelNum);
                thirdLevelNumDTO.setTotleNum(totleNum);
                Double thirdPercent = BigDecimal.valueOf(thirdLevelNum)
                        .divide(BigDecimal.valueOf(totleNum), 4, RoundingMode.HALF_UP)
                        .doubleValue();
                String thirdPercentStr = df.format(BigDecimal.valueOf(thirdPercent).multiply(BigDecimal.valueOf(100))) + "%";
                thirdLevelNumDTO.setPercent(thirdPercent);
                thirdLevelNumDTO.setPercentStr(thirdPercentStr);
                retList.add(totleNumDTO);
                retList.add(firstLevelNumDTO);
                retList.add(secondLevelNumDTO);
                retList.add(thirdLevelNumDTO);
                retMap.put(map.get("NAME").toString(), retList);
            }
        }
        return retMap;
    }

    /**
     * 各模块缺陷占比排名-按科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> entryCountGroupByCaseAndDept(FilterVO filterVO) {
        DecimalFormat df = new DecimalFormat("#0.00");
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        if (filterVO.getLimitCount() == null || filterVO.getLimitCount().equals(0)) {
            filterVO.setLimitCount(10);
        }
        Integer limitCount = filterVO.getLimitCount();
        QcresultFilterVO qcresultFilterVO = new QcresultFilterVO();
        BeanUtil.copyProperties(filterVO, qcresultFilterVO);
        //关联科室
        Map<String, Object> deptMap = getDeptByUser(filterVO);
        if (deptMap == null) {
            return retMap;
        }
        List<NumDTO> mrNumList = qcresultInfoFacade.resultCountByDept(qcresultFilterVO);
        Map<String, NumDTO> mrMap = ListUtil.isEmpty(mrNumList)
                ? new HashMap<>()
                : EntityUtil.makeEntityMap(mrNumList, "name");
        List<DeptNumDTO> qcEntryNumList = qcresultInfoFacade.entryCountGroupByCaseAndDept(filterVO);
        Map<String, List<DeptNumDTO>> qcEntryMap = ListUtil.isEmpty(qcEntryNumList)
                ? new HashMap<>()
                : EntityUtil.makeEntityListMap(qcEntryNumList, "deptName");
        List<NumDTO> standardEntryNumList = qcCasesFacade.entryGroupByCase();
        Map<String, NumDTO> standardMap = ListUtil.isEmpty(standardEntryNumList)
                ? new HashMap<>()
                : EntityUtil.makeEntityMap(standardEntryNumList, "name");
        for (String deptName : deptMap.keySet()) {
            //没有质控病历
            if (!mrMap.containsKey(deptName)) {
                retMap.put(deptName, Lists.newLinkedList());
                continue;
            }
            //病历数
            Integer mrNum = mrMap.get(deptName).getNum();
            //缺陷模块条目未维护
            if (ListUtil.isEmpty(standardEntryNumList)) {
                retMap.put(deptName, Lists.newLinkedList());
                continue;
            }
            //没有缺陷
            if (!qcEntryMap.containsKey(deptName)) {
                retMap.put(deptName, Lists.newLinkedList());
                continue;
            }
            //模块缺陷
            List<DeptNumDTO> qcEntryNumByDeptList = qcEntryMap.get(deptName);
            if (ListUtil.isEmpty(qcEntryNumByDeptList)) {
                retMap.put(deptName, Lists.newLinkedList());
                continue;
            }
            List<NumDTO> retList = Lists.newLinkedList();
            retList = BeanUtil.listCopyTo(qcEntryNumByDeptList, NumDTO.class);
            retList.forEach(item -> {
                if (!standardMap.containsKey(item.getName())) {
                    item.setTotleNum(0);
                    item.setPercent(0d);
                    item.setPercentStr("0%");
                } else {
                    Integer totleNum = standardMap.get(item.getName()).getNum() * mrNum;
                    Double percent = BigDecimal.valueOf(item.getNum())
                            .divide(BigDecimal.valueOf(totleNum), 4, RoundingMode.HALF_UP)
                            .doubleValue();
                    String percentStr
                            = df.format(BigDecimal.valueOf(percent).multiply(BigDecimal.valueOf(100))) + "%";
                    item.setTotleNum(totleNum);
                    item.setPercent(percent);
                    item.setPercentStr(percentStr);
                }
            });

            //降序排序
            Collections.sort(retList, new Comparator<NumDTO>() {
                @Override
                public int compare(NumDTO o1, NumDTO o2) {
                    return o2.getPercent().compareTo(o1.getPercent());
                }
            });


            //取top10
            retList = retList
                    .stream()
                    .limit(limitCount)
                    .collect(Collectors.toList());
            retMap.put(deptName, retList);

        }
        return retMap;
    }


    /**
     * 条目缺陷占比-按科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> entryCountGroupByEntryAndDept(FilterVO filterVO) {
        Map<String, Object> retMap = new LinkedHashMap<>();
        filterFacade.filterVOSet(filterVO);
        Integer limitCount = filterVO.getLimitCount();
        //关联科室
        Map<String, Object> deptMap = getDeptByUser(filterVO);
        if (deptMap == null) {
            return retMap;
        }
        List<DeptNumDTO> entryList = qcresultInfoFacade.entryCountGroupByEntryAndDept(filterVO);
        Map<String, List<DeptNumDTO>> numListMap = ListUtil.isEmpty(entryList)
                ? new HashMap<>()
                : EntityUtil.makeEntityListMap(entryList, "deptName");
        for (String deptName : deptMap.keySet()) {
            if (!numListMap.containsKey(deptName)) {
                retMap.put(deptName, Lists.newLinkedList());
                continue;
            }
            List<DeptNumDTO> listByDept = numListMap.get(deptName);
            if (ListUtil.isNotEmpty(listByDept)) {
                //降序排序
                Collections.sort(listByDept, new Comparator<DeptNumDTO>() {
                    @Override
                    public int compare(DeptNumDTO o1, DeptNumDTO o2) {
                        return o2.getPercent().compareTo(o1.getPercent());
                    }
                });

                if (listByDept.size() <= limitCount) {
                    retMap.put(deptName, listByDept);
                } else {
                    retMap.put(deptName, listByDept.subList(0, limitCount));
                }
            }
        }
        return retMap;
    }

    /**
     * 用户关联科室
     *
     * @param filterVO
     * @return
     */
    public Map<String, Object> getDeptByUser(FilterVO filterVO) {
        List<DeptBaseDTO> deptList = basDeptInfoFacade.getDeptByUser(filterVO);
        if (ListUtil.isNotEmpty(deptList)) {
            return EntityUtil.makeMapWithKeyValue(deptList, "deptName", "deptId");
        } else {
            return null;
        }
    }

    /**
     * 获取关联科室
     *
     * @param
     * @return
     */
    public List<DeptBaseDTO> getDept() {
        FilterVO filterVO = new FilterVO();
        String hospitalId = SysUserUtils.getCurrentHospitalID();
        String userId = SysUserUtils.getCurrentPrincipleID();
        filterVO.setHospitalId(hospitalId);
        filterVO.setUserId(Long.valueOf(userId));
        List<DeptBaseDTO> deptList = basDeptInfoFacade.getDeptByUser(filterVO);
        return deptList;
    }


    /**
     * 各模块缺陷占比-科室（分页）
     *
     * @param filterPageByDeptVO
     * @return
     */
    public IPage<NumDTO> entryCountGroupByCaseAndDeptPage(FilterPageByDeptVO filterPageByDeptVO) {
        if (StringUtil.isBlank(filterPageByDeptVO.getDeptName())) {
            List<DeptBaseDTO> deptList = this.getDept();
            //默认取第一个科室
            if (ListUtil.isNotEmpty(deptList)) {
                filterPageByDeptVO.setDeptName(deptList.get(0).getDeptName());
            }
        }
        filterFacade.filterPageByDeptVOSet(filterPageByDeptVO);
        IPage<NumDTO> page = qcresultInfoFacade.entryCountGroupByCaseAndDeptPage(filterPageByDeptVO);
        return page;
    }

    /**
     * 缺陷详情-科室（分页）
     *
     * @param filterPageByDeptVO
     * @return
     */
    public IPage<EntryNumGroupDTO> entryCountGroupByEntryAndDeptPage(FilterPageByDeptVO filterPageByDeptVO) {
        if (StringUtil.isBlank(filterPageByDeptVO.getDeptName())) {
            List<DeptBaseDTO> deptList = this.getDept();
            //默认取第一个科室
            if (ListUtil.isNotEmpty(deptList)) {
                filterPageByDeptVO.setDeptName(deptList.get(0).getDeptName());
            }
        }
        if (filterPageByDeptVO.getDeptName().equals(filterPageByDeptVO.getDoctorName())) {
            filterPageByDeptVO.setDoctorName("");
        }
        filterFacade.filterPageByDeptVOSet(filterPageByDeptVO);
        IPage<EntryNumGroupDTO> page = qcresultInfoFacade.entryCountGroupByEntryAndDeptPage(filterPageByDeptVO);
        return page;
    }

    /**
     * 缺陷明细-科室（分页）
     *
     * @param filterPageByDeptVO
     * @return
     */
    public IPage<DeptNumDTO> resultStatisticsByDeptAndDoctorPage(FilterPageByDeptVO filterPageByDeptVO) {
        if (StringUtil.isBlank(filterPageByDeptVO.getDeptName())) {
            List<DeptBaseDTO> deptList = this.getDept();
            //默认取第一个科室
            if (ListUtil.isNotEmpty(deptList)) {
                filterPageByDeptVO.setDeptName(deptList.get(0).getDeptName());
            }
        }
        filterFacade.filterPageByDeptVOSet(filterPageByDeptVO);
        IPage<DeptNumDTO> page = behospitalInfoFacade.resultStatisticsByDeptAndDoctorPage(filterPageByDeptVO);
        return page;
    }

    /**
     * 条目缺陷占比-科室（内页）
     *
     * @param filterPageByDeptVO
     * @return
     */
    public IPage<DeptEntryNumDTO> entryGroupByEntryAndDeptInnerPage(FilterPageByDeptVO filterPageByDeptVO) {
        if (StringUtil.isBlank(filterPageByDeptVO.getDeptName())) {
            List<DeptBaseDTO> deptList = this.getDept();
            //默认取第一个科室
            if (ListUtil.isNotEmpty(deptList)) {
                filterPageByDeptVO.setDeptName(deptList.get(0).getDeptName());
            }
        }
        filterFacade.filterPageByDeptVOSet(filterPageByDeptVO);
        IPage<DeptEntryNumDTO> page = qcresultInfoFacade.entryGroupByEntryAndDeptInnerPage(filterPageByDeptVO);
        return page;
    }

    /**
     * 各科室缺陷占比（组合）
     *
     * @param filterOrderVO
     * @return
     */
    public List<LevelStsByDeptDTO> levelStatisticsByDept(FilterOrderVO filterOrderVO) {
        List<DeptBaseDTO> deptList = getDept();
        if (ListUtil.isEmpty(deptList)) {
            return null;
        }
        if (StringUtil.isBlank(filterOrderVO.getDeptName())) {
            filterOrderVO.setDeptName(deptList.get(0).getDeptName());
        }
        filterFacade.filterOrderVOSame(filterOrderVO);
        List<LevelStsByDeptDTO> records = behospitalInfoFacade.levelStatisticsByDept(filterOrderVO);
        if(ListUtil.isNotEmpty(records)){
            for (LevelStsByDeptDTO record : records) {
                BigDecimalMethod(record);
            }
        }
        return records;
    }

    public void BigDecimalMethod(LevelStsByDeptDTO 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 filterOrderByDeptVO
     * @return
     */
    public List<HomePageByDeptDTO> homePageLevelStatisticsByDept(FilterOrderByDeptVO filterOrderByDeptVO) {
        List<DeptBaseDTO> deptList = getDept();
        if (ListUtil.isEmpty(deptList)) {
            return null;
        }
        if (StringUtil.isBlank(filterOrderByDeptVO.getDeptName())) {
            filterOrderByDeptVO.setDeptName(deptList.get(0).getDeptName());
        }
        filterFacade.filterOrderByDeptVOSet(filterOrderByDeptVO);
        List<HomePageByDeptDTO> records = behospitalInfoFacade.homePageLevelStatisticsByDept(filterOrderByDeptVO);
        //没有医生过滤时增加全科室数据 --暂时不做汇总处理
       /* if (StringUtil.isBlank(filterOrderByDeptVO.getDeptName())
                || filterOrderByDeptVO.getDeptName().equals(filterOrderByDeptVO.getDeptName())) {
            HomePageByDeptDTO item = getGlobleRecord(records, filterOrderByDeptVO.getDeptName());
            if (item != null) {
                records.add(0, item);
            }
        }*/
        return records;
    }

    /**
     * 单条条目缺陷统计（首页）
     *
     * @param filterVO
     * @return
     */
    public  Map<String, List<AdmissionCountDTO>>casesEntryStatisticsByDept(FilterVO filterVO) {
        filterFacade.filterVOSet(filterVO);
        List<AdmissionCountDTO> totleNumList = behospitalInfoFacade.casesEntryStatisticsByDept(filterVO);
        Map<String, List<AdmissionCountDTO>> resourceData = mapResource(filterVO, totleNumList);
        return resourceData;
    }

    public Map<String, List<AdmissionCountDTO>> mapResource(FilterVO filterVO,List<AdmissionCountDTO>totleNumList){
        Map<String, Object> deptMap = getDeptByUser(filterVO);
            Map<String, List<AdmissionCountDTO>> mapSource = new HashMap<>();
            Map<String, List<AdmissionCountDTO>> returnSource = new HashMap<>();
            if (deptMap == null) {
                return mapSource;
            }

            if(ListUtil.isNotEmpty(totleNumList)) {
                mapSource = EntityUtil.makeEntityListMap(totleNumList, "deptName");
                for (String deptName : deptMap.keySet()) {
                    List<AdmissionCountDTO> admissionCountDTOS = mapSource.get(deptName);
                if(ListUtil.isNotEmpty(admissionCountDTOS) ){
//                    if ( admissionCountDTOS.size()> filterVO.getLimitCount()) {
//                        admissionCountDTOS = admissionCountDTOS.subList(0, 10);
//                      }
                    AdmissionCountDTO admissionCount = new AdmissionCountDTO();
                    Integer tolCount = admissionCountDTOS.stream()
                            .map(AdmissionCountDTO::getNum)
                            .reduce(0, Integer::sum);
                    admissionCount.setDoctorName(deptName);
                    admissionCount.setNum(tolCount);
                    admissionCountDTOS.add(0, admissionCount);
                    returnSource.put(deptName,admissionCountDTOS);
                    }
                }
            }
            return returnSource;
        }
    /**
     * 不合格/合格数病历号-科室（内页）
     *
     * @param qcResultPageVO
     * @return
     */
    public IPage<QcResultShortDTO> homePageOrGoodLevelByDept(QcResultPageVO qcResultPageVO) {
        filterFacade.OrGoodLevelPageVOSet(qcResultPageVO);
        return behospitalInfoFacade.getOrGoodLevelByDept(qcResultPageVO);
    }




    /**
     * 病案首页合格率占比（首页）
     *
     * @param filterOrderByDeptVO
     * @return
     */
    public List<HomePageByDeptDTO> homePageLevelByDeptLimit(FilterOrderByDeptVO filterOrderByDeptVO) {

        List<DeptBaseDTO> deptList = getDept();
        if (ListUtil.isEmpty(deptList)) {
            return null;
        }
        if (StringUtil.isBlank(filterOrderByDeptVO.getDeptName())) {
            filterOrderByDeptVO.setDeptName(deptList.get(0).getDeptName());
        }
        filterFacade.filterOrderByDeptVOSet(filterOrderByDeptVO);
        if (filterOrderByDeptVO.getLimitCount() == null || filterOrderByDeptVO.getLimitCount().equals(0)) {
            filterOrderByDeptVO.setLimitCount(10);
        }
        List<HomePageByDeptDTO> records = behospitalInfoFacade.homePageLevelStatisticsByDept(filterOrderByDeptVO);
        HomePageByDeptDTO item = getGlobleRecord(records, filterOrderByDeptVO.getDeptName());
        if (item != null) {
            records.add(0, item);
        }

        records = records
                .stream()
                .limit(filterOrderByDeptVO.getLimitCount())
                .collect(Collectors.toList());

        return records;
    }

    /**
     * 获取某个科室全科室数据
     *
     * @param records
     * @param deptName
     * @return
     */
    public HomePageByDeptDTO getGlobleRecord(List<HomePageByDeptDTO> records, String deptName) {
        DecimalFormat df = new DecimalFormat("#0.00");
        HomePageByDeptDTO item = new HomePageByDeptDTO();
        //总病历数
        Integer mrNum = records
                .stream()
                .map(HomePageByDeptDTO::getMrNum)
                .reduce(0, Integer::sum);
        if (mrNum == null || mrNum == 0) {
            return null;
        }
        //总缺陷数
        Integer entryNum = records
                .stream()
                .map(HomePageByDeptDTO::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(HomePageByDeptDTO::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(HomePageByDeptDTO::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(HomePageByDeptDTO::getEntryTotleNum)
                .reduce(0, Integer::sum);
        //空项总数
        Integer emptyNum = records
                .stream()
                .map(HomePageByDeptDTO::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(HomePageByDeptDTO::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.setDoctorName(deptName);
//        item.setDeptId(deptId);
        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> qcResultShortByDeptPage(QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        IPage<QcResultShortDTO> page = behospitalInfoFacade.qcResultShortByDeptPage(qcResultShortPageVO);
        return page;
    }


    /**
     * 关键条目缺陷占比统计-科室
     *
     * @param entryStatisticsVO
     * @return
     */
    public List<EntryStasByDeptDTO> entryStatisticsByDept(EntryStatisticsVO entryStatisticsVO) {
        filterFacade.entryStatisticsVOSet(entryStatisticsVO);
        if (entryStatisticsVO.getDeptName().equals("全院")) {
            entryStatisticsVO.setDeptName("");
        }
        List<EntryStasByDeptDTO> records = behospitalInfoFacade.entryStatisticsByDept(entryStatisticsVO);
        return records;
    }

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

    /**
     * 质控核查统计-科室（内页）
     *
     * @param filterOrderVO
     * @return
     */
    public List<ImproveByDeptDTO> qcCheckStatisticsByDept(FilterOrderVO filterOrderVO) {
        filterFacade.filterOrderVOSet(filterOrderVO);
        List<ImproveByDeptDTO> records = behospitalInfoFacade.qcCheckStatisticsByDept(filterOrderVO);
        return records;
    }
    /**
     * 质控核查质控评分页-科室（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> qcCheckMRPageByDept(@Param("qcResultShortPageVO") QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.qcCheckMRPageByDept(qcResultShortPageVO);
    }
    /**
     * 病案首页改善率质控评分页-科室（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> hmImproveMRPageByDept(@Param("qcResultShortPageVO") QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.hmImproveMRPageByDept(qcResultShortPageVO);
    }

    /**
     * 31天再入院详情页-科室
     *
     * @param reBeHosPageVO
     * @return
     */
    public IPage<ReBeHosByDeptDTO> reHos31DaysPageByDept(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.reHos31DaysPageByDept(reBeHosPageVO);
        List<ReBeHosMergeDTO> records = page.getRecords();
        IPage<ReBeHosByDeptDTO> retPage = new Page<>();
        if (ListUtil.isNotEmpty(records)) {
            List<ReBeHosByDeptDTO> retRecords = Lists.newLinkedList();
            BeanUtil.copyProperties(page, retPage);
            Iterator<ReBeHosMergeDTO> iterator = records.iterator();
            while(iterator.hasNext()){
                ReBeHosMergeDTO record = iterator.next();
                strTrans(record);
                Boolean flag = ConsoleFacade.isContainDiagnose(record);
                if(!flag){
                    iterator.remove();
                    continue;
                }
                ReBeHosByDeptDTO retRecord = new ReBeHosByDeptDTO();
                BeanUtil.copyProperties(record, retRecord);
                List<ReBeHosDetailByDeptDTO> details = Lists.newLinkedList();
                ReBeHosDetailByDeptDTO detailRecord = new ReBeHosDetailByDeptDTO();
                BeanUtil.copyProperties(record, detailRecord);
                details.add(detailRecord);
                ReBeHosDetailByDeptDTO lastDetailRecord = new ReBeHosDetailByDeptDTO();
                lastDetailRecord.setName(record.getName());
                lastDetailRecord.setBehDeptId(record.getLastBehDeptId());
                lastDetailRecord.setBehDeptName(record.getLastBehDeptName());
                lastDetailRecord.setDoctorName(record.getLastDoctorName());
                lastDetailRecord.setDiagnose(record.getLastDiagnose());
                lastDetailRecord.setDiagnoseName(record.getLastDiagnoseName());
                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()==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;
    }

    public static void strTrans(ReBeHosMergeDTO record) {
        String replace = record.getLastAgainBehospitalPlan();
        if(StringUtils.isEmpty(replace)){
            replace = "否";
            record.setLastAgainBehospitalPlan(replace);
            return;
        }
        replace = replace.replace("无", "否")
                .replace("-", "无").replace("是一周后", "是")
                .replace("1", "否").replace("2", "是")
                .replace("有", "是");
        record.setLastAgainBehospitalPlan(replace);
    }
    /**
     * 未整改病历质控评分页-科室（内页）
     *
     * @param qcResultShortPageVO
     * @return
     */
    public IPage<QcResultShortDTO> unModifyMRByDept(QcResultShortPageVO qcResultShortPageVO) {
        filterFacade.qcResultShortPageVOSet(qcResultShortPageVO);
        return behospitalInfoFacade.unModifyMRByDept(qcResultShortPageVO);
    }
    /**
     * 病历稽查表导出-科室
     *
     * @param filterVO
     * @return
     */


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




    /**
     * 病历稽查表（title）-科室
     *
     * @param
     * @return
     */
    public List<ColumnDTO> medicalCheckTitleKs() {
        //病历稽查入参拼接
        String hospitalId = SysUserUtils.getCurrentHospitalID();
        //colums
        QueryWrapper<SysHospitalSet> hospitalSetQueryWrapper = new QueryWrapper<>();
        hospitalSetQueryWrapper.eq("is_deleted", 'N')
                .eq("hospital_id", hospitalId)
                .eq("code", "medical_check_form_ks");
        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("doctorId");
        columnDeptId.setColumnName("医生编码");
        columnDeptId.setIsShow(0);
        columns.add(columnDeptId);
        orderNo++;
        ColumnDTO columnDeptName = new ColumnDTO();
        columnDeptName.setOrderNo(orderNo);
        columnDeptName.setFieldName("doctorName");
        columnDeptName.setColumnName("主管医生");
        columnDeptName.setIsShow(1);
        columns.add(columnDeptName);
        orderNo++;
        ColumnDTO columnMedicalName = new ColumnDTO();
        columnMedicalName.setOrderNo(orderNo);
        columnMedicalName.setFieldName("doctorGroup");
        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 filterVO
     * @return
     */
    public IPage<MedicalCheckDTO> getMedicalChecks(@Param("filterVO") FilterMedicalCheckVO filterVO) {
        filterFacade.getMedicalCheckVOSet(filterVO);
        //colums
        QueryWrapper<SysHospitalSet> hospitalSetQueryWrapper = new QueryWrapper<>();
        hospitalSetQueryWrapper.eq("is_deleted", 'N')
                .eq("hospital_id", filterVO.getHospitalId())
                .eq("code", "medical_check_form_ks");
        SysHospitalSet hospitalSet = sysHospitalSetFacade.getOne(hospitalSetQueryWrapper);

        //表头生成
        List<String> columnSet = Arrays.asList(hospitalSet.getValue().split(","));

        //目标条目
        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]));
            }
        }
        IPage<MedicalCheckDTO> medicalCheck = behospitalInfoFacade.getMedicalChecks(filterVO,casesEntryIds);
        return medicalCheck;
    }

    /**
     * 病历质控报表-科室
     *
     * @param behospitalPageVO
     * @return
     */
    public IPage<QualityControlDeptDTO> qualityControlByDept(@Param("filterVO")  BehospitalPageVO behospitalPageVO) {
        behospitalPageSet(behospitalPageVO);
        IPage<QualityControlDeptDTO> records = behospitalInfoFacade.qualityControlByDept(behospitalPageVO);
        List<QualityControlDeptDTO> 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;
    }


    /**
     * 未整改病历统计-科室
     *
     * @param filterUnModifyMRVO
     * @return
     */
    public UnModifyMRDTO unModifyMRSByDept(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_ks");
        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("doctorId");
        columnDeptId.setColumnName("医生编码");
        columnDeptId.setIsShow(0);
        columns.add(columnDeptId);
        orderNo++;
        ColumnDTO columnDeptName = new ColumnDTO();
        columnDeptName.setOrderNo(orderNo);
        columnDeptName.setFieldName("doctorName");
        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.unModifyMRSByDept(filterUnModifyMRVO);
        //以科室分组，将符合科室的每条数据以map形式存储
        Map<String, List<UnModifyMRDetailDTO>> deptMap = EntityUtil.makeEntityListMap(records, "doctorName");
        //科室对应科室id
        Map<String, String> deptInfoMap = EntityUtil.makeMapWithKeyValue(records, "doctorName", "doctorId");
        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("doctorName", Class.forName("java.lang.String"));
                addValMap.put("doctorName", entry.getKey());
                addMap.put("doctorId", Class.forName("java.lang.String"));
                addValMap.put("doctorId", 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;
    }

    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.setUserId(Long.valueOf(SysUserUtils.getCurrentPrincipleID()));
    }

    /**
     * 评结果分数(长兴)
     *
     * @param algorithmVO 操作条目的所有信息
     * @return 评结果分数
     */
    private void getScoreForCx(AlgorithmVO algorithmVO,QualityControlDeptDTO 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 ,QualityControlDeptDTO 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);

    }

}
