添加代码 问答功能代码

main
xueqingkun 11 months ago
parent c137fbcad4
commit 3df54e29dc

@ -86,6 +86,13 @@
<artifactId>spring-boot-starter-freemarker</artifactId> <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.24.1</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -2,8 +2,10 @@ package com.supervision.controller;
import com.supervision.dto.robot.RobotTalkDTO; import com.supervision.dto.robot.RobotTalkDTO;
import com.supervision.dto.robot.SuspectInfo;
import com.supervision.service.RobotTalkService; import com.supervision.service.RobotTalkService;
import com.supervision.vo.robot.ArchivesReqVo; import com.supervision.vo.robot.ArchivesReqVo;
import com.supervision.vo.robot.CommonDialogVo;
import com.supervision.vo.talk.RobotTalkReq; import com.supervision.vo.talk.RobotTalkReq;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -44,7 +46,7 @@ public class RobotTalkController {
@ApiOperation("获取对话内容列表") @ApiOperation("获取对话内容列表")
@GetMapping("/talkList") @GetMapping("/talkList")
public List<RobotTalkDTO> talkList(String sessionId) { public List<CommonDialogVo> talkList(String sessionId) {
return robotTalkService.talkList(sessionId); return robotTalkService.talkList(sessionId);
} }
@ -55,12 +57,12 @@ public class RobotTalkController {
robotTalkService.getAudio(response,audioId); robotTalkService.getAudio(response,audioId);
} }
@ApiOperation("下载嫌疑人归档数据") /* @ApiOperation("下载嫌疑人归档数据")
@GetMapping("/downLoadArchives") @GetMapping("/downLoadArchives")
public void downLoadArchives(HttpServletResponse response, public void downLoadArchives(HttpServletResponse response,
ArchivesReqVo archivesReq) throws IOException { ArchivesReqVo archivesReq) throws IOException {
robotTalkService.downLoadArchives(response,archivesReq); robotTalkService.downLoadArchives(response,archivesReq);
} }*/
@ApiOperation("下载对话过程中的文件") @ApiOperation("下载对话过程中的文件")
@ -70,4 +72,11 @@ public class RobotTalkController {
String imageId) throws IOException { String imageId) throws IOException {
robotTalkService.downLoadFile(response,fileType,imageId); robotTalkService.downLoadFile(response,fileType,imageId);
} }
@ApiOperation("查询嫌疑人信息")
@GetMapping("/querySuspectInfo")
public List<SuspectInfo> querySuspectInfo(String sessionId, String name) {
return robotTalkService.querySuspectInfo(sessionId,name);
}
} }

@ -16,7 +16,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.List; import java.util.List;
@Slf4j @Slf4j

