package com.xinelu.manage.service.signpatientmanageroute.impl;

import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.constant.*;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.entity.SysDictData;
import com.xinelu.common.enums.*;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.AgeUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.labelfieldcontent.LabelFieldContent;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientquestionoptionresult.PatientQuestionOptionResult;
import com.xinelu.manage.domain.patientquestionsubjectresult.PatientQuestionSubjectResult;
import com.xinelu.manage.domain.patientquestionsubmitresult.PatientQuestionSubmitResult;
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.phonedialrecord.PhoneDialRecord;
import com.xinelu.manage.domain.questioninfo.QuestionInfo;
import com.xinelu.manage.domain.scriptInfo.ScriptInfo;
import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.domain.signroutetriggercondition.SignRouteTriggerCondition;
import com.xinelu.manage.dto.aiob.ActualTimeTaskDto;
import com.xinelu.manage.dto.manualfollowup.ManualFollowUpDTO;
import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
import com.xinelu.manage.dto.patientquestionoptionresult.PatientQuestionOptionResultDTO;
import com.xinelu.manage.dto.patientquestionsubjectresult.PatientQuestionSubjectResultDTO;
import com.xinelu.manage.dto.patientquestionsubmitresult.PatientQuestionSubmitResultDTO;
import com.xinelu.manage.dto.signpatientmanageroutenode.CreateAiobActualTimeTaskDto;
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientquestionoptionresult.PatientQuestionOptionResultMapper;
import com.xinelu.manage.mapper.patientquestionsubjectresult.PatientQuestionSubjectResultMapper;
import com.xinelu.manage.mapper.patientquestionsubmitresult.PatientQuestionSubmitResultMapper;
import com.xinelu.manage.mapper.patienttaskexecuterecord.PatientTaskExecuteRecordMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.phonedialrecord.PhoneDialRecordMapper;
import com.xinelu.manage.mapper.scriptInfo.ScriptInfoMapper;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.mapper.signroutetriggercondition.SignRouteTriggerConditionMapper;
import com.xinelu.manage.service.aiob.IAIOBService;
import com.xinelu.manage.service.labelfieldcontent.ILabelFieldContentService;
import com.xinelu.manage.service.patienttaskstatistics.IPatientTaskStatisticsService;
import com.xinelu.manage.service.propagandainfo.IPropagandaInfoService;
import com.xinelu.manage.service.questioninfo.IQuestionInfoService;
import com.xinelu.manage.service.signpatientmanageroute.ISignPatientManageRouteService;
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
import com.xinelu.manage.service.specialdiseasenode.ISpecialDiseaseNodeService;
import com.xinelu.manage.service.specialdiseaseroute.ISpecialDiseaseRouteService;
import com.xinelu.manage.vo.labelfieldcontent.LabelField;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldAndPartitionDict;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import com.xinelu.manage.vo.manualfollowup.ManualFollowPatientVO;
import com.xinelu.manage.vo.manualfollowup.ManualFollowUpVO;
import com.xinelu.manage.vo.patientinfo.PatientInfoVo;
import com.xinelu.manage.vo.propagandainfo.PropagandaMaterialsVo;
import com.xinelu.manage.vo.questionInfo.QuestionVO;
import com.xinelu.manage.vo.signpatientmanageroute.PhonePush;
import com.xinelu.manage.vo.signpatientmanageroute.SignPatientManageRouteVO;
import com.xinelu.manage.vo.signpatientmanageroutenode.SignPatientManageNodeAuditVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordSelectVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordVo;
import com.xinelu.manage.vo.signroutetriggercondition.SignRouteTriggerConditionVO;
import com.xinelu.manage.vo.specialdiseasenode.RouteTaskAuditVo;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeAuditVo;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseChildRouteAuditVo;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteAuditVo;
import com.xinelu.system.mapper.SysDictDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 签约患者管理任务路径Service业务层处理
 *
 * @author haown
 * @date 2024-03-18
 */
@Slf4j
@Service
public class SignPatientManageRouteServiceImpl implements ISignPatientManageRouteService {
    @Resource
    private SignPatientManageRouteMapper signPatientManageRouteMapper;
    @Resource
    private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
    @Resource
    private PatientTaskExecuteRecordMapper patientTaskExecuteRecordMapper;
    @Resource
    private PatientQuestionSubmitResultMapper patientQuestionSubmitResultMapper;
    @Resource
    private PatientQuestionSubjectResultMapper patientQuestionSubjectResultMapper;
    @Resource
    private PatientQuestionOptionResultMapper patientQuestionOptionResultMapper;
    @Resource
    private SignRouteTriggerConditionMapper signRouteTriggerConditionMapper;
    @Resource
    private ISignPatientManageRouteNodeService iSignPatientManageRouteNodeService;
    @Resource
    private SignPatientRecordMapper signPatientRecordMapper;
    @Resource
    private ISpecialDiseaseRouteService specialDiseaseRouteService;
    @Resource
    private ISpecialDiseaseNodeService specialDiseaseNodeService;
    @Resource
    private PatientVisitRecordMapper patientVisitRecordMapper;
    @Resource
    private ScriptInfoMapper scriptInfoMapper;
    @Resource
    private IQuestionInfoService questionInfoService;
    @Resource
    private IPropagandaInfoService propagandaInfoService;
    @Resource
    private LabelFieldContentMapper labelFieldContentMapper;
    @Resource
    private ISignPatientManageRouteNodeService signPatientManageRouteNodeService;
    @Resource
    private AliYunSmsTwoConfig aliYunSmsTwoConfig;
    @Resource
    private PhoneDialRecordMapper phoneDialRecordMapper;
    @Resource
    private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
    @Resource
    private IPatientTaskStatisticsService patientTaskStatisticsService;
    @Resource
    private ILabelFieldContentService labelFieldContentService;
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private IAIOBService aiobService;
    @Resource
    private SysDictDataMapper sysDictDataMapper;
    @Value("${aiob.callBackUrl}")
    private String callBackUrl;

    private static final String SUCCESS = "OK";

    /**
     * 查询签约患者管理任务路径
     *
     * @param id 签约患者管理任务路径主键
     * @return 签约患者管理任务路径
     */
    @Override
    public SignPatientManageRouteVO selectSignPatientManageRouteById(Long id) {
        return signPatientManageRouteMapper.selectSignPatientManageRoute(id);
    }

    /**
     * 查询签约患者管理任务路径列表
     *
     * @param signPatientManageRoute 签约患者管理任务路径
     * @return 签约患者管理任务路径
     */
    @Override
    public List<SignPatientManageRoute> selectSignPatientManageRouteList(SignPatientManageRoute signPatientManageRoute) {
        return signPatientManageRouteMapper.selectSignPatientManageRouteList(signPatientManageRoute);
    }

