fix: 修复知识库配置管理的权限检查和错误提示
1. 权限检查优化
- 使用 hasPermission('dify:bind:update') 替代硬编码的角色判断
- 支持细粒度的权限控制,市级管理员可以通过授权获得编辑权限
- 保留降级方案,provincial_admin 角色自动拥有所有权限
2. 错误处理优化
- 新增统一的 handleApiError 错误处理函数
- 优先显示后端返回的具体错误信息(error.response.data.msg)
- 支持多种错误格式的提取(axios、fetch、自定义格式)
- 简化 handleCreate、handleUpdate、handleDelete 的错误处理代码
3. 调试支持
- 添加权限检查的调试日志,便于排查问题
- 输出当前路由、用户角色、权限列表等关键信息
修复问题:
- 市级管理员被授予 dify:bind:update 权限后,编辑按钮仍不显示
- 403 错误只显示通用提示,无法看到后端返回的具体错误原因
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -67,14 +67,63 @@ const ROLE_LABELS: Record<string, string> = {
|
||||
|
||||
export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn {
|
||||
// 权限控制
|
||||
const { userRole: permissionUserRole } = usePermission();
|
||||
const { hasPermission, userRole: permissionUserRole, permissions, permissionMap } = usePermission();
|
||||
|
||||
// 根据 userRole 判断权限
|
||||
// provincial_admin 可以管理所有知识库配置
|
||||
// 其他角色只能查看自己地区的配置
|
||||
const canManageDataset = permissionUserRole === 'provincial_admin' || permissionUserRole.toLowerCase().includes('provin');
|
||||
// 根据权限判断是否可以管理知识库配置
|
||||
// 权限键:dify:bind:update(知识库绑定更新权限)
|
||||
// 降级方案:如果 permissionMap 中没有配置权限,usePermission 会自动降级为角色判断
|
||||
const canManageDataset = hasPermission('dify:bind:update');
|
||||
const canViewDataset = true; // 所有登录用户都可以查看
|
||||
|
||||
// 🔍 调试日志(修复后可删除)
|
||||
if (typeof window !== 'undefined') {
|
||||
console.log('[DatasetConfig] 权限检查:', {
|
||||
currentPath: window.location.pathname,
|
||||
userRole: permissionUserRole,
|
||||
hasDifyBindUpdate: hasPermission('dify:bind:update'),
|
||||
currentPermissions: permissions,
|
||||
canManageDataset,
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== 错误处理工具函数 ====================
|
||||
|
||||
/**
|
||||
* 统一处理 API 错误
|
||||
* @param error 错误对象
|
||||
* @param operation 操作名称(创建/更新/删除)
|
||||
*/
|
||||
const handleApiError = (error: any, operation: string) => {
|
||||
console.error(`${operation}知识库绑定失败:`, error);
|
||||
|
||||
// 提取错误信息的优先级:
|
||||
// 1. error.response.data.msg (axios 响应格式)
|
||||
// 2. error.data.msg (其他格式)
|
||||
// 3. error.msg (直接错误对象)
|
||||
// 4. error.response.data.message (备用字段)
|
||||
// 5. error.message (标准错误对象)
|
||||
const errorMsg = error?.response?.data?.msg ||
|
||||
error?.data?.msg ||
|
||||
error?.msg ||
|
||||
error?.response?.data?.message ||
|
||||
error?.message;
|
||||
|
||||
// 检查是否为403权限不足错误
|
||||
const is403 = error?.response?.status === 403 ||
|
||||
error?.status === 403 ||
|
||||
error?.code === 403;
|
||||
|
||||
if (is403) {
|
||||
// 403 错误:显示具体的权限错误信息
|
||||
message.error(errorMsg || `无权限操作:您没有${operation}知识库绑定的权限`);
|
||||
} else {
|
||||
// 其他错误:显示具体的错误信息或通用提示
|
||||
message.error(errorMsg || `${operation}失败,请稍后重试`);
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== 数据状态 ====================
|
||||
|
||||
// 数据状态
|
||||
const [datasets, setDatasets] = useState<AreaDataset[]>([]);
|
||||
const [allDatasets, setAllDatasets] = useState<AreaDataset[]>([]); // 保存所有数据用于提取地区
|
||||
@@ -221,13 +270,7 @@ export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn {
|
||||
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('创建失败,请稍后重试');
|
||||
}
|
||||
handleApiError(error, '创建');
|
||||
return false;
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
@@ -259,13 +302,7 @@ export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn {
|
||||
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('更新失败,请稍后重试');
|
||||
}
|
||||
handleApiError(error, '更新');
|
||||
return false;
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
@@ -296,13 +333,7 @@ export function useAreaDatasetConfig(): UseAreaDatasetConfigReturn {
|
||||
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('删除失败,请稍后重试');
|
||||
}
|
||||
handleApiError(error, '删除');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user