|
|
package com.supervision.service.impl;
|
|
|
|
|
|
import cn.hutool.core.codec.Base64;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.convert.Convert;
|
|
|
import cn.hutool.core.date.TimeInterval;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.io.IoUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
import cn.hutool.core.util.NumberUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.supervision.domain.*;
|
|
|
import com.supervision.dto.paddlespeech.res.TtsResultDTO;
|
|
|
import com.supervision.dto.robot.*;
|
|
|
import com.supervision.dto.matchTool.ExtractInformationDTO;
|
|
|
import com.supervision.dto.matchTool.MatchQuestionAnswerDTO;
|
|
|
import com.supervision.dto.QueryProcessDTO;
|
|
|
import com.supervision.mapper.RobotDataMapper;
|
|
|
import com.supervision.service.*;
|
|
|
import com.supervision.util.UserUtil;
|
|
|
import com.supervision.vo.robot.ArchivesReqVo;
|
|
|
import com.supervision.vo.robot.CommonDialogVo;
|
|
|
import com.supervision.vo.talk.RobotTalkReq;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Paths;
|
|
|
import java.util.*;
|
|
|
import java.util.regex.Matcher;
|
|
|
import java.util.regex.Pattern;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
@RequiredArgsConstructor
|
|
|
public class RobotTalkServiceImpl implements RobotTalkService {
|
|
|
|
|
|
private final QueryTemplateProcessor queryTemplateProcessor;
|
|
|
|
|
|
private final MatchToolService matchToolService;
|
|
|
|
|
|
private final VoiceService voiceService;
|
|
|
|
|
|
private final IrRobotConfigService irRobotConfigService;
|
|
|
|
|
|
private final IrSessionHistoryService sessionService;
|
|
|
|
|
|
private final IrSessionParamService irSessionParamService;
|
|
|
|
|
|
private final IrVoiceService irVoiceService;
|
|
|
|
|
|
private final IrFileService irFileService;
|
|
|
|
|
|
@Resource
|
|
|
private final RobotDataMapper robotDataMapper;
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public RobotTalkDTO textTalk2Robot(RobotTalkReq robotTalkReq) {
|
|
|
String sessionId = robotTalkReq.getSessionId();
|
|
|
Assert.notEmpty(sessionId, "sessionId不能为空");
|
|
|
TimeInterval timeInterval = new TimeInterval();
|
|
|
timeInterval.start("all");
|
|
|
log.info("textTalk2Robot:开始问答,参数:{}",JSONUtil.toJsonStr(robotTalkReq));
|
|
|
|
|
|
RobotTalkDTO robotTalkDTO = RobotTalkDTO.builder()
|
|
|
.sessionId(sessionId).doNext(true)
|
|
|
.askInfo(AskInfo.builder().contentType(1).message(robotTalkReq.getMessage()).build())
|
|
|
.answerInfo(AnswerInfo.builder().contentType(robotTalkReq.getAnswerType()).build())
|
|
|
.build();
|
|
|
|
|
|
// 获取机器人配置
|
|
|
IrRobotConfig config = irRobotConfigService.lambdaQuery().one();
|
|
|
|
|
|
// 确认弹框信息
|
|
|
if (StrUtil.isNotEmpty(robotTalkReq.getAskId())){
|
|
|
IrSessionHistory sessionHistory = sessionService.lambdaQuery().eq(IrSessionHistory::getId, robotTalkReq.getAskId()).one();
|
|
|
if (Objects.nonNull(sessionHistory)){
|
|
|
robotTalkReq.setMessage(sessionHistory.getUserQuestion());
|
|
|
robotTalkReq.setConfirmFlag(true);
|
|
|
robotTalkDTO.getAskInfo().setAskId(robotTalkReq.getAskId());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 匹配问题意图
|
|
|
MatchQuestionAnswerDTO matchQuestionAnswerDTO = matchQuestionAnswer(robotTalkReq.getMessage());
|
|
|
setSuspectInfoAndNextFlag(robotTalkReq, robotTalkDTO, matchQuestionAnswerDTO,config);
|
|
|
|
|
|
if (Objects.isNull(matchQuestionAnswerDTO) && robotTalkDTO.isDoNext()){
|
|
|
// 未匹配到查询意图,设置默认错误语
|
|
|
log.info("问题:{}未匹配到意图",robotTalkReq.getMessage());
|
|
|
robotTalkDTO.getAnswerInfo().setMessage(config.getErrorLanguage());
|
|
|
robotTalkDTO.setDoNext(false);
|
|
|
}
|
|
|
|
|
|
if (robotTalkDTO.isDoNext()){
|
|
|
QueryProcessDTO matchAnswer = queryMatch2Answer(sessionId, matchQuestionAnswerDTO, robotTalkDTO, robotTalkReq.getTitleContent());
|
|
|
if (Integer.valueOf(0).equals(matchAnswer.getState()) &&
|
|
|
Integer.valueOf(3).equals(matchAnswer.getContentType())
|
|
|
&& matchAnswer.getByteContent() != null){
|
|
|
// 查询结果类型为字节数组
|
|
|
robotTalkDTO.getAnswerInfo().setContentType(3);
|
|
|
robotTalkDTO.getAnswerInfo().setAnswerByte(matchAnswer.getByteContent());
|
|
|
}else{
|
|
|
robotTalkDTO.getAnswerInfo().setAnswerFile(matchAnswer.getFileContent());
|
|
|
robotTalkDTO.getAnswerInfo().setMessage(decideAnswer(matchAnswer, config));
|
|
|
if (matchAnswer.getState() == 1){
|
|
|
if (!Boolean.TRUE.equals(robotTalkReq.isConfirmFlag())){
|
|
|
robotTalkDTO.getAnswerInfo().setContentType(6);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
logSessionInfo(robotTalkDTO, matchQuestionAnswerDTO);
|
|
|
|
|
|
// 清除中间数据
|
|
|
robotTalkDTO.getAnswerInfo().setVoiceBase64(null);
|
|
|
robotTalkDTO.getAnswerInfo().setAnswerByte(null);
|
|
|
robotTalkDTO.getAnswerInfo().setAnswerFile(null);
|
|
|
|
|
|
log.info("textTalk2Robot:结束问答,耗时:{}ms",timeInterval.interval("all"));
|
|
|
return robotTalkDTO;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 转换语句中的数字,方便语音合成发音
|
|
|
* @param input
|
|
|
* @return
|
|
|
*/
|
|
|
private String numberToChinese(String input){
|
|
|
|
|
|
if (StrUtil.isEmpty(input)){
|
|
|
return input;
|
|
|
}
|
|
|
String regex = "(\\d+(\\.\\d+)?)(?=元|万元|亿元|个)";
|
|
|
Pattern pattern = Pattern.compile(regex);
|
|
|
Matcher matcher = pattern.matcher(input);
|
|
|
|
|
|
while (matcher.find()) {
|
|
|
String group = matcher.group();
|
|
|
if (StrUtil.isNotEmpty(group) && NumberUtil.isNumber(group)){
|
|
|
input = input.replace(group,Convert.numberToChinese(NumberUtil.parseDouble(group),false));
|
|
|
}
|
|
|
}
|
|
|
return input;
|
|
|
}
|
|
|
|
|
|
|
|
|
private void setSuspectInfoAndNextFlag(RobotTalkReq robotTalkReq, RobotTalkDTO robotTalkDTO, MatchQuestionAnswerDTO matchQuestionAnswerDTO, IrRobotConfig config) {
|
|
|
|
|
|
String sessionId = robotTalkReq.getSessionId();
|
|
|
|
|
|
if (Objects.nonNull(matchQuestionAnswerDTO)){
|
|
|
List<ParamCheckDTO> paramCheckDTOS = queryTemplateProcessor.paramCheck(matchQuestionAnswerDTO.getMatchQuestionCode(), sessionId,
|
|
|
suspectInfo2IrSessionParam(sessionId, null));
|
|
|
// 匹配到意图,但是参数校验不通过,尝试提取消息中的信息
|
|
|
if (CollUtil.isNotEmpty(paramCheckDTOS) && !Boolean.TRUE.equals(robotTalkReq.isConfirmFlag())){
|
|
|
String paramsJoin = paramCheckDTOS.stream().map(ParamCheckDTO::getParamName).collect(Collectors.joining(","));
|
|
|
log.info("匹配到的问题:{} ,需要参数:{} ,尝试抽取问题:{} 中的参数。",matchQuestionAnswerDTO.getMatchQuestionCode(),paramsJoin, robotTalkReq.getMessage());
|
|
|
extractInformation(sessionId, robotTalkReq.getMessage(), robotTalkDTO);
|
|
|
SuspectInfo suspectInfo = robotTalkDTO.getAnswerInfo().getSuspectInfo();
|
|
|
if (Objects.isNull(suspectInfo) || suspectInfo.isEmpty()){
|
|
|
// 未抽取到信息,继续下一步操作
|
|
|
robotTalkDTO.setDoNext(true);
|
|
|
}else {
|
|
|
robotTalkDTO.getAnswerInfo().setContentType(6);
|
|
|
}
|
|
|
}
|
|
|
}else {
|
|
|
if (!Boolean.TRUE.equals(robotTalkReq.isConfirmFlag())){
|
|
|
log.info("问题:{},未匹配到意图,且confirmFlag标识不为true,抽取问题中的关键属性", robotTalkReq.getMessage());
|
|
|
// 未匹配到意图,且不是关键信息确认操作则提取信息中的关键信息
|
|
|
extractInformation(sessionId, robotTalkReq.getMessage(), robotTalkDTO);
|
|
|
}else {
|
|
|
// 未匹配到意图,是关键信息确认操作,不做问题响应,只做默认回答
|
|
|
log.info("问题:{},未匹配到意图,且confirmFlag标识为true,设置默认回答:{}", robotTalkReq.getMessage(), config.getUnrecognizedTwo());
|
|
|
robotTalkDTO.getAnswerInfo().setMessage(config.getUnrecognizedTwo());
|
|
|
robotTalkDTO.setDoNext(false);
|
|
|
}
|
|
|
}
|
|
|
SuspectInfo suspectInfo = robotTalkDTO.getAnswerInfo().getSuspectInfo();
|
|
|
if (Objects.isNull(suspectInfo) || suspectInfo.isEmpty()){
|
|
|
robotTalkDTO.getAnswerInfo().setSuspectInfo(robotTalkReq.getTitleContent());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void logSessionInfo(RobotTalkDTO robotTalkDTO, MatchQuestionAnswerDTO matchQuestionAnswerDTO) {
|
|
|
// 组装日志信息
|
|
|
IrSessionHistory irSessionHistory = talk2SessionHistory(robotTalkDTO.getSessionId(),
|
|
|
robotTalkDTO, matchQuestionAnswerDTO);
|
|
|
|
|
|
// 保存回答音频文件
|
|
|
IrVoice irVoice = saveAudioIfNoAbsent(robotTalkDTO.getAnswerInfo().getMessage());
|
|
|
if (Objects.nonNull(irVoice)) {
|
|
|
robotTalkDTO.getAnswerInfo().setVoiceBaseId(irVoice.getId());
|
|
|
robotTalkDTO.getAnswerInfo().setVoiceBase64(irVoice.getVoiceBase64());
|
|
|
robotTalkDTO.getAnswerInfo().setAudioLength(irVoice.getLength());
|
|
|
irSessionHistory.setAnswerVoiceId(irVoice.getId());
|
|
|
}
|
|
|
|
|
|
if (Objects.nonNull(robotTalkDTO.getAnswerInfo().getAnswerByte())
|
|
|
|| Objects.nonNull(robotTalkDTO.getAnswerInfo().getAnswerFile())) {
|
|
|
// 如果返回的结果是字节,保存到文件表
|
|
|
IrFile irFile = saveFileIfNoAbsent(robotTalkDTO.getAnswerInfo());
|
|
|
if (Objects.nonNull(irFile)) {
|
|
|
robotTalkDTO.getAnswerInfo().setContentType(3);
|
|
|
robotTalkDTO.getAnswerInfo().setByteId(irFile.getId());
|
|
|
irSessionHistory.setAnswerFileId(irFile.getId());
|
|
|
}
|
|
|
}
|
|
|
// 写入对话日志
|
|
|
sessionService.saveOrUpdate(irSessionHistory);
|
|
|
robotTalkDTO.getAskInfo().setAskId(irSessionHistory.getId());
|
|
|
}
|
|
|
|
|
|
private IrVoice saveAudioIfNoAbsent(String message) {
|
|
|
|
|
|
if (StrUtil.isEmpty(message)) {
|
|
|
return null;
|
|
|
}
|
|
|
String translate = numberToChinese(message);
|
|
|
TtsResultDTO resultDTO = voiceService.textToVoice(translate);
|
|
|
IrVoice irVoice = new IrVoice();
|
|
|
irVoice.setVoiceBase64(resultDTO.getAudio());
|
|
|
if (NumberUtil.isNumber(resultDTO.getDuration())){
|
|
|
irVoice.setLength(NumberUtil.parseInt(resultDTO.getDuration()));
|
|
|
}
|
|
|
irVoiceService.save(irVoice);
|
|
|
return irVoice;
|
|
|
}
|
|
|
|
|
|
private QueryProcessDTO queryMatch2Answer(String sessionId, MatchQuestionAnswerDTO matchQuestionAnswerDTO,
|
|
|
RobotTalkDTO robotTalkDTO, SuspectInfo suspectInfo) {
|
|
|
QueryProcessDTO process = QueryProcessDTO.builder().state(2).build();
|
|
|
if (Objects.nonNull(matchQuestionAnswerDTO) && robotTalkDTO.isDoNext()) {
|
|
|
process = queryTemplateProcessor.process(matchQuestionAnswerDTO.getMatchQuestionCode(), sessionId,
|
|
|
()->this.suspectInfo2IrSessionParam(sessionId,suspectInfo));
|
|
|
}
|
|
|
return process;
|
|
|
}
|
|
|
|
|
|
private List<IrSessionParam> suspectInfo2IrSessionParam(String sessionId,SuspectInfo suspectInfo) {
|
|
|
List<IrSessionParam> sessionParams = new ArrayList<>();
|
|
|
|
|
|
if (Objects.nonNull(suspectInfo)){
|
|
|
sessionParams.add(new IrSessionParam(sessionId,"jykh",StrUtil.join(",",suspectInfo.getCardNumber())));
|
|
|
sessionParams.add(new IrSessionParam(sessionId,"khrzjhm",suspectInfo.getIdNumber()));
|
|
|
sessionParams.add(new IrSessionParam(sessionId,"khrmc",suspectInfo.getName()));
|
|
|
}
|
|
|
|
|
|
IrSessionParam sessionParam = irSessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId)
|
|
|
.eq(IrSessionParam::getParamName, "ajid").one();
|
|
|
if (Objects.nonNull(sessionParam)) {
|
|
|
sessionParams.add(sessionParam);
|
|
|
}
|
|
|
return sessionParams;
|
|
|
}
|
|
|
|
|
|
private MatchQuestionAnswerDTO matchQuestionAnswer(String message) {
|
|
|
|
|
|
if (StrUtil.isNotEmpty(message)){
|
|
|
// 如果消息为空,则没必要进行意图匹配
|
|
|
try {
|
|
|
List<MatchQuestionAnswerDTO> matchQuestionAnswerDTOS = matchToolService.execMatch(message);
|
|
|
log.info("问题:{} 匹配到的意图:{}", message, JSONUtil.toJsonStr(matchQuestionAnswerDTOS));
|
|
|
return CollUtil.getFirst(matchQuestionAnswerDTOS);
|
|
|
} catch (Exception e) {
|
|
|
log.error("textTalk2Robot:内容:{} 相似度匹配失败", message,e);
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
private void extractInformation(String sessionId, String message, RobotTalkDTO robotTalkDTO) {
|
|
|
ExtractInformationDTO extractInformationDTO = matchToolService.extractInformation(message);
|
|
|
if (Objects.isNull(extractInformationDTO) || extractInformationDTO.allEmpty()) {
|
|
|
return;
|
|
|
}
|
|
|
// 识别到重要信息
|
|
|
IrSessionParam sessionParam = irSessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId).eq(IrSessionParam::getParamName, "ajid").one();
|
|
|
AnswerInfo answerInfo = robotTalkDTO.getAnswerInfo();
|
|
|
if (Objects.isNull(sessionParam) || StrUtil.isEmpty(sessionParam.getParamValue())) {
|
|
|
// 案件id为空,需要设置案件id
|
|
|
answerInfo.setContentType(2);
|
|
|
answerInfo.setMessage("请先设置案件信息");
|
|
|
robotTalkDTO.setDoNext(false);
|
|
|
} else {
|
|
|
Integer caseNo = StrUtil.isEmpty(sessionParam.getParamValue()) ? null : Integer.valueOf(sessionParam.getParamValue());
|
|
|
List<SuspectInfo> suspectInfos = robotDataMapper.querySuspect(caseNo,
|
|
|
extractInformationDTO.getIdNumber(),
|
|
|
extractInformationDTO.getName(),
|
|
|
extractInformationDTO.getCardNumber());
|
|
|
|
|
|
answerInfo.setContentType(6);
|
|
|
SuspectInfo suspectInfo = Objects.isNull(CollUtil.getFirst(suspectInfos)) ?
|
|
|
extractInformation2Suspect(extractInformationDTO) : CollUtil.getFirst(suspectInfos);
|
|
|
answerInfo.setSuspectInfo(suspectInfo);
|
|
|
robotTalkDTO.setDoNext(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private SuspectInfo extractInformation2Suspect(ExtractInformationDTO informationDTO) {
|
|
|
|
|
|
SuspectInfo suspectInfo = new SuspectInfo();
|
|
|
suspectInfo.setName(informationDTO.getName());
|
|
|
suspectInfo.setIdNumber(informationDTO.getIdNumber());
|
|
|
if (StrUtil.isNotEmpty(informationDTO.getCardNumber())){
|
|
|
suspectInfo.setCardNumber(CollUtil.newArrayList(informationDTO.getCardNumber()));
|
|
|
}
|
|
|
return suspectInfo;
|
|
|
}
|
|
|
|
|
|
private static String decideAnswer(QueryProcessDTO process, IrRobotConfig config) {
|
|
|
// 正确查询出结果
|
|
|
if (Integer.valueOf(0).equals(process.getState())){
|
|
|
if (Integer.valueOf(1).equals(process.getContentType()) ||
|
|
|
Integer.valueOf(6).equals(process.getContentType())){
|
|
|
// 查询结果类型为字符串
|
|
|
return process.getStringContent();
|
|
|
}
|
|
|
}
|
|
|
// 参数异常或查询结果异常
|
|
|
if (Integer.valueOf(1).equals(process.getState())){
|
|
|
return StrUtil.join(",",process.paramCheckToMessage());
|
|
|
}
|
|
|
|
|
|
if (Integer.valueOf(2).equals(process.getState())){
|
|
|
return config.getUnrecognizedOne();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
private IrFile saveFileIfNoAbsent(AnswerInfo answerInfo) {
|
|
|
if (Objects.isNull(answerInfo.getAnswerByte()) && Objects.isNull(answerInfo.getAnswerFile())){
|
|
|
return null;
|
|
|
}
|
|
|
String fileType = Integer.valueOf(3).equals(answerInfo.getContentType()) ? "1" : "2";
|
|
|
IrFile irFile = new IrFile();
|
|
|
irFile.setFileType(fileType);
|
|
|
irFile.setFileName("answer");
|
|
|
if ("1".equals(irFile.getFileType())){
|
|
|
irFile.setFileByte(answerInfo.getAnswerByte());
|
|
|
}else {
|
|
|
irFile.setFileByte(IoUtil.readBytes(FileUtil.getInputStream(answerInfo.getAnswerFile())));
|
|
|
FileUtil.del(answerInfo.getAnswerFile());
|
|
|
}
|
|
|
irFile.setFileSize(irFile.getFileByte().length);
|
|
|
irFile.setFileType(fileType);
|
|
|
irFileService.save(irFile);
|
|
|
return irFile;
|
|
|
}
|
|
|
|
|
|
|
|
|
private IrSessionHistory talk2SessionHistory(String sessionId, RobotTalkDTO robotTalkDTO,
|
|
|
MatchQuestionAnswerDTO matchQuestionAnswerDTO) {
|
|
|
IrSessionHistory sessionHistory = new IrSessionHistory();
|
|
|
sessionHistory.setId(robotTalkDTO.getAskInfo().getAskId());
|
|
|
sessionHistory.setSessionId(sessionId);
|
|
|
AnswerInfo answerInfo = robotTalkDTO.getAnswerInfo();
|
|
|
sessionHistory.setAnswer(answerInfo.getMessage());
|
|
|
sessionHistory.setAnswerType(answerInfo.getContentType());
|
|
|
|
|
|
sessionHistory.setUserQuestion(robotTalkDTO.getAskInfo().getMessage());
|
|
|
sessionHistory.setCreateUserId(UserUtil.getUser().getId());
|
|
|
if (Objects.nonNull(matchQuestionAnswerDTO)){
|
|
|
sessionHistory.setMatchKnowledgeId(matchQuestionAnswerDTO.getMatchQuestionCode());
|
|
|
sessionHistory.setThreshold(BigDecimal.valueOf(matchQuestionAnswerDTO.getMatchScore()));
|
|
|
}
|
|
|
return sessionHistory;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public RobotTalkDTO videoTalk2Robot(MultipartFile multipartFile,RobotTalkReq robotTalkReq) {
|
|
|
|
|
|
String sessionId = robotTalkReq.getSessionId();
|
|
|
|
|
|
Assert.notEmpty(sessionId, "sessionId不能为空");
|
|
|
Assert.notNull(multipartFile, "multipartFile不能为空");
|
|
|
|
|
|
byte[] bytes = null;
|
|
|
try {
|
|
|
bytes = multipartFile.getBytes();
|
|
|
String message = voiceService.voiceToText(bytes, sessionId);
|
|
|
robotTalkReq.setMessage(message);
|
|
|
} catch (IOException e) {
|
|
|
log.error("语音转文字失败", e);
|
|
|
}
|
|
|
RobotTalkDTO robotTalkDTO = this.textTalk2Robot(robotTalkReq);
|
|
|
robotTalkDTO.getAskInfo().setContentType(2);
|
|
|
|
|
|
if (Objects.nonNull(bytes)){
|
|
|
IrVoice irVoice = new IrVoice();
|
|
|
irVoice.setVoiceBase64(Base64.encode(bytes));
|
|
|
irVoiceService.save(irVoice);
|
|
|
if (StrUtil.isNotEmpty(robotTalkDTO.getAskInfo().getAskId())){
|
|
|
sessionService.lambdaUpdate()
|
|
|
.eq(IrSessionHistory::getId,robotTalkDTO.getAskInfo().getAskId())
|
|
|
.set(IrSessionHistory::getUserQuestionVoiceId,irVoice.getId()).update();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return robotTalkDTO;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<CommonDialogVo> talkList(String sessionId) {
|
|
|
|
|
|
Assert.notEmpty(sessionId, "sessionId不能为空");
|
|
|
List<IrSessionHistory> sessionHistoryList = sessionService.lambdaQuery().eq(IrSessionHistory::getSessionId, sessionId).orderBy(true, true,IrSessionHistory::getCreateTime).list();
|
|
|
|
|
|
// 获取音频的长度
|
|
|
List<String> voiceIds = sessionHistoryList.stream()
|
|
|
.map(session -> CollUtil.toList(session.getAnswerVoiceId(), session.getUserQuestionVoiceId()))
|
|
|
.flatMap(Collection::stream).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
|
|
|
Map<String, Integer> voiceLengthMap = CollUtil.isEmpty(voiceIds) ? new HashMap<>() :
|
|
|
irVoiceService.listByIds(voiceIds).stream().filter(i->Objects.nonNull(i.getLength())).collect(Collectors.toMap(IrVoice::getId, IrVoice::getLength));
|
|
|
|
|
|
return sessionHistoryList.stream().map(session->this.sessionHistory2RobotTalkDTO(session,voiceLengthMap))
|
|
|
.filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
private List<CommonDialogVo> sessionHistory2RobotTalkDTO(IrSessionHistory sessionHistory,Map<String, Integer> voiceLengthMap) {
|
|
|
if (Objects.isNull(sessionHistory)){
|
|
|
return null;
|
|
|
}
|
|
|
CommonDialogVo askDiaLog = CommonDialogVo.builder().dialogType(1)
|
|
|
.dialogId(sessionHistory.getId()).sessionId(sessionHistory.getSessionId())
|
|
|
.contentType(StrUtil.isEmpty(sessionHistory.getUserQuestionVoiceId()) ? 1 : 2)//userQuestionVoiceId 为空,则为1 否则为2
|
|
|
.message(sessionHistory.getUserQuestion()).voiceBaseId(sessionHistory.getUserQuestionVoiceId())
|
|
|
.audioLength(voiceLengthMap.get(sessionHistory.getUserQuestionVoiceId())).build();
|
|
|
|
|
|
if (Integer.valueOf(6).equals(sessionHistory.getAnswerType())){
|
|
|
// 屏蔽弹框记录
|
|
|
return CollUtil.newArrayList(askDiaLog);
|
|
|
}
|
|
|
|
|
|
CommonDialogVo answerDiaLog = CommonDialogVo.builder().dialogType(2)
|
|
|
.dialogId(sessionHistory.getId()).sessionId(sessionHistory.getSessionId())
|
|
|
.contentType(sessionHistory.getAnswerType()).message(sessionHistory.getAnswer())
|
|
|
.byteId(sessionHistory.getAnswerFileId()).voiceBaseId(sessionHistory.getAnswerVoiceId())
|
|
|
.audioLength(voiceLengthMap.get(sessionHistory.getAnswerVoiceId()))
|
|
|
.build();
|
|
|
|
|
|
return CollUtil.toList(askDiaLog,answerDiaLog);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void getAudio(HttpServletResponse response, String audioId) throws IOException {
|
|
|
Assert.notEmpty(audioId, "audioId不能为空");
|
|
|
|
|
|
IrVoice voice = irVoiceService.getById(audioId);
|
|
|
if (Objects.isNull(voice) || StrUtil.isEmpty(voice.getVoiceBase64())){
|
|
|
return;
|
|
|
}
|
|
|
Base64.decodeToStream(voice.getVoiceBase64(), response.getOutputStream(),false);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void downLoadArchives(HttpServletResponse response,ArchivesReqVo archivesReq) throws IOException {
|
|
|
String path = localArchivesFilePath(archivesReq);
|
|
|
if (StrUtil.isEmpty(path)){
|
|
|
return;
|
|
|
}
|
|
|
IoUtil.copy(Files.newInputStream(Paths.get(path)),response.getOutputStream());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void downLoadFile(HttpServletResponse response, String fileType, String imageId) throws IOException {
|
|
|
IrFile file = irFileService.getById(imageId);
|
|
|
if (Objects.isNull(file) || Objects.isNull(file.getFileByte())){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if ("1".equals(file.getFileType())){
|
|
|
IoUtil.write(response.getOutputStream(), true, Base64.decode(file.getFileByte()));
|
|
|
}
|
|
|
|
|
|
if ("2".equals(file.getFileType())){
|
|
|
IoUtil.write(response.getOutputStream(), true,file.getFileByte());
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<SuspectInfo> querySuspectInfo(String sessionId, String name) {
|
|
|
|
|
|
Assert.notEmpty(sessionId, "sessionId不能为空");
|
|
|
//Assert.notEmpty(name, "name不能为空");
|
|
|
|
|
|
IrSessionParam sessionParam = irSessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId).eq(IrSessionParam::getParamName, "ajid").one();
|
|
|
Assert.notNull(sessionParam, "未查询到案件");
|
|
|
Assert.notEmpty(sessionParam.getParamValue(), "ajid不能为空");
|
|
|
return robotDataMapper.querySuspect(NumberUtil.parseInt(sessionParam.getParamValue()), null, name, null);
|
|
|
}
|
|
|
|
|
|
private String localArchivesFilePath(ArchivesReqVo archivesReq) {
|
|
|
String path = StrUtil.join(File.separator,archivesReq.getCaseId(),
|
|
|
StrUtil.join("-",archivesReq.getName(),archivesReq.getIdNumber()),
|
|
|
archivesReq.getDocumentId());
|
|
|
|
|
|
// 判断文件是否存在
|
|
|
if (FileUtil.exist(path)){
|
|
|
return path;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
}
|