feat(knowledge): enhance knowledge base management with improved interfaces and components

refactor(interfaces): add comprehensive documentation and type definitions
feat(components): implement empty state handling and team filtering in KnowledgeGridView
refactor(hooks): optimize knowledge list fetching with better parameter handling
style(interfaces): improve code readability with detailed comments
This commit is contained in:
2025-10-11 18:30:41 +08:00
parent 836ee763e3
commit d475a0e982
9 changed files with 463 additions and 82 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback } from 'react';
import React, { useState, useCallback, useMemo } from 'react';
import {
Box,
Typography,
@@ -20,6 +20,7 @@ import {
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import { useKnowledgeList } from '@/hooks/knowledge_hooks';
import { useUserData } from '@/hooks/useUserData';
import KnowledgeGridView from '@/components/KnowledgeGridView';
import type { IKnowledge } from '@/interfaces/database/knowledge';
@@ -29,37 +30,43 @@ const KnowledgeBaseList: React.FC = () => {
// 搜索和筛选状态
const [searchTerm, setSearchTerm] = useState('');
const [teamFilter, setTeamFilter] = useState('all');
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 12; // 每页显示12个知识库
// 获取用户数据(包含租户列表)
const { tenantList } = useUserData();
// 使用knowledge_hooks获取数据
const {
knowledgeBases,
total,
loading,
error,
currentPage,
setKeywords,
setCurrentPage,
refresh,
} = useKnowledgeList({
keywords: searchTerm,
page: currentPage,
page: 1,
page_size: pageSize,
});
// 处理搜索
const handleSearch = useCallback((value: string) => {
setSearchTerm(value);
setCurrentPage(1); // 搜索时重置到第一页
}, []);
setKeywords(value);
}, [setKeywords]);
// 处理团队筛选
const handleTeamFilterChange = useCallback((value: string) => {
setTeamFilter(value);
setCurrentPage(1); // 筛选时重置到第一页
}, []);
}, [setCurrentPage]);
// 处理分页变化
const handlePageChange = useCallback((_: React.ChangeEvent<unknown>, page: number) => {
setCurrentPage(page);
}, []);
}, [setCurrentPage]);
// 处理刷新
const handleRefresh = useCallback(() => {
@@ -88,22 +95,57 @@ const KnowledgeBaseList: React.FC = () => {
}, []);
// 根据团队筛选过滤知识库
const filteredKnowledgeBases = React.useMemo(() => {
const filteredKnowledgeBases = useMemo(() => {
if (!knowledgeBases) return [];
if (teamFilter === 'all') {
return knowledgeBases;
}
return knowledgeBases.filter(kb => {
if (teamFilter === 'me') return kb.permission === 'me';
if (teamFilter === 'team') return kb.permission === 'team';
return true;
});
}, [knowledgeBases, teamFilter]);
// 根据租户ID筛选
if (teamFilter !== 'all') {
return knowledgeBases.filter(kb => {
// 如果选择的是特定租户ID则筛选该租户的知识库
if (teamFilter === 'me') {
// 假设'me'表示当前用户的知识库,这里可以根据实际业务逻辑调整
return kb.permission === 'me' || kb.tenant_id === tenantList?.[0].tenant_id;
}
// 如果是具体的租户ID
return kb.tenant_id === teamFilter;
});
}
return knowledgeBases;
}, [knowledgeBases, teamFilter, tenantList]);
// 计算总页数
const totalPages = Math.ceil((knowledgeBases?.length || 0) / pageSize);
// 计算总页数(基于筛选后的结果)
const totalPages = Math.ceil(filteredKnowledgeBases.length / pageSize);
// 获取当前页的数据
const currentPageData = useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize;
return filteredKnowledgeBases.slice(startIndex, endIndex);
}, [filteredKnowledgeBases, currentPage, pageSize]);
// 构建团队筛选选项
const teamFilterOptions = useMemo(() => {
const options = [
{ value: 'all', label: '全部' },
];
// 添加租户选项
if (tenantList && tenantList.length > 0) {
tenantList.forEach(tenant => {
options.push({
value: tenant.tenant_id,
label: tenant.nickname || tenant.tenant_id,
});
});
}
return options;
}, [tenantList]);
return (
<Box sx={{ p: 3 }}>
@@ -145,9 +187,11 @@ const KnowledgeBaseList: React.FC = () => {
label="团队筛选"
onChange={(e) => handleTeamFilterChange(e.target.value)}
>
<MenuItem value="all"></MenuItem>
<MenuItem value="me"></MenuItem>
<MenuItem value="team"></MenuItem>
{teamFilterOptions.map(option => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
@@ -181,11 +225,14 @@ const KnowledgeBaseList: React.FC = () => {
{!loading && (
<>
<KnowledgeGridView
knowledgeBases={filteredKnowledgeBases}
knowledgeBases={currentPageData}
onEdit={handleEditKnowledge}
onDelete={handleDeleteKnowledge}
onView={handleViewKnowledge}
loading={loading}
searchTerm={searchTerm}
teamFilter={teamFilter}
onCreateKnowledge={handleCreateKnowledge}
/>
{/* 分页组件 */}
@@ -202,35 +249,11 @@ const KnowledgeBaseList: React.FC = () => {
showLastButton
/>
<Typography variant="body2" color="text.secondary" textAlign="center">
{knowledgeBases?.length || 0} {currentPage} {totalPages}
{filteredKnowledgeBases.length} {currentPage} {totalPages}
</Typography>
</Stack>
</Box>
)}
{/* 空状态 */}
{!loading && filteredKnowledgeBases.length === 0 && !error && (
<Box sx={{ textAlign: 'center', py: 8 }}>
<Typography variant="h6" color="text.secondary" gutterBottom>
{searchTerm || teamFilter !== 'all' ? '没有找到匹配的知识库' : '暂无知识库'}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
{searchTerm || teamFilter !== 'all'
? '尝试调整搜索条件或筛选器'
: '创建您的第一个知识库开始使用'
}
</Typography>
{(!searchTerm && teamFilter === 'all') && (
<Button
variant="contained"
startIcon={<AddIcon />}
onClick={handleCreateKnowledge}
>
</Button>
)}
</Box>
)}
</>
)}
</Box>