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

import com.alibaba.fastjson2.JSONObject;
import com.xinelu.common.annotation.DataScope;
import com.xinelu.common.constant.ApplyRangeContant;
import com.xinelu.common.constant.SignRecordServiceStatusConstants;
import com.xinelu.common.constant.TaskCreateTypeConstant;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.RouteCheckStatusEnum;
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.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientnodeparamscurrent.PatientNodeParamsCurrent;
import com.xinelu.manage.domain.patientnodeparamslog.PatientNodeParamsLog;
import com.xinelu.manage.domain.signpatientinformed.SignPatientInformed;
import com.xinelu.manage.domain.signpatientmanageroute.SignPatientManageRoute;
import com.xinelu.manage.domain.signpatientmanageroutenode.SignPatientManageRouteNode;
import com.xinelu.manage.domain.signpatientpackage.SignPatientPackage;
import com.xinelu.manage.domain.signpatientpackagehardware.SignPatientPackageHardware;
import com.xinelu.manage.domain.signpatientrecord.SignPatientRecord;
import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute;
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
import com.xinelu.manage.dto.signpatientpackage.SignPatientPackageSaveDto;
import com.xinelu.manage.dto.signpatientrecord.IntentionalSignDto;
import com.xinelu.manage.dto.signpatientrecord.PortaitCheckDto;
import com.xinelu.manage.dto.signpatientrecord.RouteCheckDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientAddDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientListDto;
import com.xinelu.manage.dto.signpatientrecord.SignPatientStatusDto;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientnodeparamslcurrent.PatientNodeParamsCurrentMapper;
import com.xinelu.manage.mapper.patientnodeparamslog.PatientNodeParamsLogMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.signpatientinformed.SignPatientInformedMapper;
import com.xinelu.manage.mapper.signpatientmanageroute.SignPatientManageRouteMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.mapper.signpatientpackage.SignPatientPackageMapper;
import com.xinelu.manage.mapper.signpatientpackagehardware.SignPatientPackageHardwareMapper;
import com.xinelu.manage.mapper.signpatientrecord.SignPatientRecordMapper;
import com.xinelu.manage.mapper.specialdiseasenode.SpecialDiseaseNodeMapper;
import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper;
import com.xinelu.manage.service.labelfieldcontent.ILabelFieldContentService;
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
import com.xinelu.manage.service.signpatientrecord.ISignPatientRecordService;
import com.xinelu.manage.vo.labelfieldcontent.LabelField;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import com.xinelu.manage.vo.patientinfo.PatientPortaitVo;
import com.xinelu.manage.vo.signpatientrecord.IntentionalSignVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientInfoVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientListVo;
import com.xinelu.manage.vo.signpatientrecord.SignPatientRecordVo;
import com.xinelu.manage.vo.specialdiseasenode.RouteTaskAuditVo;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;
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;
import org.springframework.util.CollectionUtils;

/**
* @author haown
* @description 针对表【sign_patient_record(签约记录表)】的数据库操作Service实现
* @createDate 2024-02-28 15:05:02
*/
@Service
public class SignPatientRecordServiceImpl implements ISignPatientRecordService {

	@Resource
	private SignPatientRecordMapper signPatientRecordMapper;
	@Resource
	private SignPatientPackageMapper signPatientPackageMapper;
	@Resource
	private SignPatientPackageHardwareMapper hardwareMapper;
	@Resource
	private SignPatientInformedMapper informedMapper;
	@Resource
	private PatientInfoMapper patientInfoMapper;
	@Resource
	private SignPatientPackageHardwareMapper signPatientPackageHardwareMapper;
	@Resource
	private SignPatientInformedMapper signPatientInformedMapper;
	@Resource
	private SpecialDiseaseRouteMapper specialDiseaseRouteMapper;
	@Resource
	private SignPatientManageRouteMapper signPatientManageRouteMapper;
	@Resource
	private SpecialDiseaseNodeMapper specialDiseaseNodeMapper;
	@Resource
	private SignPatientManageRouteNodeMapper manageRouteNodeMapper;
	@Resource
	private PatientNodeParamsCurrentMapper patientNodeParamsCurrentMapper;
	@Resource
	private PatientNodeParamsLogMapper patientNodeParamsLogMapper;
	@Resource
	private ISignPatientManageRouteNodeService signPatientManageRouteNodeService;
	@Resource
	private LabelFieldContentMapper labelFieldContentMapper;
	@Resource
	private ILabelFieldContentService labelFieldContentService;
	@Resource
	private PatientVisitRecordMapper patientVisitRecordMapper;

