diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseKnowledgeServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseKnowledgeServiceImpl.java index 7af1c6f0..28f212d1 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseKnowledgeServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/boecase/service/impl/CaseKnowledgeServiceImpl.java @@ -8,6 +8,7 @@ import com.xboe.common.OrderCondition; import com.xboe.core.orm.FieldFilters; import com.xboe.enums.CaseDocumentLogCaseStatusEnum; import com.xboe.enums.CaseDocumentLogOptStatusEnum; +import com.xboe.enums.CaseDocumentLogOptTypeEnum; import com.xboe.module.boecase.dao.CaseDocumentLogDao; import com.xboe.module.boecase.dao.CasesDao; import com.xboe.module.boecase.entity.CaseDocumentLog; @@ -110,6 +111,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { // 5. 重试逻辑:最多3次机会 int maxRetries = 3; + JSONObject requestBody = new JSONObject(); for (int attempt = 1; attempt <= maxRetries; attempt++) { log.info("上传案例文档第{}次尝试,caseId: {}", attempt, caseId); @@ -122,11 +124,17 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.addBinaryBody("file", file); builder.addTextBody("userId", userId, ContentType.TEXT_PLAIN); + requestBody.put("userId", userId); builder.addTextBody("kId", caseAiProperties.getCaseKnowledgeId(), ContentType.TEXT_PLAIN); + requestBody.put("kId", caseAiProperties.getCaseKnowledgeId()); builder.addTextBody("fileName", fileName, ContentType.TEXT_PLAIN); + requestBody.put("fileName", fileName); builder.addTextBody("fileType", fileType, ContentType.TEXT_PLAIN); + requestBody.put("fileType", fileType); builder.addTextBody("parseType", "AUTO", ContentType.TEXT_PLAIN); + requestBody.put("parseType", "AUTO"); builder.addTextBody("callbackUrl", caseAiProperties.getFileUploadCallbackUrl(), ContentType.TEXT_PLAIN); + requestBody.put("callbackUrl", caseAiProperties.getFileUploadCallbackUrl()); HttpEntity multipart = builder.build(); httpPost.setEntity(multipart); @@ -143,16 +151,16 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { String taskId = data.getString("taskId"); // 保存成功的CaseDocumentLog记录 - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "create", uploadUrl, - "上传案例文档", responseBody, CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.SUCCESS.getCode(), taskId); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.CREATE.getCode(), uploadUrl, + requestBody.toJSONString(), responseBody, CaseDocumentLogOptStatusEnum.CALLING.getCode(), CaseDocumentLogCaseStatusEnum.SUCCESS.getCode(), taskId); log.info("上传案例文档成功,caseId: {}, taskId: {}, 尝试次数: {}", caseId, taskId, attempt); return true; } else { // 业务处理失败,不重试 log.error("上传案例文档业务处理失败,不重试,response: {}", responseBody); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "create", uploadUrl, - "上传案例文档", responseBody, CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.CREATE.getCode(), uploadUrl, + requestBody.toJSONString(), responseBody, CaseDocumentLogOptStatusEnum.CALLING.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } } else { @@ -160,8 +168,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { log.warn("上传案例文档接口调用失败,第{}次尝试,status: {}, response: {}", attempt, statusCode, responseBody); if (attempt == maxRetries) { // 最后一次尝试仍然失败 - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "create", uploadUrl, - "上传案例文档", responseBody, CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.CREATE.getCode(), uploadUrl, + requestBody.toJSONString(), responseBody, CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } // 继续下一次重试 @@ -173,8 +181,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { if (attempt == maxRetries) { // 最后一次尝试仍然异常 log.error("上传案例文档最终失败,已重试{}次", maxRetries); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "create", uploadUrl, - "上传案例文档", "接口调用异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.CREATE.getCode(), uploadUrl, + requestBody.toJSONString(), "接口调用异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } // 继续下一次重试 @@ -229,11 +237,11 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { int maxRetries = 3; for (int attempt = 1; attempt <= maxRetries; attempt++) { log.info("删除案例文档第{}次尝试,caseId: {}, taskId: {}", attempt, caseId, taskId); - + + // 构建请求参数 + String params = "kId=" + caseAiProperties.getCaseKnowledgeId() + + "&taskIds=" + taskId; try (CloseableHttpClient httpClient = HttpClients.createDefault()) { - // 构建请求参数 - String params = "kId=" + URLEncoder.encode(caseAiProperties.getCaseKnowledgeId(), StandardCharsets.UTF_8.name()) + - "&taskIds=" + URLEncoder.encode(taskId, StandardCharsets.UTF_8.name()); HttpDelete httpDelete = new HttpDelete(deleteUrl + "?" + params); httpDelete.setHeader("X-AI-ApiCode", caseAiProperties.getAiApiCode()); httpDelete.setHeader("access_token", accessToken); @@ -259,8 +267,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { int caseStatus = (deleteSuccess != null && deleteSuccess) ? CaseDocumentLogCaseStatusEnum.SUCCESS.getCode() : CaseDocumentLogCaseStatusEnum.FAILED.getCode(); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "delete", deleteUrl, - "删除案例文档", responseBody, optStatus, caseStatus, null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.DELETE.getCode(), deleteUrl, + params, responseBody, optStatus, caseStatus, null); if (deleteSuccess != null && deleteSuccess) { log.info("删除案例文档成功,caseId: {}, taskId: {}, 尝试次数: {}", caseId, taskId, attempt); @@ -273,8 +281,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { } else { // 业务处理失败,不重试 log.error("删除案例文档业务处理失败,不重试,response: {}", responseBody); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "delete", deleteUrl, - "删除案例文档", responseBody, CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.DELETE.getCode(), deleteUrl, + params, responseBody, CaseDocumentLogOptStatusEnum.SUCCESS.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } } else { @@ -282,8 +290,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { log.warn("删除案例文档接口调用失败,第{}次尝试,status: {}, response: {}", attempt, statusCode, responseBody); if (attempt == maxRetries) { // 最后一次尝试仍然失败 - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "delete", deleteUrl, - "删除案例文档", responseBody, CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.DELETE.getCode(), deleteUrl, + params, responseBody, CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } // 继续下一次重试 @@ -295,8 +303,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { if (attempt == maxRetries) { // 最后一次尝试仍然异常 log.error("删除案例文档最终失败,已重试{}次", maxRetries); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "delete", deleteUrl, - "删除案例文档", "接口调用异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.DELETE.getCode(), deleteUrl, + params, "接口调用异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } // 继续下一次重试 @@ -326,23 +334,76 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { String accessToken = aiAccessTokenService.getAccessToken(); if (StringUtil.isBlank(accessToken)) { log.error("更新案例文档失败,获取access_token失败"); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "update", "", - "更新案例文档", "获取access_token失败", CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); +// saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), "", +// "更新案例文档", "获取access_token失败", CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } + // 1. 根据案例ID查询最新一条CaseDocumentLog数据 + List logList = caseDocumentLogDao.getGenericDao() + .findList(CaseDocumentLog.class, 1, + OrderCondition.desc("sysCreateTime"), + FieldFilters.eq("caseId", caseId)); + + if (logList.isEmpty()) { + log.warn("调用删除接口时未找到相关的日志记录,caseId: {}", caseId); + return false; + } + + CaseDocumentLog latestLog = logList.get(0); + String oldTaskId = latestLog.getTaskId(); + if (StringUtil.isBlank(oldTaskId)) { + log.warn("调用删除接口时日志记录中taskId为空,caseId: {}", caseId); + return false; + } + String requestBody = ""; + String requestUrl = ""; + try { // 2. 先调用删除接口 + String deleteParam = "kId=" + caseAiProperties.getCaseKnowledgeId() + "taskId=" + oldTaskId; + requestUrl = caseAiProperties.getBaseUrl() + "/apigateway/knowledge/v1/file/delete?" + deleteParam; + requestBody = deleteParam; boolean deleteSuccess = callDeleteInterface(caseId, caseEntity, accessToken); if (!deleteSuccess) { log.error("更新案例文档失败,删除接口调用失败,不继续执行上传操作,caseId: {}", caseId); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "update", "", - "更新案例文档", "删除接口:失败,上传接口:未执行", CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), requestUrl, + deleteParam, "删除接口:失败,上传接口:未执行", CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } // 3. 删除成功后,再调用上传接口 - String taskId = callUploadInterface(caseId, caseEntity, accessToken); + requestUrl = caseAiProperties.getBaseUrl() + "/apigateway/knowledge/v1/file/upload"; + // 1. 检查文件路径 + if (StringUtil.isBlank(caseEntity.getFilePath())) { + log.warn("调用上传接口失败,案例文件路径为空,caseId: {}", caseId); + return false; + } + + File file = new File(caseEntity.getFilePath()); + if (!file.exists()) { + log.warn("调用上传接口失败,案例文件不存在,filePath: {}", caseEntity.getFilePath()); + return false; + } + + // 2. 构建上传参数 + String fileName = caseEntity.getFileName(); + if (StringUtil.isBlank(fileName)) { + fileName = file.getName(); + } + + String fileType = getFileType(fileName); + String userId = getCurrentUserId(); + JSONObject uploadRequestBody = new JSONObject(); + uploadRequestBody.put("userId", userId); + uploadRequestBody.put("kId", caseAiProperties.getCaseKnowledgeId()); + uploadRequestBody.put("fileName", fileName); + uploadRequestBody.put("fileType", fileType); + uploadRequestBody.put("parseType", "AUTO"); + uploadRequestBody.put("callbackUrl", caseAiProperties.getFileUploadCallbackUrl()); + requestBody = uploadRequestBody.toJSONString(); + + String taskId = callUploadInterface(caseId, file, fileName, fileType, userId, accessToken, requestUrl); boolean uploadSuccess = StringUtil.isNotBlank(taskId); // 4. 根据结果保存一条CaseDocumentLog数据 @@ -350,9 +411,9 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { int caseStatus = uploadSuccess ? CaseDocumentLogCaseStatusEnum.SUCCESS.getCode() : CaseDocumentLogCaseStatusEnum.FAILED.getCode(); String result = String.format("删除接口:成功,上传接口:%s", uploadSuccess ? "成功" : "失败"); - - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "update", "", - "更新案例文档", result, optStatus, caseStatus, taskId); + + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), requestUrl, + requestBody, result, optStatus, caseStatus, taskId); if (uploadSuccess) { log.info("更新案例文档成功,caseId: {}, taskId: {}", caseId, taskId); @@ -364,8 +425,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { } catch (Exception e) { log.error("更新案例文档异常", e); - saveCaseDocumentLog(caseId, caseEntity.getTitle(), "update", "", - "更新案例文档", "更新异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); + saveCaseDocumentLog(caseId, caseEntity.getTitle(), CaseDocumentLogOptTypeEnum.UPDATE.getCode(), requestUrl, + requestBody, "更新异常: " + e.getMessage(), CaseDocumentLogOptStatusEnum.FAILED.getCode(), CaseDocumentLogCaseStatusEnum.FAILED.getCode(), null); return false; } } @@ -382,21 +443,22 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { return false; } - try { - // 1. 根据taskId查询最新一条CaseDocumentLog数据 - List logList = caseDocumentLogDao.getGenericDao() - .findList(CaseDocumentLog.class, 1, - OrderCondition.desc("sysCreateTime"), - FieldFilters.eq("taskId", taskId)); - - if (logList.isEmpty()) { - log.error("处理上传回调失败,未找到对应的日志记录,taskId: {}", taskId); - return false; - } + // 1. 根据taskId查询最新一条CaseDocumentLog数据 + List logList = caseDocumentLogDao.getGenericDao() + .findList(CaseDocumentLog.class, 1, + OrderCondition.desc("sysCreateTime"), + FieldFilters.eq("taskId", taskId)); - CaseDocumentLog latestLog = logList.get(0); - log.info("找到对应的日志记录,logId: {}, taskId: {}, 原状态 - optStatus: {}, caseStatus: {}", - latestLog.getId(), taskId, latestLog.getOptStatus(), latestLog.getCaseStatus()); + if (logList.isEmpty()) { + log.error("处理上传回调失败,未找到对应的日志记录,taskId: {}", taskId); + return false; + } + + CaseDocumentLog latestLog = logList.get(0); + log.info("找到对应的日志记录,logId: {}, taskId: {}, 原状态 - optStatus: {}, caseStatus: {}", + latestLog.getId(), taskId, latestLog.getOptStatus(), latestLog.getCaseStatus()); + + try { // 2. 根据fileStatus更新状态 int newOptStatus; @@ -420,7 +482,11 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { // 3. 更新日志记录状态 latestLog.setOptStatus(newOptStatus); latestLog.setCaseStatus(newCaseStatus); - latestLog.setResponseBody(StringUtil.isNotBlank(message) ? message : latestLog.getResponseBody()); + JSONObject callbackResponse = new JSONObject(); + callbackResponse.put("message", message); + callbackResponse.put("fileStatus", fileStatus); + callbackResponse.put("taskId", taskId); + latestLog.setResponseBody(callbackResponse.toJSONString()); latestLog.setSysUpdateTime(LocalDateTime.now()); caseDocumentLogDao.save(latestLog); @@ -431,7 +497,12 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { return true; } catch (Exception e) { - log.error("处理上传回调异常,taskId: {}", taskId, e); + log.error("上传回调异常,taskId: {}", taskId, e); + latestLog.setOptStatus(CaseDocumentLogOptStatusEnum.FAILED.getCode()); + latestLog.setSysUpdateTime(LocalDateTime.now()); + caseDocumentLogDao.save(latestLog); + log.info("更新日志记录成功,logId: {}, taskId: {}, 新状态 - optStatus: {}, caseStatus: {}", + latestLog.getId(), taskId, latestLog.getOptStatus(), latestLog.getCaseStatus()); return false; } } @@ -508,8 +579,8 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 构建请求参数 - String params = "kId=" + URLEncoder.encode(caseAiProperties.getCaseKnowledgeId(), StandardCharsets.UTF_8.name()) + - "&taskIds=" + URLEncoder.encode(taskId, StandardCharsets.UTF_8.name()); + String params = "kId=" + caseAiProperties.getCaseKnowledgeId() + + "&taskIds=" + taskId; HttpDelete httpDelete = new HttpDelete(deleteUrl + "?" + params); httpDelete.setHeader("X-AI-ApiCode", caseAiProperties.getAiApiCode()); httpDelete.setHeader("access_token", accessToken); @@ -570,29 +641,7 @@ public class CaseKnowledgeServiceImpl implements ICaseKnowledgeService { /** * 调用上传接口(仅调用接口,不记录日志) */ - private String callUploadInterface(String caseId, Cases caseEntity, String accessToken) { - // 1. 检查文件路径 - if (StringUtil.isBlank(caseEntity.getFilePath())) { - log.warn("调用上传接口失败,案例文件路径为空,caseId: {}", caseId); - return null; - } - - File file = new File(caseEntity.getFilePath()); - if (!file.exists()) { - log.warn("调用上传接口失败,案例文件不存在,filePath: {}", caseEntity.getFilePath()); - return null; - } - - // 2. 构建上传参数 - String fileName = caseEntity.getFileName(); - if (StringUtil.isBlank(fileName)) { - fileName = file.getName(); - } - - String fileType = getFileType(fileName); - String userId = getCurrentUserId(); - String uploadUrl = caseAiProperties.getBaseUrl() + "/apigateway/knowledge/v1/file/upload"; - + private String callUploadInterface(String caseId, File file, String fileName, String fileType, String userId, String accessToken, String uploadUrl) { // 3. 重试逻辑:最多3次机会 int maxRetries = 3; for (int attempt = 1; attempt <= maxRetries; attempt++) {