package com.diagbot.facade;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.diagbot.client.AuthServiceClient;
import com.diagbot.dto.*;
import com.diagbot.entity.*;
import com.diagbot.enums.*;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.impl.BehospitalInfoServiceImpl;
import com.diagbot.service.impl.QcresultDetailServiceImpl;
import com.diagbot.service.impl.StrInformedConsentServiceImpl;
import com.diagbot.util.*;
import com.diagbot.vo.*;
import com.google.common.collect.Lists;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: zhoutg
 * @time: 2024/4/12 11:39
 */
@Component
public class BehospitalInfoFacade extends BehospitalInfoServiceImpl {

    @Autowired
    QcClientFacade qcServiceClient;
    @Autowired
    DoctorAdviceFacade doctorAdviceFacade;
    @Autowired
    HomePageFacade homePageFacade;
    @Autowired
    private QcCasesEntryFacade qcCasesEntryFacade;
    @Autowired
    HomeDiagnoseInfoFacade homeDiagnoseInfoFacade;
    @Autowired
    HomeOperationInfoFacade homeOperationInfoFacade;
    @Autowired
    MedicalRecordFacade medicalRecordFacade;
    @Autowired
    BasHospitalInfoFacade basHospitalInfoFacade;
    @Autowired
    private AlgorithmFacade algorithmFacade;
    @Autowired
    SysDictionaryFacade sysDictionaryFacade;
    @Autowired
    private QcresultInfoFacade qcresultInfoFacade;
    @Autowired
    QcModeFacade qcModeFacade;
    @Autowired
    AuthServiceClient authServiceClient;
    @Autowired
    QcCasesEntryPagedataFacade qcCasesEntryPagedataFacade;
    @Value("${encrypt.enable}")
    Boolean encryptFlag;
    @Autowired
    QcQuestionFacade qcQuestionFacade;
    @Autowired
    QcModelHospitalFacade qcModelHospitalFacade;
    @Autowired
    private FilterFacade filterFacade;
    @Autowired
    MedLisInfoFacade medLisInfoFacade;
    @Autowired
    MedLisResultFacade medLisResultFacade;
    @Autowired
    MedPacsResultFacade medPacsResultFacade;
    @Autowired
    MedCrisisInfoFacade medCrisisInfoFacade;
    @Autowired
    MedExamineInfoFacade medCheckInfoFacade;
    @Autowired
    MedRejectedInfoFacade medRejectedInfoFacade;
    @Autowired
    StrConsultationApplyFacade strConsultationApplyFacade;
    @Autowired
    StrConsultationResultFacade strConsultationResultFacade;
    @Autowired
    StrConsultationNoteFacade strConsultationNoteFacade;
    @Autowired
    StrConsultationRecordFacade strConsultationRecordFacade;
    @Autowired
    StrAdmissionNoteFacade strAdmissionNoteFacade;
    @Autowired
    StrBloodResultFacade strBloodResultFacade;
    @Autowired
    StrBloodTransfusionFacade strBloodTransfusionFacade;
    @Autowired
    StrCrisisNoteFacade strCrisisNoteFacade;
    @Autowired
    StrDeathDiscussionFacade strDeathDiscussionFacade;
    @Autowired
    StrDeathNoteFacade strDeathNoteFacade;
    @Autowired
    StrDifficultCaseFacade strDifficultCaseFacade;
    @Autowired
    StrFirstRecordFacade strFirstRecordFacade;
    @Autowired
    StrIllCriticallyFacade strIllCriticallyFacade;
    @Autowired
    StrIllSeriouslFacade strIllSeriouslFacade;
    @Autowired
    StrLeaveHospitalFacade strLeaveHospitalFacade;
    @Autowired
    StrOperativeFirstRecordFacade strOperativeFirstRecordFacade;
    @Autowired
    StrOperativeNoteFacade strOperativeNoteFacade;
    @Autowired
    StrPeriodConclusionFacade strPeriodConclusionFacade;
    @Autowired
    StrPreoperativeDiscussionFacade strPreoperativeDiscussionFacade;
    @Autowired
    StrRescueNoteFacade strRescueNoteFacade;
    @Autowired
    StrTransferInNoteFacade strTransferInNoteFacade;
    @Autowired
    StrTransferOutNoteFacade strTransferOutNoteFacade;
    @Autowired
    StrWardRecordFacade strWardRecordFacade;
    @Autowired
    MedTransferRecordFacade medTransferRecordFacade;
    @Autowired
    MedNurseFacade medNurseFacade;
    @Autowired
    SysHospitalSetFacade sysHospitalSetFacade;
    @Autowired
    QcCasesRelevanceEntryFacade qcCasesRelevanceEntryFacade;
    @Autowired
    StrInformedConsentServiceImpl strInformedConsentServiceImpl;

    @Autowired
    SysUserRoleFacade sysUserRoleFacade;
    @Autowired
    QcresultDetailFacade qcresultDetailFacade;

    @Autowired
    BasDeptInfoFacade basDeptInfoFacade;

    @Autowired
    private BehospitalInfoFacade behospitalInfoFacade;
    @Autowired
    @Qualifier("qcresultDetailServiceImpl")
    private QcresultDetailServiceImpl qcresultDetailServiceImpl;

    private TZDBConn tzDBConn = new TZDBConn();

    /**
     * 分页
     *
     * @param behospitalPageVO
     * @return
     */
    public IPage<BehospitalInfoDTO> pageFac(BehospitalPageVO behospitalPageVO) {
        behospitalPageSet(behospitalPageVO);
        IPage<BehospitalInfoDTO> res = getPage(behospitalPageVO);
        return res;
    }

    /**
     * 获取明细
     *
     * @param getDetailVO
     * @return
     */
    public Map<String, Object> getByBehospitalCode(GetDetailVO getDetailVO) {
        Map<String, Object> res = new HashMap<>(); // 返回结果
        Long hospitalId = Long.parseLong(SysUserUtils.getCurrentHospitalID());
        getDetailVO.setHospitalId(hospitalId);
        // 获取病历信息
        BehospitalInfo behospitalInfo = this.getOne(new QueryWrapper<BehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", getDetailVO.getHospitalId())
                .eq("behospital_code", getDetailVO.getBehospitalCode()), false
        );

        // 获取患者年龄
        HomePage homePage = homePageFacade.getOne(new QueryWrapper<HomePage>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", getDetailVO.getHospitalId())
                .eq("behospital_code", getDetailVO.getBehospitalCode()), false
        );

        List<String> paramList = getDetailVO.getParamStr();// 参数列表

        if (ListUtil.isEmpty(paramList) || paramList.contains("beHospital")) {
            BehosDTO behosDTO = new BehosDTO();
            if (behospitalInfo == null) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病历已删除!");
            }
            BeanUtil.copyProperties(behospitalInfo, behosDTO);
            if (null != homePage && StringUtils.isNotEmpty(homePage.getAge()) && StringUtils.isNotEmpty(homePage.getAgeUnit())) {
                behosDTO.setAge(homePage.getAge() + homePage.getAgeUnit());
            }
            res.put("beHospital", behosDTO);
        }

