From 79eefb651f82c822fecff80d4baa3d2cb7342b3f Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Mon, 10 Nov 2025 15:10:59 +0800 Subject: [PATCH 01/16] =?UTF-8?q?update:=E8=A7=92=E8=89=B2=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=A1=B5=E9=9D=A2mcp=E5=9B=BE=E6=A0=87=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/views/roleConfig.vue | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/main/manager-web/src/views/roleConfig.vue b/main/manager-web/src/views/roleConfig.vue index bc561f94..a0f89503 100644 --- a/main/manager-web/src/views/roleConfig.vue +++ b/main/manager-web/src/views/roleConfig.vue @@ -105,7 +105,7 @@
功能名称: {{ func.name }}
- {{ func.name.charAt(0) }} + {{ getFunctionDisplayChar(func.name) }}
acc + char.charCodeAt(0), 0); return this.functionColorMap[hash % this.functionColorMap.length]; }, + getFunctionDisplayChar(name) { + if (!name || name.length === 0) return ''; + + for (let i = 0; i < name.length; i++) { + const char = name[i]; + if (/[\u4e00-\u9fa5a-zA-Z0-9]/.test(char)) { + return char; + } + } + + // 如果没有找到有效字符,返回第一个字符 + return name.charAt(0); + }, showFunctionIcons(type) { return type === 'Intent' && this.form.model.intentModelId !== 'Intent_nointent'; From 5bead86fd5d3b9f2f1ae0e637795ec1c91a5bfe9 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Mon, 10 Nov 2025 15:11:48 +0800 Subject: [PATCH 02/16] =?UTF-8?q?fix:=E7=9F=A5=E8=AF=86=E5=BA=93=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E5=A2=9E=E5=8A=A0=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/components/KnowledgeBaseDialog.vue | 5 +++++ main/manager-web/src/i18n/en.js | 1 + 2 files changed, 6 insertions(+) diff --git a/main/manager-web/src/components/KnowledgeBaseDialog.vue b/main/manager-web/src/components/KnowledgeBaseDialog.vue index 99d01341..a9ce84b5 100644 --- a/main/manager-web/src/components/KnowledgeBaseDialog.vue +++ b/main/manager-web/src/components/KnowledgeBaseDialog.vue @@ -72,6 +72,11 @@ export default { } ], description: [ + { + required: true, + message: this.$t("knowledgeBaseDialog.descriptionRequired"), + trigger: "blur" + }, { max: 200, message: this.$t("knowledgeBaseDialog.descriptionLength"), diff --git a/main/manager-web/src/i18n/en.js b/main/manager-web/src/i18n/en.js index 4cec8051..77a6d9e0 100644 --- a/main/manager-web/src/i18n/en.js +++ b/main/manager-web/src/i18n/en.js @@ -1259,4 +1259,5 @@ export default { 'knowledgeFileUpload.comprehensiveSimilarity': 'Comprehensive Similarity', 'knowledgeFileUpload.content': 'Content:', 'knowledgeFileUpload.testQuestionRequired': 'Please enter test question', + 'knowledgeBaseDialog.descriptionRequired': 'Please enter knowledge base description', } \ No newline at end of file From ee0d89d8d2e1bae6de4eec1bcd314c46274e1eeb Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Mon, 10 Nov 2025 15:14:32 +0800 Subject: [PATCH 03/16] =?UTF-8?q?fix:=E7=9F=A5=E8=AF=86=E5=BA=93=E3=80=90?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E3=80=91=E3=80=90=E5=88=A0=E9=99=A4=E3=80=91?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E9=80=BB=E8=BE=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/KnowledgeBaseServiceImpl.java | 92 ++++++++++++++----- main/manager-web/src/i18n/zh_CN.js | 1 + main/manager-web/src/i18n/zh_TW.js | 1 + .../src/views/KnowledgeBaseManagement.vue | 37 ++++++-- 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java index 56a404dc..b2b75f48 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java @@ -51,6 +51,7 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl ragConfig = getValidatedRAGConfig(knowledgeBaseDTO.getRagModelId()); + + // 调用RAGFlow API更新数据集 + updateDatasetInRAGFlow( + knowledgeBaseDTO.getDatasetId(), + knowledgeBaseDTO.getName(), + knowledgeBaseDTO.getDescription(), + ragConfig); + + log.info("RAGFlow API更新成功,datasetId: {}", knowledgeBaseDTO.getDatasetId()); + } else { + log.warn("datasetId或ragModelId为空,跳过RAGFlow更新"); + } + KnowledgeBaseEntity entity = ConvertUtils.sourceToTarget(knowledgeBaseDTO, KnowledgeBaseEntity.class); knowledgeBaseDao.updateById(entity); @@ -209,22 +229,6 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl ragConfig = getValidatedRAGConfig(knowledgeBaseDTO.getRagModelId()); - updateDatasetInRAGFlow( - knowledgeBaseDTO.getDatasetId(), - knowledgeBaseDTO.getName(), - knowledgeBaseDTO.getDescription(), - ragConfig); - } catch (Exception e) { - // 如果RAG API调用失败,回滚本地数据库操作 - knowledgeBaseDao.updateById(existingEntity); - throw e; - } - } - return ConvertUtils.sourceToTarget(entity, KnowledgeBaseDTO.class); } @@ -265,22 +269,29 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl 0 ? "成功" : "失败"); - - // 调用RAGFlow API删除数据集 + // 先调用RAGFlow API删除数据集 + boolean apiDeleteSuccess = false; if (StringUtils.isNotBlank(entity.getDatasetId()) && StringUtils.isNotBlank(entity.getRagModelId())) { try { log.info("开始调用RAGFlow API删除数据集"); + // 在删除前进行RAG配置校验 Map ragConfig = getValidatedRAGConfig(entity.getRagModelId()); deleteDatasetInRAGFlow(entity.getDatasetId(), ragConfig); log.info("RAGFlow API删除调用完成"); + apiDeleteSuccess = true; } catch (Exception e) { - log.warn("删除RAGFlow数据集失败: {}", e.getMessage()); + log.error("删除RAGFlow数据集失败: {}", e.getMessage()); + throw new RenException(ErrorCode.RAG_API_ERROR, "删除RAGFlow数据集失败: " + e.getMessage()); } } else { log.warn("datasetId或ragModelId为空,跳过RAGFlow删除"); + apiDeleteSuccess = true; // 没有RAG数据集,视为成功 + } + + // API删除成功后再删除本地记录 + if (apiDeleteSuccess) { + int deleteCount = knowledgeBaseDao.deleteById(entity.getId()); + log.info("本地数据库删除结果: {}", deleteCount > 0 ? "成功" : "失败"); } log.info("=== 通过datasetId删除操作结束 ==="); @@ -513,6 +524,24 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl responseMap = objectMapper.readValue(responseBody, Map.class); + Integer code = (Integer) responseMap.get("code"); + String message = (String) responseMap.get("message"); + + if (code != null && code != 0) { + log.error("RAGFlow API调用失败,响应码: {}, 消息: {}", code, message); + throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败: " + message); + } + } catch (Exception e) { + log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); + throw new RenException(ErrorCode.RAG_API_ERROR, "解析响应失败: " + e.getMessage()); + } + } + log.info("RAGFlow数据集更新成功,datasetId: {}", datasetId); } @@ -555,6 +584,25 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl responseMap = objectMapper.readValue(responseBody, Map.class); + Integer code = (Integer) responseMap.get("code"); + String message = (String) responseMap.get("message"); + + if (code != null && code != 0) { + log.error("RAGFlow API调用失败,响应码: {}, 消息: {}", code, message); + throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败: " + message); + } + } catch (Exception e) { + log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); + throw new RenException(ErrorCode.RAG_API_ERROR, "解析响应失败: " + e.getMessage()); + } + } + log.info("RAGFlow数据集删除成功,datasetId: {}", datasetId); } diff --git a/main/manager-web/src/i18n/zh_CN.js b/main/manager-web/src/i18n/zh_CN.js index 3986e858..cc2654c9 100644 --- a/main/manager-web/src/i18n/zh_CN.js +++ b/main/manager-web/src/i18n/zh_CN.js @@ -1259,4 +1259,5 @@ export default { 'knowledgeFileUpload.comprehensiveSimilarity': '综合相似度', 'knowledgeFileUpload.content': '内容:', 'knowledgeFileUpload.testQuestionRequired': '请输入测试问题', + 'knowledgeBaseDialog.descriptionRequired': '请输入知识库描述', } \ No newline at end of file diff --git a/main/manager-web/src/i18n/zh_TW.js b/main/manager-web/src/i18n/zh_TW.js index af8872d8..984c51d1 100644 --- a/main/manager-web/src/i18n/zh_TW.js +++ b/main/manager-web/src/i18n/zh_TW.js @@ -1258,4 +1258,5 @@ export default { 'knowledgeFileUpload.comprehensiveSimilarity': '綜合相似度', 'knowledgeFileUpload.content': '內容:', 'knowledgeFileUpload.testQuestionRequired': '請輸入測試問題', + 'knowledgeBaseDialog.descriptionRequired': '請輸入知识库描述', } \ No newline at end of file diff --git a/main/manager-web/src/views/KnowledgeBaseManagement.vue b/main/manager-web/src/views/KnowledgeBaseManagement.vue index 13707357..a672e324 100644 --- a/main/manager-web/src/views/KnowledgeBaseManagement.vue +++ b/main/manager-web/src/views/KnowledgeBaseManagement.vue @@ -273,11 +273,9 @@ export default { handleSubmit: function(form) { console.log('handleSubmit called with form:', form); if (form.id) { - // 编辑 - 使用dataset_id作为路径参数,form作为请求体 console.log('Editing knowledge base:', form.datasetId); Api.knowledgeBase.updateKnowledgeBase(form.datasetId, form, (res) => { console.log('Update response:', res); - // 修复:检查 res.data.code 而不是 res.code if (res.data && res.data.code === 0) { this.dialogVisible = false; this.fetchKnowledgeBaseList(); @@ -285,8 +283,15 @@ export default { } else { this.$message.error(res.data?.msg || this.$t('knowledgeBaseManagement.updateFailed')); } - }, () => { - this.$message.error(this.$t('knowledgeBaseManagement.updateFailed')); + }, (err) => { + console.log('Error callback received:', err); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + console.log('后端返回错误消息:', err.data.msg || err.msg); + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeBaseManagement.updateFailed')); + } else { + this.$message.error(this.$t('knowledgeBaseManagement.updateFailed')); + } }); } else { // 新增 - 只传递必要的字段,不传递id @@ -303,6 +308,8 @@ export default { this.dialogVisible = false; this.fetchKnowledgeBaseList(); this.$message.success(this.$t('knowledgeBaseManagement.addSuccess')); + } else { + this.$message.error(res.data?.msg || this.$t('knowledgeBaseManagement.addFailed')); } }, (err) => { console.log('Error callback received:', err); @@ -338,8 +345,15 @@ export default { } else { this.$message.error(res.data?.msg || this.$t('knowledgeBaseManagement.deleteFailed')); } - }, () => { - this.$message.error(this.$t('knowledgeBaseManagement.deleteFailed')); + }, (err) => { + console.log('Error callback received:', err); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + console.log('后端返回错误消息:', err.data.msg || err.msg); + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeBaseManagement.deleteFailed')); + } else { + this.$message.error(this.$t('knowledgeBaseManagement.deleteFailed')); + } }); }).catch(() => { this.$message({ @@ -365,8 +379,15 @@ export default { } else { this.$message.error(res.data?.msg || this.$t('knowledgeBaseManagement.deleteFailed')); } - }, () => { - this.$message.error(this.$t('knowledgeBaseManagement.deleteFailed')); + }, (err) => { + console.log('Error callback received:', err); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + console.log('后端返回错误消息:', err.data.msg || err.msg); + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeBaseManagement.deleteFailed')); + } else { + this.$message.error(this.$t('knowledgeBaseManagement.deleteFailed')); + } }); }).catch(() => { this.$message({ From ab5e91c07b9816220eb5cfa3f8c0ab5263907b9b Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Mon, 10 Nov 2025 18:41:03 +0800 Subject: [PATCH 04/16] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E5=BA=93=E9=A1=B5=E9=9D=A2=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/KnowledgeBaseServiceImpl.java | 57 +++++++++++++------ .../main/resources/i18n/messages.properties | 2 +- .../resources/i18n/messages_en_US.properties | 2 +- .../resources/i18n/messages_zh_CN.properties | 2 +- .../resources/i18n/messages_zh_TW.properties | 2 +- .../src/views/KnowledgeFileUpload.vue | 8 ++- 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java index b2b75f48..7d37fe4a 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java @@ -281,7 +281,7 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl { this.loading = false; - this.$message.error(this.$t('knowledgeFileUpload.getListFailed')); + console.log('Error callback received:', err); + if (err && err.data) { + console.log('后端返回错误消息:', err.data.msg || err.msg); + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeFileUpload.getListFailed')); + } else { + this.$message.error(this.$t('knowledgeFileUpload.getListFailed')); + } console.error('获取文档列表失败:', err); this.fileList = []; this.total = 0; From 96da84dad4adb8186eecf6f86a9fbe6483936bfe Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Tue, 11 Nov 2025 16:02:46 +0800 Subject: [PATCH 05/16] =?UTF-8?q?fix:=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xiaozhi/common/exception/ErrorCode.java | 2 +- .../impl/KnowledgeFilesServiceImpl.java | 295 +++++++----------- .../main/resources/i18n/messages.properties | 2 +- .../resources/i18n/messages_en_US.properties | 2 +- .../resources/i18n/messages_zh_CN.properties | 2 +- .../resources/i18n/messages_zh_TW.properties | 2 +- .../src/views/KnowledgeFileUpload.vue | 49 ++- 7 files changed, 167 insertions(+), 187 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java index b8525e63..268df223 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java +++ b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java @@ -205,7 +205,7 @@ public interface ErrorCode { int RAG_CONFIG_NOT_FOUND = 10164; // RAG配置未找到 int RAG_CONFIG_TYPE_ERROR = 10165; // RAG配置类型错误 int RAG_DEFAULT_CONFIG_NOT_FOUND = 10166; // 默认RAG配置未找到 - int RAG_API_ERROR = 10167; // RAG配置缺少必要参数 + int RAG_API_ERROR = 10167; // RAG调用失败 int UPLOAD_FILE_ERROR = 10168; // 上传文件失败 int NO_PERMISSION = 10169; // 没有权限 int KNOWLEDGE_BASE_NAME_EXISTS = 10170; // 同名知识库已存在 diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java index 458ef063..3608399b 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java @@ -16,15 +16,11 @@ import org.springframework.core.io.AbstractResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; -import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; @@ -112,8 +108,8 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR); + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode()); } String responseBody = response.getBody(); @@ -127,27 +123,20 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { Object dataObj = responseMap.get("data"); return parseDocumentListResponse(dataObj, page, limit); } else { - log.error("RAGFlow API调用失败,响应码: {}, 响应内容: {}", code, responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,响应码: " + code); + log.error("RAGFlow API调用失败,响应码: {}", code); + // 获取错误消息,如果存在的话 + String apiMessage = (String) responseMap.get("message"); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } - } catch (IOException e) { - log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { log.error("获取文档列表失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取文档列表失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 获取文档列表操作结束 ==="); } @@ -480,8 +469,11 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR); + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + String responseBody = response.getBody(); + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + + ", 响应内容: " + (responseBody != null ? responseBody : "无响应内容")); } String responseBody = response.getBody(); @@ -502,32 +494,20 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { } throw new RenException(ErrorCode.Knowledge_Base_RECORD_NOT_EXISTS); } else { - log.error("RAGFlow API调用失败,响应码: {}, 响应内容: {}", code, responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,响应码: " + code); + log.error("RAGFlow API调用失败,响应码: {}", code); + // 获取错误消息,如果存在的话 + String apiMessage = (String) responseMap.get("message"); + String errorDetail = apiMessage != null ? apiMessage : "无详细错误信息"; + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } - } catch (IOException e) { - log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - if (e.getStatusCode() == HttpStatus.NOT_FOUND) { - log.warn("文档不存在,documentId: {}, datasetId: {}", documentId, datasetId); - throw new RenException(ErrorCode.Knowledge_Base_RECORD_NOT_EXISTS); - } - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString()); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString()); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { log.error("根据documentId获取文档失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取文档失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 根据documentId获取文档操作结束 ==="); } @@ -583,8 +563,8 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR); + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode()); } String responseBody = response.getBody(); @@ -615,25 +595,10 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { datasetId, status, pageData.getList().size()); return pageData; } else { - log.error("RAGFlow API调用失败,响应码: {}, 响应内容: {}", code, responseBody); + log.error("RAGFlow API调用失败,响应码: {}", code); throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,响应码: " + code); } - } catch (IOException e) { - log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString()); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString()); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "获取RAGFlow文档列表失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { log.error("根据状态查询文档列表失败: {}", e.getMessage(), e); throw new RenException(ErrorCode.RAG_API_ERROR, "查询文档列表失败: " + e.getMessage()); @@ -722,7 +687,11 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { } catch (Exception e) { log.error("删除文档失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "删除文档失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 根据documentId删除文档操作结束 ==="); } @@ -842,7 +811,7 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { // 验证base_url是否存在且非空 if (StringUtils.isBlank(baseUrl)) { - throw new RenException(ErrorCode.RAG_API_ERROR); + throw new RenException(ErrorCode.RAG_API_ERROR, "RAG配置缺少必要参数: base_url"); } } @@ -939,44 +908,40 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("文档上传成功,documentId: {}", documentId); } else { // 如果响应码不为0,说明API调用失败 - log.error("RAGFlow API调用失败,响应码: {}, 响应内容: {}", code, responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败,响应码: " + code); + log.error("RAGFlow API调用失败,响应码: {}", code); + // 获取错误消息,如果存在的话 + String apiMessage = (String) responseMap.get("message"); + String errorDetail = apiMessage != null ? apiMessage : "无详细错误信息"; + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } log.info("从RAGFlow API响应中解析出documentId: {}", documentId); log.debug("完整响应内容: {}", responseBody); } catch (Exception e) { - log.error("解析RAGFlow API响应失败: {}, 响应内容: {}", e.getMessage(), responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow响应失败: " + e.getMessage()); + log.error("解析RAGFlow API响应失败: {}", e.getMessage()); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } } else { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR); + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + + ", 响应内容: " + (responseBody != null ? responseBody : "无响应内容")); } if (StringUtils.isBlank(documentId)) { - log.error("无法从RAGFlow API响应中获取documentId,响应内容: {}", responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API响应中未包含documentId"); + log.error("无法从RAGFlow API响应中获取documentId"); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } log.info("RAGFlow文档上传成功,documentId: {},文档已开始自动解析切片", documentId); return documentId; - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "上传RAGFlow文档失败: " + e.getMessage() + ", 响应: " + e.getResponseBodyAsString()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "上传RAGFlow文档失败: " + e.getMessage() + ", 响应: " + e.getResponseBodyAsString()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "上传RAGFlow文档失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { - log.error("RAGFlow API调用失败 - 未知错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "上传RAGFlow文档失败: " + e.getMessage()); + log.error("RAGFlow API调用失败: {}", e.getMessage(), e); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } } @@ -1093,8 +1058,9 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { return; } else { String message = (String) responseMap.get("message"); - log.error("RAGFlow API调用失败,响应码: {}, 消息: {}", code, message); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败: " + message); + log.error("RAGFlow API调用失败,响应码: {}", code); + String errorDetail = message != null ? message : "无详细错误信息"; + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } } catch (Exception e) { log.warn("解析RAGFlow响应失败,但HTTP状态码成功,视为删除成功: {}", e.getMessage()); @@ -1106,26 +1072,19 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { return; } } else { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR); + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + + ", 响应内容: " + (responseBody != null ? responseBody : "无响应内容")); } - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "删除RAGFlow文档失败: " + e.getMessage() + ", 响应: " + e.getResponseBodyAsString()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, - "删除RAGFlow文档失败: " + e.getMessage() + ", 响应: " + e.getResponseBodyAsString()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "删除RAGFlow文档失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { - log.error("RAGFlow API调用失败 - 未知错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "删除RAGFlow文档失败: " + e.getMessage()); + log.error("RAGFlow API调用失败: {}", e.getMessage(), e); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } } @@ -1204,14 +1163,16 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); - if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR); - } - String responseBody = response.getBody(); log.debug("RAGFlow API响应内容: {}", responseBody); + if (!response.getStatusCode().is2xxSuccessful()) { + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + String errorDetail = responseBody != null ? responseBody : "无响应内容"; + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + ", 响应内容: " + errorDetail); + } + // 解析响应 Map responseMap = objectMapper.readValue(responseBody, Map.class); Integer code = (Integer) responseMap.get("code"); @@ -1220,28 +1181,20 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("文档解析成功,datasetId: {}, documentIds: {}", datasetId, documentIds); return true; } else { + // 获取错误消息,如果存在的话 String message = (String) responseMap.get("message"); - log.error("RAGFlow API调用失败,响应码: {}, 消息: {}, 响应内容: {}", code, message, responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, response.getStatusCode().toString()); + String errorDetail = message != null ? message : "无详细错误信息"; + log.error("RAGFlow API调用失败,响应码: {}, 错误信息: {}", code, errorDetail); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } - } catch (IOException e) { - log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow文档失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow文档失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow文档失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { log.error("解析文档失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析文档失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 解析文档操作结束 ==="); } @@ -1308,14 +1261,16 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); - if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR, "列出切片失败"); - } - String responseBody = response.getBody(); log.debug("RAGFlow API响应内容: {}", responseBody); + if (!response.getStatusCode().is2xxSuccessful()) { + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + String errorDetail = responseBody != null ? responseBody : "无响应内容"; + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + ", 响应内容: " + errorDetail); + } + // 解析响应 Map responseMap = objectMapper.readValue(responseBody, Map.class); Integer code = (Integer) responseMap.get("code"); @@ -1326,28 +1281,24 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { // 解析切片数据并格式化返回 return parseChunkListResponse(responseMap); } else { + // 获取错误消息,如果存在的话 String message = (String) responseMap.get("message"); - log.error("RAGFlow API调用失败,响应码: {}, 消息: {}, 响应内容: {}", code, message, responseBody); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败: " + message); + String errorDetail = message != null ? message : "无详细错误信息"; + log.error("RAGFlow API调用失败,响应码: {}, 错误信息: {}", code, errorDetail); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } } catch (IOException e) { log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "列出切片失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "列出切片失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "列出切片失败: 网络连接错误 - " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } catch (Exception e) { log.error("列出切片失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "列出切片失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 列出切片操作结束 ==="); } @@ -1736,14 +1687,16 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); - if (!response.getStatusCode().is2xxSuccessful()) { - log.error("RAGFlow API调用失败,状态码: {}, 响应内容: {}", response.getStatusCode(), response.getBody()); - throw new RenException(ErrorCode.RAG_API_ERROR); - } - String responseBody = response.getBody(); log.debug("RAGFlow API响应内容: {}", responseBody); + if (!response.getStatusCode().is2xxSuccessful()) { + log.error("RAGFlow API调用失败,状态码: {}", response.getStatusCode()); + String errorDetail = responseBody != null ? responseBody : "无响应内容"; + throw new RenException(ErrorCode.RAG_API_ERROR, + "RAGFlow API调用失败,HTTP状态码: " + response.getStatusCode() + ", 响应内容: " + errorDetail); + } + // 解析响应 Map responseMap = objectMapper.readValue(responseBody, Map.class); Integer code = (Integer) responseMap.get("code"); @@ -1755,32 +1708,24 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.info("召回测试成功,返回 {} 条切片", result.get("total")); return result; } else { - log.error("RAGFlow API响应格式错误,data字段不是Map类型: {}", dataObj); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API响应格式错误"); + log.error("RAGFlow API响应格式错误,data字段不是Map类型"); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } } else { + // 获取错误消息,如果存在的话 String message = (String) responseMap.get("message"); - log.error("RAGFlow API调用失败,响应码: {}, 错误信息: {}", code, message); - throw new RenException(ErrorCode.RAG_API_ERROR, "RAGFlow API调用失败: " + message); + String errorDetail = message != null ? message : "无详细错误信息"; + log.error("RAGFlow API调用失败,响应码: {}, 错误信息: {}", code, errorDetail); + throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } - } catch (IOException e) { - log.error("解析RAGFlow API响应失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "解析RAGFlow响应失败: " + e.getMessage()); - } catch (HttpClientErrorException e) { - log.error("RAGFlow API调用失败 - HTTP错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "召回测试失败: " + e.getMessage()); - } catch (HttpServerErrorException e) { - log.error("RAGFlow API调用失败 - 服务器错误: {}, 状态码: {}, 响应内容: {}", - e.getMessage(), e.getStatusCode(), e.getResponseBodyAsString(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "召回测试失败: " + e.getMessage()); - } catch (ResourceAccessException e) { - log.error("RAGFlow API调用失败 - 网络连接错误: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "召回测试失败: 网络连接错误 - " + e.getMessage()); } catch (Exception e) { log.error("召回测试失败: {}", e.getMessage(), e); - throw new RenException(ErrorCode.RAG_API_ERROR, "召回测试失败: " + e.getMessage()); + String errorMessage = e.getMessage() != null ? e.getMessage() : "未知错误"; + if (e instanceof RenException) { + throw (RenException) e; + } + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); } finally { log.info("=== 召回测试操作结束 ==="); } diff --git a/main/manager-api/src/main/resources/i18n/messages.properties b/main/manager-api/src/main/resources/i18n/messages.properties index f927e7f7..ebde5cdf 100644 --- a/main/manager-api/src/main/resources/i18n/messages.properties +++ b/main/manager-api/src/main/resources/i18n/messages.properties @@ -173,7 +173,7 @@ 10164=RAG\u914D\u7F6E\u672A\u627E\u5230 10165=RAG\u914D\u7F6E\u7C7B\u578B\u9519\u8BEF 10166=\u9ED8\u8BA4RAG\u914D\u7F6E\u672A\u627E\u5230 -10167=RAG\u914d\u7f6e\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570\uFF0C{0} +10167=\u0052\u0041\u0047\u8c03\u7528\u5931\u8d25\uFF0C{0} 10168=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25 10169=\u60A8\u6CA1\u6709\u6743\u9650\u64CD\u4F5C\u8BE5\u8BB0\u5F55 10170=\u77E5\u8BC6\u5E93\u540D\u79F0\u91CD\u590D \ No newline at end of file diff --git a/main/manager-api/src/main/resources/i18n/messages_en_US.properties b/main/manager-api/src/main/resources/i18n/messages_en_US.properties index 2d318dbc..74b29caa 100644 --- a/main/manager-api/src/main/resources/i18n/messages_en_US.properties +++ b/main/manager-api/src/main/resources/i18n/messages_en_US.properties @@ -173,7 +173,7 @@ 10164=RAG configuration not found 10165=RAG configuration type error 10166=Default RAG configuration not found -10167=RAG configuration missing necessary parameters: {0} +10167=RAG API call failed: {0} 10168=Upload file failed 10169=No permission to operate this knowledge base 10170=Knowledge base name already exists \ No newline at end of file diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties index 1a9a2a63..e319c922 100644 --- a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties +++ b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties @@ -173,7 +173,7 @@ 10164=RAG\u914D\u7F6E\u672A\u627E\u5230 10165=RAG\u914D\u7F6E\u7C7B\u578B\u9519\u8BEF 10166=\u9ED8\u8BA4RAG\u914D\u7F6E\u672A\u627E\u5230 -10167=RAG\u914d\u7f6e\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570\uFF0C{0} +10167=\u0052\u0041\u0047\u8c03\u7528\u5931\u8d25\uFF0C{0} 10168=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25 10169=\u60A8\u6CA1\u6709\u6743\u9650\u64CD\u4F5C\u8BE5\u8BB0\u5F55 10170=\u77E5\u8BC6\u5E93\u540D\u79F0\u91CD\u590D \ No newline at end of file diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties index 5b9465ec..026664f6 100644 --- a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties +++ b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties @@ -173,7 +173,7 @@ 10164=RAG\u914D\u7F6E\u672A\u627E\u5230 10165=RAG\u914D\u7F6E\u985E\u578B\u932F\u8AA4 10166=\u9810\u8A2DRAG\u914D\u7F6E\u672A\u627E\u5230 -10167=RAG\u914d\u7f6e\u6f0f\u5c11\u5fc5\u8981\u53c2\u6570\uFF0C{0} +10167=\u0052\u0041\u0047\u8abf\u7528\u5931\u6557\uFF0C{0} 10168=\u4E0A\u50B3\u6587\u4EF6\u5931\u6557 10169=\u60A8\u6C92\u6709\u6B0A\u9650\u64CD\u4F5C\u8A72\u8A18\u9304 10170=\u77E5\u8B58\u5EAB\u540D\u7A31\u91CD\u8907 diff --git a/main/manager-web/src/views/KnowledgeFileUpload.vue b/main/manager-web/src/views/KnowledgeFileUpload.vue index 134f7fd9..dec0da85 100644 --- a/main/manager-web/src/views/KnowledgeFileUpload.vue +++ b/main/manager-web/src/views/KnowledgeFileUpload.vue @@ -663,7 +663,12 @@ export default { } }, (err) => { - reject({ success: false, fileName: file.name, error: this.$t('knowledgeFileUpload.uploadFailed') }); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + reject({ success: false, fileName: file.name, error: err.data.msg || err.msg || this.$t('knowledgeFileUpload.uploadFailed') }); + } else { + reject({ success: false, fileName: file.name, error: this.$t('knowledgeFileUpload.uploadFailed') }); + } console.error('上传文档失败:', err); } ); @@ -724,7 +729,12 @@ export default { }, (err) => { this.uploading = false; - this.$message.error(this.$t('knowledgeFileUpload.uploadFailed')); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeFileUpload.uploadFailed')); + } else { + this.$message.error(this.$t('knowledgeFileUpload.uploadFailed')); + } console.error('上传文档失败:', err); } ); @@ -757,7 +767,12 @@ export default { } }, (err) => { - this.$message.error(this.$t('knowledgeFileUpload.parseFailed')); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeFileUpload.parseFailed')); + } else { + this.$message.error(this.$t('knowledgeFileUpload.parseFailed')); + } console.error('解析文档失败:', err); } ); @@ -790,7 +805,12 @@ export default { } }, (err) => { - this.$message.error(this.$t('knowledgeFileUpload.deleteFailed')); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + this.$message.error(err.data.msg || err.msg || this.$t('knowledgeFileUpload.deleteFailed')); + } else { + this.$message.error(this.$t('knowledgeFileUpload.deleteFailed')); + } console.error('删除文档失败:', err); } ); @@ -835,7 +855,12 @@ export default { } }, (err) => { - reject(this.$t('knowledgeFileUpload.deleteFailed')); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + reject(err.data.msg || err.msg || this.$t('knowledgeFileUpload.deleteFailed')); + } else { + reject(this.$t('knowledgeFileUpload.deleteFailed')); + } console.error('删除文档失败:', err); } ); @@ -944,7 +969,12 @@ export default { }, (err) => { this.sliceLoading = false; - this.$message.error('获取切片列表失败'); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + this.$message.error(err.data.msg || err.msg || '获取切片列表失败'); + } else { + this.$message.error('获取切片列表失败'); + } console.error('获取切片列表失败:', err); this.sliceList = []; this.sliceTotal = 0; @@ -1061,7 +1091,12 @@ export default { }, (err) => { this.retrievalTestLoading = false; - this.$message.error('召回测试失败'); + // 错误回调处理后端返回的错误信息 + if (err && err.data) { + this.$message.error(err.data.msg || err.msg || '召回测试失败'); + } else { + this.$message.error('召回测试失败'); + } console.error('召回测试失败:', err); } ); From de0eda1b6ca1be2431e8a112c79791aaa7cad4d3 Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Tue, 11 Nov 2025 18:47:25 +0800 Subject: [PATCH 06/16] =?UTF-8?q?update:=E5=A2=9E=E5=8A=A0ragflow=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=95=99=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- README_en.md | 3 +- docs/FAQ.md | 1 + docs/ragflow-integration.md | 255 +++++++++++++++++++++ docs/voiceprint-integration.md | 2 +- main/xiaozhi-server/docker-compose_all.yml | 2 +- 6 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 docs/ragflow-integration.md diff --git a/README.md b/README.md index fc41f2bd..bca5f9ee 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 本项目基于人机共生智能理论和技术研发智能终端软硬件体系
为开源智能硬件项目 xiaozhi-esp32提供后端服务
根据小智通信协议使用Python、Java、Vue实现
-支持MQTT+UDP协议、Websocket协议、MCP接入点、声纹识别 +支持MQTT+UDP协议、Websocket协议、MCP接入点、声纹识别、知识库

@@ -248,6 +248,7 @@ Websocket接口地址: wss://2662r3426b.vicp.fun/xiaozhi/v1/ | 视觉感知 | 支持多种VLLM(视觉大模型),实现多模态交互 | | 意图识别 | 支持LLM意图识别、Function Call函数调用,提供插件化意图处理机制 | | 记忆系统 | 支持本地短期记忆、mem0ai接口记忆,具备记忆总结功能 | +| 知识库 | 支持RAGFlow知识库,让大模型判断需要调度知识库后再回答 | | 工具调用 | 支持客户端IOT协议、客户MCP协议、服务端MCP协议、MCP接入点协议、自定义工具函数 | | 指令下发 | 依托MQTT协议,支持从智控台将MCP指令下发到ESP32设备 | | 管理后台 | 提供Web管理界面,支持用户管理、系统配置和设备管理;界面支持中文简体、中文繁体、英文显示 | diff --git a/README_en.md b/README_en.md index bc0ddea9..015f1054 100644 --- a/README_en.md +++ b/README_en.md @@ -6,7 +6,7 @@ This project is based on human-machine symbiotic intelligence theory and technology to develop intelligent terminal hardware and software systems
providing backend services for the open-source intelligent hardware project xiaozhi-esp32
Implemented using Python, Java, and Vue according to the Xiaozhi Communication Protocol
-Supports MCP endpoints and voiceprint recognition +Support for MQTT+UDP protocol, Websocket protocol, MCP access point, voiceprint recognition, and knowledge base

@@ -244,6 +244,7 @@ This project provides the following testing tools to help you verify the system | Visual Perception | Supports multiple VLLM(vision large models), implements multimodal interaction | | Intent Recognition | Supports LLM intent recognition, Function Call function calling, provides plugin-based intent processing mechanism | | Memory System | Supports local short-term memory, mem0ai interface memory, with memory summarization functionality | +| Knowledge Base | Supports RAGFlow knowledge base, enabling LLM to judge whether to schedule the knowledge base after receiving the user's question, and then answer the question | | Command Delivery | Supports MCP command delivery to ESP32 devices via MQTT protocol from Smart Console | | Tool Calling | Supports client IOT protocol, client MCP protocol, server MCP protocol, MCP endpoint protocol, custom tool functions | | Management Backend | Provides Web management interface, supports user management, system configuration and device management; Supports Simplified Chinese, Traditional Chinese and English display | diff --git a/docs/FAQ.md b/docs/FAQ.md index 1e237921..83df8c2c 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -79,6 +79,7 @@ VAD: 6、[MCP方法如何获取设备信息](./mcp-get-device-info.md)
7、[如何开启声纹识别](./voiceprint-integration.md)
8、[新闻插件源配置指南](./newsnow_plugin_config.md)
+9、[知识库ragflow集成指南](./ragflow-integration.md)
### 11、语音克隆、本地语音部署相关教程 1、[如何在智控台克隆音色](./huoshan-streamTTS-voice-cloning.md)
diff --git a/docs/ragflow-integration.md b/docs/ragflow-integration.md new file mode 100644 index 00000000..135c7de4 --- /dev/null +++ b/docs/ragflow-integration.md @@ -0,0 +1,255 @@ +# ragflow 集成指南 + +本教程主要是是两部分 + +- 一、如何部署ragflow +- 二、如何在智控台配置ragflow接口 + +如果您对ragflow很熟悉,且已经部署了ragflow,可直接跳过第一部分,直接进入第二部分。但是如果你希望有人指导你部署ragflow,让它能够和`xiaozhi-esp32-server`共同使用`mysql`、`redis`基础服务,以减少资源成本,你需要从第一部分开始。 + +# 第一部分 如何部署ragflow +## 第一步, 确认mysql、redis是否可用 + +ragflow需要依赖`mysql`数据库。如果你之前已经部署`智控台`,说明你已经安装了`mysql`。你可以共用它。 + +你可以你试一下在宿主机使用`telnet`命令,看看能不能正常访问`mysql`的`3306`端口。 +``` shell +telnet 127.0.0.1 3306 + +telnet 127.0.0.1 6379 +``` +如果能访问到`3306`端口和`6379`端口,请忽略以下的内容,直接进入第二步。 + +如果不能访问,你需要回忆一下,你的`mysql`是怎么安装的。 + +如果你的mysql是通过自己使用安装包安装的,说明你的`mysql`做了网络隔离。你可能先解决访问`mysql`的`3306`端口这个问题。 + +如果你`mysql`是通过本项目的`docker-compose_all.yml`安装的。你需要找一下你当时创建数据库的`docker-compose_all.yml`文件,修改以下的内容 + +修改前 +``` yaml + xiaozhi-esp32-server-db: + ... + networks: + - default + expose: + - "3306:3306" + xiaozhi-esp32-server-redis: + ... + expose: + - 6379 +``` + +修改后 +``` yaml + xiaozhi-esp32-server-db: + ... + networks: + - default + ports: + - "3306:3306" + xiaozhi-esp32-server-redis: + ... + ports: + - "6379:6379" +``` + +注意是将`xiaozhi-esp32-server-db`和`xiaozhi-esp32-server-redis`下面的`expose`改成`ports`。改完后,需要重新启动。以下是重启mysql的命令: + +``` shell +# 进入你docker-compose_all.yml所在的文件夹,例如我的是xiaozhi-server +cd xiaozhi-server +docker compose -f docker-compose_all.yml down +docker compose -f docker-compose.yml up -d +``` + +启动完后,在宿主机再使用`telnet`命令,看看能不能正常访问`mysql`的`3306`端口。 +``` shell +telnet 127.0.0.1 3306 + +telnet 127.0.0.1 6379 +``` +正常来说这样就可以访问的了。 + +## 第二步, 创建数据库和表 +如果你的宿主机,能正常访问mysql数据库,那就在mysql上创建一个名字为`rag_flow`的数据库和`rag_flow`用户,密码为`infini_rag_flow`。 + +``` sql +-- 创建数据库 +CREATE DATABASE IF NOT EXISTS rag_flow CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 创建用户并授权 +CREATE USER IF NOT EXISTS 'rag_flow'@'%' IDENTIFIED BY 'infini_rag_flow'; +GRANT ALL PRIVILEGES ON rag_flow.* TO 'rag_flow'@'%'; + +-- 刷新权限 +FLUSH PRIVILEGES; +``` + +## 第三步, 下载ragflow项目 + +你需要在你电脑找一个文件夹,用来存放ragflow项目。例如我在`/home/system/xiaozhi`文件夹。 + +你可以使用`git`命令,将ragflow项目下载到这个文件夹,本教程使用的是`2025年11月11日`提交的`dd5b8e2e1a877211d17aae5552d8895b1bca763d`版本进行安装部署。 +``` +git clone https://ghfast.top/https://github.com/infiniflow/ragflow.git +cd ragflow +git reset --hard dd5b8e2e1a877211d17aae5552d8895b1bca763d + +``` +下载完后,进入`docker`文件夹。 +``` shell +cd docker +``` +修改`ragflow/docker`文件夹下的`docker-compose.yml`文件,将`ragflow-cpu`和`ragflow-gpu`服务的`depends_on`配置去掉,用于解除`ragflow-cpu`服务对`mysql`的依赖。 + +这是修改前: +``` yaml + ragflow-cpu: + depends_on: + mysql: + condition: service_healthy + profiles: + - cpu + ... + ragflow-gpu: + depends_on: + mysql: + condition: service_healthy + profiles: + - gpu +``` +这是修改后: +``` yaml + ragflow-cpu: + profiles: + - cpu + ... + ragflow-gpu: + profiles: + - gpu +``` + +接着,修改`ragflow/docker`文件夹下的`docker-compose-base.yml`文件,去掉`mysql`和`redis`的配置。 + +例如,删除前: +``` yaml +services: + minio: + image: quay.io/minio/minio:RELEASE.2025-06-13T11-33-47Z + ... + mysql: + image: mysql:8.0 + ... + redis: + image: redis:6.2-alpine + ... +``` + +删除后 +``` yaml +services: + minio: + image: quay.io/minio/minio:RELEASE.2025-06-13T11-33-47Z + ... +``` +## 第四步,修改环境变量配置 + +编辑`ragflow/docker`文件夹下的`.env`文件,找到以下配置,逐个搜索,逐个修改!逐个搜索,逐个修改! + +``` env +# ragflow镜像 +RAGFLOW_IMAGE=infiniflow/ragflow@sha256:d9ff494d1bf72138ce6fe0eaf4962cf4bea471c8c266d12b8bfb9d10ac3a2f6e +# 端口设置 +SVR_WEB_HTTP_PORT=8008 # HTTP端口 +SVR_WEB_HTTPS_PORT=8009 # HTTPS端口 +# MySQL配置 - 修改为您本地MySQL的信息 +MYSQL_HOST=host.docker.internal # 使用host.docker.internal让容器访问主机服务 +MYSQL_PORT=3306 # 本地MySQL端口 +MYSQL_USER=rag_flow # 上面创建的用户名,如果没有这项就增加这一项 +MYSQL_PASSWORD=infini_rag_flow # 上面设置的密码 +MYSQL_DBNAME=rag_flow # 数据库名称 + +# Redis配置 - 修改为您本地Redis的信息 +REDIS_HOST=host.docker.internal # 使用host.docker.internal让容器访问主机服务 +REDIS_PORT=6379 # 本地Redis端口 +REDIS_PASSWORD= # 如果你的Redis没有设置密码,这里填写None,否则填写密码 +``` + +注意,如果你的Redis没有设置密码,还要修改`ragflow/docker`文件夹下`service_conf.yaml.template`,将`infini_rag_flow`替换成空字符串。 + +修改前 +``` shell +redis: + db: 1 + password: '${REDIS_PASSWORD:-infini_rag_flow}' + host: '${REDIS_HOST:-redis}:6379' +``` +修改后 +``` shell +redis: + db: 1 + password: '${REDIS_PASSWORD:-}' + host: '${REDIS_HOST:-redis}:6379' +``` + +## 第五步,启动ragflow服务 +执行命令: +``` shell +docker-compose -f docker-compose.yml up -d +``` +执行成功后,你可以使用`docker logs -n 20 -f docker-ragflow-cpu-1`命令,查看`docker-ragflow-cpu-1`服务的日志。 + +如果日志中没有报错,说明ragflow服务启动成功。 + +# 第五步,注册账号 +你可以在浏览器中访问`http://127.0.0.1:8008`,点击`Sign Up`,注册一个账号。 + +注册成功后,你可以点击`Sign In`,登录到ragflow服务。如果你想关闭ragflow服务的注册服务,不想让其他人注册账号,你可以在`ragflow/docker`文件夹下的`.env`文件中,将`REGISTER_ENABLED`配置项设置为`0`。 + +``` dotenv +REGISTER_ENABLED=0 +``` +修改后,重启启动ragflow服务。 +``` shell +docker-compose -f docker-compose.yml down +docker-compose -f docker-compose.yml up -d +``` + +# 第二部分 配置ragflow服务 + +# 第一步 登录ragflow服务 +你可以在浏览器中访问`http://127.0.0.1:8008`,点击`Sign In`,登录到ragflow服务。 + +然后点击右上角的`头像`,进入设置页面。在左侧导航栏中,点击`API`功能,然后点击"API Key"按钮。出现一个弹框, + +在弹框中,点击"Create new Key"按钮,生成一个API Key。复制这个`API Key`,你稍后会用到。 + +# 第二步 配置到智控台 +确保你的智控台版本是`0.8.7`或以上。使用超级管理员账号登录到智控台。在顶部导航栏中,点击`模型配置`,在左侧导航栏中,点击`知识库`。 + +在列表中找到`RAG_RAGFlow`,点击`编辑`按钮。 + +在`服务地址`中,填写`http://你的ragflow服务的局域网IP:8008`,例如我的ragflow服务的局域网IP是`192.168.1.100`,那么我就填写`http://192.168.1.100:8008`。 + +在`API密钥`中,填写之前复制的`API Key`。 + +最后点击保存按钮。 + +# 第二步 创建一个知识库 +使用超级管理员账号登录到智控台。在顶部导航栏中,点击`知识库`,在列表左下脚,点击`新增`按钮。填写一个知识库的名字和描述。点击保存。 + +为了提高大模型对知识库的理解和召回能力,建议在创建知识库时,填写一个有意义的名字和描述。例如,如果你要创建一个关于`公司介绍`的知识库,那么知识库的名字可以是`公司介绍`,描述可以是`关于公司的相关信息例如公司基本信息、服务项目、联系电话、地址等。`。 + +保存后,你可以在知识库列表中看到这个知识库。点击刚才创建的知识库的`查看`按钮,进入知识库详情页面。 + +在知识库详情页面中,左下角点击`新增`按钮,可以上传文档到知识库。 + +上传后,你可以在知识库详情页面中,看到上传的文档。此时可以点击文档的`解析`按钮,解析文档。 + +解析完成后,你可以查看解析后的切片信息。你可以在知识库详情页面中,点击`召回测试`按钮,可以测试知识库的召回/检索功能。 + +# 第三步 让小智使用ragflow知识库 +登录到智控台。在顶部导航栏中,点击`智能体`,找到你要配置的智能体,点击`配置角色`按钮。 + +在意图识别左侧,点击`编辑功能`按钮,弹出一个弹框。在弹框中选择你要添加的知识库。保存即可。 \ No newline at end of file diff --git a/docs/voiceprint-integration.md b/docs/voiceprint-integration.md index 9db1af0c..fbc12b1f 100644 --- a/docs/voiceprint-integration.md +++ b/docs/voiceprint-integration.md @@ -28,7 +28,7 @@ telnet 127.0.0.1 3306 如果不能访问,你需要回忆一下,你的`mysql`是怎么安装的。 -如果你的mysql是通过自己使用安装包安装的,说明你的`mysql`做了网络隔离。你可能先解访问`mysql`的`3306`端口这个问题。 +如果你的mysql是通过自己使用安装包安装的,说明你的`mysql`做了网络隔离。你可能先解决访问`mysql`的`3306`端口这个问题。 如果你`mysql`是通过本项目的`docker-compose_all.yml`安装的。你需要找一下你当时创建数据库的`docker-compose_all.yml`文件,修改以下的内容 diff --git a/main/xiaozhi-server/docker-compose_all.yml b/main/xiaozhi-server/docker-compose_all.yml index b3602d45..327676e1 100644 --- a/main/xiaozhi-server/docker-compose_all.yml +++ b/main/xiaozhi-server/docker-compose_all.yml @@ -76,7 +76,7 @@ services: - MYSQL_INITDB_ARGS="--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci" # redis模块 xiaozhi-esp32-server-redis: - image: redis + image: redis:8.0 expose: - 6379 container_name: xiaozhi-esp32-server-redis From 1b28e8ddcb9661b701e9c801c04781176a7818bf Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 12:25:53 +0800 Subject: [PATCH 07/16] =?UTF-8?q?uptate:ragflow=E9=85=8D=E7=BD=AE=E6=95=99?= =?UTF-8?q?=E7=A8=8B=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ragflow-integration.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/ragflow-integration.md b/docs/ragflow-integration.md index 135c7de4..5010cde3 100644 --- a/docs/ragflow-integration.md +++ b/docs/ragflow-integration.md @@ -216,6 +216,13 @@ docker-compose -f docker-compose.yml down docker-compose -f docker-compose.yml up -d ``` +# 第六步,配置ragflow服务的模型 +你可以在浏览器中访问`http://127.0.0.1:8008`,点击`Sign In`,登录到ragflow服务。点击页面右上角的`头像`,进入设置页面。 +首先,在左侧导航栏中,点击`模型供应商`,进入到模型配置页面。在右侧的`可选模型`搜索框下,选择`LLM`,在列表选择你使用的模型供应商,点击`添加`,输入你的密钥; +然后,选择`TEXT EMBEDDING`,在列表选择你使用的模型供应商,点击`添加`,输入你的密钥。 +最后,刷新一下页面,分别点击`设置默认模型`列表的LLM和Embedding,选择你使用的模型即可。请确认你的密钥开通了相应的服务,比如我是用的Embedding模型是xxx供应商的,需要去这个供应商官网查看这个模型是否需要购买资源包才能使用。 + + # 第二部分 配置ragflow服务 # 第一步 登录ragflow服务 From f16906ad9d50c6810077cc846e00d4137b510ca1 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 12:28:08 +0800 Subject: [PATCH 08/16] =?UTF-8?q?uptate:=E5=A2=9E=E5=8A=A0=E7=9F=A5?= =?UTF-8?q?=E8=AF=86=E5=BA=93=E7=9B=B8=E5=85=B3=E6=8F=90=E7=A4=BA=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent/service/impl/AgentPluginMappingServiceImpl.java | 2 +- main/xiaozhi-server/agent-base-prompt.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java index 1ebb522a..fe197fbc 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentPluginMappingServiceImpl.java @@ -85,7 +85,7 @@ public class AgentPluginMappingServiceImpl extends ServiceImpl - **识别前缀:** 当用户格式为 `{"speaker":"某某某","content":"xxx"}` 时,表示系统已识别说话人身份,speaker是他的名字,content是说话的内容。 - **个性化回应:** - - **称呼姓名:** 在第一次识别说话人的时候必须称呼对方名字。 - **适配风格:** 参考该说话人**已知的特点或历史信息**(如有),调整回应风格和内容,使其更贴心。 @@ -63,6 +62,8 @@ - 查询**详细农历信息**(宜忌、八字、节气等)。 - 除上述例外外的**任何其他信息或操作请求**(如查新闻、订闹钟、算数学、查非本地天气等)。 - 我已经给你装了摄像头,如果用户说“拍照”,你需要调用self_camera_take_photo工具说一下你看到了什么。默认question的参数是“描述一下看到的物品” + - 当工具列表包含search_from_ragflow,说明可以使用知识库,你应该结合用户上下文意图并结合知识库的使用描述,推断是否要调用调用知识库。 + From c3ffa9d393bbad89df957d427e1a2e820f9baf5b Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 12:32:16 +0800 Subject: [PATCH 09/16] =?UTF-8?q?uptate:=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84=E8=A7=A3=E6=9E=90=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=A0=BC=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/utils/util.py | 28 +++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/main/xiaozhi-server/core/utils/util.py b/main/xiaozhi-server/core/utils/util.py index ea34d3e8..f10cc369 100644 --- a/main/xiaozhi-server/core/utils/util.py +++ b/main/xiaozhi-server/core/utils/util.py @@ -224,7 +224,10 @@ def check_ffmpeg_installed() -> bool: error_msg.append("⚠️ 发现缺少依赖库:libiconv.so.2") error_msg.append("解决方法:在当前 conda 环境中执行:") error_msg.append(" conda install -c conda-forge libiconv\n") - elif "no such file or directory" in stderr_output and "ffmpeg" in stderr_output.lower(): + elif ( + "no such file or directory" in stderr_output + and "ffmpeg" in stderr_output.lower() + ): error_msg.append("⚠️ 系统未找到 ffmpeg 可执行文件。") error_msg.append("解决方法:在当前 conda 环境中执行:") error_msg.append(" conda install -c conda-forge ffmpeg\n") @@ -245,7 +248,9 @@ def extract_json_from_string(input_string): return None -def audio_to_data_stream(audio_file_path, is_opus=True, callback: Callable[[Any], Any]=None) -> None: +def audio_to_data_stream( + audio_file_path, is_opus=True, callback: Callable[[Any], Any] = None +) -> None: # 获取文件后缀名 file_type = os.path.splitext(audio_file_path)[1] if file_type: @@ -262,6 +267,7 @@ def audio_to_data_stream(audio_file_path, is_opus=True, callback: Callable[[Any] raw_data = audio.raw_data pcm_to_data_stream(raw_data, is_opus, callback) + def audio_to_data(audio_file_path: str, is_opus: bool = True) -> list[bytes]: """ 将音频文件转换为Opus/PCM编码的帧列表 @@ -313,7 +319,10 @@ def audio_to_data(audio_file_path: str, is_opus: bool = True) -> list[bytes]: return datas -def audio_bytes_to_data_stream(audio_bytes, file_type, is_opus, callback: Callable[[Any], Any]) -> None: + +def audio_bytes_to_data_stream( + audio_bytes, file_type, is_opus, callback: Callable[[Any], Any] +) -> None: """ 直接用音频二进制数据转为opus/pcm数据,支持wav、mp3、p3 """ @@ -357,6 +366,7 @@ def pcm_to_data_stream(raw_data, is_opus=True, callback: Callable[[Any], Any] = frame_data = chunk if isinstance(chunk, bytes) else bytes(chunk) callback(frame_data) + def opus_datas_to_wav_bytes(opus_datas, sample_rate=16000, channels=1): """ 将opus帧列表解码为wav字节流 @@ -383,6 +393,7 @@ def opus_datas_to_wav_bytes(opus_datas, sample_rate=16000, channels=1): wf.writeframes(pcm_bytes) return wav_buffer.getvalue() + def check_vad_update(before_config, new_config): if ( new_config.get("selected_module") is None @@ -456,6 +467,17 @@ def filter_sensitive_info(config: dict) -> dict: filtered[k] = _filter_dict(v) elif isinstance(v, list): filtered[k] = [_filter_dict(i) if isinstance(i, dict) else i for i in v] + elif isinstance(v, str): + try: + json_data = json.loads(v) + if isinstance(json_data, dict): + filtered[k] = json.dumps( + _filter_dict(json_data), ensure_ascii=False + ) + else: + filtered[k] = v + except (json.JSONDecodeError, TypeError): + filtered[k] = v else: filtered[k] = v return filtered From 4966a42ed86caa297cb99aded0d72830891bf920 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 14:41:27 +0800 Subject: [PATCH 10/16] =?UTF-8?q?fix:=E8=BF=98=E5=8E=9F=E8=AF=AF=E5=88=A0?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E7=A4=BA=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/agent-base-prompt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/xiaozhi-server/agent-base-prompt.txt b/main/xiaozhi-server/agent-base-prompt.txt index 061ebef8..5b2fa792 100644 --- a/main/xiaozhi-server/agent-base-prompt.txt +++ b/main/xiaozhi-server/agent-base-prompt.txt @@ -44,6 +44,7 @@ - **识别前缀:** 当用户格式为 `{"speaker":"某某某","content":"xxx"}` 时,表示系统已识别说话人身份,speaker是他的名字,content是说话的内容。 - **个性化回应:** + - **称呼姓名:** 在第一次识别说话人的时候必须称呼对方名字。 - **适配风格:** 参考该说话人**已知的特点或历史信息**(如有),调整回应风格和内容,使其更贴心。 @@ -63,7 +64,6 @@ - 除上述例外外的**任何其他信息或操作请求**(如查新闻、订闹钟、算数学、查非本地天气等)。 - 我已经给你装了摄像头,如果用户说“拍照”,你需要调用self_camera_take_photo工具说一下你看到了什么。默认question的参数是“描述一下看到的物品” - 当工具列表包含search_from_ragflow,说明可以使用知识库,你应该结合用户上下文意图并结合知识库的使用描述,推断是否要调用调用知识库。 - From 2dc0c101c6cb7022507e169885a6e5b5072090dd Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 15:04:05 +0800 Subject: [PATCH 11/16] =?UTF-8?q?fix:=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../knowledge/service/impl/KnowledgeFilesServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java index 3608399b..e7e68bd5 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeFilesServiceImpl.java @@ -126,6 +126,8 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { log.error("RAGFlow API调用失败,响应码: {}", code); // 获取错误消息,如果存在的话 String apiMessage = (String) responseMap.get("message"); + String errorDetail = apiMessage != null ? apiMessage : "无详细错误信息"; + log.error("RAGFlow API调用失败,响应码: {}, 错误详情: {}", errorDetail); throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } @@ -498,6 +500,7 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { // 获取错误消息,如果存在的话 String apiMessage = (String) responseMap.get("message"); String errorDetail = apiMessage != null ? apiMessage : "无详细错误信息"; + log.error("RAGFlow API调用失败详情: {}", errorDetail); throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } @@ -912,6 +915,7 @@ public class KnowledgeFilesServiceImpl implements KnowledgeFilesService { // 获取错误消息,如果存在的话 String apiMessage = (String) responseMap.get("message"); String errorDetail = apiMessage != null ? apiMessage : "无详细错误信息"; + log.error("RAGFlow API调用失败详情: {}", errorDetail); throw new RenException(ErrorCode.RAG_API_ERROR, responseBody); } From 5d860e5b45db0f6d069f24a8a0cd5970091c9008 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 15:55:36 +0800 Subject: [PATCH 12/16] =?UTF-8?q?fix:=E5=A2=9E=E5=8A=A0=E7=9F=A5=E8=AF=86?= =?UTF-8?q?=E5=BA=93=E6=93=8D=E4=BD=9C=E6=97=B6=E7=B3=BB=E7=BB=9F=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/KnowledgeBaseServiceImpl.java | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java index 7d37fe4a..80934316 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java @@ -1,5 +1,6 @@ package xiaozhi.modules.knowledge.service.impl; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -150,7 +151,7 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + ResponseEntity response; + try { + response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); + } catch (Exception e) { + String errorMessage = url + e.getMessage(); + log.error(errorMessage, e); + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); + } log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); log.debug("RAGFlow API响应内容: {}", response.getBody()); @@ -468,6 +476,9 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl response = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, String.class); + ResponseEntity response; + try { + response = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, String.class); + } catch (Exception e) { + String errorMessage = url + e.getMessage(); + log.error(errorMessage, e); + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); + } log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); log.debug("RAGFlow API响应内容: {}", response.getBody()); @@ -546,6 +564,9 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl response = restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, - String.class); + ResponseEntity response; + try { + response = restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, String.class); + } catch (Exception e) { + String errorMessage = url + e.getMessage(); + log.error(errorMessage, e); + throw new RenException(ErrorCode.RAG_API_ERROR, errorMessage); + } log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); log.debug("RAGFlow API响应内容: {}", response.getBody()); @@ -615,6 +642,9 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + ResponseEntity response; + try { + response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + } catch (Exception e) { + String errorMessage = url + e.getMessage(); + log.error(errorMessage, e); + return 0; + } log.info("RAGFlow API响应状态码: {}", response.getStatusCode()); @@ -767,6 +804,8 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl Date: Wed, 12 Nov 2025 16:45:26 +0800 Subject: [PATCH 13/16] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96rag=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E9=AA=8C=E8=AF=81=E5=92=8C=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xiaozhi/common/exception/ErrorCode.java | 4 + .../impl/KnowledgeBaseServiceImpl.java | 163 +++++++++++------- .../resources/i18n/messages_en_US.properties | 6 +- .../resources/i18n/messages_zh_CN.properties | 6 +- .../resources/i18n/messages_zh_TW.properties | 6 + 5 files changed, 118 insertions(+), 67 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java index 268df223..659e135a 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java +++ b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java @@ -209,4 +209,8 @@ public interface ErrorCode { int UPLOAD_FILE_ERROR = 10168; // 上传文件失败 int NO_PERMISSION = 10169; // 没有权限 int KNOWLEDGE_BASE_NAME_EXISTS = 10170; // 同名知识库已存在 + int RAG_API_ERROR_URL_NULL = 10171; // RAG配置中base_url为空,请完善配置 + int RAG_API_ERROR_API_KEY_NULL = 10172; // RAG配置中api_key为空,请完善配置 + int RAG_API_ERROR_API_KEY_INVALID = 10173; // RAG配置中api_key包含占位符,请替换为实际的API密钥 + int RAG_API_ERROR_URL_INVALID = 10174; // RAG配置中base_url格式不正确,请检查协议是否正确 } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java index 80934316..b56923de 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/knowledge/service/impl/KnowledgeBaseServiceImpl.java @@ -110,7 +110,10 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl ragConfig = getValidatedRAGConfig(knowledgeBaseDTO.getRagModelId()); deleteDatasetInRAGFlow(datasetId, ragConfig); } catch (Exception deleteException) { - log.warn("删除重复datasetId的RAGFlow数据集失败: {}", deleteException.getMessage()); + // 提供更详细的错误信息,包括异常类型和消息 + String errorMessage = "删除重复datasetId的RAGFlow数据集失败: " + deleteException.getClass().getSimpleName(); + if (deleteException.getMessage() != null) { + errorMessage += " - " + deleteException.getMessage(); + } + log.warn(errorMessage, deleteException); } throw new RenException(ErrorCode.DB_RECORD_EXISTS); } @@ -207,17 +215,27 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl ragConfig = getValidatedRAGConfig(knowledgeBaseDTO.getRagModelId()); + try { + // 先校验RAG配置 + Map ragConfig = getValidatedRAGConfig(knowledgeBaseDTO.getRagModelId()); - // 调用RAGFlow API更新数据集 - updateDatasetInRAGFlow( - knowledgeBaseDTO.getDatasetId(), - knowledgeBaseDTO.getName(), - knowledgeBaseDTO.getDescription(), - ragConfig); + // 调用RAGFlow API更新数据集 + updateDatasetInRAGFlow( + knowledgeBaseDTO.getDatasetId(), + knowledgeBaseDTO.getName(), + knowledgeBaseDTO.getDescription(), + ragConfig); - log.info("RAGFlow API更新成功,datasetId: {}", knowledgeBaseDTO.getDatasetId()); + log.info("RAGFlow API更新成功,datasetId: {}", knowledgeBaseDTO.getDatasetId()); + } catch (Exception e) { + // 提供更详细的错误信息,包括异常类型和消息 + String errorMessage = "更新RAGFlow数据集失败: " + e.getClass().getSimpleName(); + if (e.getMessage() != null) { + errorMessage += " - " + e.getMessage(); + } + log.error(errorMessage, e); + throw e; + } } else { log.warn("datasetId或ragModelId为空,跳过RAGFlow更新"); } @@ -281,7 +299,12 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl config) { if (config == null) { - throw new RenException(ErrorCode.RAG_CONFIG_NOT_FOUND); + throw new RenException(ErrorCode.RAG_CONFIG_NOT_FOUND, "RAG配置为空,请检查配置"); } // 从配置中提取必要的参数 @@ -385,7 +408,22 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl ragConfig) { - if (ragConfig == null) { - throw new RenException(ErrorCode.RAG_CONFIG_NOT_FOUND, "RAG配置为空,请检查配置"); - } - - // 从配置中提取必要的参数 - String baseUrl = (String) ragConfig.get("base_url"); - String apiKey = (String) ragConfig.get("api_key"); - - if (StringUtils.isBlank(baseUrl)) { - throw new RenException(ErrorCode.RAG_API_ERROR, "RAG配置中base_url为空,请完善配置"); - } - - if (StringUtils.isBlank(apiKey)) { - throw new RenException(ErrorCode.RAG_API_ERROR, "RAG配置中api_key为空,请完善配置"); - } - - if (apiKey.contains("你")) { - throw new RenException(ErrorCode.RAG_API_ERROR, "RAG配置中api_key包含占位符'你',请替换为实际的API密钥"); - } - - if (!baseUrl.startsWith("http://") && !baseUrl.startsWith("https://")) { - throw new RenException(ErrorCode.RAG_API_ERROR, "RAG配置中base_url格式不正确,必须以http://或https://开头"); - } - } - /** * 检查是否存在同名知识库 * @@ -805,9 +832,15 @@ public class KnowledgeBaseServiceImpl extends BaseServiceImpl Date: Wed, 12 Nov 2025 16:46:04 +0800 Subject: [PATCH 14/16] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E7=AD=94=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugins_func/functions/search_from_ragflow.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main/xiaozhi-server/plugins_func/functions/search_from_ragflow.py b/main/xiaozhi-server/plugins_func/functions/search_from_ragflow.py index cdb709e3..d585a762 100644 --- a/main/xiaozhi-server/plugins_func/functions/search_from_ragflow.py +++ b/main/xiaozhi-server/plugins_func/functions/search_from_ragflow.py @@ -84,11 +84,12 @@ def search_from_ragflow(conn, question=None): else: contents.append(str(content)) - # 构建适合大模型的上下文内容(每段前加编号,段间两个换行) - context_text = "\n\n".join( - f"{i+1}. {c.strip()}" for i, c in enumerate(contents[:5]) - ) - if not context_text: + if contents: + # 组织知识库内容为引用模式 + context_text = f"# 关于问题【{question}】查到知识库如下\n" + context_text += "```\n\n\n".join(contents[:5]) + context_text += "\n```" + else: context_text = "根据知识库查询结果,没有相关信息。" return ActionResponse(Action.REQLLM, context_text, None) From 37f0d2398e636d2a4c0ce41c70a4d0a47470d177 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 16:46:20 +0800 Subject: [PATCH 15/16] =?UTF-8?q?fix:=E5=88=A0=E9=99=A4=E7=A9=BA=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/i18n/messages_zh_TW.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties index 8ef44180..c57f9e2c 100644 --- a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties +++ b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties @@ -181,5 +181,3 @@ 10172=\u0052\u0041\u0047\u914D\u7F6E\u4F53\u7684api_key\u4E0D\u80FD\u4E3A\u7A7A 10173=\u0052\u0041\u0047\u914D\u7F6E\u4F53\u7684api_key\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u8BF7\u66F4\u6362\u4E3A\u5728\u53D6\u7684API\u53C2\u6570 10174=\u0052\u0041\u0047\u914D\u7F6E\u4F53\u7684base_url\u683C\u5F0F\u9519\u8BEF\uFF0C\u5FC5\u987B\u4EE5http\u6216https\u5F00\u5934 - - From ae321b26af7164d9f16c64dfd747879fc3bd74d8 Mon Sep 17 00:00:00 2001 From: rainv123 <2148537152@qq.com> Date: Wed, 12 Nov 2025 17:02:53 +0800 Subject: [PATCH 16/16] =?UTF-8?q?fix:=E7=9F=A5=E8=AF=86=E5=BA=93=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=96=87=E6=9C=AC=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/i18n/en.js | 4 ++-- main/manager-web/src/i18n/zh_CN.js | 4 ++-- main/manager-web/src/i18n/zh_TW.js | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/main/manager-web/src/i18n/en.js b/main/manager-web/src/i18n/en.js index 77a6d9e0..a1a40942 100644 --- a/main/manager-web/src/i18n/en.js +++ b/main/manager-web/src/i18n/en.js @@ -1183,7 +1183,7 @@ export default { 'knowledgeBaseDialog.descriptionLengthLimit': 'Knowledge base description cannot exceed 200 characters', // Knowledge Base Management page new view button text - 'knowledgeBaseManagement.view': 'View', + 'knowledgeBaseManagement.view': 'Manage Files', // Knowledge File Upload page text 'knowledgeFileUpload.back': 'Back', @@ -1215,7 +1215,7 @@ export default { 'knowledgeFileUpload.statusProcessing': 'Processing', 'knowledgeFileUpload.statusCancelled': 'Cancelled', 'knowledgeFileUpload.statusCompleted': 'Completed', - 'knowledgeFileUpload.statusFailed': 'Parse Failed', + 'knowledgeFileUpload.statusFailed': 'Failed', 'knowledgeFileUpload.uploadSuccess': 'Document upload successful', 'knowledgeFileUpload.uploadFailed': 'Document upload failed', 'knowledgeFileUpload.parseSuccess': 'Document parse successful', diff --git a/main/manager-web/src/i18n/zh_CN.js b/main/manager-web/src/i18n/zh_CN.js index cc2654c9..9bf780bc 100644 --- a/main/manager-web/src/i18n/zh_CN.js +++ b/main/manager-web/src/i18n/zh_CN.js @@ -1183,7 +1183,7 @@ export default { 'knowledgeBaseDialog.descriptionLengthLimit': '知识库描述不能超过200个字符', // 知识库管理页面新增查看按钮文本 - 'knowledgeBaseManagement.view': '查看', + 'knowledgeBaseManagement.view': '管理文件', // 上传文件页面文本 'knowledgeFileUpload.back': '返回', @@ -1215,7 +1215,7 @@ export default { 'knowledgeFileUpload.statusProcessing': '处理中', 'knowledgeFileUpload.statusCancelled': '已取消', 'knowledgeFileUpload.statusCompleted': '已完成', - 'knowledgeFileUpload.statusFailed': '解析失败', + 'knowledgeFileUpload.statusFailed': '失败', 'knowledgeFileUpload.uploadSuccess': '文档上传成功', 'knowledgeFileUpload.uploadFailed': '文档上传失败', 'knowledgeFileUpload.parseSuccess': '文档解析成功', diff --git a/main/manager-web/src/i18n/zh_TW.js b/main/manager-web/src/i18n/zh_TW.js index 984c51d1..55927fa7 100644 --- a/main/manager-web/src/i18n/zh_TW.js +++ b/main/manager-web/src/i18n/zh_TW.js @@ -1183,7 +1183,7 @@ export default { 'knowledgeBaseDialog.descriptionLengthLimit': '知識庫描述不能超過200個字符', // 知識庫管理頁面查看按鈕文本 - 'knowledgeBaseManagement.view': '查看', + 'knowledgeBaseManagement.view': '管理文件', // 知識庫文件上傳頁面文本 'knowledgeFileUpload.back': '返回', @@ -1215,6 +1215,7 @@ export default { 'knowledgeFileUpload.statusProcessing': '處理中', 'knowledgeFileUpload.statusCancelled': '已取消', 'knowledgeFileUpload.statusCompleted': '已完成', + 'knowledgeFileUpload.statusFailed': '失敗', 'knowledgeFileUpload.uploadSuccess': '文檔上傳成功', 'knowledgeFileUpload.uploadFailed': '文檔上傳失敗', 'knowledgeFileUpload.parseSuccess': '文檔解析成功',