添加代码 问答功能代码

main
xueqingkun 1 year ago
parent 3df54e29dc
commit 7859e05d7a

@ -86,13 +86,6 @@
<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>

@ -57,20 +57,13 @@ public class RobotTalkController {
robotTalkService.getAudio(response,audioId); robotTalkService.getAudio(response,audioId);
} }
/* @ApiOperation("下载嫌疑人归档数据")
@GetMapping("/downLoadArchives")
public void downLoadArchives(HttpServletResponse response,
ArchivesReqVo archivesReq) throws IOException {
robotTalkService.downLoadArchives(response,archivesReq);
}*/
@ApiOperation("下载对话过程中的文件") @ApiOperation("下载对话过程中的文件")
@GetMapping("/downLoadFile") @GetMapping("/downLoadFile")
public void downLoadFile(HttpServletResponse response, public void downLoadFile(HttpServletResponse response,
String fileType, String fileType,
String imageId) throws IOException { String fileId) throws IOException {
robotTalkService.downLoadFile(response,fileType,imageId); robotTalkService.downLoadFile(response,fileType,fileId);
} }

@ -1,14 +1,16 @@
package com.supervision.dto; package com.supervision.dto;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
@Data @Data
@Builder @Builder
@ -48,6 +50,14 @@ public class QueryProcessDTO {
private List<ParamCheckDTO> paramCheckList; private List<ParamCheckDTO> paramCheckList;
public String paramCheckToMessage(){
if (CollUtil.isEmpty(paramCheckList)){
return "";
}
return paramCheckList.stream().map(ParamCheckDTO::toMessage).collect(Collectors.joining(","));
}
/** /**
* *
@ -59,6 +69,9 @@ public class QueryProcessDTO {
public <T> void notNullParam(String paramName, T value, String errorMsgTemplate){ public <T> void notNullParam(String paramName, T value, String errorMsgTemplate){
if(Objects.isNull(value)){ if(Objects.isNull(value)){
this.state = 1; this.state = 1;
if (null == paramCheckList){
paramCheckList = new ArrayList<>();
}
this.paramCheckList.add(new ParamCheckDTO(paramName, errorMsgTemplate,1)); this.paramCheckList.add(new ParamCheckDTO(paramName, errorMsgTemplate,1));
} }
@ -90,5 +103,18 @@ public class QueryProcessDTO {
* 1 2 3 * 1 2 3
*/ */
private Integer errorType; private Integer errorType;
public String toMessage(){
if (Integer.valueOf(1).equals(errorType)){
return String.format("参数%s缺失",paramName);
}
if (Integer.valueOf(2).equals(errorType)){
return String.format("参数%s值错误",paramName);
}
if (Integer.valueOf(3).equals(errorType)){
return String.format("参数%s类型错误",paramName);
}
return "";
}
} }
} }

@ -10,5 +10,8 @@ public interface VoiceService {
String voiceToText(MultipartFile file, String sessionId) throws IOException; String voiceToText(MultipartFile file, String sessionId) throws IOException;
String voiceToText(byte[] bytes, String sessionId) throws IOException;
TtsResultDTO textToVoice(String text); TtsResultDTO textToVoice(String text);
} }

