feat(knowledge): add team filtering and improve request handling

This commit is contained in:
2025-10-29 13:24:19 +08:00
parent ef0a99ea30
commit 184c232cc8
3 changed files with 58 additions and 56 deletions

View File

@@ -1,7 +1,8 @@
import { useState, useEffect, useCallback, useMemo } from 'react'; import { useState, useEffect, useCallback, useMemo } from 'react';
import knowledgeService from '@/services/knowledge_service'; import knowledgeService from '@/services/knowledge_service';
import type { IKnowledge, IKnowledgeGraph, IKnowledgeResult } from '@/interfaces/database/knowledge'; import type { IKnowledge, IKnowledgeGraph, IKnowledgeResult } from '@/interfaces/database/knowledge';
import type { IFetchKnowledgeListRequestParams } from '@/interfaces/request/knowledge'; import type { IFetchKnowledgeListRequestBody, IFetchKnowledgeListRequestParams } from '@/interfaces/request/knowledge';
import logger from '@/utils/logger';
/** /**
{ {
@@ -64,8 +65,9 @@ export interface UseKnowledgeListState {
// 知识库列表Hook返回值接口 // 知识库列表Hook返回值接口
export interface UseKnowledgeListReturn extends UseKnowledgeListState { export interface UseKnowledgeListReturn extends UseKnowledgeListState {
fetchKnowledgeBases: (params?: IFetchKnowledgeListRequestParams) => Promise<void>; fetchKnowledgeBases: (params?: IFetchKnowledgeListRequestParams & IFetchKnowledgeListRequestBody) => Promise<void>;
setKeywords: (keywords: string) => void; setKeywords: (keywords: string) => void;
setTeamFilter: (teamFilter: string[]) => void;
setCurrentPage: (page: number) => void; setCurrentPage: (page: number) => void;
setPageSize: (size: number) => void; setPageSize: (size: number) => void;
refresh: () => Promise<void>; refresh: () => Promise<void>;
@@ -76,7 +78,7 @@ export interface UseKnowledgeListReturn extends UseKnowledgeListState {
* 支持关键词搜索、分页等功能 * 支持关键词搜索、分页等功能
*/ */
export const useKnowledgeList = ( export const useKnowledgeList = (
initialParams?: IFetchKnowledgeListRequestParams initialParams?: IFetchKnowledgeListRequestParams & IFetchKnowledgeListRequestBody
): UseKnowledgeListReturn => { ): UseKnowledgeListReturn => {
const [knowledgeBases, setKnowledgeBases] = useState<IKnowledge[]>([]); const [knowledgeBases, setKnowledgeBases] = useState<IKnowledge[]>([]);
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
@@ -85,11 +87,12 @@ export const useKnowledgeList = (
const [currentPage, setCurrentPage] = useState(initialParams?.page || 1); const [currentPage, setCurrentPage] = useState(initialParams?.page || 1);
const [pageSize, setPageSize] = useState(initialParams?.page_size || 10); const [pageSize, setPageSize] = useState(initialParams?.page_size || 10);
const [keywords, setKeywords] = useState(initialParams?.keywords || ''); const [keywords, setKeywords] = useState(initialParams?.keywords || '');
const [filterData, setFilterData] = useState<any>({});
/** /**
* 获取知识库列表 * 获取知识库列表
*/ */
const fetchKnowledgeBases = useCallback(async (params?: IFetchKnowledgeListRequestParams) => { const fetchKnowledgeBases = useCallback(async (params?: IFetchKnowledgeListRequestParams & IFetchKnowledgeListRequestBody) => {
try { try {
setLoading(true); setLoading(true);
setError(null); setError(null);
@@ -102,13 +105,17 @@ export const useKnowledgeList = (
}; };
// 构建请求体 // 构建请求体
const requestBody: any = {}; const requestBody: IFetchKnowledgeListRequestBody = {};
if (queryParams.keywords && queryParams.keywords.trim()) { if (params?.owner_ids && params.owner_ids.length > 0) {
requestBody.keywords = queryParams.keywords.trim(); requestBody.owner_ids = params.owner_ids;
}
if (filterData.owner_ids && filterData.owner_ids.length > 0) {
requestBody.owner_ids = filterData.owner_ids;
} }
// 构建查询参数 // 构建查询参数
const requestParams: any = {}; const requestParams: IFetchKnowledgeListRequestParams = {};
if (queryParams.page) { if (queryParams.page) {
requestParams.page = queryParams.page; requestParams.page = queryParams.page;
} }
@@ -139,7 +146,7 @@ export const useKnowledgeList = (
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, [keywords, currentPage, pageSize]); }, [keywords, currentPage, pageSize, filterData]);
/** /**
* 刷新当前页面数据 * 刷新当前页面数据
@@ -156,6 +163,10 @@ export const useKnowledgeList = (
setCurrentPage(1); setCurrentPage(1);
}, []); }, []);
const handleSetTeamFilter = useCallback((newTeamFilter: string[]) => {
setFilterData({ ...filterData, owner_ids: newTeamFilter });
}, []);
/** /**
* 设置当前页 * 设置当前页
*/ */
@@ -173,8 +184,10 @@ export const useKnowledgeList = (
// 当关键词、页码或页面大小变化时重新获取数据 // 当关键词、页码或页面大小变化时重新获取数据
useEffect(() => { useEffect(() => {
logger.info('useEffect currentPage:', currentPage);
logger.info('useEffect pageSize:', pageSize);
fetchKnowledgeBases(); fetchKnowledgeBases();
}, [keywords, currentPage, pageSize]); }, [currentPage, pageSize, filterData, keywords]);
return { return {
knowledgeBases, knowledgeBases,
@@ -186,6 +199,7 @@ export const useKnowledgeList = (
keywords, keywords,
fetchKnowledgeBases, fetchKnowledgeBases,
setKeywords: handleSetKeywords, setKeywords: handleSetKeywords,
setTeamFilter: handleSetTeamFilter,
setCurrentPage: handleSetCurrentPage, setCurrentPage: handleSetCurrentPage,
setPageSize: handleSetPageSize, setPageSize: handleSetPageSize,
refresh, refresh,

View File

@@ -1,4 +1,4 @@
import React, { useState, useCallback, useMemo } from 'react'; import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { import {
Box, Box,
Typography, Typography,
@@ -24,15 +24,16 @@ import { useUserData } from '@/hooks/useUserData';
import KnowledgeGridView from '@/components/knowledge/KnowledgeGridView'; import KnowledgeGridView from '@/components/knowledge/KnowledgeGridView';
import type { IKnowledge } from '@/interfaces/database/knowledge'; import type { IKnowledge } from '@/interfaces/database/knowledge';
import { useDialog } from '@/hooks/useDialog'; import { useDialog } from '@/hooks/useDialog';
import logger from '@/utils/logger';
const KnowledgeBaseList: React.FC = () => { const KnowledgeBaseList: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const {deleteKnowledge} = useKnowledgeOperations(); const { deleteKnowledge } = useKnowledgeOperations();
// 搜索和筛选状态 // 搜索和筛选状态
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState('');
const [teamFilter, setTeamFilter] = useState('all'); const [teamFilter, setTeamFilter] = useState<string[]>([]);
const pageSize = 12; // 每页显示12个知识库 const pageSize = 12; // 每页显示12个知识库
// 获取用户数据(包含租户列表) // 获取用户数据(包含租户列表)
@@ -45,6 +46,7 @@ const KnowledgeBaseList: React.FC = () => {
loading, loading,
error, error,
currentPage, currentPage,
setTeamFilter: hookSetTeamFilter,
setKeywords, setKeywords,
setCurrentPage, setCurrentPage,
refresh, refresh,
@@ -61,10 +63,16 @@ const KnowledgeBaseList: React.FC = () => {
}, [setKeywords]); }, [setKeywords]);
// 处理团队筛选 // 处理团队筛选
const handleTeamFilterChange = useCallback((value: string) => { const handleTeamFilterChange = useCallback((value: string[]) => {
setTeamFilter(value); if (value.includes('all')) {
setCurrentPage(1); // 筛选时重置到第一页 setTeamFilter([]);
}, [setCurrentPage]); hookSetTeamFilter([]);
} else {
setTeamFilter(value);
hookSetTeamFilter(value);
}
setCurrentPage(1);
}, [setCurrentPage, hookSetTeamFilter]);
// 处理分页变化 // 处理分页变化
const handlePageChange = useCallback((_: React.ChangeEvent<unknown>, page: number) => { const handlePageChange = useCallback((_: React.ChangeEvent<unknown>, page: number) => {
@@ -107,46 +115,22 @@ const KnowledgeBaseList: React.FC = () => {
navigate(`/knowledge/${kb.id}`); navigate(`/knowledge/${kb.id}`);
}, [navigate]); }, [navigate]);
// 根据团队筛选过滤知识库
const filteredKnowledgeBases = useMemo(() => {
if (!knowledgeBases) return [];
if (teamFilter === 'all') {
return knowledgeBases;
}
// 根据租户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(filteredKnowledgeBases.length / pageSize); const totalPages = Math.ceil(knowledgeBases.length / pageSize);
// 获取当前页的数据 // 获取当前页的数据
const currentPageData = useMemo(() => { const currentPageData = useMemo(() => {
const startIndex = (currentPage - 1) * pageSize; const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize; const endIndex = startIndex + pageSize;
return filteredKnowledgeBases.slice(startIndex, endIndex); return knowledgeBases.slice(startIndex, endIndex);
}, [filteredKnowledgeBases, currentPage, pageSize]); }, [knowledgeBases, currentPage, pageSize]);
// 构建团队筛选选项 // 构建团队筛选选项
const teamFilterOptions = useMemo(() => { const teamFilterOptions = useMemo(() => {
const options = [ const options = [
{ value: 'all', label: '全部' }, { value: 'all', label: '全部' },
]; ];
// 添加租户选项 // 添加租户选项
if (tenantList && tenantList.length > 0) { if (tenantList && tenantList.length > 0) {
tenantList.forEach(tenant => { tenantList.forEach(tenant => {
@@ -156,7 +140,7 @@ const KnowledgeBaseList: React.FC = () => {
}); });
}); });
} }
return options; return options;
}, [tenantList]); }, [tenantList]);
@@ -192,13 +176,17 @@ const KnowledgeBaseList: React.FC = () => {
), ),
}} }}
/> />
<FormControl sx={{ minWidth: 120 }}> <FormControl sx={{ minWidth: 120 }}>
<InputLabel></InputLabel> <InputLabel></InputLabel>
<Select <Select
value={teamFilter} value={teamFilter.length > 0 ? teamFilter[0] : 'all'}
label="团队筛选" label="团队筛选"
onChange={(e) => handleTeamFilterChange(e.target.value)} defaultValue={'all'}
onChange={(e) => {
const value = e.target.value as string;
handleTeamFilterChange([value]);
}}
> >
{teamFilterOptions.map(option => ( {teamFilterOptions.map(option => (
<MenuItem key={option.value} value={option.value}> <MenuItem key={option.value} value={option.value}>
@@ -243,7 +231,7 @@ const KnowledgeBaseList: React.FC = () => {
onDelete={handleDeleteKnowledge} onDelete={handleDeleteKnowledge}
loading={loading} loading={loading}
searchTerm={searchTerm} searchTerm={searchTerm}
teamFilter={teamFilter} // teamFilter={teamFilter}
onCreateKnowledge={handleCreateKnowledge} onCreateKnowledge={handleCreateKnowledge}
/> />
@@ -261,7 +249,7 @@ const KnowledgeBaseList: React.FC = () => {
showLastButton showLastButton
/> />
<Typography variant="body2" color="text.secondary" textAlign="center"> <Typography variant="body2" color="text.secondary" textAlign="center">
{filteredKnowledgeBases.length} {currentPage} {totalPages} {knowledgeBases.length} {currentPage} {totalPages}
</Typography> </Typography>
</Stack> </Stack>
</Box> </Box>

View File

@@ -22,13 +22,13 @@ import type { IRunDocumentRequestBody } from '@/interfaces/request/document';
// 知识库相关API服务 // 知识库相关API服务
const knowledgeService = { const knowledgeService = {
// ===== 知识库管理 ===== // ===== 知识库管理 =====
// 获取知识库列表 // 获取知识库列表
getKnowledgeList: ( getKnowledgeList: (
params?: IFetchKnowledgeListRequestParams, params?: IFetchKnowledgeListRequestParams,
body?: IFetchKnowledgeListRequestBody body?: IFetchKnowledgeListRequestBody
) => { ) => {
return request.post(api.kb_list, { data: body || {}}, { params }); return request.post(api.kb_list, body || {}, { params });
}, },
// 创建知识库 // 创建知识库
@@ -255,7 +255,7 @@ const knowledgeService = {
params?: IFetchKnowledgeListRequestParams, params?: IFetchKnowledgeListRequestParams,
body?: IFetchDocumentListRequestBody body?: IFetchDocumentListRequestBody
) => { ) => {
return request.post(api.fetchDataPipelineLog, { data: body || {}, params }); return request.post(api.fetchDataPipelineLog, body || {}, { params });
}, },
// 获取管道详情 // 获取管道详情
@@ -268,7 +268,7 @@ const knowledgeService = {
params?: IFetchKnowledgeListRequestParams, params?: IFetchKnowledgeListRequestParams,
body?: IFetchDocumentListRequestBody body?: IFetchDocumentListRequestBody
) => { ) => {
return request.post(api.fetchPipelineDatasetLogs, { data: body || {}, params }); return request.post(api.fetchPipelineDatasetLogs, body || {}, { params });
}, },
// 运行GraphRAG // 运行GraphRAG