package cn.huge.module.ai.controller; import cn.huge.base.common.utils.*; import cn.huge.module.ai.domain.dto.*; import cn.huge.module.ai.domain.po.*; import cn.huge.module.ai.domain.vo.AiChatVo; import cn.huge.module.ai.domain.vo.AiMediateStrategyVo; import cn.huge.module.ai.domain.vo.AiRepeatVo; import cn.huge.module.ai.domain.vo.AiRequestVo; import cn.huge.module.ai.domain.vo.AiRiskVo; import cn.huge.module.ai.domain.vo.AiPropertyChatVo; import cn.huge.module.ai.service.AiCaseClassService; import cn.huge.module.ai.service.AiChatService; import cn.huge.module.ai.service.AiDifyService; import cn.huge.module.ai.service.AiSimilarityCaseService; import cn.huge.module.constant.AiCaseType; import cn.huge.module.client.api.impl.KnowledgeCaseClientImpl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.servlet.http.HttpServletRequest; import java.util.*; /** * AI请求调用/get-case获取案件列表(一般包含3个纠纷类和3个判决类),/get-law获取法条推荐列表;案件详情在根据案件列表的id及type调用/get-case-detail获取案件详情 */ @Slf4j @RestController @RequestMapping("/api/ai/case-law") public class AiController { @Autowired(required = false) private HttpServletRequest request; @Value("${ai.url}") private String aiUrl; @Value("${dify.url}") private String difyUrl; @Value("${dify.getSimilarityDyhCaseApi}") private String getSimilarityDyhCaseApi; @Value("${dify.user}") private String user; @Autowired private AiChatService aiChatService; @Autowired private AiCaseClassService aiCaseClassService; @Autowired private AiDifyService aiDifyService; @Autowired private KnowledgeCaseClientImpl knowledgeCaseClient; @Autowired private AiSimilarityCaseService aiSimilarityCaseService; private Map getParameter() { Map terms = Maps.newHashMap(); // 案件id String caseId = request.getParameter("caseId"); if (StringUtils.isNotBlank(caseId)) { terms.put("caseId", caseId); } // 用户id String userId = request.getParameter("userId"); if (StringUtils.isNotBlank(userId)) { terms.put("userId", userId); } // 会话标题 String conversationTitle = request.getParameter("conversationTitle"); if (StringUtils.isNotBlank(conversationTitle)) { terms.put("conversationTitle", conversationTitle); } // 会话id String aiConversationId = request.getParameter("aiConversationId"); if (StringUtils.isNotBlank(aiConversationId)) { terms.put("aiConversationId", aiConversationId); } // 案件描述 String caseDes = request.getParameter("caseDes"); if (StringUtils.isNotBlank(caseDes)) { terms.put("caseDes", caseDes); } // 案件诉求 String caseClaim = request.getParameter("caseClaim"); if (StringUtils.isNotBlank(caseClaim)) { terms.put("caseClaim", caseClaim); } // 用户消息(提问) String userMessage = request.getParameter("userMessage"); if (StringUtils.isNotBlank(userMessage)) { terms.put("userMessage", userMessage); } // 相似案件id String similarityCaseId = request.getParameter("similarityCaseId"); if (StringUtils.isNotBlank(similarityCaseId)) { terms.put("similarityCaseId", similarityCaseId); } // 判决案件正文 String caseContent = request.getParameter("caseContent"); if (StringUtils.isNotBlank(caseContent)) { terms.put("caseContent", caseContent); } // 评价 String likeStatus = request.getParameter("likeStatus"); if (StringUtils.isNotBlank(likeStatus)) { terms.put("likeStatus", likeStatus); } // 需要判断的案件文本 String caseText = request.getParameter("caseText"); if (StringUtils.isNotBlank(caseText)) { terms.put("caseText", caseText); } // 申请方当事人-证件号码 String plaintiffsCertiNo = request.getParameter("plaintiffsCertiNo"); if (StringUtils.isNotBlank(plaintiffsCertiNo)) { terms.put("plaintiffsCertiNo", plaintiffsCertiNo); } // 被申请方当事人-证件号码 String defendantsCertiNo = request.getParameter("defendantsCertiNo"); if (StringUtils.isNotBlank(defendantsCertiNo)) { terms.put("defendantsCertiNo", defendantsCertiNo); } return terms; } /** * 获取查询案件的重复案件 * * @return * @url {ctx}/api/ai/case-law/getRepeatResult */ @PostMapping("/getRepeatResult") public Object getRepeatResult(@RequestBody AiRepeatVo aiRepeatVo) { try { // return ReturnSucUtils.getRepInfo("请求成功", aiCaseClassService.getRepeatResult(aiRepeatVo)); return ReturnSucUtils.getRepInfo("请求成功", new ArrayList<>()); } catch (Exception e) { log.error("判断案件是否为重复来访案件失败:{}", e.getMessage()); return ReturnSucUtils.getRepInfo(); } } /** * 请求ai判断案件是否为风险、重点案件并保存标签到数据库 * * @return * @url {ctx}/api/ai/case-law/getRiskResult */ @PostMapping("/getRiskResult") public Object getRiskResult(@RequestBody AiRiskVo aiRiskVo) { try { // return ReturnSucUtils.getRepInfo("请求成功", aiCaseClassService.getRiskResult(aiRiskVo)); return ReturnSucUtils.getRepInfo("请求成功", aiCaseClassService.getCaseRisk(aiRiskVo)); } catch (Exception e) { log.error("判断案件是否为风险/重点案件失败:{}", e.getMessage()); // return ReturnFailUtils.getRepInfo(); return ReturnSucUtils.getRepInfo(); } } /** * 向量化案件到向量数据库 * * @return * @url {ctx}/api/ai/case-law/embeddingTextToMilvus */ @PostMapping("/embeddingTextToMilvus") public Object embeddingTextToMilvus(@RequestBody AiRepeatVo aiRepeatVo) { try { return ReturnSucUtils.getRepInfo("请求成功", aiCaseClassService.embeddingTextToMilvus(aiRepeatVo)); } catch (Exception e) { log.error("向量化案件到向量数据库失败:{}", e.getMessage()); // return ReturnFailUtils.getRepInfo(); return ReturnSucUtils.getRepInfo(); } } /** * 创建会话 * * @param * @return Object * @url {ctx}/api/ai/case-law/createAiChat */ @PostMapping("/createAiChat") public Object createAiChat() { Map terms = getParameter(); try { AiConversation aiConversation = aiChatService.createAiChat(terms); return ReturnSucUtils.getRepInfo("请求成功", aiConversation); } catch (Exception e) { log.error("创建AI会话失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } /** * 获取智能会话列表 * * @param * @return Object * @url {ctx}/api/ai/case-law/queryAiChatList */ @GetMapping("/queryAiChatList") public Object queryAiChatList() { Map terms = getParameter(); String caseId = terms.get("caseId").toString(); String userId = terms.get("userId").toString(); // 先从缓存中获取,如果有直接返回 Object cacheAi = GuavaCacheUtils.getCacheAi("queryAiChatList" + caseId + userId); if (ObjectUtils.isNotEmpty(cacheAi)) { return ReturnSucUtils.getRepInfo("请求成功", cacheAi); } try { List aiConversations = aiChatService.queryAiChatList(caseId, userId); // 放入缓存 GuavaCacheUtils.putCacheAi("queryAiChatList" + caseId + userId, aiConversations); return ReturnSucUtils.getRepInfo("请求成功", aiConversations); } catch (Exception e) { log.error("查询AI会话列表失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } /** * 创建对话 * * @param * @return Object * @url {ctx}/api/ai/case-law/createAiChatMessage */ @PostMapping(value = "/createAiChatMessage", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public StreamingResponseBody createAiChatMessage() { Map terms = getParameter(); try { return aiChatService.createAiChatMessage(terms); } catch (Exception e) { log.error("创建AI会话消息失败:{}", e.getMessage()); return null; } } /** * 获取智能会话列表 * * @return * @url {ctx}/api/ai/case-law/getAiChatMessageList */ @GetMapping("/getAiChatMessageList") public Object getAiChatMessageList() { Map terms = getParameter(); String aiConversationId = terms.get("aiConversationId").toString(); // 先从缓存中获取,如果有直接返回 Object cacheAi = GuavaCacheUtils.getCacheAi("getAiChatMessageList" + aiConversationId); if (ObjectUtils.isNotEmpty(cacheAi)) { return ReturnSucUtils.getRepInfo("请求成功", cacheAi); } try { List aiConversationMessages = aiChatService.getAiChatMessageList(aiConversationId); // 放入缓存 GuavaCacheUtils.putCacheAi("getAiChatMessageList" + aiConversationId, aiConversationMessages); return ReturnSucUtils.getRepInfo("请求成功", aiConversationMessages); } catch (Exception e) { log.error("查询AI会话消息列表失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } /** * 删除会话 * * @return * @url {ctx}/api/ai/case-law/deleteConversation */ @PostMapping("/deleteConversation") public Object deleteConversation() { Map terms = getParameter(); try { return ReturnSucUtils.getRepInfo("请求成功", aiChatService.deleteConversation(terms)); } catch (Exception e) { log.error("删除AI会话失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } /** * 获取案件总结 * * @return * @url {ctx}/api/ai/case-law/getJudgmentSummarize */ @PostMapping("/getJudgmentSummarize") public Object getJudgmentSummarize() { Map terms = getParameter(); String similarityCaseId = terms.get("similarityCaseId").toString(); String caseContent = terms.get("caseContent").toString(); String caseId = terms.get("caseId").toString(); // 先从缓存中获取,如果有直接返回 Object cacheAi = GuavaCacheUtils.getCacheAi("getJudgmentSummarize" + caseId + similarityCaseId); if (ObjectUtils.isNotEmpty(cacheAi)) { return ReturnSucUtils.getRepInfo("请求成功", cacheAi); } try { CaseSimilarityExplanatory caseSimilarityExplanatory = aiChatService.getJudgmentSummarize(similarityCaseId, caseContent, caseId); // 放入缓存 GuavaCacheUtils.putCacheAi("getJudgmentSummarize" + caseId + similarityCaseId, caseSimilarityExplanatory); return ReturnSucUtils.getRepInfo("请求成功", caseSimilarityExplanatory); } catch (Exception e) { log.error("获取案件总结失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } /** * 类案推荐评价 * * @return * @url {ctx}/api/ai/case-law/setLikeStatus */ @PostMapping("/setLikeStatus") public Object setLikeStatus() { Map terms = getParameter(); try { aiChatService.setLikeStatus(terms); return ReturnSucUtils.getRepInfo(true); } catch (Exception e) { log.error("设置点赞状态失败:{}", e.getMessage()); return ReturnFailUtils.getRepInfo(); } } // @PostMapping("/get-case") public Object getCase(@RequestBody AiRequestVo aiRequestVo) { Object cacheAi = GuavaCacheUtils.getCacheAi("get-case" + aiRequestVo.getCaseId()); if (ObjectUtils.isNotEmpty(cacheAi)) { return ReturnSucUtils.getRepInfo("请求成功", cacheAi); } List caseInfoDtoList = new ArrayList<>(); Map params = new HashMap<>(); params.put("caseDes", aiRequestVo.getCaseDes());//案件描述 params.put("caseClaim", aiRequestVo.getCaseClaim());//案件诉求 params.put("caseId", aiRequestVo.getCaseId());//案件id params.put("topK", "2"); params.put("metricType", "IP"); String s = HttpClientUtils.httpPostForm(aiUrl + "/queryConciliationCase", params, new HashMap<>(), "utf-8"); JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); if (code == 200) { JSONArray data = object.getJSONArray("data"); for (int i = 0; i < data.size(); i++) { JSONObject jsonObject = data.getJSONObject(i); CaseInfoDto caseInfoDto = new CaseInfoDto(); caseInfoDto.setCaseId(jsonObject.getString("id")); caseInfoDto.setCaseName(jsonObject.getString("case_title")); caseInfoDto.setCaseType(1);//表示调解类案件 caseInfoDtoList.add(caseInfoDto); } } if (caseInfoDtoList.size() < 4) { s = HttpClientUtils.httpPostForm(aiUrl + "/queryJudgmentCase", params, new HashMap<>(), "utf-8"); object = JSONObject.parseObject(s); code = object.getIntValue("code"); if (code == 200) { JSONArray data = object.getJSONArray("data"); for (int i = 0; i < data.size(); i++) { JSONObject jsonObject = data.getJSONObject(i); CaseInfoDto caseInfoDto = new CaseInfoDto(); caseInfoDto.setCaseId(jsonObject.getString("cpws_case_info_id")); caseInfoDto.setCaseName(jsonObject.getString("case_name")); caseInfoDto.setCaseType(2);//表示判决类案件 caseInfoDtoList.add(caseInfoDto); if (caseInfoDtoList.size() == 3) { break; } } } } GuavaCacheUtils.putCacheAi("get-case" + aiRequestVo.getCaseId(), caseInfoDtoList); return ReturnSucUtils.getRepInfo("请求成功", caseInfoDtoList); } @PostMapping("/get-law") public Object getLaw(@RequestBody AiRequestVo aiRequestVo) { return aiSimilarityCaseService.getCaseLaw(aiRequestVo); } @RequestMapping("/get-case-detail") public Object getCaseLawDetail(@RequestParam String caseId, @RequestParam int type) { CaseInfoDetailDto caseInfoDetailDto = new CaseInfoDetailDto(); try { if (type == AiCaseType.AI_CASE_TYPE_DYH) {//表示纠纷类案件 DyhCaseDetailDTO dyhCaseDetailDTO = knowledgeCaseClient.getCaseDetail(caseId); if (ObjectUtils.isNotEmpty(dyhCaseDetailDTO)) { caseInfoDetailDto.setCaseId(dyhCaseDetailDTO.getId()); caseInfoDetailDto.setCaseTitle( StringUtils.defaultIfBlank(dyhCaseDetailDTO.getCaseTitle(), "")); caseInfoDetailDto.setCaseDesc( StringUtils.defaultIfBlank(dyhCaseDetailDTO.getCaseDes(), "")); caseInfoDetailDto.setAgreeContent( StringUtils.defaultIfBlank(dyhCaseDetailDTO.getAgreeContent(), "")); caseInfoDetailDto.setCaseClaim( StringUtils.defaultIfBlank(dyhCaseDetailDTO.getCaseClaim(), "")); } } else { CpwsCaseText cpwsCaseText = knowledgeCaseClient.getCpwsCaseTextById(caseId); if (cpwsCaseText != null) { caseInfoDetailDto.setCaseId(cpwsCaseText.getCpwsCaseTextId()); caseInfoDetailDto.setCaseTitle( StringUtils.defaultIfBlank(cpwsCaseText.getBasicCaseInfo(), "")); // 拼接完整文本,处理可能为null的字段 List textParts = new ArrayList<>(); if (StringUtils.isNotBlank(cpwsCaseText.getTrialProcess())) { textParts.add(cpwsCaseText.getTrialProcess()); } if (StringUtils.isNotBlank(cpwsCaseText.getBasicCaseInfo())) { textParts.add(cpwsCaseText.getBasicCaseInfo()); } if (StringUtils.isNotBlank(cpwsCaseText.getTrialFinding())) { textParts.add(cpwsCaseText.getTrialFinding()); } if (StringUtils.isNotBlank(cpwsCaseText.getJudgment())) { textParts.add(cpwsCaseText.getJudgment()); } if (StringUtils.isNotBlank(cpwsCaseText.getLegalBasis())) { textParts.add(cpwsCaseText.getLegalBasis()); } String fullText = String.join("\n", textParts); caseInfoDetailDto.setCaseDesc(fullText); caseInfoDetailDto.setAgreeContent( StringUtils.defaultIfBlank(cpwsCaseText.getJudgment(), "")); caseInfoDetailDto.setLegalBasis( StringUtils.defaultIfBlank(cpwsCaseText.getLegalBasis(), "")); } } return ReturnSucUtils.getRepInfo("处理成功", caseInfoDetailDto); } catch (Exception e) { log.error("获取案件详情失败:", e); return ReturnFailUtils.getRepInfo(); } } @PostMapping("/get-clain-rise-case") public Object getClaimRiskByCase(@RequestBody AiRequestVo aiRequestVo) { Object cacheAi = GuavaCacheUtils.getCacheAi("get-clain-rise-case" + aiRequestVo.getCaseId()); if (ObjectUtils.isNotEmpty(cacheAi)) { return ReturnSucUtils.getRepInfo("请求成功", cacheAi); } CaseRiskDto caseRiskDto = new CaseRiskDto(); Map params = new HashMap<>(); params.put("caseDes", aiRequestVo.getCaseDes());//案件描述 params.put("caseClaim", aiRequestVo.getCaseClaim());//案件诉求 params.put("caseId", aiRequestVo.getCaseId());//案件id String s = HttpClientUtils.httpPostForm(aiUrl + "/getClaimRiskByCase", params, new HashMap<>(), "utf-8"); JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); if (code == 200) { JSONObject data = object.getJSONObject("data"); caseRiskDto.setIsClaimRisk(data.getIntValue("is_claim_risk")); caseRiskDto.setAnalysisProcess(data.getString("analysis_process")); } GuavaCacheUtils.putCacheAi("get-clain-rise-case" + aiRequestVo.getCaseId(), caseRiskDto); return ReturnSucUtils.getRepInfo("请求成功", caseRiskDto); } @PostMapping("/get-case") public Object getSimilarityCase(@RequestBody AiRequestVo aiRequestVo) { return aiSimilarityCaseService.getSimilarityCase(aiRequestVo); } /** * 根据案件描述生成调解策略 * * @return * @url {ctx}/api/ai/case-law/getMediateStrategy */ @PostMapping("/getMediateStrategy") public Object getMediateStrategy(@RequestBody AiMediateStrategyVo aiMediateStrategyVo) { try { String caseText = aiMediateStrategyVo.getCaseText(); return aiDifyService.getMediateStrategy(caseText); } catch (Exception e) { log.error("获取案件调解策略失败:{}", e.getMessage()); return ReturnSucUtils.getRepInfo("获取调解策略失败", null); } } /** * 流式AI对话 * * @return StreamingResponseBody 流式响应体 * @url {ctx}/api/ai/case-law/streamChat */ @PostMapping(value = "/streamChat", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public StreamingResponseBody streamChat(@RequestBody AiChatVo aiChatVo) { try { return aiDifyService.streamChat( aiChatVo.getCaseText(), aiChatVo.getQuery(), aiChatVo.getConversationId(), aiChatVo.getResponseMode() ); } catch (Exception e) { log.error("AI流式对话失败:{}", e.getMessage(), e); return null; } } /** * 阻塞式AI对话,直接返回完整回答 * * @return 包含AI回答和对话ID的对象 * @url {ctx}/api/ai/case-law/blockingChat */ @PostMapping("/blockingChat") public Object blockingChat(@RequestBody AiChatVo aiChatVo) { try { Map result = aiDifyService.blockingChat( aiChatVo.getCaseText(), aiChatVo.getQuery(), aiChatVo.getConversationId() ); return ReturnSucUtils.getRepInfo("请求成功", result); } catch (Exception e) { log.error("AI阻塞式对话失败:{}", e.getMessage(), e); return ReturnSucUtils.getRepInfo("对话失败", null); } } /** * 阻塞式AI财产对话,直接返回完整回答 * * @return 包含AI回答和对话ID的对象 * @url {ctx}/api/ai/case-law/blockingPropertyChat */ @PostMapping("/blockingPropertyChat") public Object blockingPropertyChat(@RequestBody AiPropertyChatVo aiPropertyChatVo) { try { Map result = aiDifyService.blockingPropertyChat( aiPropertyChatVo.getQuery(), aiPropertyChatVo.getConversationId(), aiPropertyChatVo.getCheckRationality() ); return ReturnSucUtils.getRepInfo("请求成功", result); } catch (Exception e) { log.error("AI阻塞式财产对话失败:{}", e.getMessage(), e); return ReturnSucUtils.getRepInfo("对话失败", null); } } }