	@Override
	@DataScope(agencyAlias = "sign", deptAlias = "sign", userAlias = "sign.billing_doctor_id")
	public List<SignPatientListVo> selectList(SignPatientListDto signPatientRecord) {
		return signPatientRecordMapper.selectList(signPatientRecord);
	}

	@Override public SignPatientInfoVo getByRecordId(Long id) {
		// 查询签约信息、签约服务包、签约路径
		SignPatientInfoVo signPatientInfoVo = signPatientRecordMapper.getByRecordId(id);
		// 根据签约记录主键查询设备列表
		SignPatientPackageHardware queryDevice = new SignPatientPackageHardware();
		queryDevice.setSignPatientRecordId(id);
		List<SignPatientPackageHardware> devices = signPatientPackageHardwareMapper.selectSignPatientPackageHardwareList(queryDevice);
		signPatientInfoVo.setSignDevices(devices);
		// 签约知情同意书
		SignPatientInformed signPatientInformed = new SignPatientInformed();
		signPatientInformed.setSignPatientRecordId(id);
		List<SignPatientInformed> informeds = signPatientInformedMapper.selectSignPatientInformedList(signPatientInformed);
		signPatientInfoVo.setSignPatientInformeds(informeds);
		return signPatientInfoVo;
	}

	@Override public List<SignPatientRecordVo> getByPatient(Long patientId) {
		return signPatientRecordMapper.getByPatient(patientId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int add(SignPatientAddDto body) {
		SignPatientPackageSaveDto signPatientPackageDto = body.getSignPackage();
		if (ObjectUtils.isEmpty(signPatientPackageDto)) {
			throw new ServiceException("请选择服务包");
		}
		if (signPatientPackageDto.getServicePackageId() == null) {
			throw new ServiceException("请选择服务包");
		}
		if (ObjectUtils.isNotEmpty(body.getRecord())) {
			SignPatientRecord signPatientRecord = body.getRecord();
			if (signPatientRecord.getPatientId() == null) {
				throw new ServiceException("请选择签约居民");
			}
			PatientInfo patient = patientInfoMapper.selectPatientInfoById(signPatientRecord.getPatientId());
			if (ObjectUtils.isEmpty(patient)) {
				throw new ServiceException("请选择签约居民");
			}
			signPatientRecord.setServiceStatus(SignRecordServiceStatusConstants.SERVICE_CENTER);
			signPatientRecord.setDelFlag(0);
			signPatientRecord.setPaymentStatus(signPatientPackageDto.getPackagePaymentStatus());
			signPatientRecord.setSignTime(LocalDateTime.now());
			signPatientRecord.setSignStatus(SignRecordServiceStatusConstants.IN_SIGN);
			signPatientRecord.setPrice(signPatientPackageDto.getPackagePrice());
			signPatientRecord.setCreateTime(LocalDateTime.now());
			signPatientRecord.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
			// 保存签约记录
			int flag;
			if (StringUtils.equals("sign", body.getSignCategory())) { // 签约，修改意向签约记录状态
				signPatientRecord.setId(patient.getSignPatientRecordId());
				flag = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
			} else {
				signPatientRecord.setId(null);
				signPatientRecord.setPatientVisitRecordId(patient.getPatientVisitRecordId());
				flag = signPatientRecordMapper.insert(signPatientRecord);
			}
			// 签约信息保存到患者表
			patient.setSignPatientRecordId(signPatientRecord.getId());
			patient.setSignStatus(SignRecordServiceStatusConstants.IN_SIGN);
			patient.setServiceStatus(SignRecordServiceStatusConstants.SERVICE_CENTER);
			patient.setSignTime(LocalDateTime.now());
			patientInfoMapper.updatePatientInfoSelective(patient);
			if (flag > 0) {
				// 保存签约服务包信息
				SignPatientPackage signPatientPackage = new SignPatientPackage();

				// 服务开始时间、服务结束时间
				BeanUtils.copyBeanProp(signPatientPackage, signPatientPackageDto);
				signPatientPackage.setSignPatientRecordId(signPatientRecord.getId());
				signPatientPackage.setPatientId(signPatientRecord.getPatientId());
				signPatientPackage.setServiceStartTime(signPatientPackageDto.getServiceStartTime().atStartOfDay());
				signPatientPackage.setServiceEndTime(signPatientPackageDto.getServiceEndTime().atTime(23,59,59));
				signPatientPackage.setCreateTime(LocalDateTime.now());
				signPatientPackage.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
				signPatientPackageMapper.insertSignPatientPackage(signPatientPackage);
				if (ObjectUtils.isEmpty(body.getRoute()) || body.getRoute().getRouteId() == null) {
					throw new ServiceException("请选择管理路径");
				}
				// 保存管理路径
				SignPatientManageRoute signPatientManageRoute = body.getRoute();
				SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(signPatientManageRoute.getRouteId());
				BeanUtils.copyBeanProp(signPatientManageRoute, specialDiseaseRoute);
				signPatientManageRoute.setSignPatientRecordId(signPatientRecord.getId());
				signPatientManageRoute.setPatientId(patient.getId());
				signPatientManageRoute.setPatientName(patient.getPatientName());
				signPatientManageRoute.setId(null);
				signPatientManageRoute.setRouteId(specialDiseaseRoute.getId());
				signPatientManageRoute.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
				signPatientManageRoute.setParentRouteId(0L);
				signPatientManageRoute.setCreateTime(LocalDateTime.now());
				signPatientManageRoute.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
				signPatientManageRouteMapper.insertSignPatientManageRoute(signPatientManageRoute);

				// 保存硬件
				if (!CollectionUtils.isEmpty(body.getDevices())) {
					for(SignPatientPackageHardware hardware : body.getDevices()) {
						hardware.setSignPatientRecordId(signPatientRecord.getId());
						hardwareMapper.insertSignPatientPackageHardware(hardware);
					}
				}

				// 保存告知书
				if (!CollectionUtils.isEmpty(body.getInformeds())) {
					for (SignPatientInformed informed : body.getInformeds()) {
						informed.setSignPatientRecordId(signPatientRecord.getId());
						informed.setPatientId(signPatientRecord.getPatientId());
						informedMapper.insertSignPatientInformed(informed);
					}
				}
			}
			return flag;
		}
		return 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int edit(SignPatientAddDto body) {
		SignPatientPackageSaveDto signPatientPackageDto = body.getSignPackage();
		if (ObjectUtils.isEmpty(signPatientPackageDto) || signPatientPackageDto.getServicePackageId() == null) {
			throw new ServiceException("请选择服务包");
		}
		SignPatientRecord record = body.getRecord();
		if (record.getId() == null) {
			throw new ServiceException("数据传输错误");
		}
		SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(record.getId());
		BeanUtils.copyBeanProp(signPatientRecord, record);
		// 修改签约记录表
		int flag = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
		if (flag > 0) {
			// 修改签约服务包信息
			SignPatientPackage signPatientPackage = new SignPatientPackage();
			// 服务开始时间、服务结束时间
			BeanUtils.copyBeanProp(signPatientPackage, signPatientPackageDto);
			signPatientPackage.setSignPatientRecordId(signPatientRecord.getId());
			signPatientPackage.setPatientId(signPatientRecord.getPatientId());
			signPatientPackage.setServiceStartTime(signPatientPackageDto.getServiceStartTime().atStartOfDay());
			signPatientPackage.setServiceEndTime(signPatientPackageDto.getServiceEndTime().atTime(23,59,59));
			signPatientPackage.setUpdateTime(LocalDateTime.now());
			signPatientPackage.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
			signPatientPackageMapper.updateSignPatientPackage(signPatientPackage);

			if (ObjectUtils.isEmpty(body.getRoute()) || body.getRoute().getRouteId() == null) {
				throw new ServiceException("请选择管理路径");
			}
			// 修改签约路径信息,判断签约路径是否修改，修改：删除未执行的任务、路径审核状态改为未审核，未修改：不做处理
			SignPatientManageRoute signRouteQuery = new SignPatientManageRoute();
			signRouteQuery.setSignPatientRecordId(record.getId());
			signRouteQuery.setTaskCreateType(TaskCreateTypeConstant.MANUAL_MATCHE);
			List<SignPatientManageRoute> signPatientManageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(signRouteQuery);
			if (!CollectionUtils.isEmpty(signPatientManageRouteList) && Objects.equals(signPatientManageRouteList.get(0).getRouteId(), body.getRoute().getRouteId())) {

			} else {
				SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
				signPatientManageRouteNodeDto.setManageRouteId(signPatientManageRouteList.get(0).getId());
				List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeService.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
				if (!CollectionUtils.isEmpty(nodeList)) {
					// 删除未执行的任务
					List<Long> ids = nodeList.stream()
						.filter(node -> !StringUtils.equals(NodeExecuteStatusEnum.EXECUTED.getInfo(), node.getNodeExecuteStatus()))
						.map(SignPatientManageRouteNode::getId).collect(Collectors.toList());
					signPatientManageRouteNodeService.deleteSignPatientManageRouteNodeByIds(ids.toArray(new Long[0]));

					// 路径改为未审核
					signPatientRecord.setRouteCheckStatus(null);
					signPatientRecord.setRouteCheckDate(null);
					signPatientRecord.setRouteCheckPerson(null);
					signPatientRecord.setRouteCheckRemark(null);
					signPatientRecordMapper.updateByPrimaryKey(signPatientRecord);
				}
			}
			// 修改硬件
			if (!CollectionUtils.isEmpty(body.getDevices())) {
				SignPatientPackageHardware signPatientPackageHardware = new SignPatientPackageHardware();
				signPatientPackageHardware.setSignPatientRecordId(signPatientRecord.getId());
				List<SignPatientPackageHardware> hardwareList = hardwareMapper.selectSignPatientPackageHardwareList(signPatientPackageHardware);
				if (!CollectionUtils.isEmpty(hardwareList)) {
					List<Long> hardwareIds = hardwareList.stream().map(SignPatientPackageHardware::getId).collect(Collectors.toList());
					hardwareMapper.deleteSignPatientPackageHardwareByIds(hardwareIds.toArray(new Long[0]));
				}
				for(SignPatientPackageHardware hardware : body.getDevices()) {
					hardware.setSignPatientRecordId(signPatientRecord.getId());
					hardwareMapper.insertSignPatientPackageHardware(hardware);
				}
			}

			// 修改告知书
			if (!CollectionUtils.isEmpty(body.getInformeds())) {
				SignPatientInformed signPatientInformed = new SignPatientInformed();
				signPatientInformed.setSignPatientRecordId(signPatientRecord.getId());
				List<SignPatientInformed> signPatientInformedList = informedMapper.selectSignPatientInformedList(signPatientInformed);
				if (!CollectionUtils.isEmpty(signPatientInformedList)) {
					List<Long> informedIds = signPatientInformedList.stream().map(SignPatientInformed::getId).collect(Collectors.toList());
					informedMapper.deleteSignPatientInformedByIds(informedIds.toArray(new Long[0]));
				}
				for (SignPatientInformed informed : body.getInformeds()) {
					informed.setSignPatientRecordId(signPatientRecord.getId());
					informed.setPatientId(signPatientRecord.getPatientId());
					informedMapper.insertSignPatientInformed(informed);
				}
			}
		}
		return flag;
	}

	@Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSignStatus(SignPatientStatusDto patientCancelSignDto) {
        if (patientCancelSignDto.getPatientId() == null) {
            throw new ServiceException("居民主键不能为空");
        }
        // 修改签约记录状态
        SignPatientRecord signRecord = new SignPatientRecord();
        signRecord.setId(patientCancelSignDto.getId());
        signRecord.setSignStatus(patientCancelSignDto.getSignStatus());
        signRecord.setServiceStatus(patientCancelSignDto.getServiceStatus());
        signRecord.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        signRecord.setUpdateTime(LocalDateTime.now());
        signRecord.setSeparateReason(patientCancelSignDto.getSeparateReason());
        if (StringUtils.equals(SignRecordServiceStatusConstants.SEPARATE_SIGN, patientCancelSignDto.getSignStatus())) {

			PatientInfo patient = patientInfoMapper.selectPatientInfoById(patientCancelSignDto.getPatientId());
			// 签约信息保存到患者表
			patient.setSignStatus(patientCancelSignDto.getSignStatus());
			patient.setServiceStatus(patientCancelSignDto.getServiceStatus());
			patientInfoMapper.updatePatientInfoSelective(patient);

			// 删除patient_node_params_current、patient_node_params_log
	        // 查询signPatientManageRoute
	        SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
	        manageRouteQuery.setSignPatientRecordId(patientCancelSignDto.getId());
	        List<SignPatientManageRoute> manageRouteList = signPatientManageRouteMapper.selectSignPatientManageRouteList(manageRouteQuery);
	        List<Long> logDelIds = new ArrayList<>();
			List<Long> nodeDelIds = new ArrayList<>();
			for (SignPatientManageRoute manageRoute : manageRouteList) {
				// 删除patient_node_params_log
				PatientNodeParamsLog paramsLogQuery = new PatientNodeParamsLog();
				paramsLogQuery.setRouteId(manageRoute.getRouteId());
				List<PatientNodeParamsLog> paramsLogList = patientNodeParamsLogMapper.selectPatientNodeParamsLogList(paramsLogQuery);
				List<Long> logIds = paramsLogList.stream().map(PatientNodeParamsLog::getId).collect(Collectors.toList());
				logDelIds.addAll(logIds);

				// 未执行的任务删除
				SignPatientManageRouteNodeDto manageRouteNodeDto = new SignPatientManageRouteNodeDto();
				manageRouteNodeDto.setManageRouteId(manageRoute.getId());
				manageRouteNodeDto.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
				List<SignPatientManageRouteNode> manageNodeList = manageRouteNodeMapper.selectSignPatientManageRouteNodeList(manageRouteNodeDto);
				List<Long> nodeIds = manageNodeList.stream().map(SignPatientManageRouteNode::getId).collect(Collectors.toList());
				nodeDelIds.addAll(nodeIds);
			}
			if (!CollectionUtils.isEmpty(logDelIds)) {
				patientNodeParamsLogMapper.deletePatientNodeParamsLogByIds(logDelIds.stream().toArray(Long[]::new));
			}
			if (!CollectionUtils.isEmpty(nodeDelIds)) {
				manageRouteNodeMapper.deleteSignPatientManageRouteNodeByIds(nodeDelIds.stream().toArray(Long[]::new));
			}

		}
		return signPatientRecordMapper.updateByPrimaryKeySelective(signRecord);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int intentionalSign(IntentionalSignDto intentionalSignDto) {
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(intentionalSignDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("未找到该居民");
		}
		// 查询当前居民签约状态是否已意向签约
		if (StringUtils.equals(SignRecordServiceStatusConstants.INTENTIONAL_SIGNING, patientInfo.getServiceStatus())) {
			throw new ServiceException("该居民已意向签约!");
		}
		// 查询当前居民签约状态是否已签约
		if (StringUtils.equals(SignRecordServiceStatusConstants.SERVICE_CENTER, patientInfo.getServiceStatus())) {
			throw new ServiceException("该居民已签约!");
		}

		patientInfo.setServiceStatus(SignRecordServiceStatusConstants.INTENTIONAL_SIGNING);
		SignPatientRecord signRecord = new SignPatientRecord();
		// 患者信息保存到签约表
		BeanUtils.copyBeanProp(signRecord, patientInfo);
		signRecord.setSignDiagnosis(patientInfo.getMainDiagnosis());
		signRecord.setBillingDoctorId(intentionalSignDto.getBillingDoctorId());
		signRecord.setBillingDoctorName(intentionalSignDto.getBillingDoctorName());
		signRecord.setIntentionalSource(intentionalSignDto.getIntentionalSource());
		signRecord.setIntentionalTime(LocalDateTime.now());
		signRecord.setPatientId(patientInfo.getId());
		signRecord.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
		signRecord.setCreateTime(LocalDateTime.now());
		signRecord.setId(null);
		int flag = signPatientRecordMapper.insertSelective(signRecord);
		if (flag > 0) {
			patientInfo.setSignPatientRecordId(signRecord.getId());
			patientInfoMapper.updatePatientInfoSelective(patientInfo);
		}
		return flag;
	}

	@Override public IntentionalSignVo getIntentionalSign(Long id) {
		return signPatientRecordMapper.getIntentionalSign(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateIntentionalSign(IntentionalSignDto intentionalSignDto) {
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(intentionalSignDto.getPatientId());
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("未找到该居民");
		}

		patientInfo.setServiceStatus(SignRecordServiceStatusConstants.INTENTIONAL_SIGNING);
		SignPatientRecord signRecord = new SignPatientRecord();
		signRecord.setId(patientInfo.getSignPatientRecordId());
		// 患者信息保存到签约表
		signRecord.setBillingDoctorId(intentionalSignDto.getBillingDoctorId());
		signRecord.setBillingDoctorName(intentionalSignDto.getBillingDoctorName());
		signRecord.setIntentionalSource(intentionalSignDto.getIntentionalSource());
		signRecord.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
		signRecord.setUpdateTime(LocalDateTime.now());
		signRecord.setId(signRecord.getId());
		int flag = signPatientRecordMapper.updateByPrimaryKeySelective(signRecord);
		if (flag > 0) {
			patientInfo.setSignPatientRecordId(signRecord.getId());
			patientInfoMapper.updatePatientInfoSelective(patientInfo);
		}
		return flag;
	}

	/**
	 * @description 撤销意向签约
	 * @param patientId 患者主键
	 * @return 结果
	 * @Author haown
	 * @Date 2024-08-07 11:16
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int cancelIntentionalSign(Long patientId) {
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientId);
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("未找到该居民");
		}
		patientInfo.setServiceStatus(null);
		// 删除签约记录
		signPatientRecordMapper.deleteByPrimaryKey(patientInfo.getSignPatientRecordId());
		// 患者信息表设置最新一条签约记录id
		List<SignPatientRecordVo> signPatientRecords = signPatientRecordMapper.getByPatient(patientId);
		if (CollectionUtils.isEmpty(signPatientRecords)) {
			patientInfo.setSignPatientRecordId(null);
		} else {
			patientInfo.setSignPatientRecordId(signPatientRecords.get(0).getId());
		}
		return patientInfoMapper.updatePatientInfo(patientInfo);
	}

	/**
	 * 任务审核页面左侧画像信息
	 * @param patientId 患者主键
	 */
	@Override
	public PatientPortaitVo getPortaitInfo(Long patientId) {
		// 查询患者诊断信息、手术信息
		PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(patientId);
		if (ObjectUtils.isEmpty(patientInfo)) {
			throw new ServiceException("数据有误，未找到该患者");
		}
		List<JSONObject> drugInfo = new ArrayList<>();
		List<JSONObject> consultationInfo = new ArrayList<>();
		// 查询画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientId);

		if (!CollectionUtils.isEmpty(labelFieldContentList)) {
			// 按照任务细分分组
			Map<Long, List<LabelFieldInfoContentVo>> groupByPartition = labelFieldContentList.stream()
				.filter(labelField-> ObjectUtils.isNotEmpty(labelField.getTaskPartitionDictId()))
				.collect(Collectors.groupingBy(LabelFieldInfoContentVo::getTaskPartitionDictId));
			// 查询用药
			List<LabelFieldInfoContentVo> drugList = labelFieldContentList.stream().filter(labelField->labelField.getFieldCode().equals("DRUGNAME") && StringUtils.isNotBlank(labelField.getFieldValue())).collect(Collectors.toList());
			// 包含用药的标签列表
			List<LabelFieldInfoContentVo> drugLabelList = new ArrayList<>();
			for (LabelFieldInfoContentVo drugName : drugList) {
				drugLabelList.addAll(groupByPartition.get(drugName.getTaskPartitionDictId()));
			}
			// 按照sn分组，每个分组是一个用药
			if (!CollectionUtils.isEmpty(drugLabelList)) {
				Map<String, List<LabelFieldInfoContentVo>> patientDrugList = drugLabelList.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getPortraitSn));
				for (String sn : patientDrugList.keySet()) {
					List<LabelFieldInfoContentVo> propertyList = patientDrugList.get(sn);
					JSONObject drug = new JSONObject();
					propertyList.forEach(property-> {
						drug.fluentPut(property.getFieldCode(), property.getFieldValue());
					});
					drugInfo.add(drug);
				}
			}

			// 查询复诊日期
			List<LabelFieldInfoContentVo> consultationList = labelFieldContentList.stream().filter(labelField->labelField.getFieldCode().equals("CONSULTATIONDATE")).collect(Collectors.toList());
			Map<Long, List<LabelFieldInfoContentVo>> groupByPartitionDictId = consultationList.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getTaskPartitionDictId));
			// 包含复诊的标签列表
			List<LabelFieldInfoContentVo> consultationLabelList = new ArrayList<>();
			for (Long taskPartitionDictId : groupByPartitionDictId.keySet()) {
				consultationLabelList.addAll(groupByPartition.get(taskPartitionDictId));
			}
			// 按照sn分组，每个分组是一个复诊
			if (!CollectionUtils.isEmpty(consultationLabelList)) {
				Map<String, List<LabelFieldInfoContentVo>> patientConsultationList = consultationLabelList.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getPortraitSn));
				for (String sn : patientConsultationList.keySet()) {
					List<LabelFieldInfoContentVo> propertyList = patientConsultationList.get(sn);
					JSONObject consultation = new JSONObject();
					propertyList.forEach(property-> {
						consultation.fluentPut(property.getFieldCode(), property.getFieldValue());
					});
					consultationInfo.add(consultation);
				}
			}
		}

