1. 添加案件证据文件到知识库文库

2. 添加对话接口
jinan_dev
xueqingkun 5 months ago
parent 6baed0d345
commit 3ec4963db1

@ -1,7 +1,10 @@
package com.supervision.police.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.police.domain.Conversation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.supervision.police.vo.ConversationResVo;
/**
* @author yaxin
@ -11,6 +14,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface ConversationMapper extends BaseMapper<Conversation> {
IPage<ConversationResVo> queryUserConversationList(String userId, Page<ConversationResVo> page);
}

@ -1,9 +1,17 @@
package com.supervision.police.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.supervision.police.vo.ChatReqVO;
import com.supervision.police.vo.ChatResVO;
import com.supervision.police.vo.ConversationResVo;
public interface ChatService {
ChatResVO chat(ChatReqVO chatReqVO);
ChatResVO chatNew(ChatReqVO chatReqVO);
IPage<ChatResVO> queryConversationInfoList(String conversationId, int page, int size);
IPage<ConversationResVo> queryUserConversationList(String userId, int page, int size);
}

@ -1,7 +1,10 @@
package com.supervision.police.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.police.domain.Conversation;
import com.baomidou.mybatisplus.extension.service.IService;
import com.supervision.police.vo.ConversationResVo;
/**
* @author yaxin
@ -10,4 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface ConversationService extends IService<Conversation> {
IPage<ConversationResVo> queryUserConversationList(String userId, Page<ConversationResVo> objectPage);
}

@ -58,5 +58,8 @@ public interface ModelCaseService extends IService<ModelCase> {
*/
void migrateRecordKnowledgeBase();
List<String> listCaseFileIds(String caseId);
}

@ -12,9 +12,5 @@ public interface NoteRecordService extends IService<NoteRecord> {
void uploadFileToLangChainChat(String caseId);
void uploadRecordFileToDifyKnowledgeBase(String caseId);
String saveOrUpdRecord(NoteRecord noteRecord);
}

