/** * 知识库配置管理 Hook * * 提供地区-知识库绑定管理功能 */ import { useState, useEffect, useCallback, useMemo } from 'react'; import { getMyDatasets, getAllDatasets, getAvailableAreas, createDatasetBinding, updateDatasetBinding, deleteDatasetBinding, type AreaDataset, type CreateDatasetRequest, type UpdateDatasetRequest, } from '~/api/v3/dify/area-datasets'; import { message } from 'antd'; import { usePermission } from '~/hooks/usePermission'; // ==================== Type Definitions ==================== export interface UseAreaDatasetConfigReturn { // 数据 datasets: AreaDataset[]; loading: boolean; total: number; userArea: string; userRole: string; areas: string[]; areasLoading: boolean; // 筛选 - 支持多选 filterAreas: string[]; setFilterAreas: (areas: string[]) => void; page: number; setPage: (page: number) => void; pageSize: number; // 表单状态 modalVisible: boolean; setModalVisible: (visible: boolean) => void; editingId: number | null; setEditingId: (id: number | null) => void; submitLoading: boolean; // 操作方法 loadDatasets: () => Promise; loadAreas: () => Promise; handleCreate: (data: CreateDatasetRequest) => Promise; handleUpdate: (id: number, data: UpdateDatasetRequest) => Promise; handleDelete: (id: number) => Promise; // 权限 canManageDataset: boolean; } // 角色名称映射 const ROLE_LABELS: Record = { common: '普通用户', admin: '市级管理员', provincial_admin: '省级管理员', }; // ==================== Hook Implementation ==================== export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn { // 权限控制 const { userRole: permissionUserRole } = usePermission(); // 根据 userRole 判断权限 // provincial_admin 可以管理所有知识库配置 // 其他角色只能查看自己地区的配置 const canManageDataset = permissionUserRole === 'provincial_admin' || permissionUserRole.toLowerCase().includes('provin'); const canViewDataset = true; // 所有登录用户都可以查看 // 数据状态 const [datasets, setDatasets] = useState([]); const [allDatasets, setAllDatasets] = useState([]); // 保存所有数据用于提取地区 const [loading, setLoading] = useState(false); const [total, setTotal] = useState(0); const [userArea, setUserArea] = useState(''); const [apiAreas, setApiAreas] = useState([]); // API 返回的地区列表 const [areasLoading, setAreasLoading] = useState(false); // 筛选状态 - 支持多选 const [filterAreas, setFilterAreas] = useState([]); const [page, setPage] = useState(1); const pageSize = 20; // 表单状态 const [modalVisible, setModalVisible] = useState(false); const [editingId, setEditingId] = useState(null); const [submitLoading, setSubmitLoading] = useState(false); // 从数据集中提取地区列表 const extractedAreas = useMemo(() => { const areaSet = new Set(); allDatasets.forEach(ds => { if (ds.area) { areaSet.add(ds.area); } }); return Array.from(areaSet).sort(); }, [allDatasets]); // 合并 API 返回的地区和从数据中提取的地区 const areas = useMemo(() => { const areaSet = new Set([...apiAreas, ...extractedAreas]); return Array.from(areaSet).sort(); }, [apiAreas, extractedAreas]); // 获取角色显示名称 const userRoleLabel = ROLE_LABELS[permissionUserRole] || permissionUserRole || '未知角色'; // ==================== Data Loading ==================== /** * 加载知识库列表 */ const loadDatasets = useCallback(async () => { if (!canViewDataset) { message.warning('您没有查看知识库的权限'); return; } setLoading(true); try { let response; if (canManageDataset) { // 省级管理员:获取所有知识库 // 如果有多个地区筛选,用逗号分隔传递 const areaFilter = filterAreas.length > 0 ? filterAreas.join(',') : undefined; response = await getAllDatasets({ area: areaFilter, only_enabled: false, // 管理员可以看到所有状态 page, page_size: pageSize, }); } else { // 普通用户/市级管理员:获取我的知识库 response = await getMyDatasets(); } console.log('[AreaDatasetConfig] API响应:', response); if (response && response.code === 0 && response.data) { const dataList = Array.isArray(response.data.data) ? response.data.data : []; setDatasets(dataList); setTotal(response.data.total || dataList.length); // 如果没有筛选,保存所有数据用于提取地区 if (filterAreas.length === 0) { setAllDatasets(dataList); } // 如果是 my 接口,保存用户信息 if ('user_area' in response.data) { setUserArea((response.data as any).user_area || ''); } } else { console.error('[AreaDatasetConfig] API响应格式错误:', response); message.error(`加载失败: ${response?.message || '未知错误'}`); } } catch (error: any) { console.error('加载知识库失败:', error); message.error('加载知识库失败,请稍后重试'); } finally { setLoading(false); } }, [canManageDataset, canViewDataset, filterAreas, page, pageSize]); /** * 加载地区列表(仅省级管理员) */ const loadAreas = useCallback(async () => { if (!canManageDataset) return; setAreasLoading(true); try { const areasList = await getAvailableAreas(); console.log('[AreaDatasetConfig] 地区列表响应:', areasList); if (Array.isArray(areasList)) { setApiAreas(areasList); } else { console.warn('[AreaDatasetConfig] 地区列表不是数组:', areasList); setApiAreas([]); } } catch (error: any) { console.error('加载地区列表失败:', error); // 不显示错误提示,因为可以从数据中提取地区 } finally { setAreasLoading(false); } }, [canManageDataset]); // ==================== Operations ==================== /** * 创建知识库绑定 */ const handleCreate = useCallback( async (data: CreateDatasetRequest): Promise => { if (!canManageDataset) { message.error('您没有创建知识库绑定的权限'); return false; } setSubmitLoading(true); try { const response = await createDatasetBinding(data); if (response.code === 0) { message.success('创建成功'); await loadDatasets(); return true; } else { message.error(`创建失败: ${response.message}`); return false; } } catch (error: any) { console.error('创建知识库绑定失败:', error); // 检查是否为403权限不足错误 if (error?.response?.status === 403 || error?.status === 403 || error?.code === 403) { message.error('无权限操作:您没有创建知识库绑定的权限'); } else { message.error('创建失败,请稍后重试'); } return false; } finally { setSubmitLoading(false); } }, [canManageDataset, loadDatasets] ); /** * 更新知识库绑定 */ const handleUpdate = useCallback( async (id: number, data: UpdateDatasetRequest): Promise => { if (!canManageDataset) { message.error('您没有编辑知识库绑定的权限'); return false; } setSubmitLoading(true); try { const response = await updateDatasetBinding(id, data); if (response.code === 0) { message.success('更新成功'); await loadDatasets(); return true; } else { message.error(`更新失败: ${response.message}`); return false; } } catch (error: any) { console.error('更新知识库绑定失败:', error); // 检查是否为403权限不足错误 if (error?.response?.status === 403 || error?.status === 403 || error?.code === 403) { message.error('无权限操作:您没有编辑知识库绑定的权限'); } else { message.error('更新失败,请稍后重试'); } return false; } finally { setSubmitLoading(false); } }, [canManageDataset, loadDatasets] ); /** * 删除知识库绑定 */ const handleDelete = useCallback( async (id: number): Promise => { if (!canManageDataset) { message.error('您没有删除知识库绑定的权限'); return false; } try { const response = await deleteDatasetBinding(id); if (response.code === 0) { message.success('删除成功'); await loadDatasets(); return true; } else { message.error(`删除失败: ${response.message}`); return false; } } catch (error: any) { console.error('删除知识库绑定失败:', error); // 检查是否为403权限不足错误 if (error?.response?.status === 403 || error?.status === 403 || error?.code === 403) { message.error('无权限操作:您没有删除知识库绑定的权限'); } else { message.error('删除失败,请稍后重试'); } return false; } }, [canManageDataset, loadDatasets] ); // ==================== Effects ==================== // 初始加载数据 useEffect(() => { loadDatasets(); }, []); // 只在挂载时加载一次 // 加载地区列表 useEffect(() => { loadAreas(); }, [loadAreas]); // 监听筛选条件和页码变化 useEffect(() => { loadDatasets(); }, [filterAreas, page]); return { // 数据 datasets, loading, total, userArea, userRole: userRoleLabel, areas, areasLoading, // 筛选 filterAreas, setFilterAreas, page, setPage, pageSize, // 表单状态 modalVisible, setModalVisible, editingId, setEditingId, submitLoading, // 操作方法 loadDatasets, loadAreas, handleCreate, handleUpdate, handleDelete, // 权限 canManageDataset, }; }