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

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.constant.ApplyRangeContant;
import com.xinelu.common.constant.RouteNodeNameConstants;
import com.xinelu.common.constant.SignRecordServiceStatusConstants;
import com.xinelu.common.constant.TaskCreateTypeConstant;
import com.xinelu.common.constant.TaskNodeTypeConstants;
import com.xinelu.common.constant.TaskStatusConstant;
import com.xinelu.common.constant.TemplateTypeConstants;
import com.xinelu.common.constant.TriggerConditionOperatorConstants;
import com.xinelu.common.constant.TriggerLogicConstants;
import com.xinelu.common.constant.VisitMethodConstants;
import com.xinelu.common.core.domain.entity.SysUser;
import com.xinelu.common.enums.*;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.agency.Agency;
import com.xinelu.manage.domain.patientinfo.PatientAllInfoViewUppercase;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientnodeparamscurrent.PatientNodeParamsCurrent;
import com.xinelu.manage.domain.patienttaskexecuterecord.PatientTaskExecuteRecord;
import com.xinelu.manage.domain.patienttaskstatistics.PatientTaskStatistics;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.phonedialrecord.PhoneDialRecord;
import com.xinelu.manage.domain.propagandainfo.PropagandaInfo;
import com.xinelu.manage.domain.questioninfo.QuestionInfo;
import com.xinelu.manage.domain.scriptInfo.ScriptInfo;
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.domain.specialdiseasenode.SpecialDiseaseNode;
import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute;
import com.xinelu.manage.domain.specialdiseasetriggercondition.SpecialDiseaseTriggerCondition;
import com.xinelu.manage.domain.textmessage.TextMessage;
import com.xinelu.manage.domain.wechattemplate.WechatTemplate;
import com.xinelu.manage.dto.patientinfo.PatientInfoDto;
import com.xinelu.manage.dto.signpatientmanageroutenode.*;
import com.xinelu.manage.mapper.agency.AgencyMapper;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientAllInfoViewMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
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.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.mapper.specialdiseasenode.SpecialDiseaseNodeMapper;
import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper;
import com.xinelu.manage.mapper.specialdiseasetriggercondition.SpecialDiseaseTriggerConditionMapper;
import com.xinelu.manage.mapper.textmessage.TextMessageMapper;
import com.xinelu.manage.mapper.wechattemplate.WechatTemplateMapper;
import com.xinelu.manage.service.aiob.IAIOBService;
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.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
import com.xinelu.manage.service.specialdiseaseroute.ISpecialDiseaseRouteService;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import com.xinelu.manage.vo.patientinfo.PatientInfoVo;
import com.xinelu.manage.vo.patientinfo.PatientNextTaskVo;
import com.xinelu.manage.vo.patientquestionsubmitresult.PatientQuestionSubmitResultVO;
import com.xinelu.manage.vo.propagandainfo.PropagandaMaterialsVo;
import com.xinelu.manage.vo.questionInfo.QuestionVO;
import com.xinelu.manage.vo.signpatientmanageroutenode.*;
import com.xinelu.manage.vo.specialdiseasenode.PatientSpecialDiseaseNodeVo;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeVO;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.xinelu.system.mapper.SysUserMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 签约患者管理任务路径节点Service业务层处理
 *
 * @author haown
 * @date 2024-03-18
 */
@Service
public class SignPatientManageRouteNodeServiceImpl implements ISignPatientManageRouteNodeService {
    @Resource
    private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
	@Resource
	private PatientInfoMapper patientInfoMapper;
	@Resource
	private SignPatientManageRouteMapper signRouteMapper;
	@Resource
	private ScriptInfoMapper scriptInfoMapper;
	@Resource
	private IQuestionInfoService questionInfoService;
	@Resource
	private IPropagandaInfoService propagandaInfoService;
	@Resource
	private ISpecialDiseaseRouteService specialDiseaseRouteService;
	@Resource
	private SignPatientRecordMapper signPatientRecordMapper;
	@Resource
	private PatientVisitRecordMapper patientVisitRecordMapper;
	@Resource
	private SpecialDiseaseNodeMapper specialDiseaseNodeMapper;
	@Resource
	private TextMessageMapper textMessageMapper;
	@Resource
	private SpecialDiseaseTriggerConditionMapper triggerConditionMapper;
	@Resource
	private LabelFieldContentMapper labelFieldContentMapper;
	@Resource
	private WechatTemplateMapper wechatTemplateMapper;
	@Resource
	private PatientAllInfoViewMapper patientAllInfoViewMapper;
	@Resource
	private SpecialDiseaseRouteMapper specialDiseaseRouteMapper;
	@Resource
	private SignRouteTriggerConditionMapper signRouteTriggerConditionMapper;
	@Resource
	private PatientQuestionSubmitResultMapper patientQuestionSubmitResultMapper;
	@Resource
	private PatientTaskExecuteRecordMapper patientTaskExecuteRecordMapper;
	@Resource
	private IPatientTaskStatisticsService patientTaskStatisticsService;
	@Resource
	private PhoneDialRecordMapper phoneDialRecordMapper;
	@Resource
	private IAIOBService aiobService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private AgencyMapper agencyMapper;

    /**
     * 查询签约患者管理任务路径节点
     *
     * @param id 签约患者管理任务路径节点主键
     * @return 签约患者管理任务路径节点
     */
    @Override
    public PatientManageNodeInfoVo selectSignPatientManageRouteNodeById(Long id) {
	    PatientManageNodeInfoVo retVo = new PatientManageNodeInfoVo();
	    SignPatientManageRouteNode node = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeById(id);
		BeanUtils.copyBeanProp(retVo, node);
		// 判断节点是否选择模板，选择模板则返回模板内容
	    JSONObject detailInfo = new JSONObject();
	    if (node.getPropagandaInfoId() != null) {
			// 宣教
		    PropagandaMaterialsVo propagandaMaterialsVo = propagandaInfoService.selectPropagandaInfoById(node.getPropagandaInfoId());
		    detailInfo = JSONObject.parseObject(JSONObject.toJSONString(propagandaMaterialsVo));
		    retVo.setTemplateType(TemplateTypeConstants.PROPAGANDA);
	    } else if (StringUtils.isNotBlank(node.getPhoneTemplateId())) {
			// 话术
		    ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
		    detailInfo = JSONObject.parseObject(JSONObject.toJSONString(scriptInfo));
		    retVo.setTemplateType(TemplateTypeConstants.SCRIPT);
	    } else if (node.getQuestionInfoId() != null) {
			// 问卷
		    QuestionVO questionVO = questionInfoService.selectQuestionInfoById(node.getQuestionInfoId());
		    detailInfo = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
		    retVo.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
	    }
	    retVo.setDetailInfo(detailInfo);
        return retVo;
    }