@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.supervision.chat.client.LangChainChatService;
import com.supervision.chat.client.dto.chat.ChatReqDTO;
import com.supervision.chat.client.dto.chat.ChatResDTO;
@ -17,6 +18,7 @@ import com.supervision.police.dto.caseScore.CaseScoreDetailDTO;
import com.supervision.police.service.*;
import com.supervision.police.vo.ChatReqVO;
import com.supervision.police.vo.ChatResVO;
import com.supervision.police.vo.ConversationResVo;
import com.supervision.police.vo.dify.DifyChatReqVO;
import com.supervision.utils.DifyApiUtil;
import lombok.RequiredArgsConstructor;
@ -170,6 +172,23 @@ public class ChatServiceImpl implements ChatService {
return chatResVO;
}
@Override
public IPage<ChatResVO> queryConversationInfoList(String conversationId, int page, int size) {
Assert.notEmpty(conversationId, "会话id不能为空");
IPage<ConversationQa> qaPage = conversationQaService.lambdaQuery().eq(ConversationQa::getConversationId, conversationId)
.orderBy(true, true, ConversationQa::getQuestionTime).page(Page.of(page, size));
return qaPage.convert(ChatResVO::new);
}
@Override
public IPage<ConversationResVo> queryUserConversationList(String userId, int page, int size) {
Assert.notEmpty(userId, "用户id不能为空");
return conversationService.queryUserConversationList(userId, new Page<>(page,size));
}
/**
*
*

@ -1,9 +1,12 @@
package com.supervision.police.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.police.domain.Conversation;
import com.supervision.police.service.ConversationService;
import com.supervision.police.mapper.ConversationMapper;
import com.supervision.police.vo.ConversationResVo;
import org.springframework.stereotype.Service;
/**
@ -15,6 +18,10 @@ import org.springframework.stereotype.Service;
public class ConversationServiceImpl extends ServiceImpl<ConversationMapper, Conversation>
implements ConversationService{
@Override
public IPage<ConversationResVo> queryUserConversationList(String userId, Page<ConversationResVo> page) {
return super.getBaseMapper().queryUserConversationList(userId, page);
}
}

@ -403,7 +403,7 @@ public class ModelCaseServiceImpl extends ServiceImpl<ModelCaseMapper, ModelCase
return;
}
log.info("案件:{} 开始上传笔录到支持库...",modelCase.getCaseName());
noteRecordService.uploadRecordFileToDifyKnowledgeBase(caseId);
difyApiUtil.uploadCaseFileToDifyKnowledgeBase(modelCase,this.listCaseFileIds(caseId));
log.info("案件:{} 上传笔录到支持库成功...",modelCase.getCaseName());
}
@ -433,6 +433,22 @@ public class ModelCaseServiceImpl extends ServiceImpl<ModelCaseMapper, ModelCase
log.info("===========>>>>>迁移笔录到支持库完成,成功个数:{},失败个数:{},总耗时:{}秒...<<<<<===========",success,allModelCase.size()-success,timer.intervalSecond());
}
@Override
public List<String> listCaseFileIds(String caseId) {
List<NoteRecord> noteRecordList = noteRecordService.lambdaQuery().eq(NoteRecord::getCaseId, caseId).list();
List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS = caseEvidenceService.queryEvidenceList(caseId);
List<String> recordFileIds = noteRecordList.stream().map(NoteRecord::getFileIds)
.filter(StrUtil::isNotEmpty).flatMap(fileId -> StrUtil.split(fileId, ",").stream()).collect(Collectors.toList());
List<String> evidenceFileIds = caseEvidenceDetailDTOS.stream().map(CaseEvidenceDetailDTO::getFileList)
.filter(list -> !CollUtil.isEmpty(list)).flatMap(Collection::stream).map(EvidenceFileDTO::getFileId).toList();
recordFileIds.addAll(evidenceFileIds);
return recordFileIds.stream().distinct().toList();
}
/**
*

@ -27,7 +27,7 @@ import com.supervision.police.mapper.*;
import com.supervision.police.mybatis.RowSqlMapper;
import com.supervision.police.service.*;
import com.supervision.utils.CalculationUtil;
import com.supervision.utils.IndexRuleUtil;
import com.supervision.utils.DifyApiUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -96,6 +96,11 @@ public class ModelServiceImpl implements ModelService {
private final CaseEvidencePropertyService caseEvidencePropertyService;
private final DifyApiUtil difyApiUtil;
@Autowired
private ModelCaseService modelCaseService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<?> analyseCase(AnalyseCaseDTO analyseCaseDTO) {
@ -171,7 +176,7 @@ public class ModelServiceImpl implements ModelService {
calculateFinalScore(analyseCaseDTO, modelCase, atomicResultMap);
caseStatusManageService.whenAnalyseCaseSuccess(analyseCaseDTO.getCaseId(), modelCase.getTotalScore());
// 计算完成之后,把所有的笔录上传到模型
noteRecordService.uploadRecordFileToDifyKnowledgeBase(analyseCaseDTO.getCaseId());
difyApiUtil.uploadCaseFileToDifyKnowledgeBase(modelCase, modelCaseService.listCaseFileIds(analyseCaseDTO.getCaseId()));
return R.ok();
}
@ -323,7 +328,7 @@ public class ModelServiceImpl implements ModelService {
modelCase.setTotalScore(max);
log.info("更新案件得分情况。最终得分:{}分(共性+入罪/共性+出罪 取最大值)。入罪:{}分。出罪:{}分。共性:{}分。", max, rz, cz, gx);
caseStatusManageService.whenAnalyseCaseSuccess(analyseCaseDTO.getCaseId(), modelCase.getTotalScore());
noteRecordService.uploadRecordFileToDifyKnowledgeBase(analyseCaseDTO.getCaseId());
difyApiUtil.uploadCaseFileToDifyKnowledgeBase(modelCase, modelCaseService.listCaseFileIds(caseId));
return R.ok();
}

@ -106,64 +106,6 @@ public class NoteRecordServiceImpl extends ServiceImpl<NoteRecordMapper, NoteRec
}
@Override
public void uploadRecordFileToDifyKnowledgeBase(String caseId) {
ModelCase modelCase = modelCaseService.getById(caseId);
if (null == modelCase || StrUtil.isEmpty(modelCase.getKnowledgeBaseId())){
log.warn("uploadRecordFileToKnowledgeBase:案件:{}案件或者知识库为空,不进行知识库维护!", caseId);
return;
}
List<Document> documents = difyApiUtil.queryDocuments(modelCase.getKnowledgeBaseId());
Set<String> documentFileIds = documents.stream().map(Document::getFileId).collect(Collectors.toSet());
List<NoteRecord> recordList = this.lambdaQuery().eq(NoteRecord::getCaseId, caseId).list();
// 只上传 doc docx、txt、md、pdf 文件且文件大小不能超过15mb
List<String> allFileIds = recordList.stream().map(NoteRecord::getFileIds).filter(StrUtil::isNotEmpty)
.flatMap(s -> StrUtil.split(s, ",").stream()).collect(Collectors.toList());
List<MinioFile> minioFiles = minioService.listMinioFile(allFileIds);
List<String> recordFileIds = minioFiles.stream().filter(minioFile -> {
boolean currentFileSize = minioFile.getSize() < 15 * 1024 * 1024;
if (!currentFileSize) {
log.warn("文件大小超过15mb不进行知识库维护:{}", minioFile.getFilename());
return false;
}
boolean currentFileType = StrUtil.equalsAny(minioFile.getFileType(), "doc", "docx", "txt", "md", "pdf");
if (!currentFileType) {
log.warn("文件:{}类型非doc、docx、txt、md、pdf不进行知识库维护...", minioFile.getFilename());
return false;
}
return true;
}).map(MinioFile::getId).toList();
Map<String, MinioFile> fileMap = minioFiles.stream().collect(Collectors.toMap(MinioFile::getId, target -> target));
log.info("案件:{},共有:{}个笔录文件,符合上传要求的文件有:{}",modelCase.getCaseName(), allFileIds.size(), recordFileIds.size());
for (String recordId : recordFileIds) {
// 把新增的笔录数据添加到到知识库
if (!documentFileIds.contains(recordId)){
log.info("案件:{},笔录文件:{},添加到知识库...",modelCase.getCaseName(), fileMap.get(recordId).getFilename());
difyApiUtil.createDocumentByFile(modelCase.getKnowledgeBaseId(),recordId);
}
}
if (CollUtil.isNotEmpty(recordFileIds)){
for (Document document : documents) {
String fileId = document.getFileId();
if (StrUtil.isNotEmpty(fileId) && !recordFileIds.contains(fileId)){
// 删除不在笔录文件列表中的知识库
log.info("案件:{},笔录文件:{},从知识库中删除...",modelCase.getCaseName(), document.getName());
difyApiUtil.deleteDocument(modelCase.getKnowledgeBaseId(),document.getId());
}
}
}
log.info("案件:{}上传笔录文件到知识库完成!",modelCase.getCaseName());
}
@Override
public String saveOrUpdRecord(NoteRecord noteRecord) {

@ -1,8 +1,10 @@
package com.supervision.police.vo;
import com.supervision.chat.client.dto.chat.ChatResDTO;
import com.supervision.police.domain.ConversationQa;
import lombok.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -10,6 +12,18 @@ import java.util.Objects;
@Data
public class ChatResVO {
/**
* id
*/
private String id;
/**
*
*/
private String question;
private Date questionTime;
private String answer;
private Map<String, Object> answwerMap;
private String type;
@ -26,4 +40,16 @@ public class ChatResVO {
this.answer = chatResDTO.getAnswer();
this.docs = chatResDTO.getDocs();
}
public ChatResVO(ConversationQa conversationQa) {
if (null == conversationQa){
return;
}
this.setId(conversationQa.getId());
this.setQuestion(conversationQa.getQuestion());
this.setAnswer(conversationQa.getAnswer());
this.setType(conversationQa.getType());
this.setQuestionTime(conversationQa.getQuestionTime());
this.setIntentType(conversationQa.getIntentType());
}
}