@ -2,7 +2,6 @@ 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.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.map.MapUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@ -18,7 +17,6 @@ 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;
@ -46,7 +44,7 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
private final RowSqlMapper rowSqlMapper; private final RowSqlMapper rowSqlMapper;
@Value("${rootPath:F:\\tmp}") @Value("${query.rootPath:/data/intro-robot}")
private String rootPath; private String rootPath;
@Override @Override
//note:重新构建一个事务,与调用方事务隔离 //note:重新构建一个事务,与调用方事务隔离
@ -77,10 +75,10 @@ public class QueryTemplateProcessorImpl implements QueryTemplateProcessor {
// 校验知识查询sql必填参数 // 校验知识查询sql必填参数
List<IrSessionParam> sessionParams = null == sessionParamSupplier ? List<IrSessionParam> sessionParams = null == sessionParamSupplier ?
sessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId).list() : sessionParamSupplier.get(); sessionParamService.lambdaQuery().eq(IrSessionParam::getSessionId, sessionId).list() : sessionParamSupplier.get();
Set<String> sessionParamsNames = sessionParams.stream().map(IrSessionParam::getParamName).collect(Collectors.toSet()); Set<String> sessionParamsNames = sessionParams.stream().filter(param->StrUtil.isNotEmpty(param.getParamValue())).map(IrSessionParam::getParamName).collect(Collectors.toSet());
paramsList.stream().filter(param -> Integer.valueOf(1).equals(param.getParamRequire())).forEach(param -> { paramsList.stream().filter(param -> Integer.valueOf(1).equals(param.getParamRequire())).forEach(param -> {
queryProcessDTO.notNullParam(param.getParamName(), queryProcessDTO.notNullParam(param.getParamName(),
sessionParamsNames.contains(param.getParamName()) ? true : null, "参数[" + param.getParamName() + "]未设置!"); sessionParamsNames.contains(param.getParamName())? true : null, "参数[" + param.getParamName() + "]未设置!");
}); });
if (Integer.valueOf(1).equals(queryProcessDTO.getState())) { if (Integer.valueOf(1).equals(queryProcessDTO.getState())) {
// 参数校验不通过,返回结果 // 参数校验不通过,返回结果

@ -144,6 +144,7 @@ public class RobotTalkServiceImpl implements RobotTalkService {
if (Objects.nonNull(irFile)) { if (Objects.nonNull(irFile)) {
robotTalkDTO.getAnswerInfo().setContentType(3); robotTalkDTO.getAnswerInfo().setContentType(3);
robotTalkDTO.getAnswerInfo().setByteId(irFile.getId()); robotTalkDTO.getAnswerInfo().setByteId(irFile.getId());
irSessionHistory.setAnswerFileId(irFile.getId());
} }
} }
// 写入对话日志 // 写入对话日志
@ -258,8 +259,11 @@ public class RobotTalkServiceImpl implements RobotTalkService {
} }
} }
// 参数异常或查询结果异常 // 参数异常或查询结果异常
if (Integer.valueOf(1).equals(process.getState()) if (Integer.valueOf(1).equals(process.getState())){
|| Integer.valueOf(2).equals(process.getState())){ return StrUtil.join(",",process.paramCheckToMessage());
}
if (Integer.valueOf(2).equals(process.getState())){
return config.getUnrecognizedOne(); return config.getUnrecognizedOne();
} }
return null; return null;
@ -294,7 +298,8 @@ public class RobotTalkServiceImpl implements RobotTalkService {
AnswerInfo answerInfo = robotTalkDTO.getAnswerInfo(); AnswerInfo answerInfo = robotTalkDTO.getAnswerInfo();
sessionHistory.setAnswer(answerInfo.getMessage()); sessionHistory.setAnswer(answerInfo.getMessage());
sessionHistory.setAnswerType(answerInfo.getContentType()); sessionHistory.setAnswerType(answerInfo.getContentType());
sessionHistory.setUserQuestion(answerInfo.getMessage());
sessionHistory.setUserQuestion(robotTalkDTO.getAnswerInfo().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());
@ -312,8 +317,10 @@ public class RobotTalkServiceImpl implements RobotTalkService {
Assert.notEmpty(sessionId, "sessionId不能为空"); Assert.notEmpty(sessionId, "sessionId不能为空");
Assert.notNull(multipartFile, "multipartFile不能为空"); Assert.notNull(multipartFile, "multipartFile不能为空");
byte[] bytes = null;
try { try {
String message = voiceService.voiceToText(multipartFile, sessionId); bytes = multipartFile.getBytes();
String message = voiceService.voiceToText(bytes, sessionId);
robotTalkReq.setMessage(message); robotTalkReq.setMessage(message);
} catch (IOException e) { } catch (IOException e) {
log.error("语音转文字失败", e); log.error("语音转文字失败", e);
@ -321,6 +328,18 @@ public class RobotTalkServiceImpl implements RobotTalkService {
// todo: 设置问题语音长度和 历史记录中的语音id // todo: 设置问题语音长度和 历史记录中的语音id
RobotTalkDTO robotTalkDTO = this.textTalk2Robot(robotTalkReq); RobotTalkDTO robotTalkDTO = this.textTalk2Robot(robotTalkReq);
robotTalkDTO.getAskInfo().setContentType(2); 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::getAnswerVoiceId,irVoice.getId()).update();
}
}
return robotTalkDTO; return robotTalkDTO;
} }
@ -328,16 +347,14 @@ public class RobotTalkServiceImpl implements RobotTalkService {
public List<CommonDialogVo> 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).orderBy(true, false,IrSessionHistory::getCreateTime).list(); List<IrSessionHistory> sessionHistoryList = sessionService.lambdaQuery().eq(IrSessionHistory::getSessionId, sessionId).orderBy(true, true,IrSessionHistory::getCreateTime).list();
// 获取音频的长度 // 获取音频的长度
List<String> voiceIds = sessionHistoryList.stream() List<String> voiceIds = sessionHistoryList.stream()
.map(session -> CollUtil.toList(session.getAnswerVoiceId(), session.getUserQuestionVoiceId())) .map(session -> CollUtil.toList(session.getAnswerVoiceId(), session.getUserQuestionVoiceId()))
.flatMap(Collection::stream).filter(StrUtil::isNotEmpty).collect(Collectors.toList()); .flatMap(Collection::stream).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
Map<String, Integer> voiceLengthMap = CollUtil.isEmpty(voiceIds) ? new HashMap<>() : Map<String, Integer> voiceLengthMap = CollUtil.isEmpty(voiceIds) ? new HashMap<>() :
irVoiceService.listByIds(voiceIds).stream().collect(Collectors.toMap(IrVoice::getId, IrVoice::getLength)); 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)) return sessionHistoryList.stream().map(session->this.sessionHistory2RobotTalkDTO(session,voiceLengthMap))
.filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList()); .filter(Objects::nonNull).flatMap(Collection::stream).collect(Collectors.toList());