    /**
     * 新增签约患者管理任务路径
     *
     * @param signPatientManageRoute 签约患者管理任务路径
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSignPatientManageRoute(SignPatientManageRouteVO signPatientManageRoute) {
        //如果是批量 创建
        if (StringUtils.isNotBlank(signPatientManageRoute.getSn())) {
            SignPatientManageRouteNodeDto signPatientManageRouteNode = new SignPatientManageRouteNodeDto();
            signPatientManageRouteNode.setNodePlanTime(LocalDateTime.now());
            List<SignPatientManageRouteNode> signPatientManageRouteNodes = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNode);
            if (CollectionUtils.isNotEmpty(signPatientManageRouteNodes) && signPatientManageRouteNodes.size() >= 1000) {
                return AjaxResult.error("今日创建任务已达上线，请改日创建任务！");
            }
            //获取患者信息
            List<PatientInfoVo> listPatient = new ArrayList<>();
            PatientInfoDto patientInfo = new PatientInfoDto();
            patientInfo.setSn(signPatientManageRoute.getSn());
            listPatient = patientInfoMapper.getPatientList(patientInfo);
            if (CollectionUtils.isNotEmpty(listPatient) && listPatient.size() > 1000) {
                return AjaxResult.error("创建任务数量超出当日上限，请减少创建任务数量！");
            }
            if (CollectionUtils.isNotEmpty(listPatient) && CollectionUtils.isNotEmpty(signPatientManageRouteNodes) && (listPatient.size() + signPatientManageRouteNodes.size()) > 1000) {
                return AjaxResult.error("创建任务数量超出当日上限，请减少创建任务数量！");
            }
            for (PatientInfoVo patientInfoVo : listPatient) {
                signPatientManageRoute.setPatientId(patientInfoVo.getId());
                signPatientManageRoute.setPatientName(patientInfoVo.getPatientName());
                signPatientManageRoute.setDepartmentId(patientInfoVo.getDepartmentId());
                signPatientManageRoute.setDepartmentName(patientInfoVo.getDepartmentName());
                AjaxResult ar = insertSignPatientManageRouteForPatient(signPatientManageRoute);
                //如果有错误码，直接返回；
                if (ar.containsValue(901))
                    return ar;
            }
            return AjaxResult.success();
        } else {
            return insertSignPatientManageRouteForPatient(signPatientManageRoute);

        }

    }

    public AjaxResult insertSignPatientManageRouteForPatient(SignPatientManageRouteVO signPatientManageRoute) {
        // 新增主表
        signPatientManageRoute.setTaskCreateType(TaskCreateTypeEnum.MANUAL_CREATE.getInfo());
        signPatientManageRoute.setCreateBy(SecurityUtils.getUsername());
        signPatientManageRoute.setCreateTime(LocalDateTime.now());
        //任务执行类型，批量执行
        if (StringUtils.isNotBlank(signPatientManageRoute.getSn())) {
            signPatientManageRoute.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
        }

        //任务路由主表  新增
        int insertRoute = signPatientManageRouteMapper.insertSignPatientManageRoute(signPatientManageRoute);
        if (insertRoute < 0) {
            return AjaxResult.error(901, "患者管理任务路径失败！请联系管理员！");//新增签约
        }
        // 新增节点表
        List<SignPatientManageRouteNode> signPatientManageRouteNodes = new ArrayList<>();
        for (SignPatientManageRouteNode routeNode : signPatientManageRoute.getRouteNodeList()) {
            if (Objects.isNull(routeNode) || StringUtils.isBlank(routeNode.getTaskNodeType()) || (" ").equals(routeNode.getTaskNodeType())
                    || (Objects.isNull(routeNode.getNodePlanTime()) && (StringUtils.isBlank(routeNode.getRouteNodeName()) || !Objects.isNull(routeNode.getRouteNodeDay()))) ||
                    (Objects.isNull(routeNode.getRouteNodeDay()) && Objects.isNull(routeNode.getNodePlanTime()))) {
                continue;
            }
            //任务执行类型，批量执行
            if (StringUtils.isNotBlank(signPatientManageRoute.getSn())) {
                routeNode.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
                routeNode.setSn(signPatientManageRoute.getSn());
            }
            if (Objects.isNull(signPatientManageRoute.getSignPatientRecordId())) {
                //更新   审核状态为 已审核，适用场景：对未签约患者 手动创建任务  zyk  20241204
                routeNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
            }
            extracted(signPatientManageRoute, signPatientManageRouteNodes, routeNode);
        }
        if (CollectionUtils.isEmpty(signPatientManageRouteNodes)) {
            return AjaxResult.error(901, "创建任务中至少有一个管理任务节点！可能是因为时间或其它属性信息不全导致，请完善后重试。");
        }
        //批量插入任务
        int insertBatchCount = signPatientManageRouteNodeMapper.insertBatch(signPatientManageRouteNodes);
        if (insertBatchCount < 0) {
            return AjaxResult.error(901, "新增签约患者管理任务路径失败！请联系管理员！");
        }
        SignPatientRecord signPatientRecord = new SignPatientRecord();
        // if(Objects.isNull(signPatientManageRoute.getSignPatientRecordId())) {
        //     //更新 签约记录的 审核状态为 已审核，适用场景：手动创建任务  zyk  20241204
        //     signPatientRecord.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
        // }
        // else

        //×××××更新 签约记录的 审核状态为 未审核，适用场景：对已签约患者 手动创建任务  zyk  20241204
        if (Objects.nonNull(signPatientManageRoute.getSignPatientRecordId())) {
            signPatientRecord.setRouteCheckStatus(RouteCheckStatusEnum.UNAUDITED.getInfo());
            signPatientRecord.setId(signPatientManageRoute.getSignPatientRecordId());
            int updateRecord = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
            if (updateRecord < 0) {
                return AjaxResult.error(901, "修改签约患者管理任务路径失败！请联系管理员！");
            }
        }
        //适用场景：对未签约患者 手动创建任务，  或已签约但尚未审核画像的
        if (labelFieldContentService.selectLabelFieldContentByPatientId(signPatientManageRoute.getPatientId()).size() == 0) {
            //获取画像信息
            List<LabelFieldAndPartitionDict> labelFieldAndPartitionDictList = labelFieldContentService.groupingValue(0L, signPatientManageRoute.getPatientId());
            // 画像信息保存
            LabelField labelField = new LabelField();
            labelField.setLabelFieldAndPartitionDictList(labelFieldAndPartitionDictList);
            labelFieldContentService.insertLabelField(labelField);
            // 替换手动生成的任务中的标签
            signPatientManageRouteNodeService.manualCreateTaskLabelReplaceByPatientId(signPatientManageRoute.getPatientId());

        }
        return AjaxResult.success();
    }


    /**
     * 修改签约患者管理任务路径
     *
     * @param signPatientManageRoute 签约患者管理任务路径
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateSignPatientManageRoute(SignPatientManageRouteVO signPatientManageRoute) {
        int deleteRouteNodeCount = signPatientManageRouteNodeMapper.deleteRouteNodeByManageRouteId(signPatientManageRoute.getSignPatientManageRouteId());
        if (deleteRouteNodeCount < 0) {
            return AjaxResult.error("修改签约患者管理任务路径失败！请联系管理员！");
        }
        int deleteConditionCount = signRouteTriggerConditionMapper.deleteConditionByPatientManageRouteId(signPatientManageRoute.getSignPatientManageRouteId());
        if (deleteConditionCount < 0) {
            return AjaxResult.error("修改签约患者管理任务路径失败！请联系管理员！");
        }
        signPatientManageRoute.setUpdateBy(SecurityUtils.getUsername());
        signPatientManageRoute.setUpdateTime(LocalDateTime.now());
        int updateCount = signPatientManageRouteMapper.updateSignPatientManageRoute(signPatientManageRoute);
        if (updateCount < 0) {
            return AjaxResult.error("修改签约患者管理任务路径失败！请联系管理员！");
        }

        List<SignPatientManageRouteNode> routeNodeList = signPatientManageRoute.getRouteNodeList();
        for (SignPatientManageRouteNode signPatientManageRouteNode : routeNodeList) {
            signPatientManageRouteNode.setManageRouteId(signPatientManageRoute.getSignPatientManageRouteId());
            signPatientManageRouteNode.setCreateTime(LocalDateTime.now());
            signPatientManageRouteNode.setCreateBy(SecurityUtils.getUsername());
        }
        int insertBatchCount = signPatientManageRouteNodeMapper.insertBatch(routeNodeList);
        if (insertBatchCount < 0) {
            return AjaxResult.error("新增签约患者管理任务路径失败！请联系管理员！");
        }
        List<SignRouteTriggerCondition> signRouteTriggerConditions = new ArrayList<>();
        for (SignRouteTriggerConditionVO signRouteTriggerCondition : signPatientManageRoute.getTriggerConditionList()) {
            SignRouteTriggerCondition triggerCondition = new SignRouteTriggerCondition();
            signRouteTriggerCondition.setCreateTime(LocalDateTime.now());
            signRouteTriggerCondition.setPatientManageRouteId(signPatientManageRoute.getId());
            signRouteTriggerCondition.setCreateBy(SecurityUtils.getUsername());
            BeanUtils.copyBeanProp(triggerCondition, signRouteTriggerCondition);
            signRouteTriggerConditions.add(triggerCondition);
        }
        int insertTriggerCondition = signRouteTriggerConditionMapper.insertBatch(signRouteTriggerConditions);
        if (insertTriggerCondition < 0) {
            return AjaxResult.error("新增签约患者管理任务路径失败！请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除签约患者管理任务路径
     *
     * @param ids 需要删除的签约患者管理任务路径主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteSignPatientManageRouteByIds(Long[] ids) {
        return signPatientManageRouteMapper.deleteSignPatientManageRouteByIds(ids);
    }

    /**
     * 删除签约患者管理任务路径信息
     *
     * @param id 签约患者管理任务路径主键
     * @return 结果
     */
    @Override
    public int deleteSignPatientManageRouteById(Long id) {
        return signPatientManageRouteMapper.deleteSignPatientManageRouteById(id);
    }

    /**
     * 查询人工随访待办列表
     *
     * @param manualFollowUpDTO 人工随访查询DTO
     * @return ManualFollowUpVO 人工随访代办VO
     */
    @Override
    @DataScope(agencyAlias = "pi", deptAlias = "pi")
    public List<ManualFollowUpVO> selectManualFollowUpList(ManualFollowUpDTO manualFollowUpDTO) {
        if (manualFollowUpDTO.getNodeExecuteStatus().equals(NodeExecuteStatusEnum.UNEXECUTED.getInfo())) {
            manualFollowUpDTO.setPhoneNodeExecuteResultStatus(null);
        }
        manualFollowUpDTO.setPhonePushSign(1L);
        //1、查询
        List<ManualFollowUpVO> manualFollowUpVOS = signPatientManageRouteMapper.selectManualFollowUpList(manualFollowUpDTO);
        //字典名称匹配
        ArrayList<String> strings = new ArrayList<>();
        strings.add("task_node_type");
        strings.add("route_name");
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByTypeList(strings);
        for (ManualFollowUpVO manualFollowUpVO : manualFollowUpVOS) {
            SysDictData taskNodeType = sysDictDataList.stream().filter(Objects::nonNull).filter(item -> item.getDictValue().equals(manualFollowUpVO.getTaskNodeType())).findFirst().orElse(new SysDictData());
            if (StringUtils.isNotBlank(taskNodeType.getDictLabel())) {
                manualFollowUpVO.setTaskNodeTypeName(taskNodeType.getDictLabel());
            }
            SysDictData routeNodeName = sysDictDataList.stream().filter(Objects::nonNull).filter(item -> item.getDictValue().equals(manualFollowUpVO.getRouteNodeName())).findFirst().orElse(new SysDictData());
            if (StringUtils.isNotBlank(routeNodeName.getDictLabel())) {
                manualFollowUpVO.setRouteNode(routeNodeName.getDictLabel());
            }
        }
        //2、1如果是查询已执行的任务，直接返回查询结果
        if (manualFollowUpDTO.getNodeExecuteStatus().equals(NodeExecuteStatusEnum.EXECUTED.getInfo())) {
            return manualFollowUpVOS;
        }
        //2.2如果是查询“所有”、"未执行“任务，则直接返回查询结果
        if (StringUtils.isNotBlank(manualFollowUpDTO.getTimeSign()) && manualFollowUpDTO.getTimeSign().equals("WHOLE")) {
            return manualFollowUpVOS;
        }
        //2.3如果是查询未执行（截止到当前时间）的任务，
        ArrayList<ManualFollowUpVO> manualFollowUps = new ArrayList<>();
        for (ManualFollowUpVO manualFollowUpVO : manualFollowUpVOS) {
            //3.1判断路径节点，组装数据
            //任务执行时间，
            LocalDate localDate = null;
            if (Objects.nonNull(manualFollowUpVO.getNodePlanTime()) && StringUtils.isNotBlank(manualFollowUpVO.getNodePlanTime().toString())) {
                localDate = manualFollowUpVO.getNodePlanTime().toLocalDate();
            } else {
                //3.2根据出院时间 和 第几天 计算
                if (Objects.nonNull(manualFollowUpVO.getDischargeTime())) {
                    localDate = manualFollowUpVO.getDischargeTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
                }
                //3.3根据就诊时间  和 第几天  计算
                if (Objects.isNull(manualFollowUpVO.getDischargeTime()) && Objects.nonNull(manualFollowUpVO.getVisitTime())) {
                    localDate = manualFollowUpVO.getVisitTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
                }
                //3.4如果为空，不予处理
                if (Objects.isNull(localDate)) {
                    continue;
                }
            }
            //3.5如果截止到当前时间，已到期，则放入返回集合
            boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
            if (before) {
                //转换成中文……
                manualFollowUpVO.setRouteNodeName(RouteNodeNameEnum.getNameByInfo(manualFollowUpVO.getRouteNodeName()).getName());
                manualFollowUpVO.setPlanTime(localDate);
                // 3.6  放入集合
                manualFollowUps.add(manualFollowUpVO);
            }
        }

        //返回今天之前任务
        return manualFollowUps;
    }

