mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/per-boe/java-servers.git
synced 2025-12-07 01:46:47 +08:00
案例助手:代码整理和部分问题修复
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
package com.xboe.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.elasticsearch.client.indices.CreateIndexRequest;
|
||||
import org.elasticsearch.client.indices.CreateIndexResponse;
|
||||
import org.elasticsearch.client.indices.GetIndexRequest;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ElasticSearch索引初始化器
|
||||
* 在Spring Boot启动完成并监听到配置文件加载完毕后,检查并创建所需的ES索引
|
||||
*
|
||||
* @author AI Assistant
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ElasticSearchIndexInitializer {
|
||||
|
||||
@Autowired(required = false)
|
||||
private RestHighLevelClient elasticsearchClient;
|
||||
|
||||
/**
|
||||
* 监听Spring Boot应用启动完成事件
|
||||
* ApplicationReadyEvent在应用启动完成、所有配置加载完毕后触发
|
||||
*/
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void initializeElasticSearchIndices() {
|
||||
if (elasticsearchClient == null) {
|
||||
log.warn("ElasticSearch客户端未配置,跳过索引初始化");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("开始检查和初始化ElasticSearch索引...");
|
||||
|
||||
try {
|
||||
// 检查并创建ai_chat_messages索引
|
||||
checkAndCreateIndex("ai_chat_messages");
|
||||
|
||||
log.info("ElasticSearch索引初始化完成");
|
||||
} catch (Exception e) {
|
||||
log.error("ElasticSearch索引初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查索引是否存在,如果不存在则创建
|
||||
*
|
||||
* @param indexName 索引名称
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
private void checkAndCreateIndex(String indexName) throws IOException {
|
||||
// 检查索引是否存在
|
||||
GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
|
||||
boolean exists = elasticsearchClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
if (exists) {
|
||||
log.info("ElasticSearch索引 [{}] 已存在", indexName);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("ElasticSearch索引 [{}] 不存在,开始创建...", indexName);
|
||||
|
||||
// 创建索引
|
||||
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
|
||||
|
||||
// 设置索引配置
|
||||
createIndexRequest.settings(Settings.builder()
|
||||
.put("index.number_of_shards", 1)
|
||||
.put("index.number_of_replicas", 0)
|
||||
.put("index.analysis.analyzer.ik_max_word.tokenizer", "ik_max_word")
|
||||
.put("index.analysis.analyzer.ik_smart.tokenizer", "ik_smart")
|
||||
);
|
||||
|
||||
// 设置字段映射
|
||||
String mapping = getAiChatMessagesMapping();
|
||||
createIndexRequest.mapping(mapping, XContentType.JSON);
|
||||
|
||||
// 执行创建索引请求
|
||||
CreateIndexResponse createIndexResponse = elasticsearchClient.indices()
|
||||
.create(createIndexRequest, RequestOptions.DEFAULT);
|
||||
|
||||
if (createIndexResponse.isAcknowledged()) {
|
||||
log.info("ElasticSearch索引 [{}] 创建成功", indexName);
|
||||
} else {
|
||||
log.warn("ElasticSearch索引 [{}] 创建可能失败,响应未确认", indexName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ai_chat_messages索引的字段映射配置
|
||||
* 根据项目中的会话消息数据结构规范定义映射
|
||||
*
|
||||
* @return JSON格式的映射配置
|
||||
*/
|
||||
private String getAiChatMessagesMapping() {
|
||||
return "{\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"conversationId\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"messageId\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"messageType\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"query\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\",\n" +
|
||||
" \"fields\": {\n" +
|
||||
" \"keyword\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"ignore_above\": 256\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"answer\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\"\n" +
|
||||
" },\n" +
|
||||
" \"caseRefer\": {\n" +
|
||||
" \"type\": \"nested\",\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"caseId\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"title\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\"\n" +
|
||||
" },\n" +
|
||||
" \"authorName\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"keywords\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\"\n" +
|
||||
" },\n" +
|
||||
" \"content\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"suggestions\": {\n" +
|
||||
" \"type\": \"text\",\n" +
|
||||
" \"analyzer\": \"ik_max_word\",\n" +
|
||||
" \"search_analyzer\": \"ik_smart\"\n" +
|
||||
" },\n" +
|
||||
" \"userId\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"userName\": {\n" +
|
||||
" \"type\": \"keyword\",\n" +
|
||||
" \"index\": true\n" +
|
||||
" },\n" +
|
||||
" \"timestamp\": {\n" +
|
||||
" \"type\": \"date\",\n" +
|
||||
" \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'||epoch_millis\"\n" +
|
||||
" },\n" +
|
||||
" \"createTime\": {\n" +
|
||||
" \"type\": \"date\",\n" +
|
||||
" \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'||epoch_millis\"\n" +
|
||||
" },\n" +
|
||||
" \"updateTime\": {\n" +
|
||||
" \"type\": \"date\",\n" +
|
||||
" \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSS'Z'||epoch_millis\"\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.xboe.enums;
|
||||
|
||||
public enum CaseAiChatStatusEnum {
|
||||
|
||||
REFERS(0, "引用文档"),
|
||||
|
||||
CHAT(1, "聊天中"),
|
||||
|
||||
CHAT_COMPLETED(2, "聊天完成"),
|
||||
|
||||
SUGGESTIONS(3, "建议"),
|
||||
|
||||
API_COMPLETED(4, "接口完成"),
|
||||
;
|
||||
|
||||
private final int code;
|
||||
|
||||
private final String label;
|
||||
|
||||
CaseAiChatStatusEnum(int code, String label) {
|
||||
this.code = code;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static CaseAiChatStatusEnum getByCode(int code) {
|
||||
for (CaseAiChatStatusEnum value : values()) {
|
||||
if (value.code == code) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return API_COMPLETED;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.xboe.module.boecase.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.xboe.module.boecase.vo.CaseReferVo;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI聊天会话数据实体
|
||||
* 纯数据容器,不与数据库交互
|
||||
*
|
||||
* @author AI Assistant
|
||||
*/
|
||||
@Data
|
||||
@Slf4j
|
||||
public class AiChatConversationData {
|
||||
|
||||
/**
|
||||
* 会话ID
|
||||
*/
|
||||
private String conversationId;
|
||||
|
||||
/**
|
||||
* 用户提问内容
|
||||
*/
|
||||
private String query;
|
||||
|
||||
/**
|
||||
* AI回答内容(使用StringBuilder收集流式数据)
|
||||
*/
|
||||
private StringBuilder answer = new StringBuilder();
|
||||
|
||||
/**
|
||||
* 案例引用列表
|
||||
*/
|
||||
private List<CaseReferVo> caseRefers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 建议列表
|
||||
*/
|
||||
private List<String> suggestions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 消息时间戳
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime timestamp;
|
||||
|
||||
// ================== 构造函数 ==================
|
||||
|
||||
public AiChatConversationData() {
|
||||
this.timestamp = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public AiChatConversationData(String conversationId, String query, String answer,
|
||||
List<CaseReferVo> caseRefers, List<String> suggestions,
|
||||
String userId) {
|
||||
this.conversationId = conversationId;
|
||||
this.query = query;
|
||||
this.answer = new StringBuilder(answer != null ? answer : "");
|
||||
this.caseRefers = caseRefers != null ? caseRefers : new ArrayList<>();
|
||||
this.suggestions = suggestions != null ? suggestions : new ArrayList<>();
|
||||
this.userId = userId;
|
||||
this.timestamp = LocalDateTime.now();
|
||||
}
|
||||
|
||||
// ================== 便捷方法 ==================
|
||||
|
||||
/**
|
||||
* 获取回答内容的字符串形式
|
||||
*/
|
||||
public String getAnswerAsString() {
|
||||
return this.answer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加回答内容
|
||||
*/
|
||||
public void appendAnswer(String content) {
|
||||
if (content != null) {
|
||||
this.answer.append(content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加案例引用
|
||||
*/
|
||||
public void addCaseRefer(CaseReferVo caseRefer) {
|
||||
if (caseRefer != null) {
|
||||
this.caseRefers.add(caseRefer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加建议
|
||||
*/
|
||||
public void addSuggestion(String suggestion) {
|
||||
if (suggestion != null && !suggestion.trim().isEmpty()) {
|
||||
this.suggestions.add(suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.xboe.module.boecase.service.impl;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.xboe.core.CurrentUser;
|
||||
import com.xboe.enums.CaseAiChatStatusEnum;
|
||||
import com.xboe.module.boecase.dao.CaseAiConversationsDao;
|
||||
import com.xboe.module.boecase.dao.CaseDocumentLogDao;
|
||||
import com.xboe.module.boecase.dao.CasesDao;
|
||||
@@ -15,6 +16,7 @@ import com.xboe.module.boecase.service.IAiAccessTokenService;
|
||||
import com.xboe.module.boecase.service.ICaseAiChatService;
|
||||
import com.xboe.module.boecase.vo.CaseAiMessageVo;
|
||||
import com.xboe.module.boecase.vo.CaseReferVo;
|
||||
import com.xboe.module.boecase.entity.AiChatConversationData;
|
||||
import com.xboe.system.organization.vo.OrgSimpleVo;
|
||||
import com.xboe.system.user.service.IUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -89,19 +91,6 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
// 1. 获取conversationId
|
||||
String conversationId = getOrCreateConversationId(caseAiChatDto, currentUser);
|
||||
|
||||
// 2. 检查是否为新会话,如果是则保存会话记录
|
||||
boolean isNewConversation = StringUtils.isEmpty(caseAiChatDto.getConversationId());
|
||||
CaseAiConversations conversation = null;
|
||||
if (isNewConversation) {
|
||||
// 新会话,需要保存到数据库
|
||||
conversation = new CaseAiConversations();
|
||||
conversation.setAiConversationId(conversationId);
|
||||
conversation.setConversationName("AI案例咨询-" + LocalDateTime.now());
|
||||
conversation.setConversationUser(currentUser.getAccountId());
|
||||
// 保存会话到数据库
|
||||
caseAiConversationsDao.save(conversation);
|
||||
}
|
||||
|
||||
// 3. 构建请求参数
|
||||
String userId = currentUser.getAccountId();
|
||||
String kId = caseAiProperties.getCaseKnowledgeId();
|
||||
@@ -128,10 +117,10 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
SseEmitter sseEmitter = new SseEmitter();
|
||||
|
||||
// 6. 用于收集对话数据的容器
|
||||
ConversationData conversationData = new ConversationData();
|
||||
conversationData.query = caseAiChatDto.getQuery();
|
||||
conversationData.conversationId = conversationId;
|
||||
conversationData.userId = userId;
|
||||
AiChatConversationData conversationData = new AiChatConversationData();
|
||||
conversationData.setQuery(caseAiChatDto.getQuery());
|
||||
conversationData.setConversationId(conversationId);
|
||||
conversationData.setUserId(userId);
|
||||
|
||||
// 7. 创建事件监听器
|
||||
EventSourceListener listener = new EventSourceListener() {
|
||||
@@ -150,7 +139,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
|
||||
@Override
|
||||
public void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {
|
||||
log.info("调用接口 [{}] 监听数据 id: [{}] type: [{}] data: [{}]", request.url(), id, type, data);
|
||||
log.debug("调用接口 [{}] 监听数据 id: [{}] type: [{}] data: [{}]", request.url(), id, type, data);
|
||||
|
||||
try {
|
||||
// 解析返回的数据
|
||||
@@ -160,8 +149,9 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
Integer status = responseData.getInteger("status");
|
||||
|
||||
if (status != null) {
|
||||
switch (status) {
|
||||
case 0: // 返回引用文件
|
||||
CaseAiChatStatusEnum statusEnum = CaseAiChatStatusEnum.getByCode(status);
|
||||
switch (statusEnum) {
|
||||
case REFERS: // 返回引用文件
|
||||
// 处理文件引用并构建返给前端的数据
|
||||
JSONObject modifiedData = handleFileReferAndBuildResponse(responseData, conversationData);
|
||||
if (modifiedData != null) {
|
||||
@@ -170,19 +160,18 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
return; // 早期返回,不发送原始数据
|
||||
}
|
||||
break;
|
||||
case 1: // 流式对话中
|
||||
case CHAT: // 流式对话中
|
||||
String content = responseData.getString("content");
|
||||
if (content != null) {
|
||||
conversationData.answer.append(content);
|
||||
conversationData.appendAnswer(content);
|
||||
}
|
||||
break;
|
||||
case 2: // 回答完成
|
||||
// 不做特殊处理
|
||||
break;
|
||||
case 3: // 返回建议
|
||||
case SUGGESTIONS: // 返回建议
|
||||
handleSuggestions(responseData, conversationData);
|
||||
break;
|
||||
case 4: // 接口交互完成
|
||||
case CHAT_COMPLETED:
|
||||
case API_COMPLETED: // 接口交互完成
|
||||
default:
|
||||
// 不做特殊处理
|
||||
break;
|
||||
}
|
||||
@@ -402,7 +391,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 处理文件引用并构建返给前端的响应数据
|
||||
*/
|
||||
private JSONObject handleFileReferAndBuildResponse(JSONObject responseData, ConversationData conversationData) {
|
||||
private JSONObject handleFileReferAndBuildResponse(JSONObject responseData, AiChatConversationData conversationData) {
|
||||
try {
|
||||
// 先处理文件引用,收集CaseReferVo数据
|
||||
List<CaseReferVo> currentCaseRefers = new ArrayList<>();
|
||||
@@ -418,7 +407,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
CaseReferVo caseRefer = getCaseReferByDocId(docId);
|
||||
if (caseRefer != null) {
|
||||
currentCaseRefers.add(caseRefer);
|
||||
conversationData.caseRefers.add(caseRefer); // 也添加到总的收集器中
|
||||
conversationData.addCaseRefer(caseRefer); // 也添加到总的收集器中
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,7 +416,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
// 构建返给前端的数据结构
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("status", 0);
|
||||
data.put("conversationId", conversationData.conversationId);
|
||||
data.put("conversationId", conversationData.getConversationId());
|
||||
data.put("content", responseData.getString("content"));
|
||||
|
||||
// 添加处理后的案例引用数据
|
||||
@@ -471,7 +460,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 处理文件引用(原方法,保留用于数据收集)
|
||||
*/
|
||||
private void handleFileRefer(JSONObject responseData, ConversationData conversationData) {
|
||||
private void handleFileRefer(JSONObject responseData, AiChatConversationData conversationData) {
|
||||
try {
|
||||
JSONObject fileRefer = responseData.getJSONObject("fileRefer");
|
||||
if (fileRefer != null && fileRefer.containsKey("files")) {
|
||||
@@ -483,7 +472,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
// 根据docId从 case_document_log 表查询案例数据
|
||||
CaseReferVo caseRefer = getCaseReferByDocId(docId);
|
||||
if (caseRefer != null) {
|
||||
conversationData.caseRefers.add(caseRefer);
|
||||
conversationData.addCaseRefer(caseRefer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,14 +485,14 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 处理建议
|
||||
*/
|
||||
private void handleSuggestions(JSONObject responseData, ConversationData conversationData) {
|
||||
private void handleSuggestions(JSONObject responseData, AiChatConversationData conversationData) {
|
||||
try {
|
||||
JSONArray suggestions = responseData.getJSONArray("suggestions");
|
||||
if (suggestions != null) {
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
String suggestion = suggestions.getString(i);
|
||||
if (suggestion != null) {
|
||||
conversationData.suggestions.add(suggestion);
|
||||
conversationData.addSuggestion(suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -559,7 +548,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 保存对话记录到ES
|
||||
*/
|
||||
private void saveConversationToES(ConversationData conversationData) {
|
||||
private void saveConversationToES(AiChatConversationData conversationData) {
|
||||
if (elasticsearchClient == null) {
|
||||
log.warn("未配置Elasticsearch客户端,无法保存对话记录");
|
||||
return;
|
||||
@@ -568,15 +557,15 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
try {
|
||||
// 构建要保存的数据
|
||||
JSONObject esData = new JSONObject();
|
||||
esData.put("query", conversationData.query);
|
||||
esData.put("answer", conversationData.answer.toString());
|
||||
esData.put("conversationId", conversationData.conversationId);
|
||||
esData.put("userId", conversationData.userId);
|
||||
esData.put("query", conversationData.getQuery());
|
||||
esData.put("answer", conversationData.getAnswerAsString());
|
||||
esData.put("conversationId", conversationData.getConversationId());
|
||||
esData.put("userId", conversationData.getUserId());
|
||||
esData.put("timestamp", LocalDateTime.now().toString());
|
||||
|
||||
// 构建 caseRefer 数据
|
||||
JSONArray caseReferArray = new JSONArray();
|
||||
for (CaseReferVo caseRefer : conversationData.caseRefers) {
|
||||
for (CaseReferVo caseRefer : conversationData.getCaseRefers()) {
|
||||
JSONObject caseReferObj = new JSONObject();
|
||||
caseReferObj.put("caseId", caseRefer.getCaseId());
|
||||
caseReferObj.put("title", caseRefer.getTitle());
|
||||
@@ -588,7 +577,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
esData.put("caseRefer", caseReferArray);
|
||||
|
||||
// 添加建议
|
||||
esData.put("suggestions", conversationData.suggestions);
|
||||
esData.put("suggestions", conversationData.getSuggestions());
|
||||
|
||||
// 保存到ES
|
||||
IndexRequest indexRequest = new IndexRequest("ai_chat_messages");
|
||||
@@ -605,7 +594,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 当 SSE 失败时,作为普通 HTTP 请求处理
|
||||
*/
|
||||
private void handleAsRegularHttpRequest(Request request, SseEmitter sseEmitter, ConversationData conversationData) {
|
||||
private void handleAsRegularHttpRequest(Request request, SseEmitter sseEmitter, AiChatConversationData conversationData) {
|
||||
try {
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
@@ -634,12 +623,5 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
|
||||
/**
|
||||
* 对话数据容器
|
||||
*/
|
||||
private static class ConversationData {
|
||||
public String query;
|
||||
public StringBuilder answer = new StringBuilder();
|
||||
public List<CaseReferVo> caseRefers = new ArrayList<>();
|
||||
public List<String> suggestions = new ArrayList<>();
|
||||
public String conversationId;
|
||||
public String userId;
|
||||
}
|
||||
// ConversationData 已移动到独立的Entity类:AiChatConversationData
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user