Compare commits

...

6 Commits

Author SHA1 Message Date
liu.zixi
8a3899dfd1 fix: 日志转储 2025-11-25 17:46:42 +08:00
liu.zixi
c17a594393 fix: 解决报错 2025-11-25 16:52:11 +08:00
liu.zixi
09d61ceb9d fix: 完善错误信息提示的处理方式 2025-11-25 16:51:16 +08:00
liu.zixi
106fde8e6b fix: 报错时也记录 2025-11-25 14:03:53 +08:00
liu.zixi
3bf0534d77 fix: 修复ES数据类型解析的问题 2025-11-25 13:30:41 +08:00
liu.zixi
dd0e10539f fix: 修复下载excel接口入参问题 2025-11-25 12:09:32 +08:00
7 changed files with 57 additions and 41 deletions

View File

@@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
@@ -105,8 +106,9 @@ public class CaseAiChatApi extends ApiBaseController {
public void downloadConversationExcel(@RequestParam String startTime,
@RequestParam String endTime,
HttpServletResponse response) {
LocalDate startDate = LocalDate.parse(startTime);
LocalDate endDate = LocalDate.parse(endTime);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate startDate = LocalDate.parse(startTime, formatter);
LocalDate endDate = LocalDate.parse(endTime, formatter);
caseAiChatService.getConversationExcel(startDate.atStartOfDay(), endDate.atTime(23, 59, 59), response);
}

View File

@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
@EnableConfigurationProperties({CaseAiProperties.class})
@Service
@Slf4j
@Slf4j(topic = "caseAiChatLogger")
public class AiAccessTokenServiceImpl implements IAiAccessTokenService {
private static final String ACCESS_TOKEN_CACHE_KEY = "case_ai_access_token";

View File

@@ -122,7 +122,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
conversationId = getOrCreateConversationId(caseAiChatDto, currentUser);
} catch (Exception e) {
log.error("获取会话ID失败", e);
errMessage(sseEmitter, SYS_ERR_MSG);
errMessage(sseEmitter, null, SYS_ERR_MSG);
sseEmitter.complete();
return sseEmitter;
}
@@ -132,6 +132,13 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
// 3. 构建请求参数
String userId = currentUser.getCode();
// 6. 用于收集对话数据的容器
AiChatConversationData conversationData = new AiChatConversationData();
conversationData.setQuery(caseAiChatDto.getQuery());
conversationData.setConversationId(conversationId);
conversationData.setUserId(userId);
String kId = caseAiProperties.getCaseKnowledgeId();
JSONObject chatParam = new JSONObject();
chatParam.put("userId", userId);
@@ -162,9 +169,18 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
String accessToken;
try {
accessToken = aiAccessTokenService.getAccessToken();
if (org.apache.commons.lang3.StringUtils.isBlank(accessToken)) {
errMessage(sseEmitter, conversationId, SYS_ERR_MSG);
sseEmitter.complete();
conversationData.appendAnswer(SYS_ERR_MSG);
elasticSearchIndexService.createData(conversationData);
return sseEmitter;
}
} catch (Exception e) {
log.error("获取access_token失败", e);
errMessage(sseEmitter, SYS_ERR_MSG);
errMessage(sseEmitter, conversationId, SYS_ERR_MSG);
conversationData.appendAnswer(SYS_ERR_MSG);
elasticSearchIndexService.createData(conversationData);
sseEmitter.complete();
return sseEmitter;
}
@@ -176,13 +192,6 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
RequestBody bodyRequestBody = RequestBody.create(chatParamStr, MediaType.parse("application/json"));
builder.post(bodyRequestBody);
Request request = builder.build();
// 6. 用于收集对话数据的容器
AiChatConversationData conversationData = new AiChatConversationData();
conversationData.setQuery(caseAiChatDto.getQuery());
conversationData.setConversationId(conversationId);
conversationData.setUserId(userId);
// 7. 创建事件监听器
EventSourceListener listener = new EventSourceListener() {
@@ -236,7 +245,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
} else {
// 异常问题取message内容
String message = jsonData.getString("message");
errMessage(sseEmitter, message);
errMessage(sseEmitter, conversationId, message);
return;
}
}
@@ -265,12 +274,13 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
log.error("调用接口 [{}] 接口异常", request.url(), e);
if (isTimeoutException(e)) {
log.warn("接口调用超时conversationId: {}", conversationId);
errMessage(sseEmitter, SYS_ERR_MSG);
errMessage(sseEmitter, conversationId, SYS_ERR_MSG);
sseEmitter.complete();
// 从Map中移除失败的会话
conversationEventSourceMap.remove(conversationId);
// 即使失败也要将已有的对话数据保存到ES
conversationData.appendAnswer(SYS_ERR_MSG);
elasticSearchIndexService.createData(conversationData);
return;
}
@@ -282,16 +292,17 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
// 从Map中移除失败的会话
conversationEventSourceMap.remove(conversationId);
// 即使失败也要将已有的对话数据保存到ES
conversationData.appendAnswer(SYS_ERR_MSG);
elasticSearchIndexService.createData(conversationData);
return;
}
sseEmitter.completeWithError(e);
// 从Map中移除失败的会话
conversationEventSourceMap.remove(conversationId);
// 即使失败也要将已有的对话数据保存到ES
elasticSearchIndexService.createData(conversationData);
sseEmitter.completeWithError(e);
}
};
@@ -663,7 +674,7 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
// 将响应内容原封不动地推送到 SseEmitter
JSONObject responseData = JSONObject.parseObject(responseBody);
if (responseBody.contains("message")) {
errMessage(sseEmitter, responseData.getString("message"));
errMessage(sseEmitter, conversationData.getConversationId(), responseData.getString("message"));
sseEmitter.complete();
return;
}
@@ -679,12 +690,23 @@ public class CaseAiChatServiceImpl implements ICaseAiChatService {
}
}
private void errMessage(SseEmitter sseEmitter, String message) {
private void errMessage(SseEmitter sseEmitter, String conversationId, String message) {
JSONObject conversationData = new JSONObject();
conversationData.put("conversationId", conversationId);
conversationData.put("content", "");
conversationData.put("status", 0);
JSONObject jsonData = new JSONObject();
jsonData.put("status", 1);
jsonData.put("content", message);
JSONObject finishData = new JSONObject();
jsonData.put("status", 4);
jsonData.put("content", "");
try {
sseEmitter.send(conversationData.toJSONString());
sseEmitter.send(jsonData.toJSONString());
sseEmitter.send(finishData.toJSONString());
} catch (IOException e) {
log.error("发送错误信息异常", e);
sseEmitter.completeWithError(e);

View File

@@ -216,7 +216,7 @@ public class ElasticSearchIndexServiceImpl implements IElasticSearchIndexService
messageVo.setStartTime(LocalDateTime.parse(startTimeStr));
}
if (sourceMap.containsKey("durationSeconds")) {
messageVo.setDurationSeconds((Long) sourceMap.get("durationSeconds"));
messageVo.setDurationSeconds((Integer) sourceMap.get("durationSeconds"));
}
// 解析 suggestions

View File

@@ -29,7 +29,7 @@ public class CaseAiMessageVo {
/**
* 会话时长(秒)
*/
private Long durationSeconds;
private Integer durationSeconds;
/**
* 案例引用列表

View File

@@ -31,20 +31,16 @@
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<appender name="caseAiChat"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<File>${log.path}/caseAiChat.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.path}/caseAiChat.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
</appender>
<!-- Log file error output -->

View File

@@ -47,20 +47,16 @@
</filter>
</appender>
<!-- Log file error output -->
<appender name="caseAiChat" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/caseAiChat.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/caseAiChat.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<appender name="caseAiChat"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<File>${log.path}/caseAiChat.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.path}/caseAiChat.%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->