fu-hsi-service/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java

234 lines
11 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.supervision.police.service.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.supervision.chat.client.LangChainChatService;
import com.supervision.chat.client.dto.chat.ChatReqDTO;
import com.supervision.chat.client.dto.chat.ChatResDTO;
import com.supervision.police.domain.Conversation;
import com.supervision.police.domain.ConversationQa;
import com.supervision.police.domain.ModelCase;
import com.supervision.police.domain.ModelIndex;
import com.supervision.police.dto.IndexDetail;
import com.supervision.police.dto.IndexResultQuery;
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.dify.DifyChatReqVO;
import com.supervision.police.vo.dify.DifyChatResVO;
import com.supervision.police.vo.dify.KnowledgeBaseSegmentVO;
import com.supervision.utils.DifyApiUtil;
import com.supervision.utils.UserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import static com.supervision.common.constant.DifyConstants.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService {
private final LangChainChatService langChainChatService;
private final ModelCaseService modelCaseService;
private final ModelService modelService;
private final ConversationService conversationService;
private final ConversationQaService conversationQaService;
private final ModelIndexService modelIndexService;
private final DifyApiUtil difyApiUtil;
@Override
public ChatResVO chat(ChatReqVO chatReqVO) {
Assert.notEmpty(chatReqVO.getQuery(), "query 不能为空");
Assert.notEmpty(chatReqVO.getCaseId(), "caseId 不能为空");
ModelCase modelCase = modelCaseService.getById(chatReqVO.getCaseId());
Assert.notNull(modelCase, "案件不存在");
log.info("chat: caseNo:{},query{}", modelCase.getCaseNo(), chatReqVO.getQuery());
ChatResDTO chat = null;
try {
chat = langChainChatService.chat(
ChatReqDTO.create(chatReqVO.getQuery(), modelCase.getCaseNo(), chatReqVO.getHistory()));
} catch (Exception e) {
log.error("chat: caseNo:{},query{},error:{}", modelCase.getCaseNo(), chatReqVO.getQuery(), e.getMessage(), e);
chat = new ChatResDTO();
chat.setAnswer("服务繁忙,请稍后重试!");
}
if (null == chat) {
chat = new ChatResDTO();
}
if (StrUtil.isEmpty(chat.getAnswer())) {
chat.setAnswer("我暂时还不知道怎么回答,您可以尝试换一种问法!");
chat.setDocs(new ArrayList<>(1));
}
log.info("chat: caseNo:{},query{},answer:{}", modelCase.getCaseNo(), chatReqVO.getQuery(), chat.getAnswer());
return new ChatResVO(chat);
}
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
@Override
public ChatResVO chatNew(ChatReqVO chatReqVO) {
ChatResVO chatResVO = new ChatResVO();
Map<String, Object> answerMap = new HashMap<>();
String query = chatReqVO.getQuery();
String caseId = chatReqVO.getCaseId();
String userId = UserUtil.getUser().getId();
String type = chatReqVO.getType();
String intentType = chatReqVO.getIntentType();
long startTime = System.currentTimeMillis();
if (StringUtils.isEmpty(chatReqVO.getConversationId())) {
Conversation conversation = new Conversation();
conversation.setId(UUID.randomUUID().toString());
conversation.setCaseId(caseId);
conversation.setUserId(userId);
conversationService.save(conversation);
chatReqVO.setConversationId(conversation.getId());
log.info("会话已创建conversationId:{}", conversation.getId());
} else {
Conversation conversation = conversationService.getById(chatReqVO.getConversationId());
conversation.setUpdateTime(new Date());
conversationService.updateById(conversation);
log.info("会话已更新conversationId:{}", conversation.getId());
}
List<ModelIndex> modelIndices = modelIndexService.list();
switch (type) {
case QA_TYPE_DIFY:
if (modelIndices.stream().map(ModelIndex::getName).anyMatch(query::contains)) {
handleIndexResultQA(modelIndices, query, caseId, answerMap);
} else if (INTENT_TYPE_TEXT_CASE_RESULT.equals(query) || INTENT_TYPE_CASE_RESULT.equals(intentType)) {
answerMap = JSON.parseObject(JSON.toJSONString(modelService.caseScoreDetail(caseId)), Map.class);
} else if (INTENT_TYPE_CASE_OVERVIEW.equals(query) || INTENT_TYPE_CASE_OVERVIEW.equals(intentType)) {
ModelCase modelCase = modelCaseService.getById(caseId);
answerMap.put("answerText", modelCase.getCaseDetail());
} else if (INTENT_TYPE_CASE_EVIDENCE_GUIDE.equals(query) || INTENT_TYPE_CASE_EVIDENCE_GUIDE.equals(intentType)) {
CaseScoreDetailDTO caseScoreDetailDTO = modelService.caseScoreDetail(caseId);
answerMap.put("guideDesc", caseScoreDetailDTO.getGuideDesc());
} else {
ModelCase modelCase = modelCaseService.getById(caseId);
DifyChatReqVO difyChatReqVO = new DifyChatReqVO();
difyChatReqVO.setUser(userId);
difyChatReqVO.setConversationId(chatReqVO.getConversationId());
difyChatReqVO.setQuery(query);
difyChatReqVO.setInputs(Map.of("dataset_id", modelCase.getKnowledgeBaseId()));
DifyChatResVO chat = difyApiUtil.chat(difyChatReqVO);
JSONObject json = JSON.parseObject(chat.getAnswer());
chatResVO.setAnswer(json.getString("answerText"));
chatResVO.setSegmentVOList(JSONArray.parseArray(json.getString("quote"), KnowledgeBaseSegmentVO.class));
}
break;
case QA_TYPE_NX_LLM:
switch (intentType) {
case INTENT_TYPE_INDEX_RESULT:
if (modelIndices.stream().map(ModelIndex::getName).anyMatch(query::contains)) {
handleIndexResultQA(modelIndices, query, caseId, answerMap);
} else {
answerMap.put("answerText", "暂无相关指标信息");
}
break;
case INTENT_TYPE_CASE_RESULT:
answerMap = JSON.parseObject(JSON.toJSONString(modelService.caseScoreDetail(caseId)), Map.class);
break;
case INTENT_TYPE_CASE_OVERVIEW:
ModelCase modelCase = modelCaseService.getById(caseId);
answerMap.put("answerText", modelCase.getCaseDetail());
break;
case INTENT_TYPE_CASE_EVIDENCE_GUIDE:
CaseScoreDetailDTO caseScoreDetailDTO = modelService.caseScoreDetail(caseId);
answerMap.put("guideDesc", caseScoreDetailDTO.getGuideDesc());
break;
default:
break;
}
break;
default:
break;
}
long end = System.currentTimeMillis();
ConversationQa qa = new ConversationQa();
qa.setId(UUID.randomUUID().toString());
qa.setQuestion(query);
qa.setQuestionTime(new Date(startTime));
qa.setAnswer(JSON.toJSONString(answerMap));
qa.setAnswerTime(new Date(end));
qa.setType(type);
qa.setIntentType(intentType);
qa.setTimeInterval(String.valueOf(end - startTime));
qa.setCaseId(caseId);
qa.setUserId(userId);
qa.setConversationId(chatReqVO.getConversationId());
conversationQaService.save(qa);
log.info("QA已保存qaId:{}", qa.getId());
chatResVO.setAnswwerMap(answerMap);
chatResVO.setType(type);
chatResVO.setIntentType(intentType);
return chatResVO;
}
/**
* 处理指标结果问答
*
* @param modelIndices 指标列表
* @param query 问题
* @param caseId 案件id
* @param answerMap 答案map
*/
private void handleIndexResultQA(List<ModelIndex> modelIndices, String query, String caseId, Map<String, Object> answerMap) {
ModelIndex modelIndex = modelIndices.stream().filter(index -> query.contains(index.getName())).findFirst().get();
IndexResultQuery indexResultQuery = new IndexResultQuery();
indexResultQuery.setCaseId(caseId);
indexResultQuery.setIndexType(modelIndex.getIndexType());
indexResultQuery.setIndexName(modelIndex.getName());
IPage<IndexDetail> indexDetailPage = modelCaseService.getIndexDetail(indexResultQuery, 1, 1);
if (!indexDetailPage.getRecords().isEmpty()) {
IndexDetail indexDetail = indexDetailPage.getRecords().get(0);
answerMap.put("indexName", modelIndex.getName());
answerMap.put("result", Boolean.parseBoolean(indexDetail.getIndexResult()) ? "符合" : "不符合");
List<Map<String, String>> qaSplitList = new ArrayList<>();
if (!indexDetail.getChildren().isEmpty()) {
indexDetail.getChildren().forEach(atomicIndexDTO -> {
if (!atomicIndexDTO.getRecordSegmentationList().isEmpty()) {
atomicIndexDTO.getRecordSegmentationList().forEach(split -> {
Map<String, String> qaMap = new HashMap<>();
qaMap.put("question", split.getQuestion());
qaMap.put("answer", split.getAnswer());
qaMap.put("noteRecordId", split.getNoteRecordId());
qaMap.put("noteRecordName", split.getNoteName());
qaSplitList.add(qaMap);
});
}
});
}
answerMap.put("qaSplitList", qaSplitList);
List<String> evidenceNames = new ArrayList<>();
if (!indexDetail.getChildren().isEmpty()) {
indexDetail.getChildren().forEach(atomicIndexDTO -> {
if (!atomicIndexDTO.getEvidentResultList().isEmpty()) {
atomicIndexDTO.getEvidentResultList().forEach(evidentIndexResultDTO -> {
evidenceNames.add(evidentIndexResultDTO.getEvidenceName());
});
}
});
}
answerMap.put("evidenceNames", evidenceNames);
}
}
}