@ -0,0 +1,33 @@
package com.supervision.police.vo;
import lombok.Data;
@Data
public class ConversationResVo {
/**
* id
*/
private String conversationId;
/**
* id
*/
private String caseId;
/**
*
*/
private String caseName;
/**
*
*/
private String caseActor;
/**
* id
*/
private String caseActorId;
}

@ -10,6 +10,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.supervision.minio.domain.MinioFile;
import com.supervision.minio.service.MinioService;
import com.supervision.police.domain.ModelCase;
import com.supervision.police.vo.dify.DatasetReqVO;
import com.supervision.police.vo.dify.DatasetResVO;
import com.supervision.police.vo.dify.DifyChatReqVO;
@ -30,9 +31,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import static com.supervision.common.constant.DifyConstants.*;
@ -257,6 +257,58 @@ public class DifyApiUtil {
return documents;
}
public void uploadCaseFileToDifyKnowledgeBase(ModelCase modelCase,List<String> allFileIds) {
if (StrUtil.isEmpty(modelCase.getKnowledgeBaseId())){
log.warn("uploadRecordFileToKnowledgeBase:案件:{}案件或者知识库为空,不进行知识库维护!", modelCase.getCaseName());
return;
}
List<Document> documents = this.queryDocuments(modelCase.getKnowledgeBaseId());
Set<String> documentFileIds = documents.stream().map(Document::getFileId).collect(Collectors.toSet());
// 只上传 doc docx、txt、md、pdf 文件且文件大小不能超过15mb
List<MinioFile> minioFiles = minioService.listMinioFile(allFileIds);
List<String> recordFileIds = minioFiles.stream().filter(minioFile -> {
boolean currentFileSize = minioFile.getSize() < 15 * 1024 * 1024;
if (!currentFileSize) {
log.warn("文件大小超过15mb不进行知识库维护:{}", minioFile.getFilename());
return false;
}
boolean currentFileType = StrUtil.equalsAny(minioFile.getFileType(), "doc", "docx", "txt", "md", "pdf");
if (!currentFileType) {
log.warn("文件:{}类型非doc、docx、txt、md、pdf不进行知识库维护...", minioFile.getFilename());
return false;
}
return true;
}).map(MinioFile::getId).toList();
Map<String, MinioFile> fileMap = minioFiles.stream().collect(Collectors.toMap(MinioFile::getId, target -> target));
log.info("案件:{},共有:{}个笔录文件,符合上传要求的文件有:{}",modelCase.getCaseName(), allFileIds.size(), recordFileIds.size());
for (String recordId : recordFileIds) {
// 把新增的笔录数据添加到到知识库
if (!documentFileIds.contains(recordId)){
log.info("案件:{},笔录文件:{},添加到知识库...",modelCase.getCaseName(), fileMap.get(recordId).getFilename());
this.createDocumentByFile(modelCase.getKnowledgeBaseId(),recordId);
}
}
if (CollUtil.isNotEmpty(recordFileIds)){
for (Document document : documents) {
String fileId = document.getFileId();
if (StrUtil.isNotEmpty(fileId) && !recordFileIds.contains(fileId)){
// 删除不在笔录文件列表中的知识库
log.info("案件:{},笔录文件:{},从知识库中删除...",modelCase.getCaseName(), document.getName());
this.deleteDocument(modelCase.getKnowledgeBaseId(),document.getId());
}
}
}
log.info("案件:{}上传笔录文件到知识库完成!",modelCase.getCaseName());
}
/**
*
@ -265,7 +317,7 @@ public class DifyApiUtil {
* @param fileId id
* @return + "_" + ID +"." +
*/
public String generateDocumentName(String fileName, String fileId) {
private String generateDocumentName(String fileName, String fileId) {
String[] split = fileName.split("\\.");
List<String> nameTrunk = new ArrayList<>(Arrays.asList(split).subList(0, split.length - 1));
@ -283,7 +335,7 @@ public class DifyApiUtil {
* @param documentName
* @return keyvalueid
*/
public Pair<String, String> decodeDocumentName(String documentName) {
private Pair<String, String> decodeDocumentName(String documentName) {
if (StrUtil.isEmpty(documentName)) {
return Pair.of(null, null);

@ -19,4 +19,15 @@
case_id,user_id,create_time,
update_time
</sql>
<select id="queryUserConversationList" resultType="com.supervision.police.vo.ConversationResVo">
select c.id as conversationId,
mc.case_name as caseName,
mc.id as caseId,
cp.id as caseActorId,
cp.name as caseActor
from conversation c
left join model_case mc on c.case_id = mc.id
left join case_person cp on (c.case_id = cp.case_id and cp.case_actor_flag = 1 and cp.role_code = '1')
where c.user_id = #{userId} order by c.create_time desc
</select>
</mapper>

Loading…
Cancel
Save