1. 添加 问答对话 功能

main
xueqingkun 11 months ago
parent 05b18c060b
commit 4fe9410236

@ -4,9 +4,9 @@ package com.supervision.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.KgInfo;
import com.supervision.qanything.dto.ChatResult;
import com.supervision.service.KGService;
import com.supervision.vo.kg.ChatReqVo;
import com.supervision.vo.kg.ChatResVo;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.NoSuchAlgorithmException;
@Slf4j
@ -25,13 +26,13 @@ public class KGController {
private final KGService kgService;
@ApiOperation("问答对话")
@PostMapping("/chat")
public ChatResult chat(@RequestBody ChatReqVo chatReqVo) {
public ChatResVo chat(@RequestBody ChatReqVo chatReqVo) throws NoSuchAlgorithmException {
return kgService.chat(chatReqVo.getQuestion());
}
@ApiOperation("问答对话")
@ApiOperation("热点知识")
@PostMapping("/hotKG")
public IPage<KgInfo> hotKG() {

@ -37,6 +37,8 @@ public interface QanythingService {
*/
ResultWrapper<List<UploadResult>> uploadDoc(String kbId, File file) throws NoSuchAlgorithmException;
ResultWrapper<List<UploadResult>> uploadDoc(String kbId, String fileName,byte[] bytes) throws NoSuchAlgorithmException;
ResultWrapper<List<UploadResult>> uploadUrl(String kbId, String url) throws NoSuchAlgorithmException;
ResultWrapper<List<String>> deleteFile(String kbId, List<String> fileIds) throws NoSuchAlgorithmException;

@ -115,6 +115,26 @@ public class QanythingServiceImpl implements QanythingService {
}
}
@Override
public ResultWrapper<List<UploadResult>> uploadDoc(String kbId, String fileName, byte[] bytes) throws NoSuchAlgorithmException {
Assert.notNull(bytes, "bytes数组不能为空");
Assert.notEmpty(fileName, "fileName不能为空");
Assert.notEmpty(kbId, "kbId不能为空");
log.info("uploadDoc:请求入参kbId:{} fileName:{}", kbId,fileName);
BaseParam baseParam = new BaseParam();
baseParam.setQ(kbId);
AuthV3Util.addAuthParams(APP_KEY, APP_SECRET,baseParam);
log.info("uploadDoc:请求参数:{}", JSONUtil.toJsonStr(baseParam));
HttpRequest request = HttpRequest.post(BASE_URL + QanythingConstant.URL_UPLOAD_DOC).form(baseParam.toMap()).form("file", bytes,fileName);
try (HttpResponse execute = request.execute()) {
String body = execute.body();
log.info("uploadDoc:响应结果:{}", body);
return JSONUtil.toBean(body, new TypeReference<ResultWrapper<List<UploadResult>>>(){},true);
}
}
@Override
public ResultWrapper<List<UploadResult>> uploadUrl(String kbId, String url) throws NoSuchAlgorithmException {

@ -4,9 +4,28 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.KgInfo;
import com.supervision.qanything.dto.ChatResult;
import com.supervision.vo.kg.ChatResVo;
import com.supervision.vo.kg.UploadDocResVo;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
public interface KGService {
ChatResult chat(String question);
ChatResVo chat(String question) throws NoSuchAlgorithmException;
IPage<KgInfo> hotKG(Page<KgInfo> page);
/**
*
* @param kbId
* @param file
*/
void uploadDoc(KgInfo kgInfo,String kbId, File file) throws IOException;
UploadDocResVo uploadDoc(String kbId, MultipartFile multipartFile);
}

@ -2,22 +2,41 @@ package com.supervision.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.model.GeBytearray;
import com.supervision.model.KgInfo;
import com.supervision.qanything.QanythingService;
import com.supervision.qanything.dto.ChatResult;
import com.supervision.qanything.dto.ResultWrapper;
import com.supervision.qanything.dto.SourceDTO;
import com.supervision.qanything.dto.UploadResult;
import com.supervision.service.GeBytearrayService;
import com.supervision.service.KGService;
import com.supervision.service.KgInfoService;
import com.supervision.vo.kg.ChatResVo;
import com.supervision.vo.kg.SourceKgInfo;
import com.supervision.vo.kg.UploadDocResVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -31,25 +50,81 @@ public class KGServiceImpl implements KGService {
private final KgInfoService kgInfoService;
private final GeBytearrayService geBytearrayService;
@Override
public ChatResult chat(String question) {
public ChatResVo chat(String question) throws NoSuchAlgorithmException {
Assert.notEmpty(question, "问题不能为空");
ResultWrapper<ChatResult> chat = qanythingService.chat(question, CollUtil.newArrayList(kbId));
if (!chat.isSuccess()) {
log.info("Qanything 聊天失败,原因:{}",chat.getMsg());
return ChatResVo.makeError();
}
ChatResult result = chat.getResult();
if (Objects.isNull(result)){
log.info("Qanything 聊天结果为空");
return ChatResVo.makeError();
}
ChatResVo chatResVo = ChatResVo.makeSuccess(result.getResponse());
if (CollUtil.isEmpty(result.getSource())){
return chatResVo;
}
Set<String> qaFileId = result.getSource().stream().map(SourceDTO::getFileId).filter(Objects::nonNull).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(qaFileId)) {
List<SourceKgInfo> sourceKgInfos = kgInfoService.lambdaQuery().in(KgInfo::getFileQaDocId, qaFileId).list()
.stream().map(SourceKgInfo::kgInfo2SourceKgInfo).collect(Collectors.toList());
chatResVo.setSourceKgInfoList(sourceKgInfos);
}
return chatResVo;
}
@Override
public IPage<KgInfo> hotKG(Page<KgInfo> page) {
return kgInfoService.lambdaQuery().eq(KgInfo::getHotFlag,1).page(page);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void uploadDoc(KgInfo kgInfo,String kbId, File file) throws IOException {
// 保存到qanthing中
try {
ResultWrapper<ChatResult> chat = qanythingService.chat(question, CollUtil.newArrayList(kbId));
if (chat.isSuccess()){
return chat.getResult();
ResultWrapper<List<UploadResult>> resultWrapper = qanythingService.uploadDoc(kbId, file);
if (!resultWrapper.isSuccess() || CollUtil.isEmpty(resultWrapper.getResult())){
log.error("Qanything 上传失败,原因:{}",resultWrapper.getMsg());
return;
}
List<UploadResult> result = resultWrapper.getResult();
if (CollUtil.size(result)>1){
log.warn("Qanything 上传成功,但是返回结果不止一个,返回结果:{}",result);
}
kgInfo.setFileQaDocId(CollUtil.getFirst(result).getFileId());
} catch (NoSuchAlgorithmException e) {
log.error("Qanything 签名失败",e);
throw new RuntimeException(e);
}
return null;
//保存到数据库中
GeBytearray geBytearray = new GeBytearray();
geBytearray.setFileName(file.getName());
geBytearray.setFileSize(file.length());
geBytearray.setContent(IoUtil.readBytes(Files.newInputStream(file.toPath())));
geBytearrayService.save(geBytearray);
// 保存文件信息
kgInfo.setFileByteId(geBytearray.getId());
kgInfoService.save(kgInfo);
}
@Override
public IPage<KgInfo> hotKG(Page<KgInfo> page) {
public UploadDocResVo uploadDoc(String kbId, MultipartFile multipartFile) {
return null;
return kgInfoService.lambdaQuery().eq(KgInfo::getHotFlag,1).page(page);
}
}

@ -0,0 +1,28 @@
package com.supervision.vo.kg;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ChatResVo {
private String response;
List<SourceKgInfo> sourceKgInfoList;
public static ChatResVo makeError() {
ChatResVo chatResVo = new ChatResVo();
chatResVo.response = "未查询到相关信息";
chatResVo.sourceKgInfoList = new ArrayList<>();
return chatResVo;
}
public static ChatResVo makeSuccess(String response) {
ChatResVo chatResVo = new ChatResVo();
chatResVo.response = response;
chatResVo.sourceKgInfoList = new ArrayList<>();
return chatResVo;
}
}

@ -0,0 +1,51 @@
package com.supervision.vo.kg;
import com.supervision.model.KgInfo;
import lombok.Data;
import java.util.Objects;
@Data
public class SourceKgInfo {
private String fileId;
/**
*
*/
private String title;
/**
* 1 2 3 4
*/
private String label;
/**
* 1:退
*/
private Integer classify;
/**
* 1 2 3 4:pdf 5:docx
*/
private Integer contentType;
/**
*
*/
private String summary;
public static SourceKgInfo kgInfo2SourceKgInfo(KgInfo kgInfo){
SourceKgInfo sourceKgInfo = new SourceKgInfo();
if (Objects.isNull(kgInfo)){
return sourceKgInfo;
}
sourceKgInfo.setFileId(kgInfo.getId());
sourceKgInfo.setTitle(kgInfo.getTitle());
sourceKgInfo.setLabel(kgInfo.getLabel());
sourceKgInfo.setClassify(kgInfo.getClassify());
sourceKgInfo.setContentType(kgInfo.getContentType());
sourceKgInfo.setSummary(kgInfo.getSummary());
return sourceKgInfo;
}
}

@ -0,0 +1,11 @@
package com.supervision.vo.kg;
import lombok.Data;
@Data
public class UploadDocResVo {
private String fileId;
private String fileName;
}

@ -106,4 +106,4 @@ youdao:
baseUrl: https://openapi.youdao.com
appKey: 071053d9bc4b544c
appSecret: nObcggsh0li2eGtyII6XOGtSCo6nFgdD
kbId: KB249d43fdb96f4e1399340b8f95e1baa0_240328
kbId: KB6ada48988e694ad197af53cc0d1e4b78_240328

@ -3,19 +3,23 @@ package com.supervision;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;
import com.supervision.model.KgInfo;
import com.supervision.qanything.QanythingService;
import com.supervision.qanything.dto.ChatResult;
import com.supervision.qanything.dto.CreateKBResult;
import com.supervision.qanything.dto.ResultWrapper;
import com.supervision.qanything.dto.UploadResult;
import com.supervision.service.KGService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
@ -46,7 +50,7 @@ public class YoudaoTest {
public void qanythingUploadDocTest() throws NoSuchAlgorithmException {
//
ResultWrapper<List<UploadResult>> resultWrapper = qanythingService.fileList("KB403a6543629648a3a74b60be5707398f_240328");
/* ResultWrapper<List<UploadResult>> resultWrapper = qanythingService.fileList("KB403a6543629648a3a74b60be5707398f_240328");
List<UploadResult> result = resultWrapper.getResult();
Set<String> fileNames = result.stream().map(UploadResult::getFileName).collect(Collectors.toSet());
@ -59,7 +63,11 @@ public class YoudaoTest {
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
});
});*/
ResultWrapper<List<UploadResult>> resultWrapper = qanythingService.uploadDoc("KB403a6543629648a3a74b60be5707398f_240328", new File("F:\\supervision\\doc\\数据库备份\\virtual_patient_137_0301.txt"));
// {"errorCode":"0","msg":"SUCCESS","requestId":"2a70ee9e-e0d3-41cc-a54d-b0570106ad05","result":[{"fileId":"fb27e1dcfc9d4084ab2a987145a81c19","fileName":"virtual_patient_137_0301.txt","status":"0"}]}
System.out.println(JSONUtil.toJsonStr(resultWrapper));
}
@Test
@ -118,4 +126,26 @@ public class YoudaoTest {
// {"errorCode":"0","msg":"SUCCESS","requestId":"6d1c37a6-f10f-438a-a372-57ab6aeabba0","result":null}
System.out.println(resultWrapper.getResult());
}
@Autowired
private KGService kgService;
@Test
public void uploadDocTest() throws IOException {
String kbid = "KB6ada48988e694ad197af53cc0d1e4b78_240328";// 养老退休知识库-dev
FileUtil.walkFiles(new File("F:\\supervision\\doc\\深圳人社\\v0.1相关文档"),(f)->{
if (f.getName().equals("广东省城乡居民基本养老保险实施办法.docx")){
return;
}
KgInfo kgInfo = new KgInfo();
kgInfo.setTitle(f.getName().split("\\.")[0]);
try {
kgService.uploadDoc(kgInfo,kbid,f);
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(f.getName() + "====ok====");
});
}
}

@ -1,11 +1,9 @@
package com.supervision.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Arrays;
import lombok.Data;
/**
@ -18,6 +16,7 @@ public class GeBytearray implements Serializable {
/**
*
*/
@TableId
private String id;
/**
@ -28,7 +27,7 @@ public class GeBytearray implements Serializable {
/**
*
*/
private Integer fileSize;
private Long fileSize;
/**
*

@ -1,6 +1,5 @@
package com.supervision.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@ -21,13 +20,18 @@ public class KgInfo implements Serializable {
@TableId
private String id;
/**
* 1 2 3 4
*/
private String label;
/**
*
*/
private String title;
/**
* 1 2 3
* 1:退
*/
private Integer classify;
@ -37,7 +41,7 @@ public class KgInfo implements Serializable {
private Integer hotFlag;
/**
* 1 2 3
* 1 2 3 4:pdf 5:docx
*/
private Integer contentType;
@ -57,7 +61,7 @@ public class KgInfo implements Serializable {
private String summary;
/**
*
* 1:退
*/
private String policyItem;

@ -6,6 +6,7 @@
<resultMap id="BaseResultMap" type="com.supervision.model.KgInfo">
<result property="id" column="id" jdbcType="VARCHAR"/>
<result property="label" column="label" jdbcType="VARCHAR"/>
<result property="title" column="title" jdbcType="VARCHAR"/>
<result property="classify" column="classify" jdbcType="INTEGER"/>
<result property="hotFlag" column="hot_flag" jdbcType="INTEGER"/>
@ -23,7 +24,7 @@
</resultMap>
<sql id="Base_Column_List">
id,title,classify,
id,label,title,classify,
content_type,hot_flag,pre_url,content,summary,
policy_item,file_byte_id,file_qa_doc_id,create_user_id,create_time,
update_user_id,update_time

Loading…
Cancel
Save