	/**
	 * 查询患者管理路径节点
	 * @param signPatientRecordId 签约记录主键
	 * @return 患者管理任务路径节点
	 * @Author haown
	 * @Date 2024-08-01 15:23
	 */
	@Override public List<SignPatientTaskVo> getNodeList(Long signPatientRecordId) {
		List<SignPatientTaskVo> retList = new ArrayList<>();
		SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signPatientRecordId);
		if (ObjectUtils.isEmpty(signPatientRecord)) {
			throw new ServiceException("数据有误，请联系管理员!");
		}
		if (!StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getRouteCheckStatus())) {
			return new ArrayList<>();
		}
		PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
		// 根据签约记录主键查询患者任务列表
		SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
		manageRouteQuery.setSignPatientRecordId(signPatientRecordId);
		List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
		if (CollectionUtils.isNotEmpty(manageRouteList)) {
			List<Long> manageRouteIds = manageRouteList.stream().map(SignPatientManageRoute::getId).collect(Collectors.toList());
			List<SignPatientTaskVo> manageNodeList = signPatientManageRouteNodeMapper.selectNodeInfoByManageIds(manageRouteIds);
			// 组装数据
			List<SignPatientTaskVo> finalRetList = new ArrayList<>();
			manageNodeList.forEach(manageNode -> {
				manageNode.setTaskCreateType(ObjectUtils.isEmpty(manageNode.getRouteNodeId()) ? TaskCreateTypeConstant.MANUAL_CREATE : TaskCreateTypeConstant.MANUAL_MATCHE);
				manageNode.setRouteNodeNameCN(RouteNodeNameEnum.getNameByInfo(manageNode.getRouteNodeName()).getName());
				manageNode.setExecuteDateTime(getExecuteTime(manageNode.getExecuteTime(), manageNode.getRouteNodeName(), manageNode.getRouteNodeDay(), patientVisitRecord));
				manageNode.setTaskTypeName(StringUtils.isEmpty(manageNode.getTaskTypeName()) ? manageNode.getTaskNodeTypeName() : manageNode.getTaskTypeName());
				// 判断电话拨通情况、任务超时、已读、未读
				if (StringUtils.equals(NodeExecuteResultStatusEnum.FAILURE.getInfo(), manageNode.getPhoneNodeExecuteResultStatus())) {
					manageNode.setTaskStatus(TaskStatusConstant.NOT_CONNECTED);
				} else if (StringUtils.equals(NodeExecuteResultStatusEnum.SUCCESS.getInfo(), manageNode.getPhoneNodeExecuteResultStatus())) {
					manageNode.setTaskStatus(TaskStatusConstant.CONNECTED);
				} else if (StringUtils.equals(NodeExecuteResultStatusEnum.EXPIRED.getInfo(), manageNode.getPhoneNodeExecuteResultStatus())) {
					manageNode.setTaskStatus(TaskStatusConstant.EXPIRED);
				} else {
					// 判断消息已读未读
					if (ObjectUtils.isEmpty(manageNode.getNodeFinishDate()) || StringUtils.isBlank(manageNode.getMessageStatus()) || StringUtils.equals(MessageStatusEnum.UNREAD.getInfo(), manageNode.getMessageStatus())) {
						manageNode.setTaskStatus(TaskStatusConstant.UNREAD);
					} else {
						manageNode.setTaskStatus(TaskStatusConstant.READ);
					}
				}

				JSONObject templateDetail = new JSONObject();
				if (StringUtils.isNotBlank(manageNode.getTaskNodeType())) {
					switch (manageNode.getTaskNodeType()) {
						// 电话外呼
						case TaskNodeTypeConstants.PHONE_OUTBOUND:
							manageNode.setTaskName(manageNode.getPhoneTemplateName());
							break;
						// 问卷,查询问卷详情，已作答的问卷展示作答详情，未作答显示问卷详情
						case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
							if (manageNode.getQuestionInfoId() != null) {
								if (ObjectUtils.isEmpty(manageNode.getNodeFinishDate())) {
									QuestionVO questionVO = questionInfoService.selectQuestionInfoById(manageNode.getQuestionInfoId());
									if (ObjectUtils.isNotEmpty(questionVO)) {
										templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
										manageNode.setDetailInfo(templateDetail);
									}
									manageNode.setTaskName(questionVO.getQuestionnaireName());
								} else {
									// 查询执行记录
									PatientTaskExecuteRecord patientTaskExecuteRecordQuery = new PatientTaskExecuteRecord();
									patientTaskExecuteRecordQuery.setManageRouteNodeId(manageNode.getId());
									List<PatientTaskExecuteRecord> taskExecuteRecordList = patientTaskExecuteRecordMapper.selectPatientTaskExecuteRecordList(patientTaskExecuteRecordQuery);
									if (CollectionUtils.isEmpty(taskExecuteRecordList)) {
										QuestionVO questionVO = questionInfoService.selectQuestionInfoById(manageNode.getQuestionInfoId());
										if (ObjectUtils.isNotEmpty(questionVO)) {
											templateDetail = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
											manageNode.setTaskName(questionVO.getQuestionnaireName());
										}
									} else {
										PatientQuestionSubmitResultVO patientQuestionSubmitResultVO = patientQuestionSubmitResultMapper.selectResultByTaskExecuteRecordId(taskExecuteRecordList.get(0).getId(), null);
										if (ObjectUtils.isNotEmpty(patientQuestionSubmitResultVO)) {
											templateDetail = JSONObject.parseObject(JSONObject.toJSONString(patientQuestionSubmitResultVO));
											manageNode.setTaskName(patientQuestionSubmitResultVO.getQuestionnaireName());
										}
									}
									manageNode.setDetailInfo(templateDetail);
								}
							}
							break;
						// 宣教
						case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
							// 查询宣教详情
							if (manageNode.getPropagandaInfoId() != null) {
								PropagandaInfo propagandaInfo = propagandaInfoService.getById(manageNode.getPropagandaInfoId());
								if (ObjectUtils.isNotEmpty(propagandaInfo)) {
									manageNode.setPropagandaContent(propagandaInfo.getPropagandaContent());
								}
								manageNode.setTaskName(propagandaInfo.getPropagandaTitle());
							}
							break;
						// 文字提醒--展示nodeContent,根据message_status判断已读状态
						case TaskNodeTypeConstants.TEXT_REMIND:
							manageNode.setTaskName(StringUtils.isEmpty(manageNode.getTaskPartitionDictName()) ? manageNode.getTaskNodeTypeName() : manageNode.getTaskPartitionDictName());
							break;
					}
				}
				finalRetList.add(manageNode);
			});
			// 按照执行时间正序排序
			retList = finalRetList.stream().sorted(Comparator.comparing(SignPatientTaskVo::getExecuteDateTime)).collect(Collectors.toList());
		}
		return retList;
	}

	@Override public List<PatientManageNodeInfoVo> getNodeListByPatient(PatientTaskDto patientTaskDto) {
		List<PatientManageNodeInfoVo> retList = new ArrayList<>();
		if (patientTaskDto.getPatientId() == null) {
			throw new ServiceException("患者信息有误");
		}
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientTaskDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("患者信息有误!");
		}
		patientTaskDto.setSignPatientRecordId(patientInfo.getSignPatientRecordId());
		// 根据任务类型、审核状态查询节点列表
		List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeMapper.getNodeList(patientTaskDto);
		nodeList.forEach(node -> {
			PatientManageNodeInfoVo retVo = new PatientManageNodeInfoVo();
			JSONObject detailInfo = new JSONObject();
			if (node.getPropagandaInfoId() != null) {
				// 宣教
				PropagandaMaterialsVo propagandaMaterialsVo = propagandaInfoService.selectPropagandaInfoById(node.getPropagandaInfoId());
				detailInfo = JSONObject.parseObject(JSONObject.toJSONString(propagandaMaterialsVo));
				retVo.setTemplateType(TemplateTypeConstants.PROPAGANDA);
			} else if (StringUtils.isNotBlank(node.getPhoneTemplateId())) {
				// 话术
				ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
				detailInfo = JSONObject.parseObject(JSONObject.toJSONString(scriptInfo));
				retVo.setTemplateType(TemplateTypeConstants.SCRIPT);
			} else if (node.getQuestionInfoId() != null) {
				// 问卷
				QuestionVO questionVO = questionInfoService.selectQuestionInfoById(node.getQuestionInfoId());
				detailInfo = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
				retVo.setTemplateType(TemplateTypeConstants.QUESTIONNAIRE);
			}
			retVo.setDetailInfo(detailInfo);
			retList.add(retVo);
		});
		return retList;
	}

	@Override public List<SignPatientManageRouteNodeVo> getRouteNodeList(PatientTaskDto patientTaskDto) {
		List<SignPatientManageRouteNodeVo> retList = new ArrayList<>();
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientTaskDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("请选择患者!");
		}
		// 根据任务创建类型、审核状态查询节点列表
		List<SignPatientManageRouteNode> allNodeList = signPatientManageRouteNodeMapper.getNodeList(patientTaskDto);
		// 根据任务id进行分组
		Map<Long, List<SignPatientManageRouteNode>> groupByRoute = allNodeList.stream().collect(Collectors.groupingBy(SignPatientManageRouteNode::getManageRouteId));

		SpecialDiseaseRouteVO specialDiseaseRoute = null;
		for (Long manageRouteId : groupByRoute.keySet()) {
			List<SignPatientManageRouteNodeInfoVo> nodeInfoVoList = new ArrayList<>();
			List<SignPatientManageRouteNode> nodeList = groupByRoute.get(manageRouteId);
			SignPatientManageRoute manageRoute = signRouteMapper.selectSignPatientManageRouteById(manageRouteId);
			// 判断手动创建或自动生成
			switch (manageRoute.getTaskCreateType()) {
				case TaskCreateTypeConstant.MANUAL_CREATE:
					// 查询模板内容
					for (SignPatientManageRouteNode node : nodeList) {
						SignPatientManageRouteNodeInfoVo signNodeInfo = new SignPatientManageRouteNodeInfoVo();
						BeanUtils.copyBeanProp(signNodeInfo, node);
						JSONObject detailInfo = new JSONObject();
						switch (node.getTaskNodeType()) {
							case TaskNodeTypeConstants.PHONE_OUTBOUND: // 电话外呼-查询话术表
								if (node.getScriptInfoId() != null) {
									ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
									detailInfo = JSONObject.parseObject(JSONObject.toJSONString(scriptInfo));
								} else if (node.getQuestionInfoId() != null) { // 问卷
									// 查询问卷详情
									QuestionVO questionVO = questionInfoService.selectQuestionInfoById(node.getQuestionInfoId());
									if (ObjectUtils.isNotEmpty(questionVO)) {
										detailInfo = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
									}
								}
								break;
							case (TaskNodeTypeConstants.QUESTIONNAIRE_SCALE): // 问卷量表-返回问卷信息
								if (node.getQuestionInfoId() != null) {
									QuestionVO questionVO = questionInfoService.selectQuestionInfoById(node.getQuestionInfoId());
									detailInfo = JSONObject.parseObject(JSONObject.toJSONString(questionVO));
								}
								break;
							case (TaskNodeTypeConstants.PROPAGANDA_ARTICLE): // 宣教文章-返回宣教库信息
								if (node.getPropagandaInfoId() != null) {
									PropagandaMaterialsVo propagandaMaterialsVo = propagandaInfoService.selectPropagandaInfoById(node.getPropagandaInfoId());
									signNodeInfo.setPropagandaContent(propagandaMaterialsVo.getPropagandaContent());
									detailInfo = JSONObject.parseObject(JSONObject.toJSONString(propagandaMaterialsVo));
								}
								break;
						}
						signNodeInfo.setDetailInfo(detailInfo);
						nodeInfoVoList.add(signNodeInfo);
					}
					break;
				case TaskCreateTypeConstant.MANUAL_MATCHE:
					// 查询专病路径
					specialDiseaseRoute = specialDiseaseRouteService.selectSpecialDiseaseRouteById(manageRoute.getRouteId());
					break;
			}

			retList.add(SignPatientManageRouteNodeVo.builder().specialDiseaseRoute(specialDiseaseRoute)
				.manageRouteId(manageRouteId)
				.routeName(manageRoute.getRouteName())
				.taskCreateType(manageRoute.getTaskCreateType())
				.suitRange(manageRoute.getSuitRange())
				.nodeList(nodeInfoVoList).build());
		}
		return retList;
	}

	/**
     * 查询签约患者管理任务路径节点列表
     *
     * @param signPatientManageRouteNodeDto 签约患者管理任务路径节点查询传输对象
     * @return 签约患者管理任务路径节点
     */
    @Override
    public List<SignPatientManageRouteNode> selectSignPatientManageRouteNodeList(SignPatientManageRouteNodeDto signPatientManageRouteNodeDto) {
		return signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
    }

	@Override public List<PatientManageNodeListVo> selectPatientManageNodeList(SignPatientManageRouteNodeDto signPatientManageRouteNodeDto) {
		return signPatientManageRouteNodeMapper.selectPatientManageNodeList(signPatientManageRouteNodeDto);
	}

	/**
     * 新增签约患者管理任务路径节点
     *
     * @param signPatientManageRouteNode 签约患者管理任务路径节点
     * @return 结果
     */
    @Override
    public int insertSignPatientManageRouteNode(SignPatientManageRouteNode signPatientManageRouteNode) {
        signPatientManageRouteNode.setCreateTime(LocalDateTime.now());
	    signPatientManageRouteNode.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
	    signPatientManageRouteNode.setDelFlag(0);
        return signPatientManageRouteNodeMapper.insertSignPatientManageRouteNode(signPatientManageRouteNode);
    }

    /**
     * 修改签约患者管理任务路径节点
     *
     * @param signPatientManageRouteNode 签约患者管理任务路径节点
     * @return 结果
     */
    @Override
    public int updateSignPatientManageRouteNode(SignPatientManageRouteNode signPatientManageRouteNode) {
        signPatientManageRouteNode.setUpdateTime(LocalDateTime.now());
	    signPatientManageRouteNode.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        return signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signPatientManageRouteNode);
    }

    /**
     * 批量删除签约患者管理任务路径节点
     *
     * @param ids 需要删除的签约患者管理任务路径节点主键
     * @return 结果
     */
    @Override
    public int deleteSignPatientManageRouteNodeByIds(Long[] ids) {
        return signPatientManageRouteNodeMapper.deleteSignPatientManageRouteNodeByIds(ids);
    }

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

	@Override
	@DataScope(agencyAlias = "patient")
	public List<PatientTaskVo> selectPatientTaskList(PatientTaskDto patientTaskDto) {
		return signPatientManageRouteNodeMapper.selectPatientTaskList(patientTaskDto);
	}

	/**
	 * 审核任务
	 * @param routeNodeCheckDto 任务审核传输对象
	 * @return 结果
	 */
	@Override
	@Transactional
	public int audit(RouteNodeCheckDto routeNodeCheckDto) {
		int flag = 0;
		if (CollectionUtils.isEmpty(routeNodeCheckDto.getManageRouteNodeIds())) {
			throw new ServiceException("没有要审核的任务");
		}
		// 根据manageRouteId查询所有节点
		for (Long nodeId : routeNodeCheckDto.getManageRouteNodeIds()) {
			SignPatientManageRouteNode node = new SignPatientManageRouteNode();
			node.setId(nodeId);
			node.setRouteCheckStatus(routeNodeCheckDto.getRouteCheckStatus());
			node.setRouteCheckPerson(routeNodeCheckDto.getRouteCheckPerson());
			node.setRouteCheckDate(LocalDateTime.now());
			node.setRouteCheckRemark(routeNodeCheckDto.getRouteCheckRemark());
			flag += signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(node);
		}
		return flag;
	}

	@Override public List<AppletRouteNodeListVo> getAppletTaskList(AppletPatientTaskDto appletPatientTaskDto) {
		// 根据居民信息表主键查询患者信息
		List<AppletRouteNodeListVo> retList = new ArrayList<>();
		// 查询患者表信息
		PatientInfoDto patientQuery = new PatientInfoDto();
		patientQuery.setResidentId(appletPatientTaskDto.getResidentId());
		List<PatientInfo> patientInfoList = patientInfoMapper.selectPatientInfoList(patientQuery);
		if (CollectionUtils.isEmpty(patientInfoList)) {
			return retList;
		}
		for (PatientInfo patientInfo : patientInfoList) {
			// 查询患者最新一次签约记录
			if (patientInfo.getSignPatientRecordId() == null) {
				continue;
			}
			SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(patientInfo.getSignPatientRecordId());
			if (ObjectUtils.isEmpty(signPatientRecord)) {
				continue;
			}
			PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
			if (ObjectUtils.isEmpty(patientVisitRecord)) {
				continue;
			}
			// 根据患者签约记录查询自动生成的任务
			SignPatientManageRoute signPatientManageRoute = new SignPatientManageRoute();
			signPatientManageRoute.setSignPatientRecordId(patientInfo.getSignPatientRecordId());
			signPatientManageRoute.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
			List<SignPatientManageRoute> signRouteList = signRouteMapper.selectSignPatientManageRouteList(signPatientManageRoute);
			if (CollectionUtils.isNotEmpty(signRouteList)) {
				SignPatientManageRoute signRoute = signRouteList.get(0);
				SignPatientManageRouteNodeDto nodeQuery = new SignPatientManageRouteNodeDto();
				nodeQuery.setManageRouteId(signRoute.getId());
				nodeQuery.setTaskTypeList(Arrays.asList(appletPatientTaskDto.getTaskTypeList().split(",")));
				List<SignPatientManageRouteNode> signNodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(nodeQuery);
				for (SignPatientManageRouteNode node : signNodeList) {
					// 任务执行时间
					LocalDateTime executeTime = getExecuteTime(node.getExecuteTime(), node.getRouteNodeName(), node.getRouteNodeDay(), patientVisitRecord);

					retList.add(AppletRouteNodeListVo.builder()
						.id(node.getId())
						.patientName(patientInfo.getPatientName())
						.hospitalAgencyName(patientVisitRecord.getHospitalAgencyName())
						.manageRouteId(node.getManageRouteId())
						.manageRouteName(node.getManageRouteName())
						.routeNodeName(node.getRouteNodeName())
						.routeNodeDay(node.getRouteNodeDay())
						.taskType(node.getTaskType())
						.executeTime(executeTime)
						.build());
				}
			}
		}
		// 按照时间顺序排序
		if (CollectionUtils.isNotEmpty(retList)) {
			retList = retList.stream().sorted(Comparator.comparing(AppletRouteNodeListVo::getExecuteTime)).collect(Collectors.toList());
		}
		return retList;
	}

	@Override public List<PatientSpecialDiseaseNodeVo> getSpecialDiseaseNode(PatientTaskDto patientTaskDto) {
		// 查询最新一次签约记录
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientTaskDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("请选择患者!");
		}
		patientTaskDto.setSignPatientRecordId(patientInfo.getSignPatientRecordId());
		SignPatientManageRoute routeQuery = new SignPatientManageRoute();
		routeQuery.setSignPatientRecordId(patientInfo.getSignPatientRecordId());
		routeQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
		List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(routeQuery);
		if (CollectionUtils.isEmpty(manageRouteList)) {
			throw new ServiceException("未找到签约管理路径");
		}
		// 根据专病路径查询专病节点信息
		return specialDiseaseNodeMapper.selectRouteNodeByRouteId(manageRouteList.get(0).getRouteId());
	}

	/**
	 * @description 根据任务主键获取最新一次的电话拨打录音及通话记录
	 * @Param  id 任务主键
	 * @return 电话拨打录音及通话记录
	 * @Author haown
	 * @Date 2024-11-8 14:43
	 */
	@Override public AIDialRecordVo getPhoneDialVideo(Long id) {
		AIDialRecordVo recordVo = new AIDialRecordVo();
		// 查询通话记录
		SignPatientManageRouteNode signPatientManageRouteNode = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeById(id);

		PhoneDialRecord phoneDialRecord = phoneDialRecordMapper.getLastRecord(id);

		String phoneResultJson = signPatientManageRouteNode.getPhoneResultJson();
		if (StringUtils.isNotBlank(phoneResultJson)) {
			JSONObject resultJson = JSONObject.parseObject(phoneResultJson);
			JSONArray record = resultJson.getJSONArray("record");
			recordVo.setRecord(record);

			if(ObjectUtils.isEmpty(phoneDialRecord) || StringUtils.isBlank(phoneDialRecord.getCtUuid())) {
				// 从任务中解析ctuuid
				String ctuuid = resultJson.getString("contactUUID");
				if (StringUtils.isNotBlank(ctuuid)) {
					String videoUrl = aiobService.getPhoneDialRecord(ctuuid);
					recordVo.setPhoneDialRecordVideo(videoUrl);
				}
				return recordVo;
			}
		}

		if (StringUtils.isBlank(phoneDialRecord.getPhoneDialRecordVideo())) {
			String videoUrl = aiobService.getPhoneDialRecord(phoneDialRecord.getCtUuid());
			phoneDialRecord.setPhoneDialRecordVideo(videoUrl);
			phoneDialRecordMapper.updatePhoneDialRecord(phoneDialRecord);
			recordVo.setPhoneDialRecordVideo(videoUrl);
		} else {
			recordVo.setPhoneDialRecordVideo(phoneDialRecord.getPhoneDialRecordVideo());
		}

		return recordVo;
	}

	/**
	 * 生成有参数得任务
	 * @param routeNodeId 节点id
	 * @param manageRouteId  管理路径id
	 * @param manageRouteName  管理路径名称
	 * @param paramsCurrentLists  参数列表
	 */
	private void generateTask(Long routeNodeId, Long manageRouteId, String manageRouteName, List<List<PatientNodeParamsCurrent>> paramsCurrentLists) {
		// 查询专病路径节点
		SpecialDiseaseNode specialDiseaseNode = specialDiseaseNodeMapper.selectSpecialDiseaseNodeById(routeNodeId);
		if (ObjectUtils.isEmpty(specialDiseaseNode)) {
			throw new ServiceException("数据错误，请联系管理员");
		}

		List<SignPatientManageRouteNode> manageNodeList = new ArrayList<>();
		for (List<PatientNodeParamsCurrent> paramsCurrentList : paramsCurrentLists) {
				SignPatientManageRouteNode manageRouteNode = new SignPatientManageRouteNode();
				BeanUtils.copyBeanProp(manageRouteNode, specialDiseaseNode);
				manageRouteNode.setManageRouteId(manageRouteId);
				manageRouteNode.setManageRouteName(manageRouteName);
				manageRouteNode.setId(null);
				manageRouteNode.setRouteNodeId(specialDiseaseNode.getId());
				manageRouteNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
				manageRouteNode.setRouteCheckDate(LocalDateTime.now());
				manageRouteNode.setRouteCheckRemark("手动生成任务");
				manageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
				// 替换文本
				manageRouteNode.setNodeContent(replaceNodeContent(specialDiseaseNode.getNodeContent(), paramsCurrentList));
				manageRouteNode.setExecuteTime(specialDiseaseNode.getExecutionTime());
				manageRouteNode.setCreateTime(LocalDateTime.now());
				manageRouteNode.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());

				manageNodeList.add(manageRouteNode);
		}

		// 批量保存
		signPatientManageRouteNodeMapper.insertBatch(manageNodeList);
	}

	/**
	 * 根据参数列表修改任务
	 * @param paramsCurrentLists 参数列表
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateTaskWithParam(List<List<PatientNodeParamsCurrent>> paramsCurrentLists) {
		// 查询患者
		Long patientId = paramsCurrentLists.get(0).get(0).getPatientId();
		if (patientId == null) {
			throw new ServiceException("未找到该患者");
		}
		// 查询患者
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientId);
		SignPatientManageRoute routeQuery = new SignPatientManageRoute();
		routeQuery.setSignPatientRecordId(patientInfo.getSignPatientRecordId());
		routeQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
		List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(routeQuery);
		if (CollectionUtils.isEmpty(manageRouteList)) {
			throw new ServiceException("未找到签约管理路径");
		}

		SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
		signPatientManageRouteNodeDto.setManageRouteId(manageRouteList.get(0).getId());
		signPatientManageRouteNodeDto.setRouteNodeId(paramsCurrentLists.get(0).get(0).getRouteNodeId());
		List<SignPatientManageRouteNode> manageNodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
		if (CollectionUtils.isEmpty(manageNodeList)) {
			// 生成任务
			generateTask(paramsCurrentLists.get(0).get(0).getRouteNodeId(), manageRouteList.get(0).getId(),manageRouteList.get(0).getRouteName(), paramsCurrentLists);
		} else {
			if (StringUtils.equals(NodeExecuteStatusEnum.EXECUTED.getInfo(), manageNodeList.get(0).getNodeExecuteStatus())) {
				// 任务已执行不修改
				throw new ServiceException("任务已执行，修改失败");
			} else {
				// 删除任务，重新生成
				Long[] nodeIds = manageNodeList.stream().map(SignPatientManageRouteNode::getId).toArray(Long[]::new);
				signPatientManageRouteNodeMapper.deleteSignPatientManageRouteNodeByIds(nodeIds);
				generateTask(paramsCurrentLists.get(0).get(0).getRouteNodeId(),manageRouteList.get(0).getId(),manageRouteList.get(0).getRouteName(), paramsCurrentLists);
			}
		}
	}

	/**
	 * 获取节点执行时间
	 * @param executeTime 节点执行时间，HH:mm
	 * @param routeNodeName 节点名称
	 * @param routeNodeDay 节点执行天数
	 * @param patientVisitRecord 患者就诊记录
	 * @return
	 */
	@Override
	public LocalDateTime getExecuteTime(LocalTime executeTime, String routeNodeName, Integer routeNodeDay, PatientVisitRecord patientVisitRecord) {
		LocalDateTime executeDateTime = null;

		LocalTime et = LocalTime.of(8,0,0);
		if (executeTime != null) {
			et = executeTime;
		}
		switch(routeNodeName) {
			case RouteNodeNameConstants.AFTER_DISCHARGE: // 出院后
			case RouteNodeNameConstants.AFTER_VISIT_DISCHARGE: // 就诊/出院后
				// 判断是门诊/住院
				if (StringUtils.equals(VisitMethodConstants.BE_IN_HOSPITAL, patientVisitRecord.getVisitMethod())) {
					executeDateTime = LocalDateTime.of(patientVisitRecord.getDischargeTime().plusDays(routeNodeDay).toLocalDate(), et);
				} else {
					executeDateTime = LocalDateTime.of(patientVisitRecord.getVisitDate().plusDays(routeNodeDay).toLocalDate(), et);
				}
				break;
			case RouteNodeNameConstants.AFTER_ADMISSION: // 入院后
				if (StringUtils.equals(VisitMethodConstants.BE_IN_HOSPITAL, patientVisitRecord.getVisitMethod())) {
					executeDateTime = LocalDateTime.of(patientVisitRecord.getAdmissionTime().plusDays(routeNodeDay).toLocalDate(), et);
				} else {
					executeDateTime = LocalDateTime.of(patientVisitRecord.getVisitDate().plusDays(routeNodeDay).toLocalDate(), et);
				}
				break;
			case RouteNodeNameConstants.AFTER_CONSULTATION: // 就诊后
				executeDateTime = LocalDateTime.of(patientVisitRecord.getVisitDate().plusDays(routeNodeDay).toLocalDate(), et);
				break;
			default:
				executeDateTime = LocalDateTime.of(patientVisitRecord.getVisitDate().plusDays(routeNodeDay).toLocalDate(), et);
				break;
		}
		return executeDateTime;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void generateMainRouteTask(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 = signRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
		if (CollectionUtils.isEmpty(manageRouteList)) {
			throw new ServiceException("未找到签约管理路径");
		}
		SignPatientManageRoute signPatientManageRoute = manageRouteList.get(0);
		generateByManageRoute(signPatientManageRoute, signPatientRecord.getPatientId());
	}

	/**
	 * 手动创建的任务标签替换
	 * @param signRecordId 签约记录主键
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void manualCreateTaskLabelReplace(Long signRecordId) {
		SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
		manageRouteQuery.setSignPatientRecordId(signRecordId);
		manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_CREATE);
		List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
		manualCreateTaskLabelReplaceForManageRouteList(manageRouteList);
	}
	/**
	 * 手动创建的任务标签替换
	 * @param patientId 签约记录主键
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void manualCreateTaskLabelReplaceByPatientId(Long patientId) {
		SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
		manageRouteQuery.setPatientId(patientId);
		manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_CREATE);
		List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
		manualCreateTaskLabelReplaceForManageRouteList(manageRouteList);
	}
	/**
	 * 手动创建的任务标签替换
	 * @param manageRouteList
	 */
	public void manualCreateTaskLabelReplaceForManageRouteList(List<SignPatientManageRoute> manageRouteList) {
		if (CollectionUtils.isNotEmpty(manageRouteList)) {
			// 查询患者画像信息
			List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(manageRouteList.get(0).getPatientId());
			if (CollectionUtils.isEmpty(labelFieldContentList)) {
				throw new ServiceException("请先维护画像信息");
			}
			List<Long> manageRouteIds = manageRouteList.stream().map(SignPatientManageRoute::getId).collect(Collectors.toList());
			List<SignPatientManageRouteNode> manageNodeList = signPatientManageRouteNodeMapper.selectNodesByManageIds(manageRouteIds);
			// 根据node去替换模板信息
			manageNodeList.forEach(manageNode -> {
				if (StringUtils.isNotBlank(manageNode.getTaskNodeType())) {
					switch(manageNode.getTaskNodeType()) {
						// 电话外呼--话术/问卷，只替换话术
						case TaskNodeTypeConstants.PHONE_OUTBOUND:
							if (manageNode.getScriptInfoId() != null) {
								ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(manageNode.getScriptInfoId());
								if (ObjectUtils.isNotEmpty(scriptInfo)) {
									// 话术库json内容替换
									manageNode.setPhoneNodeContent(getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
									manageNode.setPhoneTemplateId(scriptInfo.getScriptId());
									if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
										throw new ServiceException("第三方机器人id为空");
									}
								}
							}
							// 电话短信内容
							if (manageNode.getPhoneMessageTemplateId() != null) {
								// 查询短信库
								manageNode.setPhoneMessageTemplateContent(replaceMessageInfo(manageNode.getPhoneMessageTemplateId(), labelFieldContentList));
							}
							break;
						// 问卷
						case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
							// 宣教
						case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
							// 文字提醒
						case TaskNodeTypeConstants.TEXT_REMIND:
							break;
					}
				}
				// 替换短信、公众号、小程序内容
				if (manageNode.getMessageTemplateId() != null) {
					// 替换短信模板
					manageNode.setMessageNodeContent(replaceMessageInfo(manageNode.getMessageTemplateId(), labelFieldContentList));
				}
				if (manageNode.getPhoneMessageTemplateId() != null) {
					// 替换短信模板
					manageNode.setPhoneMessageTemplateContent(replaceMessageInfo(manageNode.getPhoneMessageTemplateId(), labelFieldContentList));
				}
				// 替换公众号模板
				if (manageNode.getOfficialPushSign() != null && manageNode.getOfficialPushSign() == 1) {
					manageNode.setOfficialNodeContent(replaceWeChatTemplate(manageNode.getOfficialTemplateId(), labelFieldContentList));
				}
				// 替换小程序模板
				if (manageNode.getAppletPushSign() != null && manageNode.getAppletPushSign() == 1) {
					manageNode.setAppletNodeContent(replaceWeChatTemplate(manageNode.getAppletTemplateId(), labelFieldContentList));
				}
				manageNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
				manageNode.setRouteCheckDate(LocalDateTime.now());
				manageNode.setRouteCheckPerson(SecurityUtils.getLoginUser().getUser().getNickName());
				signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(manageNode);
			});

			// 任务统计表中插入数据
			if (CollectionUtils.isNotEmpty(manageNodeList)) {
				patientTaskStatisticsService.insertOrUpdate(PatientTaskStatistics.builder()
					.signPatientRecordId(manageRouteList.get(0).getSignPatientRecordId())
					.patientId(manageRouteList.get(0).getPatientId())
					.taskNum(BigDecimal.valueOf(manageNodeList.size()))
					.taskExecuteNum(BigDecimal.ZERO)
					.taskFinishNum(BigDecimal.ZERO)
					.build());
			}
		}
	}

	/**
	 * 根据触发条件生成子路径任务
	 * @param patientId 患者主键
	 * @param signPatientRecordId 签约记录表主键
	 * @param specialDiseaseRouteId 专病管理路径子路径主键
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void generateChildRouteTask(Long patientId, Long signPatientRecordId, Long specialDiseaseRouteId) {
		// 查询是否满足触发条件
		boolean generateTask = getTriggerConditon(specialDiseaseRouteId, patientId);
		if (generateTask) {
			// 保存sign_patient_manage_route表
			SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
			manageRouteQuery.setSignPatientRecordId(signPatientRecordId);
			manageRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
			List<SignPatientManageRoute> mainRouteList = signRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
			if (CollectionUtils.isEmpty(mainRouteList)) {
				throw new ServiceException("未找到签约管理路径");
			}
			SignPatientManageRoute mainManageRoute = mainRouteList.get(0);
			SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseRouteId);
			SignPatientManageRoute signPatientManageRoute = new SignPatientManageRoute();
			BeanUtils.copyBeanProp(signPatientManageRoute, specialDiseaseRoute);
			signPatientManageRoute.setSignPatientRecordId(signPatientRecordId);
			signPatientManageRoute.setPatientId(patientId);
			signPatientManageRoute.setPatientName(mainManageRoute.getPatientName());
			signPatientManageRoute.setId(null);
			signPatientManageRoute.setRouteId(specialDiseaseRoute.getId());
			signPatientManageRoute.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
			signPatientManageRoute.setParentRouteId(mainManageRoute.getId());
			signPatientManageRoute.setCreateTime(LocalDateTime.now());
			signRouteMapper.insertSignPatientManageRoute(signPatientManageRoute);
			// 保存任务
			generateByManageRoute(signPatientManageRoute, patientId);
		}
	}

	/**
	 * 话术json参数替换
	 * @param flowScheme 话术json
	 * @param labelFieldContentList 患者画像信息
	 * @return 替换标签后的话术json
	 */
	@Override
	public String getFlowScheme(String flowScheme, List<LabelFieldInfoContentVo> labelFieldContentList) {
		// 话术库json内容替换
		if (StringUtils.isNotBlank(flowScheme)) {
			// 替换{{}}中的内容
			Pattern pattern = Pattern.compile("#\\{([^\\}]*)\\}");
			Matcher matcher = pattern.matcher(flowScheme);
			while (matcher.find()) {
				//过滤出符合条件的对象，不匹配返回null。
				LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), matcher.group(1))).findFirst().orElse(null);
				if (ObjectUtils.isNotEmpty(labelFieldContent)) {
					flowScheme = flowScheme.replaceAll("#\\{"+matcher.group(1) +"\\}", ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
				}
			}
		}
		return flowScheme;
	}

	/**
	 * * 短信模板内容
	 * @param messageTemplateId 短信模板主键
	 * @param labelFieldContentList 患者画像信息
	 * @return 替换标签后的内容
	 */
	@Override
	public String replaceMessageInfo(Long messageTemplateId, List<LabelFieldInfoContentVo> labelFieldContentList) {
		// 查询短信模板
		TextMessage textMessage = textMessageMapper.selectTextMessageById(messageTemplateId);
		if (ObjectUtils.isNotEmpty(textMessage)) {
			String textMessageContent = textMessage.getTextMessageContent();
			if (StringUtils.isBlank(textMessageContent)) {
				return null;
			}
			// 替换{{}}中的内容
			Pattern pattern = Pattern.compile("#\\{([^\\}]*)\\}");
			Matcher matcher = pattern.matcher(textMessage.getTextMessageContent());
			while (matcher.find()) {
				// 过滤出符合条件的对象，不匹配返回null。
				LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), matcher.group(1))).findFirst().orElse(null);
				if (ObjectUtils.isNotEmpty(labelFieldContent)) {
					textMessageContent = textMessageContent.replaceAll("#\\{"+matcher.group(1) +"\\}", ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
				}
			}
			return textMessageContent;
		}
		return null;
	}

	/**
	 * 替换公众号、小程序模板内容
	 * @param templateId 微信库模板id
	 * @param labelFieldContentList 患者画像信息
	 */
	@Override
	public String replaceWeChatTemplate(Long templateId, List<LabelFieldInfoContentVo> labelFieldContentList) {
		WechatTemplate wechatTemplate = wechatTemplateMapper.selectWechatTemplateById(templateId);
		if (ObjectUtils.isEmpty(wechatTemplate)){
			return null;
		}
		String templateContent = wechatTemplate.getTemplateContent();
		if (StringUtils.isBlank(templateContent)) {
			return null;
		}
		Pattern pattern = Pattern.compile("#\\{([^\\}]*)\\}");
		Matcher matcher = pattern.matcher(templateContent);
		while (matcher.find()) {
			// 过滤出符合条件的对象，不匹配返回null。
			LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), matcher.group(1))).findFirst().orElse(null);
			if (ObjectUtils.isNotEmpty(labelFieldContent)) {
				templateContent = templateContent.replaceAll("#\\{"+matcher.group(1) +"\\}", ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
			}
		}
		return templateContent;
	}

	/**
	 * 替换节点标签内容
	 * @param manageRouteNode 签约管理路径节点
	 * @param taskPartitionDictId 专病节点任务细分
	 * @param labelFieldContentList 患者画像
	 * @return 签约路径节点列表
	 */
	@Override
	public List<SignPatientManageNodeAuditVo> replaceNodeContent(SignPatientManageNodeAuditVo manageRouteNode, Long taskPartitionDictId, List<LabelFieldInfoContentVo> labelFieldContentList) {
		List<SignPatientManageNodeAuditVo> manageNodeList = new ArrayList<>();
		// 过滤掉适用范围为空的字段
		labelFieldContentList.forEach(labelFieldInfoContentVo -> {
			if (StringUtils.isBlank(labelFieldInfoContentVo.getApplyRange())) {
				labelFieldInfoContentVo.setApplyRange(ApplyRangeContant.PUBLIC);
			}
		});
		Map<String, List<LabelFieldInfoContentVo>> groupByRang = labelFieldContentList.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getApplyRange));
		// 筛选应用范围是否有私用的画像
		List<LabelFieldInfoContentVo> privateLabelFields = groupByRang.get(ApplyRangeContant.PRIVATE);
		List<LabelFieldInfoContentVo> publicLabelFields = groupByRang.get(ApplyRangeContant.PUBLIC);

		Map<Long, List<LabelFieldInfoContentVo>> groupByPartition = new HashMap<>();
		List<LabelFieldInfoContentVo> nodeLabelFieldContent = new ArrayList<>();
		// 按照sn进行分组，判断生成几条任务
		if (CollectionUtils.isNotEmpty(privateLabelFields)) {
			groupByPartition = privateLabelFields.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getTaskPartitionDictId));
			nodeLabelFieldContent = groupByPartition.get(taskPartitionDictId);
		}
		if (CollectionUtils.isEmpty(privateLabelFields) || CollectionUtils.isEmpty(nodeLabelFieldContent)) {
			// 都是公有属性，只生成一条任务
			SignPatientManageNodeAuditVo manageNode = new SignPatientManageNodeAuditVo();
			BeanUtils.copyBeanProp(manageNode, manageRouteNode);
			// 替换文本
			Map<String, String> map = publicLabelFields.stream().collect(Collectors.toMap(LabelFieldInfoContentVo::getFieldCode,LabelFieldInfoContentVo::getFieldValue,(key1,key2)->key2));
			Document document = Jsoup.parse(manageNode.getNodeContent());
			// 需要提取的span
			Elements spanlist = document.select("span[data-w-e-type]");
			for (Element span : spanlist) {
				String paramKey = span.attr("data-fieldMark");
				span.text(map.getOrDefault(paramKey, ""));
				span.unwrap();
			}
			manageNode.setNodeContent(document.body().html());
			manageNodeList.add(manageNode);
		} else {
			Map<String, List<LabelFieldInfoContentVo>> groupBySn = nodeLabelFieldContent.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getPortraitSn));

			for (String portraitSn : groupBySn.keySet()) {
				SignPatientManageNodeAuditVo manageNode = new SignPatientManageNodeAuditVo();
				BeanUtils.copyBeanProp(manageNode, manageRouteNode);
				// 替换文本
				List<LabelFieldInfoContentVo> nodeParams = groupBySn.get(portraitSn);
				if (CollectionUtils.isNotEmpty(publicLabelFields)) {
					nodeParams.addAll(publicLabelFields);
				}

				Map<String, String> map = nodeParams.stream().collect(Collectors.toMap(LabelFieldInfoContentVo::getFieldCode,LabelFieldInfoContentVo::getFieldValue,(key1,key2)->key2));
				Document document = Jsoup.parse(manageNode.getNodeContent());
				// 需要提取的span
				Elements spanlist = document.select("span[data-w-e-type]");
				for (Element span : spanlist) {
					String paramKey = span.attr("data-fieldMark");
					span.text(map.getOrDefault(paramKey, ""));
					span.unwrap();
				}
				manageNode.setNodeContent(document.body().html());
				manageNodeList.add(manageNode);
			}
		}

		return manageNodeList;
	}

	/**
	 * 查询触发条件是否满足
	 * @param specialDiseaseRouteId 专病管理路径主键
	 * @param patientId 患者主键
	 * @return 是否满足触发条件，true:满足，false:不满足
	 */
	@Override
	public Boolean getTriggerConditon(Long specialDiseaseRouteId, Long patientId) {
		boolean generateTask = false;
		// 查询患者信息
		PatientAllInfoViewUppercase patientAllInfo = null;
		List<PatientAllInfoViewUppercase> patientAllInfoViewList = patientAllInfoViewMapper.selectPatientAllInfoListViewByPatientId(patientId);
		if (CollectionUtils.isNotEmpty(patientAllInfoViewList)) {
			patientAllInfo = patientAllInfoViewList.get(0);
		}

		// 查询画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientId);

		SpecialDiseaseTriggerCondition triggerConditionQuery = new SpecialDiseaseTriggerCondition();
		triggerConditionQuery.setRouteId(specialDiseaseRouteId);
		List<SpecialDiseaseTriggerCondition> triggerConditionList = triggerConditionMapper.selectSpecialDiseaseTriggerConditionList(triggerConditionQuery);
		// 判断触发条件是否成立
		if (CollectionUtils.isNotEmpty(triggerConditionList)) {
			boolean condition1 = judgeTriggerCondition(triggerConditionList.get(0), patientAllInfo, labelFieldContentList);
			if (condition1) {
				// 条件1成立，继续判断条件2，3
				if (triggerConditionList.size() > 1) {
					boolean condition2 = judgeTriggerCondition(triggerConditionList.get(1), patientAllInfo, labelFieldContentList);
					if (triggerConditionList.size() > 2) { // 有3个条件
						boolean condition3 = judgeTriggerCondition(triggerConditionList.get(2), patientAllInfo, labelFieldContentList);
						switch (triggerConditionList.get(2).getTriggerLogic()) {
							case TriggerLogicConstants.AND:
								generateTask = condition2 && condition3;
								break;
							case TriggerLogicConstants.OR:
								generateTask = condition2 || condition3;
								break;
							default:
								generateTask = condition2 && condition3;
								break;
						}
					} else { // 有两个条件
						generateTask = condition2;
					}
				} else {
					// 只有1个条件且成立，生成任务
					generateTask = true;
				}
			}
		}
		return generateTask;
	}

	/**
	 * 查询手动创建路径触发条件是否满足
	 * @param signPatientManageRouteId 专病管理路径主键
	 * @param patientId 患者主键
	 * @return 是否满足触发条件，true:满足，false:不满足
	 */
	@Override public Boolean getSignTriggerConditon(Long signPatientManageRouteId, Long patientId) {
		// 查询患者信息
		PatientAllInfoViewUppercase patientAllInfo = null;
		List<PatientAllInfoViewUppercase> patientAllInfoViewList = patientAllInfoViewMapper.selectPatientAllInfoListViewByPatientId(patientId);
		if (CollectionUtils.isNotEmpty(patientAllInfoViewList)) {
			patientAllInfo = patientAllInfoViewList.get(0);
		}
		// 查询画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientId);

		boolean generateTask = false;
		SignRouteTriggerCondition signRouteTriggerCondition = new SignRouteTriggerCondition();
		signRouteTriggerCondition.setPatientManageRouteId(signPatientManageRouteId);
		List<SignRouteTriggerCondition> signRouteTriggerConditions = signRouteTriggerConditionMapper.selectSignRouteTriggerConditionList(signRouteTriggerCondition);
		if (CollectionUtils.isNotEmpty(signRouteTriggerConditions)) {
			// 判断条件是否成立
			SpecialDiseaseTriggerCondition triggerCondition = new SpecialDiseaseTriggerCondition();
			BeanUtils.copyBeanProp(triggerCondition, signRouteTriggerConditions.get(0));
			boolean condition1 = judgeTriggerCondition(triggerCondition, patientAllInfo, labelFieldContentList);
			if (condition1) {
				// 条件1成立，继续判断条件2，3
				if (signRouteTriggerConditions.size() > 1) {
					BeanUtils.copyBeanProp(triggerCondition, signRouteTriggerConditions.get(1));
					boolean condition2 = judgeTriggerCondition(triggerCondition, patientAllInfo, labelFieldContentList);
					if (signRouteTriggerConditions.size() > 2) { // 有3个条件
						BeanUtils.copyBeanProp(triggerCondition, signRouteTriggerConditions.get(2));
						boolean condition3 = judgeTriggerCondition(triggerCondition, patientAllInfo, labelFieldContentList);
						switch (signRouteTriggerConditions.get(2).getTriggerLogic()) {
							case TriggerLogicConstants.AND:
								generateTask = condition2 && condition3;
								break;
							case TriggerLogicConstants.OR:
								generateTask = condition2 || condition3;
								break;
							default:
								generateTask = condition2 && condition3;
								break;
						}
					} else { // 有两个条件
						generateTask = condition2;
					}
				} else {
					// 只有1个条件且成立，生成任务
					generateTask = true;
				}
			}
		}
		return generateTask;
	}

	/**
	 * 测试生成患者档案列表数据用
	 */
	@Override public void generateStatistic() {
		// 查询患者
		PatientInfoDto patientInfo = new PatientInfoDto();
		List<PatientInfoVo> patientInfoVoList = patientInfoMapper.getPatientList(patientInfo);
		patientInfoVoList.forEach(patientInfoVo -> {
			PatientInfo patientInfo1 = patientInfoMapper.selectPatientInfoById(patientInfoVo.getId());
			PatientTaskStatistics patientTaskStatistics = new PatientTaskStatistics();
			patientTaskStatistics.setPatientId(patientInfoVo.getId());
			patientTaskStatistics.setSignPatientRecordId(patientInfo1.getSignPatientRecordId());
			patientTaskStatistics.setServiceStatus(patientInfo1.getServiceStatus());
			patientTaskStatistics.setTaskNum(patientInfoVo.getTaskNum());
			patientTaskStatistics.setTaskExecuteNum(patientInfoVo.getTaskExecuteNum());
			patientTaskStatistics.setTaskFinishNum(patientInfoVo.getTaskFinishNum());
			// 下次任务
			PatientNextTaskVo patientNextTask = patientInfoMapper.getPatientNextTask(patientInfoVo.getId());
			if (ObjectUtils.isNotEmpty(patientNextTask)) {
				patientTaskStatistics.setNextTaskName(patientNextTask.getTaskName());
				patientTaskStatistics.setNextTaskTime(patientNextTask.getExecuteDateTime());
			}
			patientTaskStatisticsService.insertPatientTaskStatistics(patientTaskStatistics);
		});
	}

	/**
	 * @description 专病路径修改时修改任务，已经执行的任务不修改，未执行的任务进行删除或修改
	 * @Param routeId 专病路径主键
	 * @return null
	 * @Author haown
	 * @Date 2024-11-15 10:52
	 */
	@Override
	public void updateBySpecialDiseaseRoute(List<Long> delDiseaseNodeIds, List<SpecialDiseaseNodeVO> updateList, List<SpecialDiseaseNodeVO> addDiseaseNodeList) {
		// 删除的路径节点，未执行的任务删除
		if (CollectionUtils.isNotEmpty(delDiseaseNodeIds)) {
			SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
			signPatientManageRouteNodeDto.setRouteNodeIds(delDiseaseNodeIds);
			signPatientManageRouteNodeDto.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
			List<SignPatientManageRouteNode> delNodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
			// 删除任务
			if (CollectionUtils.isNotEmpty(delNodeList)) {
				signPatientManageRouteNodeMapper.deleteSignPatientManageRouteNodeByIds(delNodeList.stream().map(SignPatientManageRouteNode::getId).collect(Collectors.toList()).toArray(new Long[0]));
			}
		}
		// 修改的路径节点，对未执行的任务进行修改
		if (CollectionUtils.isNotEmpty(updateList)) {
			updateList.forEach(diseaseNode -> {
				SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
				signPatientManageRouteNodeDto.setRouteNodeId(diseaseNode.getId());
				signPatientManageRouteNodeDto.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
				List<SignPatientManageRouteNode> updNodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);

				if (CollectionUtils.isNotEmpty(updNodeList)) {
					updNodeList.forEach(manageRouteNode -> {
						SignPatientManageRoute signPatientManageRoute = signRouteMapper.selectSignPatientManageRouteById(manageRouteNode.getManageRouteId());
						// 查询患者画像信息
						List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(signPatientManageRoute.getPatientId());
						if (CollectionUtils.isEmpty(labelFieldContentList)) {
							throw new ServiceException("请先维护画像信息");
						}
						Long id = manageRouteNode.getId();
						BeanUtils.copyBeanProp(manageRouteNode, diseaseNode);
						manageRouteNode.setManageRouteId(signPatientManageRoute.getId());
						manageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
						manageRouteNode.setId(null);
						manageRouteNode.setRouteNodeId(diseaseNode.getId());
						manageRouteNode.setDelFlag(0);

						// 根据模板类型，存放模板字段
						if(StringUtils.isNotBlank(diseaseNode.getTaskNodeType())) {
							switch(diseaseNode.getTaskNodeType()) {
								// 宣教
								case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
									manageRouteNode.setPropagandaInfoId(diseaseNode.getTemplateId());
									manageRouteNode.setPropagandaTitle(diseaseNode.getTemplateName());
									break;
								// 问卷
								case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
									QuestionInfo questionInfo = questionInfoService.selectQuestionInfoById(diseaseNode.getTemplateId());
									manageRouteNode.setQuestionInfoId(diseaseNode.getTemplateId());
									manageRouteNode.setQuestionnaireName(diseaseNode.getTemplateName());
									if (ObjectUtils.isNotEmpty(questionInfo)) {
										manageRouteNode.setScriptInfoId(questionInfo.getScriptInfoId());
										manageRouteNode.setRobotPublishId(questionInfo.getRobotPublishId());
										// 节点是否是AI电话
										if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(questionInfo.getRobotPublishId())) {
											throw new ServiceException("第三方机器人id为空");
										}
									}
									break;
								// 话术
								case TaskNodeTypeConstants.PHONE_OUTBOUND:
									manageRouteNode.setScriptInfoId(diseaseNode.getScriptInfoId());
									// 查询话术
									ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(diseaseNode.getScriptInfoId());
									if (ObjectUtils.isNotEmpty(scriptInfo)) {
										// 话术库json内容替换
										manageRouteNode.setPhoneNodeContent(getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
										manageRouteNode.setRobotPublishId(scriptInfo.getRobotPublishId());
										// 节点是否是AI电话
										if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
											throw new ServiceException("第三方机器人id为空");
										}
									}
									break;
							}
						}
						// 替换短信、公众号、小程序内容
						replaceTemplateInfo(manageRouteNode, diseaseNode, labelFieldContentList);
						// 替换nodeContent
						List<SignPatientManageRouteNode> manageNodeList = new ArrayList<>();
						if (StringUtils.contains(diseaseNode.getNodeContent(), "data-w-e-type")) {
							SignPatientManageNodeAuditVo signPatientManageNodeAuditVo = new SignPatientManageNodeAuditVo();
							BeanUtils.copyBeanProp(signPatientManageNodeAuditVo, manageRouteNode);
							List<SignPatientManageNodeAuditVo> manageNodeAuditVoList = replaceNodeContent(signPatientManageNodeAuditVo, diseaseNode.getTaskPartitionDictId(), labelFieldContentList);
							manageNodeAuditVoList.forEach(manageNodeAuditVo -> {
								SignPatientManageRouteNode signNode = new SignPatientManageRouteNode();
								BeanUtils.copyBeanProp(signNode, manageNodeAuditVo);
								signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signNode);
							});

						} else {
							signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(manageRouteNode);
						}
					});
				}
			});

		}
		// 新增的路径节点，新增未执行任务
		if (CollectionUtils.isNotEmpty(addDiseaseNodeList)) {
			//
			List<SignPatientManageRouteNode> nodeSaveList = new ArrayList();
			addDiseaseNodeList.forEach(diseaseNode -> {
				// 查询签约专病路径的sign_patient_manage_route
				SignPatientManageRoute signPatientManageRoute = new SignPatientManageRoute();
				signPatientManageRoute.setRouteId(diseaseNode.getRouteId());
				List<SignPatientManageRoute> manageRouteList = signRouteMapper.selectSignPatientManageRouteList(signPatientManageRoute);
				// 查询已审核通过的签约记录
				manageRouteList.forEach(manageRoute -> {
					SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(manageRoute.getSignPatientRecordId());
					// 审核通过并且在服务期限内的签约记录
					if (StringUtils.equals(SignRecordServiceStatusConstants.SERVICE_CENTER, signPatientRecord.getServiceStatus()) && StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getPortaitCheckStatus()) && StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getRouteCheckStatus())) {
						// 查询患者画像信息
						List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(signPatientManageRoute.getPatientId());
						if (CollectionUtils.isEmpty(labelFieldContentList)) {
							throw new ServiceException("请先维护画像信息");
						}
						// 生成任务
						SignPatientManageRouteNode manageRouteNode = new SignPatientManageRouteNode();
						BeanUtils.copyBeanProp(manageRouteNode, diseaseNode);
						manageRouteNode.setManageRouteId(signPatientManageRoute.getId());
						manageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
						manageRouteNode.setId(null);
						manageRouteNode.setRouteNodeId(diseaseNode.getId());
						manageRouteNode.setExecuteTime(diseaseNode.getExecutionTime());
						manageRouteNode.setDelFlag(0);
						manageRouteNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
						manageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());

						// 根据模板类型，存放模板字段
						if(StringUtils.isNotBlank(diseaseNode.getTaskNodeType())) {
							switch(diseaseNode.getTaskNodeType()) {
								// 宣教
								case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
									manageRouteNode.setPropagandaInfoId(diseaseNode.getTemplateId());
									manageRouteNode.setPropagandaTitle(diseaseNode.getTemplateName());
									break;
								// 问卷
								case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
									QuestionInfo questionInfo = questionInfoService.selectQuestionInfoById(diseaseNode.getTemplateId());
									manageRouteNode.setQuestionInfoId(diseaseNode.getTemplateId());
									manageRouteNode.setQuestionnaireName(diseaseNode.getTemplateName());
									if (ObjectUtils.isNotEmpty(questionInfo)) {
										manageRouteNode.setScriptInfoId(questionInfo.getScriptInfoId());
										manageRouteNode.setRobotPublishId(questionInfo.getRobotPublishId());
										// 节点是否是AI电话
										if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(questionInfo.getRobotPublishId())) {
											throw new ServiceException("第三方机器人id为空");
										}
									}
									break;
								// 话术
								case TaskNodeTypeConstants.PHONE_OUTBOUND:
									manageRouteNode.setScriptInfoId(diseaseNode.getScriptInfoId());
									// 查询话术
									ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(diseaseNode.getScriptInfoId());
									if (ObjectUtils.isNotEmpty(scriptInfo)) {
										// 话术库json内容替换
										manageRouteNode.setPhoneNodeContent(getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
										manageRouteNode.setRobotPublishId(scriptInfo.getRobotPublishId());
										// 节点是否是AI电话
										if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
											throw new ServiceException("第三方机器人id为空");
										}
									}
									break;
							}
						}
						// 替换短信、公众号、小程序内容
						replaceTemplateInfo(manageRouteNode, diseaseNode, labelFieldContentList);
						// 替换nodeContent
						List<SignPatientManageRouteNode> manageNodeList = new ArrayList<>();
						if (StringUtils.contains(diseaseNode.getNodeContent(), "data-w-e-type")) {
							SignPatientManageNodeAuditVo signPatientManageNodeAuditVo = new SignPatientManageNodeAuditVo();
							BeanUtils.copyBeanProp(signPatientManageNodeAuditVo, manageRouteNode);
							List<SignPatientManageNodeAuditVo> manageNodeAuditVoList = replaceNodeContent(signPatientManageNodeAuditVo, diseaseNode.getTaskPartitionDictId(), labelFieldContentList);
							manageNodeAuditVoList.forEach(manageNodeAuditVo -> {
								SignPatientManageRouteNode signNode = new SignPatientManageRouteNode();
								BeanUtils.copyBeanProp(signNode, manageNodeAuditVo);
								manageNodeList.add(signNode);
							});

						} else {
							manageNodeList.add(manageRouteNode);
						}
						nodeSaveList.addAll(manageNodeList);
					}
				});
			});
			// 保存
			if(CollectionUtils.isNotEmpty(nodeSaveList)) {
				signPatientManageRouteNodeMapper.insertBatch(nodeSaveList);
			}
		}
	}

	/**
	 * 外呼记录
	 *
	 * @param uploadRobotPublishRecordDto 时间信息
	 * @return UploadRobotPublishRecordVo
	 */
	@DataScope(agencyAlias = "pi")
	@Override
	public List<UploadRobotPublishRecordVo> uploadRobotPublishRecord(UploadRobotPublishRecordDto uploadRobotPublishRecordDto) {
		if (Objects.nonNull(uploadRobotPublishRecordDto)){
			uploadRobotPublishRecordDto.setQuestionType(QuestionTypeEnum.FEEDBACK_BLANKS_SUBJECT.getInfo());
		}
        //登录用户科室信息
        SysUser sysUser = sysUserMapper.selectUserById(SecurityUtils.getUserId());
        if (Objects.nonNull(sysUser) && Objects.nonNull(sysUser.getHospitalAgencyId())){
            Agency agency = agencyMapper.selectAgencyById(sysUser.getHospitalAgencyId());
            if (Objects.nonNull(agency) && Objects.nonNull(agency.getId())){
                uploadRobotPublishRecordDto.setHospitalAgencyId(agency.getId());
            }
        }
		List<UploadRobotPublishRecordVo> uploadRobotPublishRecordVos = signPatientManageRouteNodeMapper.selectTaskContented(uploadRobotPublishRecordDto);
		//总分为0设为null
		if(CollectionUtils.isNotEmpty(uploadRobotPublishRecordVos)){
			for (UploadRobotPublishRecordVo uploadRobotPublishRecordVo : uploadRobotPublishRecordVos) {
				if (Objects.nonNull(uploadRobotPublishRecordVo.getTotalScore()) && uploadRobotPublishRecordVo.getTotalScore().compareTo(BigDecimal.ZERO) == 0){
					uploadRobotPublishRecordVo.setTotalScore(null);
				}
			}
		}
		return uploadRobotPublishRecordVos;
	}

	/**
	 * 根据管理路径生成任务
	 * @param signPatientManageRoute 签约管理路径
	 * @param patientId 患者主键
	 */
	private void generateByManageRoute(SignPatientManageRoute signPatientManageRoute, Long patientId) {
		List<SignPatientManageRouteNode> nodeSaveList = new ArrayList<>();
		// 查询路径节点
		SpecialDiseaseNode specialDiseaseNodeQuery = new SpecialDiseaseNode();
		specialDiseaseNodeQuery.setRouteId(signPatientManageRoute.getRouteId());
		List<SpecialDiseaseNodeVO> nodeList = specialDiseaseNodeMapper.selectSpeciaDiseaseNodeVoList(specialDiseaseNodeQuery);
		// 查询患者画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientId);
		if (CollectionUtils.isEmpty(labelFieldContentList)) {
			throw new ServiceException("请先维护画像信息");
		}
		// 组装数据
		nodeList.forEach(node -> {
			SignPatientManageRouteNode manageRouteNode = new SignPatientManageRouteNode();
			BeanUtils.copyBeanProp(manageRouteNode, node);
			manageRouteNode.setManageRouteId(signPatientManageRoute.getId());
			manageRouteNode.setManageRouteName(signPatientManageRoute.getRouteName());
			manageRouteNode.setId(null);
			manageRouteNode.setRouteNodeId(node.getId());
			manageRouteNode.setExecuteTime(node.getExecutionTime());
			manageRouteNode.setDelFlag(0);
			manageRouteNode.setRouteCheckStatus(RouteCheckStatusEnum.AGREE.getInfo());
			manageRouteNode.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());

			// 根据模板类型，存放模板字段
			if(StringUtils.isNotBlank(node.getTaskNodeType())) {
				switch(node.getTaskNodeType()) {
					// 宣教
					case TaskNodeTypeConstants.PROPAGANDA_ARTICLE:
						manageRouteNode.setPropagandaInfoId(node.getTemplateId());
						manageRouteNode.setPropagandaTitle(node.getTemplateName());
						break;
					// 问卷
					case TaskNodeTypeConstants.QUESTIONNAIRE_SCALE:
						QuestionInfo questionInfo = questionInfoService.selectQuestionInfoById(node.getTemplateId());
						manageRouteNode.setQuestionInfoId(node.getTemplateId());
						manageRouteNode.setQuestionnaireName(node.getTemplateName());
						if (ObjectUtils.isNotEmpty(questionInfo)) {
							manageRouteNode.setScriptInfoId(questionInfo.getScriptInfoId());
							manageRouteNode.setRobotPublishId(questionInfo.getRobotPublishId());
							// 节点是否是AI电话
							if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(questionInfo.getRobotPublishId())) {
								throw new ServiceException("第三方机器人id为空");
							}
						}
						break;
					// 话术
					case TaskNodeTypeConstants.PHONE_OUTBOUND:
						manageRouteNode.setScriptInfoId(node.getScriptInfoId());
						// 查询话术
						ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
						if (ObjectUtils.isNotEmpty(scriptInfo)) {
							// 话术库json内容替换
							manageRouteNode.setPhoneNodeContent(getFlowScheme(scriptInfo.getFlowScheme(), labelFieldContentList));
							manageRouteNode.setRobotPublishId(scriptInfo.getRobotPublishId());
							// 节点是否是AI电话
							if (StringUtils.equals(PhoneDialMethodEnum.AI.getInfo(), manageRouteNode.getPhoneDialMethod()) && StringUtils.isBlank(scriptInfo.getRobotPublishId())) {
								throw new ServiceException("第三方机器人id为空");
							}
						}
						break;
				}
			}
			// 替换短信、公众号、小程序内容
			replaceTemplateInfo(manageRouteNode, node, labelFieldContentList);
			// 替换nodeContent
			List<SignPatientManageRouteNode> manageNodeList = new ArrayList<>();
			if (StringUtils.contains(node.getNodeContent(), "data-w-e-type")) {
				SignPatientManageNodeAuditVo signPatientManageNodeAuditVo = new SignPatientManageNodeAuditVo();
				BeanUtils.copyBeanProp(signPatientManageNodeAuditVo, manageRouteNode);
				List<SignPatientManageNodeAuditVo> manageNodeAuditVoList = replaceNodeContent(signPatientManageNodeAuditVo, node.getTaskPartitionDictId(), labelFieldContentList);
				manageNodeAuditVoList.forEach(manageNodeAuditVo -> {
					SignPatientManageRouteNode signNode = new SignPatientManageRouteNode();
					BeanUtils.copyBeanProp(signNode, manageNodeAuditVo);
					manageNodeList.add(signNode);
				});

			} else {
				manageNodeList.add(manageRouteNode);
			}
			nodeSaveList.addAll(manageNodeList);
		});
		// 保存
		if(CollectionUtils.isNotEmpty(nodeSaveList)) {
			signPatientManageRouteNodeMapper.insertBatch(nodeSaveList);

			// 任务统计表中插入数据
			patientTaskStatisticsService.insertOrUpdate(PatientTaskStatistics.builder()
				.signPatientRecordId(signPatientManageRoute.getSignPatientRecordId())
				.patientId(patientId)
				.taskNum(BigDecimal.valueOf(nodeSaveList.size()))
				.taskExecuteNum(BigDecimal.ZERO)
				.taskFinishNum(BigDecimal.ZERO)
				.build());

		}
	}

	private String replaceNodeContent(String nodeContent, List<PatientNodeParamsCurrent> paramsList) {
		Map<String, String> map = paramsList.stream().collect(Collectors.toMap(PatientNodeParamsCurrent::getParamKey,PatientNodeParamsCurrent::getParamValue,(key1,key2)->key2));
		Document document = Jsoup.parse(nodeContent);
		// 需要提取的span
		Elements spanlist = document.select("span[data-w-e-type]");
		for (Element span : spanlist) {
			String paramKey = span.attr("data-fieldMark");
			span.text(map.getOrDefault(paramKey, ""));
			span.unwrap();
		}
		return document.body().html();
	}

	/**
	 * 替换短信、公众号、小程序内容
	 * @param manageRouteNode 签约路径节点
	 * @param node 专病路径节点
	 * @param labelFieldContentList 患者画像信息
	 */
	private void replaceTemplateInfo(SignPatientManageRouteNode manageRouteNode, SpecialDiseaseNode node, List<LabelFieldInfoContentVo> labelFieldContentList) {
		if (node.getMessageTemplateId() != null) {
			// 替换短信模板
			TextMessage textMessage = textMessageMapper.selectTextMessageById(node.getMessageTemplateId());
			if (ObjectUtils.isNotEmpty(textMessage)) {
				manageRouteNode.setMessageTemplateCode(textMessage.getTextMessageId());
				manageRouteNode.setMessageNodeContent(replaceMessageInfo(node.getMessageTemplateId(), labelFieldContentList));
			}
		}
		if (node.getPhoneMessageTemplateId() != null) {
			// 替换短信模板
			manageRouteNode.setPhoneMessageTemplateContent(replaceMessageInfo(node.getPhoneMessageTemplateId(), labelFieldContentList));
		}
		// 替换公众号模板
		if (node.getOfficialPushSign() != null && node.getOfficialPushSign() == 1) {
			WechatTemplate wechatTemplate = wechatTemplateMapper.selectWechatTemplateById(node.getOfficialTemplateId());
			if (ObjectUtils.isNotEmpty(wechatTemplate)) {
				manageRouteNode.setOfficialTemplateCode(wechatTemplate.getTemplateId());
				manageRouteNode.setOfficialNodeContent(replaceWeChatTemplate(node.getOfficialTemplateId(), labelFieldContentList));
			}
		}
		// 替换小程序模板
		if (node.getAppletPushSign() != null && node.getAppletPushSign() == 1) {
			WechatTemplate wechatTemplate = wechatTemplateMapper.selectWechatTemplateById(node.getOfficialTemplateId());
			if (ObjectUtils.isNotEmpty(wechatTemplate)) {
				manageRouteNode.setAppletTemplateCode(wechatTemplate.getTemplateId());
				manageRouteNode.setAppletNodeContent(replaceWeChatTemplate(node.getAppletTemplateId(), labelFieldContentList));
			}
		}
	}

	private boolean judgeTriggerCondition(SpecialDiseaseTriggerCondition triggerCondition, PatientAllInfoViewUppercase patientAllInfo, List<LabelFieldInfoContentVo> labelFieldContentList) {
		List<String> labelValueList = new ArrayList<>();
		String triggerConditionCode = triggerCondition.getTriggerConditionCode().replaceAll("_", "");
		if (ObjectUtils.isNotEmpty(patientAllInfo)) {
			Field[] declaredFields = PatientAllInfoViewUppercase.class.getDeclaredFields();
			List<Field> fieldList = Arrays.stream(declaredFields).collect(Collectors.toList());
			fieldList.forEach(field -> {
				if (StringUtils.equals(field.getName(), triggerConditionCode)) {
					Class<?> clazz = patientAllInfo.getClass();
					field.setAccessible(true);
					// 获取字段的值
					try {
						Object value = field.get(patientAllInfo);
						if (ObjectUtils.isNotEmpty(value)) {
							labelValueList.add(String.valueOf(value));
						}
					} catch (IllegalAccessException e) {
						throw new RuntimeException(e);
					}
				}
			});
		}

		// 查询画像中的信息
		if (CollectionUtils.isNotEmpty(labelFieldContentList)) {
			labelValueList.addAll(labelFieldContentList.stream()
				.filter(content -> StringUtils.equals(content.getFieldCode(), triggerConditionCode))
				.map(LabelFieldInfoContentVo::getFieldValue)
				.collect(Collectors.toList()));
		}

		boolean retBoolean = false;
		if (CollectionUtils.isNotEmpty(labelValueList)) {
			switch (triggerCondition.getTriggerConditionOperator()) {
				case (TriggerConditionOperatorConstants.CONTAIN):
					// 判断labelValue中的内容是否包含triggerConditionValue
					retBoolean = labelValueList.stream().anyMatch(labelValue -> StringUtils.containsIgnoreCase(labelValue, triggerCondition.getTriggerConditionValue()));
					break;
				case (TriggerConditionOperatorConstants.NOT_CONTAIN):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> !StringUtils.containsIgnoreCase(labelValue, triggerCondition.getTriggerConditionValue()));
					break;
				case (TriggerConditionOperatorConstants.EQUAL_TO):
				case (TriggerConditionOperatorConstants.EQUAL):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> StringUtils.equalsIgnoreCase(labelValue, triggerCondition.getTriggerConditionValue()));
					break;
				case (TriggerConditionOperatorConstants.NOT_EQUAL_TO):
				case (TriggerConditionOperatorConstants.NOT_EQUAL):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> !StringUtils.equalsIgnoreCase(labelValue, triggerCondition.getTriggerConditionValue()));
					break;

				case (TriggerConditionOperatorConstants.GREATER_THAN_OR_EQUAL):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> new BigDecimal(labelValue).compareTo(new BigDecimal(triggerCondition.getTriggerConditionValue())) >= 0);
					break;
				case (TriggerConditionOperatorConstants.GREATER_THAN):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> new BigDecimal(labelValue).compareTo(new BigDecimal(triggerCondition.getTriggerConditionValue())) > 0);
					break;
				case (TriggerConditionOperatorConstants.LESS_THAN):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> new BigDecimal(labelValue).compareTo(new BigDecimal(triggerCondition.getTriggerConditionValue())) < 0);
					break;
				case (TriggerConditionOperatorConstants.LESS_THAN_OR_EQUAL):
					retBoolean = labelValueList.stream().anyMatch(labelValue -> new BigDecimal(labelValue).compareTo(new BigDecimal(triggerCondition.getTriggerConditionValue())) <= 0);
					break;
			}
		}
		return retBoolean;
	}

}