        if (ListUtil.isEmpty(paramList) || paramList.contains("result") || paramList.contains("resultSimple")) {
            // 获取结果主表信息
            QcResultDTO qcResultDTO = qcresultInfoFacade.getByBehospitalCode(getDetailVO);
            if (qcResultDTO == null) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病历未评分!");
            }
            if (paramList.contains("resultSimple")) {
                qcResultDTO.setPageData("");
                qcResultDTO.setMenuData("");
            }
            res.put("result", qcResultDTO);
            //通过页面类型显示不同操作按钮
            showButtonByPageType(hospitalId, getDetailVO, res);
            //添加核查操作是否与申诉状态关联配置
            if (StringUtil.isBlank(sysHospitalSetFacade.getValue(hospitalId, "check_operation_with_appeal"))) {
                res.put("checkOperationWithAppeal", false);
            } else {
                res.put("checkOperationWithAppeal", Boolean.parseBoolean(sysHospitalSetFacade.getValue(hospitalId, "check_operation_with_appeal")));
            }
//            //增加该病历是否核查状态
//            QueryWrapper<MedCheckInfo> medCheckInfoQuerys = new QueryWrapper<>();
//            medCheckInfoQuerys.eq("is_deleted", IsDeleteEnum.N.getKey());
//            medCheckInfoQuerys.eq("behospital_code", getDetailVO.getBehospitalCode());
//            medCheckInfoQuerys.eq("hospital_id", hospitalId);
//            medCheckInfoQuerys.in("check_type", 0, 2);
//            medCheckInfoQuerys.eq("status", 1);
//            int count = medCheckInfoFacade.count(medCheckInfoQuerys);
//            if (count > 0) {
//                res.put("checkStatus", 1);
//            } else {
//                res.put("checkStatus", 0);
//            }
//            //增加该病案首页是否核查状态
//            Map<String, Object> mapAllMr = new HashMap<String, Object>();
//            mapAllMr.put("is_deleted", IsDeleteEnum.N.getKey());
//            mapAllMr.put("behospital_code", getDetailVO.getBehospitalCode());
//            mapAllMr.put("hospital_id", hospitalId);
//            mapAllMr.put("check_type", 1);
//            QueryWrapper<MedCheckInfo> medCheckInfoMr = new QueryWrapper<>();
//            medCheckInfoMr.allEq(mapAllMr);
//            int countMr = medCheckInfoFacade.count(medCheckInfoMr);
//            if (countMr > 0) {
//                res.put("mrStatus", 1);
//            } else {
//                res.put("mrStatus", 0);
//            }
            //新增如果当前用户不是核查人员返回标志位用户核查按钮、修改、删除、隐藏显示
            //1.获取病历核查人员id，该操作只能是核查员操作
//            List<MedCheckInfo> medCheckInfos = medCheckInfoFacade.list(new QueryWrapper<MedCheckInfo>()
//                    .eq("is_deleted", IsDeleteEnum.N.getKey())
//                    .eq("hospital_id", hospitalId)
//                    .eq("behospital_code", getDetailVO.getBehospitalCode()));
//            if (medCheckInfos.size() == 1 && medCheckInfos.get(0).getCheckId() != null
//                    && medCheckInfos.get(0).getCheckId().equals(Long.parseLong(SysUserUtils.getCurrentPrincipleID()))) {
//                //2.1获取核查类型，判断当前用户有没有对应核查类型的角色
//                int jobType = medCheckInfoFacade.list(new QueryWrapper<MedCheckInfo>()
//                        .eq("is_deleted", IsDeleteEnum.N.getKey())
//                        .eq("behospital_code", getDetailVO.getBehospitalCode())
//                        .eq("hospital_id", hospitalId)
//                        .eq("check_id", SysUserUtils.getCurrentPrincipleID())).get(0).getJobType();
//                //2.2获取用户角色
//                List<Long> roleIds = sysUserRoleFacade.list(new QueryWrapper<SysUserRole>()
//                        .eq("is_deleted", IsDeleteEnum.N.getKey())
//                        .eq("user_id", SysUserUtils.getCurrentPrincipleID())
//                ).stream().distinct().map(SysUserRole::getRoleId).collect(Collectors.toList());
//                switch (jobType) {
//                    case 0:
//                        if (roleIds.contains(CheckerRoleEnum.DEPT_GENERAL.getKey() * 1l)) {
//                            res.put("checkShow", 1);
//                        } else {
//                            res.put("checkShow", 0);
//                        }
//                        break;
//                    case 1:
//                        if (roleIds.contains(CheckerRoleEnum.QUAT_GENERAL.getKey() * 1l)) {
//                            res.put("checkShow", 1);
//                        } else {
//                            res.put("checkShow", 0);
//                        }
//                        break;
//                    case 2:
//                        if (roleIds.contains(CheckerRoleEnum.HOSP_GENERAL.getKey() * 1l)) {
//                            res.put("checkShow", 1);
//                        } else {
//                            res.put("checkShow", 0);
//                        }
//                        break;
//                    default:
//                        res.put("checkShow", 0);
//                        break;
//                }
//
//            } else {
//                res.put("checkShow", 0);
//            }
//            //获取用户角色，如果用户包含核查角色显示核查相关按钮(不管病历是否生成、分配，只要有质控角色就显示核查对应按钮）
//            List<Long> roleIds = sysUserRoleFacade.list(new QueryWrapper<SysUserRole>()
//                    .eq("is_deleted", IsDeleteEnum.N.getKey())
//                    .eq("user_id", SysUserUtils.getCurrentPrincipleID())
//            ).stream().distinct().map(SysUserRole::getRoleId).collect(Collectors.toList());
//            if (roleIds.contains(CheckerRoleEnum.DEPT_GENERAL.getKey() * 1l)) {
//                res.put("checkShow", 1);
//            } else if (roleIds.contains(CheckerRoleEnum.QUAT_GENERAL.getKey() * 1l)) {
//                res.put("checkShow", 1);
//            } else if (roleIds.contains(CheckerRoleEnum.HOSP_GENERAL.getKey() * 1l)) {
//                res.put("checkShow", 1);
//            } else {
//                res.put("checkShow", 0);
//            }
        }

        // 获取提示信息
        if (ListUtil.isEmpty(paramList) || paramList.contains("msg")) {
            AnalyzeVO analyzeVO = new AnalyzeVO();
            BeanUtil.copyProperties(getDetailVO, analyzeVO);
            QcresultInfo qcresultInfo = qcresultInfoFacade.getOne(new QueryWrapper<QcresultInfo>()
                    .eq("hospital_id", analyzeVO.getHospitalId())
                    .eq("behospital_code", analyzeVO.getBehospitalCode())
                    .eq("is_deleted", IsDeleteEnum.N.getKey()));
            if (qcresultInfo != null && qcresultInfo.getId() != null) {
                analyzeVO.setQcresultInfoId(qcresultInfo.getId());
            }
            List<MsgDTO> msgDTOList = getMsg(analyzeVO);

            if (ListUtil.isEmpty(msgDTOList)) {
                analyzeVO.setQcresultInfoId(null);
                msgDTOList = getMsg(analyzeVO);
            }

            if (ListUtil.isNotEmpty(msgDTOList)) {
                // 从qc_question_info的cases_entry_ids获取
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("hospitalId", hospitalId);
                paramMap.put("casesEntryIds", msgDTOList.stream().map(r -> r.getCasesEntryId()).collect(Collectors.toList()));
                Map<Long, List<QuestionEntryDTO>> quesEntryMap = qcQuestionFacade.getByCaseEntryIdsFac(paramMap);
                for (MsgDTO msgDTO : msgDTOList) {
                    if (quesEntryMap.get(msgDTO.getCasesEntryId()) != null) {
                        msgDTO.setPageKeyList(quesEntryMap.get(msgDTO.getCasesEntryId())
                                .stream().map(r -> r.getId()).collect(Collectors.toList()));
                    }
                }
            }
            // 根据模块分组
            Map<String, List<MsgDTO>> msgMap = EntityUtil.makeEntityListMap(msgDTOList, "modelName");
            res.put("msg", msgMap);

            // 添加DRGS分组
            List<MsgDTO> msgDTOListDrgs = msgDTOList.stream().filter(r -> r.getDrgs().equals(1)).collect(Collectors.toList());
            Map<String, List<MsgDTO>> drgsMap = EntityUtil.makeEntityListMap(msgDTOListDrgs, "modelName");
            res.put("drgs", drgsMap);
        }

        return res;
    }

    private void showButtonByPageType(Long hospitalId, GetDetailVO getDetailVO, Map<String, Object> res) {
        //        switch (getDetailVO.getPageType()){
        //            case "1":
        //                break;
        //            case "2":
        //                checkButtonShow(hospitalId,getDetailVO,res);
        //                break;
        //            case "3":
        //                appealButtonShow(hospitalId,getDetailVO,res);
        //                break;
        //            default:
        //                break;
        //        }
        checkButtonShow(hospitalId, getDetailVO, res);
        appealButtonShow(hospitalId, getDetailVO, res);
    }

    private void checkButtonShow(Long hospitalId, GetDetailVO getDetailVO, Map<String, Object> res) {
        //增加该病历是否核查状态
        QueryWrapper<MedExamineInfo> medCheckInfoQuerys = new QueryWrapper<>();
        medCheckInfoQuerys.eq("is_deleted", IsDeleteEnum.N.getKey());
        medCheckInfoQuerys.eq("behospital_code", getDetailVO.getBehospitalCode());
        medCheckInfoQuerys.eq("hospital_id", hospitalId);
        medCheckInfoQuerys.in("check_type", 0, 2);
        medCheckInfoQuerys.eq("status", 1);
        int count = medCheckInfoFacade.count(medCheckInfoQuerys);
        if (count > 0) {
            res.put("checkStatus", 1);
        } else {
            res.put("checkStatus", 0);
        }
        //增加该病案首页是否核查状态
        Map<String, Object> mapAllMr = new HashMap<String, Object>();
        mapAllMr.put("is_deleted", IsDeleteEnum.N.getKey());
        mapAllMr.put("behospital_code", getDetailVO.getBehospitalCode());
        mapAllMr.put("hospital_id", hospitalId);
        mapAllMr.put("check_type", 1);
        QueryWrapper<MedExamineInfo> medCheckInfoMr = new QueryWrapper<>();
        medCheckInfoMr.allEq(mapAllMr);
        int countMr = medCheckInfoFacade.count(medCheckInfoMr);
        if (countMr > 0) {
            res.put("mrStatus", 1);
        } else {
            res.put("mrStatus", 0);
        }
        //新增如果当前用户不是核查人员返回标志位用户核查按钮、修改、删除、隐藏显示
        //1.获取病历核查人员id，该操作只能是核查员操作
        List<MedExamineInfo> medCheckInfos = medCheckInfoFacade.list(new QueryWrapper<MedExamineInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", getDetailVO.getBehospitalCode())
                .orderByDesc("gmt_create"));
        if (medCheckInfos.size() >= 1 && medCheckInfos.get(0).getCheckId() != null
                && medCheckInfos.get(0).getCheckId().equals(Long.parseLong(SysUserUtils.getCurrentPrincipleID()))) {
            //2.1获取核查类型，判断当前用户有没有对应核查类型的角色
//            int jobType = medCheckInfoFacade.list(new QueryWrapper<MedExamineInfo>()
//                    .eq("is_deleted", IsDeleteEnum.N.getKey())
//                    .eq("behospital_code", getDetailVO.getBehospitalCode())
//                    .eq("hospital_id", hospitalId)
//                    .eq("check_id", SysUserUtils.getCurrentPrincipleID())).get(0).getJobType();
            //2.2获取用户角色
            List<Long> roleIds = sysUserRoleFacade.list(new QueryWrapper<SysUserRole>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("user_id", SysUserUtils.getCurrentPrincipleID())
            ).stream().distinct().map(SysUserRole::getRoleId).collect(Collectors.toList());
//            switch (jobType) {
            switch (0) {
                case 0:
                    if (roleIds.contains(CheckerRoleEnum.DEPT_GENERAL.getKey() * 1l)) {
                        res.put("checkShow", 1);
                    } else {
                        res.put("checkShow", 0);
                    }
                    break;
                case 1:
                    if (roleIds.contains(CheckerRoleEnum.QUAT_GENERAL.getKey() * 1l)) {
                        res.put("checkShow", 1);
                    } else {
                        res.put("checkShow", 0);
                    }
                    break;
                case 2:
                    if (roleIds.contains(CheckerRoleEnum.HOSP_GENERAL.getKey() * 1l)) {
                        res.put("checkShow", 1);
                    } else {
                        res.put("checkShow", 0);
                    }
                    break;
                default:
                    res.put("checkShow", 0);
                    break;
            }

        } else {
            res.put("checkShow", 0);
        }
    }

    private void appealButtonShow(Long hospitalId, GetDetailVO getDetailVO, Map<String, Object> res) {
        res.put("appealShow", 1);
    }

    /**
     * 处理数据(公共方法)
     *
     * @param hospitalId
     * @param analyzeVO
     * @return
     */
    public QueryVo dealCommonData(Long hospitalId, AnalyzeVO analyzeVO) {
        // 获取质控条目
        List<QcCasesEntryDTO> qcCasesEntryDTOList = qcCasesEntryFacade.getQcCasesEntry(analyzeVO);
        if (ListUtil.isEmpty(qcCasesEntryDTOList)) {
            throw new CommonException(CommonErrorCode.NOT_EXISTS, "该病历无关联的质控条目!");
        }

        // 获取病历所有数据
        Map<String, Map<String, String>> dicMap = sysDictionaryFacade.getDictionaryWithKey(); // 获取字典信息
        // 获取文书信息
        RecordContentVO recordContentVO = new RecordContentVO();
        BeanUtil.copyProperties(analyzeVO, recordContentVO);
        List<RecordContentDTO> recordContentDTOList = medicalRecordFacade.getRecordContentFac(recordContentVO);
        String recTitle = "";
        // 解密数据
        if (encryptFlag) {
            try {
                EncrypDES encrypDES = new EncrypDES();
                for (RecordContentDTO recordContentDTO : recordContentDTOList) {
                    recTitle = recordContentDTO.getRecTitle();
                    if (StringUtils.isNotEmpty(recordContentDTO.getXmlText())) {
                        recordContentDTO.setXmlText(encrypDES.decryptor(recordContentDTO.getXmlText()));
                    }
                    try {
                        if (StringUtils.isNotEmpty(recordContentDTO.getHtmlText())) {
                            recordContentDTO.setHtmlText(encrypDES.decryptor(recordContentDTO.getHtmlText()));
                        }
                    } catch (Exception e) {
                        recordContentDTO.setHtmlText(null);
                    }
                }
            } catch (Exception e) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR,
                        "解密错误!病历号=【" + analyzeVO.getBehospitalCode() + "】，医院文书名称=【" + recTitle + "】");
            }
        }

        Map<String, List<RecordContentDTO>> recMap = EntityUtil.makeEntityListMap(recordContentDTOList, "standModelName");
