package cn.huge.module.ai.service; import cn.huge.base.common.exception.ServiceException; import cn.huge.base.common.utils.HttpClientUtils; import cn.huge.module.ai.domain.po.AiConversation; import cn.huge.module.ai.domain.po.AiMessage; import cn.huge.module.ai.domain.po.CaseSimilarityExplanatory; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import java.io.IOException; import java.util.*; @Slf4j @Service @Transactional(rollbackFor = Exception.class) public class AiChatService { @Value("${ai.url}") private String aiUrl; /** * 创建会话 * 该方法用于初始化与AI的对话会话它接收一个包含必要信息(如案例ID、用户ID和对话标题)的映射, * 并使用这些信息来创建一个AiConversation对象然后,它通过HTTP请求将这些信息发送到AI服务, * 以创建一个对话会话如果请求成功,它将解析响应并更新AiConversation对象的ID * * @param terms 包含创建对话所需信息的映射,包括案例ID、用户ID和对话标题 * @return 返回一个AiConversation对象,如果创建成功,该对象将包含AI对话ID */ public AiConversation createAiChat(Map terms){ try{ // 从terms映射中提取必要的参数 String caseId = terms.get("caseId").toString(); String userId = terms.get("userId").toString(); String conversationTitle = terms.get("conversationTitle").toString(); // 创建一个空的AiConversation对象 AiConversation aiConversation = new AiConversation(); // 准备POST请求的参数 Map params = new HashMap<>(); params.put("caseId", caseId); params.put("userId", userId); params.put("conversationTitle", conversationTitle); // 发送HTTP POST请求创建AI对话 String s = HttpClientUtils.httpPostForm(aiUrl + "/createAiChat", params, new HashMap<>(), "utf-8"); // 解析响应JSON对象 JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); // 检查响应状态码,如果成功,更新AiConversation对象的ID if (code == 200) { JSONObject data = object.getJSONObject("data"); aiConversation.setAiConversationId(data.getString("aiConversationId")); } // 返回AiConversation对象 return aiConversation; }catch (Exception e){ // 记录异常信息并抛出服务异常 log.error("[AiChatService.updateCaseAgent]调用失败,异常信息:"+e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 获取智能会话列表 * 根据案件ID和用户ID查询智能会话列表 * @param caseId 案件ID * @param userId 用户ID * @return Object 返回智能会话列表对象 */ public List queryAiChatList(String caseId,String userId){ try{ // 构造请求URL String message = String.format("/queryAiChatList?caseId=%s&userId=%s", caseId, userId); // 发起HTTP GET请求 String s = HttpClientUtils.httpGet(aiUrl + message, new HashMap<>(), "utf-8"); // 解析JSON响应 JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); List aiConversationList = new ArrayList<>(); if (code == 200) { // 获取会话列表数据 JSONArray data = object.getJSONArray("data"); for (int i = 0; i < data.size(); i++) { JSONObject jsonObject = data.getJSONObject(i); AiConversation aiConversation = new AiConversation(); // 设置会话属性 aiConversation.setAiConversationId(jsonObject.getString("ai_conversation_id")); aiConversation.setCaseId(jsonObject.getString("case_id")); aiConversation.setConversationTitle(jsonObject.getString("conversation_title")); aiConversationList.add(aiConversation); } } return aiConversationList; }catch (Exception e){ // 记录异常日志并抛出自定义异常 log.error("[AiChatService.updateCaseAgent]调用失败,异常信息:"+e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 创建对话 * 该方法用于构建并发送一个聊天消息请求到AI服务,以便生成AI聊天响应 * 它从输入参数中提取必要的聊天信息,并使用WebClient进行HTTP请求 * * @param terms 包含聊天所需信息的映射,包括aiConversationId、caseDes、caseClaim和userMessage * @return Object 返回一个StreamingResponseBody对象,用于流式处理AI聊天消息的响应 */ public StreamingResponseBody createAiChatMessage(Map terms){ try{ // 从输入参数中提取聊天所需的信息 String aiConversationId = terms.get("aiConversationId").toString(); String caseDes = terms.get("caseDes").toString(); String caseClaim = terms.get("caseClaim").toString(); String userMessage = terms.get("userMessage").toString(); // 创建表单数据对象,用于发送聊天信息 MultiValueMap formData = new LinkedMultiValueMap<>(); formData.add("aiConversationId", aiConversationId); formData.add("caseDes", caseDes); formData.add("caseClaim", caseClaim); formData.add("userMessage", userMessage); // 创建WebClient对象,用于发送HTTP请求 WebClient client = WebClient.create(aiUrl + "/createAiChatMessage"); // 返回一个StreamingResponseBody对象,用于处理流式响应 return outputStream -> client.post() .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(BodyInserters.fromFormData(formData)) .retrieve() .bodyToFlux(DataBuffer.class) .doOnNext(dataBuffer -> { // 将响应数据缓冲区转换为字节数组并写入输出流 byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); try { outputStream.write(bytes); // 刷新输出流以确保数据立即发送 outputStream.flush(); } catch (IOException e) { // 异常处理 e.printStackTrace(); } }) .blockLast(); }catch (Exception e){ // 日志记录异常信息 log.error("[AiChatService.createAiChatMessage]调用失败,异常信息:"+e, e); // 抛出服务异常 throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 获取智能对话列表 * * 本方法通过HTTP GET请求从服务器获取与特定AI对话ID相关的智能对话消息列表 * 它首先构造请求URL,然后调用HttpClient工具类发送请求并解析响应 * 如果响应代码为200,表示成功,它将解析响应数据中的消息列表,并将其转换为AiMessage对象列表返回 * * @param aiConversationId AI对话ID,用于标识特定的对话 * @return 包含AiMessage对象的列表,表示智能对话的消息列表 * 如果请求失败或解析错误,将抛出ServiceException异常 */ public List getAiChatMessageList(String aiConversationId){ try { // 构造请求路径 String message = String.format("/getAiChatMessageList?aiConversationId=%s", aiConversationId); // 发送HTTP GET请求并接收响应内容 String s = HttpClientUtils.httpGet(aiUrl + message, new HashMap<>(), "utf-8"); // 解析响应内容为JSONObject JSONObject object = JSONObject.parseObject(s); // 获取响应状态码 int code = object.getIntValue("code"); List aiMessageList = new ArrayList<>(); // 如果响应状态码为200,表示请求成功,进一步解析响应数据 if (code == 200) { // 获取消息列表数据 JSONArray data = object.getJSONArray("data"); // 遍历消息列表,将每条消息转换为AiMessage对象 for (int i = 0; i < data.size(); i++) { JSONObject jsonObject = data.getJSONObject(i); AiMessage aiMessage = new AiMessage(); aiMessage.setAiMessageId(jsonObject.getString("ai_message_id")); aiMessage.setConversationId(jsonObject.getString("conversation_id")); aiMessage.setMessageContent(jsonObject.getString("message_content")); aiMessage.setSenderType(jsonObject.getString("sender_type")); aiMessageList.add(aiMessage); } } return aiMessageList; }catch (Exception e) { // 记录错误日志并抛出自定义异常 log.error("[AiChatService.getAiChatMessageList]调用失败,异常信息:"+e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 删除会话(修改状态) */ public Object deleteConversation(Map terms){ try { String aiConversationId = terms.get("aiConversationId").toString(); Map params = new HashMap<>(); params.put("aiConversationId", aiConversationId); String s = HttpClientUtils.httpPostForm(aiUrl + "/deleteConversation", params, new HashMap<>(), "utf-8"); JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); if (code == 200) { return object.getString("data"); } return null; }catch (Exception e) { log.error("[AiChatService.deleteConversation]调用失败,异常信息:"+e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 判决简介接口 */ public CaseSimilarityExplanatory getJudgmentSummarize(String similarityCaseId, String caseContent, String caseId) { try { Map params = new HashMap<>(); params.put("similarityCaseId", similarityCaseId); params.put("caseContent", caseContent); params.put("caseId", caseId); String s = HttpClientUtils.httpPostForm(aiUrl + "/getJudgmentSummarize", params, new HashMap<>(), "utf-8"); JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); CaseSimilarityExplanatory caseSimilarityExplanatory = new CaseSimilarityExplanatory(); if (code == 200) { JSONObject data = object.getJSONObject("data"); caseSimilarityExplanatory.setCaseId(data.getString("case_id")); caseSimilarityExplanatory.setSimilarityCaseId(data.getString("similarity_case_id")); caseSimilarityExplanatory.setCaseSimilarityExplanatoryId(data.getString("case_similarity_explanatory_id")); caseSimilarityExplanatory.setExplanatoryContent(data.getString("explanatory_content")); } return caseSimilarityExplanatory; }catch (Exception e) { log.error("[AiChatService.getJudgmentSummarize]调用失败,异常信息:"+e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } /** * 类案推荐评价 */ public Object setLikeStatus(Map terms) { try { String similarityCaseId = terms.get("similarityCaseId").toString(); String caseContent = terms.get("likeStatus").toString(); String caseId = terms.get("caseId").toString(); Map params = new HashMap<>(); params.put("similarityCaseId", similarityCaseId); params.put("caseContent", caseContent); params.put("caseId", caseId); String s = HttpClientUtils.httpPostForm(aiUrl + "/setLikeStatus", params, new HashMap<>(), "utf-8"); JSONObject object = JSONObject.parseObject(s); int code = object.getIntValue("code"); if (code == 200) { return object.getJSONObject("data"); } return null; } catch (Exception e) { log.error("[AiChatService.setLikeStatus]调用失败,异常信息:" + e, e); throw new ServiceException("AiChatService.updateCaseAgent", e); } } }