diff --git a/web/pages/KnowledgeBase.tsx b/web/pages/KnowledgeBase.tsx index 4814ef6..f5c09e9 100644 --- a/web/pages/KnowledgeBase.tsx +++ b/web/pages/KnowledgeBase.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState, useRef } from 'react'; import { Search, Plus, FileText, Upload, ArrowLeft, CloudUpload, File as FileIcon, X, Pencil, Trash2, Settings2, MoreHorizontal } from 'lucide-react'; import { Button, Input, TableHeader, TableRow, TableHead, TableCell, Card, Dialog, Badge } from '../components/UI'; -import { KnowledgeBase } from '../types'; -import { createKnowledgeBase, deleteKnowledgeBase, deleteKnowledgeDocument, fetchKnowledgeBaseById, fetchKnowledgeBases, fetchLLMModels, searchKnowledgeBase, updateKnowledgeBase, uploadKnowledgeDocument, type KnowledgeSearchResultItem } from '../services/backendApi'; +import { KnowledgeBase, KnowledgeDocument } from '../types'; +import { createKnowledgeBase, deleteKnowledgeBase, deleteKnowledgeDocument, fetchKnowledgeBaseById, fetchKnowledgeBases, fetchLLMModels, indexKnowledgeDocument, searchKnowledgeBase, updateKnowledgeBase, uploadKnowledgeDocument, type KnowledgeSearchResultItem } from '../services/backendApi'; const EMBEDDING_OPTIONS = [ 'text-embedding-3-small', @@ -189,6 +189,15 @@ export const KnowledgeBasePage: React.FC = () => { onImport={() => setIsUploadOpen(true)} onEdit={() => openEditKb(selectedKb)} onDelete={() => handleDeleteKb(selectedKb)} + onIndexDocument={async (docId, content) => { + try { + await indexKnowledgeDocument(selectedKb.id, docId, content); + await refreshKnowledgeBases(); + } catch (error: any) { + console.error(error); + throw new Error(error?.message || '索引失败。'); + } + }} onDeleteDocument={async (docId) => { try { await deleteKnowledgeDocument(selectedKb.id, docId); @@ -452,9 +461,13 @@ const KnowledgeBaseDetail: React.FC<{ onImport: () => void; onEdit: () => void; onDelete: () => void; + onIndexDocument: (docId: string, content: string) => Promise; onDeleteDocument: (docId: string) => void; -}> = ({ kb, onBack, onImport, onEdit, onDelete, onDeleteDocument }) => { +}> = ({ kb, onBack, onImport, onEdit, onDelete, onIndexDocument, onDeleteDocument }) => { const [docSearch, setDocSearch] = useState(''); + const [indexingDoc, setIndexingDoc] = useState(null); + const [indexContent, setIndexContent] = useState(''); + const [indexing, setIndexing] = useState(false); const [debugQuery, setDebugQuery] = useState(''); const [debugTopK, setDebugTopK] = useState(5); const [debugLoading, setDebugLoading] = useState(false); @@ -489,6 +502,26 @@ const KnowledgeBaseDetail: React.FC<{ return `${(score * 100).toFixed(2)}%`; }; + const handleStartIndex = async () => { + if (!indexingDoc) return; + const content = indexContent.trim(); + if (!content) { + alert('请输入文档内容后再开始索引'); + return; + } + + try { + setIndexing(true); + await onIndexDocument(indexingDoc.id, content); + setIndexingDoc(null); + setIndexContent(''); + } catch (error: any) { + alert(error?.message || '索引失败'); + } finally { + setIndexing(false); + } + }; + return (
@@ -546,6 +579,17 @@ const KnowledgeBaseDetail: React.FC<{ {doc.chunkCount ?? 0} {doc.uploadDate} + + + + } + > +
+

+ 当前后端索引接口需要提交文本内容。请粘贴要写入向量库的文档全文或片段后执行。 +

+