feat: 添加知识库配置管理功能
新增地区-知识库绑定管理功能,支持增删改查操作 - 添加 V3 API 路由层:area-datasets 相关接口 - 添加 API 客户端:area-datasets.ts - 添加自定义 Hook:use-area-dataset-config.ts - 添加管理组件:area-dataset-config.tsx - 修复路由冲突问题,删除重复的 .ts 路由文件 - 更新 dataset-manager 页面,添加 Tabs 导航 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* 知识库配置管理 Hook
|
||||
*
|
||||
* 提供地区-知识库绑定管理功能
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback } 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;
|
||||
|
||||
// 筛选
|
||||
filterArea: string;
|
||||
setFilterArea: (area: 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<void>;
|
||||
loadAreas: () => Promise<void>;
|
||||
handleCreate: (data: CreateDatasetRequest) => Promise<boolean>;
|
||||
handleUpdate: (id: number, data: UpdateDatasetRequest) => Promise<boolean>;
|
||||
handleDelete: (id: number) => Promise<boolean>;
|
||||
|
||||
// 权限
|
||||
canManageDataset: boolean;
|
||||
}
|
||||
|
||||
// ==================== Hook Implementation ====================
|
||||
|
||||
export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn {
|
||||
// 权限控制
|
||||
const { canManageDataset, canViewDataset, userRole } = usePermission();
|
||||
|
||||
// 数据状态
|
||||
const [datasets, setDatasets] = useState<AreaDataset[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [total, setTotal] = useState<number>(0);
|
||||
const [userArea, setUserArea] = useState<string>('');
|
||||
const [userRoleState, setUserRoleState] = useState<string>('');
|
||||
const [areas, setAreas] = useState<string[]>([]);
|
||||
const [areasLoading, setAreasLoading] = useState<boolean>(false);
|
||||
|
||||
// 筛选状态
|
||||
const [filterArea, setFilterArea] = useState<string>('');
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const pageSize = 20;
|
||||
|
||||
// 表单状态
|
||||
const [modalVisible, setModalVisible] = useState<boolean>(false);
|
||||
const [editingId, setEditingId] = useState<number | null>(null);
|
||||
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
|
||||
|
||||
// ==================== Data Loading ====================
|
||||
|
||||
/**
|
||||
* 加载知识库列表
|
||||
*/
|
||||
const loadDatasets = useCallback(async () => {
|
||||
if (!canViewDataset) {
|
||||
message.warning('您没有查看知识库的权限');
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
let response;
|
||||
|
||||
if (canManageDataset) {
|
||||
// 省级管理员:获取所有知识库
|
||||
response = await getAllDatasets({
|
||||
area: filterArea || undefined,
|
||||
only_enabled: true,
|
||||
page,
|
||||
page_size: pageSize,
|
||||
});
|
||||
} else {
|
||||
// 普通用户/市级管理员:获取我的知识库
|
||||
response = await getMyDatasets();
|
||||
}
|
||||
|
||||
if (response.code === 0) {
|
||||
setDatasets(response.data.data);
|
||||
setTotal(response.data.total);
|
||||
|
||||
// 如果是 my 接口,保存用户信息
|
||||
if ('user_area' in response.data) {
|
||||
setUserArea((response.data as any).user_area);
|
||||
setUserRoleState((response.data as any).user_role);
|
||||
}
|
||||
} else {
|
||||
message.error(`加载失败: ${response.message}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('加载知识库失败:', error);
|
||||
message.error('加载知识库失败,请稍后重试');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [canManageDataset, canViewDataset, filterArea, page, pageSize]);
|
||||
|
||||
/**
|
||||
* 加载地区列表(仅省级管理员)
|
||||
*/
|
||||
const loadAreas = useCallback(async () => {
|
||||
if (!canManageDataset) return;
|
||||
|
||||
setAreasLoading(true);
|
||||
try {
|
||||
const areasList = await getAvailableAreas();
|
||||
setAreas(areasList);
|
||||
} catch (error: any) {
|
||||
console.error('加载地区列表失败:', error);
|
||||
message.error('加载地区列表失败');
|
||||
} finally {
|
||||
setAreasLoading(false);
|
||||
}
|
||||
}, [canManageDataset]);
|
||||
|
||||
// ==================== Operations ====================
|
||||
|
||||
/**
|
||||
* 创建知识库绑定
|
||||
*/
|
||||
const handleCreate = useCallback(
|
||||
async (data: CreateDatasetRequest): Promise<boolean> => {
|
||||
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);
|
||||
message.error('创建失败,请稍后重试');
|
||||
return false;
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
},
|
||||
[canManageDataset, loadDatasets]
|
||||
);
|
||||
|
||||
/**
|
||||
* 更新知识库绑定
|
||||
*/
|
||||
const handleUpdate = useCallback(
|
||||
async (id: number, data: UpdateDatasetRequest): Promise<boolean> => {
|
||||
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);
|
||||
message.error('更新失败,请稍后重试');
|
||||
return false;
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
},
|
||||
[canManageDataset, loadDatasets]
|
||||
);
|
||||
|
||||
/**
|
||||
* 删除知识库绑定
|
||||
*/
|
||||
const handleDelete = useCallback(
|
||||
async (id: number): Promise<boolean> => {
|
||||
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);
|
||||
message.error('删除失败,请稍后重试');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[canManageDataset, loadDatasets]
|
||||
);
|
||||
|
||||
// ==================== Effects ====================
|
||||
|
||||
// 加载数据
|
||||
useEffect(() => {
|
||||
loadDatasets();
|
||||
}, [loadDatasets]);
|
||||
|
||||
useEffect(() => {
|
||||
loadAreas();
|
||||
}, [loadAreas]);
|
||||
|
||||
// 监听筛选条件变化
|
||||
useEffect(() => {
|
||||
if (canManageDataset) {
|
||||
setPage(1); // 筛选条件变化时重置到第一页
|
||||
loadDatasets();
|
||||
}
|
||||
}, [filterArea, canManageDataset, loadDatasets]);
|
||||
|
||||
// 监听页码变化
|
||||
useEffect(() => {
|
||||
if (canManageDataset) {
|
||||
loadDatasets();
|
||||
}
|
||||
}, [page, canManageDataset, loadDatasets]);
|
||||
|
||||
return {
|
||||
// 数据
|
||||
datasets,
|
||||
loading,
|
||||
total,
|
||||
userArea,
|
||||
userRole: userRoleState,
|
||||
areas,
|
||||
areasLoading,
|
||||
|
||||
// 筛选
|
||||
filterArea,
|
||||
setFilterArea,
|
||||
page,
|
||||
setPage,
|
||||
pageSize,
|
||||
|
||||
// 表单状态
|
||||
modalVisible,
|
||||
setModalVisible,
|
||||
editingId,
|
||||
setEditingId,
|
||||
submitLoading,
|
||||
|
||||
// 操作方法
|
||||
loadDatasets,
|
||||
loadAreas,
|
||||
handleCreate,
|
||||
handleUpdate,
|
||||
handleDelete,
|
||||
|
||||
// 权限
|
||||
canManageDataset,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user