import React, { useState, useEffect } from 'react';
import { Card, App, Table, Button, Modal, Form, Select, message, Input, Divider, Popconfirm } from 'antd';
import { PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import { supabase } from '@/config/supabase';
const RoleHeader = ({ onAdd, onSearch }) => (
}
onClick={onAdd}
>
添加权限
);
export default function PermissionManagement() {
const [loading, setLoading] = useState(false);
const [permissions, setPermissions] = useState([]);
const [roles, setRoles] = useState([]);
const [resources, setResources] = useState([]);
const [modalVisible, setModalVisible] = useState(false);
const [modalType, setModalType] = useState('add');
const [form] = Form.useForm();
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 0,
});
const [sorter, setSorter] = useState({
field: 'created_at',
order: 'descend',
});
const [roleModalVisible, setRoleModalVisible] = useState(false);
const [resourceModalVisible, setResourceModalVisible] = useState(false);
const [roleForm] = Form.useForm();
const [resourceForm] = Form.useForm();
const [editingResource, setEditingResource] = useState(null);
const fetchPermissions = async (params = {}) => {
try {
setLoading(true);
let query = supabase
.from('permissions')
.select(`
*,
roles:role_id(*),
resources:resource_id(*)
`, { count: 'exact' });
// 添加排序
if (params.field && params.order) {
const ascending = params.order === 'ascend';
query = query.order(params.field, { ascending });
} else {
// 默认排序
query = query.order('created_at', { ascending: false });
}
// 添加分页
const from = (params.current - 1) * params.pageSize || 0;
const to = from + (params.pageSize || 10) - 1;
query = query.range(from, to);
const { data, count, error } = await query;
if (error) throw error;
setPermissions(data || []);
setPagination(prev => ({
...prev,
total: count || 0,
current: params.current || prev.current,
pageSize: params.pageSize || prev.pageSize,
}));
} catch (error) {
message.error('获取权限数据失败');
console.error(error);
} finally {
setLoading(false);
}
};
// 获取所有角色
const fetchRoles = async () => {
try {
const { data, error } = await supabase
.from('roles')
.select('*')
.order('name');
if (error) throw error;
setRoles(data || []);
} catch (error) {
message.error('获取角色数据失败');
console.error(error);
}
};
// 获取所有资源
const fetchResources = async () => {
try {
const { data, error } = await supabase
.from('permission_resources')
.select('*')
.order('resource_name');
if (error) throw error;
setResources(data || []);
} catch (error) {
message.error('获取资源数据失败');
console.error(error);
}
};
// 添加权限
const handleAdd = async (values) => {
try {
const { error } = await supabase
.from('permissions')
.insert([{
role_id: values.role_id,
resource_id: values.resource_id,
action: values.action
}]);
if (error) throw error;
message.success('添加成功');
fetchPermissions(pagination);
} catch (error) {
message.error('添加失败');
throw error;
}
};
// 更新权限
const handleUpdate = async (values) => {
try {
const { error } = await supabase
.from('permissions')
.update({
role_id: values.role_id,
resource_id: values.resource_id,
action: values.action
})
.eq('id', values.id);
if (error) throw error;
message.success('更新成功');
fetchPermissions(pagination);
} catch (error) {
message.error('更新失败');
throw error;
}
};
// 删除权限
const handleDelete = async (id) => {
try {
const { error } = await supabase
.from('permissions')
.delete()
.eq('id', id);
if (error) throw error;
message.success('删除成功');
fetchPermissions(pagination);
} catch (error) {
message.error('删除失败');
throw error;
}
};
// 添加新角色
const handleAddRole = async (values) => {
try {
const { data, error } = await supabase
.from('roles')
.insert([{
name: values.name,
description: values.description
}])
.select()
.single();
if (error) throw error;
message.success('添加角色成功');
setRoles([...roles, data]);
setRoleModalVisible(false);
roleForm.resetFields();
return data;
} catch (error) {
message.error('添加角色失败');
throw error;
}
};
// 添加新资源
const handleAddResource = async (values) => {
try {
const { data, error } = await supabase
.from('permission_resources')
.insert([{
resource_name: values.resource_name,
resource_type: values.resource_type,
attributes_type: values.attributes_type,
description: values.description
}])
.select()
.single();
if (error) throw error;
message.success('添加资源成功');
setResources([...resources, data]);
setResourceModalVisible(false);
resourceForm.resetFields();
return data;
} catch (error) {
message.error('添加资源失败');
throw error;
}
};
// 添加删除资源的函数
const handleDeleteResource = async (resourceId) => {
try {
const { error } = await supabase
.from('permission_resources')
.delete()
.eq('id', resourceId);
if (error) throw error;
message.success('删除资源成功');
fetchResources();
} catch (error) {
message.error('删除资源失败');
console.error(error);
}
};
// 添加更新资源的函数
const handleUpdateResource = async (values) => {
try {
const { error } = await supabase
.from('permission_resources')
.update({
resource_name: values.resource_name,
resource_type: values.resource_type,
attributes_type: values.attributes_type,
description: values.description
})
.eq('id', editingResource.id);
if (error) throw error;
message.success('更新资源成功');
setResourceModalVisible(false);
resourceForm.resetFields();
fetchResources();
} catch (error) {
message.error('更新资源失败');
console.error(error);
}
};
// 初始化加载
useEffect(() => {
fetchPermissions();
fetchRoles();
fetchResources();
}, []);
const handleTableChange = (newPagination, filters, newSorter) => {
const params = {
current: newPagination?.current,
pageSize: newPagination?.pageSize,
field: newSorter?.field,
order: newSorter?.order,
};
setPagination(prev => ({
...prev,
current: params.current,
pageSize: params.pageSize,
}));
setSorter({
field: params.field || sorter.field,
order: params.order || sorter.order,
});
fetchPermissions(params);
};
const columns = [
{
title: '角色',
dataIndex: ['roles', 'name'],
key: 'role_name',
render: (name) => (
{name}
)
},
{
title: '资源',
dataIndex: ['resources', 'resource_name'],
key: 'resource_name',
},
{
title: '控制颗粒度',
dataIndex: ['resources', 'resource_type'],
key: 'resource_type',
render: (type) => (
{type === 'table' ? '数据表' : '字段值'}
)
},
{
title: '属性类型',
dataIndex: ['resources', 'attributes_type'],
key: 'attributes_type',
render: (attributes_type) => (
{!attributes_type ? '-' : attributes_type}
)
},
{
title: '操作类型',
dataIndex: 'action',
key: 'action',
render: (action) => {
const actionMap = {
create: { text: '创建', color: 'bg-green-100 text-green-800' },
read: { text: '读取', color: 'bg-blue-100 text-blue-800' },
update: { text: '更新', color: 'bg-yellow-100 text-yellow-800' },
delete: { text: '删除', color: 'bg-red-100 text-red-800' }
};
const { text, color } = actionMap[action] || { text: action, color: 'bg-gray-100 text-gray-800' };
return (
{text}
);
}
},
// {
// title: '描述',
// dataIndex: ['resources', 'description'],
// key: 'description',
// ellipsis: true,
// },
{
title: '操作',
key: 'operation',
render: (_, record) => (
}
onClick={() => {
setModalType('edit');
form.setFieldsValue(record);
setModalVisible(true);
}}
/>
handleDelete(record.id)}
>
}
/>
),
},
];
// Modal 表单内容
const renderFormItems = () => {
const [roleSelectOpen, setRoleSelectOpen] = useState(false);
const [resourceSelectOpen, setResourceSelectOpen] = useState(false);
return (
<>
>
);
};
return (
{
setModalType('add');
setModalVisible(true);
}}
onSearch={(value) => {
fetchPermissions({
...pagination,
current: 1,
search: value
});
}}
/>
{
setModalVisible(false);
form.resetFields();
}}
onOk={() => form.submit()}
confirmLoading={loading}
>
{/* 添加角色 Modal */}
{
setRoleModalVisible(false);
roleForm.resetFields();
}}
onOk={() => roleForm.submit()}
>
{/* 添加资源 Modal */}
{
setResourceModalVisible(false);
setEditingResource(null);
resourceForm.resetFields();
}}
onOk={() => resourceForm.submit()}
zIndex={1100}
>
);
}