package com.ruoyi.phone.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.service.SubtaskOptionMatchApi;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.*;
import com.ruoyi.phone.domain.PhoneCallBackSHVO;
import com.ruoyi.phone.domain.PhoneCallBackVO;
import com.ruoyi.phone.domain.PhoneCallBackYQVO;
import com.ruoyi.phone.domain.PhoneCallRecordVO;
import com.ruoyi.phone.domain.PhoneCallReqYQVO;
import com.ruoyi.phone.domain.PhoneCallResultYQVO;
import com.ruoyi.phone.domain.PullTaskVO;
import com.ruoyi.phone.domain.QuestionMessage;
import com.ruoyi.phone.service.IPhoneService;
import com.ruoyi.task.api.TaskSubtaskApi;
import com.ruoyi.task.api.spi.TaskFtpPort;
import com.ruoyi.task.api.spi.TaskPreachformPort;
import com.ruoyi.task.api.spi.TaskSysConfigPort;
import com.ruoyi.task.domain.IvrTaskVisitResult;
import com.ruoyi.task.domain.ServiceSubTaskDetailReq;
import com.ruoyi.task.domain.ServiceSubtask;
import com.ruoyi.task.domain.ServiceSubtaskDetail;
import com.ruoyi.task.domain.ServiceSubtaskDetailTrace;
import com.ruoyi.task.domain.ServiceSubtaskPreachform;
import com.ruoyi.task.domain.ServiceTask;
import com.ruoyi.task.domain.entity.ServiceSubtaskEntity;
import com.ruoyi.template.domain.IvrLibaExtemplatescript;
import com.ruoyi.template.domain.IvrTaskTemplate;
import com.ruoyi.template.domain.IvrTaskTemplateScript;
import com.ruoyi.template.domain.IvrTaskTemplateScriptVO;
import com.ruoyi.template.domain.IvrTaskTemplateTargetoption;
import com.ruoyi.template.domain.IvrTaskTemplateVO;
import com.ruoyi.template.domain.SvyLibScriptCategory;
import com.ruoyi.template.service.IIvrLibaExtemplatescriptService;
import com.ruoyi.template.service.IIvrTaskTemplateScriptService;
import com.ruoyi.template.service.IIvrTaskTemplateService;
import com.ruoyi.template.service.IIvrTaskTemplateTargetoptionService;
import com.ruoyi.template.service.ISvyLibScriptCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 电话业务Service实现(原 {@code ruoyi-task} 里 {@code ServiceSubtaskServiceImpl} 的电话部分)。
*
*
这个类是怎么来的
* 逐行从 {@code ServiceSubtaskServiceImpl} 搬出,只做两类机械改写,业务分支一行未动:
*
* - 数据访问换入口:原 {@code serviceSubtaskMapper} / {@code serviceSubtaskDetailMapper} /
* {@code serviceTaskVisitResultMapper} / {@code serviceTaskService} / {@code traceService}
* 的调用,统一改为 {@link TaskSubtaskApi}(表归 {@code ruoyi-task},非归属模块不许写这些表);
* - 跨模块读取换入口:模板话术改走 {@code ruoyi-template} 的 service 接口
* ({@code IIvrTaskTemplateService} / {@code IIvrTaskTemplateScriptService} /
* {@code IIvrTaskTemplateTargetoptionService} / {@code IIvrLibaExtemplatescriptService} /
* {@code ISvyLibScriptCategoryService});AI 选项匹配改走 ruoyi-common 契约
* {@link SubtaskOptionMatchApi}(实现在 {@code ruoyi-task},原 {@code matchOptionIndex} 仍留在那边)。
*
*
* 会话状态在哪里
* 一通电话的进行状态(当前题号、已问遍数、静默次数、分数、是否已挂机、结束语等)
* 全部放在 Redis(key 前缀是本通电话的 uuid 或"子任务ID-手机号"),
* 这些 key 的拼写、TTL、读写顺序与原实现完全一致 —— 电话回调是外部平台驱动的、
* 进程重启后要继续,所以这些 key 就是"业务状态机",迁移时不能动。
*
* 被刻意删掉的东西
* 原 {@code ServiceSubtaskServiceImpl#getSmsCompensate(Long)}("电话的补偿方法(老)")没有搬:
* 它的两个调用点({@code phoneCallBackYQ} 里"患者挂断"、{@code recordAccept} 里"无人接听")
* 在模块化前就已被注释掉,属死代码;搬过来只会把 {@code service_out_path} /
* 短信发送方 / {@code pub_key} 一串依赖拖进电话模块。如需恢复电话补偿,请按
* {@code doc/电话模块化_调研与实施方案.md} 的说明走"归属模块 API"补齐。
*
* @author ruoyi
* @date 2024-08-08
*/
@Slf4j
@Service
public class PhoneServiceImpl implements IPhoneService {
/**
* 任务数据访问 API:子任务 / 子任务明细 / 任务访问结果 / 异常跟踪。
*
* 这些表归 {@code ruoyi-task},本模块不写它们的 SQL,只经这个 API 读写。
*/
@Autowired
private TaskSubtaskApi taskSubtaskApi;
/**
* 发送方式状态(service_subtask_preachform):记录"电话"这一通道的发送状态与备注。
* 该表归 ruoyi-inhospvisit,由 smartor 侧适配实现本端口。
*/
@Autowired
private TaskPreachformPort taskPreachformPort;
/**
* 录音文件下载(雨绮通话记录回调里把当天录音从 FTP 拉回本地)
*/
@Autowired
private TaskFtpPort taskFtpPort;
/**
* 参数配置读取({@code sys.voice.match.ai.url}:AI 选项匹配服务地址,按机构配置)
*/
@Autowired
private TaskSysConfigPort taskSysConfigPort;
/**
* AI 选项匹配契约(ruoyi-common,实现在 ruoyi-task,即原 {@code matchOptionIndex})
*/
@Autowired
private SubtaskOptionMatchApi subtaskOptionMatchApi;
@Autowired
private RedisCache redisCache;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private IIvrTaskTemplateService ivrTaskTemplateService;
@Autowired
private IIvrTaskTemplateScriptService iIvrTaskTemplateScriptService;
@Autowired
private IIvrTaskTemplateTargetoptionService ivrTaskTemplateTargetoptionService;
@Autowired
private IIvrLibaExtemplatescriptService ivrLibaExtemplatescriptService;
@Autowired
private ISvyLibScriptCategoryService svyLibScriptCategoryService;
/**
* 雨绮任务拉取时回填的 ASR 回调地址
*/
@Value("${ASRCallBackPath}")
private String ASRCallBackPath;
/**
* 雨绮外呼账号
*/
@Value("${app_key_yq}")
private String app_key_yq;
/**
* 上海通道短信补偿串解密用({@code saveQuestionAnswerPhone} 的 param1/param2)
*/
@Value("${pri_key}")
private String pri_key;
/**
* 雨绮挂机接口地址
*/
@Value("${hangup}")
private String hangup;
/**
* 录音本地根目录({@code ruoyi.profile})
*/
@Value("${ruoyi.profile}")
private String profile;
/**
* 语音文件对外访问前缀(存库前把 FTP 绝对路径改写成前端可访问路径)
*/
@Value("${voicePathPrefix}")
private String voicePathPrefix;
/**
* 每小时可外呼量
*/
@Value("${phoneUpEveryHour}")
private Integer phoneUpEveryHour;
/**
* 停止外呼的时刻(小时,默认 20 点)
*/
@Value("${phoneEndHour}")
private Integer phoneEndHour;
@Override
public void phoneCallBack(PhoneCallBackVO phoneCallBackVO) {
phoneCallBackVO.setTextResult(phoneCallBackVO.getTextResult().substring(0, phoneCallBackVO.getTextResult().length() - 1));
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
//获取数据
Boolean aBoolean = redisCache.hasKey(phoneCallBackVO.getUuid());
if (!aBoolean) {
throw new BaseException("该uuid不存在");
}
Integer hangupValue = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "hangup");
PhoneUtils phoneUtils = new PhoneUtils();
if (hangupValue != null && hangupValue == 1) {
String date = simpleDateFormat1.format(new Date());
log.info("电话要挂断了: {}", date);
//hangupValue == 1 随访结束,直接可以挂电话
phoneUtils.hangup("", "", "", "", "", "", "", phoneCallBackVO.getUuid());
return;
}
Map map = redisCache.getCacheObject(phoneCallBackVO.getUuid());
ServiceSubtask serviceSubtask = (ServiceSubtask) map.get("ServiceSubtask");
List IvrTaskTemplateScriptVOs = (List) map.get("IvrTaskTemplateScriptVO");
//将uuid更新到数据库中
serviceSubtask.setSenduuid(phoneCallBackVO.getUuid());
taskSubtaskApi.updateSubtask(serviceSubtask);
//获取模板信息
IvrTaskTemplateVO ivrTaskTemplateVO = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "IvrTaskTemplateVO");
//语音识别结果上报接口: 3
Integer noVoice = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "noVoice");
QuestionMessage returnQues = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "returnQues");
//将传回的结果放到回复对象中
returnQues.setContent(phoneCallBackVO.getTextResult());
IvrTaskTemplateScriptVO nowQuestion = returnQues.getNowQuestion();
if (StringUtils.isEmpty(returnQues.getContent())) {
//无回话
//判断noVoice是否已经到了最大值
if (noVoice == ivrTaskTemplateVO.getNoVoiceNum().intValue()) {
//已经问了对应的遍数,就判断是否还有下一题
if (nowQuestion.getTargetid() == IvrTaskTemplateScriptVOs.size()) {
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(5L);
ss.setRemark("电话无响应");
taskSubtaskApi.updateSubtask(ss);
//没有下一题了,就挂断电话,播放结束语
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "hangup", 1, 120, TimeUnit.MINUTES);
phoneUtils.ttsPlayback(ivrTaskTemplateVO.getRevisitAfter(), phoneCallBackVO.getUuid());
return;
} else {
//有下一题
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", 0, 120, TimeUnit.MINUTES);
IvrTaskTemplateScriptVO nextQuestion = getNextQuestion(IvrTaskTemplateScriptVOs, nowQuestion);
// 问题, 去调用"tts合成和播放"接口
String date = simpleDateFormat1.format(new Date());
log.info("去调用tts合成和播放接口: {},uuid为:{}", date, phoneCallBackVO.getUuid());
phoneUtils.ttsPlayback(nowQuestion.getIvrtext(), phoneCallBackVO.getUuid());
}
} else {
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", noVoice + 1, 120, TimeUnit.MINUTES);
//调用ivrLibaTemplateScriptVO中的slienceText(静默话术)
String slienceText = nowQuestion.getSlienceText();
//静默话术 + 问题, 去调用"tts合成和播放"接口
String date = simpleDateFormat1.format(new Date());
log.info("静默话术 + 问题,去调用tts合成和播放接口: {},uuid为:{}", date, phoneCallBackVO.getUuid());
phoneUtils.ttsPlayback(slienceText + nowQuestion.getIvrtext(), phoneCallBackVO.getUuid());
return;
}
} else {
//isppd用来记录是否匹配到
Boolean isppd = false;
//有回话,对回答的问题,进行正则匹配(这里只针对选择题,其它题型不行)
for (int j = 0; j < nowQuestion.getIvrTaskScriptTargetoptionList().size(); j++) {
//包含
Matcher matcher = null;
if (StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex())) {
Pattern pattern = Pattern.compile(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex());
matcher = pattern.matcher(phoneCallBackVO.getTextResult());
}
//不包含
Matcher matcher2 = null;
if (StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2())) {
Pattern pattern2 = Pattern.compile(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2());
matcher2 = pattern2.matcher(phoneCallBackVO.getTextResult());
}
log.error("PCB--getQuestionText问题为:{},UUID:{}", nowQuestion.getIvrtext(), phoneCallBackVO.getUuid());
if (StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() && StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches() || StringUtils.isEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && StringUtils.isNotEmpty(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches()) {
//说明匹配正确了
//这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
nowQuestion.getIvrTaskScriptTargetoptionList().get(j).setIsUserOperation(1);
ivrTaskTemplateTargetoptionService.updateIvrTaskTemplateTargetoption(nowQuestion.getIvrTaskScriptTargetoptionList().get(j));
//将静默置为0
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "noVoice", 0, 120, TimeUnit.MINUTES);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", 0, 120, TimeUnit.MINUTES);
//将患者的回签写进表里
IvrTaskVisitResult serviceTaskVisitResult = DtoConversionUtils.sourceToTarget(serviceSubtask, IvrTaskVisitResult.class);
serviceTaskVisitResult.setId(null);
serviceTaskVisitResult.setQuestion(nowQuestion.getIvrtext());
serviceTaskVisitResult.setPatientAnswer(phoneCallBackVO.getTextResult());
serviceTaskVisitResult.setCreateTime(new Date());
serviceTaskVisitResult.setOptionResult(nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getTargetvalue());
taskSubtaskApi.insertVisitResult(serviceTaskVisitResult);
//将匹配到的标识改成true
isppd = true;
//获取下一题
Long nextQuestion = nowQuestion.getIvrTaskScriptTargetoptionList().get(j).getNextQuestion();
for (IvrTaskTemplateScriptVO script : IvrTaskTemplateScriptVOs) {
if (script.getTargetid() == nextQuestion) {
QuestionMessage questionMessage = new QuestionMessage();
questionMessage.setNowQuestion(script);
questionMessage.setQuestionList(IvrTaskTemplateScriptVOs);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
phoneUtils.ttsPlayback(script.getIvrtext(), phoneCallBackVO.getUuid());
return;
} else if (nextQuestion > IvrTaskTemplateScriptVOs.size()) {
//没有下一题了,就结束了
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(6L);
taskSubtaskApi.updateSubtask(ss);
String date = simpleDateFormat1.format(new Date());
log.error("没有下一题了,就结束了: {},uuid为:{}", date, phoneCallBackVO.getUuid());
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "hangup", 1, 120, TimeUnit.MINUTES);
phoneUtils.ttsPlayback(ivrTaskTemplateVO.getRevisitAfter(), phoneCallBackVO.getUuid());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
phoneUtils.hangup("", "", ivrTaskTemplateVO.getRevisitAfter(), "", "", "", "", phoneCallBackVO.getUuid());
return;
}
}
return;
} else {
//没有匹配上当前option
//Targetregex2 为false,表示在Targetregex2中存在 语句中的关键字,这个option就不用再继续匹配了,直接匹配下一个option
continue;
}
}
if (isppd != true) {
//没有匹配到
Integer mateNum = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "mateNum");
if (mateNum == null) mateNum = 0;
//无匹配次数去判断是否到最大询问次数,并且所有的选项都匹配完了
if (mateNum == ivrTaskTemplateVO.getMateNum().intValue()) {
//如果下一题为空.则新的数据返回,并加上感谢语
if (nowQuestion.getTargetid() < IvrTaskTemplateScriptVOs.size()) {
QuestionMessage questionMessage = new QuestionMessage();
IvrTaskTemplateScriptVO nextQuestion = getNextQuestion(IvrTaskTemplateScriptVOs, nowQuestion);
questionMessage.setQuestionList(IvrTaskTemplateScriptVOs);
questionMessage.setNowQuestion(nextQuestion);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", 0, 120, TimeUnit.MINUTES);
String date = simpleDateFormat1.format(new Date());
log.info("如果下一题为空.则新的数据返回,并加上感谢语: {},uuid为:{}", date, phoneCallBackVO.getUuid());
phoneUtils.ttsPlayback(nextQuestion.getIvrtext(), phoneCallBackVO.getUuid());
return;
} else {
//就可以挂断电话了
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(6L);
taskSubtaskApi.updateSubtask(ss);
String date = simpleDateFormat1.format(new Date());
log.info("就可以挂断电话了------: {},uuid为:{}", date, phoneCallBackVO.getUuid());
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "hangup", 1, 120, TimeUnit.MINUTES);
phoneUtils.ttsPlayback(ivrTaskTemplateVO.getRevisitAfter(), phoneCallBackVO.getUuid());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
phoneUtils.hangup("", "", ivrTaskTemplateVO.getRevisitAfter(), "", "", "", "", phoneCallBackVO.getUuid());
return;
}
} else if (mateNum < ivrTaskTemplateVO.getMateNum().intValue()) {
//没有问到规定次数
mateNum = mateNum + 1;
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "mateNum", mateNum, 120, TimeUnit.MINUTES);
}
}
//选项匹配完成后,需要再去通过库再进行匹配一次
String extemplateID = ivrTaskTemplateVO.getSubmoduleID();
String[] split = extemplateID.split(",");
List list = Arrays.asList(split);
List list1 = new ArrayList<>();
if (StringUtils.isNotEmpty(extemplateID)) {
for (String str : list) {
list1.add(Long.valueOf(str));
}
List ivrLibaExtemplatescripts = ivrLibaExtemplatescriptService.queryIvrLibaExtemplatescriptList(list1);
for (IvrLibaExtemplatescript ivrLibaExtemplatescript : ivrLibaExtemplatescripts) {
Matcher matcher = null;
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex())) {
Pattern pattern = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex());
matcher = pattern.matcher(returnQues.getContent());
}
Matcher matcher2 = null;
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2())) {
Pattern pattern2 = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex2());
matcher2 = pattern2.matcher(returnQues.getContent());
}
log.error("++++++++++++++++++++++++++通用库是否为空:selfRegex : {} , selfRegex2 : {}", ivrLibaExtemplatescript.getSelfRegex(), ivrLibaExtemplatescript.getSelfRegex2());
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches() && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches()) {
QuestionMessage questionMessage = redisCache.getCacheObject(phoneCallBackVO.getUuid() + "returnQues");
IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO = returnQues.getNowQuestion();
ivrTaskTemplateScriptVO.setSubmoduleText(ivrLibaExtemplatescript.getSwitchText());
ivrTaskTemplateScriptVO.setSubmoduleVoice(ivrLibaExtemplatescript.getSwitchWav());
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
if (ivrLibaExtemplatescript.getIsEnd() == 1) {
//将问题置空
IvrTaskTemplateScriptVO nowQuestion1 = questionMessage.getNowQuestion();
nowQuestion1.setScriptContent(null);
nowQuestion1.setScriptVoice(null);
questionMessage.setNowQuestion(nowQuestion1);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "returnQues", questionMessage, 120, TimeUnit.MINUTES);
redisCache.setCacheObject(phoneCallBackVO.getUuid() + "isOver", 1, 120, TimeUnit.MINUTES);
}
//调用"15、tts合成和播放, tts_playback"将结果传回
String date = simpleDateFormat1.format(new Date());
log.info("调用tts合成和播放------: {},uuid为:{}", date, phoneCallBackVO.getUuid());
phoneUtils.ttsPlayback(nowQuestion.getIvrtext() + ivrTaskTemplateScriptVO.getSubmoduleText(), phoneCallBackVO.getUuid());
}
break;
}
String date = simpleDateFormat1.format(new Date());
log.info("最后的信息回复-: {},uuid为:{}", date, phoneCallBackVO.getUuid());
phoneUtils.ttsPlayback(nowQuestion.getIvrtext(), phoneCallBackVO.getUuid());
}
}
}
/**
* 电话ASR通话回调(雨绮)
*
* @param phoneCallReqYQVO
*/
@Override
public PhoneCallBackYQVO phoneCallBackYQ(PhoneCallReqYQVO phoneCallReqYQVO) {
//先把该subId从cache_exist中剔除,只要有回调就剔除(目的是,尽快让cache-exist为空,去缓存下一批要打的电话;这里剔除不影响电话的正常业务)
// redisCache.removeElementFromList("cache-exist", phoneCallReqYQVO.getTaskid());
//判断是否挂机
String hangupState = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "- hangup");
Object cacheObject1 = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
if (StringUtils.isNotEmpty(hangupState) && hangupState.equals("1") || ObjectUtils.isNotEmpty(cacheObject1) && String.valueOf(cacheObject1).equals("1")) {
return new PhoneCallBackYQVO();
}
if ("AsrCallback".equals(phoneCallReqYQVO.getOperate()) && phoneCallReqYQVO.getEnd_time() != null && phoneCallReqYQVO.getEnd_time() != -1) {
//处理挂断
if (phoneCallReqYQVO.getAsrtext().contains("拨叫的用户正忙")) {
//判断 recordAccept-hungup 是否有值,如果有,则说明不用处理了,之前已经处理过了(recordAccept-hungup这个主要是给"通话记录用的,")
Object cacheObject = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
if (ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallReqYQVO.getTaskid()));
setFailPreachForm(serviceSubtask, "3", "拨叫的用户正忙", "4");
return new PhoneCallBackYQVO();
}
//如果发送状态为6,就说明已经打完了,也没有必要继续往下走了
if (StringUtils.isNotEmpty(phoneCallReqYQVO.getTaskid())) {
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallReqYQVO.getTaskid()));
if (serviceSubtask.getSendstate() == 6L) return new PhoneCallBackYQVO();
}
ServiceSubtask serviceSubtask2 = new ServiceSubtask();
serviceSubtask2.setRemark("电话发送成功(患者挂断)");
serviceSubtask2.setSenduuid(phoneCallReqYQVO.getUuid());
serviceSubtask2.setId(Long.valueOf(phoneCallReqYQVO.getTaskid()));
taskSubtaskApi.updateSubtask(serviceSubtask2);
Map req = new HashMap<>();
req.put("uuid", phoneCallReqYQVO.getUuid());
req.put("caller", phoneCallReqYQVO.getPhone());
HttpUtil.postJsonRequest(hangup, new Gson().toJson(req));
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- hangup", "1", 2, TimeUnit.MINUTES);
//先把默认的recordAccept-hungup删除,再更新
redisCache.deleteObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup", "1", 10, TimeUnit.MINUTES);
//记录电话发送状态
setFailPreachForm(serviceSubtask2, "3", "电话发送成功(患者挂断)", "4");
//这个时候就需要走补偿机制了,先暂定走短信
//原 getSmsCompensate(...) 未随电话模块化搬迁(模块化前调用点就已注释、属死代码),
//如需恢复短信补偿,请走 service_out_path / 短信发送方的归属模块 API,见 doc/电话模块化_调研与实施方案.md
return new PhoneCallBackYQVO();
}
}
//定义一个分数的变量
Boolean aBoolean1 = redisCache.hasKey(phoneCallReqYQVO.getUuid() + "SCORE");
if (!aBoolean1) redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", 0.0, 120, TimeUnit.MINUTES);
PhoneCallBackYQVO phoneCallBackYQVO = new PhoneCallBackYQVO();
//channel_create 通道创建的时候,可以执行一些其它操作,譬如发个短信之类的; 我们的业务可以不用管 PlayEventCallback 这个是播放语音的,暂时用不到 End_time()= -1或null表示当前的asrtext不是一句完整的话
if (phoneCallReqYQVO.getOperate().equals("channel_create")) {
return phoneCallBackYQVO;
}
//PlayEventCallback 这个是播放语音的 playstart:放音开始(问题播报开始) playstop: 放音结束(问题播报结束)
if (phoneCallReqYQVO.getOperate().equals("PlayEventCallback")) {
String cacheJSY = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "- jsy");
if (phoneCallReqYQVO.getOperate().equals("PlayEventCallback") && phoneCallReqYQVO.getPlaystop() == false) {
//判断redis中是否有结束语
if (StringUtils.isEmpty(cacheJSY)) {
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop", false, 120, TimeUnit.MINUTES);
log.error("PlayEventCallbackPlaystop的值为-------:{}", false);
}
} else {
//如果结束语不为空,则要挂电话了
if (StringUtils.isNotEmpty(cacheJSY)) {
Map req = new HashMap<>();
req.put("uuid", phoneCallReqYQVO.getUuid());
req.put("caller", phoneCallReqYQVO.getPhone());
// HttpUtils.sendPost(hangup, new Gson().toJson(req));
HttpUtil.postJsonRequest(hangup, new Gson().toJson(req));
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallReqYQVO.getTaskid()));
//记录电话发送状态
setFailPreachForm(serviceSubtask, "3", "通话正常结束", "9");
//删除结束语的缓存
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "- jsy");
} else {
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop", true, 120, TimeUnit.MINUTES);
log.error("-------PlayEventCallbackPlaystop的值为:{}", true);
}
}
return phoneCallBackYQVO;
}
//获取放音是否结束
Object isPlayEventOverObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
if (ObjectUtils.isNotEmpty(isPlayEventOverObj)) {
Boolean isPlayEventOver = (Boolean) isPlayEventOverObj;
if (!isPlayEventOver) {
return phoneCallBackYQVO;
}
}
//通过子任务ID获取到模板信息
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallReqYQVO.getTaskid()));
IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
//获取模板问题
IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
ivrTaskTemplateScript.setTemplateID(serviceSubtask.getTemplateid());
List ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript);
//获取问题ID 和 序号
String scriptId = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim());
log.error("scriptId是多少:{}", scriptId);
//当前题的信息
IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO = iIvrTaskTemplateScriptService.getTaskTempScriptInfoByid(Long.valueOf(scriptId));
//判断UUID是否存在
Boolean aBoolean = redisCache.hasKey(phoneCallReqYQVO.getUuid());
if (!aBoolean) {
//给静默设置一个默认次数在redis中
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "noVoice", 0, 120, TimeUnit.MINUTES);
//如果不存在,就把当前的UUID做为key,放到对象中去
redisCache.setCacheObject(phoneCallReqYQVO.getUuid(), phoneCallReqYQVO, 120, TimeUnit.MINUTES);
}
if ("SilentCallback".equals(phoneCallReqYQVO.getOperate())) {
//如果是静默回调
Integer num = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "noVoice");
//判断静默回调次数是否小与模板规定的次数
if (num < ivrTaskTemplate.getNoVoiceNum()) {
//小与的话,就继续问患者
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = ivrTaskTemplateScriptVO.getIvrtext();
log.error("SilentCallback的问题内容scriptContent:{}", scriptContent);
phoneCallBackYQVO.setValue(getObject(serviceSubtask, scriptContent));
//将静默次数加1
Integer noVoiceNum = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "noVoice");
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "noVoice", noVoiceNum + 1, 120, TimeUnit.MINUTES);
return phoneCallBackYQVO;
} else {
log.error("静默次数达到,挂掉电话:{}", num);
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(5L);
ss.setRemark("电话静默");
taskSubtaskApi.updateSubtask(ss);
//大与等于的话,直接挂断
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
phoneCallBackYQVO.setValue(serviceTask1.getJsy());
//将结果写到detail中
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
serviceSubtaskDetailList.add(getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate));
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
//去redis中,把该子任务ID删除
Long id = serviceSubtask.getId();
//先更新一下分数
double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setUpdateTime(new Date());
log.error("先更新一下分数,电话的serviceSubtask的值为:{}", serviceSubtask);
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "静默次数达到" + num + "次", "4");
Map map = delRedisValue(null, id.toString());
if (ObjectUtils.isNotEmpty(map)) redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
}
return phoneCallBackYQVO;
} else if ("AsrCallback".equals(phoneCallReqYQVO.getOperate()) && phoneCallReqYQVO.getEnd_time() != null && phoneCallReqYQVO.getEnd_time() != -1) {
//做一个标识,用来在通话详情接口里,判断是否有人接电话(value=2,表示有人接)
redisCache.deleteObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup");
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid() + "recordAccept-hungup", "2", 10, TimeUnit.MINUTES);
// 先对通话进行通用库匹配一次
String extemplateID = ivrTaskTemplate.getSubmoduleID();
if (StringUtils.isNotEmpty(extemplateID)) {
String[] split = extemplateID.split(",");
List list = Arrays.asList(split);
List list1 = new ArrayList<>();
for (String str : list) {
list1.add(Long.valueOf(str));
}
List ivrLibaExtemplatescripts = ivrLibaExtemplatescriptService.queryIvrLibaExtemplatescriptList(list1);
IvrLibaExtemplatescript les = null;
for (IvrLibaExtemplatescript ivrLibaExtemplatescript : ivrLibaExtemplatescripts) {
Matcher matcher = null;
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex())) {
Pattern pattern = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex());
matcher = pattern.matcher(phoneCallReqYQVO.getAsrtext());
}
Matcher matcher2 = null;
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2())) {
Pattern pattern2 = Pattern.compile(ivrLibaExtemplatescript.getSelfRegex2());
matcher2 = pattern2.matcher(phoneCallReqYQVO.getAsrtext());
}
if (StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches() && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && matcher2.matches() || StringUtils.isEmpty(ivrLibaExtemplatescript.getSelfRegex2()) && StringUtils.isNotEmpty(ivrLibaExtemplatescript.getSelfRegex()) && matcher.matches()) {
//将通用库匹配的,放到返回值中
// phoneCallBackYQVO.setValue(phoneCallBackYQVO.getValue() + ivrLibaExtemplatescript.getSwitchText());
phoneCallBackYQVO.setCommonValue(ivrLibaExtemplatescript.getSwitchText());
les = ivrLibaExtemplatescript;
}
break;
}
log.info("是否需要挂机:{}", les);
if (ObjectUtils.isNotEmpty(les)) {
//对匹配的结果处理一下(看看是不是需要挂机)
if (les.getIsEnd() != null && les.getIsEnd() == 1) {
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(6L);
ss.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(ss);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//可以挂机了
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + les.getSwitchText());
//将结果写进detail表
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ivrTaskTemplateScriptVO.setExtemplateText(les.getSwitchText());
serviceSubtaskDetailList.add(getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate));
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
return phoneCallBackYQVO;
}
}
}
//如果是文本回调
//根据问题ID获取该问题的类型
if (ivrTaskTemplateScriptVO.getScriptType().equals("1")) {
//用来标记,是否有匹配上的
Integer flag = 0;
//1-AI识别
String url = taskSysConfigPort.selectConfigValue("sys.voice.match.ai.url", phoneCallReqYQVO.getOrgid());
if (ObjectUtils.isNotEmpty(url)) {
PhoneCallBackYQVO aiMatchResult = AiMatch(url, phoneCallReqYQVO, phoneCallBackYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate, ivrTaskTemplateScripts, scriptId, flag, phoneCallReqYQVO.getUuid());
if (aiMatchResult != null) {
return aiMatchResult;
}
} else {
//是选择题
for (int j = 0; j < ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().size(); j++) {
log.error("phoneCallReqYQVO.getAsrtext()的值为:{}", phoneCallReqYQVO.getAsrtext());
if (StringUtils.isEmpty(phoneCallReqYQVO.getAsrtext())) {
continue;
}
boolean matchedFlag = false;
//包含
Matcher matcher = null;
if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex())) {
Pattern pattern = Pattern.compile(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex());
matcher = pattern.matcher(phoneCallReqYQVO.getAsrtext());
}
//不包含
Matcher matcher2 = null;
if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2())) {
Pattern pattern2 = Pattern.compile(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2());
matcher2 = pattern2.matcher(phoneCallReqYQVO.getAsrtext());
}
if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches() || StringUtils.isEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && matcher2.matches() || StringUtils.isEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex2()) && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getTargetregex()) && matcher.matches()) {
matchedFlag = true;
}
//说明匹配正确了
if (matchedFlag) {
//这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
log.info("匹配正确了吗--------------");
ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).setIsUserOperation(1);
ivrTaskTemplateTargetoptionService.updateIvrTaskTemplateTargetoption(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j));
//将患者的回签写进service_subtask_detail中
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ivrTaskTemplateScriptVO.setQuestionResult(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getOptiondesc());
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
//判断一下当前的问题是不是满意度问题,并且dutyDeptCode是否有值,并且选项是不是异常选项,如果全符合,则往满意度问题异常表新增
if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && 1 == ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getIsabnormal()) {
ServiceSubtaskDetailTrace subtaskDetailTrace = new ServiceSubtaskDetailTrace();
//用taskid、subid和scriptid去获取detailid
ServiceSubtaskDetail ssd = new ServiceSubtaskDetail();
ssd.setSubId(serviceSubtask.getId());
ssd.setTaskid(serviceSubtask.getTaskid());
ssd.setScriptid(StringUtils.isNotEmpty(scriptId) ? Long.valueOf(scriptId) : null);
List serviceSubtaskDetails = taskSubtaskApi.findSubtaskDetails(ssd);
subtaskDetailTrace.setDetailId(CollectionUtils.isNotEmpty(serviceSubtaskDetails) ? serviceSubtaskDetails.get(0).getId() : null);
subtaskDetailTrace.setSubId(serviceSubtask.getId());
subtaskDetailTrace.setTaskid(serviceSubtask.getTaskid());
subtaskDetailTrace.setTemplateid(ivrTaskTemplateScriptVO.getId());
subtaskDetailTrace.setTemplatequestionnum(ivrTaskTemplateScriptVO.getScriptno());
subtaskDetailTrace.setSwitchid(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getId());
subtaskDetailTrace.setQuestiontext(ivrTaskTemplateScriptVO.getScriptContent());
subtaskDetailTrace.setQuestionvoice(null);
subtaskDetailTrace.setCategoryname(ivrTaskTemplateScriptVO.getScriptAssortname());
subtaskDetailTrace.setCategoryid(ivrTaskTemplateScriptVO.getScriptAssortid());
//获取所有选项
String optionDescStr = Optional.ofNullable(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList()).filter(list -> !list.isEmpty()).map(list -> list.stream().map(IvrTaskTemplateTargetoption::getOptiondesc).filter(Objects::nonNull).collect(Collectors.joining("&"))).orElse("");
subtaskDetailTrace.setTargetid(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getId());
subtaskDetailTrace.setTargetvalue(optionDescStr);
subtaskDetailTrace.setMatchedtext(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getOptiondesc());
subtaskDetailTrace.setValueType(serviceSubtaskDetails.get(0).getValueType());
subtaskDetailTrace.setTemplateType(1);
SvyLibScriptCategory svyLibScriptCategory = svyLibScriptCategoryService.selectSvyLibScriptCategoryById(ivrTaskTemplateScriptVO.getScriptAssortid());
subtaskDetailTrace.setType(svyLibScriptCategory.getType());
subtaskDetailTrace.setScriptid(ivrTaskTemplateScriptVO.getId());
subtaskDetailTrace.setAsrtext(phoneCallReqYQVO.getAsrtext());
subtaskDetailTrace.setRecordpath(phoneCallReqYQVO.getRecordpath());
subtaskDetailTrace.setPatid(serviceSubtask.getPatid());
JSONObject patdescJson = new JSONObject();
patdescJson.put("sendname", serviceSubtask.getSendname());
patdescJson.put("phone", serviceSubtask.getPhone());
patdescJson.put("age", serviceSubtask.getAge());
patdescJson.put("sex", serviceSubtask.getSex() != null ? serviceSubtask.getSex() == 1 ? "男" : "女" : null);
subtaskDetailTrace.setPatdesc(patdescJson.toJSONString());
subtaskDetailTrace.setTodeptcode(ivrTaskTemplateScriptVO.getDutyDeptCode());
subtaskDetailTrace.setTodeptname(ivrTaskTemplateScriptVO.getDutyDeptName());
subtaskDetailTrace.setOrgid(serviceSubtask.getOrgid());
subtaskDetailTrace.setHandleFlag("0");
subtaskDetailTrace.setGuid(phoneCallReqYQVO.getGuid());
subtaskDetailTrace.setCreateTime(new Date());
subtaskDetailTrace.setUpdateTime(new Date());
subtaskDetailTrace.setOrgid(phoneCallReqYQVO.getOrgid());
taskSubtaskApi.insertDetailTrace(subtaskDetailTrace);
}
//判断一下,这个选项结果是不是还有继续问下去的必要,例如选项结果是别人不想继续回答问题,就要结束掉
if (ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getIsEnd() == 1) {
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
return phoneCallBackYQVO;
}
flag = 1;
//将当前前的播报状态删除,给下一题让位
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
// //获取下一题
log.error("获取下一题的信息:{}", ivrTaskTemplateScriptVO);
if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1") || ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
Long nextQuestion = null;
if (ivrTaskTemplateScriptVO.getBranchFlag().equals("1")) {
nextQuestion = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getNextQuestion();
//更新分数
double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
score = BigDecimal.valueOf(score).add(new BigDecimal(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score);
} else {
nextQuestion = ivrTaskTemplateScriptVO.getNextScriptno();
//更新分数
Object obj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
Double score = (obj == null ? new Double(0.00) : new Double(((Double) obj).doubleValue()));
score = BigDecimal.valueOf(score).add(new BigDecimal(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(j).getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
}
if (nextQuestion == null || nextQuestion == 0L) {
//如果下一题为空,或者为0,则挂机
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(6L);
ss.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(ss);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
//将结果写进detail表
ServiceSubTaskDetailReq ssdReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList2 = new ArrayList<>();
serviceSubtaskDetailList.add(getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate));
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList2);
ssdReq.setGuid(phoneCallReqYQVO.getGuid());
ssdReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(ssdReq);
return phoneCallBackYQVO;
}
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (script.getSort() == nextQuestion.intValue()) {
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = StringUtils.isNotEmpty(script.getIvrtext()) ? script.getIvrtext() : script.getScriptContent();
log.error("下一题问题:{}", scriptContent);
log.error("下一题的子任务是:{}", serviceSubtask);
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
//将该患者的Redis中的题目ID,进行修改
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim(), script.getId().toString(), 120, TimeUnit.MINUTES);
//删除无响应
redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
}
}
} else if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
//更新一下分数
double score = 0.0;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (double) scoreObj;
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setSendstate(6L);
serviceSubtask.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//设置结束语
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
Long id = serviceSubtask.getId();
Map map = delRedisValue(null, id.toString());
log.error("map的值为:{}", map);
if (ObjectUtils.isNotEmpty(map))
redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
// return phoneCallBackYQVO;
}
} else {
log.info("没有匹配上----------------------------");
//flag=0,说明没 匹配上,也要把患者说的话记录下来
if (j == ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().size() - 1 && flag == 0) {
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
//如果没有 匹配上,这个必须为null
serviceSubtaskDetailList.get(0).setMatchedtext("");
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
}
continue;
}
}
}
//都没有匹配到
if (StringUtils.isEmpty(phoneCallBackYQVO.getValue())) {
log.info("都没有匹配到-------------------------");
Integer count = null;
Object countObj = redisCache.getCacheObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
if (ObjectUtils.isNotEmpty(countObj)) count = (Integer) countObj;
if (count != null && count >= ivrTaskTemplate.getMateNum()) {
//如果count已经大于或等于没有匹配次数
if (ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getBranchFlag().equals("0") && ivrTaskTemplateScriptVO.getNextScriptno() == 0 || ivrTaskTemplateScriptVO.getBranchFlag().equals("1") && ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getBranchFlag().equals("1") && ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
//如果是最后一道题,或者没有下一题了,就直接挂机
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
if (StringUtils.isNotEmpty(phoneCallBackYQVO.getValue()))
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + phoneCallBackYQVO.getValue() + serviceTask1.getJsy());
else phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setSendstate(6L);
serviceSubtask.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
//去redis中,把该子任务ID删除
Long id = serviceSubtask.getId();
Map map = delRedisValue(null, id.toString());
if (ObjectUtils.isNotEmpty(map)) {
redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
}
// return phoneCallBackYQVO;
} else {
//根据ivrTaskTemplateScriptVO.getNextScriptno()获取下一题进行提问
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = StringUtils.isNotEmpty(script.getIvrtext()) ? script.getIvrtext() : script.getScriptContent();
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
//将该患者的Redis中的题目ID,进行修改
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim(), script.getId().toString(), 120, TimeUnit.MINUTES);
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
score = BigDecimal.valueOf(score).add(new BigDecimal(script.getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
}
}
}
} else {
if (count == null)
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid(), 1, 120, TimeUnit.MINUTES);
else
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid(), count + 1, 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(ivrTaskTemplateScriptVO.getNoMatchText() + getObject(serviceSubtask, StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrtext()) ? ivrTaskTemplateScriptVO.getIvrtext() : ivrTaskTemplateScriptVO.getScriptContent()));
}
}
} else {
//不是选择题,直接记录答案,将结果写到detail中
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
// String xh = idSort.split("-")[1];
//如果选项分支为1的话,则需要根据问题上的nextScriptno进行跳转
//问答题没有跳转
if (ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
for (IvrTaskTemplateScript ivrTaskTemplateScript1 : ivrTaskTemplateScripts) {
if (ivrTaskTemplateScriptVO.getNextScriptno().intValue() == ivrTaskTemplateScript1.getSort()) {
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = StringUtils.isNotEmpty(ivrTaskTemplateScript1.getIvrtext()) ? ivrTaskTemplateScript1.getIvrtext() : ivrTaskTemplateScript1.getScriptContent();
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
redisCache.setCacheObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone(), ivrTaskTemplateScript1.getId().toString());
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
score = BigDecimal.valueOf(score).add(new BigDecimal(ivrTaskTemplateScriptVO.getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
}
}
} else if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
//没有下一题了,就结束了
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setRemark("电话拨打已完成");
serviceSubtask.setSendstate(6L);
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//去redis中,把该子任务ID删除
Long id = serviceSubtask.getId();
Map map = delRedisValue(null, id.toString());
redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
//在redis中保存一下结束语,在调用挂电话的方法时删除
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask1.getJsy(), 120, TimeUnit.MINUTES);
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
}
}
}
log.error("phoneCallBackYQVO的返回值是:{}", phoneCallBackYQVO);
return phoneCallBackYQVO;
}
private String getObject(ServiceSubtask serviceSubtask, String scriptContent) {
Map> param = getParam(serviceSubtask.getTaskid());
for (Map map : param.values()) {
for (String key : map.keySet()) {
scriptContent = scriptContent.replace(key, StringUtils.isNotEmpty(map.get(key)) ? map.get(key) : "");
}
}
if (StringUtils.isEmpty(scriptContent)) {
return scriptContent;
}
scriptContent = scriptContent.replace("${name}", StringUtils.isNotEmpty(serviceSubtask.getSendname()) ? serviceSubtask.getSendname() : "");
scriptContent = scriptContent.replace("${dzz}", StringUtils.isNotEmpty(serviceSubtask.getAddr()) ? serviceSubtask.getAddr() : "");
scriptContent = scriptContent.replace("${phone}", StringUtils.isNotEmpty(serviceSubtask.getTelcode()) ? serviceSubtask.getTelcode() : "");
return scriptContent;
}
/**
* 获取任务里的通配符
*
* @param taskId
* @return
*/
private Map> getParam(Long taskId) {
ServiceTask serviceTask = taskSubtaskApi.getTask(taskId);
ObjectMapper objectMapper = new ObjectMapper();
Map> serviceTaskMap = null;
try {
serviceTaskMap = objectMapper.readValue(serviceTask.getTextParam(), Map.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return serviceTaskMap;
}
private Map delRedisValue(String cache, String id) {
id = "," + id + ",";
String val = "";
String cacheName = "";
Map map = new HashMap<>();
if (StringUtils.isNotEmpty(cache)) {
val = redisCache.getCacheObject(cache);
if (!StringUtils.isEmpty(val)) {
if (val.contains(id)) {
val = val.replaceAll(id, "");
}
}
map.put("val", val);
map.put("cacheName", cache);
return map;
}
for (int i = 0; i < 6; i++) {
val = redisCache.getCacheObject("cache-0" + i);
if (!StringUtils.isEmpty(val)) {
if (val.contains(id)) {
val = val.replaceAll(id, "");
map.put("val", val);
map.put("cacheName", "cache-0" + i);
}
}
}
return map;
}
/**
* 雨绮任务拉取
*
* @return
*/
@Override
public List taskPull() {
//pullTaskVOList用于数据返回
List pullTaskVOList = new ArrayList<>();
List cacheList = new ArrayList<>();
ListOperations listOps = redisTemplate.opsForList();
//必须等ache-exist全部打完才能拉取下一批(主要是怕所有的数据都堆在电话的缓存里,在规定的时间打不完)
// long existSize = listOps.size("cache-exist");
// if (existSize > 0) return pullTaskVOList;
int count = 0;
long size = listOps.size("cache-0");
log.info("---------打电话之前缓存中的数据量:{}", size);
if (size > 0) {
//phoneCount() 通过给出的每个小时需要打出的电话量,算出到晚上8点一点能打出多少个电话,获取到总量
//如果需要立即执行的数据量大于一天要执行的上限,则只取上限的数量,其它的则放回redis中
count = Math.min(phoneCount(), (int) size);
if (count != 0) {
cacheList = listOps.range("cache-0", 0, count - 1);
} else {
return null;
}
}
log.info("任务拉取cache-0的值是多少:{}", cacheList);
// cache-0为立即发起的,其它的先推迟
if (!CollectionUtils.isEmpty(cacheList)) {
pullTaskVOList = getPullTaskList(cacheList, "cache-0");
// 删除已处理的数据
listOps.trim("cache-0", count, -1);
log.info("打电话之后缓存中的数据量---------:{}", listOps.size("cache-0"));
} else {
for (int i = 1; i < 6; i++) {
//取出从cache-1 到 cache-5的第一个子任务信息
try {
Long size1 = listOps.size("cache-" + i);
if (size1 == null || size1 == 0) continue;
int count1 = Math.min(phoneCount(), size1.intValue());
List value = listOps.range("cache-0" + i, 0, count1 - 1);
List pullTaskVOList2 = getPullTaskList(value, "cache-" + i);
if (CollectionUtils.isNotEmpty(pullTaskVOList2) && pullTaskVOList2.size() > 0) {
pullTaskVOList.addAll(pullTaskVOList2);
}
//将处理过的数据删除
listOps.trim("cache-0" + i, count1, -1);
} catch (Exception e) {
// log.error("看着烦");
}
}
}
//existList用来记录接下来需要执行的子任务ID
// List existList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(pullTaskVOList)) {
//给回调参数赋值
for (PullTaskVO pullTaskVO : pullTaskVOList) {
// existList.add(pullTaskVO.getTaskid());
pullTaskVO.setAsrcallback(ASRCallBackPath);
}
}
// if (existList.size() != 0) redisCache.setCacheListRight("cache-exist", existList);
log.info("-----------实际拉取的电话数据量:{}", CollectionUtils.isNotEmpty(pullTaskVOList) ? pullTaskVOList.size() : null);
return pullTaskVOList;
}
private List getPullTaskList(List subIds, String cacheName) {
log.error("任务拉取subIds的值是多少:{}", subIds);
//pullTaskVOList用于数据返回
List pullTaskVOList = new ArrayList<>();
//newValue0用于保存没有处理的子 任务
// String newValue0 = "";
List newValue0 = new ArrayList<>();
//根据,获取子任务的ID
// String[] split = subIds.split(",,");
for (int i = 0; i < subIds.size(); i++) {
if (cacheName.equals("cache-0") && i < subIds.size() || !cacheName.equals("cache-0") && i < 1) {
PullTaskVO pullTaskVO = new PullTaskVO();
String subId = subIds.get(i).trim();
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(subId));
if (ObjectUtils.isEmpty(serviceSubtask)) {
log.error("该subId有问题,在表中查询不到:{}", subId);
continue;
}
if (StringUtils.isEmpty(serviceSubtask.getPhone())) {
serviceSubtask.setRemark("手机号为空");
serviceSubtask.setSendstate(4L);
serviceSubtask.setResult("error");
// serviceSubtask.setFinishtime(new Date());
taskSubtaskApi.updateSubtask(serviceSubtask);
continue;
}
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
if (ObjectUtils.isEmpty(ivrTaskTemplate)) continue;
//通过任务模板中的"第一次问题编号"获取第一个问题;
IvrTaskTemplateScript ivrTaskTemplateScript = null;
IvrTaskTemplateScript ivrTaskTemplateScript1 = new IvrTaskTemplateScript();
ivrTaskTemplateScript1.setTemplateID(ivrTaskTemplate.getId());
List ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript1);
aa:
for (IvrTaskTemplateScript ivrTaskTemplateScript2 : ivrTaskTemplateScripts) {
if (ivrTaskTemplate.getFirstQuestionNum() == Long.valueOf(ivrTaskTemplateScript2.getSort())) {
ivrTaskTemplateScript = ivrTaskTemplateScript2;
break aa;
}
}
//如果ivrTaskTemplateScript为空,也就没有往下执行的必要了
if (ObjectUtils.isEmpty(ivrTaskTemplateScript)) {
log.error("---------这个ivrTaskTemplate.getId()的问题为空:{}", ivrTaskTemplate.getId());
continue;
}
//获取通配符匹配过后的问题
String scriptContent = ivrTaskTemplateScript.getIvrtext();
if (StringUtils.isEmpty(scriptContent)) scriptContent = ivrTaskTemplateScript.getScriptContent();
String scrContent = getObject(serviceSubtask, scriptContent);
String kcb = serviceTask.getKcb() + "," + scrContent;
//封装返回数据
//taskId = 子任务ID + 问题ID +问题序号
pullTaskVO.setTaskid(subId);
pullTaskVO.setAppkey(app_key_yq);
pullTaskVO.setSections(LocalTime.now().format(DateTimeFormatter.ofPattern("hh:mm")) + "-" + LocalTime.now().plusMinutes(1).format(DateTimeFormatter.ofPattern("hh:mm")));
pullTaskVO.setPhones(serviceSubtask.getPhone());
pullTaskVO.setPrologue(kcb);
if (cacheName.equals("cache-0")) pullTaskVO.setDisplayNo("2");
else pullTaskVO.setDisplayNo("2");
pullTaskVOList.add(pullTaskVO);
redisCache.setCacheObject(subId.trim() + "-" + serviceSubtask.getPhone().trim(), ivrTaskTemplateScript.getId().toString(), 120, TimeUnit.MINUTES);
} else {
newValue0.add(subIds.get(i));
redisCache.setCacheListRight(cacheName, newValue0);
}
}
return pullTaskVOList;
}
@Override
public Integer saveQuestionAnswerPhone(ServiceSubTaskDetailReq serviceSubTaskDetailReq) {
int i = 0;
log.info("保存电话回调内容 saveQuestionAnswerPhone:{}", serviceSubTaskDetailReq);
if (StringUtils.isNotEmpty(serviceSubTaskDetailReq.getParam1())) {
RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
Long tid = Long.valueOf(rsaPublicKeyExample.decryptedData(serviceSubTaskDetailReq.getParam1(), pri_key));
Long pid = Long.valueOf(rsaPublicKeyExample.decryptedData(serviceSubTaskDetailReq.getParam2(), pri_key));
ServiceSubtaskEntity ivrTaskSingle = new ServiceSubtaskEntity();
ivrTaskSingle.setTaskid(tid);
ivrTaskSingle.setPatid(pid);
List selectServiceSubtaskList = taskSubtaskApi.findSubtasks(ivrTaskSingle);
if (CollectionUtils.isEmpty(selectServiceSubtaskList) || selectServiceSubtaskList.size() == 0) {
log.error("报错了,selectServiceSubtaskList数据为空了:{}", ivrTaskSingle);
return 0;
}
//随访
for (ServiceSubtaskDetail serviceSubtaskDetail : serviceSubTaskDetailReq.getServiceSubtaskDetailList()) {
if (serviceSubtaskDetail.getScriptid() != null) {
//设置一下问题分类
IvrTaskTemplateScript ivrTaskTemplateScript = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptByID(serviceSubtaskDetail.getScriptid());
if (ivrTaskTemplateScript != null)
serviceSubtaskDetail.setCategoryid(ivrTaskTemplateScript.getScriptAssortid());
serviceSubtaskDetail.setIsMydException(ivrTaskTemplateScript.getIsMydException());
serviceSubtaskDetail.setDimension(ivrTaskTemplateScript.getDimension());
}
serviceSubtaskDetail.setSubId(selectServiceSubtaskList.get(0).getId());
// serviceSubtaskDetail.setId(UUID.randomUUID().toString());
serviceSubtaskDetail.setCreateTime(new Date());
serviceSubtaskDetail.setGuid(selectServiceSubtaskList.get(0).getGuid());
serviceSubtaskDetail.setOrgid(serviceSubTaskDetailReq.getOrgid());
serviceSubtaskDetail.setGuid(serviceSubTaskDetailReq.getGuid());
i = taskSubtaskApi.insertSubtaskDetail(serviceSubtaskDetail);
}
} else {
if (serviceSubTaskDetailReq != null && CollectionUtils.isNotEmpty(serviceSubTaskDetailReq.getServiceSubtaskDetailList())) {
for (ServiceSubtaskDetail serviceSubtaskDetail : serviceSubTaskDetailReq.getServiceSubtaskDetailList()) {
if (serviceSubtaskDetail.getScriptid() != null) {
//设置一下问题分类
IvrTaskTemplateScript ivrTaskTemplateScript = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptByID(serviceSubtaskDetail.getScriptid());
if (ivrTaskTemplateScript != null)
serviceSubtaskDetail.setCategoryid(ivrTaskTemplateScript.getScriptAssortid());
}
serviceSubtaskDetail.setCreateTime(new Date());
serviceSubtaskDetail.setGuid(serviceSubTaskDetailReq.getGuid());
serviceSubtaskDetail.setOrgid(serviceSubTaskDetailReq.getOrgid());
//先根据子任务id,任务ID和问题序号查询一下,该问题是否已经有值,如果有值,直接修改,如果为空,直接插入
ServiceSubtaskDetail ssd = new ServiceSubtaskDetail();
ssd.setSubId(serviceSubtaskDetail.getSubId());
ssd.setTaskid(serviceSubtaskDetail.getTaskid());
ssd.setScriptid(serviceSubtaskDetail.getScriptid());
if (serviceSubtaskDetail.getSubId() != null) {
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(serviceSubtaskDetail.getSubId());
ssd.setGuid(serviceSubtask.getGuid());
ssd.setOrgid(serviceSubtask.getOrgid());
}
List serviceSubtaskDetails = taskSubtaskApi.findSubtaskDetails(ssd);
if (CollectionUtils.isNotEmpty(serviceSubtaskDetails) && StringUtils.isNotEmpty(serviceSubtaskDetails.get(0).getMatchedtext())) {
serviceSubtaskDetail.setId(serviceSubtaskDetails.get(0).getId());
taskSubtaskApi.updateSubtaskDetail(serviceSubtaskDetail);
} else {
if (serviceSubtaskDetail.getSubId() != null) {
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(serviceSubtaskDetail.getSubId());
serviceSubtaskDetail.setGuid(serviceSubtask.getGuid());
serviceSubtaskDetail.setOrgid(serviceSubtask.getOrgid());
}
i = taskSubtaskApi.insertSubtaskDetail(serviceSubtaskDetail);
}
}
}
}
return i;
}
@Override
public Integer recordAccept(PhoneCallRecordVO phoneCallRecordVO) {
Object cacheObject = redisCache.getCacheObject(phoneCallRecordVO.getTaskid() + "recordAccept-hungup");
if (phoneCallRecordVO.getHangup_cause().equals("NO_USER_RESPONSE") || ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("1")) {
//无人接听
//记录电话发送状态
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallRecordVO.getTaskid()));
setFailPreachForm(serviceSubtask, "3", "无人接听", "4");
//进行短信补偿
//原 getSmsCompensate(...) 未随电话模块化搬迁(模块化前调用点就已注释、属死代码),
//如需恢复短信补偿,请走 service_out_path / 短信发送方的归属模块 API,见 doc/电话模块化_调研与实施方案.md
redisCache.deleteObject(phoneCallRecordVO.getTaskid() + "recordAccept-hungup");
// redisCache.removeElementFromList("cache-exist", phoneCallRecordVO.getTaskid());
} else if (ObjectUtils.isNotEmpty(cacheObject) && String.valueOf(cacheObject).equals("2")) {
// if (phoneCallRecordVO.getAnswered() != null && phoneCallRecordVO.getAnswered() == true) {
log.error("有人接电话了,并且完了");
//说明有人接了
int startIndex = phoneCallRecordVO.getRecord_path().indexOf("voice") + "voice".length() + 1; // 加1是跳过/符号
int endIndex = phoneCallRecordVO.getRecord_path().lastIndexOf("/");
String result = phoneCallRecordVO.getRecord_path().substring(startIndex, endIndex);
ServiceSubtask serviceSubtask = new ServiceSubtask();
serviceSubtask.setRemark("电话拨打已完成");
serviceSubtask.setSendstate(6L);
serviceSubtask.setId(Long.valueOf(phoneCallRecordVO.getTaskid()));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setUpdateTime(new Date());
log.error("电话拨打已完成serviceSubtask的值为:{}", serviceSubtask);
taskSubtaskApi.updateSubtask(serviceSubtask);
setFailPreachForm(serviceSubtask, StringUtils.isNotEmpty(serviceSubtask.getCurrentPreachform()) ? serviceSubtask.getCurrentPreachform() : "3", "电话拨打已完成", "9");
//下载文件
taskFtpPort.downloadFolder("/" + LocalDate.now().toString(), profile + "/upload/vadio/voice/" + LocalDate.now().toString());
redisCache.deleteObject(phoneCallRecordVO.getTaskid() + "recordAccept-hungup");
} else {
//患者拒绝随访
//先把该subId从cache_exist中剔除,只要有回调就剔除(目的是,尽快让cache-exist为空,去缓存下一批要打的电话;这里剔除不影响电话的正常业务)
// redisCache.removeElementFromList("cache-exist", phoneCallRecordVO.getTaskid());
ServiceSubtask serviceSubtask = new ServiceSubtask();
serviceSubtask.setRemark("电话接通成功,患者拒绝随访");
serviceSubtask.setId(Long.valueOf(phoneCallRecordVO.getTaskid()));
serviceSubtask.setSendstate(6L);
taskSubtaskApi.updateSubtask(serviceSubtask);
// int startIndex = phoneCallRecordVO.getRecord_path().indexOf("voice") + "voice".length() + 1; // 加1是跳过/符号
// int endIndex = phoneCallRecordVO.getRecord_path().lastIndexOf("/");
// String result = phoneCallRecordVO.getRecord_path().substring(startIndex, endIndex);
//下载文件
// taskFtpPort.downloadFolder("/" + LocalDate.now().toString(), profile + "/upload/vadio/voice/" + LocalDate.now().toString());
redisCache.deleteObject(phoneCallRecordVO.getTaskid() + "recordAccept-hungup");
ServiceSubtask ss = taskSubtaskApi.getSubtask(serviceSubtask.getId());
setFailPreachForm(ss, StringUtils.isNotEmpty(ss.getCurrentPreachform()) ? ss.getCurrentPreachform() : "3", "电话接通成功,患者拒绝随访", "5");
}
return 1;
}
private IvrTaskTemplateScriptVO getNextQuestion(List IvrTaskTemplateScriptVOList, IvrTaskTemplateScriptVO IvrTaskTemplateScriptVO) {
for (int j = 0; j < IvrTaskTemplateScriptVOList.size(); j++) {
if (IvrTaskTemplateScriptVOList.get(j).getTargetid() == IvrTaskTemplateScriptVO.getTargetid() + 1) {
// 对该条templateScriptVO进行处理
return IvrTaskTemplateScriptVOList.get(j);
}
}
return null;
}
private ServiceSubtaskDetail getServiceSubtaskDetail(PhoneCallReqYQVO phoneCallReqYQVO, IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO, ServiceSubtask serviceSubtask, IvrTaskTemplate ivrTaskTemplate) {
log.info("-----------------phoneCallReqYQVO的值为:{}", phoneCallReqYQVO);
ServiceSubtaskDetail serviceSubtaskDetail = new ServiceSubtaskDetail();
serviceSubtaskDetail.setSubId(Long.valueOf(phoneCallReqYQVO.getTaskid()));
ServiceSubtask serviceSubtask1 = taskSubtaskApi.getSubtask(Long.valueOf(phoneCallReqYQVO.getTaskid()));
if (serviceSubtask1 != null) {
serviceSubtaskDetail.setTaskid(serviceSubtask1.getTaskid());
serviceSubtaskDetail.setPatid(serviceSubtask1.getPatid());
}
serviceSubtaskDetail.setTargetid(ivrTaskTemplateScriptVO.getTargetid() != null ? ivrTaskTemplateScriptVO.getTargetid().intValue() : null);
serviceSubtaskDetail.setUuid(phoneCallReqYQVO.getUuid());
serviceSubtaskDetail.setPhone(phoneCallReqYQVO.getPhone());
serviceSubtaskDetail.setOperate(serviceSubtask.getCreateBy());
serviceSubtaskDetail.setDisplayno(phoneCallReqYQVO.getPhone());
serviceSubtaskDetail.setAssigntime(System.currentTimeMillis());
serviceSubtaskDetail.setStarttime(System.currentTimeMillis());
serviceSubtaskDetail.setAnswertime(System.currentTimeMillis());
serviceSubtaskDetail.setCategoryid(ivrTaskTemplateScriptVO.getScriptAssortid());
serviceSubtaskDetail.setAsrtext("无应答");
if (StringUtils.isNotEmpty(phoneCallReqYQVO.getAsrtext()))
serviceSubtaskDetail.setAsrtext(phoneCallReqYQVO.getAsrtext());
serviceSubtaskDetail.setBeginTime(System.currentTimeMillis());
serviceSubtaskDetail.setEndTime(System.currentTimeMillis());
serviceSubtaskDetail.setSentEnd(1L);
serviceSubtaskDetail.setTemplateid(ivrTaskTemplate.getId().toString());
serviceSubtaskDetail.setTemplatequestionnum(ivrTaskTemplateScriptVO.getScriptno());
serviceSubtaskDetail.setQuestiontext(StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrtext()) ? ivrTaskTemplateScriptVO.getIvrtext() : ivrTaskTemplateScriptVO.getScriptContent());
serviceSubtaskDetail.setQuestionvoice(phoneCallReqYQVO.getRecordpath());
serviceSubtaskDetail.setCategoryname(ivrTaskTemplateScriptVO.getScriptType());
serviceSubtaskDetail.setTargetoptions(ivrTaskTemplateScriptVO.getTargetOptions());
serviceSubtaskDetail.setExtemplateText(ivrTaskTemplateScriptVO.getExtemplateText());
serviceSubtaskDetail.setScriptid(ivrTaskTemplateScriptVO.getId());
serviceSubtaskDetail.setLibTemplateid(serviceSubtask.getLibtemplateid() != null ? serviceSubtask.getLibtemplateid().intValue() : null);
int i = 1;
for (IvrTaskTemplateTargetoption ivrTaskTemplateTargetoption : ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList()) {
if (ivrTaskTemplateTargetoption.getIsUserOperation() == 1) {
serviceSubtaskDetail.setMatchedtext(ivrTaskTemplateTargetoption.getTargetvalue());
serviceSubtaskDetail.setScore(ivrTaskTemplateTargetoption.getScore() != null ? ivrTaskTemplateTargetoption.getScore().toString() : "0");
}
serviceSubtaskDetail.setTargetvalue(StringUtils.isEmpty(serviceSubtaskDetail.getTargetvalue()) ? ivrTaskTemplateTargetoption.getTargetvalue() : serviceSubtaskDetail.getTargetvalue() + "&" + ivrTaskTemplateTargetoption.getTargetvalue());
}
serviceSubtaskDetail.setAddtime(new Date());
serviceSubtaskDetail.setIsupload(0L);
serviceSubtaskDetail.setUploadTime(new Date());
serviceSubtaskDetail.setDelFlag("0");
serviceSubtaskDetail.setValueType(ivrTaskTemplateScriptVO.getScriptType());
return serviceSubtaskDetail;
}
//通过当前时间,拉取电话总数
private Integer phoneCount() {
// 当前时间
LocalTime currentTime = LocalTime.now();
// 目标时间(晚上 8 点)
LocalTime targetTime = LocalTime.of(phoneEndHour, 0);
// // 计算当前时间到目标时间的时长
// Duration duration = Duration.between(currentTime, targetTime);
// // 获取剩余时间的小时数
// long remainingHours = 0;
// long remainingMinutes = duration.toMinutes();
// //如果超过8点,就设置为0
// //距离结束时间小于20分钟,就不拉取了
// if (remainingMinutes < 20) remainingHours = 0;
// else if (remainingMinutes < 60 && remainingMinutes > 20) remainingHours = 1;
// else if (remainingMinutes > 60) remainingHours = remainingMinutes / 60;
// // 计算剩余可以打的电话数
// int remainingCalls = (int) (remainingHours * phoneUpEveryHour);
// return remainingCalls;
if (currentTime.isBefore(targetTime)) {
//如果当前时间还在截止时间内,则继续发
return phoneUpEveryHour;
}
return 0;
}
/**
* @param serviceSubtask
* @param preachform
* @param remark
* @param failSendstate
* @return
*/
public Boolean setFailPreachForm(ServiceSubtask serviceSubtask, String preachform, String remark, String failSendstate) {
log.info("setFailPreachForm 随访流程处理 serviceSubtask:{}, preachform:{}, remark:{}, failSendstate:{}", serviceSubtask, preachform, remark, failSendstate);
//将状态设置为失败
ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
serviceSubtaskPreachform.setSubid(serviceSubtask.getId());
serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid());
serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid());
//获取该患者的发送方式总数
List spSize = taskPreachformPort.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
serviceSubtaskPreachform.setPreachform(preachform);
//1:未发送状态
serviceSubtaskPreachform.setSendstate("1");
if (preachform.equals("3")) {
//电话进入队列后,状态会变成2
serviceSubtaskPreachform.setSendstate("2");
}
List serviceSubtaskPreachforms = taskPreachformPort.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
ServiceSubtaskPreachform serviceSubtaskPreachform1 = serviceSubtaskPreachforms.get(0);
serviceSubtaskPreachform1.setSendstate(failSendstate);
serviceSubtaskPreachform1.setRemark(remark);
taskPreachformPort.updateServiceSubtaskPreachform(serviceSubtaskPreachform1);
//如果当前的preachform已经是最后一个了,那直接将serviceSubtask的sendstate状态改成5就行了(全失败了)
if (serviceSubtaskPreachform1.getSort() == spSize.size() && failSendstate.equals("4")) {
serviceSubtask.setCurrentPreachform(preachform);
serviceSubtask.setSendstate(5L);
serviceSubtask.setRemark(remark + ";所有执行方式均未获取结果,任务失败");
taskSubtaskApi.updateSubtask(serviceSubtask);
return true;
} else {
//加入目前补偿里的 remark
serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + "," + remark : remark);
taskSubtaskApi.updateSubtask(serviceSubtask);
}
}
//尽管失败,这里也将当前发送方式继续设置成“电话”,sendstate设置成3;因为ryTask里的补偿的定时任务运行时,会找到这条subtask,并进行处理
serviceSubtask.setCurrentPreachform(preachform);
serviceSubtask.setSendstate(3L);
//如果等于9,则说明电话正常结束了
if (failSendstate.equals("9")) serviceSubtask.setSendstate(6L);
serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime()));
taskSubtaskApi.updateSubtask(serviceSubtask);
return true;
}
private Date getNextVisitTime(Long subid, Long taskid, Date visitTime) {
ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform();
serviceSubtaskPreachform.setSubid(subid);
serviceSubtaskPreachform.setTaskid(taskid);
List serviceSubtaskPreachforms = taskPreachformPort.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
if (CollectionUtils.isNotEmpty(serviceSubtaskPreachforms)) {
//没有随访时间则按当天来算--临时
if (ObjectUtils.isEmpty(visitTime)) {
visitTime = new Date();
}
String compensateTime = serviceSubtaskPreachforms.get(0).getCompensateTime();
int hoursToAdd = Integer.valueOf(compensateTime) * 24;
Calendar calendar = Calendar.getInstance();
calendar.setTime(visitTime);
calendar.add(Calendar.HOUR_OF_DAY, hoursToAdd);
Date newDate = calendar.getTime();
return newDate;
}
return visitTime;
}
public PhoneCallBackSHVO getFirstQues(PhoneCallReqYQVO phoneCallReqYQVO) {
//用于返回
PhoneCallBackSHVO phoneCallBackSHVO = new PhoneCallBackSHVO();
//根据手机号获取用户的的子任务信息
ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity();
serviceSubtaskVO.setPhone(phoneCallReqYQVO.getPhone());
serviceSubtaskVO.setType("1");
serviceSubtaskVO.setSendstate(2L);
List serviceSubtasks = taskSubtaskApi.findSubtasks(serviceSubtaskVO);
if (CollectionUtils.isNotEmpty(serviceSubtasks)) {
ServiceSubtask serviceSubtask = serviceSubtasks.get(0);
IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
//通过任务模板中的"第一次问题编号"获取第一个问题;
IvrTaskTemplateScript ivrTaskTemplateScript = null;
IvrTaskTemplateScript ivrTaskTemplateScript1 = new IvrTaskTemplateScript();
ivrTaskTemplateScript1.setTemplateID(ivrTaskTemplate.getId());
List ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript1);
for (IvrTaskTemplateScript ivrTaskTemplateScript2 : ivrTaskTemplateScripts) {
if (ivrTaskTemplate.getFirstQuestionNum() == Long.valueOf(ivrTaskTemplateScript2.getSort())) {
ivrTaskTemplateScript = ivrTaskTemplateScript2;
break;
}
}
//获取开场白
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackSHVO.setSubId(serviceSubtask.getId());
phoneCallBackSHVO.setScriptId(ivrTaskTemplateScript.getId());
phoneCallBackSHVO.setSort(ivrTaskTemplateScript.getSort());
phoneCallBackSHVO.setTaskTemplateid(ivrTaskTemplateScript.getTemplateID());
phoneCallBackSHVO.setScriptContent(serviceTask.getKcb() + "," + ivrTaskTemplateScript.getScriptContent());
}
return phoneCallBackSHVO;
}
/**
* 三汇ASR结果处理
*
* @param phoneCallResultYQVO
* @return
*/
public PhoneCallBackSHVO processResust(PhoneCallResultYQVO phoneCallResultYQVO) {
PhoneCallBackSHVO phoneCallBackSHVO = new PhoneCallBackSHVO();
//通过scriptid,获取所有的结果
String url = taskSysConfigPort.selectConfigValue("sys.voice.match.ai.url", phoneCallResultYQVO.getOrgid());
ServiceSubtask serviceSubtask = taskSubtaskApi.getSubtask(phoneCallResultYQVO.getSubId());
IvrTaskTemplate ivrTaskTemplate = ivrTaskTemplateService.selectIvrTaskTemplateByID(serviceSubtask.getTemplateid());
IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO = iIvrTaskTemplateScriptService.getTaskTempScriptInfoByid(Long.valueOf(phoneCallResultYQVO.getScriptId()));
Integer i = subtaskOptionMatchApi.matchOptionIndex(url, phoneCallResultYQVO.getScriptContent(), phoneCallResultYQVO.getAsrResult(), ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList(), phoneCallResultYQVO.getUuid());
if (i >= 0) {
String optiondesc = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList().get(i).getOptiondesc();
//将患者的回答写进service_subtask_detail中
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ivrTaskTemplateScriptVO.setQuestionResult(optiondesc);
PhoneCallReqYQVO phoneCallReqYQVO = new PhoneCallReqYQVO();
phoneCallReqYQVO.setTaskid("" + serviceSubtask.getId());
phoneCallReqYQVO.setPhone(phoneCallResultYQVO.getPhone());
phoneCallReqYQVO.setAsrtext(phoneCallResultYQVO.getAsrResult());
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallResultYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallResultYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
ivrTaskTemplateScript.setTemplateID(ivrTaskTemplateScriptVO.getTemplateID());
List ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript);
//获取下一题
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackSHVO.setScriptContent(serviceTask.getJsy());
phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
phoneCallBackSHVO.setSort(script.getSort());
phoneCallBackSHVO.setScriptId(script.getId());
phoneCallBackSHVO.setSubId(serviceSubtask.getId());
phoneCallBackSHVO.setStatus("0");
} else if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
phoneCallBackSHVO.setScriptContent(script.getScriptContent());
phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
phoneCallBackSHVO.setSort(script.getSort());
phoneCallBackSHVO.setScriptId(script.getId());
phoneCallBackSHVO.setSubId(serviceSubtask.getId());
break;
}
}
//把缓存清除
redisCache.deleteObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
} else {
//再将重复询问
//记录一下这个问题被问题的次数
Object cacheObject = redisCache.getCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
if (cacheObject == null || (Integer) cacheObject < ivrTaskTemplate.getMateNum()) {
// 获取选项集合中的 optiondesc 用于引导患者
List optionList = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList();
String optionDescStr = "";
if (optionList != null && !optionList.isEmpty()) {
optionDescStr = optionList.stream().map(IvrTaskTemplateTargetoption::getTargetvalue).filter(StringUtils::isNotEmpty).collect(Collectors.joining("或"));
}
String scriptContent = "请问" + phoneCallResultYQVO.getScriptContent();
if (StringUtils.isNotEmpty(optionDescStr)) {
scriptContent += ",你可以回答:" + optionDescStr;
}
phoneCallBackSHVO.setScriptContent(scriptContent);
phoneCallBackSHVO.setTaskTemplateid(phoneCallResultYQVO.getTaskTemplateid());
phoneCallBackSHVO.setSort(phoneCallResultYQVO.getSort());
phoneCallBackSHVO.setScriptId(phoneCallResultYQVO.getScriptId());
phoneCallBackSHVO.setSubId(phoneCallResultYQVO.getSubId());
if (cacheObject == null)
redisCache.setCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId(), 1, 120, TimeUnit.MINUTES);
else
redisCache.setCacheObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId(), (Integer) cacheObject + 1, 120, TimeUnit.MINUTES);
} else if ((Integer) cacheObject >= ivrTaskTemplate.getMateNum()) {
//如果已经问了规定次数,就不问了,继续问下一题(这个要商量一下,是继续问下一题,还是停了,是不是要做个开关)
IvrTaskTemplateScript ivrTaskTemplateScript = new IvrTaskTemplateScript();
ivrTaskTemplateScript.setTemplateID(ivrTaskTemplateScriptVO.getTemplateID());
List ivrTaskTemplateScripts = iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptList(ivrTaskTemplateScript);
//获取下一题
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
phoneCallBackSHVO.setScriptContent(script.getScriptContent());
phoneCallBackSHVO.setTaskTemplateid(script.getTemplateID());
phoneCallBackSHVO.setSort(script.getSort());
phoneCallBackSHVO.setScriptId(script.getId());
phoneCallBackSHVO.setSubId(serviceSubtask.getId());
break;
}
}
//把缓存清除
redisCache.deleteObject(phoneCallResultYQVO.getSubId() + "-" + phoneCallResultYQVO.getScriptId());
}
}
return phoneCallBackSHVO;
}
public PhoneCallBackYQVO AiMatch(String url, PhoneCallReqYQVO phoneCallReqYQVO, PhoneCallBackYQVO phoneCallBackYQVO, IvrTaskTemplateScriptVO ivrTaskTemplateScriptVO, ServiceSubtask serviceSubtask, IvrTaskTemplate ivrTaskTemplate, List ivrTaskTemplateScripts, String scriptId, Integer flag, String uuid) {
PhoneCallBackYQVO back = null;
List options = ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList();
String voiceText = phoneCallReqYQVO.getAsrtext();
String questionText = StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrtext()) ? ivrTaskTemplateScriptVO.getIvrtext() : ivrTaskTemplateScriptVO.getScriptContent();
Integer matched = -1;
log.info("AI匹配:url = {},questionText = {},voiceText = {},options = {},uuid ={}",
url,questionText,voiceText,options,uuid);
matched = subtaskOptionMatchApi.matchOptionIndex(url, questionText, voiceText, options, uuid);
//说明匹配正确了
if (matched != null && matched >= 0) {
IvrTaskTemplateTargetoption chosenOption = options.get(matched);
//这里应该先判断类型,去再修改,设置IsUserOperation是单选题的改法
log.info("匹配正确了吗--------------");
chosenOption.setIsUserOperation(1);
ivrTaskTemplateTargetoptionService.updateIvrTaskTemplateTargetoption(chosenOption);
//将患者的回签写进service_subtask_detail中
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ivrTaskTemplateScriptVO.setQuestionResult(chosenOption.getOptiondesc());
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
//判断一下当前的问题是不是满意度问题,并且dutyDeptCode是否有值,并且选项是不是异常选项,如果全符合,则往满意度问题异常表新增
if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && 1 == chosenOption.getIsabnormal()) {
ServiceSubtaskDetailTrace subtaskDetailTrace = new ServiceSubtaskDetailTrace();
//用taskid、subid和scriptid去获取detailid
ServiceSubtaskDetail ssd = new ServiceSubtaskDetail();
ssd.setSubId(serviceSubtask.getId());
ssd.setTaskid(serviceSubtask.getTaskid());
ssd.setScriptid(StringUtils.isNotEmpty(scriptId) ? Long.valueOf(scriptId) : null);
List serviceSubtaskDetails = taskSubtaskApi.findSubtaskDetails(ssd);
subtaskDetailTrace.setDetailId(CollectionUtils.isNotEmpty(serviceSubtaskDetails) ? serviceSubtaskDetails.get(0).getId() : null);
subtaskDetailTrace.setSubId(serviceSubtask.getId());
subtaskDetailTrace.setTaskid(serviceSubtask.getTaskid());
subtaskDetailTrace.setTemplateid(ivrTaskTemplateScriptVO.getId());
subtaskDetailTrace.setTemplatequestionnum(ivrTaskTemplateScriptVO.getScriptno());
subtaskDetailTrace.setSwitchid(chosenOption.getId());
subtaskDetailTrace.setQuestiontext(ivrTaskTemplateScriptVO.getScriptContent());
subtaskDetailTrace.setQuestionvoice(null);
subtaskDetailTrace.setCategoryname(ivrTaskTemplateScriptVO.getScriptAssortname());
subtaskDetailTrace.setCategoryid(ivrTaskTemplateScriptVO.getScriptAssortid());
//获取所有选项
String optionDescStr = Optional.ofNullable(ivrTaskTemplateScriptVO.getIvrTaskScriptTargetoptionList()).filter(list -> !list.isEmpty()).map(list -> list.stream().map(IvrTaskTemplateTargetoption::getOptiondesc).filter(Objects::nonNull).collect(Collectors.joining("&"))).orElse("");
subtaskDetailTrace.setTargetid(chosenOption.getId());
subtaskDetailTrace.setTargetvalue(optionDescStr);
subtaskDetailTrace.setMatchedtext(chosenOption.getOptiondesc());
subtaskDetailTrace.setValueType(serviceSubtaskDetails.get(0).getValueType());
subtaskDetailTrace.setTemplateType(1);
SvyLibScriptCategory svyLibScriptCategory = svyLibScriptCategoryService.selectSvyLibScriptCategoryById(ivrTaskTemplateScriptVO.getScriptAssortid());
subtaskDetailTrace.setType(svyLibScriptCategory.getType());
subtaskDetailTrace.setScriptid(ivrTaskTemplateScriptVO.getId());
subtaskDetailTrace.setAsrtext(phoneCallReqYQVO.getAsrtext());
subtaskDetailTrace.setRecordpath(phoneCallReqYQVO.getRecordpath());
subtaskDetailTrace.setPatid(serviceSubtask.getPatid());
JSONObject patdescJson = new JSONObject();
patdescJson.put("sendname", serviceSubtask.getSendname());
patdescJson.put("phone", serviceSubtask.getPhone());
patdescJson.put("age", serviceSubtask.getAge());
patdescJson.put("sex", serviceSubtask.getSex() != null ? serviceSubtask.getSex() == 1 ? "男" : "女" : null);
subtaskDetailTrace.setPatdesc(patdescJson.toJSONString());
subtaskDetailTrace.setTodeptcode(ivrTaskTemplateScriptVO.getDutyDeptCode());
subtaskDetailTrace.setTodeptname(ivrTaskTemplateScriptVO.getDutyDeptName());
subtaskDetailTrace.setOrgid(serviceSubtask.getOrgid());
subtaskDetailTrace.setHandleFlag("0");
subtaskDetailTrace.setGuid(phoneCallReqYQVO.getGuid());
subtaskDetailTrace.setCreateTime(new Date());
subtaskDetailTrace.setUpdateTime(new Date());
subtaskDetailTrace.setOrgid(phoneCallReqYQVO.getOrgid());
taskSubtaskApi.insertDetailTrace(subtaskDetailTrace);
}
//判断一下,这个选项结果是不是还有继续问下去的必要,例如选项结果是别人不想继续回答问题,就要结束掉
if (chosenOption.getIsEnd() == 1) {
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
back = phoneCallBackYQVO;
return back;
}
flag = 1;
//将当前前的播报状态删除,给下一题让位
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
// //获取下一题
log.error("获取下一题的信息:{}", ivrTaskTemplateScriptVO);
//branchFlag为null时按分支0处理,避免NPE
if ("1".equals(ivrTaskTemplateScriptVO.getBranchFlag()) || "0".equals(ivrTaskTemplateScriptVO.getBranchFlag()) && ivrTaskTemplateScriptVO.getNextScriptno() != null && ivrTaskTemplateScriptVO.getNextScriptno() != 0) {
Long nextQuestion = null;
if ("1".equals(ivrTaskTemplateScriptVO.getBranchFlag())) {
nextQuestion = chosenOption.getNextQuestion();
//更新分数
double score = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
score = BigDecimal.valueOf(score).add(new BigDecimal(chosenOption.getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score);
} else {
nextQuestion = ivrTaskTemplateScriptVO.getNextScriptno();
//更新分数
Object obj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
Double score = (obj == null ? new Double(0.00) : new Double(((Double) obj).doubleValue()));
score = BigDecimal.valueOf(score).add(new BigDecimal(String.valueOf(chosenOption.getScore()))).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
}
if (nextQuestion == null || nextQuestion == 0L) {
//如果下一题为空,或者为0,则挂机
ServiceSubtask ss = new ServiceSubtask();
ss.setId(serviceSubtask.getId());
ss.setSendstate(6L);
ss.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(ss);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "noVoice");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask.getJsy());
//明细在本题匹配成功时已落库(见上方 saveQuestionAnswerPhone),这里不再重复保存
back = phoneCallBackYQVO;
return back;
}
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (script.getSort() == nextQuestion.intValue()) {
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = StringUtils.isNotEmpty(script.getIvrtext()) ? script.getIvrtext() : script.getScriptContent();
log.error("下一题问题:{}", scriptContent);
log.error("下一题的子任务是:{}", serviceSubtask);
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
//将该患者的Redis中的题目ID,进行修改
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim(), script.getId().toString(), 120, TimeUnit.MINUTES);
//删除无响应
redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
}
}
//下一题脚本没找到时,兜底重问当前题,避免调用方误判为未处理而退回正则识别
if (StringUtils.isEmpty(phoneCallBackYQVO.getValue())) {
log.error("下一题脚本未找到,重问当前题,nextQuestion:{}", nextQuestion);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, questionText));
}
back = phoneCallBackYQVO;
return back;
} else if (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0) {
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
//更新一下分数
double score = 0.0;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (double) scoreObj;
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setSendstate(6L);
serviceSubtask.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//设置结束语
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
Long id = serviceSubtask.getId();
Map map = delRedisValue(null, id.toString());
log.error("map的值为:{}", map);
if (ObjectUtils.isNotEmpty(map)) redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "PlayEventCallbackPlaystop");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
//结束语已拼进返回值,挂机由平台按返回值执行
back = phoneCallBackYQVO;
return back;
}
} else {
//AI没有匹配上:由AI分支自己按"没问清就重问"的次数处理,不再退回正则识别
log.info("ai没有匹配上----------------------------");
//没匹配上也要把患者说的话记录下来(matchedtext置空,与正则路径口径一致)
ServiceSubTaskDetailReq serviceSubTaskDetailReq = new ServiceSubTaskDetailReq();
List serviceSubtaskDetailList = new ArrayList<>();
ServiceSubtaskDetail serviceSubtaskDetail = getServiceSubtaskDetail(phoneCallReqYQVO, ivrTaskTemplateScriptVO, serviceSubtask, ivrTaskTemplate);
//修改一下语音路径(改成前端可以访问的,存到数据库中)
if (StringUtils.isNotEmpty(serviceSubtaskDetail.getQuestionvoice())) {
String questionvoice = serviceSubtaskDetail.getQuestionvoice();
String[] split = questionvoice.split("\\\\");
if (split.length > 0) {
String lastPart = split[split.length - 1];
serviceSubtaskDetail.setQuestionvoice(voicePathPrefix + lastPart);
}
}
serviceSubtaskDetailList.add(serviceSubtaskDetail);
//如果没有 匹配上,这个必须为null
serviceSubtaskDetailList.get(0).setMatchedtext("");
serviceSubTaskDetailReq.setServiceSubtaskDetailList(serviceSubtaskDetailList);
serviceSubTaskDetailReq.setGuid(phoneCallReqYQVO.getGuid());
serviceSubTaskDetailReq.setOrgid(phoneCallReqYQVO.getOrgid());
saveQuestionAnswerPhone(serviceSubTaskDetailReq);
String mateKey = phoneCallReqYQVO.getTaskid().trim() + "&&" + "mate" + "&&" + phoneCallReqYQVO.getUuid();
Integer count = null;
Object countObj = redisCache.getCacheObject(mateKey);
if (ObjectUtils.isNotEmpty(countObj)) count = (Integer) countObj;
if (count != null && count >= ivrTaskTemplate.getMateNum()) {
//没匹配次数已经用满,不能再重问了
boolean noNextQuestion = ("0".equals(ivrTaskTemplateScriptVO.getBranchFlag()) || "1".equals(ivrTaskTemplateScriptVO.getBranchFlag()))
&& (ivrTaskTemplateScriptVO.getNextScriptno() == null || ivrTaskTemplateScriptVO.getNextScriptno() == 0);
if (noNextQuestion) {
//已经是最后一题,直接挂机
ServiceTask serviceTask1 = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + serviceTask1.getJsy());
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
serviceSubtask.setScore(String.valueOf(score));
serviceSubtask.setFinishtime(new Date());
serviceSubtask.setSendstate(6L);
serviceSubtask.setRemark("电话拨打已完成");
taskSubtaskApi.updateSubtask(serviceSubtask);
//记录状态
setFailPreachForm(serviceSubtask, "3", "电话拨打已完成", "9");
//在redis中保存一下结束语,在调用挂电话的方法时删除
ServiceTask serviceTask = taskSubtaskApi.getTask(serviceSubtask.getTaskid());
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "- jsy", serviceTask.getJsy(), 120, TimeUnit.MINUTES);
//去redis中,把该子任务ID删除
Long id = serviceSubtask.getId();
Map map = delRedisValue(null, id.toString());
if (ObjectUtils.isNotEmpty(map)) {
redisCache.setCacheObject(map.get("cacheName"), map.get("val"));
redisCache.deleteObject(serviceSubtask.getId() + "-" + serviceSubtask.getPhone());
redisCache.deleteObject(phoneCallReqYQVO.getUuid() + "SCORE");
}
} else {
//还有下一题,按nextScriptno继续提问
for (IvrTaskTemplateScript script : ivrTaskTemplateScripts) {
if (script.getSort() == ivrTaskTemplateScriptVO.getNextScriptno().intValue()) {
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
String scriptContent = StringUtils.isNotEmpty(script.getIvrtext()) ? script.getIvrtext() : script.getScriptContent();
phoneCallBackYQVO.setValue(phoneCallBackYQVO.getCommonValue() + getObject(serviceSubtask, scriptContent));
//将该患者的Redis中的题目ID,进行修改
redisCache.setCacheObject(phoneCallReqYQVO.getTaskid().trim() + "-" + phoneCallReqYQVO.getPhone().trim(), script.getId().toString(), 120, TimeUnit.MINUTES);
//更新一下分数
Double score = null;
Object scoreObj = redisCache.getCacheObject(phoneCallReqYQVO.getUuid() + "SCORE");
if (ObjectUtils.isNotEmpty(scoreObj)) score = (Double) scoreObj;
score = BigDecimal.valueOf(score).add(new BigDecimal(script.getScore())).doubleValue();
redisCache.setCacheObject(phoneCallReqYQVO.getUuid() + "SCORE", score, 120, TimeUnit.MINUTES);
//换题成功,没匹配次数清零
redisCache.deleteObject(mateKey);
}
}
}
} else {
//还没问满次数,用noMatchText引导患者重答
redisCache.setCacheObject(mateKey, count == null ? 1 : count + 1, 120, TimeUnit.MINUTES);
phoneCallBackYQVO.setType("text");
phoneCallBackYQVO.setSilent_interval(ivrTaskTemplate.getSilencetime().intValue());
phoneCallBackYQVO.setValue(ivrTaskTemplateScriptVO.getNoMatchText() + getObject(serviceSubtask, StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIvrtext()) ? ivrTaskTemplateScriptVO.getIvrtext() : ivrTaskTemplateScriptVO.getScriptContent()));
}
back = phoneCallBackYQVO;
return back;
}
return back;
}
}