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} 的电话部分)。
|
*
|
* <h3>这个类是怎么来的</h3>
|
* 逐行从 {@code ServiceSubtaskServiceImpl} 搬出,只做两类机械改写,<b>业务分支一行未动</b>:
|
* <ol>
|
* <li><b>数据访问换入口</b>:原 {@code serviceSubtaskMapper} / {@code serviceSubtaskDetailMapper} /
|
* {@code serviceTaskVisitResultMapper} / {@code serviceTaskService} / {@code traceService}
|
* 的调用,统一改为 {@link TaskSubtaskApi}(表归 {@code ruoyi-task},非归属模块不许写这些表);</li>
|
* <li><b>跨模块读取换入口</b>:模板话术改走 {@code ruoyi-template} 的 service 接口
|
* ({@code IIvrTaskTemplateService} / {@code IIvrTaskTemplateScriptService} /
|
* {@code IIvrTaskTemplateTargetoptionService} / {@code IIvrLibaExtemplatescriptService} /
|
* {@code ISvyLibScriptCategoryService});AI 选项匹配改走 ruoyi-common 契约
|
* {@link SubtaskOptionMatchApi}(实现在 {@code ruoyi-task},原 {@code matchOptionIndex} 仍留在那边)。</li>
|
* </ol>
|
*
|
* <h3>会话状态在哪里</h3>
|
* 一通电话的进行状态(当前题号、已问遍数、静默次数、分数、是否已挂机、结束语等)
|
* <b>全部放在 Redis</b>(key 前缀是本通电话的 uuid 或"子任务ID-手机号"),
|
* 这些 key 的拼写、TTL、读写顺序与原实现完全一致 —— 电话回调是外部平台驱动的、
|
* 进程重启后要继续,所以这些 key 就是"业务状态机",迁移时不能动。
|
*
|
* <h3>被刻意删掉的东西</h3>
|
* 原 {@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:子任务 / 子任务明细 / 任务访问结果 / 异常跟踪。
|
* <p>
|
* 这些表归 {@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<String, Object> map = redisCache.getCacheObject(phoneCallBackVO.getUuid());
|
ServiceSubtask serviceSubtask = (ServiceSubtask) map.get("ServiceSubtask");
|
List<IvrTaskTemplateScriptVO> IvrTaskTemplateScriptVOs = (List<IvrTaskTemplateScriptVO>) 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<String> list = Arrays.asList(split);
|
List<Long> list1 = new ArrayList<>();
|
if (StringUtils.isNotEmpty(extemplateID)) {
|
for (String str : list) {
|
list1.add(Long.valueOf(str));
|
}
|
List<IvrLibaExtemplatescript> 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<String, String> 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<String, String> 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<IvrTaskTemplateScript> 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<ServiceSubtaskDetail> 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<String, String> 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<String> list = Arrays.asList(split);
|
List<Long> list1 = new ArrayList<>();
|
for (String str : list) {
|
list1.add(Long.valueOf(str));
|
}
|
List<IvrLibaExtemplatescript> 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<ServiceSubtaskDetail> 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<ServiceSubtaskDetail> 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<ServiceSubtaskDetail> 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<ServiceSubtaskDetail> 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<String, String> 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<ServiceSubtaskDetail> 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<String, String> 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<ServiceSubtaskDetail> 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<String, String> 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<String, Map<String, String>> param = getParam(serviceSubtask.getTaskid());
|
for (Map<String, String> 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<String, Map<String, String>> getParam(Long taskId) {
|
ServiceTask serviceTask = taskSubtaskApi.getTask(taskId);
|
ObjectMapper objectMapper = new ObjectMapper();
|
Map<String, Map<String, String>> serviceTaskMap = null;
|
try {
|
serviceTaskMap = objectMapper.readValue(serviceTask.getTextParam(), Map.class);
|
} catch (JsonProcessingException e) {
|
e.printStackTrace();
|
}
|
return serviceTaskMap;
|
}
|
|
private Map<String, String> delRedisValue(String cache, String id) {
|
id = "," + id + ",";
|
String val = "";
|
String cacheName = "";
|
Map<String, String> 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<PullTaskVO> taskPull() {
|
//pullTaskVOList用于数据返回
|
List<PullTaskVO> pullTaskVOList = new ArrayList<>();
|
List<String> cacheList = new ArrayList<>();
|
ListOperations<String, String> 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<String> value = listOps.range("cache-0" + i, 0, count1 - 1);
|
|
List<PullTaskVO> 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<String> 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<PullTaskVO> getPullTaskList(List<String> subIds, String cacheName) {
|
log.error("任务拉取subIds的值是多少:{}", subIds);
|
//pullTaskVOList用于数据返回
|
List<PullTaskVO> pullTaskVOList = new ArrayList<>();
|
//newValue0用于保存没有处理的子 任务
|
// String newValue0 = "";
|
List<String> 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<IvrTaskTemplateScript> 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<ServiceSubtask> 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<ServiceSubtaskDetail> 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<IvrTaskTemplateScriptVO> 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<ServiceSubtaskPreachform> spSize = taskPreachformPort.selectServiceSubtaskPreachformList(serviceSubtaskPreachform);
|
|
serviceSubtaskPreachform.setPreachform(preachform);
|
//1:未发送状态
|
serviceSubtaskPreachform.setSendstate("1");
|
if (preachform.equals("3")) {
|
//电话进入队列后,状态会变成2
|
serviceSubtaskPreachform.setSendstate("2");
|
}
|
List<ServiceSubtaskPreachform> 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<ServiceSubtaskPreachform> 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<ServiceSubtask> 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<IvrTaskTemplateScript> 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<ServiceSubtaskDetail> 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<IvrTaskTemplateScript> 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<IvrTaskTemplateTargetoption> 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<IvrTaskTemplateScript> 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<IvrTaskTemplateScript> ivrTaskTemplateScripts, String scriptId, Integer flag, String uuid) {
|
PhoneCallBackYQVO back = null;
|
List<IvrTaskTemplateTargetoption> 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<ServiceSubtaskDetail> 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<ServiceSubtaskDetail> 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<String, String> 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<ServiceSubtaskDetail> 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<String, String> 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;
|
}
|
}
|