feat(knowledge): add team filtering and improve request handling
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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,39 +115,15 @@ 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(() => {
|
||||||
@@ -196,9 +180,13 @@ 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>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const knowledgeService = {
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user