    /**
     * @return 结果
     * @description 随访待办列表-创建实时呼叫任务
     * @Param createAiboActualTimeTaskDto 创建百度外呼实时任务传输对象
     * @Author haown
     * @Date 2024-11-4 16:06
     */
    @Override
    public Long createActualTimeTask(CreateAiobActualTimeTaskDto createAiboActualTimeTaskDto) {
        ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(createAiboActualTimeTaskDto.getScriptInfoId());
        SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(createAiboActualTimeTaskDto.getManageRouteId());
        PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(signPatientManageRoute.getPatientId());
        // 没有任务则创建任务
        if (ObjectUtils.isNotEmpty(scriptInfo)) {
            ActualTimeTaskDto actualTimeTaskDto = new ActualTimeTaskDto();
            actualTimeTaskDto.setRobotId(scriptInfo.getRobotPublishId());
            actualTimeTaskDto.setMobile(patientInfo.getPatientPhone());
            actualTimeTaskDto.setSecretType(2);
            actualTimeTaskDto.setStopDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 20:00:00");
            // 查询患者画像信息
            List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfo.getId());
            // 处理变量
            JSONObject jsonObject = new JSONObject();
            if (com.xinelu.common.utils.StringUtils.isNotBlank(scriptInfo.getVariables())) {
                List<String> variables = Arrays.asList(scriptInfo.getVariables().split("\\|"));
                variables.forEach(variable -> {
                    LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), variable.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
                    jsonObject.fluentPut(variable, ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
                });
            }
            actualTimeTaskDto.setDialogVar(jsonObject);
            actualTimeTaskDto.setCallBackUrl(callBackUrl);
            actualTimeTaskDto.setExtJson(createAiboActualTimeTaskDto.getSignPatientManageRouteNodeId() + "");
            return aiobService.createActualTimeTask(actualTimeTaskDto);
        }
        return 0L;
    }

    /**
     * 查询人工随访患者基本信息
     *
     * @param id 签约患者管理任务表id
     * @return 人工随访患者基本信息VO
     */
    @Override
    public AjaxResult selectFollowPatientInfo(Long id) {
        ManualFollowPatientVO patientVO = signPatientManageRouteMapper.selectFollowPatientInfo(id);
        if (ObjectUtils.isEmpty(patientVO)) {
            return AjaxResult.error("患者信息不存在！");
        }
        if (Objects.isNull(patientVO.getAge()) && Objects.nonNull(patientVO.getBirthDate())) {
            // 设置年龄
            patientVO.setAge(AgeUtil.getAgeMonth(patientVO.getBirthDate().toString()));
        }
        return AjaxResult.success(patientVO);
    }

    /**
     * 人工随访代办处理
     *
     * @param dto 患者问卷提交结果信息表DTO
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addPatientQuestionResult(PatientQuestionSubmitResultDTO dto) throws ClientException {
        String routeHandlePerson = dto.getRouteHandlePerson();
        LocalDateTime time = LocalDateTime.now();
        // 如果任务类型是电话外呼，更新节点任务表，新增患者管理任务执行记录
        if (dto.getTaskNodeType().equals(TaskContentEnum.PHONE_OUTBOUND.getInfo())) {
            // 更新节点任务表
            if (StringUtils.isBlank(dto.getPhoneConnectStatus())) {
                dto.setPhoneConnectStatus(PhoneConnectStatusEnum.CONNECTED.getInfo());
            }
            updateSignPatientManageRouteNode(dto, routeHandlePerson, time);
            // 新增患者管理任务执行记录
            insertPatientTaskExecuteRecord(dto, routeHandlePerson, time);
            // 电话记录
            phoneDialRecordExtracted(dto, time);
            // 发送短信
            if (StringUtils.isNotBlank(dto.getPhoneMessageRemind()) && (PhoneMessageRemindEnum.EVERYONE_SEND_MESSAGE.getInfo().equals(dto.getPhoneMessageRemind()) || (PhoneConnectStatusEnum.CONNECTED.getInfo().equals(dto.getPhoneConnectStatus()) && PhoneMessageRemindEnum.CONNECTED_SEND_MESSAGE.getInfo().equals(dto.getPhoneMessageRemind())) || (PhoneConnectStatusEnum.NOTCONNECTED.getInfo().equals(dto.getPhoneConnectStatus()) && PhoneMessageRemindEnum.NOT_CONNECTED_SEND_MESSAGE.getInfo().equals(dto.getPhoneMessageRemind())))) {
                SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
                String patientPhone = signPatientManageRouteMapper.selectPatientPhone(dto.getPatientId());
                smsInfoDTO.setPhoneNumbers(patientPhone);
                smsInfoDTO.setSignName(aliYunSmsTwoConfig.getSignName());
                smsInfoDTO.setTemplateCode(dto.getPhoneMessageTemplateCode());
                Boolean b = sendSms(smsInfoDTO);
                //发送记录
                shortMessageSendRecordExtracted(dto, time, b, null);
                if (!b) {
                    log.info("短信发送失败");
                } else {
                    log.info("短信发送成功");
                }
            }
        } else {
            // 如果任务类型不是电话外呼,更新节点任务表,新增患者管理任务执行记录,新增问卷提交结果表、题目表、选项表
            // 更新节点任务表
            updateSignPatientManageRouteNode(dto, routeHandlePerson, time);
            // 新增患者管理任务执行记录
            Long taskExecuteRecordId = insertPatientTaskExecuteRecord(dto, routeHandlePerson, time);
            PatientQuestionSubmitResult patientQuestionSubmitResult = new PatientQuestionSubmitResult();
            BeanUtils.copyBeanProp(patientQuestionSubmitResult, dto);
            List<PatientQuestionOptionResultDTO> patientQuestionOptionResultsFlag = new ArrayList<>();
            patientQuestionSubmitResult.setRemarkableFlag(ContentedAndRemarkableFlagEnum.ROUTINE.getInfo());
            patientQuestionSubmitResult.setContentedFlag(ContentedAndRemarkableFlagEnum.CONTENTED.getInfo());
            dto.getSubjectResultDTOList().forEach(item -> patientQuestionOptionResultsFlag.addAll(item.getOptionResultList()));
            if (CollectionUtils.isNotEmpty(patientQuestionOptionResultsFlag)) {
                List<PatientQuestionOptionResultDTO> remarkableFlag = patientQuestionOptionResultsFlag.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getRemarkableFlag()) && Objects.nonNull(item.getOptionChooseSign()) && item.getOptionChooseSign().equals(0) && ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo().equals(item.getRemarkableFlag())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(remarkableFlag)) {
                    patientQuestionSubmitResult.setRemarkableFlag(ContentedAndRemarkableFlagEnum.REMARKABLE.getInfo());
                }
                List<PatientQuestionOptionResultDTO> contentedFlag = patientQuestionOptionResultsFlag.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getContentedFlag()) && Objects.nonNull(item.getOptionChooseSign()) && item.getOptionChooseSign().equals(0) && ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo().equals(item.getRemarkableFlag())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(contentedFlag)) {
                    patientQuestionSubmitResult.setContentedFlag(ContentedAndRemarkableFlagEnum.DISCONTENTED.getInfo());
                }
            }
            patientQuestionSubmitResult.setCreateBy(routeHandlePerson);
            patientQuestionSubmitResult.setCreateTime(time);
            patientQuestionSubmitResult.setTaskExecuteRecordId(taskExecuteRecordId);
            // 新增患者问卷提交结果
            if (patientQuestionSubmitResultMapper.insertPatientQuestionSubmitResult(patientQuestionSubmitResult) <= 0) {
                throw new ServiceException("新增患者问卷提交结果失败");
            }
            // 获取到患者问卷题目提交结果信息DTO
            List<PatientQuestionSubjectResultDTO> subjectResultList = dto.getSubjectResultDTOList();
            // 初始化患者问卷题目提交结果信息
            List<PatientQuestionSubjectResult> patientQuestionSubjectResults = new ArrayList<>();
            // 获取到患者问卷题目选项提交结果DTO
            List<PatientQuestionOptionResultDTO> patientQuestionOptionResults = new ArrayList<>();
            for (PatientQuestionSubjectResultDTO questionSubjectResult : subjectResultList) {
                PatientQuestionSubjectResult saveQuestionSubject = new PatientQuestionSubjectResult();
                BeanUtils.copyBeanProp(saveQuestionSubject, questionSubjectResult);
                saveQuestionSubject.setQuestionSubmitResultId(patientQuestionSubmitResult.getId());
                saveQuestionSubject.setCreateBy(routeHandlePerson);
                saveQuestionSubject.setCreateTime(time);
                saveQuestionSubject.setQuestionSubjectId(questionSubjectResult.getId());
                patientQuestionSubjectResults.add(saveQuestionSubject);
                patientQuestionOptionResults.addAll(questionSubjectResult.getOptionResultList());
            }
            // 新增患者问卷题目提交结果
            if (patientQuestionSubjectResultMapper.saveQuestionSubjectList(patientQuestionSubjectResults) <= 0) {
                throw new ServiceException("新增患者问卷题目提交结果失败");
            }
            // 初始化患者问卷题目选项提交结果
            List<PatientQuestionOptionResult> saveQuestionSubjectOptions = new ArrayList<>();
            for (PatientQuestionOptionResultDTO patientQuestionOptionResult : patientQuestionOptionResults) {
                PatientQuestionOptionResult saveQuestionOption = new PatientQuestionOptionResult();
                BeanUtils.copyBeanProp(saveQuestionOption, patientQuestionOptionResult);
                // 从已保存的患者问卷题目结果列表中查找当前选项所对应的题目结果
                PatientQuestionSubjectResult patientQuestionSubjectResult = patientQuestionSubjectResults.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getQuestionNumber()) && patientQuestionOptionResult.getQuestionNumber().compareTo(item.getQuestionNumber()) == 0).findFirst().orElse(new PatientQuestionSubjectResult());
                saveQuestionOption.setQuestionSubjectResultId(patientQuestionSubjectResult.getId());
                saveQuestionOption.setCreateTime(time);
                saveQuestionOption.setCreateBy(routeHandlePerson);
                //2024-12-4
                if (StringUtils.isBlank(patientQuestionOptionResult.getContentedFlag())) {
                    saveQuestionOption.setContentedFlag(ContentedAndRemarkableFlagEnum.CONTENTED.getInfo());
                }
                if (StringUtils.isBlank(patientQuestionOptionResult.getRemarkableFlag())) {
                    saveQuestionOption.setRemarkableFlag(ContentedAndRemarkableFlagEnum.ROUTINE.getInfo());
                }
                saveQuestionOption.setQuestionSubjectOptionId(patientQuestionOptionResult.getId());
                saveQuestionSubjectOptions.add(saveQuestionOption);
            }
            // 新增患者问卷题目选项提交结果
            if (patientQuestionOptionResultMapper.saveQuestionOptionList(saveQuestionSubjectOptions) <= 0) {
                throw new ServiceException("新增患者问卷题目选项提交结果失败");
            }
        }

        return AjaxResult.success();
    }

    /**
     * 短信发送记录
     *
     * @param dto  信息
     * @param time 时间
     * @param b    状态
     */
    @Override
    public void shortMessageSendRecordExtracted(PatientQuestionSubmitResultDTO dto, LocalDateTime time, Boolean b, String createBy) {
        ShortMessageSendRecord shortMessageSendRecord = new ShortMessageSendRecord();
        shortMessageSendRecord.setPatientId(dto.getPatientId());
        shortMessageSendRecord.setPatientPhone(dto.getPatientPhone());
        shortMessageSendRecord.setManageRouteNodeId(dto.getManageRouteNodeId());
        shortMessageSendRecord.setMessageTemplateId(dto.getPhoneMessageTemplateCode());
        shortMessageSendRecord.setMessageNodeContent(dto.getPhoneMessageTemplateContent());
        shortMessageSendRecord.setMessageType(ShortMessageTypeEnum.PHONE_MSG.getInfo());
        shortMessageSendRecord.setSendTime(time);
        if (!b) {
            shortMessageSendRecord.setErrorCode(1L);
            shortMessageSendRecord.setErrorStatus(ErrorStatusEnum.fail.getValue());
        } else {
            shortMessageSendRecord.setErrorCode(0L);
            shortMessageSendRecord.setErrorStatus(ErrorStatusEnum.success.getValue());
        }
        shortMessageSendRecord.setCreateBy(StringUtils.isBlank(createBy) ? SecurityUtils.getUsername() : createBy);
        shortMessageSendRecord.setCreateTime(time);
        shortMessageSendRecordMapper.insertShortMessageSendRecord(shortMessageSendRecord);
    }

    /**
     * 任务管理
     *
     * @param manualFollowUpDTO 人工随访查询DTO
     * @return ManualFollowUpVO 人工随访代办VO
     */
    @Override
    @DataScope(agencyAlias = "pi", deptAlias = "pi")
    public List<ManualFollowUpVO> taskManagement(ManualFollowUpDTO manualFollowUpDTO) {
        if (manualFollowUpDTO.getNodeExecuteStatus().equals(NodeExecuteStatusEnum.UNEXECUTED.getInfo())) {
            manualFollowUpDTO.setPhoneNodeExecuteResultStatus(null);
        }
        if (StringUtils.isNotBlank(manualFollowUpDTO.getPhoneDialMethod()) && manualFollowUpDTO.getPhoneDialMethod().equals(PhoneDialMethodEnum.ALL.getInfo())) {
            manualFollowUpDTO.setPhoneDialMethod(null);
        }
        //1、查询
        List<ManualFollowUpVO> manualFollowUpVOS = signPatientManageRouteMapper.selectManualFollowUpList(manualFollowUpDTO);
        if (CollectionUtils.isEmpty(manualFollowUpVOS) || manualFollowUpVOS.size() == 0) {
            return manualFollowUpVOS;
        }
        //字典名称匹配
        ArrayList<String> strings = new ArrayList<>();
        strings.add("task_node_type");
        strings.add("route_name");
        List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByTypeList(strings);
        for (ManualFollowUpVO manualFollowUpVO : manualFollowUpVOS) {
            SysDictData taskNodeType = sysDictDataList.stream().filter(Objects::nonNull).filter(item -> item.getDictValue().equals(manualFollowUpVO.getTaskNodeType())).findFirst().orElse(new SysDictData());
            if (StringUtils.isNotBlank(taskNodeType.getDictLabel())) {
                manualFollowUpVO.setTaskNodeTypeName(taskNodeType.getDictLabel());
            }
            SysDictData routeNodeName = sysDictDataList.stream().filter(Objects::nonNull).filter(item -> item.getDictValue().equals(manualFollowUpVO.getRouteNodeName())).findFirst().orElse(new SysDictData());
            if (StringUtils.isNotBlank(routeNodeName.getDictLabel())) {
                manualFollowUpVO.setRouteNode(routeNodeName.getDictLabel());
            }
        }
        //2、1如果是查询已执行的任务，直接返回查询结果a
        if (manualFollowUpDTO.getNodeExecuteStatus().equals(NodeExecuteStatusEnum.EXECUTED.getInfo())) {
            return manualFollowUpVOS;
        }
        //2.2如果是查询“所有”、"未执行“任务，则直接返回查询结果
        if (StringUtils.isNotBlank(manualFollowUpDTO.getTimeSign()) && manualFollowUpDTO.getTimeSign().equals("WHOLE")) {
            return manualFollowUpVOS;
        }
        //2.3如果是查询未执行（截止到当前时间）的任务，
        ArrayList<ManualFollowUpVO> manualFollowUps = new ArrayList<>();
        for (ManualFollowUpVO manualFollowUpVO : manualFollowUpVOS) {
            //3.1判断路径节点，组装数据
            //任务执行时间，
            LocalDate localDate = null;
            if (Objects.nonNull(manualFollowUpVO.getNodePlanTime()) && StringUtils.isNotBlank(manualFollowUpVO.getNodePlanTime().toString())) {
                localDate = manualFollowUpVO.getNodePlanTime().toLocalDate();
            } else {
                //3.2根据出院时间 和 第几天 计算
                if (Objects.nonNull(manualFollowUpVO.getDischargeTime())) {
                    localDate = manualFollowUpVO.getDischargeTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
                }
                //3.3根据就诊时间  和 第几天  计算
                if (Objects.isNull(manualFollowUpVO.getDischargeTime()) && Objects.nonNull(manualFollowUpVO.getVisitTime())) {
                    localDate = manualFollowUpVO.getVisitTime().plusDays(manualFollowUpVO.getRouteNodeDay()).toLocalDate();
                }
                //3.4如果为空，不予处理
                if (Objects.isNull(localDate)) {
                    continue;
                }
            }
            //3.5如果截止到当前时间，已到期，则放入返回集合
            boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
            if (before) {
                //转换成中文……
                if(StringUtils.isNotBlank(manualFollowUpVO.getRouteNodeName())){//1219应对任务管理添加管理
                    manualFollowUpVO.setRouteNodeName(RouteNodeNameEnum.getNameByInfo(manualFollowUpVO.getRouteNodeName()).getName());
                }
                manualFollowUpVO.setPlanTime(localDate);
                // 3.6  放入集合
                manualFollowUps.add(manualFollowUpVO);
            }
        }

        //返回今天之前任务
        return manualFollowUps;
    }

    /**
     * 批量删除未执行任务
     *
     * @param ids 任务id
     * @return AjaxResult
     */
    @Override
    public AjaxResult batchDeleteTask(Long[] ids) {
        if (ids.length == 0) {
            return AjaxResult.success();
        }
        int deleteNodeCount = signPatientManageRouteNodeMapper.deleteSignPatientManageRouteNodeByIds(ids);
        if (deleteNodeCount < 0) {
            return AjaxResult.error("删除失败，请联系管理员！");
        }
        List<Long> manageRouteIdByIds = signPatientManageRouteNodeMapper.selectManageRouteIdByIds(ids);
        //根据节点ids查询同路径的节点ids
        List<SignPatientManageRouteNode> signPatientManageRouteNodes = signPatientManageRouteNodeMapper.selectSameManageRouteNodeIdByNodeIds(ids);
        //无同级节点id
        List<Long> noSameLevelNodeIds = new ArrayList<>();
        //有同级节点，且同级节点状态不为0，不删除上级路径
        for (Long aLong : manageRouteIdByIds) {
            List<SignPatientManageRouteNode> collect = signPatientManageRouteNodes.stream().filter(Objects::nonNull).filter(item -> item.getManageRouteId().equals(aLong)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collect) || collect.size() == 0) {
                noSameLevelNodeIds.add(aLong);
            }
        }
        //都存在同级节点，返回，不删除其他数据
        if (CollectionUtils.isEmpty(noSameLevelNodeIds) || noSameLevelNodeIds.size() == 0) {
            return AjaxResult.success();
        }
        //无同级节点，查询上级路径 signPatientManageRoutes 上级路径ids
        List<SignPatientManageRoute> signPatientManageRoutes = signPatientManageRouteMapper.selectRouteByNodeIds(noSameLevelNodeIds);
        if (CollectionUtils.isEmpty(signPatientManageRoutes) || signPatientManageRoutes.size() == 0) {
            return AjaxResult.success();
        }
        //上级为主路径ids
        List<Long> manageRouteIds = new ArrayList<>();
        //上级为子路径ids
        List<Long> patientManageRouteIds = new ArrayList<>();
        //List<SignPatientManageRoute> patientManageRouteIds = new ArrayList<>();
        //上级为主路径，查询是否有子路径。上级为子路径继续查询同级信息
        for (SignPatientManageRoute signPatientManageRoute : signPatientManageRoutes) {
            if (Objects.nonNull(signPatientManageRoute.getParentRouteId()) && signPatientManageRoute.getParentRouteId() != 0) {
                patientManageRouteIds.add(signPatientManageRoute.getId());
            } else if (Objects.isNull(signPatientManageRoute.getParentRouteId()) || signPatientManageRoute.getParentRouteId() == 0) {
                manageRouteIds.add(signPatientManageRoute.getId());
            }
        }
        //上级为主路径，查询是否有子路径
        if (CollectionUtils.isNotEmpty(manageRouteIds)) {
            manageRouteIds = manageRouteIds.stream().distinct().collect(Collectors.toList());
            List<SignPatientManageRoute> parentRoutes = signPatientManageRouteMapper.selectRouteByParentRouteIds(manageRouteIds);
            //集合无子路径删除，有子路径筛选无子路径的路径delete
            if (CollectionUtils.isEmpty(parentRoutes) || parentRoutes.size() == 0) {
                int updateRouteCount = signPatientManageRouteMapper.deleteSignPatientManageRouteByIdList(manageRouteIds);
                if (updateRouteCount < 0) {
                    return AjaxResult.error("删除失败，请联系管理员！");
                }
            } else {
                //有子路径不删，无子路径删除 delete无子路径id集合
                List<Long> delete = new ArrayList<>();
                //筛选无子路径的路径delete
                for (Long manageRouteId : manageRouteIds) {
                    List<SignPatientManageRoute> equalsCollect = parentRoutes.stream().filter(Objects::nonNull).filter(item -> item.getParentRouteId().equals(manageRouteId)).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(equalsCollect) || equalsCollect.size() == 0) {
                        delete.add(manageRouteId);
                    }
                }
                if (CollectionUtils.isEmpty(delete) || delete.size() == 0) {
                    int updateRouteCount = signPatientManageRouteMapper.deleteSignPatientManageRouteByIdList(delete);
                    if (updateRouteCount < 0) {
                        return AjaxResult.error("删除失败，请联系管理员！");
                    }
                }
            }
        }
        //上级为子路径查询除自己以外的同级，无同级，查询上级是否有其他节点，有同级，过
        if (CollectionUtils.isNotEmpty(patientManageRouteIds)) {
            int updateRouteCount = signPatientManageRouteMapper.deleteSignPatientManageRouteByIdList(patientManageRouteIds);
            if (updateRouteCount < 0) {
                return AjaxResult.error("删除失败，请联系管理员！");
            }
            //子路径无同级mainRouteIds
            List<Long> mainRouteIds = new ArrayList<>();
            //查询上级为子路径的除自己以外的同级
            List<SignPatientManageRoute> patientSignPatientManageRoutes = signPatientManageRouteMapper.selectParentRouteIds(patientManageRouteIds);
            if (CollectionUtils.isNotEmpty(patientSignPatientManageRoutes) || patientSignPatientManageRoutes.size() != 0) {
                for (Long patientManageRouteId : patientManageRouteIds) {
                    List<SignPatientManageRoute> collect = patientSignPatientManageRoutes.stream().filter(Objects::nonNull).filter(item -> item.getParentRouteId().equals(patientManageRouteId)).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(collect) || collect.size() == 0) {
                        mainRouteIds.add(patientManageRouteId);
                    }
                }
                //无同级，查询上级
                List<Long> list = signPatientManageRouteMapper.selectParentRouteIdByRouteId(mainRouteIds);
                if (CollectionUtils.isNotEmpty(list) || list.size() == 0) {
                    list = list.stream().distinct().collect(Collectors.toList());
                    //查询上级是否有其他节点
                    List<SignPatientManageRouteNode> mainSignPatientManageRouteNodes = signPatientManageRouteNodeMapper.selectSameManageRouteNodeIdByRouteIds(list);
                    if (CollectionUtils.isEmpty(mainSignPatientManageRouteNodes) || mainSignPatientManageRouteNodes.size() == 0) {
                        int updateMainRouteCount = signPatientManageRouteMapper.updateSignPatientManageRouteByIds(list);
                        if (updateMainRouteCount < 0) {
                            return AjaxResult.error("删除失败，请联系管理员！");
                        }
                    } else {
                        //无其他节点删除
                        List<Long> delete = new ArrayList<>();
                        for (Long mainRouteId : list) {
                            List<SignPatientManageRouteNode> collect = mainSignPatientManageRouteNodes.stream().filter(Objects::nonNull).filter(item -> item.getManageRouteId().equals(mainRouteId)).collect(Collectors.toList());
                            if (CollectionUtils.isEmpty(collect) || collect.size() == 0) {
                                delete.add(mainRouteId);
                            }
                        }
                        if (CollectionUtils.isEmpty(delete) || delete.size() == 0) {
                            int count = signPatientManageRouteMapper.deleteSignPatientManageRouteByIdList(delete);
                            if (count < 0) {
                                return AjaxResult.error("删除失败，请联系管理员！");
                            }
                        }
                    }
                }
            }
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult outboundConfirmation() {
        SignPatientManageRouteNode signPatientManageRouteNode = new SignPatientManageRouteNode();
        signPatientManageRouteNode.setCreateBy(SecurityUtils.getUsername());
        SignPatientManageRouteNode databaseNode = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNode(signPatientManageRouteNode);
        if (Objects.isNull(databaseNode)){
            return AjaxResult.success(null,null);
        }
        return AjaxResult.success(databaseNode);
    }

    /**
     * 直接外呼
     *
     * @return AjaxResult
     */
    @Override
    public AjaxResult directOutbound(SignPatientManageRouteNode introducedNode) {
        //如果是批量 创建
        SignPatientManageRouteNodeDto signPatientManageRouteNode = new SignPatientManageRouteNodeDto();
        signPatientManageRouteNode.setNodePlanTime(LocalDateTime.now());
        List<SignPatientManageRouteNode> signPatientManageRouteNodes = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNode);
        if (CollectionUtils.isNotEmpty(signPatientManageRouteNodes) && signPatientManageRouteNodes.size() >= 100) {
            return AjaxResult.error("今日创建任务已达上线，请改日创建任务！");
        }
        //获取患者信息
        List<PatientInfoVo> listPatient = new ArrayList<>();
        PatientInfoDto patientInfo = new PatientInfoDto();
        patientInfo.setSn(introducedNode.getSn());
        listPatient = patientInfoMapper.getPatientList(patientInfo);
        if (CollectionUtils.isNotEmpty(listPatient) && listPatient.size() > 100) {
            return AjaxResult.error("创建任务数量超出当日上限，请减少创建任务数量！");
        }
        if (CollectionUtils.isNotEmpty(listPatient) && CollectionUtils.isNotEmpty(signPatientManageRouteNodes) && (listPatient.size() + signPatientManageRouteNodes.size()) > 100) {
            return AjaxResult.error("创建任务数量超出当日上限，请减少创建任务数量！");
        }
        List<SignPatientManageRoute> signPatientManageRoutes = new ArrayList<>();
        ArrayList<SignPatientManageRouteNode> saveNodes = new ArrayList<>();
        for (PatientInfoVo patientInfoVo : listPatient) {
            SignPatientManageRoute signPatientManageRoute = new SignPatientManageRoute();
            signPatientManageRoute.setPatientId(patientInfoVo.getId());
            signPatientManageRoute.setPatientName(patientInfoVo.getPatientName());
            signPatientManageRoute.setDepartmentId(patientInfoVo.getDepartmentId());
            signPatientManageRoute.setDepartmentName(patientInfoVo.getDepartmentName());
            signPatientManageRoute.setRouteName(introducedNode.getManageRouteName());
            signPatientManageRoute.setTaskCreateType(TaskCreateTypeEnum.MANUAL_CREATE.getInfo());
            signPatientManageRoute.setSuitRange(SuitRangeEnum.OUTPATIENT_SERVICE_DISCHARGE.getInfo());
            signPatientManageRoute.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
            signPatientManageRoute.setCreateBy(SecurityUtils.getUsername());
            signPatientManageRoute.setCreateTime(LocalDateTime.now());
            signPatientManageRoutes.add(signPatientManageRoute);
        }
        if (CollectionUtils.isNotEmpty(signPatientManageRoutes)) {
            int i = signPatientManageRouteMapper.insertBatch(signPatientManageRoutes);
            if (i < 0) {
                return AjaxResult.error("创建任务失败，请联系管理员！");
            }
            for (SignPatientManageRoute signPatientManageRoute : signPatientManageRoutes) {
                SignPatientManageRouteNode saveNode = new SignPatientManageRouteNode();
                saveNode.setManageRouteId(signPatientManageRoute.getId());
                saveNode.setManageRouteName(signPatientManageRoute.getRouteName());
                saveNode.setSn(introducedNode.getSn());
                saveNode.setDialStatus(DialStatusEnum.NODIALED.getInfo());
                saveNode.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
                saveNode.setNodePlanTime(LocalDateTime.now());
                saveNode.setTaskNodeType(introducedNode.getTaskNodeType());
                saveNode.setPhonePushSign(introducedNode.getPhonePushSign());
                saveNode.setScriptInfoId(introducedNode.getScriptInfoId());
                saveNode.setRobotPublishId(introducedNode.getRobotPublishId());
                saveNode.setPhoneDialMethod(introducedNode.getPhoneDialMethod());
                saveNode.setPhoneRedialTimes(introducedNode.getPhoneRedialTimes());
                saveNode.setPhoneTimeInterval(introducedNode.getPhoneTimeInterval());
                saveNode.setQuestionInfoId(introducedNode.getQuestionInfoId());
                saveNode.setQuestionnaireName(introducedNode.getQuestionnaireName());
                saveNode.setMessagePushSign(Objects.isNull(introducedNode.getMessagePushSign()) ? 0 : introducedNode.getMessagePushSign());
                saveNode.setOfficialPushSign(Objects.isNull(introducedNode.getOfficialPushSign()) ? 0 : introducedNode.getOfficialPushSign());
                saveNode.setAppletPushSign(Objects.isNull(introducedNode.getAppletPushSign()) ? 0 : introducedNode.getAppletPushSign());
                saveNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
                saveNode.setRouteCheckDate(LocalDateTime.now());
                saveNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
                saveNode.setCreateBy(SecurityUtils.getUsername());
                saveNode.setCreateTime(LocalDateTime.now());
                saveNodes.add(saveNode);
            }
            int i1 = signPatientManageRouteNodeMapper.insertBatch(saveNodes);
            if (i1 < 0) {
                return AjaxResult.error("创建任务失败，请联系管理员！");
            }
            List<Long> patientIds = listPatient.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getId())).map(PatientInfoVo::getId).collect(Collectors.toList());
            List<LabelFieldContent> labelFieldContents = labelFieldContentService.selectLabelFieldContentByPatientIds(patientIds);
            List<Long> manualCreateTaskPatientIds = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(labelFieldContents)) {
                for (Long patientId : patientIds) {
                    LabelFieldContent labelFieldContent = labelFieldContents.stream().filter(Objects::nonNull).filter(item -> patientId.equals(item.getPatientId())).findFirst().orElse(new LabelFieldContent());
                    if (Objects.isNull(labelFieldContent.getPatientId())) {
                        manualCreateTaskPatientIds.add(patientId);
                    }
                }
            } else {
                manualCreateTaskPatientIds.addAll(patientIds);
            }
            if (CollectionUtils.isNotEmpty(manualCreateTaskPatientIds)) {
                for (Long manualCreateTaskPatientId : manualCreateTaskPatientIds) {
                    List<LabelFieldAndPartitionDict> labelFieldAndPartitionDictList = labelFieldContentService.groupingValue(0L, manualCreateTaskPatientId);
                    // 画像信息保存
                    LabelField labelField = new LabelField();
                    labelField.setLabelFieldAndPartitionDictList(labelFieldAndPartitionDictList);
                    labelFieldContentService.insertLabelField(labelField);
                    // 替换手动生成的任务中的标签
                    signPatientManageRouteNodeService.manualCreateTaskLabelReplaceByPatientId(manualCreateTaskPatientId);
                }
            }
        }
        return AjaxResult.success();
    }


    /**
     * 电话记录
     *
     * @param dto  信息
     * @param time 时间
     */
    private void phoneDialRecordExtracted(PatientQuestionSubmitResultDTO dto, LocalDateTime time) {
        //电话记录
        PhoneDialRecord phoneDialRecord = new PhoneDialRecord();
        phoneDialRecord.setPatientId(dto.getPatientId());
        phoneDialRecord.setManageRouteNodeId(dto.getManageRouteNodeId());
        phoneDialRecord.setPatientPhone(dto.getPatientPhone());
        phoneDialRecord.setDialTime(time);
        phoneDialRecord.setPhoneTemplateName(dto.getPhoneTemplateName());
        phoneDialRecord.setPhoneTemplateId(dto.getPhoneTemplateId());
        phoneDialRecord.setMessageNodeContent(dto.getPhoneNodeContent());
        phoneDialRecord.setPhoneDialMethod(StringUtils.isBlank(dto.getPhoneDialMethod()) ? "" : dto.getPhoneDialMethod());
        if (dto.getPhoneConnectStatus().equals(PhoneConnectStatusEnum.NOTCONNECTED.getInfo())) {
            phoneDialRecord.setErrorCode(1L);
            phoneDialRecord.setErrorStatus(ErrorStatusEnum.fail.getValue());
        } else {
            phoneDialRecord.setErrorCode(0L);
            phoneDialRecord.setErrorStatus(ErrorStatusEnum.success.getValue());
        }
        phoneDialRecord.setCreateBy(SecurityUtils.getUsername());
        phoneDialRecord.setCreateTime(time);
        phoneDialRecordMapper.insertPhoneDialRecord(phoneDialRecord);
    }

    /**
     * 话术类型代办处理详情
     */
    @Override
    public AjaxResult selectPhonePush(Long manageRouteNodeId) {
        PhonePush phonePush = signPatientManageRouteMapper.selectSignPatientManageRouteNode(manageRouteNodeId);
        PhoneDialRecord phoneDialRecord = new PhoneDialRecord();
        phoneDialRecord.setManageRouteNodeId(manageRouteNodeId);
        List<PhoneDialRecord> phoneDialRecords = phoneDialRecordMapper.selectPhoneDialRecordList(phoneDialRecord);
        //时间排序、有拨打记录
        if (CollectionUtils.isNotEmpty(phoneDialRecords) && phoneDialRecords.size() > 0) {
            phoneDialRecords.sort((t1, t2) -> t2.getDialTime().compareTo(t1.getDialTime()));
            phonePush.setFirstTime(phoneDialRecords.get(0).getDialTime());
            //两条拨打记录
            if (phoneDialRecords.size() > 1) {
                phonePush.setFirstTime(phoneDialRecords.get(1).getDialTime());
            }
            //三条拨打记录
            if (phoneDialRecords.size() > 2) {
                phonePush.setFirstTime(phoneDialRecords.get(2).getDialTime());
            }
        }
        return AjaxResult.success(phonePush);
    }

    /**
     * 路径审核->路径信息获取主路径及子路径信息及节点
     *
     * @param signRecordId 签约记录主键
     * @return 主路径信息及节点、子路径信息及节点
     */
    @Override
    public SpecialDiseaseRouteAuditVo getRouteAuditInfo(Long signRecordId) {
        SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signRecordId);
        if (ObjectUtils.isEmpty(signPatientRecord)) {
            throw new ServiceException("未找到该患者签约信息");
        }
        SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
        manageRouteQuery.setSignPatientRecordId(signRecordId);
        manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
        List<SignPatientManageRoute> manageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
        if (CollectionUtils.isEmpty(manageRouteList)) {
            throw new ServiceException("未找到签约管理路径");
        }
        SignPatientManageRoute signPatientManageRoute = manageRouteList.get(0);
        SpecialDiseaseRouteAuditVo specialDiseaseRouteAuditVo = specialDiseaseRouteService.getRouteAuditInfo(signPatientManageRoute.getRouteId());
        if (ObjectUtils.isEmpty(specialDiseaseRouteAuditVo)) {
            throw new ServiceException("未找到该专病管理路径请联系管理员");
        }
        // 计算子路径的节点执行时间
        PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
        if (ObjectUtils.isEmpty(patientVisitRecord)) {
            throw new ServiceException("未找到患者就诊记录");
        }
        // 计算主路径节点执行时间
        specialDiseaseRouteAuditVo.getNodeList().forEach(node -> {
            node.setRouteNodeNameCN(RouteNodeNameEnum.getNameByInfo(node.getRouteNodeName()).getName());
            node.setExecuteTime(iSignPatientManageRouteNodeService.getExecuteTime(node.getExecutionTime(), node.getRouteNodeName(), node.getRouteNodeDay(), patientVisitRecord));
        });
        // 计算子路径节点执行时间
        specialDiseaseRouteAuditVo.getChildRouteList()
                .forEach(childRoute -> {
                    // 判断触发条件是否满足
                    boolean satisfy = signPatientManageRouteNodeService.getTriggerConditon(childRoute.getId(), signPatientRecord.getPatientId());
                    childRoute.setConditionSatisfyStatus(satisfy);
                    childRoute.getNodeList()
                            .forEach(childNode -> childNode.setExecuteTime(
                                    iSignPatientManageRouteNodeService.getExecuteTime(childNode.getExecutionTime(), childNode.getRouteNodeName(), childNode.getRouteNodeDay(), patientVisitRecord)));
                });
        // 查询手动创建的路径
        manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_CREATE);
        List<SignPatientManageRoute> manualRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
        if (CollectionUtils.isNotEmpty(manualRouteList)) {
            // 查询节点信息组装成返回的数据类型
            manualRouteList.forEach(route -> {
                //boolean satisfy = signPatientManageRouteNodeService.getSignTriggerConditon(route.getId(), signPatientRecord.getPatientId());
                // 查询节点
                List<SpecialDiseaseNodeAuditVo> nodeList = signPatientManageRouteNodeMapper.selectByRouteId(route.getId());
                nodeList.forEach(node -> {
                    node.setRouteNodeNameCN(RouteNodeNameEnum.getNameByInfo(node.getRouteNodeName()).getName());
                    node.setExecuteTime(iSignPatientManageRouteNodeService.getExecuteTime(node.getExecutionTime(), node.getRouteNodeName(), node.getRouteNodeDay(), patientVisitRecord));
                });
                specialDiseaseRouteAuditVo.getChildRouteList().add(
                        SpecialDiseaseChildRouteAuditVo.builder()
                                .diseaseTypeName(route.getDiseaseTypeName())
                                .routeName(route.getRouteName())
                                .diseaseTypeId(route.getDiseaseTypeId())
                                .conditionSatisfyStatus(true)
                                .nodeList(nodeList).build()
                );
            });
        }

        specialDiseaseRouteAuditVo.setRouteCheckStatus(signPatientRecord.getRouteCheckStatus());
        return specialDiseaseRouteAuditVo;
    }

    @Override
    public List<SignPatientManageNodeAuditVo> getRouteNodeInfo(Long signRecordId) {
        List<SignPatientManageNodeAuditVo> manageNodeAuditList = new ArrayList<>();
        // 查询专病路径节点和手动创建的任务节点
        SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signRecordId);
        if (ObjectUtils.isEmpty(signPatientRecord)) {
            throw new ServiceException("未找到该患者签约信息");
        }
        SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
        manageRouteQuery.setSignPatientRecordId(signRecordId);
        manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
        List<SignPatientManageRoute> manageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
        if (CollectionUtils.isEmpty(manageRouteList)) {
            throw new ServiceException("未找到签约管理路径");
        }
        SignPatientManageRoute signPatientManageRoute = manageRouteList.get(0);
        // 查询主路径及子路径节点
        List<RouteTaskAuditVo> nodeList = specialDiseaseNodeService.getByParentRouteId(signPatientManageRoute.getRouteId());

        // 查询子路径的触发条件是否满足
        Map<Long, List<RouteTaskAuditVo>> groupByRouteId = nodeList.stream().collect(Collectors.groupingBy(RouteTaskAuditVo::getRouteId));
        Map<Long, Boolean> routeSatisfyMap = new HashMap<>();
        for (Long routeId : groupByRouteId.keySet()) {
            if (Objects.equals(routeId, signPatientManageRoute.getRouteId())) {
                // 主路径不做处理
                routeSatisfyMap.put(routeId, true);
            } else {
                boolean satisfy = signPatientManageRouteNodeService.getTriggerConditon(routeId, signPatientRecord.getPatientId());
                routeSatisfyMap.put(routeId, satisfy);
            }
        }

        // 查询患者画像信息
        List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(signPatientRecord.getPatientId());
        if (CollectionUtils.isEmpty(labelFieldContentList)) {
            throw new ServiceException("请先维护画像信息");
        }
        // 组装数据
        nodeList.forEach(node -> {
            SignPatientManageNodeAuditVo manageRouteNode = new SignPatientManageNodeAuditVo();
            BeanUtils.copyBeanProp(manageRouteNode, node);
            manageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
            manageRouteNode.setId(null);
            manageRouteNode.setRouteNodeId(node.getId());
            manageRouteNode.setExecuteTime(node.getExecutionTime());
            manageRouteNode.setRouteNodeNameCN(RouteNodeNameEnum.getNameByInfo(node.getRouteNodeName()).getName());
            manageRouteNode.setConditionSatisfyStatus(routeSatisfyMap.getOrDefault(node.getRouteId(), null));

            JSONObject templateDetail = new JSONObject();
            // 根据模板类型，存放模板字段
            if (StringUtils.isNotBlank(node.getTaskNodeType())) {
                switch (node.getTaskNodeType()) {
                    // 宣教
                    case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
                        manageRouteNode.setPropagandaInfoId(node.getTemplateId());
                        manageRouteNode.setPropagandaTitle(node.getTemplateName());
                        // 查询宣教表
                        if (manageRouteNode.getPropagandaInfoId() != null) {
                            PropagandaMaterialsVo propagandaMaterialsVo = propagandaInfoService.selectPropagandaInfoById(node.getTemplateId());
                            if (ObjectUtils.isNotEmpty(propagandaMaterialsVo)) {
                                templateDetail = JSONObject.parseObject(JSONObject.toJSONString(propagandaMaterialsVo));
                                manageRouteNode.setTemplateDetail(templateDetail);
                            }
                        }
                        manageRouteNode.setTemplateType(TemplateTypeConstants.PROPAGANDA);
                        break;
                    // 问卷
                    case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
                        manageRouteNode.setQuestionInfoId(node.getTemplateId());
                        manageRouteNode.setQuestionnaireName(node.getTemplateName());
                        // 查询问卷详情
                        QuestionVO questionVO = questionInfoService.selectQuestionInfoById(node.getTemplateId());
                        if (ObjectUtils.isNotEmpty(questionVO)) {
                            templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
                            manageRouteNode.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
                            manageRouteNode.setTemplateDetail(templateDetail);
                        }
                        break;
                    // 话术
                    case TaskNodeTypeConstants.PHONE_OUTBOUND:
                        manageRouteNode.setScriptInfoId(node.getScriptInfoId());
                        // 查询话术
                        ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
                        if (ObjectUtils.isNotEmpty(scriptInfo)) {
                            // 话术库json内容替换
                            manageRouteNode.setPhoneNodeContent(signPatientManageRouteNodeService.getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
                            templateDetail = JSONObject.parseObject(JSONObject.toJSONString(scriptInfo));
                            manageRouteNode.setTemplateType(TemplateTypeConstants.SCRIPT);
                            manageRouteNode.setTemplateDetail(templateDetail);

                            if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
                                throw new ServiceException("第三方机器人id为空");
                            }
                        }
                        // 电话短信内容
                        if (node.getPhoneMessageTemplateId() != null) {
                            // 查询短信库
                            manageRouteNode.setPhoneMessageTemplateContent(signPatientManageRouteNodeService.replaceMessageInfo(node.getPhoneMessageTemplateId(), labelFieldContentList));
                        }
                        break;
                }
            }
            // 替换短信、公众号、小程序内容
            replaceTemplateInfo(manageRouteNode, node, labelFieldContentList);
            // 替换nodeContent
            List<SignPatientManageNodeAuditVo> manageNodeList = new ArrayList<>();
            if (StringUtils.contains(node.getNodeContent(), "data-w-e-type")) {
                manageNodeList = signPatientManageRouteNodeService.replaceNodeContent(manageRouteNode, node.getTaskPartitionDictId(), labelFieldContentList);
            } else {
                manageNodeList.add(manageRouteNode);
            }
            manageNodeAuditList.addAll(manageNodeList);
        });
        // 查询手动创建的节点
        manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_CREATE);
        List<SignPatientManageRoute> createRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
        if (CollectionUtils.isNotEmpty(createRouteList)) {
            List<Long> manageRouteIds = createRouteList.stream().map(SignPatientManageRoute::getId).collect(Collectors.toList());
            List<SignPatientManageNodeAuditVo> manageNodeList = signPatientManageRouteNodeMapper.selectAuditNodeInfo(manageRouteIds);
            // 根据node去替换模板信息
            manageNodeList.forEach(manageNode -> {
                // 判断触发条件是否满足
                manageNode.setConditionSatisfyStatus(true);
                manageNode.setRouteNodeNameCN(RouteNodeNameEnum.getNameByInfo(manageNode.getRouteNodeName()).getName());
                JSONObject templateDetail = new JSONObject();
                if (StringUtils.isNotBlank(manageNode.getTaskNodeType())) {
                    switch (manageNode.getTaskNodeType()) {
                        // 电话外呼
                        case TaskNodeTypeConstants.PHONE_OUTBOUND:
                            // 电话外呼分为话术和问卷两种，根据模板id判断选择的哪种模板
                            if (manageNode.getScriptInfoId() != null) { // 话术
                                ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(manageNode.getScriptInfoId());
                                if (ObjectUtils.isNotEmpty(scriptInfo)) {
                                    // 话术库json内容替换
                                    manageNode.setPhoneNodeContent(signPatientManageRouteNodeService.getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
                                    templateDetail = JSONObject.parseObject(JSONObject.toJSONString(scriptInfo));
                                    manageNode.setTemplateType(TemplateTypeConstants.SCRIPT);
                                    manageNode.setTemplateDetail(templateDetail);

                                    if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
                                        throw new ServiceException("第三方机器人id为空");
                                    }
                                }
                            } else if (manageNode.getQuestionInfoId() != null) { // 问卷
                                // 查询问卷详情
                                QuestionVO questionVO = questionInfoService.selectQuestionInfoById(manageNode.getQuestionInfoId());
                                if (ObjectUtils.isNotEmpty(questionVO)) {
                                    templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
                                    manageNode.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
                                    manageNode.setTemplateDetail(templateDetail);
                                }
                            }
                            // 电话短信内容
                            if (manageNode.getPhoneMessageTemplateId() != null) {
                                // 查询短信库
                                manageNode.setPhoneMessageTemplateContent(signPatientManageRouteNodeService.replaceMessageInfo(manageNode.getPhoneMessageTemplateId(), labelFieldContentList));
                            }
                            break;
                        // 问卷
                        case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
                            // 查询问卷详情
                            if (manageNode.getQuestionInfoId() != null) {
                                QuestionVO questionVO = questionInfoService.selectQuestionInfoById(manageNode.getQuestionInfoId());
                                if (ObjectUtils.isNotEmpty(questionVO)) {
                                    templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
                                    manageNode.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
                                    manageNode.setTemplateDetail(templateDetail);
                                }
                            }
                            break;
                        // 宣教
                        case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
                            // 查询宣教详情
                            if (manageNode.getPropagandaInfoId() != null) {
                                PropagandaMaterialsVo propagandaMaterialsVo = propagandaInfoService.selectPropagandaInfoById(manageNode.getPropagandaInfoId());
                                if (ObjectUtils.isNotEmpty(propagandaMaterialsVo)) {
                                    templateDetail = JSONObject.parseObject(JSONObject.toJSONString(propagandaMaterialsVo));
                                    manageNode.setTemplateType(TemplateTypeConstants.PROPAGANDA);
                                    manageNode.setTemplateDetail(templateDetail);
                                }
                            }
                            break;
                        // 文字提醒
                        case TaskNodeTypeConstants.TEXT_REMIND:
                            manageNode.setTemplateType(TaskContentConstants.TEXT_REMIND);
                            break;
                        // 人工随访
                        //case TaskContentConstants.ARTIFICIAL_FOLLOW_UP:
                        //	// 查询问卷详情
                        //	if (manageNode.getFollowTemplateId() != null) {
                        //		QuestionVO questionVO1 = questionInfoService.selectQuestionInfoById(manageNode.getFollowTemplateId());
                        //		if (ObjectUtils.isNotEmpty(questionVO1)) {
                        //			templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO1));
                        //			manageNode.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
                        //			manageNode.setTemplateDetail(templateDetail);
                        //		}
                        //	}
                        //	break;
                    }
                }
                // 替换短信、公众号、小程序内容
                if (manageNode.getMessageTemplateId() != null) {
                    // 替换短信模板
                    manageNode.setMessageNodeContent(signPatientManageRouteNodeService.replaceMessageInfo(manageNode.getMessageTemplateId(), labelFieldContentList));
                }
                if (manageNode.getPhoneMessageTemplateId() != null) {
                    // 替换短信模板
                    manageNode.setPhoneMessageTemplateContent(signPatientManageRouteNodeService.replaceMessageInfo(manageNode.getPhoneMessageTemplateId(), labelFieldContentList));
                }
                // 替换公众号模板
                if (manageNode.getOfficialPushSign() != null && manageNode.getOfficialPushSign() == 1) {
                    manageNode.setOfficialNodeContent(signPatientManageRouteNodeService.replaceWeChatTemplate(manageNode.getOfficialTemplateId(), labelFieldContentList));
                }
                // 替换小程序模板
                if (manageNode.getAppletPushSign() != null && manageNode.getAppletPushSign() == 1) {
                    manageNode.setAppletNodeContent(signPatientManageRouteNodeService.replaceWeChatTemplate(manageNode.getAppletTemplateId(), labelFieldContentList));
                }
                manageNodeAuditList.add(manageNode);
            });
        }

        return manageNodeAuditList;
    }

    /**
     * @return 签约记录列表
     * @description 患者详情--康复计划及记录，右上角签约记录下拉框
     * @Param patientId 患者主键
     * @Author haown
     * @Date 2024-08-01 14:48
     */
    @Override
    public List<SignPatientRecordSelectVo> getRecordList(Long patientId) {
        List<SignPatientRecordSelectVo> retList = new ArrayList<>();
        // 查询签约记录
        List<SignPatientRecordVo> signRecordList = signPatientRecordMapper.getByPatient(patientId);
        signRecordList.forEach(signRecord -> {
            SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
            manageRouteQuery.setSignPatientRecordId(signRecord.getId());
            manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
            List<SignPatientManageRoute> manageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
            if (CollectionUtils.isNotEmpty(manageRouteList)) {
                retList.add(SignPatientRecordSelectVo.builder()
                        .id(signRecord.getId())
                        .signRouteName(signRecord.getSignTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "|" + manageRouteList.get(0).getRouteName())
                        .build());
            }
        });
        return retList;
    }

    /**
     * 新增患者管理任务执行记录
     */
    private Long insertPatientTaskExecuteRecord(PatientQuestionSubmitResultDTO dto, String routeHandlePerson, LocalDateTime time) {
        PatientTaskExecuteRecord patientTaskExecuteRecord = new PatientTaskExecuteRecord();
        BeanUtils.copyProperties(dto, patientTaskExecuteRecord);
        patientTaskExecuteRecord.setTaskNodeType(dto.getTaskNodeType());
        patientTaskExecuteRecord.setExecuteTime(time);
        patientTaskExecuteRecord.setExecutePerson(routeHandlePerson);
        patientTaskExecuteRecord.setExecuteType(TaskCreateTypeConstant.MANUAL_CREATE);
        patientTaskExecuteRecord.setCreateBy(routeHandlePerson);
        patientTaskExecuteRecord.setCreateTime(time);
        if (patientTaskExecuteRecordMapper.insertPatientTaskExecuteRecord(patientTaskExecuteRecord) > 0) {
            // 任务统计表修改
            patientTaskStatisticsService.updateNum(dto.getPatientId(), TaskStatisticsTypeConstants.TASK_EXECUTE_NUM, 1);
            return patientTaskExecuteRecord.getId();
        } else {
            throw new ServiceException("新增患者管理任务记录失败");
        }
    }

    /**
     * 更新节点任务表
     */
    private void updateSignPatientManageRouteNode(PatientQuestionSubmitResultDTO dto, String routeHandlePerson, LocalDateTime time) {
        SignPatientManageRouteNode signPatientManageRouteNode = new SignPatientManageRouteNode();
        signPatientManageRouteNode.setId(dto.getManageRouteNodeId());
        //已接通
        if (StringUtils.isNotBlank(dto.getPhoneConnectStatus()) && PhoneConnectStatusEnum.CONNECTED.getInfo().equals(dto.getPhoneConnectStatus())) {
            signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.SUCCESS.getInfo());
        }
        //未接通
        if (StringUtils.isNotBlank(dto.getPhoneConnectStatus()) && PhoneConnectStatusEnum.NOTCONNECTED.getInfo().equals(dto.getPhoneConnectStatus())) {
            //不重播
            if (dto.getPhoneRedialTimes().equals(PhoneRedialTimesEnum.NOT_REPLAY.getInfo())) {
                signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.FAILURE.getInfo());
            }
            //重播
            if (!dto.getPhoneRedialTimes().equals(PhoneRedialTimesEnum.NOT_REPLAY.getInfo())) {
                PhoneDialRecord phoneDialRecord = new PhoneDialRecord();
                phoneDialRecord.setManageRouteNodeId(dto.getManageRouteNodeId());
                List<PhoneDialRecord> phoneDialRecords = phoneDialRecordMapper.selectPhoneDialRecordList(phoneDialRecord);
                //一次
                if (dto.getPhoneRedialTimes().equals(PhoneRedialTimesEnum.REDIAL_ONCE.getInfo()) && CollectionUtils.isNotEmpty(phoneDialRecords) && phoneDialRecords.size() > 0) {
                    signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.FAILURE.getInfo());
                }
                //两次
                if (dto.getPhoneRedialTimes().equals(PhoneRedialTimesEnum.REDIAL_ONCE.getInfo()) && CollectionUtils.isNotEmpty(phoneDialRecords) && phoneDialRecords.size() > 1) {
                    signPatientManageRouteNode.setPhoneNodeExecuteResultStatus(NodeExecuteResultStatusEnum.FAILURE.getInfo());
                }
            }
        }
        //执行状态，电话拨通情况不是空或题目信息不是空
        if (StringUtils.isNotBlank(signPatientManageRouteNode.getPhoneNodeExecuteResultStatus()) || CollectionUtils.isNotEmpty(dto.getSubjectResultDTOList())) {
            signPatientManageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.EXECUTED.getInfo());
        }
        if (dto.getTaskNodeType().equals(TaskContentEnum.PHONE_OUTBOUND.getInfo())) {
            signPatientManageRouteNode.setPhoneConnectStatus(dto.getPhoneConnectStatus());
        }
        if (dto.getTaskNodeType().equals(TaskContentEnum.QUESTIONNAIRE_SCALE.getInfo())) {
            signPatientManageRouteNode.setNodeFinishDate(time);
            signPatientManageRouteNode.setNodeFinishStatus(NodeExecuteResultStatusEnum.SUCCESS.getInfo());
        }
        signPatientManageRouteNode.setRouteHandleRemark(dto.getRouteHandleRemark());
        signPatientManageRouteNode.setRouteHandleId(dto.getRouteHandleId());
        signPatientManageRouteNode.setRouteHandlePerson(routeHandlePerson);
        signPatientManageRouteNode.setUpdateBy(routeHandlePerson);
        signPatientManageRouteNode.setUpdateTime(time);
        // 更新节点任务表
        if (signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signPatientManageRouteNode) <= 0) {
            throw new ServiceException("更新节点任务表失败");
        } else {
            if (dto.getTaskNodeType().equals(TaskContentEnum.QUESTIONNAIRE_SCALE.getInfo())) {
                // 修改任务统计表任务完成数量
                patientTaskStatisticsService.updateNum(dto.getPatientId(), TaskStatisticsTypeConstants.TASK_FINISH_NUM, 1);
            }
        }
    }

    /**
     * 塞值
     */
    private void extracted(SignPatientManageRouteVO signPatientManageRoute, List<SignPatientManageRouteNode> signPatientManageRouteNodes, SignPatientManageRouteNode routeNode) {
        SignPatientManageRouteNode signPatientManageRouteNode = new SignPatientManageRouteNode();
        //如果 导入患者主表id不为空，则认为此任务是批量执行类型
        if (StringUtils.isNotBlank(signPatientManageRoute.getSn())) {
            signPatientManageRouteNode.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
            signPatientManageRouteNode.setSn(signPatientManageRoute.getSn());
        } else
            signPatientManageRouteNode.setTaskExcuteType(TaskExcuteTypeEnum.ACTUAL_TIME_TASK.getInfo());
            signPatientManageRouteNode.setNodePlanTime(routeNode.getNodePlanTime());

        //电话外呼
        if (Objects.nonNull(routeNode) && TaskNodeTypeEnum.PHONE_OUTBOUND.getInfo().equals(routeNode.getTaskNodeType())) {
            signPatientManageRouteNode.setPhonePushSign(Objects.isNull(routeNode.getPhonePushSign()) ? null : routeNode.getPhonePushSign());
            signPatientManageRouteNode.setScriptInfoId(Objects.isNull(routeNode.getScriptInfoId()) ? null : routeNode.getScriptInfoId());
            signPatientManageRouteNode.setPhoneTemplateId(Objects.isNull(routeNode.getPhoneTemplateId()) ? null : routeNode.getPhoneTemplateId());
            signPatientManageRouteNode.setPhoneTemplateName(StringUtils.isBlank(routeNode.getPhoneTemplateName()) ? null : routeNode.getPhoneTemplateName());
            signPatientManageRouteNode.setPhoneNodeContent(StringUtils.isBlank(routeNode.getPhoneNodeContent()) ? null : routeNode.getPhoneNodeContent());
            signPatientManageRouteNode.setPhoneRedialTimes(StringUtils.isBlank(routeNode.getPhoneRedialTimes()) ? null : routeNode.getPhoneRedialTimes());
            signPatientManageRouteNode.setPhoneTimeInterval(Objects.isNull(routeNode.getPhoneTimeInterval()) ? null : routeNode.getPhoneTimeInterval());
            signPatientManageRouteNode.setPhoneMessageRemind(StringUtils.isBlank(routeNode.getPhoneMessageRemind()) ? null : routeNode.getPhoneMessageRemind());
            signPatientManageRouteNode.setPhoneMessageTemplateId(Objects.isNull(routeNode.getPhoneMessageTemplateId()) ? null : routeNode.getPhoneMessageTemplateId());
            signPatientManageRouteNode.setPhoneMessageTemplateName(StringUtils.isBlank(routeNode.getPhoneMessageTemplateName()) ? null : routeNode.getPhoneMessageTemplateName());
            signPatientManageRouteNode.setPhoneDialMethod(StringUtils.isBlank(routeNode.getPhoneDialMethod()) ? null : routeNode.getPhoneDialMethod());
        }
        //问卷
        if (Objects.nonNull(routeNode) && TaskNodeTypeEnum.QUESTIONNAIRE_SCALE.getInfo().equals(routeNode.getTaskNodeType())) {
            signPatientManageRouteNode.setQuestionInfoId(Objects.isNull(routeNode.getQuestionInfoId()) ? null : routeNode.getQuestionInfoId());
            signPatientManageRouteNode.setQuestionnaireName(StringUtils.isBlank(routeNode.getQuestionnaireName()) ? null : routeNode.getQuestionnaireName());
            signPatientManageRouteNode.setQuestionnaireContent(StringUtils.isBlank(routeNode.getQuestionnaireContent()) ? null : routeNode.getQuestionnaireContent());
            signPatientManageRouteNode.setQuestionExpirationDate(Objects.isNull(routeNode.getQuestionExpirationDate()) ? null : routeNode.getQuestionExpirationDate());

            //如果是电话外呼，则设置外呼标识为1  zyk  20241216
            if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), routeNode.getPhoneDialMethod()) || StringUtils.equals(PhoneDialMethodEnum.COMMON.getInfo(), routeNode.getPhoneDialMethod())) {
                signPatientManageRouteNode.setPhoneRedialTimes(StringUtils.isBlank(routeNode.getPhoneRedialTimes()) ? null : routeNode.getPhoneRedialTimes());
                signPatientManageRouteNode.setPhoneTimeInterval(Objects.isNull(routeNode.getPhoneTimeInterval()) ? null : routeNode.getPhoneTimeInterval());
                signPatientManageRouteNode.setPhoneMessageRemind(StringUtils.isBlank(routeNode.getPhoneMessageRemind()) ? null : routeNode.getPhoneMessageRemind());
                signPatientManageRouteNode.setPhoneMessageTemplateId(Objects.isNull(routeNode.getPhoneMessageTemplateId()) ? null : routeNode.getPhoneMessageTemplateId());
                signPatientManageRouteNode.setPhoneMessageTemplateName(StringUtils.isBlank(routeNode.getPhoneMessageTemplateName()) ? null : routeNode.getPhoneMessageTemplateName());
                signPatientManageRouteNode.setPhoneDialMethod(StringUtils.isBlank(routeNode.getPhoneDialMethod()) ? null : routeNode.getPhoneDialMethod());
                signPatientManageRouteNode.setPhonePushSign(Objects.isNull(routeNode.getPhonePushSign()) ? null : routeNode.getPhonePushSign());
            }
            //根据问卷ID，获取问卷信息  zyk  20241216
            QuestionInfo questionInfo = questionInfoService.selectQuestionInfoById(signPatientManageRouteNode.getQuestionInfoId());

            if (ObjectUtils.isNotEmpty(questionInfo)) {
                signPatientManageRouteNode.setScriptInfoId(questionInfo.getScriptInfoId());
                signPatientManageRouteNode.setRobotPublishId(questionInfo.getRobotPublishId());
                // 节点是否是AI电话  zyk  20241216
                if (com.xinelu.common.utils.StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), routeNode.getPhoneDialMethod()) && com.xinelu.common.utils.StringUtils.isBlank(questionInfo.getRobotPublishId())) {
                    throw new ServiceException("第三方机器人id为空");
                }
            }
        }
        //宣教
        if (Objects.nonNull(routeNode) && TaskNodeTypeEnum.PROPAGANDA_ARTICLE.getInfo().equals(routeNode.getTaskNodeType())) {
            signPatientManageRouteNode.setPropagandaInfoId(Objects.isNull(routeNode.getPropagandaInfoId()) ? null : routeNode.getPropagandaInfoId());
            signPatientManageRouteNode.setPropagandaTitle(StringUtils.isBlank(routeNode.getPropagandaTitle()) ? null : routeNode.getPropagandaTitle());
            signPatientManageRouteNode.setPropagandaContent(StringUtils.isBlank(routeNode.getPropagandaContent()) ? null : routeNode.getPropagandaContent());

        }
        //文字提醒
        if (Objects.nonNull(routeNode) && TaskNodeTypeEnum.TEXT_REMIND.getInfo().equals(routeNode.getTaskNodeType())) {
            signPatientManageRouteNode.setNodeContent(StringUtils.isBlank(routeNode.getNodeContent()) ? null : routeNode.getNodeContent());
        }
        //短信
        signPatientManageRouteNode.setMessagePushSign(Objects.isNull(routeNode.getMessagePushSign()) ? null : routeNode.getMessagePushSign());
        signPatientManageRouteNode.setMessageTemplateId(Objects.isNull(routeNode.getMessageTemplateId()) ? null : routeNode.getMessageTemplateId());
        signPatientManageRouteNode.setMessageTemplateCode(Objects.isNull(routeNode.getMessageTemplateCode()) ? null : routeNode.getMessageTemplateCode());
        signPatientManageRouteNode.setMessageTemplateName(StringUtils.isBlank(routeNode.getMessageTemplateName()) ? null : routeNode.getMessageTemplateName());
        //公众号
        signPatientManageRouteNode.setOfficialPushSign(Objects.isNull(routeNode.getOfficialPushSign()) ? null : routeNode.getOfficialPushSign());
        signPatientManageRouteNode.setOfficialTemplateId(Objects.isNull(routeNode.getOfficialTemplateId()) ? null : routeNode.getOfficialTemplateId());
        signPatientManageRouteNode.setOfficialTemplateCode(Objects.isNull(routeNode.getOfficialTemplateCode()) ? null : routeNode.getOfficialTemplateCode());
        signPatientManageRouteNode.setOfficialTemplateName(StringUtils.isBlank(routeNode.getOfficialTemplateName()) ? null : routeNode.getOfficialTemplateName());
        //小程序
        signPatientManageRouteNode.setAppletPushSign(Objects.isNull(routeNode.getAppletPushSign()) ? null : routeNode.getAppletPushSign());
        signPatientManageRouteNode.setAppletTemplateId(Objects.isNull(routeNode.getAppletTemplateId()) ? null : routeNode.getAppletTemplateId());
        signPatientManageRouteNode.setAppletTemplateCode(Objects.isNull(routeNode.getAppletTemplateCode()) ? null : routeNode.getAppletTemplateCode());
        signPatientManageRouteNode.setAppletTemplateName(StringUtils.isBlank(routeNode.getAppletTemplateName()) ? null : routeNode.getAppletTemplateName());
        signPatientManageRouteNode.setManageRouteId(signPatientManageRoute.getId());
        signPatientManageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
        signPatientManageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
        signPatientManageRouteNode.setTaskNodeType(routeNode.getTaskNodeType());
        signPatientManageRouteNode.setRouteNodeName(routeNode.getRouteNodeName());
        signPatientManageRouteNode.setRouteNodeDay(routeNode.getRouteNodeDay());
        signPatientManageRouteNode.setCreateTime(LocalDateTime.now());
        signPatientManageRouteNode.setCreateBy(SecurityUtils.getUsername());
        signPatientManageRouteNode.setRouteCheckStatus(routeNode.getRouteCheckStatus());
        signPatientManageRouteNodes.add(signPatientManageRouteNode);
    }


    private void replaceTemplateInfo(SignPatientManageNodeAuditVo manageRouteNode, RouteTaskAuditVo node, List<LabelFieldInfoContentVo> labelFieldContentList) {
        if (node.getMessageTemplateId() != null) {
            // 替换短信模板
            manageRouteNode.setMessageNodeContent(signPatientManageRouteNodeService.replaceMessageInfo(node.getMessageTemplateId(), labelFieldContentList));
        }
        if (node.getPhoneMessageTemplateId() != null) {
            // 替换短信模板
            manageRouteNode.setPhoneMessageTemplateContent(signPatientManageRouteNodeService.replaceMessageInfo(node.getPhoneMessageTemplateId(), labelFieldContentList));
        }
        // 替换公众号模板
        if (node.getOfficialPushSign() != null && node.getOfficialPushSign() == 1) {
            manageRouteNode.setOfficialNodeContent(signPatientManageRouteNodeService.replaceWeChatTemplate(node.getOfficialTemplateId(), labelFieldContentList));
        }
        // 替换小程序模板
        if (node.getAppletPushSign() != null && node.getAppletPushSign() == 1) {
            manageRouteNode.setAppletNodeContent(signPatientManageRouteNodeService.replaceWeChatTemplate(node.getAppletTemplateId(), labelFieldContentList));
        }
    }


    /**
     * 发送短信(无变量)
     */
    @Override
    public Boolean sendSms(SmsInfoDTO smsInfoDTO) throws ClientException, ServiceException {
        try {
            // 短信发送参数非空性判断
            if (ObjectUtils.isEmpty(smsInfoDTO)) {
                throw new ServiceException("短信发送参数不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getPhoneNumbers())) {
                throw new ServiceException("待发送手机号不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getSignName())) {
                throw new ServiceException("短信签名不能为空!");
            }
            if (StringUtils.isBlank(smsInfoDTO.getTemplateCode())) {
                throw new ServiceException("短信模板Code不能为空!");
            }

            // 设置系统的默认连接超时时间和读取超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            // 初始化acsClient，暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getAccessKeyId(), aliYunSmsTwoConfig.getAccessKeySecret());
            DefaultProfile.addEndpoint(aliYunSmsTwoConfig.getRegionId(), aliYunSmsTwoConfig.getProduct(), aliYunSmsTwoConfig.getDomain());
            IAcsClient acsClient = new DefaultAcsClient(profile);

            // 组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(smsInfoDTO.getPhoneNumbers());
            request.setSignName(smsInfoDTO.getSignName());
            request.setTemplateCode(smsInfoDTO.getTemplateCode());
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            // 判断响应的结果
            if (!SUCCESS.equals(sendSmsResponse.getCode())) {
                SmsErrorCodeEnum errorCode = SmsErrorCodeEnum.getMsgByCode(sendSmsResponse.getCode());
                log.error("短信发送失败，错误码：{}，错误信息：{}", sendSmsResponse.getCode(), errorCode.getMessage());
                return false;
            }
            log.info("短信发送成功：code：{}", sendSmsResponse.getCode());
            return true;
        } catch (ClientException e) {
            log.error("发送短信出现异常，异常信息：{}", e.getMessage());
            throw e;
        }
    }

}
