From 650c41dc411ba1408600b23f04a9a1c65d4e1f37 Mon Sep 17 00:00:00 2001 From: "guangfei.zhao" Date: Sat, 11 Oct 2025 11:31:24 +0800 Subject: [PATCH] refactor(layout): migrate styled components to sx prop in Header and Sidebar feat(pages): add new KnowledgeBaseList and Login pages with complete functionality feat(services): implement knowledge service with comprehensive API methods feat(hooks): add login hooks for authentication and form management --- src/components/Layout/Header.tsx | 136 +++++---- src/components/Layout/Sidebar.tsx | 145 +++++---- src/hooks/{login-hooks.ts => login_hooks.ts} | 0 .../{ => knowledge}/KnowledgeBaseList.tsx | 0 src/pages/{ => login}/Login.tsx | 4 +- src/routes/index.tsx | 4 +- src/services/knowledge_service.ts | 286 ++++++++++++++++++ 7 files changed, 450 insertions(+), 125 deletions(-) rename src/hooks/{login-hooks.ts => login_hooks.ts} (100%) rename src/pages/{ => knowledge}/KnowledgeBaseList.tsx (100%) rename src/pages/{ => login}/Login.tsx (98%) create mode 100644 src/services/knowledge_service.ts diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index a704839..a5de7a6 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -1,72 +1,82 @@ -import { Box, InputBase, styled } from '@mui/material'; +import { Box, InputBase } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import AccountCircleIcon from '@mui/icons-material/AccountCircle'; - -const HeaderContainer = styled(Box)(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - padding: '0 20px', - height: '60px', - backgroundColor: '#FFFFFF', - color: '#333', - boxShadow: '0 1px 3px rgba(0,0,0,0.1)', - borderBottom: '1px solid #E5E5E5', -})); - -const BrandTitle = styled(Box)(({ theme }) => ({ - fontSize: '1.2rem', - fontWeight: 'bold', - color: '#333', -})); - -const SearchBox = styled(Box)(({ theme }) => ({ - display: 'flex', - alignItems: 'center', - backgroundColor: '#F8F9FA', - borderRadius: '6px', - padding: '6px 12px', - width: '320px', - border: '1px solid #E5E5E5', - marginLeft: 'auto', - marginRight: '20px', - '&:focus-within': { - borderColor: theme.palette.primary.main, - boxShadow: `0 0 0 2px rgba(226,0,116,0.1)`, - }, - '& .MuiInputBase-input': { - border: 'none', - outline: 'none', - backgroundColor: 'transparent', - fontSize: '14px', - color: '#333', - '&::placeholder': { - color: '#999', - }, - }, -})); - -const SearchInput = styled(InputBase)(({ theme }) => ({ - marginLeft: '8px', - flex: 1, - fontSize: '0.875rem', -})); - -const UserAvatar = styled(AccountCircleIcon)(({ theme }) => ({ - color: '#666', - cursor: 'pointer', - fontSize: '2rem', -})); +import LanguageSwitcher from '../LanguageSwitcher'; const Header = () => { return ( - - RAG Dashboard - + + + RAG Dashboard + + + - - - - + + + + + + + ); }; diff --git a/src/components/Layout/Sidebar.tsx b/src/components/Layout/Sidebar.tsx index 271fe09..0a1070f 100644 --- a/src/components/Layout/Sidebar.tsx +++ b/src/components/Layout/Sidebar.tsx @@ -1,72 +1,101 @@ -import { Box, List, ListItem, ListItemButton, ListItemText, Typography, styled } from '@mui/material'; +import { Box, List, ListItemButton, ListItemText, Typography } from '@mui/material'; import { Link, useLocation } from 'react-router-dom'; - -const SidebarContainer = styled(Box)(({ theme }) => ({ - width: '240px', - backgroundColor: '#1E1E24', - color: '#DDD', - height: '100vh', - padding: '1rem 0', - display: 'flex', - flexDirection: 'column', -})); - -const Logo = styled(Typography)(({ theme }) => ({ - fontSize: '1.05rem', - fontWeight: 600, - padding: '0 1.25rem 1rem', - margin: '0 0 0.5rem', - color: '#FFF', - letterSpacing: '0.5px', -})); - -const NavItem = styled(ListItemButton)<{ active?: boolean }>(({ active, theme }) => ({ - color: active ? '#FFF' : '#B9B9C2', - backgroundColor: active ? 'rgba(226,0,116,0.12)' : 'transparent', - borderLeft: active ? `4px solid ${theme.palette.primary.main}` : '4px solid transparent', - fontWeight: active ? 600 : 'normal', - '&:hover': { - backgroundColor: 'rgba(255,255,255,0.05)', - color: '#FFF', - }, - '& .MuiListItemText-primary': { - fontSize: '0.9rem', - }, -})); - -const Footer = styled(Box)(({ theme }) => ({ - marginTop: 'auto', - padding: '20px', - fontSize: '0.75rem', - opacity: 0.7, -})); +import DashboardOutlinedIcon from '@mui/icons-material/DashboardOutlined'; +import LibraryBooksOutlinedIcon from '@mui/icons-material/LibraryBooksOutlined'; +import AccountTreeOutlinedIcon from '@mui/icons-material/AccountTreeOutlined'; +import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined'; +import StorageOutlinedIcon from '@mui/icons-material/StorageOutlined'; +import ExtensionOutlinedIcon from '@mui/icons-material/ExtensionOutlined'; const navItems = [ - { text: 'Overview', path: '/' }, - { text: 'Knowledge Bases', path: '/kb-list' }, - { text: 'RAG Pipeline', path: '/pipeline-config' }, - { text: 'Operations', path: '/dashboard' }, - { text: 'Models & Resources', path: '/models-resources' }, - { text: 'MCP', path: '/mcp' }, + { text: 'Overview', path: '/', icon: DashboardOutlinedIcon }, + { text: 'Knowledge Bases', path: '/kb-list', icon: LibraryBooksOutlinedIcon }, + { text: 'RAG Pipeline', path: '/pipeline-config', icon: AccountTreeOutlinedIcon }, + { text: 'Operations', path: '/dashboard', icon: SettingsOutlinedIcon }, + { text: 'Models & Resources', path: '/models-resources', icon: StorageOutlinedIcon }, + { text: 'MCP', path: '/mcp', icon: ExtensionOutlinedIcon }, ]; const Sidebar = () => { const location = useLocation(); return ( - - RAGflow Prototype + + + RAGflow Prototype + + - {navItems.map((item) => ( - - - - - - ))} + {navItems.map((item) => { + const IconComponent = item.icon; + const isActive = location.pathname === item.path; + + return ( + + + + + + + ); + })} -
© 2025 RAG Demo
-
+ + + © 2025 RAG Demo + + ); }; diff --git a/src/hooks/login-hooks.ts b/src/hooks/login_hooks.ts similarity index 100% rename from src/hooks/login-hooks.ts rename to src/hooks/login_hooks.ts diff --git a/src/pages/KnowledgeBaseList.tsx b/src/pages/knowledge/KnowledgeBaseList.tsx similarity index 100% rename from src/pages/KnowledgeBaseList.tsx rename to src/pages/knowledge/KnowledgeBaseList.tsx diff --git a/src/pages/Login.tsx b/src/pages/login/Login.tsx similarity index 98% rename from src/pages/Login.tsx rename to src/pages/login/Login.tsx index 2a6cb85..0f6be04 100644 --- a/src/pages/Login.tsx +++ b/src/pages/login/Login.tsx @@ -16,8 +16,8 @@ import { Tabs, Tab } from '@mui/material'; -import LanguageSwitcher from '../components/LanguageSwitcher'; -import { useLoginPage } from '../hooks/login-hooks'; +import LanguageSwitcher from '../../components/LanguageSwitcher'; +import { useLoginPage } from '../../hooks/login_hooks'; const Login = () => { const { t } = useTranslation(); diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 6d28e14..4b9dbfe 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,8 +1,8 @@ import { Routes, Route, Navigate } from 'react-router-dom'; import MainLayout from '../components/Layout/MainLayout'; -import Login from '../pages/Login'; +import Login from '../pages/login/Login'; import Home from '../pages/Home'; -import KnowledgeBaseList from '../pages/KnowledgeBaseList'; +import KnowledgeBaseList from '../pages/knowledge/KnowledgeBaseList'; import PipelineConfig from '../pages/PipelineConfig'; import Dashboard from '../pages/Dashboard'; import ModelsResources from '../pages/ModelsResources'; diff --git a/src/services/knowledge_service.ts b/src/services/knowledge_service.ts new file mode 100644 index 0000000..895b412 --- /dev/null +++ b/src/services/knowledge_service.ts @@ -0,0 +1,286 @@ +import api from './api'; +import request, { post } from '@/utils/request'; +import type { + IFetchKnowledgeListRequestBody, + IFetchKnowledgeListRequestParams, + IFetchDocumentListRequestBody, + ITestRetrievalRequestBody, +} from '@/interfaces/request/knowledge'; +import type { + IKnowledge, + IKnowledgeFile, + IChunk, + IRenameTag, + ParserConfig, +} from '@/interfaces/database/knowledge'; + +// 知识库相关API服务 +const knowledgeService = { + // ===== 知识库管理 ===== + + // 获取知识库列表 + getKnowledgeList: ( + params?: IFetchKnowledgeListRequestParams, + body?: IFetchKnowledgeListRequestBody + ) => { + return request.post(api.kb_list, { data: body || {}, params }); + }, + + // 创建知识库 + createKnowledge: (data: Partial) => { + return post(api.create_kb, data); + }, + + // 更新知识库 + updateKnowledge: (data: Partial) => { + return post(api.update_kb, data); + }, + + // 删除知识库 + removeKnowledge: (data: { kb_id: string }) => { + return post(api.rm_kb, data); + }, + + // 获取知识库详情 + getKnowledgeDetail: (params: { kb_id: string }) => { + return request.get(api.get_kb_detail, { params }); + }, + + // 获取知识库基本信息 + getKnowledgeBasicInfo: (params: { kb_id: string }) => { + return request.get(api.getKnowledgeBasicInfo, { params }); + }, + + // 获取知识库元数据 + getKnowledgeMeta: (params: { kb_id: string }) => { + return request.get(api.getMeta, { params }); + }, + + // ===== 文档管理 ===== + + // 获取文档列表 + getDocumentList: ( + params?: IFetchKnowledgeListRequestParams, + body?: IFetchDocumentListRequestBody + ) => { + return request.post(api.get_document_list, { data: body || {}, params }); + }, + + // 创建文档 + createDocument: (data: any) => { + return post(api.document_create, data); + }, + + // 上传文档 + uploadDocument: (data: FormData) => { + return post(api.document_upload, data); + }, + + // 上传并解析文档 + uploadAndParseDocument: (data: FormData) => { + return post(api.upload_and_parse, data); + }, + + // 解析文档 + parseDocument: (data: any) => { + return post(api.parse, data); + }, + + // 重命名文档 + renameDocument: (data: { doc_id: string; name: string }) => { + return post(api.document_rename, data); + }, + + // 删除文档 + removeDocument: (data: { doc_ids: string[] }) => { + return post(api.document_rm, data); + }, + + // 删除文档(DELETE方法) + deleteDocument: (doc_id: string) => { + return request.delete(`${api.document_delete}/${doc_id}`); + }, + + // 更改文档状态 + changeDocumentStatus: (data: { doc_ids: string[]; status: string }) => { + return post(api.document_change_status, data); + }, + + // 运行文档处理 + runDocument: (data: { doc_ids: string[] }) => { + return post(api.document_run, data); + }, + + // 更改文档解析器 + changeDocumentParser: (data: { doc_id: string; parser_config: ParserConfig }) => { + return post(api.document_change_parser, data); + }, + + // 获取文档缩略图 + getDocumentThumbnails: (params: { doc_id: string }) => { + return request.get(api.document_thumbnails, { params }); + }, + + // 获取文档文件 + getDocumentFile: (params: { doc_id: string }) => { + return request.get(api.get_document_file, { params }); + }, + + // 获取文档信息 + getDocumentInfos: (data: { doc_ids: string[] }) => { + return post(api.document_infos, data); + }, + + // 设置文档元数据 + setDocumentMeta: (data: any) => { + return post(api.setMeta, data); + }, + + // 网页爬取 + webCrawl: (data: { url: string; kb_id: string }) => { + return post(api.web_crawl, data); + }, + + // 获取文档过滤器 + getDocumentFilter: (data: { kb_id: string }) => { + return post(api.get_dataset_filter, data); + }, + + // ===== 分块管理 ===== + + // 获取分块列表 + getChunkList: (data: any) => { + return post(api.chunk_list, data); + }, + + // 创建分块 + createChunk: (data: Partial) => { + return post(api.create_chunk, data); + }, + + // 更新分块 + updateChunk: (data: Partial) => { + return post(api.set_chunk, data); + }, + + // 获取分块详情 + getChunk: (params: { chunk_id: string }) => { + return request.get(api.get_chunk, { params }); + }, + + // 切换分块状态 + switchChunk: (data: { chunk_ids: string[]; available_int: number }) => { + return post(api.switch_chunk, data); + }, + + // 删除分块 + removeChunk: (data: { chunk_ids: string[] }) => { + return post(api.rm_chunk, data); + }, + + // ===== 检索测试 ===== + + // 检索测试 + retrievalTest: (data: ITestRetrievalRequestBody) => { + return post(api.retrieval_test, data); + }, + + // 外部检索测试 + retrievalTestShare: (data: ITestRetrievalRequestBody) => { + return post(api.retrievalTestShare, data); + }, + + // ===== 知识图谱 ===== + + // 获取知识图谱 + getKnowledgeGraph: (knowledgeId: string) => { + return request.get(api.getKnowledgeGraph(knowledgeId)); + }, + + // 删除知识图谱 + deleteKnowledgeGraph: (knowledgeId: string) => { + return request.delete(api.getKnowledgeGraph(knowledgeId)); + }, + + // 获取分块知识图谱 + getChunkKnowledgeGraph: (params: { chunk_id: string }) => { + return request.get(api.knowledge_graph, { params }); + }, + + // ===== 标签管理 ===== + + // 获取标签列表 + getTagList: (knowledgeId: string) => { + return request.get(api.listTag(knowledgeId)); + }, + + // 根据知识库ID获取标签 + getTagsByKnowledgeIds: (params: { kb_ids: string[] }) => { + return request.get(api.listTagByKnowledgeIds, { params }); + }, + + // 删除标签 + removeTag: (knowledgeId: string, tags: string[]) => { + return post(api.removeTag(knowledgeId), { tags }); + }, + + // 重命名标签 + renameTag: (knowledgeId: string, { fromTag, toTag }: IRenameTag) => { + return post(api.renameTag(knowledgeId), { fromTag, toTag }); + }, + + // ===== 数据管道 ===== + + // 获取数据管道日志 + getDataPipelineLog: ( + params?: IFetchKnowledgeListRequestParams, + body?: IFetchDocumentListRequestBody + ) => { + return request.post(api.fetchDataPipelineLog, { data: body || {}, params }); + }, + + // 获取管道详情 + getPipelineDetail: (params: { task_id: string }) => { + return request.get(api.get_pipeline_detail, { params }); + }, + + // 获取管道数据集日志 + getPipelineDatasetLogs: ( + params?: IFetchKnowledgeListRequestParams, + body?: IFetchDocumentListRequestBody + ) => { + return request.post(api.fetchPipelineDatasetLogs, { data: body || {}, params }); + }, + + // 运行GraphRAG + runGraphRag: (data: { kb_id: string }) => { + return post(api.runGraphRag, data); + }, + + // 跟踪GraphRAG + traceGraphRag: (params: { kb_id: string }) => { + return request.get(api.traceGraphRag, { params }); + }, + + // 运行Raptor + runRaptor: (data: { kb_id: string }) => { + return post(api.runRaptor, data); + }, + + // 跟踪Raptor + traceRaptor: (params: { kb_id: string }) => { + return request.get(api.traceRaptor, { params }); + }, + + // 解绑管道任务 + unbindPipelineTask: (params: { kb_id: string; type: string }) => { + return request.delete(api.unbindPipelineTask(params)); + }, + + // 重新运行管道 + pipelineRerun: (data: any) => { + return post(api.pipelineRerun, data); + }, +}; + +export default knowledgeService; \ No newline at end of file