@@ -174,8 +178,8 @@ export default function l2Edit() {
-
-
+
+
diff --git a/src/frontend/platform/src/pages/ChatAppPage/components/ChatPanne.tsx b/src/frontend/platform/src/pages/ChatAppPage/components/ChatPanne.tsx
index 5ad5d336e..802849c5c 100644
--- a/src/frontend/platform/src/pages/ChatAppPage/components/ChatPanne.tsx
+++ b/src/frontend/platform/src/pages/ChatAppPage/components/ChatPanne.tsx
@@ -281,8 +281,8 @@ export default function ChatPanne({ customWsHost = '', chatList, chat, appendHis
{
workflow &&
-
-
{chat.flow_name}
+
+
{workflow.name}
diff --git a/src/frontend/platform/src/pages/DataSetPage/CreateDataSet.tsx b/src/frontend/platform/src/pages/DataSetPage/CreateDataSet.tsx
index 6b3fdbc75..30cd13fbf 100644
--- a/src/frontend/platform/src/pages/DataSetPage/CreateDataSet.tsx
+++ b/src/frontend/platform/src/pages/DataSetPage/CreateDataSet.tsx
@@ -169,7 +169,7 @@ const CreateDataSet = forwardRef(({ onChange }, ref) => {
{
- const errorlist = [];
- if (!selectedType) errorlist.push(t("evaluation.enterExecType"));
- // if (!selectedKeyId) errorlist.push(t("evaluation.workFlow"));
+ const errorlist = [];
+ if (!selectedType) errorlist.push(t("evaluation.enterExecType"));
+
+ if (selectedType && !selectedKeyId) {
+ if (selectedType === "workflow") errorlist.push(t("请选择工作流"));
+ if (selectedType === "flow") errorlist.push(t("请选择技能"));
+ if (selectedType === "assistant") errorlist.push(t("请选择助手"));
+ }
- // 修复版本验证 - 取消注释并添加正确的验证
- if ((selectedType === "workflow" || selectedType === "flow" || !selectedKeyId) && !selectedVersion) {
- errorlist.push(t("evaluation.workFlow"));
- }
+ if (selectedKeyId && (selectedType === "workflow" || selectedType === "flow") && !selectedVersion) {
+ errorlist.push(t("请选择版本"));
+ }
+ if (!fileRef.current && selectedKeyId&&selectedVersion) errorlist.push(t("evaluation.enterFile"));
+ if (!prompt) errorlist.push(t("evaluation.enterPrompt"));
- // 修复文件验证 - 所有类型都需要测试集数据
- // if (!fileRef.current) errorlist.push(t("evaluation.enterFile"));
-
- if (!prompt) errorlist.push(t("evaluation.enterPrompt"));
-
- if (errorlist.length) return handleError(errorlist);
+ if (errorlist.length) return handleError(errorlist);
setLoading(true);
try {
await captureAndAlertRequestErrorHoc(
diff --git a/src/frontend/platform/src/pages/KnowledgePage/AdjustFilesUpload.tsx b/src/frontend/platform/src/pages/KnowledgePage/AdjustFilesUpload.tsx
index d7bed3f32..6b63ba93f 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/AdjustFilesUpload.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/AdjustFilesUpload.tsx
@@ -5,7 +5,7 @@ import { useToast } from "@/components/bs-ui/toast/use-toast";
import { rebUploadFile, retryKnowledgeFileApi, subUploadLibFile } from "@/controllers/API";
import { captureAndAlertRequestErrorHoc } from "@/controllers/request";
import { ChevronLeft } from "lucide-react";
-import { useRef, useState } from "react";
+import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import FileUploadStep2 from "./components/FileUploadStep2";
@@ -29,6 +29,12 @@ export default function AdjustFilesUpload() {
// 从路由状态获取调整模式的初始数据(必须传文件数据)
const initFileData = location.state?.fileData;
+ useEffect(() => {
+ // 如果没有初始化数据,说明是直接访问,跳转到/filelib
+ if (!initFileData) {
+ navigate('/filelib', { replace: true });
+ }
+ }, [initFileData, navigate]);
if (!initFileData) {
navigate(-1); // 无数据时回退
return null;
@@ -112,17 +118,18 @@ export default function AdjustFilesUpload() {
const fileName = initFileData.name || initFileData.file_name || '';
const fileSuffix = fileName.split('.').pop()?.toLowerCase() || 'txt';
const fileType = ['xlsx', 'xls', 'csv'].includes(fileSuffix) ? 'table' : 'file';
+
const [resultFiles, setResultFiles] = useState([
{
id: initFileData.id,
fileName: initFileData.name || initFileData.file_name, // 兼容字段名
file_path: initFileData.filePath || initFileData.object_name, // 兼容文件路径
suffix: initFileData.suffix || initFileData.file_name?.split(".").pop() || "", // 解析后缀
+ previewUrl:initFileData.previewUrl,
fileType: fileType,
split_rule: getParsedSplitRule(initFileData.split_rule) // 传入转换后的配置对象
}
]);
- console.log(initFileData,78);
const [segmentRules, setSegmentRules] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
diff --git a/src/frontend/platform/src/pages/KnowledgePage/KnowledgeFile.tsx b/src/frontend/platform/src/pages/KnowledgePage/KnowledgeFile.tsx
index 1952ef25e..fbad75444 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/KnowledgeFile.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/KnowledgeFile.tsx
@@ -23,7 +23,7 @@ import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogT
import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/bs-ui/select";
import { useToast } from "@/components/bs-ui/toast/use-toast";
import { getKnowledgeModelConfig, getLLmServerDetail, getModelListApi } from "@/controllers/API/finetune";
-import { CircleAlert, Copy, Ellipsis, LoaderCircle, Settings, Trash2 } from "lucide-react";
+import { BookCopy, CircleAlert, Copy, Ellipsis, LoaderCircle, Settings, Trash2 } from "lucide-react";
import AutoPagination from "../../components/bs-ui/pagination/autoPagination";
import { useTable } from "../../util/hook";
import { ModelSelect } from "../ModelPage/manage/tabs/WorkbenchModel";
@@ -112,7 +112,7 @@ function CreateModal({ datalist, open, onOpenChange, onLoadEnd, mode = 'create',
fetchModelData();
}, [open, mode, currentLib]);
-
+
useEffect(() => {
// 当弹窗关闭时,清空所有内部状态
if (!open) {
@@ -122,112 +122,112 @@ function CreateModal({ datalist, open, onOpenChange, onLoadEnd, mode = 'create',
setError({ name: false, desc: false });
}
}, [open]);
-
+
const { toast } = useToast()
const [error, setError] = useState({ name: false, desc: false })
- const handleCreate = async (e, isImport = false) => {
- const name = nameRef.current.value || ''; // 名称(默认空字符串,避免null)
- let desc = descRef.current.value || ''; // 描述(默认空字符串)
+ const handleCreate = async (e, isImport = false) => {
+ const name = nameRef.current.value || ''; // 名称(默认空字符串,避免null)
+ let desc = descRef.current.value || ''; // 描述(默认空字符串)
- // 1. 定义默认描述的"固定文本部分"(不含名称)
- const defaultDescPrefix = "当回答与";
- const defaultDescSuffix = "相关的问题时,参考此知识库";
- // 固定文本总长度 = 前缀长度 + 后缀长度
- const fixedTextLength = defaultDescPrefix.length + defaultDescSuffix.length;
- // 名称可占用的最大长度 = 200 - 固定文本长度(确保名称+固定文本≤200)
- const maxNameLengthForDefaultDesc = 200 - fixedTextLength;
+ // 1. 定义默认描述的"固定文本部分"(不含名称)
+ const defaultDescPrefix = "当回答与";
+ const defaultDescSuffix = "相关的问题时,参考此知识库";
+ // 固定文本总长度 = 前缀长度 + 后缀长度
+ const fixedTextLength = defaultDescPrefix.length + defaultDescSuffix.length;
+ // 名称可占用的最大长度 = 200 - 固定文本长度(确保名称+固定文本≤200)
+ const maxNameLengthForDefaultDesc = 200 - fixedTextLength;
- // 2. 未输入描述时,生成默认描述(严格控制总长度≤200)
- if (!desc) {
- // 情况1:名称长度 ≤ 可占用最大长度 → 直接拼接生成默认描述
- if (name.length <= maxNameLengthForDefaultDesc) {
- desc = `${defaultDescPrefix}${name}${defaultDescSuffix}`;
- }
- // 情况2:名称长度 > 可占用最大长度 → 截断名称后再拼接
- else {
- // 截断名称(保留前 maxNameLengthForDefaultDesc 个字,避免总长度超200)
- const truncatedName = name.slice(0, maxNameLengthForDefaultDesc);
- // 生成截断截断后的默认描述
- desc = `${defaultDescPrefix}${truncatedName}${defaultDescSuffix}`;
- // 提示用户:名称过长已被截断(提升体验,避免用户困惑)
- toast({
- variant: "info",
- description: `知识库名称过长,已自动截断为${maxNameLengthForDefaultDesc}字,确保默认描述不超过200字限制`
- });
+ // 2. 未输入描述时,生成默认描述(严格控制总长度≤200)
+ if (!desc) {
+ // 情况1:名称长度 ≤ 可占用最大长度 → 直接拼接生成默认描述
+ if (name.length <= maxNameLengthForDefaultDesc) {
+ desc = `${defaultDescPrefix}${name}${defaultDescSuffix}`;
+ }
+ // 情况2:名称长度 > 可占用最大长度 → 截断名称后再拼接
+ else {
+ // 截断名称(保留前 maxNameLengthForDefaultDesc 个字,避免总长度超200)
+ const truncatedName = name.slice(0, maxNameLengthForDefaultDesc);
+ // 生成截断截断后的默认描述
+ desc = `${defaultDescPrefix}${truncatedName}${defaultDescSuffix}`;
+ // 提示用户:名称过长已被截断(提升体验,避免用户困惑)
+ toast({
+ variant: "info",
+ description: `知识库名称过长,已自动截断为${maxNameLengthForDefaultDesc}字,确保默认描述不超过200字限制`
+ });
+ }
}
- }
- // 3. 原有校验逻辑(仅针对用户手动输入的描述,默认描述已确保≤200)
- if (!name) {
- handleError(t('lib.enterLibraryName'));
- return;
- }
- if (name.length > 30) {
- handleError('知识库名称不能超过30字');
- return;
- }
- if (!modal) {
- handleError(t('lib.selectModel'));
- return;
- }
-
- // 修复:名称重复校验逻辑
- // 编辑模式且名称未变更时,不进行重复校验
- const isEditMode = mode === 'edit' && currentLib;
- const nameUnchanged = isEditMode && name === currentLib.name;
-
- if (!nameUnchanged && datalist.find(data => data.name === name && (!currentLib || data.id !== currentLib.id))) {
- handleError(t('lib.nameExists'));
- return;
- }
-
- // 仅校验用户手动输入的描述(默认描述已控制长度,可跳过)
- if (descRef.current.value && desc.length > 200) {
- handleError(t('lib.descriptionLimit'));
- return;
- }
-
- setIsSubmitting(true)
- if (mode === 'create') {
- await captureAndAlertRequestErrorHoc(createFileLib({
- name,
- description: desc,
- model: modal[1].value,
- type: 0
- }).then(res => {
- window.libname = [name, desc]
- navigate(isImport
- ? `/filelib/upload/${res.id}`
- : `/filelib/${res.id}`
- );
- onOpenChange(false); // 修复:用onOpenChange关闭弹窗
- })).finally(() => {
- setIsSubmitting(false)
- })
- } else {
- const data = {
- "model_id": modal[1].value,
- "model_type": "embedding",
- "knowledge_id": currentLib.id,
- "knowledge_name": name,
- "description": desc
+ // 3. 原有校验逻辑(仅针对用户手动输入的描述,默认描述已确保≤200)
+ if (!name) {
+ handleError(t('lib.enterLibraryName'));
+ return;
}
- await captureAndAlertRequestErrorHoc(updateKnowledge(data).then(res => {
- toast({
- variant: "success",
- description: '更新成功'
+ if (name.length > 200) {
+ handleError('知识库名称不能超过200字');
+ return;
+ }
+ if (!modal) {
+ handleError(t('lib.selectModel'));
+ return;
+ }
+
+ // 修复:名称重复校验逻辑
+ // 编辑模式且名称未变更时,不进行重复校验
+ const isEditMode = mode === 'edit' && currentLib;
+ const nameUnchanged = isEditMode && name === currentLib.name;
+
+ if (!nameUnchanged && datalist.find(data => data.name === name && (!currentLib || data.id !== currentLib.id))) {
+ handleError(t('lib.nameExists'));
+ return;
+ }
+
+ // 仅校验用户手动输入的描述(默认描述已控制长度,可跳过)
+ if (descRef.current.value && desc.length > 200) {
+ handleError(t('lib.descriptionLimit'));
+ return;
+ }
+
+ setIsSubmitting(true)
+ if (mode === 'create') {
+ await captureAndAlertRequestErrorHoc(createFileLib({
+ name,
+ description: desc,
+ model: modal[1].value,
+ type: 0
+ }).then(res => {
+ window.libname = [name, desc]
+ navigate(isImport
+ ? `/filelib/upload/${res.id}`
+ : `/filelib/${res.id}`
+ );
+ onOpenChange(false); // 修复:用onOpenChange关闭弹窗
+ })).finally(() => {
+ setIsSubmitting(false)
})
- onOpenChange(false); // 修复:用onOpenChange关闭弹窗(替代原setOpen)
- onLoadEnd()
- }).catch(error => {
- toast({ variant: "error", description: '更新失败,请重试' });
- onOpenChange(false); // 错误时也关闭弹窗,避免状态卡住
- })).finally(() => {
- setIsSubmitting(false)
- })
+ } else {
+ const data = {
+ "model_id": modal[1].value,
+ "model_type": "embedding",
+ "knowledge_id": currentLib.id,
+ "knowledge_name": name,
+ "description": desc
+ }
+ await captureAndAlertRequestErrorHoc(updateKnowledge(data).then(res => {
+ toast({
+ variant: "success",
+ description: '更新成功'
+ })
+ onOpenChange(false); // 修复:用onOpenChange关闭弹窗(替代原setOpen)
+ onLoadEnd()
+ }).catch(error => {
+ toast({ variant: "error", description: '更新失败,请重试' });
+ onOpenChange(false); // 错误时也关闭弹窗,避免状态卡住
+ })).finally(() => {
+ setIsSubmitting(false)
+ })
+ }
}
-}
const handleError = (message) => {
toast({
@@ -411,21 +411,21 @@ export default function KnowledgeFile() {
})
}
-const handleOpenSettings = (lib) => {
- console.log("=== handleOpenSettings 开始执行 ===");
- console.log("当前点击的lib ID:", lib.id);
- // 1. 深拷贝:彻底断开与原 lib 的引用关联(解决嵌套属性引用不变问题)
- const newCurrentLib = JSON.parse(JSON.stringify(lib));
- // 2. 注入唯一标识:即使数据完全相同,也让 currentSettingLib 引用绝对唯一
- newCurrentLib.__updateKey = Date.now(); // 每次点击生成不同的时间戳
-
- setCurrentSettingLib(newCurrentLib); // 此时传递的是完全新的对象引用
- setSettingsOpen(true);
- setModalKey(prev => prev + 1); // 保留 modalKey 确保弹窗重新挂载
- console.log("handleOpenSettings called with lib:", newCurrentLib); // 验证打印
-};
+ const handleOpenSettings = (lib) => {
+ console.log("=== handleOpenSettings 开始执行 ===");
+ console.log("当前点击的lib ID:", lib.id);
+ // 1. 深拷贝:彻底断开与原 lib 的引用关联(解决嵌套属性引用不变问题)
+ const newCurrentLib = JSON.parse(JSON.stringify(lib));
+ // 2. 注入唯一标识:即使数据完全相同,也让 currentSettingLib 引用绝对唯一
+ newCurrentLib.__updateKey = Date.now(); // 每次点击生成不同的时间戳
- const handleSettingsClose = (isOpen) => {
+ setCurrentSettingLib(newCurrentLib); // 此时传递的是完全新的对象引用
+ setSettingsOpen(true);
+ setModalKey(prev => prev + 1); // 保留 modalKey 确保弹窗重新挂载
+ console.log("handleOpenSettings called with lib:", newCurrentLib); // 验证打印
+ };
+
+ const handleSettingsClose = (isOpen) => {
console.log("handleSettingsClose called with isOpen:", isOpen);
setSettingsOpen(isOpen);
if (!isOpen) {
@@ -439,7 +439,7 @@ const handleOpenSettings = (lib) => {
const handleCachePage = () => {
window.LibPage = { page, type: 'file' }
}
-
+
useEffect(() => {
const _page = window.LibPage
if (_page) {
@@ -511,7 +511,7 @@ const handleOpenSettings = (lib) => {
key={el.id}
className=" h-[70px]"
>
- {
window.libname = [el.name, el.description];
@@ -520,27 +520,27 @@ const handleOpenSettings = (lib) => {
}}
>
-
-

+
+
{el.name}
- {el.description || ''}
+ {el.description || ''}
-
{
window.libname = [el.name, el.description];
@@ -551,7 +551,7 @@ const handleOpenSettings = (lib) => {
{el.update_time.replace('T', ' ')}
-
{
window.libname = [el.name, el.description];
@@ -565,15 +565,15 @@ const handleOpenSettings = (lib) => {
-
+
{/* 创建弹窗 */}
{
onLoadEnd={() => { }}
mode="create"
/>
-
+
{/* 编辑(设置)弹窗 - 使用 key 强制重新渲染 */}
{settingsOpen && (
-
+
)}
);
diff --git a/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep2.tsx b/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep2.tsx
index 7b5f9bb67..a608ef748 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep2.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep2.tsx
@@ -56,7 +56,6 @@ const FileUploadStep2 = forwardRef(({ step, resultFiles, isSubmitting, onNext, o
});
const displayMode: DisplayModeType | null = useMemo(() => {
if (!resultFiles || resultFiles.length === 0) return null;
-console.log(resultFiles,55555);
const hasTableFiles = resultFiles.some(file => file.fileType === 'table');
const hasDocumentFiles = resultFiles.some(file => file.fileType === 'file');
@@ -338,6 +337,7 @@ const useFileProcessingRules = (initialStrategies, resultFiles, kid, splitRule)
id: file.id,
filePath: file.file_path,
fileName: file.fileName,
+ previewUrl:file.previewUrl,
suffix: file.suffix,
fileType: file.fileType,
excelRule: file.fileType === 'table' ? {
diff --git a/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep4.tsx b/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep4.tsx
index 57c26509a..d5ee00c9f 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep4.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/components/FileUploadStep4.tsx
@@ -1,4 +1,3 @@
-
import CardComponent from "@/components/bs-comp/cardComponent";
import ProgressItem from "@/components/bs-comp/knowledgeUploadComponent/ProgressItem";
import { Button } from "@/components/bs-ui/button";
@@ -15,106 +14,148 @@ export default function FileUploadStep4({ data ,kId}) {
const [finish, setFinish] = useState(true)
const navigate = useNavigate()
const { id: kid } = useParams()
-console.log(data,kId,44);
+ console.log(data,kId,44);
const [files, setFiles] = useState([])
const timerRef = useRef(null); // 轮询定时器引用
const fileIdsRef = useRef([]); // 文件ID列表引用
- // 初始化文件状态
+ const processingRef = useRef(new Set()); // 跟踪正在处理的文件ID
+ const isPollingRef = useRef(false); // 防止轮询并发
+
+ // 初始化文件状态(只执行一次)
useEffect(() => {
- const initialFiles = data.map(item => ({
- id: item.fileId,
- fileName: item.fileName,
- error: false,
- reason: '',
- progress: 'await' // 初始状态设为解析中
- }));
- setFiles(initialFiles);
- fileIdsRef.current = data.map(item => item.fileId); // 保存文件ID列表
- }, [data]);
+ if (files.length === 0 && data.length > 0) { // 防止重复初始化
+ const initialFiles = data.map(item => ({
+ id: item.fileId,
+ fileName: item.fileName,
+ error: false,
+ reason: '',
+ progress: 'await' // 初始状态设为解析中
+ }));
+ setFiles(initialFiles);
+ fileIdsRef.current = data.map(item => item.fileId);
+ // 初始化处理中的文件集合
+ fileIdsRef.current.forEach(id => processingRef.current.add(id));
+ }
+ }, [data]); // 只依赖data变化
// 轮询文件状态
useEffect(() => {
- // 如果文件列表为空,直接完成
+ // 如果没有文件需要处理,直接完成
if (fileIdsRef.current.length === 0) {
setFinish(true);
return;
}
- // 轮询函数
+ // 轮询函数(添加并发控制)
const pollFilesStatus = async () => {
- console.log(kid,fileIdsRef.current,22);
-
+ // 防止上一次请求未完成时发起新请求
+ if (isPollingRef.current) return;
+ isPollingRef.current = true;
+
try {
+ // 只轮询仍在处理中的文件
+ const pendingFileIds = Array.from(processingRef.current);
+ if (pendingFileIds.length === 0) {
+ clearInterval(timerRef.current);
+ setFinish(true);
+ return;
+ }
+
+ console.log(kid,kId, pendingFileIds, 22);
+
const res = await readFileByLibDatabase({
id: kid || kId,
page: 0,
pageSize: 0,
- file_ids: fileIdsRef.current
+ file_ids: pendingFileIds // 只查询未完成的文件
});
// 更新文件状态
setFiles(prev => {
+ const updatedFiles = [...prev];
const resMap = new Map(res.data.map(item => [item.id, item]));
- return prev.map(file => {
- if (resMap.has(file.id)) {
- const resItem = resMap.get(file.id);
- let progress = 'await';
- let error = false;
- let reason = '';
+
+ pendingFileIds.forEach(fileId => {
+ if (resMap.has(fileId)) {
+ const resItem = resMap.get(fileId);
+ const fileIndex = updatedFiles.findIndex(f => f.id === fileId);
+
+ if (fileIndex !== -1) {
+ let progress = updatedFiles[fileIndex].progress;
+ let error = updatedFiles[fileIndex].error;
+ let reason = updatedFiles[fileIndex].reason;
- if (resItem.status === 2) {
- progress = 'end'; // 成功
- } else if (resItem.status === 3) {
- progress = 'end'; // 失败
- error = true;
- reason = resItem.remark;
+ // 状态变为完成或失败时,从处理中集合移除
+ if (resItem.status === 2) {
+ progress = 'end'; // 成功
+ processingRef.current.delete(fileId);
+ } else if (resItem.status === 3) {
+ progress = 'end'; // 失败
+ error = true;
+ reason = resItem.remark;
+ processingRef.current.delete(fileId);
+ }
+
+ updatedFiles[fileIndex] = {
+ ...updatedFiles[fileIndex],
+ progress,
+ error,
+ reason
+ };
}
-
- return { ...file, progress, error, reason };
}
- return file;
});
+
+ return updatedFiles;
});
} catch (e) {
console.error("轮询文件状态出错:", e);
+ } finally {
+ isPollingRef.current = false; // 释放锁
}
};
// 立即执行第一次轮询,然后每5秒轮询一次
pollFilesStatus();
- timerRef.current = setInterval(pollFilesStatus, 3000 + fileIdsRef.current.length * 10);
+ timerRef.current = setInterval(pollFilesStatus, 5000); // 固定间隔,避免过频繁
// 清理定时器
- return () => clearInterval(timerRef.current);
- }, [kid]);
+ return () => {
+ if (timerRef.current) {
+ clearInterval(timerRef.current);
+ }
+ };
+ }, [kid, kId]); // 只依赖kid和kId变化
// 检查所有文件是否完成
-useEffect(() => {
- // 检查是否有文件仍在处理中
- const hasProcessingFiles = files.some(f => f.progress !== 'end');
-
- // 只有当存在文件且没有文件在处理中时,才标记为完成
- if (files.length > 0 && !hasProcessingFiles) {
- console.log('所有文件处理完成');
- clearInterval(timerRef.current);
- setFinish(true);
- } else {
- // 仍有文件在处理中或文件列表为空
- if (files.length > 0) {
- const processingCount = files.filter(f => f.progress !== 'end').length;
- console.log(`仍有${processingCount}个文件正在处理中`);
+ useEffect(() => {
+ // 当处理中集合为空时,标记为完成
+ if (processingRef.current.size === 0 && fileIdsRef.current.length > 0) {
+ console.log('所有文件处理完成');
+ if (timerRef.current) {
+ clearInterval(timerRef.current);
+ }
+ setFinish(true);
+ } else {
+ setFinish(false);
}
- setFinish(false);
- }
-}, [files]);
- console.log('fukes :>> ', data, files);
+ }, [files]); // 依赖文件状态变化
- const [details] = useKnowledgeDetails([kid])
+ console.log('files :>> ', files);
+
+ let finalId = kid;
+ if (kId) {
+ finalId = kId.replace(/\D/g, '');
+ }
+ const [details] = useKnowledgeDetails([finalId])
+
const handleCreateFlow = async (params) => {
const model = await getLlmDefaultModel()
- const flow = await getKnowledgeDefaultFlowTemplate(kid, details[0].name, model.model_id)
+ console.log(details,9999);
+
+ const flow = await getKnowledgeDefaultFlowTemplate(finalId, details[0]?.name || '', model.model_id)
const res = await captureAndAlertRequestErrorHoc(createWorkflowApi(
"文档知识库问答-" + generateUUID(5),
"检索文档知识库,根据检索结果进行回答。",
@@ -148,8 +189,7 @@ useEffect(() => {
};
-
-
+// 保持getKnowledgeDefaultFlowTemplate函数不变
const getKnowledgeDefaultFlowTemplate = async (kid, kname, modelId) => {
const templates = await getWorkflowNodeTemplate()
let startNode = null
@@ -289,4 +329,5 @@ const getKnowledgeDefaultFlowTemplate = async (kid, kname, modelId) => {
}
}
}
-}
\ No newline at end of file
+}
+
\ No newline at end of file
diff --git a/src/frontend/platform/src/pages/KnowledgePage/components/Paragraphs.tsx b/src/frontend/platform/src/pages/KnowledgePage/components/Paragraphs.tsx
index ae490d9c1..6c995147d 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/components/Paragraphs.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/components/Paragraphs.tsx
@@ -55,7 +55,7 @@ export default function Paragraphs({ fileId, onBack }) {
const searchInputRef = useRef(null);
const isChangingRef = useRef(false);
const [isInitReady, setIsInitReady] = useState(false);
-
+ const [previewUrl,setPreviewUrl] = useState()
// 1. 修复:URL乱码(添加decodeURIComponent)+ 确保数据顺序
const fetchFileUrl = useCallback(async (fileId) => {
console.log('获取文件URL:', fileId);
@@ -66,15 +66,20 @@ export default function Paragraphs({ fileId, onBack }) {
const res = await getFilePathApi(fileId);
const pares = await getFileBboxApi(fileId)
setPartitions(pares)
- console.log('getFilePathApi 响应:', res,pares);
+ console.log('getFilePathApi 响应:', res.original_url,pares);
// 修复:提取URL并解码(解决中文/特殊字符乱码)
let url;
- if (res.data) {
- url = res.data.url || res.data.filePath || res.data;
+ if (res) {
+ url = res.original_url || res.data.filePath || res.url;
+ if(res.preview_url){
+ setPreviewUrl(res.preview_url)
+ }
} else {
url = res.url || res.filePath || res;
}
+ console.log(url,2222);
+
const trimmedUrl = (url || '').trim();
if (!trimmedUrl) {
@@ -363,6 +368,7 @@ export default function Paragraphs({ fileId, onBack }) {
skipToStep: 2,
fileId: selectedFileId,
fileData: {
+ previewUrl:previewUrl,
id: currentFile?.id,
name: currentFile?.name,
split_rule: currentFile?.split_rule || currentFile?.fullData?.split_rule,
diff --git a/src/frontend/platform/src/pages/KnowledgePage/components/PreviewFile.tsx b/src/frontend/platform/src/pages/KnowledgePage/components/PreviewFile.tsx
index 848c20437..b9ab9b4a3 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/components/PreviewFile.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/components/PreviewFile.tsx
@@ -45,8 +45,9 @@ export default function PreviewFile({
const targetFile = matchedRawFile || file;
const fileParseType = targetFile.parse_type;
- const fileName = targetFile.name || file.fileName;
+ const fileName = targetFile.name || file.fileName||file.name;
const suffix = useMemo(() => {
+console.log(fileName,3322);
return fileName?.split('.').pop()?.toLowerCase() || '';
}, [fileName]);
diff --git a/src/frontend/platform/src/pages/KnowledgePage/components/PreviewResult.tsx b/src/frontend/platform/src/pages/KnowledgePage/components/PreviewResult.tsx
index 15755c5e9..af641bce7 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/components/PreviewResult.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/components/PreviewResult.tsx
@@ -29,6 +29,8 @@ export type Partition = {
[key in string]: { text: string, type: string, part_id: string }
}
export default function PreviewResult({showPreview ,previewCount, rules, step, applyEachCell, cellGeneralConfig,kId,handlePreviewResult }: IProps) {
+ console.log(showPreview,rules,567);
+
const { id } = useParams()
const [chunks, setChunks] = useState([]) // 当前文件分块
@@ -71,13 +73,22 @@ export default function PreviewResult({showPreview ,previewCount, rules, step, a
const { fileList, pageHeaderFooter, chunkOverlap, chunkSize, enableFormula, forceOcr, knowledgeId
, retainImages, separator, separatorRule } = rules
const currentFile = fileList.find(file => file.id === selectId)
+
+ let preview_url
+ if(showPreview){
+ preview_url = currentFile.previewUrl ||currentFile?.filePath
+ }else {
+ preview_url=currentFile?.filePath
+ }
+ console.log(preview_url ,currentFile,6789);
+
captureAndAlertRequestErrorHoc(previewFileSplitApi({
// 缓存(修改规则后需要清空缓存, 切换文件使用缓存)
// previewCount变更时为重新预览分段操作,不使用缓存
cache: prevPreviewCountMapRef.current[currentFile.id] === previewCount,
knowledge_id: id||kId,
file_list: [{
- file_path: currentFile?.filePath,
+ file_path:preview_url,
excel_rule: applyEachCell
? currentFile.excelRule
: { ...cellGeneralConfig }
@@ -151,7 +162,7 @@ export default function PreviewResult({showPreview ,previewCount, rules, step, a
setChunks={setChunks}
partitions={partitions}
/>}
-
+
{/* 下拉框 - 右上角 */}
{(step === 3 ||(step===2 &&showPreview))&&(
diff --git a/src/frontend/platform/src/pages/KnowledgePage/qas.tsx b/src/frontend/platform/src/pages/KnowledgePage/qas.tsx
index d8985dbe5..a27264f07 100644
--- a/src/frontend/platform/src/pages/KnowledgePage/qas.tsx
+++ b/src/frontend/platform/src/pages/KnowledgePage/qas.tsx
@@ -251,14 +251,29 @@ export default function QasPage() {
}
}, [datalist])
- useEffect(() => {
- // @ts-ignore
- const libname = window.libname // 临时记忆
- if (libname) {
- localStorage.setItem('libname', window.libname)
+// 修改 useEffect 中处理标题的部分
+useEffect(() => {
+ // 处理 window.libname 可能的格式问题
+ let libName = '';
+ // 检查 window.libname 是否存在且有效
+ if (window.libname) {
+ // 处理数组格式([名称, 描述])
+ if (Array.isArray(window.libname) && window.libname.length > 0) {
+ libName = window.libname[0];
+ }
+ // 处理字符串格式
+ else if (typeof window.libname === 'string') {
+ libName = window.libname;
}
- setTitle(window.libname[0] || localStorage.getItem('libname'))
- }, [])
+ // 存储到 localStorage 时只存名称
+ localStorage.setItem('libname', libName);
+ }
+ // 从 localStorage 获取备份
+ else {
+ libName = localStorage.getItem('libname') || '';
+ }
+ setTitle(libName || t('unknownKnowledgeBase')); // 提供默认文本
+}, []);
const handleEnableSelected = async () => {
if (!selectedItems.length) return;
diff --git a/src/frontend/platform/src/pages/LogPage/useAppLog/appChatDetail.tsx b/src/frontend/platform/src/pages/LogPage/useAppLog/appChatDetail.tsx
index e9e07b088..b3f736ae2 100644
--- a/src/frontend/platform/src/pages/LogPage/useAppLog/appChatDetail.tsx
+++ b/src/frontend/platform/src/pages/LogPage/useAppLog/appChatDetail.tsx
@@ -1,14 +1,16 @@
+import AppAvator from "@/components/bs-comp/cardComponent/avatar";
import MessagePanne from "@/components/bs-comp/chatComponent/MessagePanne";
import { useMessageStore } from "@/components/bs-comp/chatComponent/messageStore";
import { LoadingIcon } from "@/components/bs-icons/loading";
import { Button } from "@/components/bs-ui/button";
import ShadTooltip from "@/components/ShadTooltipComponent";
+import { getDeleteFlowApi } from "@/controllers/API/flow";
import ChatMessages from "@/pages/BuildPage/flow/FlowChat/ChatMessages";
import { useMessageStore as useFlowMessageStore } from "@/pages/BuildPage/flow/FlowChat/messageStore";
import { useAssistantStore } from "@/store/assistantStore";
import { AppNumType } from "@/types/app";
import { ArrowLeft } from "lucide-react";
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
@@ -47,6 +49,8 @@ export default function AppChatDetail() {
}
}, [])
+ const logo = useAppAvatar(cid, type)
+
return
{loading &&
@@ -66,8 +70,8 @@ export default function AppChatDetail() {
{type === AppNumType.FLOW
- ? loadMoreFlowHistoryMsg(fid, true)} onMarkClick={null}>
- : loadMoreFlowHistoryMsg(fid, true)} onMarkClick={null}>
+ : loadMoreHistoryMsg(fid, true)}
>
}
@@ -75,3 +79,19 @@ export default function AppChatDetail() {
};
+
+
+const useAppAvatar = (cid, flowType) => {
+ const [logo, setLogo] = useState('')
+ const [title, setTitle] = useState('')
+ const loadAppDetail = async () => {
+ const lostflow = await getDeleteFlowApi(cid)
+ setLogo(lostflow.flow_logo)
+ setTitle(lostflow.flow_name)
+ }
+ useEffect(() => {
+ loadAppDetail()
+ }, [])
+
+ return
+}
\ No newline at end of file