@ -27,6 +27,15 @@ public class VoiceServiceImpl implements VoiceService {
return transform; return transform;
} }
@Override
public String voiceToText(byte[] bytes, String sessionId) throws IOException {
log.info("语音转文字开始");
TimeInterval timeInterval = DateUtil.timer();
String transform = AsrUtil.asrTransformByBytes(bytes);
log.info("语音转文字结束,耗时:{}", timeInterval.interval());
return transform;
}
@Override @Override
public TtsResultDTO textToVoice(String text) { public TtsResultDTO textToVoice(String text) {

@ -42,7 +42,7 @@ spring:
slow-sql-millis: 5000 slow-sql-millis: 5000
merge-sql: false merge-sql: false
matchTool: matchTool:
url: http://192.168.10.29:8000 url: http://192.168.10.137:9711
scoreThreshold: 0.4 scoreThreshold: 0.4
paddle-speech: paddle-speech:
# https://github.com/PaddlePaddle/PaddleSpeech/wiki/PaddleSpeech-Server-RESTful-API # https://github.com/PaddlePaddle/PaddleSpeech/wiki/PaddleSpeech-Server-RESTful-API
@ -51,4 +51,7 @@ paddle-speech:
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml mapper-locations: classpath*:mapper/**/*.xml
configuration: configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
query:
rootPath: /data/intro-robot

@ -170,27 +170,12 @@ class AskApplicationTests {
InputStream inputStream = mockMultipartFile.getInputStream(); InputStream inputStream = mockMultipartFile.getInputStream();
try {
// 创建元数据对象 byte[] bytes = IoUtil.readBytes(inputStream);
Metadata metadata = new Metadata();
System.out.println(bytes.length);
// 使用Apache Tika的自动检测解析器和内容处理器 byte[] bytes1 = IoUtil.readBytes(inputStream);
Parser parser = new AutoDetectParser();
BodyContentHandler handler = new BodyContentHandler(); System.out.println(bytes1.length);
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