import React, { useState, useEffect, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { showNotification } from '../../store/notification.slice'; import { fetchKnowledgeBases, searchKnowledgeBases, createKnowledgeBase, deleteKnowledgeBase, requestKnowledgeBaseAccess, } from '../../store/knowledgeBase/knowledgeBase.thunks'; import { clearSearchResults } from '../../store/knowledgeBase/knowledgeBase.slice'; import SvgIcon from '../../components/SvgIcon'; import AccessRequestModal from '../../components/AccessRequestModal'; import CreateKnowledgeBaseModal from '../../components/CreateKnowledgeBaseModal'; import Pagination from '../../components/Pagination'; import SearchBar from '../../components/SearchBar'; import ApiModeSwitch from '../../components/ApiModeSwitch'; import debounce from 'lodash/debounce'; // 导入拆分的组件 import KnowledgeBaseList from './components/KnowledgeBaseList'; export default function KnowledgeBase() { const dispatch = useDispatch(); const navigate = useNavigate(); const [showCreateModal, setShowCreateModal] = useState(false); const [showAccessRequestModal, setShowAccessRequestModal] = useState(false); const [formErrors, setFormErrors] = useState({}); const [accessRequestKnowledgeBase, setAccessRequestKnowledgeBase] = useState({ id: '', title: '', }); const [isSubmittingRequest, setIsSubmittingRequest] = useState(false); const [createdKnowledgeBaseId, setCreatedKnowledgeBaseId] = useState(null); // 获取当前用户信息 const currentUser = useSelector((state) => state.auth.user); const [newKnowledgeBase, setNewKnowledgeBase] = useState({ name: '', desc: '', type: 'private', // 默认为私有知识库 department: currentUser?.department || '', group: currentUser?.group || '', }); // Search state const [searchKeyword, setSearchKeyword] = useState(''); const [isSearching, setIsSearching] = useState(false); // Pagination state const [pagination, setPagination] = useState({ page: 1, page_size: 10, }); // Get knowledge bases from Redux store // 更新为新的Redux状态结构 const knowledgeBases = useSelector((state) => state.knowledgeBase.knowledgeBases); const loading = useSelector((state) => state.knowledgeBase.loading); const paginationData = useSelector((state) => state.knowledgeBase.pagination); const error = useSelector((state) => state.knowledgeBase.error); const operationStatus = useSelector((state) => state.knowledgeBase.editStatus); const operationError = useSelector((state) => state.knowledgeBase.error); // 从Redux获取搜索结果和加载状态 const searchResults = useSelector((state) => state.knowledgeBase.searchResults); const searchLoading = useSelector((state) => state.knowledgeBase.searchLoading); // Determine which data to display based on search state const displayData = isSearching ? searchResults : knowledgeBases; const displayTotal = paginationData.total; const displayStatus = loading ? 'loading' : 'succeeded'; const displayError = error; // Fetch knowledge bases when component mounts or pagination changes useEffect(() => { if (!isSearching) { dispatch(fetchKnowledgeBases(pagination)); } else if (searchKeyword.trim()) { dispatch( searchKnowledgeBases({ keyword: searchKeyword, page: pagination.page, page_size: pagination.page_size, }) ); } }, [dispatch, pagination.page, pagination.page_size, isSearching, searchKeyword]); // 实时搜索处理函数 const debouncedSearch = useCallback( debounce((keyword) => { if (keyword.trim()) { dispatch( searchKnowledgeBases({ keyword, page: 1, page_size: 5, }) ); } else { dispatch(clearSearchResults()); } }, 300), [dispatch] ); // Handle search input change const handleSearchInputChange = (e) => { const value = e.target.value; setSearchKeyword(value); // 实时搜索 if (value.trim()) { debouncedSearch(value); } else { dispatch(clearSearchResults()); } }; // Handle search submit const handleSearch = (e) => { e.preventDefault(); if (searchKeyword.trim()) { setIsSearching(true); setPagination((prev) => ({ ...prev, page: 1 })); // Reset to first page dispatch( searchKnowledgeBases({ keyword: searchKeyword, page: 1, page_size: pagination.page_size, }) ); } else { // If search is empty, reset to normal list view handleClearSearch(); } }; // Handle clear search const handleClearSearch = () => { setSearchKeyword(''); setIsSearching(false); setPagination((prev) => ({ ...prev, page: 1 })); // Reset to first page dispatch(clearSearchResults()); }; // Show loading state while fetching data const isLoading = displayStatus === 'loading'; // Show error notification if fetch fails useEffect(() => { if (displayStatus === 'failed' && displayError) { dispatch( showNotification({ message: `获取知识库列表失败: ${displayError.message || displayError}`, type: 'danger', }) ); } }, [displayStatus, displayError, dispatch]); // Show notification for operation status useEffect(() => { if (operationStatus === 'successful') { // 操作成功通知由具体函数处理,这里只刷新列表 // Refresh the list after successful operation if (isSearching && searchKeyword.trim()) { dispatch( searchKnowledgeBases({ keyword: searchKeyword, page: pagination.page, page_size: pagination.page_size, }) ); } else { dispatch(fetchKnowledgeBases(pagination)); } } else if (operationStatus === 'failed' && operationError) { dispatch( showNotification({ message: `操作失败: ${operationError.message || operationError}`, type: 'danger', }) ); } }, [operationStatus, operationError, dispatch, pagination, isSearching, searchKeyword]); // Handle pagination change const handlePageChange = (newPage) => { setPagination((prev) => ({ ...prev, page: newPage, })); }; // Handle page size change const handlePageSizeChange = (newPageSize) => { setPagination({ page: 1, // Reset to first page when changing page size page_size: newPageSize, }); }; const handleInputChange = (e) => { const { name, value } = e.target; // 不允许修改部门和组别字段 if (name === 'department' || name === 'group') { return; } // 检查用户是否有权限选择指定的知识库类型 if (name === 'type') { const role = currentUser?.role; let allowed = false; // 根据角色判断可以选择的知识库类型 if (role === 'admin') { // 管理员可以选择任何类型 allowed = ['admin', 'leader', 'member', 'private', 'secret'].includes(value); } else if (role === 'leader') { // 组长只能选择 member 和 private allowed = ['member', 'private'].includes(value); } else { // 普通成员只能选择 private allowed = value === 'private'; } if (!allowed) { dispatch( showNotification({ message: '您没有权限创建此类型的知识库', type: 'warning', }) ); return; } } setNewKnowledgeBase((prev) => ({ ...prev, [name]: value, })); // Clear error when user types if (formErrors[name]) { setFormErrors((prev) => ({ ...prev, [name]: '', })); } }; const validateCreateForm = () => { const errors = {}; if (!newKnowledgeBase.name.trim()) { errors.name = '请输入知识库名称'; } if (!newKnowledgeBase.desc.trim()) { errors.desc = '请输入知识库描述'; } if (!newKnowledgeBase.type) { errors.type = '请选择知识库类型'; } setFormErrors(errors); return Object.keys(errors).length === 0; }; const handleCreateKnowledgeBase = async () => { // Validate form if (!validateCreateForm()) { return; } try { // Dispatch create knowledge base action const resultAction = await dispatch( createKnowledgeBase({ name: newKnowledgeBase.name, desc: newKnowledgeBase.desc, description: newKnowledgeBase.desc, type: newKnowledgeBase.type, department: newKnowledgeBase.department, group: newKnowledgeBase.group, }) ); console.log('创建知识库返回数据:', resultAction); // Check if the action was successful if (createKnowledgeBase.fulfilled.match(resultAction)) { console.log('创建成功,payload:', resultAction.payload); const { knowledge_base } = resultAction.payload; const { id } = knowledge_base; // Get ID from payload and navigate if (id) { console.log('新知识库ID:', id); // 显示成功通知 dispatch( showNotification({ message: '知识库创建成功', type: 'success', }) ); // 直接导航到新创建的知识库详情页 navigate(`/knowledge-base/${id}`); } else { console.error('无法获取新知识库ID:', resultAction.payload); dispatch( showNotification({ message: '创建成功,但无法获取知识库ID', type: 'warning', }) ); } } else { console.error('创建知识库失败:', resultAction.error); dispatch( showNotification({ message: `创建知识库失败: ${resultAction.error?.message || '未知错误'}`, type: 'danger', }) ); } } catch (error) { console.error('创建知识库出错:', error); dispatch( showNotification({ message: `创建知识库出错: ${error.message || '未知错误'}`, type: 'danger', }) ); } // Reset form and close modal setNewKnowledgeBase({ name: '', desc: '', type: 'private', department: '', group: '' }); setFormErrors({}); setShowCreateModal(false); }; // Handle card click to navigate to knowledge base detail const handleCardClick = (id, permissions) => { // 检查用户是否有读取权限 if (!permissions || permissions.can_read === false) { dispatch( showNotification({ message: '您没有访问此知识库的权限,请先申请权限', type: 'warning', }) ); return; } // 有权限则跳转到详情页 navigate(`/knowledge-base/${id}/datasets`); }; const handleRequestAccess = (id, title) => { setAccessRequestKnowledgeBase({ id, title, }); setShowAccessRequestModal(true); }; const handleSubmitAccessRequest = async (requestData) => { setIsSubmittingRequest(true); try { // 使用权限服务发送请求 await requestKnowledgeBaseAccess(requestData); dispatch( showNotification({ message: '权限申请已提交', type: 'success', }) ); // Close modal setShowAccessRequestModal(false); } catch (error) { dispatch( showNotification({ message: `权限申请失败: ${error.response?.data?.message || '请稍后重试'}`, type: 'danger', }) ); } finally { setIsSubmittingRequest(false); } }; const handleDelete = (e, id) => { e.preventDefault(); e.stopPropagation(); // Dispatch delete knowledge base action dispatch(deleteKnowledgeBase(id)) .unwrap() .then(() => { dispatch( showNotification({ message: '知识库已删除', type: 'success', }) ); }) .catch((error) => { dispatch( showNotification({ message: `删除失败: ${error.message || '未知错误'}`, type: 'danger', }) ); }); }; // Calculate total pages const totalPages = Math.ceil(displayTotal / pagination.page_size); // 打开创建知识库弹窗 const handleOpenCreateModal = () => { // 默认知识库类型基于用户角色 let defaultType = 'private'; // 确保部门和组别字段使用当前用户的信息 setNewKnowledgeBase((prev) => ({ ...prev, department: currentUser?.department || '', group: currentUser?.group || '', type: defaultType, })); setShowCreateModal(true); }; // 处理点击搜索结果 const handleSearchResultClick = (id, permissions) => { if (permissions?.can_read) { navigate(`/knowledge-base/${id}/datasets`); } }; return (
{isSearching && (
搜索结果: "{searchKeyword}" - 找到 {displayTotal} 个知识库
)} {isLoading ? (
加载中...
) : ( <> {/* Pagination */} {totalPages > 1 && ( )} )} {/* 新建知识库弹窗 */} setShowCreateModal(false)} onChange={handleInputChange} onSubmit={handleCreateKnowledgeBase} currentUser={currentUser} /> {/* 申请权限弹窗 */} setShowAccessRequestModal(false)} onSubmit={handleSubmitAccessRequest} isSubmitting={isSubmittingRequest} />
); }