		return PatientPortaitVo.builder().patientName(patientInfo.getPatientName())
			.birthDate(patientInfo.getBirthDate())
			.sex(patientInfo.getSex())
			.visitMethod(patientInfo.getVisitMethod())
			.patientSource(patientInfo.getPatientSource())
			.mainDiagnosis(patientInfo.getMainDiagnosis())
			.surgicalName(patientInfo.getSurgicalName())
			.drugInfo(drugInfo)
			.consultationInfo(consultationInfo).build();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updatePortaitCheckStatus(PortaitCheckDto portaitCheckDto) {
		// 画像信息保存
		if (StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), portaitCheckDto.getPortaitCheckStatus())) {
			LabelField labelField = new LabelField();
			labelField.setLabelFieldAndPartitionDictList(portaitCheckDto.getLabelFieldAndPartitionDictList());
			labelFieldContentService.insertLabelField(labelField);
		}

		// 修改签约记录
		SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(portaitCheckDto.getSignPatientRecordId());
		if (ObjectUtils.isEmpty(signPatientRecord)) {
			throw new ServiceException("未找到该签约记录");
		}
		// 画像信息保存到路径参数表
		if (StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), portaitCheckDto.getPortaitCheckStatus())) {
			saveNodeParams(signPatientRecord);
		}

		signPatientRecord.setPortaitCheckStatus(portaitCheckDto.getPortaitCheckStatus());
		signPatientRecord.setPortaitCheckRemark(portaitCheckDto.getPortaitCheckRemark());
		signPatientRecord.setPortaitCheckDate(LocalDateTime.now());
		signPatientRecord.setPortaitCheckPerson(SecurityUtils.getLoginUser().getUser().getNickName());
		int flag = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
		if (StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getRouteCheckStatus()) && StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getPortaitCheckStatus())) {
			// 路径、画像都审核通过则生成主路径任务
			signPatientManageRouteNodeService.generateMainRouteTask(portaitCheckDto.getSignPatientRecordId());
			// 替换手动生成的任务中的标签
			signPatientManageRouteNodeService.manualCreateTaskLabelReplace(portaitCheckDto.getSignPatientRecordId());
		}

		return flag;
	}

	@Override
	@Transactional
	public int updateRouteCheckStatus(RouteCheckDto routeCheckDto) {
		SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(routeCheckDto.getSignPatientRecordId());
		if (ObjectUtils.isEmpty(signPatientRecord)) {
			throw new ServiceException("未找到该签约记录");
		}
		signPatientRecord.setRouteCheckStatus(routeCheckDto.getRouteCheckStatus());
		signPatientRecord.setRouteCheckRemark(routeCheckDto.getRouteCheckRemark());
		signPatientRecord.setRouteCheckDate(LocalDateTime.now());
		signPatientRecord.setRouteCheckPerson(SecurityUtils.getLoginUser().getUser().getNickName());
		int flag = signPatientRecordMapper.updateByPrimaryKeySelective(signPatientRecord);
		if (StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getRouteCheckStatus()) && StringUtils.equals(RouteCheckStatusEnum.AGREE.getInfo(), signPatientRecord.getPortaitCheckStatus())) {
			// 路径、画像都审核通过则生成主路径任务
			signPatientManageRouteNodeService.generateMainRouteTask(routeCheckDto.getSignPatientRecordId());
			// 替换手动生成的任务中的标签
			signPatientManageRouteNodeService.manualCreateTaskLabelReplace(routeCheckDto.getSignPatientRecordId());
		}
		return flag;
	}

	/**
	 * 画像信息保存到路径参数表
	 * @param signPatientRecord 签约记录信息
	 */
	private void saveNodeParams(SignPatientRecord signPatientRecord) {
		// 画像信息保存到路径参数表
		SignPatientManageRoute manageRouteQuery = new SignPatientManageRoute();
		manageRouteQuery.setSignPatientRecordId(signPatientRecord.getId());
		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 = specialDiseaseNodeMapper.getByParentRouteId(signPatientManageRoute.getRouteId());
		List<PatientNodeParamsCurrent> paramsCurrentList = new ArrayList<>();
		List<PatientNodeParamsLog> paramsLogList = new ArrayList<>();

		// 查询画像信息
		List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(signPatientRecord.getPatientId());
		if (!CollectionUtils.isEmpty(labelFieldContentList)) {
			// 按照公共私用分组
			Map<String, List<LabelFieldInfoContentVo>> groupByRang = labelFieldContentList.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getApplyRange));
			// 筛选应用范围是否有私用的画像
			List<LabelFieldInfoContentVo> privateLabelFields = groupByRang.getOrDefault(ApplyRangeContant.PRIVATE, new ArrayList<>());
			List<LabelFieldInfoContentVo> publicLabelFields = groupByRang.getOrDefault(ApplyRangeContant.PUBLIC, new ArrayList<>());

			nodeList.forEach(node -> {
				if (StringUtils.contains(node.getNodeContent(), "data-w-e-type")) {
					boolean hasPrivate = false;
					List<LabelFieldInfoContentVo> nodeLabelFields = new ArrayList<>();
					if (StringUtils.isNotBlank(node.getNodeContent()) && StringUtils.contains("data-w-e-type", node.getNodeContent())) {
						if (!CollectionUtils.isEmpty(privateLabelFields)) {
							Map<Long, List<LabelFieldInfoContentVo>> groupByPartition = privateLabelFields.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getTaskPartitionDictId));
							nodeLabelFields = groupByPartition.get(node.getTaskPartitionDictId());
							if (!CollectionUtils.isEmpty(nodeLabelFields)) {
								hasPrivate = true;
							}
						}
					}
					if (hasPrivate) {
						// 从公共和私有查询标签
						Map<String, List<LabelFieldInfoContentVo>> groupBySn = nodeLabelFields.stream().collect(Collectors.groupingBy(LabelFieldInfoContentVo::getPortraitSn));
						// 查询node中的标签
						if (!CollectionUtils.isEmpty(publicLabelFields)) {
							Document document = Jsoup.parse(node.getNodeContent());
							// 需要提取的span
							Elements spanlist = document.select("span[data-w-e-type]");
							for(String sn : groupBySn.keySet()) {
								List<LabelFieldInfoContentVo> snLabelField = groupBySn.get(sn);
								snLabelField.addAll(publicLabelFields);
								Map<String, LabelFieldInfoContentVo> map = snLabelField.stream().collect(Collectors.toMap(LabelFieldInfoContentVo::getFieldCode,LabelFieldInfoContentVo->LabelFieldInfoContentVo ,(key1,key2)->key2));

								for (Element span : spanlist) {
									String paramKey = span.attr("data-fieldMark");
									LabelFieldInfoContentVo labelFieldInfoContentVo = map.get(paramKey);
									if (ObjectUtils.isNotEmpty(labelFieldInfoContentVo)) {
										PatientNodeParamsCurrent paramsCurrent = new PatientNodeParamsCurrent();
										paramsCurrent.setPatientId(signPatientRecord.getPatientId());
										paramsCurrent.setPatientName(signPatientRecord.getPatientName());
										paramsCurrent.setTaskPartitionDictId(node.getTaskPartitionDictId());
										paramsCurrent.setTaskPartitionDictName(node.getTaskPartitionDictName());
										paramsCurrent.setTaskTypeId(node.getTaskTypeId());
										paramsCurrent.setTaskTypeName(node.getTaskTypeName());
										paramsCurrent.setRouteId(node.getRouteId());
										paramsCurrent.setRouteName(node.getRouteName());
										paramsCurrent.setRouteNodeId(node.getId());
										paramsCurrent.setRouteNodeName(node.getRouteNodeName());
										paramsCurrent.setParamKey(paramKey);
										paramsCurrent.setParamValue(labelFieldInfoContentVo.getFieldValue());
										paramsCurrent.setParamName(labelFieldInfoContentVo.getFieldName());
										paramsCurrent.setPortraitSn(labelFieldInfoContentVo.getPortraitSn());
										paramsCurrentList.add(paramsCurrent);
										PatientNodeParamsLog paramsLog = new PatientNodeParamsLog();
										BeanUtils.copyBeanProp(paramsLog, paramsCurrent);
										paramsLogList.add(paramsLog);
									}
								}
							}
						}
					} else {
						// 只取公共标签
						Document document = Jsoup.parse(node.getNodeContent());
						// 需要提取的span
						Elements spanlist = document.select("span[data-w-e-type]");
						Map<String, LabelFieldInfoContentVo> map = publicLabelFields.stream().collect(Collectors.toMap(LabelFieldInfoContentVo::getFieldCode,LabelFieldInfoContentVo->LabelFieldInfoContentVo ,(key1,key2)->key2));

						for (Element span : spanlist) {
							String paramKey = span.attr("data-fieldMark");

							LabelFieldInfoContentVo labelFieldInfoContentVo = map.get(paramKey);
							if (ObjectUtils.isNotEmpty(labelFieldInfoContentVo)) {
								PatientNodeParamsCurrent paramsCurrent = new PatientNodeParamsCurrent();
								paramsCurrent.setPatientId(signPatientRecord.getPatientId());
								paramsCurrent.setPatientName(signPatientRecord.getPatientName());
								paramsCurrent.setTaskPartitionDictId(node.getTaskPartitionDictId());
								paramsCurrent.setTaskPartitionDictName(node.getTaskPartitionDictName());
								paramsCurrent.setTaskTypeId(node.getTaskTypeId());
								paramsCurrent.setTaskTypeName(node.getTaskTypeName());
								paramsCurrent.setRouteId(node.getRouteId());
								paramsCurrent.setRouteName(node.getRouteName());
								paramsCurrent.setRouteNodeId(node.getId());
								paramsCurrent.setRouteNodeName(node.getRouteNodeName());
								paramsCurrent.setParamKey(paramKey);
								paramsCurrent.setParamValue(labelFieldInfoContentVo.getFieldValue());
								paramsCurrent.setParamName(labelFieldInfoContentVo.getFieldName());
								paramsCurrent.setPortraitSn(labelFieldInfoContentVo.getPortraitSn());
								paramsCurrentList.add(paramsCurrent);
								PatientNodeParamsLog paramsLog = new PatientNodeParamsLog();
								BeanUtils.copyBeanProp(paramsLog, paramsCurrent);
								paramsLogList.add(paramsLog);
							}
						}
					}
				}
			});
			if (!CollectionUtils.isEmpty(paramsCurrentList)) {
				patientNodeParamsCurrentMapper.insertList(paramsCurrentList);
				patientNodeParamsLogMapper.insertList(paramsLogList);
			}
		}
	}

}