@ -30,7 +30,7 @@ public class IrFile implements Serializable {
private byte[] fileByte; private byte[] fileByte;
/** /**
* * 1: base64 2:(base64)
*/ */
private String fileType; private String fileType;

@ -45,7 +45,7 @@ public class IrKnowledge implements Serializable {
private String resultTemplate; private String resultTemplate;
/** /**
* 1Map<String,Object> 2:List<Map<String,Object>> 3: bytea * 1Map<String,Object> 2:List<Map<String,Object>> 3: bytea 4
*/ */
private Integer resultType; private Integer resultType;

@ -42,7 +42,7 @@ public class IrSessionHistory implements Serializable {
private String answer; private String answer;
/** /**
* 1: 2 3 * 1: 2 3 6-
*/ */
private Integer answerType; private Integer answerType;

@ -5,7 +5,9 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import java.io.File;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
@Data @Data
@ -18,7 +20,7 @@ public class QueryProcessDTO {
private Integer state; private Integer state;
/** /**
* 1-2-3-4-5- * 1-2-3-4-5- 6-
*/ */
private Integer contentType; private Integer contentType;
@ -32,6 +34,8 @@ public class QueryProcessDTO {
*/ */
private byte[] byteContent; private byte[] byteContent;
private File fileContent;
/** /**
* id * id
*/ */

@ -3,13 +3,15 @@ package com.supervision.dto.robot;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import java.io.File;
@Data @Data
@Builder @Builder
public class AnswerInfo { public class AnswerInfo {
/** /**
* 1-2-3-4-5- * 1-2-3-4-5- 6- 7-
*/ */
private Integer contentType; private Integer contentType;
@ -37,13 +39,15 @@ public class AnswerInfo {
/** /**
* id * id
*/ */
private String answerByteId; private String byteId;
/** /**
* *
*/ */
private transient byte[] answerByte; private transient byte[] answerByte;
private transient File answerFile;
/** /**
* *

@ -1,7 +1,9 @@
package com.supervision.service; package com.supervision.service;
import com.supervision.dto.robot.RobotTalkDTO; import com.supervision.dto.robot.RobotTalkDTO;
import com.supervision.dto.robot.SuspectInfo;
import com.supervision.vo.robot.ArchivesReqVo; import com.supervision.vo.robot.ArchivesReqVo;
import com.supervision.vo.robot.CommonDialogVo;
import com.supervision.vo.talk.RobotTalkReq; import com.supervision.vo.talk.RobotTalkReq;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -23,7 +25,7 @@ public interface RobotTalkService {
* @return * @return
*/ */
List<RobotTalkDTO> talkList(String sessionId); List<CommonDialogVo> talkList(String sessionId);
void getAudio(HttpServletResponse response, String audioId) throws IOException; void getAudio(HttpServletResponse response, String audioId) throws IOException;
@ -37,4 +39,8 @@ public interface RobotTalkService {
void downLoadFile(HttpServletResponse response, String fileType, String imageId) throws IOException; void downLoadFile(HttpServletResponse response, String fileType, String imageId) throws IOException;
List<SuspectInfo> querySuspectInfo(String sessionId,String name);
} }

@ -1,15 +0,0 @@
package com.supervision.service;
/**
*
*
*/
public interface TalkService {
/**
*
* @param questionId id
* @return
*/
String answer(String questionId);
}

@ -32,6 +32,7 @@ import com.supervision.domain.IrSessionHistory;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
/** /**
@ -103,17 +104,10 @@ public class IrSessionServiceImpl extends ServiceImpl<IrSessionMapper, IrSession
} }
this.updateById(irSession); this.updateById(irSession);
// 更新会话历史 // 更新会话历史
if (CollUtil.isNotEmpty(finishSessionVO.getIrrelevantAnswerHistoryId())) { if (CollUtil.isNotEmpty(finishSessionVO.getAnswerHistoryIdList()) && Objects.nonNull(finishSessionVO.getReasonType())){
irSessionHistoryService.lambdaUpdate().set(IrSessionHistory::getScoreCause, 2).set(IrSessionHistory::getDealState, 1) irSessionHistoryService.lambdaUpdate().set(IrSessionHistory::getScoreCause, 2).
.in(IrSessionHistory::getId, finishSessionVO.getIrrelevantAnswerHistoryId()).update(); set(IrSessionHistory::getDealState, finishSessionVO.getReasonType())
} .in(IrSessionHistory::getId, finishSessionVO.getAnswerHistoryIdList()).update();
if (CollUtil.isNotEmpty(finishSessionVO.getErrorAnswerHistoryId())) {
irSessionHistoryService.lambdaUpdate().set(IrSessionHistory::getScoreCause, 1).set(IrSessionHistory::getDealState, 1)
.in(IrSessionHistory::getId, finishSessionVO.getErrorAnswerHistoryId()).update();
}
if (CollUtil.isNotEmpty(finishSessionVO.getOtherAnswerHistoryId())) {
irSessionHistoryService.lambdaUpdate().set(IrSessionHistory::getScoreCause, 2).set(IrSessionHistory::getDealState, 1)
.in(IrSessionHistory::getId, finishSessionVO.getOtherAnswerHistoryId()).update();
} }
} }

@ -1,8 +1,12 @@
package com.supervision.service.impl; package com.supervision.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.supervision.domain.IrKnowledge; import com.supervision.domain.IrKnowledge;
import com.supervision.domain.IrSessionParam; import com.supervision.domain.IrSessionParam;
import com.supervision.domain.IrSqlParam; import com.supervision.domain.IrSqlParam;
@ -14,13 +18,16 @@ import com.supervision.service.QueryTemplateProcessor;
import com.supervision.util.ParamTypeConverter; import com.supervision.util.ParamTypeConverter;
import com.supervision.util.freemark.StringTemplateConfig; import com.supervision.util.freemark.StringTemplateConfig;
import com.supervision.util.mybatis.RowSqlMapper; import com.supervision.util.mybatis.RowSqlMapper;
import com.supervision.vo.robot.ArchivesReqVo;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -38,6 +45,9 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
private final IrSessionParamService sessionParamService; private final IrSessionParamService sessionParamService;
private final RowSqlMapper rowSqlMapper; private final RowSqlMapper rowSqlMapper;
@Value("${rootPath:F:\\tmp}")
private String rootPath;
@Override @Override
//note:重新构建一个事务,与调用方事务隔离 //note:重新构建一个事务,与调用方事务隔离
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@ -51,9 +61,12 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
// 校验必要参数 // 校验必要参数
QueryProcessDTO queryProcessDTO = QueryProcessDTO.builder().state(0).build(); QueryProcessDTO queryProcessDTO = QueryProcessDTO.builder().state(0).build();
queryProcessDTO.notNullParam(null, knowledge, "未查询到意图信息"); queryProcessDTO.notNullParam(null, knowledge, "未查询到意图信息");
queryProcessDTO.notEmptyParam("sqlTemplate", knowledge.getSqlTemplate(), "模板内容不能为空");
queryProcessDTO.notEmptyParam("resultTemplate", knowledge.getResultTemplate(), "结果模板不能为空"); queryProcessDTO.notEmptyParam("resultTemplate", knowledge.getResultTemplate(), "结果模板不能为空");
queryProcessDTO.notNullParam("resultType", knowledge.getResultType(), "结果类型不能为空"); queryProcessDTO.notNullParam("resultType", knowledge.getResultType(), "结果类型不能为空");
if (!Integer.valueOf(4).equals(knowledge.getResultType())){
// 除 档案文件 类型外其他情况sql模板不能为空
queryProcessDTO.notEmptyParam("sqlTemplate", knowledge.getSqlTemplate(), "模板内容不能为空");
}
if (Integer.valueOf(1).equals(queryProcessDTO.getState())) { if (Integer.valueOf(1).equals(queryProcessDTO.getState())) {
// 参数校验不通过,返回结果 // 参数校验不通过,返回结果
return queryProcessDTO; return queryProcessDTO;
@ -77,7 +90,20 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
// 执行查询sql // 执行查询sql
List<Map<String, Object>> maps = null; List<Map<String, Object>> maps = null;
try { try {
maps = rowSqlMapper.selectList(knowledge.getSqlTemplate(), getParams(paramsList, sessionParams)); if (Integer.valueOf(4).equals(knowledge.getResultType())){
Map<String, Object> params = getParams(paramsList, sessionParams);
// todo测试使用
String path = localArchivesFilePath(rootPath, MapUtil.getStr(params, "ajid"),
MapUtil.getStr(params, "khrzjhm"),MapUtil.getStr(params, "khrmc"));
File tempFile = FileUtil.createTempFile();
generateZip(tempFile, FileUtil.loopFiles(path), true);
Map<String, Object> stringHashMap = new HashMap<>();
stringHashMap.put("fileContent", tempFile);
maps = CollUtil.toList(stringHashMap);
}else {
maps = rowSqlMapper.selectList(knowledge.getSqlTemplate(), getParams(paramsList, sessionParams));
}
} catch (Exception e) { } catch (Exception e) {
log.error("执行查询sql失败", e); log.error("执行查询sql失败", e);
queryProcessDTO.setState(2); queryProcessDTO.setState(2);
@ -90,6 +116,13 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
return queryProcessDTO; return queryProcessDTO;
} }
public void generateZip(File targetZipFile, List<File> sourceFiles, boolean dirWithFlag) {
if (CollUtil.isNotEmpty(sourceFiles)) {
File[] fileArr = sourceFiles.toArray(new File[]{});
ZipUtil.zip(targetZipFile, dirWithFlag, fileArr);
}
}
private void wrapperSqlResult(IrKnowledge knowledge, List<Map<String, Object>> maps, QueryProcessDTO queryProcessDTO) { private void wrapperSqlResult(IrKnowledge knowledge, List<Map<String, Object>> maps, QueryProcessDTO queryProcessDTO) {
if (Integer.valueOf(1).equals(knowledge.getResultType())) { if (Integer.valueOf(1).equals(knowledge.getResultType())) {
@ -119,6 +152,12 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
queryProcessDTO.setContentType(3); queryProcessDTO.setContentType(3);
queryProcessDTO.setByteContentId(CollUtil.getFirst(maps).get("byteContentId").toString()); queryProcessDTO.setByteContentId(CollUtil.getFirst(maps).get("byteContentId").toString());
} }
if (Integer.valueOf(4).equals(knowledge.getResultType())){
queryProcessDTO.setStringContent(knowledge.getResultTemplate());
queryProcessDTO.setFileContent((File) CollUtil.getFirst(maps).get("fileContent"));
queryProcessDTO.setContentType(6);
}
// 去除回响应字符串中的特殊字符 // 去除回响应字符串中的特殊字符
if (StrUtil.isNotEmpty(queryProcessDTO.getStringContent())){ if (StrUtil.isNotEmpty(queryProcessDTO.getStringContent())){
queryProcessDTO.setStringContent(StrUtil.cleanBlank(queryProcessDTO.getStringContent())); queryProcessDTO.setStringContent(StrUtil.cleanBlank(queryProcessDTO.getStringContent()));
@ -137,4 +176,19 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
} }
private String localArchivesFilePath(String rootPath,String caseId,
String idNumber,String name) {
String path = StrUtil.join(File.separator,caseId,
StrUtil.join("-",name,idNumber));
if (StrUtil.isNotEmpty(rootPath)){
path = StrUtil.join(File.separator, rootPath, path);
}
// 判断文件是否存在
if (FileUtil.exist(path)){
return path;
}
return null;
}
} }

@ -19,6 +19,7 @@ import com.supervision.mapper.RobotDataMapper;
import com.supervision.service.*; import com.supervision.service.*;
import com.supervision.util.UserUtil; import com.supervision.util.UserUtil;
import com.supervision.vo.robot.ArchivesReqVo; import com.supervision.vo.robot.ArchivesReqVo;
import com.supervision.vo.robot.CommonDialogVo;
import com.supervision.vo.talk.RobotTalkReq; import com.supervision.vo.talk.RobotTalkReq;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -33,9 +34,7 @@ import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@ -66,11 +65,10 @@ public class RobotTalkServiceImpl implements RobotTalkService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public RobotTalkDTO textTalk2Robot(RobotTalkReq robotTalkReq) { public RobotTalkDTO textTalk2Robot(RobotTalkReq robotTalkReq) {
String sessionId = robotTalkReq.getSessionId(); String sessionId = robotTalkReq.getSessionId();
String message = robotTalkReq.getMessage();
Assert.notEmpty(sessionId, "sessionId不能为空"); Assert.notEmpty(sessionId, "sessionId不能为空");
TimeInterval timeInterval = new TimeInterval(); TimeInterval timeInterval = new TimeInterval();
timeInterval.start("all"); timeInterval.start("all");
log.info("textTalk2Robot:开始问答,sessionId:{},message:{}",sessionId,message); log.info("textTalk2Robot:开始问答,参数:{}",JSONUtil.toJsonStr(robotTalkReq));
RobotTalkDTO robotTalkDTO = RobotTalkDTO.builder() RobotTalkDTO robotTalkDTO = RobotTalkDTO.builder()
.sessionId(sessionId).doNext(true) .sessionId(sessionId).doNext(true)
@ -78,19 +76,28 @@ public class RobotTalkServiceImpl implements RobotTalkService {
.answerInfo(AnswerInfo.builder().contentType(robotTalkReq.getAnswerType()).build()) .answerInfo(AnswerInfo.builder().contentType(robotTalkReq.getAnswerType()).build())
.build(); .build();
// todo识别下载文件的语义 // 确认弹框信息
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());
}
}
// 提取信息中的关键信息 // 提取信息中的关键信息
if (Boolean.FALSE.equals(robotTalkReq.isConfirmFlag())){ if (Boolean.FALSE.equals(robotTalkReq.isConfirmFlag())){
extractInformation(sessionId, message, robotTalkDTO); extractInformation(sessionId, robotTalkReq.getMessage(), robotTalkDTO);
} }
// 匹配问题意图 // 匹配问题意图
MatchQuestionAnswerDTO matchQuestionAnswerDTO = matchQuestionAnswer(message); MatchQuestionAnswerDTO matchQuestionAnswerDTO = robotTalkDTO.isDoNext() ? matchQuestionAnswer(robotTalkReq.getMessage()) : null;
// 获取机器人配置 // 获取机器人配置
IrRobotConfig config = irRobotConfigService.lambdaQuery().one(); IrRobotConfig config = irRobotConfigService.lambdaQuery().one();
if (Objects.isNull(matchQuestionAnswerDTO) && robotTalkDTO.isDoNext()){ if (Objects.isNull(matchQuestionAnswerDTO) && robotTalkDTO.isDoNext()){
// 未匹配到查询意图,设置默认错误语 // 未匹配到查询意图,设置默认错误语
log.info("问题:{}未匹配到意图",message); log.info("问题:{}未匹配到意图",robotTalkReq.getMessage());
robotTalkDTO.getAnswerInfo().setMessage(config.getErrorLanguage()); robotTalkDTO.getAnswerInfo().setMessage(config.getErrorLanguage());
robotTalkDTO.setDoNext(false); robotTalkDTO.setDoNext(false);
} }
@ -101,14 +108,16 @@ public class RobotTalkServiceImpl implements RobotTalkService {
Integer.valueOf(3).equals(matchAnswer.getContentType())){ Integer.valueOf(3).equals(matchAnswer.getContentType())){
// 查询结果类型为字节数组 // 查询结果类型为字节数组
robotTalkDTO.getAnswerInfo().setContentType(3); robotTalkDTO.getAnswerInfo().setContentType(3);
robotTalkDTO.getAnswerInfo().setAnswerByteId(matchAnswer.getByteContentId()); robotTalkDTO.getAnswerInfo().setByteId(matchAnswer.getByteContentId());
robotTalkDTO.getAnswerInfo().setAnswerByte(matchAnswer.getByteContent()); robotTalkDTO.getAnswerInfo().setAnswerByte(matchAnswer.getByteContent());
}else { }else{
robotTalkDTO.getAnswerInfo().setAnswerFile(matchAnswer.getFileContent());
robotTalkDTO.getAnswerInfo().setMessage(decideAnswer(matchAnswer, config)); robotTalkDTO.getAnswerInfo().setMessage(decideAnswer(matchAnswer, config));
} }
} }
logSessionInfo(robotTalkDTO, matchQuestionAnswerDTO); logSessionInfo(robotTalkDTO, matchQuestionAnswerDTO);
robotTalkDTO.getAnswerInfo().setVoiceBase64(null);
log.info("textTalk2Robot:结束问答,耗时:{}ms",timeInterval.interval("all")); log.info("textTalk2Robot:结束问答,耗时:{}ms",timeInterval.interval("all"));
return robotTalkDTO; return robotTalkDTO;
@ -117,8 +126,7 @@ public class RobotTalkServiceImpl implements RobotTalkService {
private void logSessionInfo(RobotTalkDTO robotTalkDTO, MatchQuestionAnswerDTO matchQuestionAnswerDTO) { private void logSessionInfo(RobotTalkDTO robotTalkDTO, MatchQuestionAnswerDTO matchQuestionAnswerDTO) {
// 组装日志信息 // 组装日志信息
IrSessionHistory irSessionHistory = talk2SessionHistory(robotTalkDTO.getSessionId(), IrSessionHistory irSessionHistory = talk2SessionHistory(robotTalkDTO.getSessionId(),
robotTalkDTO.getAnswerInfo().getMessage(), matchQuestionAnswerDTO); robotTalkDTO, matchQuestionAnswerDTO);
irSessionHistory.setAnswerType(robotTalkDTO.getAnswerInfo().getContentType());
// 保存回答音频文件 // 保存回答音频文件
IrVoice irVoice = saveAudioIfNoAbsent(robotTalkDTO.getAnswerInfo().getMessage()); IrVoice irVoice = saveAudioIfNoAbsent(robotTalkDTO.getAnswerInfo().getMessage());
@ -129,16 +137,17 @@ public class RobotTalkServiceImpl implements RobotTalkService {
irSessionHistory.setAnswerVoiceId(irVoice.getId()); irSessionHistory.setAnswerVoiceId(irVoice.getId());
} }
if (Objects.nonNull(robotTalkDTO.getAnswerInfo().getAnswerByte())) { if (Objects.nonNull(robotTalkDTO.getAnswerInfo().getAnswerByte())
|| Objects.nonNull(robotTalkDTO.getAnswerInfo().getAnswerFile())) {
// 如果返回的结果是字节,保存到文件表 // 如果返回的结果是字节,保存到文件表
IrFile irFile = saveFileIfNoAbsent(robotTalkDTO.getAnswerInfo().getAnswerByte()); IrFile irFile = saveFileIfNoAbsent(robotTalkDTO.getAnswerInfo());
if (Objects.nonNull(irFile)) { if (Objects.nonNull(irFile)) {
robotTalkDTO.getAnswerInfo().setContentType(3); robotTalkDTO.getAnswerInfo().setContentType(3);
robotTalkDTO.getAnswerInfo().setAnswerByteId(irFile.getId()); robotTalkDTO.getAnswerInfo().setByteId(irFile.getId());
} }
} }
// 写入对话日志 // 写入对话日志
sessionService.save(irSessionHistory); sessionService.saveOrUpdate(irSessionHistory);
robotTalkDTO.getAskInfo().setAskId(irSessionHistory.getId()); robotTalkDTO.getAskInfo().setAskId(irSessionHistory.getId());
} }
@ -173,6 +182,7 @@ public class RobotTalkServiceImpl implements RobotTalkService {
if (Objects.nonNull(suspectInfo)){ if (Objects.nonNull(suspectInfo)){
sessionParams.add(new IrSessionParam(sessionId,"jykh",StrUtil.join(",",suspectInfo.getCardNumber()))); sessionParams.add(new IrSessionParam(sessionId,"jykh",StrUtil.join(",",suspectInfo.getCardNumber())));
sessionParams.add(new IrSessionParam(sessionId,"khrzjhm",suspectInfo.getIdNumber())); sessionParams.add(new IrSessionParam(sessionId,"khrzjhm",suspectInfo.getIdNumber()));
sessionParams.add(new IrSessionParam(sessionId,"khrmc",suspectInfo.getName()));
} }
IrSessionParam sessionParam = irSessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId) IrSessionParam sessionParam = irSessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId)
@ -220,17 +230,32 @@ public class RobotTalkServiceImpl implements RobotTalkService {
extractInformationDTO.getCardNumber()); extractInformationDTO.getCardNumber());
answerInfo.setContentType(6); answerInfo.setContentType(6);
answerInfo.setSuspectInfo(CollUtil.getFirst(suspectInfos)); SuspectInfo suspectInfo = Objects.isNull(CollUtil.getFirst(suspectInfos)) ?
extractInformation2Suspect(extractInformationDTO) : CollUtil.getFirst(suspectInfos);
answerInfo.setSuspectInfo(suspectInfo);
robotTalkDTO.setDoNext(false); 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) { private static String decideAnswer(QueryProcessDTO process, IrRobotConfig config) {
// 正确查询出结果 // 正确查询出结果
if (Integer.valueOf(0).equals(process.getState()) if (Integer.valueOf(0).equals(process.getState())){
&& Integer.valueOf(1).equals(process.getContentType())){ if (Integer.valueOf(1).equals(process.getContentType()) ||
// 查询结果类型为字符串 Integer.valueOf(6).equals(process.getContentType())){
// 查询结果类型为字符串
return process.getStringContent(); return process.getStringContent();
}
} }
// 参数异常或查询结果异常 // 参数异常或查询结果异常
if (Integer.valueOf(1).equals(process.getState()) if (Integer.valueOf(1).equals(process.getState())
@ -240,25 +265,36 @@ public class RobotTalkServiceImpl implements RobotTalkService {
return null; return null;
} }
private IrFile saveFileIfNoAbsent(byte[] byteContent) { private IrFile saveFileIfNoAbsent(AnswerInfo answerInfo) {
if (Objects.isNull(byteContent)){ if (Objects.isNull(answerInfo.getAnswerByte()) && Objects.isNull(answerInfo.getAnswerFile())){
return null; return null;
} }
String fileType = Integer.valueOf(3).equals(answerInfo.getContentType()) ? "1" : "2";
IrFile irFile = new IrFile(); IrFile irFile = new IrFile();
irFile.setFileByte(byteContent); irFile.setFileType(fileType);
irFile.setFileSize(byteContent.length);
irFile.setFileName("answer"); irFile.setFileName("answer");
irFile.setFileType("F"); 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); irFileService.save(irFile);
return irFile; return irFile;
} }
private IrSessionHistory talk2SessionHistory(String sessionId, String message, private IrSessionHistory talk2SessionHistory(String sessionId, RobotTalkDTO robotTalkDTO,
MatchQuestionAnswerDTO matchQuestionAnswerDTO) { MatchQuestionAnswerDTO matchQuestionAnswerDTO) {
IrSessionHistory sessionHistory = new IrSessionHistory(); IrSessionHistory sessionHistory = new IrSessionHistory();
sessionHistory.setId(robotTalkDTO.getAskInfo().getAskId());
sessionHistory.setSessionId(sessionId); sessionHistory.setSessionId(sessionId);
sessionHistory.setUserQuestion(message); AnswerInfo answerInfo = robotTalkDTO.getAnswerInfo();
sessionHistory.setAnswer(answerInfo.getMessage());
sessionHistory.setAnswerType(answerInfo.getContentType());
sessionHistory.setUserQuestion(answerInfo.getMessage());
sessionHistory.setCreateUserId(UserUtil.getUser().getId()); sessionHistory.setCreateUserId(UserUtil.getUser().getId());
if (Objects.nonNull(matchQuestionAnswerDTO)){ if (Objects.nonNull(matchQuestionAnswerDTO)){
sessionHistory.setMatchKnowledgeId(matchQuestionAnswerDTO.getMatchQuestionCode()); sessionHistory.setMatchKnowledgeId(matchQuestionAnswerDTO.getMatchQuestionCode());
@ -282,36 +318,53 @@ public class RobotTalkServiceImpl implements RobotTalkService {
} catch (IOException e) { } catch (IOException e) {
log.error("语音转文字失败", e); log.error("语音转文字失败", e);
} }
// todo: 设置问题语音长度和 历史记录中的语音id
RobotTalkDTO robotTalkDTO = this.textTalk2Robot(robotTalkReq); RobotTalkDTO robotTalkDTO = this.textTalk2Robot(robotTalkReq);
robotTalkDTO.getAskInfo().setContentType(2); robotTalkDTO.getAskInfo().setContentType(2);
return robotTalkDTO; return robotTalkDTO;
} }
@Override @Override
public List<RobotTalkDTO> talkList(String sessionId) { public List<CommonDialogVo> talkList(String sessionId) {
Assert.notEmpty(sessionId, "sessionId不能为空"); Assert.notEmpty(sessionId, "sessionId不能为空");
List<IrSessionHistory> sessionHistoryList = sessionService.lambdaQuery().eq(IrSessionHistory::getSessionId, sessionId).list(); List<IrSessionHistory> sessionHistoryList = sessionService.lambdaQuery().eq(IrSessionHistory::getSessionId, sessionId).orderBy(true, false,IrSessionHistory::getCreateTime).list();
return sessionHistoryList.stream().map(this::sessionHistory2RobotTalkDTO).collect(Collectors.toList());
// 获取音频的长度
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().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 RobotTalkDTO sessionHistory2RobotTalkDTO(IrSessionHistory sessionHistory) { private List<CommonDialogVo> sessionHistory2RobotTalkDTO(IrSessionHistory sessionHistory,Map<String, Integer> voiceLengthMap) {
if (Objects.isNull(sessionHistory)){ if (Objects.isNull(sessionHistory)){
return null; return null;
} }
AskInfo askInfo = AskInfo.builder() CommonDialogVo askDiaLog = CommonDialogVo.builder().dialogType(1)
.askId(sessionHistory.getId()) .dialogId(sessionHistory.getId()).sessionId(sessionHistory.getSessionId())
.message(sessionHistory.getUserQuestion()) .contentType(StrUtil.isEmpty(sessionHistory.getUserQuestionVoiceId()) ? 1 : 2)//userQuestionVoiceId 为空则为1 否则为2
.contentType(sessionHistory.getAnswerType()) .message(sessionHistory.getUserQuestion()).voiceBaseId(sessionHistory.getUserQuestionVoiceId())
//.audioLength(sessionHistory) .audioLength(voiceLengthMap.get(sessionHistory.getUserQuestionVoiceId())).build();
.build();
AnswerInfo answerInfo = AnswerInfo.builder() if (Integer.valueOf(6).equals(sessionHistory.getAnswerType())){
.contentType(sessionHistory.getAnswerType()) return CollUtil.newArrayList(askDiaLog);
.answerByteId(sessionHistory.getAnswerVoiceId()) }
.message(sessionHistory.getAnswer())
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(); .build();
return RobotTalkDTO.builder().sessionId(sessionHistory.getSessionId())
.askInfo(askInfo).answerInfo(answerInfo).build(); return CollUtil.toList(askDiaLog,answerDiaLog);
} }
@Override @Override
@ -340,12 +393,33 @@ public class RobotTalkServiceImpl implements RobotTalkService {
if (Objects.isNull(file) || Objects.isNull(file.getFileByte())){ if (Objects.isNull(file) || Objects.isNull(file.getFileByte())){
return; return;
} }
IoUtil.write(response.getOutputStream(), true, Base64.decode(file.getFileByte()));
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) { private String localArchivesFilePath(ArchivesReqVo archivesReq) {
String path = StrUtil.join(File.separator,archivesReq.getCaseId(), String path = StrUtil.join(File.separator,archivesReq.getCaseId(),
StrUtil.join("-",archivesReq.getName(),archivesReq.getIdNumber())); StrUtil.join("-",archivesReq.getName(),archivesReq.getIdNumber()),
archivesReq.getDocumentId());
// 判断文件是否存在 // 判断文件是否存在
if (FileUtil.exist(path)){ if (FileUtil.exist(path)){

@ -10,4 +10,16 @@ public class ArchivesReqVo {
private String idNumber; private String idNumber;
private String name; private String name;
private String documentId;
public ArchivesReqVo() {
}
public ArchivesReqVo(String caseId, String idNumber, String name, String documentId) {
this.caseId = caseId;
this.idNumber = idNumber;
this.name = name;
this.documentId = documentId;
}
} }

@ -0,0 +1,54 @@
package com.supervision.vo.robot;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class CommonDialogVo {
/**
* id
*/
private String dialogId;
/**
* id
*/
private String sessionId;
/**
* 1 2
*/
private Integer dialogType;
/**
* 1-2-3-4-5-
*/
private Integer contentType;
/**
*
*/
private String message;
/**
*
*/
private Integer audioLength;
/**
* id
*/
private String voiceBaseId;
/**
* id
*/
private String byteId;
}

@ -14,14 +14,14 @@ public class FinishSessionVO {
@ApiModelProperty("会话评分(1满意 2不满意,3未评估)") @ApiModelProperty("会话评分(1满意 2不满意,3未评估)")
private Integer sessionScore; private Integer sessionScore;
@ApiModelProperty("答非所问historyId") /**
private List<String> irrelevantAnswerHistoryId; * 1 2 3
*/
@ApiModelProperty("信息错误historyId") @ApiModelProperty("原因 1信息错误 2答非所问 3其他")
private List<String> errorAnswerHistoryId; private Integer reasonType;
@ApiModelProperty("其他historyId") @ApiModelProperty("选中的问题id")
private List<String> otherAnswerHistoryId; private List<String> answerHistoryIdList;
} }

@ -9,6 +9,11 @@ public class RobotTalkReq {
private String sessionId; private String sessionId;
/**
* id
*/
private String askId;
private String message; private String message;
/** /**

@ -1,6 +1,8 @@
package com.supervision; package com.supervision;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import com.supervision.domain.IrFile; import com.supervision.domain.IrFile;
import com.supervision.dto.QueryProcessDTO; import com.supervision.dto.QueryProcessDTO;
@ -16,17 +18,24 @@ import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.FileNotFoundException; import javax.sound.sampled.AudioInputStream;
import java.io.FileOutputStream; import javax.sound.sampled.AudioSystem;
import java.io.IOException; import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.StringWriter; import java.io.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -41,9 +50,9 @@ class AskApplicationTests {
private IrKnowledgeService irKnowledgeService; private IrKnowledgeService irKnowledgeService;
@Autowired @Autowired
private RowSqlMapper sqlMapper; private RowSqlMapper sqlMapper;
@Test @Test
void rowSqlMapperTest() { void rowSqlMapperTest() {
@ -52,7 +61,7 @@ class AskApplicationTests {
//params.put("dept_name","沈阳公安"); //params.put("dept_name","沈阳公安");
// and dept_name= #{dept_name} // and dept_name= #{dept_name}
List<Map<String, Object>> maps = sqlMapper.selectList("<script> select * from interro_robot.ir_robot_config where id = #{id} <if test= \"dept_name != null\">" + List<Map<String, Object>> maps = sqlMapper.selectList("<script> select * from interro_robot.ir_robot_config where id = #{id} <if test= \"dept_name != null\">" +
" and dept_name= #{dept_name} </if> </script>",params); " and dept_name= #{dept_name} </if> </script>", params);
System.out.println(maps); System.out.println(maps);
} }
@ -65,7 +74,7 @@ class AskApplicationTests {
Template temp = databaseFreemarkerConfiguration.getTemplate("1770984442920292354"); Template temp = databaseFreemarkerConfiguration.getTemplate("1770984442920292354");
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
HashMap<String, Object> params = new HashMap<>(); HashMap<String, Object> params = new HashMap<>();
params.put("jykh_count","ss"); params.put("jykh_count", "ss");
temp.process(params, writer); temp.process(params, writer);
System.out.println(writer); System.out.println(writer);
writer.close(); writer.close();
@ -105,16 +114,18 @@ class AskApplicationTests {
@Autowired @Autowired
private QueryTemplateProcessor queryTemplateProcessor; private QueryTemplateProcessor queryTemplateProcessor;
@Test @Test
void QueryTemplateProcessorProcessTest() { void QueryTemplateProcessorProcessTest() {
QueryProcessDTO process = queryTemplateProcessor.process("1770984442920292354", "123",null); QueryProcessDTO process = queryTemplateProcessor.process("1770984442920292354", "123", null);
System.out.println(process); System.out.println(process);
} }
@Autowired @Autowired
private IrFileService irFileService; private IrFileService irFileService;
@Test @Test
void fileByteSaveTest() { void fileByteSaveTest() {
IrFile irFile = new IrFile(); IrFile irFile = new IrFile();
@ -136,7 +147,7 @@ class AskApplicationTests {
private RobotDataMapper robotDataMapper; private RobotDataMapper robotDataMapper;
@Test @Test
void aaaTest() throws FileNotFoundException { void base64WriteTest() throws FileNotFoundException {
/*AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(null)*/ /*AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(null)*/
@ -149,4 +160,37 @@ class AskApplicationTests {
} }
@Test
void videoLengthTest() throws IOException, UnsupportedAudioFileException {
MockMultipartFile mockMultipartFile = new MockMultipartFile("test.xls", "originalFilename",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
FileUtil.getInputStream("F:\\tmp\\1\\心肺听诊-大湿罗音.mp3"));
InputStream inputStream = mockMultipartFile.getInputStream();
try {
// 创建元数据对象
Metadata metadata = new Metadata();
// 使用Apache Tika的自动检测解析器和内容处理器
Parser parser = new AutoDetectParser();
BodyContentHandler handler = new BodyContentHandler();
BufferedInputStream inputStream1 = FileUtil.getInputStream("F:\\tmp\\1\\心肺听诊-大湿罗音.mp3");
// 解析音频文件,提取元数据
parser.parse(inputStream1, handler, metadata, new ParseContext());
// 获取音频文件的长度(时长),以秒为单位
String duration = metadata.get("xmpDM:duration");
System.out.println(duration);
if (duration != null) {
/*return (long) (Double.parseDouble(duration) / 1000); // 转换为毫秒*/
}
} catch (Exception e) {
e.printStackTrace();
}
}
} }

Loading…
Cancel
Save