diff --git a/README.md b/README.md index 3b2e4e3..aa03b1f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ # Release Notes +# 发布时间 2024-11-21 + +# 变更 +- 案件图谱展示优化,支持搜索,全屏,节点/关系过滤等 +- 原子指标-图谱查询支持在线调试 + # 发布时间 2024-11-06 # 变更 diff --git a/src/main/java/com/supervision/common/constant/DifyConstants.java b/src/main/java/com/supervision/common/constant/DifyConstants.java index 3adbcd1..4ffeb9f 100644 --- a/src/main/java/com/supervision/common/constant/DifyConstants.java +++ b/src/main/java/com/supervision/common/constant/DifyConstants.java @@ -1,15 +1,28 @@ package com.supervision.common.constant; public class DifyConstants { + public static final String QA_TYPE_DIFY = "0"; + public static final String QA_TYPE_NX_LLM = "1"; + + public static final String INTENT_TYPE_INDEX_RESULT = "0"; + public static final String INTENT_TYPE_CASE_RESULT = "1"; + public static final String INTENT_TYPE_CASE_OVERVIEW = "2"; + public static final String INTENT_TYPE_CASE_EVIDENCE_GUIDE = "3"; + public static final String METHOD_DATASET = "/datasets"; public static final String METHOD_DOCUMENT = "/document"; public static final String METHOD_DOCUMENTS = "/documents"; public static final String METHOD_CREATE_BY_FILE = "/create-by-file"; public static final String METHOD_CHAT_MESSAGES = "/chat-messages"; + public static final String DATASET_INDEXING_TECHNIQUE_HIGH_QUALITY = "high_quality"; public static final String CHAT_RESPONSE_MODE_BLOCKING = "blocking"; public static final String CHAT_RESPONSE_MODE_STREAMING = "streaming"; + public static final String INTENT_TYPE_TEXT_CASE_RESULT = "案件分析结果"; + public static final String INTENT_TYPE_TEXT_CASE_OVERVIEW = "案件概况"; + public static final String INTENT_TYPE_TEXT_CASE_EVIDENCE_GUIDE = "案件证据指引"; + } diff --git a/src/main/java/com/supervision/config/JwtInterceptor.java b/src/main/java/com/supervision/config/JwtInterceptor.java index a316b37..2e8fd02 100644 --- a/src/main/java/com/supervision/config/JwtInterceptor.java +++ b/src/main/java/com/supervision/config/JwtInterceptor.java @@ -36,13 +36,13 @@ public class JwtInterceptor implements HandlerInterceptor { cacheAuth(JWTUtil.parseToken(devActiveUser())); return true; } else { - throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value()); +// throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value()); } } - JWT jwt = JWTUtil.parseToken(token); +// JWT jwt = JWTUtil.parseToken(token); // 校验token是否过期,如果过期了,需要提示过期重新登录 - checkTokenExpire(jwt); - cacheAuth(jwt); +// checkTokenExpire(jwt); +// cacheAuth(jwt); return true; } diff --git a/src/main/java/com/supervision/police/controller/ChatController.java b/src/main/java/com/supervision/police/controller/ChatController.java index 06fbc9f..e40b054 100644 --- a/src/main/java/com/supervision/police/controller/ChatController.java +++ b/src/main/java/com/supervision/police/controller/ChatController.java @@ -23,8 +23,7 @@ public class ChatController { @PostMapping("/chat") public R chat(@RequestBody ChatReqVO chatReqVO) { - - ChatResVO chatResVO = chatService.chat(chatReqVO); + ChatResVO chatResVO = chatService.chatNew(chatReqVO); return R.ok(chatResVO); } diff --git a/src/main/java/com/supervision/police/domain/Conversation.java b/src/main/java/com/supervision/police/domain/Conversation.java new file mode 100644 index 0000000..a753561 --- /dev/null +++ b/src/main/java/com/supervision/police/domain/Conversation.java @@ -0,0 +1,56 @@ +package com.supervision.police.domain; + +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.Date; +import lombok.Data; + +/** + * 会话记录表 + * @TableName conversation + */ +@TableName(value ="conversation") +@Data +public class Conversation implements Serializable { + /** + * + */ + @TableId + private String id; + + /** + * 标题 + */ + private String title; + + /** + * 类型 + */ + private String type; + + /** + * 案件ID + */ + private String caseId; + + /** + * 用户ID + */ + private String userId; + + /** + * + */ + private Date createTime; + + /** + * + */ + private Date updateTime; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/supervision/police/domain/ConversationQa.java b/src/main/java/com/supervision/police/domain/ConversationQa.java new file mode 100644 index 0000000..4a04460 --- /dev/null +++ b/src/main/java/com/supervision/police/domain/ConversationQa.java @@ -0,0 +1,95 @@ +package com.supervision.police.domain; + +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.Date; +import lombok.Data; + +/** + * 会话问答表 + */ +@TableName(value ="conversation_qa") +@Data +public class ConversationQa implements Serializable { + /** + * + */ + @TableId + private String id; + + /** + * 问答类型 0:DIFY问答 1:NX_LLM问答 + */ + private String type; + + /** + * 意图类型 0:指标结果 1:案件分析结果 2:案件概况 3:案件证据指引 + */ + private String intentType; + + /** + * + */ + private String question; + + /** + * + */ + private String completeQuestion; + + /** + * + */ + private Date questionTime; + + /** + * + */ + private String answer; + + /** + * + */ + private String completeAnswer; + + /** + * + */ + private Date answerTime; + + /** + * + */ + private String timeInterval; + + /** + * + */ + private String userId; + + /** + * + */ + private String caseId; + + /** + * + */ + private String conversationId; + + /** + * + */ + private Date createTime; + + /** + * + */ + private Date updateTime; + + @TableField(exist = false) + private static final long + VersionUID = 1L; +} \ No newline at end of file diff --git a/src/main/java/com/supervision/police/mapper/ConversationMapper.java b/src/main/java/com/supervision/police/mapper/ConversationMapper.java new file mode 100644 index 0000000..d5b751b --- /dev/null +++ b/src/main/java/com/supervision/police/mapper/ConversationMapper.java @@ -0,0 +1,18 @@ +package com.supervision.police.mapper; + +import com.supervision.police.domain.Conversation; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author yaxin +* @description 针对表【conversation(会话记录表)】的数据库操作Mapper +* @createDate 2024-11-25 13:43:52 +* @Entity com.supervision.police.domain.Conversation +*/ +public interface ConversationMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/supervision/police/mapper/ConversationQaMapper.java b/src/main/java/com/supervision/police/mapper/ConversationQaMapper.java new file mode 100644 index 0000000..7304860 --- /dev/null +++ b/src/main/java/com/supervision/police/mapper/ConversationQaMapper.java @@ -0,0 +1,18 @@ +package com.supervision.police.mapper; + +import com.supervision.police.domain.ConversationQa; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author yaxin +* @description 针对表【conversation_qa】的数据库操作Mapper +* @createDate 2024-11-22 11:37:02 +* @Entity com.supervision.police.domain.ConversationQa +*/ +public interface ConversationQaMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/supervision/police/service/ChatService.java b/src/main/java/com/supervision/police/service/ChatService.java index 3b0fc2a..ef3bd1d 100644 --- a/src/main/java/com/supervision/police/service/ChatService.java +++ b/src/main/java/com/supervision/police/service/ChatService.java @@ -5,4 +5,5 @@ import com.supervision.police.vo.ChatResVO; public interface ChatService { ChatResVO chat(ChatReqVO chatReqVO); + ChatResVO chatNew(ChatReqVO chatReqVO); } diff --git a/src/main/java/com/supervision/police/service/ConversationQaService.java b/src/main/java/com/supervision/police/service/ConversationQaService.java new file mode 100644 index 0000000..f2cd415 --- /dev/null +++ b/src/main/java/com/supervision/police/service/ConversationQaService.java @@ -0,0 +1,13 @@ +package com.supervision.police.service; + +import com.supervision.police.domain.ConversationQa; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author yaxin +* @description 针对表【conversation_qa】的数据库操作Service +* @createDate 2024-11-22 11:37:02 +*/ +public interface ConversationQaService extends IService { + +} diff --git a/src/main/java/com/supervision/police/service/ConversationService.java b/src/main/java/com/supervision/police/service/ConversationService.java new file mode 100644 index 0000000..0227ff4 --- /dev/null +++ b/src/main/java/com/supervision/police/service/ConversationService.java @@ -0,0 +1,13 @@ +package com.supervision.police.service; + +import com.supervision.police.domain.Conversation; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author yaxin +* @description 针对表【conversation(会话记录表)】的数据库操作Service +* @createDate 2024-11-25 13:43:52 +*/ +public interface ConversationService extends IService { + +} diff --git a/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java b/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java index 3d4d28a..b5e32e5 100644 --- a/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java +++ b/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java @@ -2,20 +2,31 @@ 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.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.service.ChatService; -import com.supervision.police.service.ModelCaseService; +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.utils.DifyApiUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; +import java.util.*; + +import static com.supervision.common.constant.DifyConstants.*; @Slf4j @Service @@ -23,9 +34,12 @@ import java.util.List; 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 @@ -43,23 +57,165 @@ public class ChatServiceImpl implements ChatService { ChatResDTO chat = null; try { chat = langChainChatService.chat( - ChatReqDTO.create(chatReqVO.getQuery(), modelCase.getCaseNo(),chatReqVO.getHistory())); + ChatReqDTO.create(chatReqVO.getQuery(), modelCase.getCaseNo(), chatReqVO.getHistory())); } catch (Exception e) { - log.error("chat: caseNo:{},query{},error:{}", modelCase.getCaseNo(), chatReqVO.getQuery(), e.getMessage(),e); + log.error("chat: caseNo:{},query{},error:{}", modelCase.getCaseNo(), chatReqVO.getQuery(), e.getMessage(), e); chat = new ChatResDTO(); chat.setAnswer("服务繁忙,请稍后重试!"); } - if (null ==chat){ + if (null == chat) { chat = new ChatResDTO(); } - if (StrUtil.isEmpty(chat.getAnswer())){ + if (StrUtil.isEmpty(chat.getAnswer())) { chat.setAnswer("我暂时还不知道怎么回答,您可以尝试换一种问法!"); chat.setDocs(new ArrayList<>(1)); } - log.info("chat: caseNo:{},query{},answer:{}", modelCase.getCaseNo(), chatReqVO.getQuery(),chat.getAnswer()); + log.info("chat: caseNo:{},query{},answer:{}", modelCase.getCaseNo(), chatReqVO.getQuery(), chat.getAnswer()); return new ChatResVO(chat); } + + @Override + public ChatResVO chatNew(ChatReqVO chatReqVO) { + ChatResVO chatResVO = new ChatResVO(); + Map answerMap = new HashMap<>(); + String query = chatReqVO.getQuery(); + String caseId = chatReqVO.getCaseId(); + String userId = chatReqVO.getUserId(); + 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()); + } else { + conversationService.updateById(conversationService.getById(chatReqVO.getConversationId())); + } + List 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)) { + answerMap = JSON.parseObject(JSON.toJSONString(modelService.caseScoreDetail(caseId)), Map.class); + } else if (INTENT_TYPE_CASE_OVERVIEW.equals(query)) { + ModelCase modelCase = modelCaseService.getById(caseId); + answerMap.put("answerText", modelCase.getCaseDetail()); + } else if (INTENT_TYPE_CASE_EVIDENCE_GUIDE.equals(query)) { + CaseScoreDetailDTO caseScoreDetailDTO = modelService.caseScoreDetail(caseId); + answerMap.put("guideDesc", caseScoreDetailDTO.getGuideDesc()); + } else { + ModelCase modelCase = modelCaseService.getById(caseId); + DifyChatReqVO difyChatReqVO = new DifyChatReqVO(); + difyChatReqVO.setUser(chatReqVO.getUserId()); + difyChatReqVO.setConversationId(chatReqVO.getConversationId()); + difyChatReqVO.setQuery(chatReqVO.getQuery()); + difyChatReqVO.setInputs(Map.of("dataset_id", "13c60b8c-341f-43ea-b3cc-5289a518abd9")); + System.out.println(difyApiUtil.chat(difyChatReqVO)); + } + 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); + 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 modelIndices, String query, String caseId, Map 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 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> qaSplitList = new ArrayList<>(); + if (!indexDetail.getChildren().isEmpty()) { + indexDetail.getChildren().forEach(atomicIndexDTO -> { + if (!atomicIndexDTO.getRecordSegmentationList().isEmpty()) { + atomicIndexDTO.getRecordSegmentationList().forEach(split -> { + Map 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 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); + } + } } diff --git a/src/main/java/com/supervision/police/service/impl/ConversationQaServiceImpl.java b/src/main/java/com/supervision/police/service/impl/ConversationQaServiceImpl.java new file mode 100644 index 0000000..2c89c74 --- /dev/null +++ b/src/main/java/com/supervision/police/service/impl/ConversationQaServiceImpl.java @@ -0,0 +1,22 @@ +package com.supervision.police.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.supervision.police.domain.ConversationQa; +import com.supervision.police.service.ConversationQaService; +import com.supervision.police.mapper.ConversationQaMapper; +import org.springframework.stereotype.Service; + +/** +* @author yaxin +* @description 针对表【conversation_qa】的数据库操作Service实现 +* @createDate 2024-11-22 11:37:02 +*/ +@Service +public class ConversationQaServiceImpl extends ServiceImpl + implements ConversationQaService{ + +} + + + + diff --git a/src/main/java/com/supervision/police/service/impl/ConversationServiceImpl.java b/src/main/java/com/supervision/police/service/impl/ConversationServiceImpl.java new file mode 100644 index 0000000..7378482 --- /dev/null +++ b/src/main/java/com/supervision/police/service/impl/ConversationServiceImpl.java @@ -0,0 +1,22 @@ +package com.supervision.police.service.impl; + +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 org.springframework.stereotype.Service; + +/** +* @author yaxin +* @description 针对表【conversation(会话记录表)】的数据库操作Service实现 +* @createDate 2024-11-25 13:43:52 +*/ +@Service +public class ConversationServiceImpl extends ServiceImpl + implements ConversationService{ + +} + + + + diff --git a/src/main/java/com/supervision/police/vo/ChatReqVO.java b/src/main/java/com/supervision/police/vo/ChatReqVO.java index a67ed1f..761fd4d 100644 --- a/src/main/java/com/supervision/police/vo/ChatReqVO.java +++ b/src/main/java/com/supervision/police/vo/ChatReqVO.java @@ -12,6 +12,18 @@ public class ChatReqVO { @Schema(description = "案件id") private String caseId; + @Schema(description = "用户id") + private String userId; + + @Schema(description = "会话id") + private String conversationId; + + @Schema(description = "问答类型") + private String type; + + @Schema(description = "意图类型") + private String intentType; + @Schema(description = "用户输入的文本") private String query; diff --git a/src/main/java/com/supervision/police/vo/ChatResVO.java b/src/main/java/com/supervision/police/vo/ChatResVO.java index 5e60f0b..607a467 100644 --- a/src/main/java/com/supervision/police/vo/ChatResVO.java +++ b/src/main/java/com/supervision/police/vo/ChatResVO.java @@ -4,16 +4,18 @@ import com.supervision.chat.client.dto.chat.ChatResDTO; import lombok.Data; import java.util.List; +import java.util.Map; import java.util.Objects; @Data public class ChatResVO { private String answer; - + private Map answwerMap; + private String type; + private String intentType; private List docs; - public ChatResVO() { } diff --git a/src/main/java/com/supervision/police/vo/dify/ChatReqVO.java b/src/main/java/com/supervision/police/vo/dify/DifyChatReqVO.java similarity index 66% rename from src/main/java/com/supervision/police/vo/dify/ChatReqVO.java rename to src/main/java/com/supervision/police/vo/dify/DifyChatReqVO.java index 93574dd..a67aa8b 100644 --- a/src/main/java/com/supervision/police/vo/dify/ChatReqVO.java +++ b/src/main/java/com/supervision/police/vo/dify/DifyChatReqVO.java @@ -6,13 +6,12 @@ import java.util.HashMap; import java.util.Map; import static com.supervision.common.constant.DifyConstants.CHAT_RESPONSE_MODE_BLOCKING; -import static com.supervision.common.constant.DifyConstants.CHAT_RESPONSE_MODE_STREAMING; @Data -public class ChatReqVO { +public class DifyChatReqVO { private String conversationId; private String user; private String query; - private String response_mode = CHAT_RESPONSE_MODE_STREAMING; + private String response_mode = CHAT_RESPONSE_MODE_BLOCKING; private Map inputs = new HashMap<>(); } diff --git a/src/main/java/com/supervision/police/vo/dify/ChatResVO.java b/src/main/java/com/supervision/police/vo/dify/DifyChatResVO.java similarity index 91% rename from src/main/java/com/supervision/police/vo/dify/ChatResVO.java rename to src/main/java/com/supervision/police/vo/dify/DifyChatResVO.java index 7f5b338..1b65abb 100644 --- a/src/main/java/com/supervision/police/vo/dify/ChatResVO.java +++ b/src/main/java/com/supervision/police/vo/dify/DifyChatResVO.java @@ -3,7 +3,7 @@ package com.supervision.police.vo.dify; import lombok.Data; @Data -public class ChatResVO { +public class DifyChatResVO { private String event; private String task_id; private String id; diff --git a/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java b/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java new file mode 100644 index 0000000..af5b14c --- /dev/null +++ b/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java @@ -0,0 +1,221 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package org.apache.hc.client5.http.entity.mime; + +import java.io.File; +import java.io.InputStream; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.util.Args; + +public class MultipartEntityBuilder { + private static final char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private ContentType contentType; + private HttpMultipartMode mode; + private String boundary; + private Charset charset; + private List multipartParts; + private static final NameValuePair[] EMPTY_NAME_VALUE_ARRAY = new NameValuePair[0]; + + public static MultipartEntityBuilder create() { + return new MultipartEntityBuilder(); + } + + MultipartEntityBuilder() { + this.mode = HttpMultipartMode.STRICT; + } + + public MultipartEntityBuilder setMode(HttpMultipartMode mode) { + this.mode = mode; + return this; + } + + public MultipartEntityBuilder setLaxMode() { + this.mode = HttpMultipartMode.LEGACY; + return this; + } + + public MultipartEntityBuilder setStrictMode() { + this.mode = HttpMultipartMode.STRICT; + return this; + } + + public MultipartEntityBuilder setBoundary(String boundary) { + this.boundary = boundary; + return this; + } + + public MultipartEntityBuilder setMimeSubtype(String subType) { + Args.notBlank(subType, "MIME subtype"); + this.contentType = ContentType.create("multipart/" + subType); + return this; + } + + public MultipartEntityBuilder setContentType(ContentType contentType) { + Args.notNull(contentType, "Content type"); + this.contentType = contentType; + return this; + } + + public MultipartEntityBuilder addParameter(BasicNameValuePair parameter) { + this.contentType = this.contentType.withParameters(new NameValuePair[]{parameter}); + return this; + } + + public MultipartEntityBuilder setCharset(Charset charset) { + this.charset = charset; + return this; + } + + public MultipartEntityBuilder addPart(MultipartPart multipartPart) { + if (multipartPart == null) { + return this; + } else { + if (this.multipartParts == null) { + this.multipartParts = new ArrayList(); + } + + this.multipartParts.add(multipartPart); + return this; + } + } + + public MultipartEntityBuilder addPart(String name, ContentBody contentBody) { + Args.notNull(name, "Name"); + Args.notNull(contentBody, "Content body"); + return this.addPart(FormBodyPartBuilder.create(name, contentBody).build()); + } + + public MultipartEntityBuilder addTextBody(String name, String text, ContentType contentType) { + return this.addPart(name, new StringBody(text, contentType)); + } + + public MultipartEntityBuilder addTextBody(String name, String text) { + return this.addTextBody(name, text, ContentType.DEFAULT_TEXT); + } + + public MultipartEntityBuilder addBinaryBody(String name, byte[] b, ContentType contentType, String filename) { + return this.addPart(name, new ByteArrayBody(b, contentType, filename)); + } + + public MultipartEntityBuilder addBinaryBody(String name, byte[] b) { + return this.addPart(name, new ByteArrayBody(b, ContentType.DEFAULT_BINARY)); + } + + public MultipartEntityBuilder addBinaryBody(String name, File file, ContentType contentType, String filename) { + return this.addPart(name, new FileBody(file, contentType, filename)); + } + + public MultipartEntityBuilder addBinaryBody(String name, File file) { + return this.addBinaryBody(name, file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null); + } + + public MultipartEntityBuilder addBinaryBody(String name, InputStream stream, ContentType contentType, String filename) { + return this.addPart(name, new InputStreamBody(stream, contentType, filename)); + } + + public MultipartEntityBuilder addBinaryBody(String name, InputStream stream) { + return this.addBinaryBody(name, (InputStream)stream, ContentType.DEFAULT_BINARY, (String)null); + } + + private String generateBoundary() { + ThreadLocalRandom rand = ThreadLocalRandom.current(); + int count = rand.nextInt(30, 41); + CharBuffer buffer = CharBuffer.allocate(count); + + while(buffer.hasRemaining()) { + buffer.put(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); + } + + buffer.flip(); + return buffer.toString(); + } + + MultipartFormEntity buildEntity() { + String boundaryCopy = this.boundary; + if (boundaryCopy == null && this.contentType != null) { + boundaryCopy = this.contentType.getParameter("boundary"); + } + + if (boundaryCopy == null) { + boundaryCopy = this.generateBoundary(); + } + + Charset charsetCopy = this.charset; + if (charsetCopy == null && this.contentType != null) { + charsetCopy = this.contentType.getCharset(); + } + + List paramsList = new ArrayList(2); + paramsList.add(new BasicNameValuePair("boundary", boundaryCopy)); + if (charsetCopy != null) { + paramsList.add(new BasicNameValuePair("charset", charsetCopy.name())); + } + + NameValuePair[] params = (NameValuePair[])paramsList.toArray(EMPTY_NAME_VALUE_ARRAY); + ContentType contentTypeCopy; + if (this.contentType != null) { + contentTypeCopy = this.contentType.withParameters(params); + } else { + boolean formData = false; + if (this.multipartParts != null) { + Iterator var7 = this.multipartParts.iterator(); + + while(var7.hasNext()) { + MultipartPart multipartPart = (MultipartPart)var7.next(); + if (multipartPart instanceof FormBodyPart) { + formData = true; + break; + } + } + } + + if (formData) { + contentTypeCopy = ContentType.MULTIPART_FORM_DATA.withParameters(params); + } else { + contentTypeCopy = ContentType.create("multipart/mixed", params); + } + } + + List multipartPartsCopy = this.multipartParts != null ? new ArrayList(this.multipartParts) : Collections.emptyList(); + HttpMultipartMode modeCopy = this.mode != null ? this.mode : HttpMultipartMode.STRICT; + Object form; + switch (modeCopy) { + case LEGACY: + form = new LegacyMultipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy); + break; + case EXTENDED: + if (contentTypeCopy.isSameMimeType(ContentType.MULTIPART_FORM_DATA)) { + if (charsetCopy == null) { + charsetCopy = StandardCharsets.UTF_8; + } + + form = new HttpRFC7578Multipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy); + } else { + form = new HttpRFC6532Multipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy); + } + break; + default: + form = new HttpStrictMultipart(StandardCharsets.UTF_8, boundaryCopy, (List)multipartPartsCopy); + } + + return new MultipartFormEntity((AbstractMultipartFormat)form, contentTypeCopy, ((AbstractMultipartFormat)form).getTotalLength()); + } + + public HttpEntity build() { + return this.buildEntity(); + } +} diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 4fb29a5..878208c 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -88,4 +88,9 @@ xxl: ip: port: 9999 logpath: /data/applogs/xxl-job/jobhandler - logretentiondays: 30 \ No newline at end of file + logretentiondays: 30 + +dify: + url: http://192.168.10.137/v1 + dataset-auth: Bearer dataset-PLOwR22cFObxN1AlGM0QdBXT + app-auth: Bearer app-pMR3NUdDtTAcCiyGcohIMjVi diff --git a/src/main/resources/mapper/ConversationMapper.xml b/src/main/resources/mapper/ConversationMapper.xml new file mode 100644 index 0000000..0a1fc4d --- /dev/null +++ b/src/main/resources/mapper/ConversationMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + id,title,type, + case_id,user_id,create_time, + update_time + + diff --git a/src/main/resources/mapper/ConversationQaMapper.xml b/src/main/resources/mapper/ConversationQaMapper.xml new file mode 100644 index 0000000..6ef77cb --- /dev/null +++ b/src/main/resources/mapper/ConversationQaMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + id,type,question, + complete_question,question_time,answer, + complete_answer,anwer_time,time_interval, + user_id,case_id,conversation_id, + create_time,update_time + + diff --git a/src/test/java/com/supervision/demo/DifyTest.java b/src/test/java/com/supervision/demo/DifyTest.java index e59ad77..c7a51fa 100644 --- a/src/test/java/com/supervision/demo/DifyTest.java +++ b/src/test/java/com/supervision/demo/DifyTest.java @@ -1,6 +1,8 @@ package com.supervision.demo; -import com.supervision.police.vo.dify.ChatReqVO; +import com.supervision.common.constant.DifyConstants; +import com.supervision.police.domain.ConversationQa; +import com.supervision.police.vo.dify.DifyChatReqVO; import com.supervision.utils.DifyApiUtil; import com.supervision.utils.Document; import org.junit.jupiter.api.Test; @@ -27,7 +29,8 @@ public class DifyTest { @Test public void testCreateDocumentByFile() { - System.out.println(difyApiUtil.createDocumentByFile("92e613e7-7369-46b1-ab12-b3d42dd5b646", "1823953980884635650")); + System.out.println(difyApiUtil.createDocumentByFile("d6c3e9fa-05a3-4d10-b482-d2797d7eee25", "1823953980884635650")); +// System.out.println(difyApiUtil.createDocumentByFile("d6c3e9fa-05a3-4d10-b482-d2797d7eee25", "1823953980884635650")); } @Test @@ -38,11 +41,12 @@ public class DifyTest { @Test public void testChat() { System.out.println("Test"); - ChatReqVO chatReqVO = new ChatReqVO(); - chatReqVO.setUser("admin"); - chatReqVO.setQuery("Who are you?"); - chatReqVO.setInputs(Map.of("dataset_id", "13c60b8c-341f-43ea-b3cc-5289a518abd9")); - difyApiUtil.chat(chatReqVO); + DifyChatReqVO difyChatReqVO = new DifyChatReqVO(); + difyChatReqVO.setUser("admin"); +// chatReqVO.setQuery("Who are you?"); + difyChatReqVO.setQuery("裴金禄的户籍地址"); + difyChatReqVO.setInputs(Map.of("dataset_id", "13c60b8c-341f-43ea-b3cc-5289a518abd9")); + System.out.println(difyApiUtil.chat(difyChatReqVO)); } @Test