//        -------------------------------------文书数据改造开始----------------------------------
        // 获取会诊申请单
        List<StrConsultationApply> strConsultationApplyList = strConsultationApplyFacade.list(new QueryWrapper<StrConsultationApply>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("behospital_date")
        );

        // 获取会诊结果单
        List<StrConsultationResult> strConsultationResultList = strConsultationResultFacade.list(new QueryWrapper<StrConsultationResult>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("behospital_date")
        );

        // 会诊单（申请和结果）
        List<StrConsultationNote> strConsultationNoteList = strConsultationNoteFacade.list(new QueryWrapper<StrConsultationNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("behospital_date")
        );

        // 会诊记录
        List<StrConsultationRecord> strConsultationRecordList = strConsultationRecordFacade.list(new QueryWrapper<StrConsultationRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("behospital_date")
        );

        // 入院记录
        List<StrAdmissionNote> strAdmissionNoteList = strAdmissionNoteFacade.list(new QueryWrapper<StrAdmissionNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByDesc("behospital_date", "rec_id")
                .last("limit 1")
        );

        // 输血效果评价
        List<StrBloodResult> strBloodResultList = strBloodResultFacade.list(new QueryWrapper<StrBloodResult>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 输血记录
        List<StrBloodTransfusion> strBloodTransfusionList = strBloodTransfusionFacade.list(new QueryWrapper<StrBloodTransfusion>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 危急值记录
        List<StrCrisisNote> strCrisisNoteList = strCrisisNoteFacade.list(new QueryWrapper<StrCrisisNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 死亡病例讨论记录
        List<StrDeathDiscussion> strDeathDiscussionList = strDeathDiscussionFacade.list(new QueryWrapper<StrDeathDiscussion>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 死亡记录
        List<StrDeathNote> strDeathNoteList = strDeathNoteFacade.list(new QueryWrapper<StrDeathNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("death_date")
        );

        // 疑难病例讨论记录
        List<StrDifficultCase> strDifficultCaseList = strDifficultCaseFacade.list(new QueryWrapper<StrDifficultCase>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 首次病程录
        List<StrFirstRecord> strFirstRecordList = strFirstRecordFacade.list(new QueryWrapper<StrFirstRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 病危通知单
        List<StrIllCritically> strIllCriticallyList = strIllCriticallyFacade.list(new QueryWrapper<StrIllCritically>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("doctor_sign_date")
        );

        // 病重通知单
        List<StrIllSeriousl> strIllSeriouslList = strIllSeriouslFacade.list(new QueryWrapper<StrIllSeriousl>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("doctor_sign_date")
        );

        // 出院小结
        List<StrLeaveHospital> strLeaveHospitalList = strLeaveHospitalFacade.list(new QueryWrapper<StrLeaveHospital>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("leave_hospital_date")
        );

        // 术后首程
        List<StrOperativeFirstRecord> strOperativeFirstRecordList = strOperativeFirstRecordFacade.list(new QueryWrapper<StrOperativeFirstRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 手术记录
        List<StrOperativeNote> strOperativeNoteList = strOperativeNoteFacade.list(new QueryWrapper<StrOperativeNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 阶段小结
        List<StrPeriodConclusion> strPeriodConclusionList = strPeriodConclusionFacade.list(new QueryWrapper<StrPeriodConclusion>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 术前讨论小结
        List<StrPreoperativeDiscussion> strPreoperativeDiscussionList = strPreoperativeDiscussionFacade.list(new QueryWrapper<StrPreoperativeDiscussion>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        // 抢救记录
        List<StrRescueNote> strRescueNoteList = strRescueNoteFacade.list(new QueryWrapper<StrRescueNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );

        List<LocalDateTime> transferOutDate = new ArrayList<>();
        List<LocalDateTime> transferInDate = new ArrayList<>();
        Map<String, List<LocalDateTime>> transferMap = new HashMap<>();

        //转入转出时间表
        List<MedTransferRecord> medTransferRecordList = medTransferRecordFacade.list(new QueryWrapper<MedTransferRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .orderByDesc("id"));
        if (ListUtil.isNotEmpty(medTransferRecordList)) {
            medTransferRecordList.forEach(medTransferRecord -> {
                transferOutDate.add(medTransferRecord.getTransferOutDate());
                transferInDate.add(medTransferRecord.getTransferInDate());
            });
        }
        transferMap.put("转出时间", transferOutDate);
        transferMap.put("转入时间", transferInDate);

        // 转入记录
        List<StrTransferInNote> strTransferInNoteList = strTransferInNoteFacade.list(new QueryWrapper<StrTransferInNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("transfer_in_date")
        );

        // 转出记录
        List<StrTransferOutNote> strTransferOutNoteList = strTransferOutNoteFacade.list(new QueryWrapper<StrTransferOutNote>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("transfer_in_date")
        );

        // 查房记录
        List<StrWardRecord> strWardRecordList = strWardRecordFacade.list(new QueryWrapper<StrWardRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .select("whole_data", "rec_id", "hospital_id")
                .orderByAsc("rec_date")
        );
//        -------------------------------------文书数据改造结束----------------------------------
        // 获取护理
        List<MedNurse> medNurseList = medNurseFacade.list(new QueryWrapper<MedNurse>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .orderByAsc("gmt_create")
        );

        // 获取医嘱
        List<DoctorAdvice> doctorAdviceList = doctorAdviceFacade.list(new QueryWrapper<DoctorAdvice>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .orderByAsc("da_start_date")
        );

        // 危急值
        List<MedCrisisInfo> medCrisisInfoList = medCrisisInfoFacade.list(new QueryWrapper<MedCrisisInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
        );

        // 获取病案首页
        HomePage homePage = homePageFacade.getOne(new QueryWrapper<HomePage>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode()), false
        );

        //知情同意书
    /*    List<MedicalRecord> recordList = medicalRecordFacade.list(new QueryWrapper<MedicalRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .eq("hospital_id", hospitalId)
                .in("mode_id", Arrays.asList(53, 16))
                .orderByAsc("rec_date")
        );
        List<MedicalRecordDTO> medicalRecordDTOList = BeanUtil.listCopyTo(recordList, MedicalRecordDTO.class);
*/
        List<HomeDiagnoseInfo> homePageList = new ArrayList<>();
        List<HomeOperationInfo> homeOperationInfoList = new ArrayList<>();
        if (homePage != null) {
            String ageData = homePage.getAge();
            try {
                if (StringUtils.isNotEmpty(homePage.getAge()) && "-".equals(homePage.getAge()) == false && "—".equals(homePage.getAge()) == false) {
                    //兼容数据库出现 .03岁数据 作后期判断处理
                    String ageUnitString = homePage.getAgeUnit() == null ? "" : homePage.getAgeUnit();
                    if (homePage.getAge().contains(".") && "岁".equals(ageUnitString)) {
                        String ageString = homePage.getAge().split("\\.")[0];
                        //该年龄作为判断使用
                        homePage.setAge(StringUtils.isEmpty(ageString) == true ? "0" + homePage.getAge() : homePage.getAge());
                    }
                    //根据时间单位对模版年龄进行区分
                    if (Double.parseDouble(homePage.getAge()) <= 1 && "岁".equals(ageUnitString)) {
                        homePage.setNewbornMonth(StringUtils.isEmpty(homePage.getNewbornMonth()) == true ? "0" : homePage.getNewbornMonth());
                        homePage.setNewbornDay(StringUtils.isEmpty(homePage.getNewbornDay()) == true ? "0" : homePage.getNewbornDay());
                    } else if ("月".equals(ageUnitString)) {
                        if (StringUtils.isEmpty(homePage.getNewbornDay()) == true) {
                            homePage.setNewbornMonth(StringUtils.isEmpty(homePage.getNewbornMonth()) == true ? homePage.getAge() : homePage.getNewbornMonth());
                        } else if (StringUtils.isEmpty(homePage.getNewbornMonth()) == true && StringUtils.isEmpty(homePage.getNewbornDay()) == false) {
                            homePage.setNewbornMonth("0");
                        }
                        homePage.setNewbornDay(StringUtils.isEmpty(homePage.getNewbornDay()) == true ? "0" : homePage.getNewbornDay());
                    } else if ("天".equals(ageUnitString) || "日".equals(ageUnitString)) {
                        if (StringUtils.isEmpty(homePage.getNewbornMonth()) && StringUtils.isEmpty(homePage.getNewbornDay())) {
                            homePage.setNewbornDay(homePage.getAge());
                            homePage.setNewbornMonth(StringUtils.isEmpty(homePage.getNewbornMonth()) == true ? "0" : homePage.getNewbornMonth());
                        } else {
                            homePage.setNewbornMonth(StringUtils.isEmpty(homePage.getNewbornMonth()) == true ? "0" : homePage.getNewbornMonth());
                            homePage.setNewbornDay(StringUtils.isEmpty(homePage.getNewbornDay()) == true ? "0" : homePage.getNewbornDay());
                        }
                    } else if ("时".equals(ageUnitString)) {
                        homePage.setNewbornMonth(StringUtils.isEmpty(homePage.getNewbornMonth()) == true ? "0" : homePage.getNewbornMonth());
                        homePage.setNewbornDay(StringUtils.isEmpty(homePage.getNewbornDay()) == true ? "0" : homePage.getNewbornDay());
                    } else if (Double.parseDouble(homePage.getAge()) > 1 && "岁".equals(ageUnitString)) {
                        homePage.setNewbornMonth("-");
                        homePage.setNewbornDay("-");
                    }
                }
            } catch (Exception e) {
                System.out.println("年龄解析出错" + e);
            }
            homePage.setAge(ageData + (StringUtils.isEmpty(homePage.getAgeUnit()) == true ? "" : homePage.getAgeUnit()));
            //去掉年龄单位
            homePage.setAgeUnit("");

            // 获取首页出院诊断、病理诊断
            homePageList = homeDiagnoseInfoFacade.list(new QueryWrapper<HomeDiagnoseInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .eq("home_page_id", homePage.getHomePageId())
                    .orderByAsc("diagnose_order_no")
            );

            // 获取首页手术信息
            homeOperationInfoList = homeOperationInfoFacade.list(new QueryWrapper<HomeOperationInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .eq("home_page_id", homePage.getHomePageId())
                    .orderByAsc("operation_order_no")
            );
            analyzeVO.setHaveHomePage(1);
        } else {
            analyzeVO.setHaveHomePage(0);
        }

        // 拼接数据
        String hosCode = basHospitalInfoFacade.getHosCode(hospitalId);
        QueryVo queryVo = new QueryVo();
        queryVo.setCid(hosCode); // 设置医院编码
        queryVo.setHospitalId(String.valueOf(hospitalId));
        queryVo.setInputCatalogueMap(getInputCatalogueMap(qcCasesEntryDTOList)); // 设置质控条目编码
        List<MedrecVo> medrecVoList = new ArrayList<>(); // 设置内容

        // 添加住院病历信息
        List<BehospitalInfo> behospitalInfoList = this.list(new QueryWrapper<BehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("behospital_code", analyzeVO.getBehospitalCode())
        );
        if (ListUtil.isNotEmpty(behospitalInfoList)) {
            MedrecVo medrecVo = new MedrecVo();
            medrecVo.setTitle("住院病历信息");
            Map<String, Object> content = new HashMap<>();
            content.put("content", behospitalInfoList);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);

            queryVo.setBehospitalInfo(behospitalInfoList.get(0));
        }


        // 化验
        //使用sql进行关联优化数据查询
        List<MedLisResultDTO> medLisResultListDTO = medLisResultFacade.getMedLisResultList(behospitalInfoList.get(0));
        List<MedLisResultDTO> medLisResultList = new ArrayList<>();
        for (MedLisResultDTO medLisResultSingle : medLisResultListDTO) {
            MedLisResultDTO medLisResult = new MedLisResultDTO();
            BeanUtil.copyProperties(medLisResultSingle, medLisResult);
            medLisResult.setItemName(medLisResultSingle.getRepName() + "=" + medLisResultSingle.getReportName());
            medLisResultList.add(medLisResult);
        }

        // 辅检
        //使用sql进行关联优化数据查询
        List<MedPacsResultDTO> medPacsResultList = medPacsResultFacade.getMedPacsResultList(behospitalInfoList.get(0));

        /**
         * 结构化/文书数据兼容处理
         */

        // 会诊记录
        if (ListUtil.isNotEmpty(strConsultationRecordList)) {
            specialData("会诊", strConsultationRecordList, recMap, medrecVoList, "会诊记录", null);
        } else {
            specialDataWithKey("会诊", recMap, medrecVoList, "会诊记录",
                    Arrays.asList("会诊记录"), null);
        }

        //会诊申请单
        if (ListUtil.isNotEmpty(strConsultationApplyList)) {
            specialData("会诊", strConsultationApplyList, recMap, medrecVoList, "会诊申请单", null);
        } else {
            specialDataWithKey("会诊", recMap, medrecVoList, "会诊申请单",
                    Arrays.asList("会诊申请单"), null);
        }
        //会诊结果单
        if (ListUtil.isNotEmpty(strConsultationResultList)) {
            specialData("会诊", strConsultationResultList, recMap, medrecVoList, "会诊结果单", null);
        } else {
            specialDataWithKey("会诊", recMap, medrecVoList, "会诊结果单",
                    Arrays.asList("会诊记录", "会诊结果单", "会诊申请单"), null);
        }

        //会诊单（申请和结果）
        if (ListUtil.isNotEmpty(strConsultationNoteList)) {
            specialData("会诊", strConsultationNoteList, recMap, medrecVoList, "会诊单（申请和结果）", null);
        }
        //入院记录
        if (ListUtil.isNotEmpty(strAdmissionNoteList)) {
            newAddData("入院记录", strAdmissionNoteList, recMap, medrecVoList);
        } else {
            addDataHZQY("入院记录", recMap, medrecVoList, "1", analyzeVO);
        }

        //输血效果评价
        if (ListUtil.isNotEmpty(strBloodResultList)) {
            newAddData("输血后效果评价", strBloodResultList, recMap, medrecVoList);
        } else {
            addData("输血后效果评价", recMap, medrecVoList);
        }

        //输血记录
        if (ListUtil.isNotEmpty(strBloodTransfusionList)) {
            newAddData("输血/血制品病程记录", strBloodTransfusionList, recMap, medrecVoList);
        } else {
            addData("输血/血制品病程记录", recMap, medrecVoList);
        }


        //危急值记录
        if (ListUtil.isNotEmpty(strCrisisNoteList)) {
            newAddData("危急值记录", strCrisisNoteList, recMap, medrecVoList);
        } else {
            addData("危急值记录", recMap, medrecVoList);
        }

        //死亡病例讨论记录
        if (ListUtil.isNotEmpty(strDeathDiscussionList)) {
            newAddData("死亡病例讨论记录", strDeathDiscussionList, recMap, medrecVoList);
        } else {
            addData("死亡病例讨论记录", recMap, medrecVoList);
        }

        //死亡记录
        if (ListUtil.isNotEmpty(strDeathNoteList)) {
            newAddData("死亡记录", strDeathNoteList, recMap, medrecVoList);
        } else {
            addData("死亡记录", recMap, medrecVoList);
        }

        //疑难病例讨论记录
        if (ListUtil.isNotEmpty(strDifficultCaseList)) {
            newAddData("疑难病例讨论记录", strDifficultCaseList, recMap, medrecVoList);
        } else {
            addData("疑难病例讨论记录", recMap, medrecVoList);
        }

        //首次病程录
        if (ListUtil.isNotEmpty(strFirstRecordList)) {
            newAddData("首次病程录", strFirstRecordList, recMap, medrecVoList);
        } else {
            addDataHZQY("首次病程录", recMap, medrecVoList, "2", analyzeVO);
        }

        //病危通知单
        if (ListUtil.isNotEmpty(strIllCriticallyList)) {
            newAddData("病危通知书", strIllCriticallyList, recMap, medrecVoList);
        } else {
            addData("病危通知书", recMap, medrecVoList);
        }

        //病重通知单
        if (ListUtil.isNotEmpty(strIllSeriouslList)) {
            newAddData("病重通知书", strIllSeriouslList, recMap, medrecVoList);
        } else {
            addData("病重通知书", recMap, medrecVoList);
        }

        //出院小结
        if (ListUtil.isNotEmpty(strLeaveHospitalList)) {
            newAddData("出院小结", strLeaveHospitalList, recMap, medrecVoList);
        } else {
            addData("出院小结", recMap, medrecVoList);
        }

        //术后首程
        if (ListUtil.isNotEmpty(strOperativeFirstRecordList)) {
            specialData("手术", strOperativeFirstRecordList, recMap, medrecVoList, "术后首次病程及谈话记录", null);
        } else {
            specialDataWithKey("手术", recMap, medrecVoList, "术后首次病程及谈话记录",
                    null, null);
        }

        //手术记录
        if (ListUtil.isNotEmpty(strOperativeNoteList)) {
            specialData("手术", strOperativeNoteList, recMap, medrecVoList, "手术记录", null);
        } else {
            specialDataWithKey("手术", recMap, medrecVoList, "手术记录",
                    null, null);
        }

        //阶段小结
        if (ListUtil.isNotEmpty(strPeriodConclusionList)) {
            newAddData("阶段小结", strPeriodConclusionList, recMap, medrecVoList);
        } else {
            addData("阶段小结", recMap, medrecVoList);
        }

        //术前讨论小结
        if (ListUtil.isNotEmpty(strPreoperativeDiscussionList)) {
            specialData("手术", strPreoperativeDiscussionList, recMap, medrecVoList, "术前讨论、术前小结", null);
        } else {
            specialDataWithKey("手术", recMap, medrecVoList, "术前讨论、术前小结",
                    null, null);
        }


        //抢救记录
        if (ListUtil.isNotEmpty(strRescueNoteList)) {
            newAddData("抢救记录", strRescueNoteList, recMap, medrecVoList);
        } else {
            addData("抢救记录", recMap, medrecVoList);
        }

        //转入记录
        if (ListUtil.isNotEmpty(strTransferInNoteList)) {
            specialData("转科", strTransferInNoteList, recMap, medrecVoList, "转入记录", transferMap);
        } else {
            specialDataWithKey("转科", recMap, medrecVoList, "转入记录",
                    null, transferMap);
        }

        //转出记录
        if (ListUtil.isNotEmpty(strTransferOutNoteList)) {
            specialData("转科", strTransferOutNoteList, recMap, medrecVoList, "转出记录", transferMap);
        } else {
            specialDataWithKey("转科", recMap, medrecVoList, "转出记录",
                    null, transferMap);
        }

        //查房记录
        if (ListUtil.isNotEmpty(strWardRecordList)) {
            newAddData("查房记录", strWardRecordList, recMap, medrecVoList);
        } else {
            addData("查房记录", recMap, medrecVoList);
        }

        //==============非结构化表拥有，文书单独查出来====================
        specialDataWithKey("手术", recMap, medrecVoList, "手术知情同意书",
                null, null);

        specialDataWithKey("手术", recMap, medrecVoList, "手术安全核查表",
                null, null);


//=========================================
    /*    // 会诊记录
        addDataWithKey("会诊", recMap, medrecVoList,
                Arrays.asList("会诊记录", "会诊结果单", "会诊申请单"));

        // 手术
        addDataWithKey("手术", recMap, medrecVoList,
                Arrays.asList("术后首次病程及谈话记录", "手术记录",
                        "术前讨论、术前小结", "手术知情同意书", "手术安全核查表"));

        // 转科
        addDataWithKey("转科", recMap, medrecVoList,
                Arrays.asList("转入记录", "转出记录"));
*/
//        ==================================

        addData("有创操作", recMap, medrecVoList);

        addData("病理检验送检单", recMap, medrecVoList);

        addData("日常病程录", recMap, medrecVoList);

        //DataWithKey("知情同意书", medicalRecordDTOList, medrecVoList);
        addDataWithInnerKey("知情同意书", recMap, medrecVoList);
        addDataWithInnerKey("谈话告知书", recMap, medrecVoList);

        //==============文书====================
        //护理
        if (ListUtil.isNotEmpty(medNurseList)) {
            addDataWithKeyConvert("护理", medNurseList, medrecVoList,
                    dicMap.get("23"), Arrays.asList("measureTime"));
        }
        // 医嘱
        if (ListUtil.isNotEmpty(doctorAdviceList)) {
            addDataWithKeyConvert("医嘱信息", doctorAdviceList, medrecVoList,
                    dicMap.get("1"), Arrays.asList("daStartDate", "daStopDate"));
        }

        // 危急值
        if (ListUtil.isNotEmpty(medCrisisInfoList)) {
            addDataWithKeyConvert("危急值", medCrisisInfoList, medrecVoList,
                    dicMap.get("20"), Arrays.asList("sendDate", "repDate"));
        }

        // 化验
        if (ListUtil.isNotEmpty(medLisResultList)) {
            addDataWithKeyConvert("化验", medLisResultList, medrecVoList,
                    dicMap.get("21"), new ArrayList<>());
        }

        // 辅检
        if (ListUtil.isNotEmpty(medPacsResultList)) {
            addDataWithKeyConvert("辅检", medPacsResultList, medrecVoList,
                    dicMap.get("22"), new ArrayList<>());
        }

        // 病案首页
        if (homePage != null) {
            addDataWithFirstPage("病案首页", homePage, medrecVoList, dicMap,
                    homePageList, homeOperationInfoList);
        }
//        }

        queryVo.setMedrec(medrecVoList);
        return queryVo;
    }

    /**
     * 评分-终末质控
     *
     * @param analyzeVO
     * @return
     */
    public AnalyzeDTO analyze(AnalyzeVO analyzeVO) {

        Long hospitalId = analyzeVO.getHospitalId();
        if (!analyzeVO.getIsTask()) {
            hospitalId = Long.parseLong(SysUserUtils.getCurrentHospitalID());
        }
        //        Long hospitalId = 1L; // 写死
        analyzeVO.setHospitalId(hospitalId);

        // 处理公共数据
        QueryVo queryVo = dealCommonData(hospitalId, analyzeVO);
        queryVo.setUseCrfCache(analyzeVO.isUseCrfCache());
        //已核查抛出以评分
//        List<MedCheckInfo> medCheckInfos = medCheckInfoFacade.list(new QueryWrapper<MedCheckInfo>()
//                .eq("is_deleted", IsDeleteEnum.N.getKey())
//                .eq("hospital_id", analyzeVO.getHospitalId())
//                .eq("behospital_code", analyzeVO.getBehospitalCode()));
//        Set<Integer> status = medCheckInfos.stream().map(MedCheckInfo::getStatus).collect(Collectors.toSet());
//        if (medCheckInfos.size() >= 1 && status.contains(CheckStatusEnum.Enable.getKey()) && analyzeVO.getCheckFlag()) {
//            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病例已经核查无需评分！");
//        }
        //  调用质控接口
        Response<OutputInfo> response = qcServiceClient.extract(queryVo);
        if (response == null || response.getData() == null) {
            if (null == response) {
                throw new CommonException(CommonErrorCode.RPC_ERROR, "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】");
            } else {
                throw new CommonException(CommonErrorCode.RPC_ERROR,
                        "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】错误原因:" + response.getMsg());
            }
        }
        OutputInfo outputInfo = response.getData();
        // 质控编码列表
        List<String> codeList = new ArrayList<>();
        // code和info的映射map
        Map<String, String> codeToInfoMap = new LinkedHashMap<>();
        // 对codeList 和 codeToInfoMap进行赋值
        setCodeData(outputInfo, codeList, codeToInfoMap);

        // 计算分值并保存结果至数据库
        Map<String, Object> resMap = calScoreAndSave(outputInfo, codeList, codeToInfoMap, analyzeVO, queryVo.getBehospitalInfo().getIsPlacefile());
        AlgorithmDTO algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
        Date date = (Date) resMap.get("date");

        // 返回提示信息
        //        List<MsgDTO> msgDTOList = getMsg(analyzeVO);
        //        Map<String, List<MsgDTO>> msgMap = EntityUtil.makeEntityListMap(msgDTOList, "modelName");

        //返回参数组装
        AnalyzeDTO analyzeDTO = new AnalyzeDTO();
        analyzeDTO.setBehospitalCode(analyzeVO.getBehospitalCode());
        analyzeDTO.setIsSuccess(true);
        analyzeDTO.setGradeType(1);
        analyzeDTO.setGradeTypeName("机器");
        analyzeDTO.setScoreRes(algorithmDTO.getScore());
        analyzeDTO.setGradeTime(date);
        return analyzeDTO;
    }


    /**
     * 拼接数据
     *
     * @param key
     * @param recMap
     * @param medrecVoList
     */
    public void addData(String key, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList) {
        List<RecordContentDTO> list = recMap.get(key);
        if (ListUtil.isNotEmpty(list)) {
            for (RecordContentDTO recordContentDTO : list) {
                recordContentDTO.setIsParsed(0);
            }
        }
        if (ListUtil.isNotEmpty(list)) {
            MedrecVo medrecVo = new MedrecVo();
            Map<String, Object> content = new HashMap<>();
            content.put("content", list);
            medrecVo.setTitle(key);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);
        }
    }

    /**
     * 拼接数据
     *
     * @param key
     * @param recMap
     * @param medrecVoList
     */
    public void addDataHZQY(String key, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList, String modeId, AnalyzeVO analyzeVO) {
        List<RecordContentDTO> list = recMap.get(key);
        List<MedicalRecord> recordList = medicalRecordFacade.list(new QueryWrapper<MedicalRecord>()
                .eq("mode_id", modeId)
                .eq("hospital_id", analyzeVO.getHospitalId())
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .orderByAsc("rec_date")
        );

        if (ListUtil.isNotEmpty(list)) {
            for (RecordContentDTO recordContentDTO : list) {
                recordContentDTO.setIsParsed(0);
                recordContentDTO.setFirstCreateDate(recordList.get(0).getRecDate());
            }
        }
        if (ListUtil.isNotEmpty(list)) {
            MedrecVo medrecVo = new MedrecVo();
            Map<String, Object> content = new HashMap<>();
            content.put("content", list);
            medrecVo.setTitle(key);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);
        }
    }


    /**
     * 1.5.0拼接数据(手术、会诊)
     *
     * @param key
     * @param recMap
     * @param medrecVoList
     */
    public void specialDataWithKey(String key, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList,
                                   String keyTagert, List<String> keyList, Map<String, List<LocalDateTime>> transferMap) {
        MedrecVo medrecVo = new MedrecVo();
        Map<String, List<RecordContentDTO>> specialContent = new HashMap<String, List<RecordContentDTO>>();
        Map<String, Object> content = new HashMap<>();
        Map<String, Object> Map = new HashMap<>();
        Boolean flag = false;
        if (ListUtil.isNotEmpty(keyList)) {
            for (String k : keyList) {
                if (ListUtil.isNotEmpty(recMap.get(k))) {
                    Map.put(k, recMap.get(k));
                }
            }

        }
        //设置特殊属性
        List<RecordContentDTO> recordContentDTOS = recMap.get(keyTagert);
        if (ListUtil.isNotEmpty(recordContentDTOS)) {
            for (RecordContentDTO recordContentDTO : recordContentDTOS) {
                if (null != transferMap) {
                    recordContentDTO.setTransferOutDate(transferMap.get("转出时间"));
                    recordContentDTO.setTransferInDate(transferMap.get("转入时间"));
                }
                recordContentDTO.setIsParsed(0);
            }
        }

        //用来复制申请单
        List<RecordContentDTO> recordContentList = recMap.get("会诊申请单");
        if (ListUtil.isNotEmpty(recordContentList)) {
            for (RecordContentDTO recordContentDTO : recordContentList) {
                if (null != transferMap) {
                    recordContentDTO.setTransferOutDate(transferMap.get("转出时间"));
                    recordContentDTO.setTransferInDate(transferMap.get("转入时间"));
                }
                recordContentDTO.setIsParsed(0);
            }
        }

        for (MedrecVo medrec : medrecVoList) {
//            存在标题
            if (key.equals(medrec.getTitle())) {
                Map<String, Object> keyContent = medrec.getContent();
                specialContent = JSON.parseObject(JSON.toJSONString(keyContent.get("content")), new TypeReference<Map<String, List<RecordContentDTO>>>() {
                });
                if (ListUtil.isNotEmpty(keyList) && keyList.size() == 3) {
                    if (Map.get("会诊申请单") != null && Map.get("会诊结果单") == null && ListUtil.isNotEmpty(recordContentDTOS)) {
                        specialContent.put(keyTagert, recordContentList);
                    } else if (Map.get("会诊结果单") != null && ListUtil.isNotEmpty(recordContentDTOS)) {
                        specialContent.put(keyTagert, recordContentDTOS);
                    }
                } else {
                    if (ListUtil.isNotEmpty(recordContentDTOS)) {
                        specialContent.put(keyTagert, recordContentDTOS);
                    }
                }

                if (!specialContent.isEmpty()) {
                    keyContent.put("content", specialContent);
                    flag = true;
                }

            }
        }

        //没有第一标题
        if (!flag) {
            if (ListUtil.isNotEmpty(keyList) && keyList.size() == 3) {
                if (Map.get("会诊申请单") != null && Map.get("会诊结果单") == null && ListUtil.isNotEmpty(recordContentDTOS)) {
                    specialContent.put(keyTagert, recordContentList);
                } else if (Map.get("会诊结果单") != null && ListUtil.isNotEmpty(recordContentDTOS)) {
                    specialContent.put(keyTagert, recordContentDTOS);
                }
            } else {
                if (ListUtil.isNotEmpty(recordContentDTOS)) {
                    specialContent.put(keyTagert, recordContentDTOS);
                }
            }
            if (!specialContent.isEmpty()) {
                content.put("content", specialContent);
                medrecVo.setTitle(key);
                medrecVo.setContent(content);
                medrecVoList.add(medrecVo);
            }
        }
    }


    /**
     * 拼接数据（例如：手术）
     *
     * @param key
     * @param recMap
     * @param medrecVoList
     */
    public void addDataWithKey(String key, Map<String, List<RecordContentDTO>> recMap,
                               List<MedrecVo> medrecVoList, List<String> keyList) {
        MedrecVo medrecVo = new MedrecVo();
        String m = key;
        if ("术前讨论、术前小结".equals(key)) {
            m = "术前讨论小结";
        }
        if ("术后首次病程及谈话记录".equals(key)) {
            m = "术后首程";
        }
        medrecVo.setTitle(m);
        Map<String, Object> content = new HashMap<>();
        Map<String, Object> listMap = new HashMap<>();
        Boolean flag = false;
        for (String k : keyList) {
            if (ListUtil.isNotEmpty(recMap.get(k))) {
                listMap.put(k, recMap.get(k));
                flag = true;
            }
        }
        if (flag) {
            if (ListUtil.isNotEmpty(keyList) && keyList.size() == 3) {
                // 会诊记录特殊处理，有会诊申请单，没有会诊结果单，复制一份到会诊结果单
                if (listMap.get("会诊申请单") != null && listMap.get("会诊结果单") == null) {
                    listMap.put("会诊结果单", listMap.get("会诊申请单"));
                }
                //只封装会诊结果单数据
                for (String k : keyList) {
                    if (!"会诊结果单".equals(k) && ListUtil.isNotEmpty(recMap.get(k))) {
                        listMap.remove(k);
                    }
                }
            }
            content.put("content", listMap);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);
        }
    }


    /**
     * 拼接数据（例如：知情同意书、谈话告知书）
     *
     * @param key
     * @param recMap
     * @param medrecVoList
     */
    public void addDataWithInnerKey(String key, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList) {
        MedrecVo medrecVo = new MedrecVo();
        medrecVo.setTitle(key);
        Map<String, Object> content = new HashMap<>();
        Map<String, Object> listMap = new HashMap<>();
        List<RecordContentDTO> recordContentDTOList = recMap.get(key);
        if (ListUtil.isNotEmpty(recordContentDTOList)) {
            Map<String, List<RecordContentDTO>> keyMap =
                    EntityUtil.makeEntityListMap(recordContentDTOList, "recTitle");
            Set<String> keyList = keyMap.keySet();
            for (String k : keyList) {
                List<RecordContentDTO> recordContentDTOS = keyMap.get(k);
                if (ListUtil.isNotEmpty(recordContentDTOS)) {
                    for (RecordContentDTO recordContentDTO : recordContentDTOS) {
                        recordContentDTO.setIsParsed(0);
                    }
                }

                if (ListUtil.isNotEmpty(recordContentDTOS)) {
                    listMap.put(k, recordContentDTOS);
                }
            }
            content.put("content", listMap);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);
        }
    }

    /**
     * 知情同意书 单独传
     *
     * @param key
     * @param recordList
     * @param medrecVoList
     */
    public void DataWithKey(String key, List<MedicalRecordDTO> recordList, List<MedrecVo> medrecVoList) {
        MedrecVo medrecVo = new MedrecVo();
        medrecVo.setTitle(key);
        Map<String, Object> listMap = new HashMap<>();
        if (ListUtil.isNotEmpty(recordList)) {
            Map<String, List<MedicalRecordDTO>> keyMap =
                    EntityUtil.makeEntityListMap(recordList, "recTitle");
            Set<String> keyList = keyMap.keySet();
            for (String k : keyList) {
                List<MedicalRecordDTO> recordContentDTOS = keyMap.get(k);
                if (ListUtil.isNotEmpty(recordContentDTOS)) {
                    for (MedicalRecordDTO recordContentDTO : recordContentDTOS) {
                        recordContentDTO.setIsParsed(0);
                    }
                }

                if (ListUtil.isNotEmpty(recordContentDTOS)) {
                    listMap.put(k, recordContentDTOS);
                }
            }
            medrecVo.setContent(listMap);
            medrecVoList.add(medrecVo);
        }
    }

    /**
     * 1.5.0拼接数据
     *
     * @param key
     * @param list
     * @param medrecVoList
     */
    public <T> void newAddData(String key, List<T> list, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList) {
        MedrecVo medrecVo = new MedrecVo();
        medrecVo.setTitle(key);
        Map<String, Object> content = new HashMap<>();
        List<RePlaceData> contents = new ArrayList<>();

        //从结构化表中取出应用数据
        for (T bean : list) {
            try {
                RePlaceData rePlaceData = new RePlaceData();
                Map<String, Object> objectMap = MapUtil.objectToMap(bean);
                String recId = (String) objectMap.get("recId");
                rePlaceData.setRecId(recId);
                Long hospitalId = (Long) objectMap.get("hospitalId");
                rePlaceData.setHospitalId(hospitalId);
                String jsonData = (String) objectMap.get("wholeData");
                rePlaceData.setJsonData(jsonData);
                contents.add(rePlaceData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //将文书xml替换成结构化数据
        if (ListUtil.isNotEmpty(recMap.get(key))) {
            List<RecordContentDTO> recordContentDTOS = recMap.get(key);
            for (RecordContentDTO recordContentDTO : recordContentDTOS) {
                if (ListUtil.isNotEmpty(contents)) {
                    for (RePlaceData rePlaceData : contents) {
                        if (StringUtil.isNotEmpty(recordContentDTO.getRecId()) &&
                                rePlaceData.getRecId().equals(recordContentDTO.getRecId()) &&
                                rePlaceData.getHospitalId().equals(recordContentDTO.getHospitalId())) {
                            recordContentDTO.setXmlText(rePlaceData.getJsonData());
                            recordContentDTO.setIsParsed(1);
                        }
                    }
                }
            }
            content.put("content", recordContentDTOS);
            medrecVo.setContent(content);
            medrecVoList.add(medrecVo);
        }
    }


    /**
     * 1.5.0拼接数据(手术、会诊)
     *
     * @param key
     * @param list
     * @param medrecVoList
     */
    public <T> void specialData(String key, List<T> list, Map<String, List<RecordContentDTO>> recMap, List<MedrecVo> medrecVoList, String keyTagert,
                                Map<String, List<LocalDateTime>> transferMap) {
        MedrecVo medrecVo = new MedrecVo();
        Map<String, Object> content = new HashMap<String, Object>();
        Map<String, List<RecordContentDTO>> specialContent = new HashMap<>();
        List<RePlaceData> contents = new ArrayList<>();

        //从结构化表中取出应用数据
        for (T bean : list) {
            try {
                RePlaceData rePlaceData = new RePlaceData();
                Map<String, Object> objectMap = MapUtil.objectToMap(bean);
                String recId = (String) objectMap.get("recId");
                rePlaceData.setRecId(recId);
                Long hospitalId = (Long) objectMap.get("hospitalId");
                rePlaceData.setHospitalId(hospitalId);
                String jsonData = (String) objectMap.get("wholeData");
                rePlaceData.setJsonData(jsonData);
                contents.add(rePlaceData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //将文书xml替换成结构化数据
        if (ListUtil.isNotEmpty(recMap.get(keyTagert))) {
            Boolean flag = true;
            List<RecordContentDTO> recordContentDTOS = recMap.get(keyTagert);
            for (RecordContentDTO recordContentDTO : recordContentDTOS) {
                if (null != transferMap) {
                    recordContentDTO.setTransferOutDate(transferMap.get("转出时间"));
                    recordContentDTO.setTransferInDate(transferMap.get("转入时间"));
                }
                if (ListUtil.isNotEmpty(contents)) {
                    for (RePlaceData rePlaceData : contents) {
                        if (StringUtil.isNotEmpty(recordContentDTO.getRecId()) &&
                                rePlaceData.getRecId().equals(recordContentDTO.getRecId()) &&
                                rePlaceData.getHospitalId().equals(recordContentDTO.getHospitalId())) {
                            recordContentDTO.setXmlText(rePlaceData.getJsonData());
                            recordContentDTO.setIsParsed(1);
                        }
                    }
                }
            }
            for (MedrecVo medrec : medrecVoList) {
                if (key.equals(medrec.getTitle())) {
                    Map<String, Object> keyContent = medrec.getContent();
                    try {
                        specialContent = JSON.parseObject(JSON.toJSONString(keyContent.get("content")), new TypeReference<Map<String, List<RecordContentDTO>>>() {
                        });
                        specialContent.put(keyTagert, recordContentDTOS);
                        keyContent.put("content", specialContent);
                        flag = false;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            if (flag) {
                medrecVo.setTitle(key);
                specialContent.put(keyTagert, recordContentDTOS);
                content.put("content", specialContent);
                medrecVo.setContent(content);
                medrecVoList.add(medrecVo);
            }
        }
    }

    /**
     * 拼接数据,从数据字典获取信息转换
     *
     * @param key
     * @param list
     * @param medrecVoList
     * @param map
     */
    public <T> void addDataWithKeyConvert(String key, List<T> list,
                                          List<MedrecVo> medrecVoList, Map<String, String> map, List<String> dateList) {
        MedrecVo medrecVo = new MedrecVo();
        medrecVo.setTitle(key);
        Map<String, Object> content = new HashMap<>();
        List<String> contents = new ArrayList<>();
        for (T bean : list) {
            try {
                Map<String, String> res = new HashMap<>();
                Map<String, Object> objectMap = MapUtil.objectToMap(bean);
                for (String objKey : objectMap.keySet()) {
                    if (map.get(objKey) != null) {
                        if (dateList.contains(objKey)) {
                            Date date = (Date) objectMap.get(objKey);
                            res.put(map.get(objKey), DateUtil.formatDateTime(date).replaceAll("null", ""));
                        } else {
                            res.put(map.get(objKey), String.valueOf(objectMap.get(objKey)).replaceAll("null", ""));
                        }
                    }
                }
                String jsonStr = JSON.toJSONString(res);
                contents.add(jsonStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        content.put("content", contents);
        medrecVo.setContent(content);
        medrecVoList.add(medrecVo);
    }


    /**
     * 对象key转换
     *
     * @param dateList
     * @param dicMap
     * @param objectMap
     * @return
     */
    public Map<String, Object> objcetKeyConvert(List<String> dateList, Map<String, String> dicMap, Map<String, Object> objectMap) {
        Map<String, Object> res = new HashMap<>();
        for (String objKey : objectMap.keySet()) {
            if (dicMap.containsKey(objKey)) {
                if (dateList.contains(objKey)) {
                    Date date = (Date) objectMap.get(objKey);
                    res.put(dicMap.get(objKey), DateUtil.formatDateTime(date).replaceAll("null", ""));
                } else {
                    res.put(dicMap.get(objKey), String.valueOf(objectMap.get(objKey)).replaceAll("null", ""));
                }
            }
        }
        return res;
    }

    /**
     * 拼接数据（病案首页),从数据字典获取信息转换
     *
     * @param key
     * @param homePage
     * @param medrecVoList
     * @param dicMap
     * @param homeDiagnoseInfoList
     * @param homeOperationInfoList
     */
    public void addDataWithFirstPage(String key, HomePage homePage, List<MedrecVo> medrecVoList, Map<String, Map<String, String>> dicMap,
                                     List<HomeDiagnoseInfo> homeDiagnoseInfoList, List<HomeOperationInfo> homeOperationInfoList) {
        MedrecVo medrecVo = new MedrecVo();
        medrecVo.setTitle(key);

        Map<String, String> map = dicMap.get("2"); // 病案首页
        Map<String, Object> content = new HashMap<>();
        try {
            Map<String, Object> objectMap = MapUtil.objectToMap(homePage);
            List<String> firstPageDate = Arrays.asList("birthday", "behospitalDate", "leaveHospitalDate", "qcDate", "gmtCreate");
            for (String objKey : objectMap.keySet()) {
                if (map.containsKey(objKey)) {
                    if (firstPageDate.contains(objKey)) {
                        Date date = (Date) objectMap.get(objKey);
                        if ("birthday".equals(objKey)) {
                            content.put(map.get(objKey), DateUtil.formatDate(date));
                        } else {
                            content.put(map.get(objKey), DateUtil.formatDateTime(date));
                        }
                    } else {
                        content.put(map.get(objKey), String.valueOf(objectMap.get(objKey)).replaceAll("null", ""));
                    }
                }
            }

            // 病案首页手术信息
            if (ListUtil.isNotEmpty(homeOperationInfoList)) {
                Map<String, String> dic3 = dicMap.get("3"); // 病案首页手术信息
                List<Map> mapList = new ArrayList<>();
                List<String> operatDate = Arrays.asList("operationDate");
                for (HomeOperationInfo homeOperationInfo : homeOperationInfoList) {
                    try {
                        Map operatMap = objcetKeyConvert(operatDate, dic3, MapUtil.objectToMap(homeOperationInfo));
                        mapList.add(operatMap);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                content.put("手术信息", JSON.toJSONString(mapList));
            }

            // 病案首页诊断信息
            if (ListUtil.isNotEmpty(homeDiagnoseInfoList)) {
                Map<String, String> dic4 = dicMap.get("4"); // 病案首页诊断信息
                List<Map> mapList = new ArrayList<>();
                List<String> diagnoseDate = Arrays.asList("");
                for (HomeDiagnoseInfo homeDiagnoseInfo : homeDiagnoseInfoList) {
                    try {
                        Map objectMapDiag = objcetKeyConvert(diagnoseDate, dic4, MapUtil.objectToMap(homeDiagnoseInfo));
                        mapList.add(objectMapDiag);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                content.put("出院诊断", JSON.toJSONString(mapList));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        medrecVo.setContent(content);
        medrecVoList.add(medrecVo);
    }


    /**
     * 获取质控条目编码
     *
     * @param qcCasesEntryDTOList
     * @return
     */
    public Map<String, Map<String, String>> getInputCatalogueMap(List<QcCasesEntryDTO> qcCasesEntryDTOList) {
        Map<String, Map<String, String>> res = new HashMap<>();
        for (QcCasesEntryDTO qc : qcCasesEntryDTOList) {
            Map<String, String> map = new HashMap<>();
            map.put("code", qc.getCode());
            map.put("precond", qc.getPrecond());
            map.put("name", qc.getMsg());
            res.put(qc.getCode(), map);
        }
        return res;
    }


    /**
     * 处理定时任务入参
     *
     * @param param
     * @param taskVO
     */
    public void dealTaskVO(String param, TaskVO taskVO) {
        if (StringUtil.isNotBlank(param)) {
            String[] hos = param.split(",");
            List<Long> hosptialIdList = new ArrayList<>();
            for (String id : hos) {
                hosptialIdList.add(Long.parseLong(id));
            }
            taskVO.setHosptialIdList(hosptialIdList);
        }
    }

    /**
     * 评分
     */
    public void execute(TaskVO taskVO, String param) {
//        // 处理医院信息
//        dealTaskVO(param, taskVO);
//        // 类型过滤(1：出院时间比当前时间早4天前的病历（例如：长兴病历）)
//        if (taskVO.getType() != null && taskVO.getType() == 1) {
//            Date date = DateUtil.addDay(DateUtil.now(), -4);
//            taskVO.setLeaveDate(date);
//        }
//        // 近3天不含当天的病历强制评分更新
//        if (taskVO != null && ListUtil.isNotEmpty(taskVO.getIndividuation()) && taskVO.getIndividuation().contains(1)) {
//            // 4天前最早时间
//            taskVO.setStartLeaveDate(DateUtil.getFirstTimeOfDay(DateUtil.addDay(DateUtil.now(), -4)));
//            // 昨天最迟时间
//            taskVO.setEndLeaveDate(DateUtil.getLastTimeOfDay(DateUtil.addDay(DateUtil.now(), -1)));
//        }
//        List<BehospitalInfo> behospitalInfoList = getNoGrade(taskVO);

        List<BehospitalInfo> behospitalInfoList = behospitalInfoFacade.list(new QueryWrapper<BehospitalInfo>()
                .le("behospital_date", taskVO.getEndLeaveDate())
                .ge("behospital_date", taskVO.getStartLeaveDate()));
        for (BehospitalInfo bean : behospitalInfoList) {
            AnalyzeVO analyzeVO = new AnalyzeVO();
            analyzeVO.setIsTask(true);
            analyzeVO.setHospitalId(bean.getHospitalId());
            analyzeVO.setBehospitalCode(bean.getBehospitalCode());
            analyzeVO.setUseCrfCache(taskVO.isUseCrfCache());
            authServiceClient.analyze_rpc(analyzeVO);
        }
    }


    // /**
    //  * 对出院日期之前3天的未评分的病历进行评分
    //  */
    // public void execute2(TaskVO taskVO) {
    //     List<BehospitalInfo> behospitalInfoList = getNoGrade(taskVO);
    //     for (BehospitalInfo bean : behospitalInfoList) {
    //         AnalyzeVO analyzeVO = new AnalyzeVO();
    //         analyzeVO.setIsTask(true);
    //         analyzeVO.setHospitalId(bean.getHospitalId());
    //         analyzeVO.setBehospitalCode(bean.getBehospitalCode());
    //         authServiceClient.analyze_rpc(analyzeVO);
    //     }
    // }

    /**
     * 评分api
     *
     * @param analyzeRunVO
     * @return
     */
    public AnalyzeApiDTO analyzeApi(AnalyzeRunVO analyzeRunVO) {
        AnalyzeApiDTO analyzeApiDTO = new AnalyzeApiDTO(); // 返回结果
        AnalyzeVO analyzeVO = new AnalyzeVO();
        BeanUtil.copyProperties(analyzeRunVO, analyzeVO);
        Long hospitalId = analyzeVO.getHospitalId();
        // 获取病历信息
        BehospitalInfo behospitalInfo = this.getOne(new QueryWrapper<BehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", analyzeRunVO.getHospitalId())
                .eq("behospital_code", analyzeRunVO.getBehospitalCode()), false
        );
        if (null == behospitalInfo) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该病历不存在或已删除!");
        }
        // 处理公共数据
        QueryVo queryVo = dealCommonData(hospitalId, analyzeVO);
        //  调用质控接口
        Response<OutputInfo> response = qcServiceClient.extract(queryVo);
        if (response == null || response.getData() == null) {
            if (null == response) {
                throw new CommonException(CommonErrorCode.RPC_ERROR, "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】");
            } else {
                throw new CommonException(CommonErrorCode.RPC_ERROR,
                        "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】错误原因:" + response.getMsg());
            }
        }
        OutputInfo outputInfo = response.getData();
        // 质控编码列表
        List<String> codeList = new ArrayList<>();
        // code和info的映射map
        Map<String, String> codeToInfoMap = new LinkedHashMap<>();
        // 对codeList 和 codeToInfoMap进行赋值
        setCodeData(outputInfo, codeList, codeToInfoMap);
        AlgorithmDTO algorithmDTO = new AlgorithmDTO();
        // 如果是1，说明已是终末质控，不再保存质控结果数据；如果是0，则保存质控结果数据
        if ("0".equals(analyzeRunVO.getIsPlacefile())) {
            Map<String, Object> resMap = calScoreAndSave(outputInfo, codeList, codeToInfoMap, analyzeVO, queryVo.getBehospitalInfo().getIsPlacefile());
            algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
        } else {
            //终末质控不保存数据
            Map<String, Object> resMap = calScore(outputInfo, codeList, codeToInfoMap, analyzeVO, queryVo.getBehospitalInfo().getIsPlacefile());
            algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
        }

        QcresultInfo qcresultInfo = qcresultInfoFacade.getOne(new QueryWrapper<QcresultInfo>()
                .eq("hospital_id", analyzeVO.getHospitalId())
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .eq("is_deleted", IsDeleteEnum.N.getKey()));
        if (qcresultInfo != null && qcresultInfo.getId() != null) {
            analyzeVO.setQcresultInfoId(qcresultInfo.getId());
        }
        List<MsgDTO> msgDTOList = getMsg(analyzeVO);
        if (ListUtil.isNotEmpty(msgDTOList)) {
            msgDTOList.forEach(msgDTO -> {
                if (StringUtils.isNotEmpty(msgDTO.getInfo()) && StringUtils.isNotEmpty(msgDTO.getInfo().trim()) &&
                        StringUtils.isNotEmpty(msgDTO.getMsg())) {
                    msgDTO.setMsg(msgDTO.getMsg() + "(" + msgDTO.getInfo().trim() + ")");
                }
            });
        }

        List<MsgApiDTO> msgApiDTOList = Lists.newLinkedList();
        msgApiDTOList = BeanUtil.listCopyTo(msgDTOList, MsgApiDTO.class);

        //缺陷总数
        Long num = msgApiDTOList
                .stream()
                .filter(Objects::nonNull)
                .count();
        analyzeApiDTO.setNum(num);
        //不展示缺陷内容，只需要缺陷数量
        if ("1".equals(analyzeRunVO.getIsDefect())) {
            return analyzeApiDTO;
        }
        //审核状态
        analyzeApiDTO.setStatus(
                Optional.ofNullable(behospitalInfo.getStatus())
                        .map(BehospitalStatusEnum::fromCode)
                        .map(BehospitalStatusEnum::getDesc)
                        .orElse("状态未知") // 如果 code 为 null，返回默认值
        );
        analyzeApiDTO.setScoreRes(algorithmDTO.getScore());
        if ("3".equals(behospitalInfo.getStatus())) { //已驳回
            List<MedRejectedInfo> medRejectedInfos = medRejectedInfoFacade.list(new QueryWrapper<MedRejectedInfo>()
                    .eq("hospital_id", hospitalId)
                    .eq("behospital_code", analyzeRunVO.getBehospitalCode())
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .select("cases_entry_id", "rejected_reason")
                    .orderByDesc("gmt_create"));
            if (ListUtil.isNotEmpty(medRejectedInfos)) {
                msgApiDTOList.forEach(msgApiDTO -> {
                    for(MedRejectedInfo medRejectedInfo : medRejectedInfos){
                        if(msgApiDTO.getCasesEntryId().equals(medRejectedInfo.getCasesEntryId())){
                            msgApiDTO.setIsRejectedEntry("1"); //驳回条目
                            msgApiDTO.setRejectedReason(medRejectedInfo.getRejectedReason());
                        }
                    }
                });
            }
        }

        Map<String, List<MsgApiDTO>> newMsgMap = msgApiDTOList.stream()
                .collect(Collectors.groupingBy(
                        dto -> RuleTypeEnum.fromRawValue(dto.getRuleType()).getName(),
                        Collectors.toList()
                ));
        analyzeApiDTO.setMsgApiDTOMap(newMsgMap);

        return analyzeApiDTO;
    }


    /**
     * 评分-运行质控
     *
     * @param analyzeRunVO
     * @return
     */
    public AnalyzeRunDTO analyzeRun(AnalyzeRunVO analyzeRunVO) {
        AnalyzeVO analyzeVO = new AnalyzeVO();
        BeanUtil.copyProperties(analyzeRunVO, analyzeVO);
        Long hospitalId = analyzeVO.getHospitalId();

        // 处理公共数据
        QueryVo queryVo = dealCommonData(hospitalId, analyzeVO);
        //  调用质控接口
        Response<OutputInfo> response = qcServiceClient.extract(queryVo);
        if (response == null || response.getData() == null) {
            if (null == response) {
                throw new CommonException(CommonErrorCode.RPC_ERROR, "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】");
            } else {
                throw new CommonException(CommonErrorCode.RPC_ERROR,
                        "远程质控接口没有返回数据!【" + analyzeVO.getBehospitalCode() + "】错误原因:" + response.getMsg());
            }
        }
        OutputInfo outputInfo = response.getData();
        // 质控编码列表
        List<String> codeList = new ArrayList<>();
        // code和info的映射map
        Map<String, String> codeToInfoMap = new LinkedHashMap<>();
        // 对codeList 和 codeToInfoMap进行赋值
        setCodeData(outputInfo, codeList, codeToInfoMap);

        AlgorithmDTO algorithmDTO = new AlgorithmDTO();
        // 如果是1，说明已是终末质控，不再保存质控结果数据；如果是0，则保存质控结果数据
        if ("0".equals(analyzeRunVO.getIsPlacefile())) {
            Map<String, Object> resMap = calScoreAndSave(outputInfo, codeList, codeToInfoMap, analyzeVO, queryVo.getBehospitalInfo().getIsPlacefile());
            algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
        } else {
            //终末质控不保存数据
            Map<String, Object> resMap = calScore(outputInfo, codeList, codeToInfoMap, analyzeVO, queryVo.getBehospitalInfo().getIsPlacefile());
            algorithmDTO = (AlgorithmDTO) resMap.get("algorithmDTO");
        }
        // 返回缺陷提示信息
        List<MsgDTO> msgDTOList = new ArrayList<>();
        if (ListUtil.isNotEmpty(codeList)) {
            AnalyzeCodeVO analyzeCodeVO = new AnalyzeCodeVO();
            analyzeCodeVO.setCodeList(codeList);
            analyzeCodeVO.setHospitalId(hospitalId);
            // 获取缺陷条目信息
            msgDTOList = getMsgByEntryCode(analyzeCodeVO);
            // 设置info信息
            if (codeToInfoMap != null && !codeToInfoMap.isEmpty()) {
                for (MsgDTO msgDTO : msgDTOList) {
                    String info = codeToInfoMap.get(msgDTO.getCode());
                    if (StringUtil.isNotBlank(info)) {
                        msgDTO.setInfo(info);
                    }
                }
            }
        }
        //缺陷总数
        Long num = msgDTOList
                .stream()
                .filter(Objects::nonNull)
                .count();
        //返回参数组装
        AnalyzeRunDTO analyzeRunDTO = new AnalyzeRunDTO();
        analyzeRunDTO.setNum(num);
        //不展示缺陷内容，只需要缺陷数量
        if ("1".equals(analyzeRunVO.getIsDefect())) {
            return analyzeRunDTO;
        }

        analyzeRunDTO.setScoreRes(algorithmDTO.getScore());
        Map<String, List<MsgDTO>> newMsgMap = msgDTOList.stream()
                .collect(Collectors.groupingBy(
                        dto -> RuleTypeEnum.fromRawValue(dto.getRuleType()).getName(),
                        Collectors.toList()
                ));
        analyzeRunDTO.setMsgDTOMap(newMsgMap);
        return analyzeRunDTO;
    }

    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));
//        }
    }

    public void exportExcelFac(HttpServletResponse response) {
        List<ExportExcelDTO> res = this.exportExcel();
        String fileName = "ihqc";
        ExcelUtils.exportExcelUser(res, null, "病案质控", ExportExcelDTO.class, fileName + ".xls", response);
    }

    /**
     * 质控结果导出
     *
     * @param response
     * @param exportQcresultVO
     */
    public void exportQcresult(HttpServletResponse response, ExportQcresultVO exportQcresultVO) {
        String hospitalId = SysUserUtils.getCurrentHospitalID();
        exportQcresultVO.setHospitalId(hospitalId);
        //时间设置
        exportQcresultVOSet(exportQcresultVO);
        List<ExportExcelDTO> res = this.exportQcresult(exportQcresultVO);
        List<ExportWideExcelDTO> resWide = new ArrayList<ExportWideExcelDTO>();
        if ("2".equals(exportQcresultVO.getRadioCheck())) {
            resWide = transList(res, resWide);
        }
        String fileName = "抽查住院病历质量情况.xls";
        response.setContentType("text/html;charset=UTF-8");
        if ("1".equals(exportQcresultVO.getRadioCheck())) {
            ExcelUtils.exportExcelUser(res, null, "sheet1", ExportExcelDTO.class, fileName, response);
        }
        if ("2".equals(exportQcresultVO.getRadioCheck())) {
            ExcelUtils.exportExcelUser(resWide, null, "sheet1", ExportWideExcelDTO.class, fileName, response);
        }
    }

    public List<ExportWideExcelDTO> transList(List<ExportExcelDTO> res, List<ExportWideExcelDTO> resWide) {
        if (ListUtil.isNotEmpty(res)) {
            res.forEach(exportExcelDTO -> {
                ExportWideExcelDTO exportWideExcelDTO = new ExportWideExcelDTO();
                exportWideExcelDTO.setAvgScore(exportExcelDTO.getAvgScore());
                exportWideExcelDTO.setBehDeptName(exportExcelDTO.getBehDeptName());
                List<ExportExcelBehospitalDTO> excelBehospitalDTOS = exportExcelDTO.getExcelBehospitalDTOS();
                List<ExportExcelWideBehospitalDTO> exportExcelWideBehospitalDTOs = new ArrayList<>();
                excelBehospitalDTOS.forEach(exportExcelBehospitalDTO -> {
                    ExportExcelWideBehospitalDTO exportExcelWideBehospitalDTO = new ExportExcelWideBehospitalDTO();
                    exportExcelWideBehospitalDTO.setDoctorName(exportExcelBehospitalDTO.getDoctorName());
                    exportExcelWideBehospitalDTO.setBehospitalCode(exportExcelBehospitalDTO.getBehospitalCode());
                    exportExcelWideBehospitalDTO.setFileCode(exportExcelBehospitalDTO.getFileCode());
                    exportExcelWideBehospitalDTO.setBehospitalDate(exportExcelBehospitalDTO.getBehospitalDate());
                    exportExcelWideBehospitalDTO.setLeaveHospitalDate(exportExcelBehospitalDTO.getLeaveHospitalDate());
                    exportExcelWideBehospitalDTO.setPatName(exportExcelBehospitalDTO.getPatName());
                    exportExcelWideBehospitalDTO.setScore(exportExcelBehospitalDTO.getScore());
                    exportExcelWideBehospitalDTO.setScoreBn(exportExcelBehospitalDTO.getScoreBn());
                    exportExcelWideBehospitalDTOs.add(exportExcelWideBehospitalDTO);
                });
                exportWideExcelDTO.setExcelBehospitalDTOS(exportExcelWideBehospitalDTOs);
                resWide.add(exportWideExcelDTO);
            });
        }
        return resWide;
    }


    public static void exportQcresultVOSet(ExportQcresultVO exportQcresultVO) {
        //入参验证
        long interval_7 = 7 * 24 * 60 * 60 * 1000;
        long interval_90 = 90 * 24 * 60 * 60 * 1000l;
        //入院时间
        if (null != exportQcresultVO && null != exportQcresultVO.getBehosDateStart() && null != exportQcresultVO.getBehosDateEnd()) {
            Date startDate = exportQcresultVO.getBehosDateStart();
            Date endDate = exportQcresultVO.getBehosDateEnd();
            if ("1".equals(exportQcresultVO.getRadioCheck())) {
                //时间间隔7天
                if (endDate.getTime() < startDate.getTime()) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "截止时间不能小于起始时间");
                }
                if (endDate.getTime() - startDate.getTime() > interval_7) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "统计区间不能大于7天");
                }
            } else {
                //时间间隔90天
                if (endDate.getTime() < startDate.getTime()) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "截止时间不能小于起始时间");
                }
                if (endDate.getTime() - startDate.getTime() > interval_90) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "统计区间不能大于90天");
                }
            }
            exportQcresultVO.setBehosDateStart(DateUtil.getFirstTimeOfDay(exportQcresultVO.getBehosDateStart()));
            exportQcresultVO.setBehosDateEnd(DateUtil.getFirstTimeOfDay(DateUtil.addDay(exportQcresultVO.getBehosDateEnd(), 1)));
        }
        //出院时间
        if (null != exportQcresultVO && null != exportQcresultVO.getLeaveHosDateStart() && null != exportQcresultVO.getLeaveHosDateEnd()) {
            Date startDate = exportQcresultVO.getLeaveHosDateStart();
            Date endDate = exportQcresultVO.getLeaveHosDateEnd();
            if ("1".equals(exportQcresultVO.getRadioCheck())) {
                //时间间隔7天
                if (endDate.getTime() < startDate.getTime()) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "截止时间不能小于起始时间");
                }
                if (endDate.getTime() - startDate.getTime() > interval_7) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "统计区间不能大于7天");
                }
            } else {
                //时间间隔90天
                if (endDate.getTime() < startDate.getTime()) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "截止时间不能小于起始时间");
                }
                if (endDate.getTime() - startDate.getTime() > interval_90) {
                    throw new CommonException(CommonErrorCode.PARAM_ERROR, "统计区间不能大于90天");
                }
            }
            exportQcresultVO.setLeaveHosDateStart(DateUtil.getFirstTimeOfDay(exportQcresultVO.getLeaveHosDateStart()));
            exportQcresultVO.setLeaveHosDateEnd(DateUtil.getFirstTimeOfDay(DateUtil.addDay(exportQcresultVO.getLeaveHosDateEnd(), 1)));
        }
    }

    /**
     * 设置共用code数据
     *
     * @param outputInfo    质控出参数据
     * @param codeList      质控编码列表
     * @param codeToInfoMap 质控编码对应的info信息
     */
    public void setCodeData(OutputInfo outputInfo, List<String> codeList, Map<String, String> codeToInfoMap) {
        Map<String, Map<String, String>> codeMap = outputInfo.getResult();
        for (String key : codeMap.keySet()) {
            codeList.add(key);
            Map<String, String> mapInfo = codeMap.get(key);
            if (mapInfo != null && StringUtil.isNotBlank(mapInfo.get("info"))) {
                codeToInfoMap.put(key, mapInfo.get("info"));
            }
        }
    }

    /**
     * 计算分值
     *
     * @param outputInfo    质控出参数据
     * @param codeList      质控编码列表
     * @param codeToInfoMap 质控编码对应的info信息
     * @param analyzeVO     入参
     * @return
     */
    public Map<String, Object> calScore(OutputInfo outputInfo, List<String> codeList,
                                        Map<String, String> codeToInfoMap, AnalyzeVO analyzeVO,
                                        String isPlacefile) {
        Long hospitalId = analyzeVO.getHospitalId();
        List<QcResultAlgVO> qcResultAlgVOList = new ArrayList<>();
        if (ListUtil.isNotEmpty(codeList)) {
            // 根据质控结果获取质控条目
            QcResultAlgQueryVO qcResultAlgQueryVO = new QcResultAlgQueryVO();
            qcResultAlgQueryVO.setCodeList(codeList);
            qcResultAlgQueryVO.setHospitalId(hospitalId);
            qcResultAlgQueryVO.setIsPlacefile(isPlacefile);
            qcResultAlgVOList = qcCasesEntryFacade.getQcResultAlgVO(qcResultAlgQueryVO);
        }
        // 对info赋值
        for (QcResultAlgVO bean : qcResultAlgVOList) {
            String info = codeToInfoMap.get(bean.getCode());
            if (StringUtil.isNotBlank(info)) {
                bean.setInfo(info);
            }
        }

        // 评分
        AlgorithmVO algorithmVO = new AlgorithmVO();
        algorithmVO.setType(0);
        algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
        algorithmVO.setHospitalId(hospitalId);
        algorithmVO.setBehospitalCode(analyzeVO.getBehospitalCode());
        algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
        algorithmVO.setIsPlacefile(isPlacefile);
        AlgorithmDTO algorithmDTO = algorithmFacade.getAlgorithmRes(algorithmVO);

        // 返回结果信息
        Map<String, Object> map = new HashMap<>();
        map.put("algorithmDTO", algorithmDTO);
        return map;
    }


    /**
     * 计算分值并保存结果至数据库
     *
     * @param outputInfo    质控出参数据
     * @param codeList      质控编码列表
     * @param codeToInfoMap 质控编码对应的info信息
     * @param analyzeVO     入参
     * @return
     */
    public Map<String, Object> calScoreAndSave(OutputInfo outputInfo, List<String> codeList,
                                               Map<String, String> codeToInfoMap, AnalyzeVO analyzeVO,
                                               String isPlacefile) {
        Long hospitalId = analyzeVO.getHospitalId();
        List<QcResultAlgVO> qcResultAlgVOList = new ArrayList<>();
        //获取本用户原手动添加的扣分条目(删除|未删除)
        List<QcCasesEntry> qcCasesEntryHistory = new ArrayList<>();
        List<QcresultDetail> qcresultDetails = getQcDetailHistory(analyzeVO, codeList, qcCasesEntryHistory);
        Map<Long, List<QcCasesEntry>> qcCasesEntryHistoryMap = qcCasesEntryHistory.stream().collect(Collectors.groupingBy(QcCasesEntry::getId));
        if (ListUtil.isNotEmpty(codeList)) {
            // 根据质控结果获取质控条目
            QcResultAlgQueryVO qcResultAlgQueryVO = new QcResultAlgQueryVO();
            qcResultAlgQueryVO.setCodeList(codeList);
            qcResultAlgQueryVO.setHospitalId(hospitalId);
            qcResultAlgQueryVO.setIsPlacefile(isPlacefile);
            qcResultAlgVOList = qcCasesEntryFacade.getQcResultAlgVO(qcResultAlgQueryVO);
        }
        // 对info赋值
        for (QcResultAlgVO bean : qcResultAlgVOList) {
            String info = codeToInfoMap.get(bean.getCode());
            if (StringUtil.isNotBlank(info)) {
                bean.setInfo(info);
            }
        }
        //1.1未删除的手工评分
        List<QcResultAlgVO> rgQcResultAlgVOList = new ArrayList<>();
        if (qcresultDetails != null) {
            List<QcresultDetail> notDelQcDetailHistory = qcresultDetails.stream()
                    .filter(qcresultDetail -> "N".equals(qcresultDetail.getIsDeleted())).collect(Collectors.toList());
            if (ListUtil.isNotEmpty(notDelQcDetailHistory)) {
                notDelQcDetailHistory.stream().forEach(qcresultDetail -> {
                    QcResultAlgVO temp = new QcResultAlgVO();
                    BeanUtils.copyProperties(qcresultDetail, temp);
                    try {
                        temp.setCode(qcCasesEntryHistoryMap.get(qcresultDetail.getCasesEntryId()).get(0).getCode());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    rgQcResultAlgVOList.add(temp);
                });
            }
            qcResultAlgVOList.addAll(rgQcResultAlgVOList);
        }

        // 评分
        AlgorithmVO algorithmVO = new AlgorithmVO();
        algorithmVO.setType(0);
        algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
        algorithmVO.setHospitalId(hospitalId);
        algorithmVO.setBehospitalCode(analyzeVO.getBehospitalCode());
        algorithmVO.setQcResultAlgVOList(qcResultAlgVOList);
        algorithmVO.setIsPlacefile(isPlacefile);
        AlgorithmDTO algorithmDTO = algorithmFacade.getAlgorithmRes(algorithmVO);

        //保存
        Map<String, Object> pageMap = outputInfo.getPageData();
        //保存解析过后的手术知情同意书
        List<String> recIds = new ArrayList<>();
        if (pageMap.containsKey("手术知情同意书")) {
            Object informObject = pageMap.get("手术知情同意书");
            List<Map<String, Object>> informList = (List<Map<String, Object>>) informObject;
            List<StrInformedConsent> strInformedConsents = new ArrayList<>();
            if (ListUtil.isNotEmpty(informList)) {
                informList.forEach(obj ->
                        {
                            Map<String, String> strMap = new HashMap<>();
                            strMap.put("使用植入性材料", String.valueOf(obj.get("使用植入性材料")));
                            StrInformedConsent strInformedConsent = new StrInformedConsent();
                            strInformedConsent.setHospitalId(analyzeVO.getHospitalId());
                            strInformedConsent.setBehospitalCode(analyzeVO.getBehospitalCode());
                            strInformedConsent.setRecId(String.valueOf(obj.get("记录编号")));
                            strInformedConsent.setRecTitle(String.valueOf(obj.get("病历标题")));
                            strInformedConsent.setRecType("知情同意书");
                            strInformedConsent.setContent(JSONObject.toJSONString(strMap));
                            strInformedConsent.setGmtCreate(new Date());
                            strInformedConsents.add(strInformedConsent);
                            recIds.add(String.valueOf(obj.get("记录编号")));
                        }
                );
                //删除手术知情同意书历史ric_id
                strInformedConsentServiceImpl.remove(new QueryWrapper<StrInformedConsent>()
                        .eq("hospital_id", analyzeVO.getHospitalId())
                        .eq("is_deleted", IsDeleteEnum.N.getKey())
                        .eq("behospital_code", analyzeVO.getBehospitalCode())
                        .in("rec_id", recIds));
                //新增
                strInformedConsentServiceImpl.saveBatch(strInformedConsents);
            }
        }
        // 手动拼接数据【知情同意书】【谈话告知书】
        List<MedicalRecord> recordList = medicalRecordFacade.list(new QueryWrapper<MedicalRecord>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .eq("hospital_id", hospitalId)
                .in("mode_id", Arrays.asList(53, 54, 16))
                .orderByAsc("rec_date")
        );
        List<MedicalRecordDTO> medicalRecordDTOList = BeanUtil.listCopyTo(recordList, MedicalRecordDTO.class);
        Map<Long, List<MedicalRecordDTO>> recordMap = EntityUtil.makeEntityListMap(medicalRecordDTOList, "modeId");
        List<MedicalRecordDTO> recordDTOList = new ArrayList<>();
        if (recordMap.get(53L) != null) {
            recordDTOList.addAll(recordMap.get(53L)); // 知情同意书
        }
        if (recordMap.get(16L) != null) {
            recordDTOList.addAll(recordMap.get(16L)); // 手术知情同意书
        }
        // 医嘱信息
        pageMap.put("医嘱信息", null);
        // 医嘱信息
        pageMap.put("检查信息", null);
        // 医嘱信息
        pageMap.put("检验信息", null);
        // 护理信息
        pageMap.put("护理信息", null);
        // 知情同意书 = 【知情同意书】 + 【手术知情同意书】
        pageMap.put("知情同意书", recordDTOList);
        pageMap.put("谈话告知书", recordMap.get(54L));

        String pageData = JSON.toJSONString(pageMap);
        // 获取菜单信息
        List<QcModeDTO> qcModeDTOList = qcModeFacade.getMenu(pageMap);
        String menuData = JSON.toJSONString(qcModeDTOList);

        // 保存评分结果信息
        //计分删除人工添加条目
        algorithmVO.getQcResultAlgVOList().removeAll(rgQcResultAlgVOList);
        Date date = qcresultInfoFacade.saveQcResult(algorithmDTO, algorithmVO, analyzeVO, pageData, menuData, analyzeVO.getIsTask(), null);

        // 返回结果信息
        Map<String, Object> map = new HashMap<>();
        map.put("algorithmDTO", algorithmDTO);
        map.put("date", date);
        return map;
    }

    /**
     * @param analyzeVO
     * @param codeList
     * @Description获取原手动扣分分值条目
     * @Return void
     */
    private List<QcresultDetail> getQcDetailHistory(AnalyzeVO analyzeVO, List<String> codeList, List<QcCasesEntry> qcCasesEntryHistory) {
        List<QcresultDetail> qcresultDetails = null;
        try {
            QcresultInfo qcresultInfoup
                    = qcresultInfoFacade.getOne(
                    new QueryWrapper<QcresultInfo>()
                            .eq("is_deleted", IsDeleteEnum.N.getKey())
                            .eq("hospital_id", analyzeVO.getHospitalId())
                            .eq("behospital_code", analyzeVO.getBehospitalCode()), false);
            //未评过分
            if (qcresultInfoup == null) {
                return null;
            }
            //1.获取上一次评分手工添加的条目
            qcresultDetails = qcresultDetailFacade.list(new QueryWrapper<QcresultDetail>()
                    .eq("hospital_id", analyzeVO.getHospitalId())
                    .eq("behospital_code", analyzeVO.getBehospitalCode())
                    .eq("grade_type", "2")
                    .eq("qcresult_info_id", qcresultInfoup.getId()));
            List<Long> qcDetailIDHistory = qcresultDetails.stream().map(QcresultDetail::getCasesEntryId).collect(Collectors.toList());

            if (ListUtil.isNotEmpty(qcDetailIDHistory)) {
                List<QcCasesEntry> qcCasesEntries = qcCasesEntryFacade.list(new QueryWrapper<QcCasesEntry>()
                        .select("id,code")
                        .eq("is_deleted", IsDeleteEnum.N.getKey())
                        .in("id", qcDetailIDHistory));
                if (ListUtil.isNotEmpty(qcCasesEntries)) {
                    qcCasesEntryHistory.addAll(qcCasesEntries);
                    codeList.removeAll(qcCasesEntryHistory.stream().map(QcCasesEntry::getCode).collect(Collectors.toList()));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return qcresultDetails;
    }

    /**
     * 获取明细
     *
     * @param behospitalcodeVO
     * @return
     */
    public AnalyzeCaseDetailDTO getCaseDetail(BehospitalcodeVO behospitalcodeVO) {
        AnalyzeCaseDetailDTO res = new AnalyzeCaseDetailDTO(); // 返回结果
        // 获取病历信息
        BehospitalInfo behospitalInfo = this.getOne(new QueryWrapper<BehospitalInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", behospitalcodeVO.getHospitalId())
                .eq("behospital_code", behospitalcodeVO.getBehospitalCode()), false
        );
        res.setBehospitalCode(behospitalcodeVO.getBehospitalCode());//病案号
        res.setName(behospitalInfo.getName());//姓名
        res.setSex(behospitalInfo.getSex());//性别
        // 获取患者年龄
        HomePage homePage = homePageFacade.getOne(new QueryWrapper<HomePage>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", behospitalcodeVO.getHospitalId())
                .eq("behospital_code", behospitalcodeVO.getBehospitalCode()), false
        );
        res.setAge(homePage.getAge());//年龄
        // 获取提示信息
        AnalyzeVO analyzeVO = new AnalyzeVO();
        BeanUtil.copyProperties(behospitalcodeVO, analyzeVO);
        QcresultInfo qcresultInfo = qcresultInfoFacade.getOne(new QueryWrapper<QcresultInfo>()
                .eq("hospital_id", analyzeVO.getHospitalId())
                .eq("behospital_code", analyzeVO.getBehospitalCode())
                .eq("is_deleted", IsDeleteEnum.N.getKey()));
        if (qcresultInfo != null && qcresultInfo.getId() != null) {
            analyzeVO.setQcresultInfoId(qcresultInfo.getId());
        }
        res.setScoreRes(qcresultInfo.getScoreRes());//得分
        List<MsgDTO> msgDTOList = getMsgDetail(analyzeVO);
        res.setNum(msgDTOList.size());//条目数
        res.setMsgDTOList(msgDTOList);//提示信息

        return res;
    }

    /**
     * 手术费，抗菌药物，手术和病理费等含有人数
     *
     * @param filterVO
     * @return
     */
    public List<Map<String, String>> selectOperationNum(FilterVO filterVO) {
        return baseMapper.selectOperationNum(filterVO);
    }

    /**
     * 触发规则人数
     *
     * @param filterVO
     * @return
     */
    public Map<String, Long> triggeringRules(FilterVO filterVO) {
        return baseMapper.triggeringRules(filterVO);
    }

    /**
     * 病案首页关联的出院病历
     *
     * @param filterVO
     * @return
     */
    public List<Map<String, String>> getMedicalRecords(@Param("filterVO") FilterVO filterVO) {
        return baseMapper.getMedicalRecords(filterVO);
    }

    /**
     * 首页恶性肿瘤人数
     *
     * @param filterVO
     * @return
     */
    public List<Map<String, String>> malignancy(@Param("filterVO") FilterVO filterVO) {
        return baseMapper.malignancy(filterVO);
    }


}
