PostDischargePatientManage/postdischarge-quartz/src/main/java/com/xinelu/quartz/task/UploadRobotPublishTask.java
2026-03-26 15:47:23 +08:00

390 lines
24 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.xinelu.quartz.task;
import com.alibaba.fastjson2.JSONObject;
import com.xinelu.common.constant.AiobTaskTypeContant;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.entity.SysDictData;
import com.xinelu.common.enums.*;
import com.xinelu.common.utils.StringUtils;
import com.xinelu.common.utils.regex.RegexUtil;
import com.xinelu.manage.domain.dialtime.DialTime;
import com.xinelu.manage.domain.patientinfo.PatientInfo;
import com.xinelu.manage.domain.patientvisitrecord.PatientVisitRecord;
import com.xinelu.manage.domain.scriptInfo.ScriptInfo;
import com.xinelu.manage.domain.scriptinfotaskinfo.ScriptInfoTaskInfo;
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.dto.aiob.ActualTimeTaskDto;
import com.xinelu.manage.dto.aiob.CreateTaskDto;
import com.xinelu.manage.dto.aiob.CustomerInfoDto;
import com.xinelu.manage.dto.aiob.ImportTaskDto;
import com.xinelu.manage.dto.signpatientmanageroutenode.SignPatientManageRouteNodeDto;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientinfoimport.PatientInfoImportMapper;
import com.xinelu.manage.mapper.patientinfoimportmain.PatientInfoImportMainMapper;
import com.xinelu.manage.mapper.patientvisitrecord.PatientVisitRecordMapper;
import com.xinelu.manage.mapper.scriptInfo.ScriptInfoMapper;
import com.xinelu.manage.mapper.scriptinfotaskinfo.ScriptInfoTaskInfoMapper;
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.service.aiob.IAIOBService;
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
import com.xinelu.manage.vo.aiob.ImportTaskVo;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldInfoContentVo;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import com.xinelu.system.service.ISysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @description: 百度智能外呼上传任务定时任务
* @author: haown
* @create: 2024-08-19 13:58
**/
@Slf4j
@Component("UploadRobotPublishTask")
public class UploadRobotPublishTask {
@Value("${aiob.callBackUrl}")
private String callBackUrl;
@Resource
private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
@Resource
private ISignPatientManageRouteNodeService signPatientManageRouteNodeService;
@Resource
private SignPatientManageRouteMapper signPatientManageRouteMapper;
@Resource
private SignPatientRecordMapper signPatientRecordMapper;
@Resource
private PatientVisitRecordMapper patientVisitRecordMapper;
@Resource
private ScriptInfoTaskInfoMapper scriptInfoTaskInfoMapper;
@Resource
private IAIOBService aiobService;
@Resource
private ScriptInfoMapper scriptInfoMapper;
@Resource
private PatientInfoMapper patientInfoMapper;
@Resource
private LabelFieldContentMapper labelFieldContentMapper;
@Resource
private RegexUtil regexUtil;
@Resource
private ISysDictTypeService iSysDictTypeService;
@Resource
private PatientInfoImportMainMapper patientInfoImportMainMapper;
/**
* @description 创建百度智能外呼任务并导入客户名单
* @Author haown
* @Date 2024-9-5 13:55
* @Date 2024-12-11 重构批量执行
*/
public void uploadRobotPublishTask() {
log.info("开始执行百度智能外呼创建任务定时任务......");
// 查找需要当天执行的AI打电话任务问卷或电话外呼类型
SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
//signPatientManageRouteNodeDto.setTaskNodeType(TaskNodeTypeEnum.PHONE_OUTBOUND.getInfo());
signPatientManageRouteNodeDto.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
signPatientManageRouteNodeDto.setPhoneDialMethod(PhoneDialMethodEnum.AI.getInfo());
//只获取 任务执行类型为 批量执行的
signPatientManageRouteNodeDto.setTaskExcuteType(TaskExcuteTypeEnum.BATCH_TASK.getInfo());
//查询未拨打的
signPatientManageRouteNodeDto.setDialStatus(DialStatusEnum.NODIALED.getInfo());
List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
List<SignPatientManageRouteNode> executeNodeList = new ArrayList<>();
nodeList.forEach(node -> {
LocalDateTime executeTime;
if (Objects.nonNull(node.getNodePlanTime()) && org.apache.commons.lang3.StringUtils.isNotBlank(node.getNodePlanTime().toString())) {
executeTime = node.getNodePlanTime();
} else {
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(node.getManageRouteId());
SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signPatientManageRoute.getSignPatientRecordId());
PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
executeTime = signPatientManageRouteNodeService.getExecuteTime(node.getExecuteTime(), node.getRouteNodeName(), node.getRouteNodeDay(), patientVisitRecord);
}
//只处理 流水号不为空的
if (node.getSn() != null &&
//精确到秒
node.getScriptInfoId() != null && (executeTime.isBefore(LocalDateTime.now()) || executeTime.isEqual(LocalDateTime.now()))) {
//精确到天
// node.getScriptInfoId() != null && (executeTime.toLocalDate().isBefore(LocalDate.now()) || executeTime.toLocalDate().isEqual(LocalDate.now()))) {
executeNodeList.add(node);
}
});
if (executeNodeList.isEmpty()) return;
//1、最外层按照导入流水号分组
Map<String, List<SignPatientManageRouteNode>> routeNodeGroupListBySn =
executeNodeList.stream().collect(Collectors.groupingBy(SignPatientManageRouteNode::getSn));
// 开始遍历
routeNodeGroupListBySn.keySet().forEach(sn -> {
//2、次外层按照话术ID分组
Map<Long, List<SignPatientManageRouteNode>> routeNodeGroupListByScriptInfoId =
routeNodeGroupListBySn.get(sn).stream().collect(Collectors.groupingBy(SignPatientManageRouteNode::getScriptInfoId));
//开始遍历,生成任务
routeNodeGroupListByScriptInfoId.keySet().forEach(scriptInfoId -> {
// 同一分组下的任务节点,配置属性 应该是 是相同的所以取第0项节点 来使用
SignPatientManageRouteNode nodeFirstTemp = routeNodeGroupListByScriptInfoId.get(scriptInfoId).get(0);
//话术
ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(scriptInfoId);
//拼接一个taskId(格式:NodeId_ScriptInfoId_ManageRouteId不用了
// String taskId = scriptInfoTaskInfoMapper.getByNodeId(Long.toString(nodeFirstTemp.getId()).concat("_")
// .concat(Long.toString(nodeFirstTemp.getManageRouteId())).concat("_")
// .concat(String.valueOf(nodeFirstTemp.getScriptInfoId()))
// , AiobTaskTypeContant.BATCHTASK);
ScriptInfoTaskInfo scriptInfoTaskInfoQuery = new ScriptInfoTaskInfo();
//同一流水号sn下所有任务id相同所以以第一个节点的属性作为查询条件即可。
// scriptInfoTaskInfoQuery.setSignPatientManageRouteId(nodeFirstTemp.getManageRouteId());
// scriptInfoTaskInfoQuery.setScriptInfoId(nodeFirstTemp.getScriptInfoId());
// scriptInfoTaskInfoQuery.setAiobTaskType(AiobTaskTypeContant.BATCHTASK);
scriptInfoTaskInfoQuery.setSn(sn);
String taskId = scriptInfoTaskInfoMapper.getByNodeId(scriptInfoTaskInfoQuery);
if (StringUtils.isBlank(taskId)) {
Long aLong = patientInfoImportMainMapper.selectHospitalAgencyId(sn);
DialTime dialTime = patientInfoImportMainMapper.selectDialTimeById(aLong);
LocalTime localStartTime = null;
LocalTime localEndTime = null;
LocalTime dateStartTime;
LocalTime dateEndTime;
if (Objects.nonNull(dialTime)) {
localStartTime = LocalTime.parse(dialTime.getDialStartTime());
localEndTime = LocalTime.parse(dialTime.getDialEndTime());
} else {
localStartTime = LocalTime.parse("08:00");
localEndTime = LocalTime.parse("19:00");
}
List<SysDictData> sysDictDataList = iSysDictTypeService.selectDictDataByType(Constants.DIAL_TIME);
if (CollectionUtils.isEmpty(sysDictDataList) || sysDictDataList.size() != 2) {
dateStartTime = LocalTime.parse("08:00");
dateEndTime = LocalTime.parse("19:00");
} else {
dateStartTime = LocalTime.parse(sysDictDataList.get(0).getDictValue());
dateEndTime = LocalTime.parse(sysDictDataList.get(1).getDictValue());
}
if (dateStartTime.isAfter(localStartTime)) {
localStartTime = dateStartTime;
}
if (dateEndTime.isBefore(localEndTime)) {
localEndTime = dateEndTime;
}
// 没有任务则创建任务
if (ObjectUtils.isNotEmpty(scriptInfo)) {
log.info("创建任务......");
CreateTaskDto createTaskDto = new CreateTaskDto();
//临时重复测试用,
String taskName = "T_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + scriptInfo.getScriptName() + "(" + sn + ")";
log.info("任务名称:" + taskName);
createTaskDto.setTaskName(taskName);
// createTaskDto.setTaskName(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + scriptInfo.getScriptName() + "(" + nodeFirstTemp.getManageRouteId() + ")");
createTaskDto.setRobotId(scriptInfo.getRobotPublishId());
createTaskDto.setDialStartDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
createTaskDto.setDialEndDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
createTaskDto.setForbidDialDate(Arrays.asList(99));
createTaskDto.setRetryTimes(StringUtils.isBlank(nodeFirstTemp.getPhoneRedialTimes()) ? 0 : PhoneRedialTimesEnum.getValueByInfo(nodeFirstTemp.getPhoneRedialTimes()).getValue());
createTaskDto.setRetryInterval(nodeFirstTemp.getPhoneTimeInterval());
createTaskDto.setNumTypeFilterList(Arrays.asList(1, 2));
createTaskDto.setTaskDataCallback(true);
createTaskDto.setCallBackUrl(callBackUrl+ "/taskCallBack");
createTaskDto.setDialStartTime(localStartTime.format(DateTimeFormatter.ofPattern("HH:mm")));
createTaskDto.setDialEndTime(localEndTime.format(DateTimeFormatter.ofPattern("HH:mm")));
taskId = aiobService.createTask(createTaskDto);
// 开启任务
log.info("开启任务......");
aiobService.updateTaskStatus(taskId, 2);
String finalTaskId1 = taskId;
routeNodeGroupListByScriptInfoId.get(scriptInfoId).forEach(nodeForTask -> {
ScriptInfoTaskInfo scriptInfoTaskInfo = new ScriptInfoTaskInfo();
scriptInfoTaskInfo.setScriptInfoId(scriptInfoId);
scriptInfoTaskInfo.setTaskId(finalTaskId1);
scriptInfoTaskInfo.setRobotId(scriptInfo.getRobotPublishId());
scriptInfoTaskInfo.setCreateTime(LocalDateTime.now());
scriptInfoTaskInfo.setSn(sn);
scriptInfoTaskInfo.setSignPatientManageRouteNodeId(nodeForTask.getId());
scriptInfoTaskInfo.setSignPatientManageRouteId(nodeForTask.getManageRouteId());
scriptInfoTaskInfo.setAiobTaskType(AiobTaskTypeContant.BATCHTASK);
//进入拔打记录表(用于后续重拨处理等判断)----有时间再优化为批量插入
scriptInfoTaskInfoMapper.insertScriptInfoTaskInfo(scriptInfoTaskInfo);
});
//3、开始组装本任务下的客户变量
// 客户名单list
List<CustomerInfoDto> customerInfoList = new ArrayList<>();
//遍历最内层任务节点
routeNodeGroupListByScriptInfoId.get(scriptInfoId).forEach(node -> {
CustomerInfoDto customerInfoDto = new CustomerInfoDto();
customerInfoDto.setExtJson(node.getId() + "");
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(node.getManageRouteId());
PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(signPatientManageRoute.getPatientId());
//校验手机号
if (org.apache.commons.lang3.StringUtils.isNotBlank(patientInfo.getPatientPhone())) {
if (regexUtil.regexPhone(patientInfo.getPatientPhone())) {
customerInfoDto.setMobile(patientInfo.getPatientPhone());
// 查询患者画像信息
List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfo.getId());
// 处理变量
JSONObject jsonObject = new JSONObject();
if (StringUtils.isNotBlank(scriptInfo.getVariables())) {
List<String> variables = Arrays.asList(scriptInfo.getVariables().split("\\|"));
variables.forEach(variable -> {
LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), variable.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
jsonObject.fluentPut(variable, ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
});
}
customerInfoDto.setVar(jsonObject);
customerInfoList.add(customerInfoDto);
}
}
});
// 上传名单
log.info("任务导入客户名单......");
ImportTaskDto importTaskDto = new ImportTaskDto();
importTaskDto.setTaskId(taskId);
importTaskDto.setSecretType(2);
importTaskDto.setCustomerInfoList(customerInfoList);
List<ImportTaskVo> importTaskList = aiobService.importTask(importTaskDto);
//设置拨打状态
SignPatientManageRouteNode signPatientManageRouteNode_DialStatus = new SignPatientManageRouteNode();
// signPatientManageRouteNode_DialStatus.setManageRouteId(routeId);
signPatientManageRouteNode_DialStatus.setSn(sn);
signPatientManageRouteNode_DialStatus.setScriptInfoId(scriptInfoId);
signPatientManageRouteNode_DialStatus.setDialStatus(DialStatusEnum.DIALED.getInfo());
signPatientManageRouteNodeMapper.updateDialStatus(signPatientManageRouteNode_DialStatus);
String finalTaskId = taskId;
importTaskList.forEach(importTaskVo -> {
SignPatientManageRouteNode signPatientManageRouteNode = new SignPatientManageRouteNode();
// 名单导入成功后sign_patient_manage_route_node表中设置taskId
if (importTaskVo.getStatus()) {
signPatientManageRouteNode.setTaskIdExt(finalTaskId);
signPatientManageRouteNode.setId(Long.valueOf(importTaskVo.getExtJson()));
signPatientManageRouteNodeMapper.updateSignPatientManageRouteNode(signPatientManageRouteNode);
}
});
}
}
});
});
// 根据机器人id查询智能外呼系统的任务id
log.info("百度智能外呼创建任务定时任务执行完成......");
}
/**
* @return null
* @description 创建实时任务
* @Author haown
* @Date 2024-9-23 10:41
*/
public void actualTimeTask() {
log.info("开始执行百度智能外呼创建实时任务定时任务......");
// 查找需要当天执行的AI打电话任务问卷或电话外呼类型
SignPatientManageRouteNodeDto signPatientManageRouteNodeDto = new SignPatientManageRouteNodeDto();
signPatientManageRouteNodeDto.setNodeExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
signPatientManageRouteNodeDto.setPhoneDialMethod(PhoneDialMethodEnum.AI.getInfo());
//只获取 任务执行类型为 单个执行的
signPatientManageRouteNodeDto.setTaskExcuteType(TaskExcuteTypeEnum.ACTUAL_TIME_TASK.getInfo());
//查询未拨打的
signPatientManageRouteNodeDto.setDialStatus(DialStatusEnum.NODIALED.getInfo());
List<SignPatientManageRouteNode> nodeList = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeList(signPatientManageRouteNodeDto);
List<SignPatientManageRouteNode> executeNodeList = new ArrayList<>();
nodeList.forEach(node -> {
LocalDateTime executeTime;
//如果有计划执行时间,则直接获取
if (node.getNodePlanTime() != null) {
executeTime = node.getNodePlanTime();
}
// 否则 ,则根据诊后/院后 第几天 计算
else {
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(node.getManageRouteId());
SignPatientRecord signPatientRecord = signPatientRecordMapper.selectByPrimaryKey(signPatientManageRoute.getSignPatientRecordId());
PatientVisitRecord patientVisitRecord = patientVisitRecordMapper.selectPatientVisitRecordById(signPatientRecord.getPatientVisitRecordId());
executeTime = signPatientManageRouteNodeService.getExecuteTime(node.getExecuteTime(), node.getRouteNodeName(), node.getRouteNodeDay(), patientVisitRecord);
}
//精确到天
// if (node.getScriptInfoId() != null && (executeTime.toLocalDate().isBefore(LocalDate.now()) || executeTime.toLocalDate().isEqual(LocalDate.now()))) {
//精确到秒
if (node.getScriptInfoId() != null && (executeTime.isBefore(LocalDateTime.now()) || executeTime.isEqual(LocalDateTime.now()))) {
executeNodeList.add(node);
}
});
// 查询需要重拨的任务
ScriptInfoTaskInfo scriptInfoTaskInfo = new ScriptInfoTaskInfo();
scriptInfoTaskInfo.setExecuteStatus(NodeExecuteStatusEnum.UNEXECUTED.getInfo());
scriptInfoTaskInfo.setAiobTaskType(AiobTaskTypeContant.ACTUALTIMETASK);
List<ScriptInfoTaskInfo> scriptInfoTaskInfoList = scriptInfoTaskInfoMapper.selectList(scriptInfoTaskInfo);
scriptInfoTaskInfoList.forEach(taskInfo -> {
SignPatientManageRouteNode node = signPatientManageRouteNodeMapper.selectSignPatientManageRouteNodeById(taskInfo.getSignPatientManageRouteNodeId());
if (taskInfo.getExecuteTime().isBefore(LocalDateTime.now()) || taskInfo.getExecuteTime().isEqual(LocalDateTime.now())) {
executeNodeList.add(node);
}
});
if (CollectionUtils.isNotEmpty(executeNodeList)) {
// 根据机器人id查询智能外呼系统的任务id
executeNodeList.forEach(node -> {
createTask(node);
});
}
log.info("百度智能外呼创建实时任务定时任务执行完成......");
}
private void createTask(SignPatientManageRouteNode node) {
ScriptInfo scriptInfo = scriptInfoMapper.selectScriptInfoById(node.getScriptInfoId());
SignPatientManageRoute signPatientManageRoute = signPatientManageRouteMapper.selectSignPatientManageRouteById(node.getManageRouteId());
PatientInfo patientInfo = patientInfoMapper.selectPatientInfoById(signPatientManageRoute.getPatientId());
// 没有任务则创建任务
if (ObjectUtils.isNotEmpty(scriptInfo) && org.apache.commons.lang3.StringUtils.isNotBlank(patientInfo.getPatientPhone()) && regexUtil.regexPhone(patientInfo.getPatientPhone())) {
log.info("创建任务......");
ActualTimeTaskDto actualTimeTaskDto = new ActualTimeTaskDto();
actualTimeTaskDto.setRobotId(scriptInfo.getRobotPublishId());
actualTimeTaskDto.setMobile(patientInfo.getPatientPhone());
actualTimeTaskDto.setSecretType(2);
actualTimeTaskDto.setStopDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 20:00:00");
// 查询患者画像信息
List<LabelFieldInfoContentVo> labelFieldContentList = labelFieldContentMapper.selectByPatientId(patientInfo.getId());
// 处理变量
JSONObject jsonObject = new JSONObject();
if (StringUtils.isNotBlank(scriptInfo.getVariables())) {
List<String> variables = Arrays.asList(scriptInfo.getVariables().split("\\|"));
variables.forEach(variable -> {
LabelFieldInfoContentVo labelFieldContent = labelFieldContentList.stream().filter(s -> Objects.equals(s.getFieldCode(), variable.replaceAll("_", "").toUpperCase())).findFirst().orElse(null);
jsonObject.fluentPut(variable, ObjectUtils.isEmpty(labelFieldContent) ? "" : labelFieldContent.getFieldValue());
});
}
actualTimeTaskDto.setDialogVar(jsonObject);
actualTimeTaskDto.setCallBackUrl(callBackUrl);
actualTimeTaskDto.setExtJson(node.getId() + "");
aiobService.createActualTimeTask(actualTimeTaskDto);
log.info("创建任务完成......");
//设置拨打状态
SignPatientManageRouteNode signPatientManageRouteNode_DialStatus = new SignPatientManageRouteNode();
signPatientManageRouteNode_DialStatus.setId(node.getId());
signPatientManageRouteNode_DialStatus.setDialStatus(DialStatusEnum.DIALED.getInfo());
signPatientManageRouteNodeMapper.updateDialStatusByNodeId(signPatientManageRouteNode_DialStatus);
}
}
}