菜单权限
This commit is contained in:
@@ -4,12 +4,8 @@ import { PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
|
||||
import { supabase } from '@/config/supabase';
|
||||
|
||||
const RoleHeader = ({ onAdd, onSearch }) => (
|
||||
<div className="flex justify-between mb-4">
|
||||
<Input.Search
|
||||
placeholder="搜索权限"
|
||||
onSearch={onSearch}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
<div className="flex justify-end mb-4">
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
@@ -43,8 +39,8 @@ export default function PermissionManagement() {
|
||||
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);
|
||||
@@ -56,15 +52,6 @@ export default function PermissionManagement() {
|
||||
resources:resource_id(*)
|
||||
`, { count: 'exact' });
|
||||
|
||||
// 添加搜索条件
|
||||
if (params.search) {
|
||||
query = query.or(`
|
||||
roles.name.ilike.%${params.search}%,
|
||||
resources.resource_name.ilike.%${params.search}%,
|
||||
resources.description.ilike.%${params.search}%
|
||||
`);
|
||||
}
|
||||
|
||||
// 添加排序
|
||||
if (params.field && params.order) {
|
||||
const ascending = params.order === 'ascend';
|
||||
@@ -240,6 +227,47 @@ export default function PermissionManagement() {
|
||||
}
|
||||
};
|
||||
|
||||
// 添加删除资源的函数
|
||||
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();
|
||||
@@ -274,7 +302,6 @@ export default function PermissionManagement() {
|
||||
title: '角色',
|
||||
dataIndex: ['roles', 'name'],
|
||||
key: 'role_name',
|
||||
sorter: true,
|
||||
render: (name) => (
|
||||
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
|
||||
{name}
|
||||
@@ -285,10 +312,9 @@ export default function PermissionManagement() {
|
||||
title: '资源',
|
||||
dataIndex: ['resources', 'resource_name'],
|
||||
key: 'resource_name',
|
||||
sorter: true,
|
||||
},
|
||||
{
|
||||
title: '资源类型',
|
||||
title: '控制颗粒度',
|
||||
dataIndex: ['resources', 'resource_type'],
|
||||
key: 'resource_type',
|
||||
render: (type) => (
|
||||
@@ -306,10 +332,8 @@ export default function PermissionManagement() {
|
||||
key: 'attributes_type',
|
||||
render: (attributes_type) => (
|
||||
<span>
|
||||
{!attributes_type ? '无' : attributes_type}
|
||||
|
||||
{!attributes_type ? '-' : attributes_type}
|
||||
</span>
|
||||
|
||||
)
|
||||
},
|
||||
{
|
||||
@@ -333,12 +357,12 @@ export default function PermissionManagement() {
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: ['resources', 'description'],
|
||||
key: 'description',
|
||||
ellipsis: true,
|
||||
},
|
||||
// {
|
||||
// title: '描述',
|
||||
// dataIndex: ['resources', 'description'],
|
||||
// key: 'description',
|
||||
// ellipsis: true,
|
||||
// },
|
||||
{
|
||||
title: '操作',
|
||||
key: 'operation',
|
||||
@@ -365,82 +389,129 @@ export default function PermissionManagement() {
|
||||
];
|
||||
|
||||
// Modal 表单内容
|
||||
const renderFormItems = () => (
|
||||
<>
|
||||
<Form.Item
|
||||
name="role_id"
|
||||
label="角色"
|
||||
rules={[{ required: true, message: '请选择角色' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择角色"
|
||||
dropdownRender={(menu) => (
|
||||
<>
|
||||
{menu}
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
<Button
|
||||
type="text"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => setRoleModalVisible(true)}
|
||||
style={{ paddingLeft: 8 }}
|
||||
>
|
||||
添加角色
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
{roles.map(role => (
|
||||
<Select.Option key={role.id} value={role.id}>
|
||||
{role.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
const renderFormItems = () => {
|
||||
const [roleSelectOpen, setRoleSelectOpen] = useState(false);
|
||||
const [resourceSelectOpen, setResourceSelectOpen] = useState(false);
|
||||
|
||||
<Form.Item
|
||||
name="resource_id"
|
||||
label="资源"
|
||||
rules={[{ required: true, message: '请选择资源' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择资源"
|
||||
dropdownRender={(menu) => (
|
||||
<>
|
||||
{menu}
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
<Button
|
||||
type="text"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => setResourceModalVisible(true)}
|
||||
style={{ paddingLeft: 8 }}
|
||||
>
|
||||
添加资源
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="role_id"
|
||||
label="角色"
|
||||
rules={[{ required: true, message: '请选择角色' }]}
|
||||
>
|
||||
{resources.map(resource => (
|
||||
<Select.Option key={resource.id} value={resource.id}>
|
||||
{`${resource.resource_name} ${resource.attributes_type?`(${resource.attributes_type})`:''}`}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Select
|
||||
allowClear
|
||||
placeholder="请选择角色"
|
||||
open={roleSelectOpen}
|
||||
onDropdownVisibleChange={setRoleSelectOpen}
|
||||
dropdownRender={(menu) => (
|
||||
<>
|
||||
{menu}
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
<Button
|
||||
type="text"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setRoleSelectOpen(false); // 关闭下拉框
|
||||
setRoleModalVisible(true);
|
||||
}}
|
||||
style={{ paddingLeft: 8 }}
|
||||
>
|
||||
添加角色
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
{roles.map(role => (
|
||||
<Select.Option key={role.id} value={role.id}>
|
||||
{role.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="action"
|
||||
label="操作类型"
|
||||
rules={[{ required: true, message: '请选择操作类型' }]}
|
||||
>
|
||||
<Select placeholder="请选择操作类型">
|
||||
<Select.Option value="create">创建</Select.Option>
|
||||
<Select.Option value="read">读取</Select.Option>
|
||||
<Select.Option value="update">更新</Select.Option>
|
||||
<Select.Option value="delete">删除</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
<Form.Item
|
||||
name="resource_id"
|
||||
label="资源"
|
||||
rules={[{ required: true, message: '请选择资源' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择资源"
|
||||
open={resourceSelectOpen}
|
||||
onDropdownVisibleChange={setResourceSelectOpen}
|
||||
dropdownRender={(menu) => (
|
||||
<>
|
||||
{menu}
|
||||
<Divider style={{ margin: '8px 0' }} />
|
||||
<div style={{ padding: '8px', display: 'flex', justifyContent: 'space-between' }}>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
setResourceSelectOpen(false);
|
||||
setEditingResource(null); // 清空编辑状态
|
||||
resourceForm.resetFields(); // 清空表单
|
||||
setResourceModalVisible(true);
|
||||
}}
|
||||
>
|
||||
添加资源
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
{resources.map(resource => (
|
||||
<Select.Option key={resource.id} value={resource.id}>
|
||||
<div className="flex justify-between items-center">
|
||||
<span>{`${resource.resource_name} ${resource.attributes_type?`(${resource.attributes_type})`:''}`}</span>
|
||||
<div className="flex space-x-2" onClick={e => e.stopPropagation()}>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => {
|
||||
setResourceSelectOpen(false);
|
||||
setEditingResource(resource);
|
||||
resourceForm.setFieldsValue(resource);
|
||||
setResourceModalVisible(true);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={() => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这个资源吗?',
|
||||
onOk: () => handleDeleteResource(resource.id),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="action"
|
||||
label="操作类型"
|
||||
rules={[{ required: true, message: '请选择操作类型' }]}
|
||||
>
|
||||
<Select placeholder="请选择操作类型" allowClear>
|
||||
<Select.Option value="create">创建</Select.Option>
|
||||
<Select.Option value="read">读取</Select.Option>
|
||||
<Select.Option value="update">更新</Select.Option>
|
||||
<Select.Option value="delete">删除</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<App>
|
||||
@@ -535,18 +606,26 @@ export default function PermissionManagement() {
|
||||
|
||||
{/* 添加资源 Modal */}
|
||||
<Modal
|
||||
title="添加资源"
|
||||
title={editingResource ? "编辑资源" : "添加资源"}
|
||||
open={resourceModalVisible}
|
||||
onCancel={() => {
|
||||
setResourceModalVisible(false);
|
||||
setEditingResource(null);
|
||||
resourceForm.resetFields();
|
||||
}}
|
||||
onOk={() => resourceForm.submit()}
|
||||
zIndex={1100}
|
||||
>
|
||||
<Form
|
||||
form={resourceForm}
|
||||
layout="vertical"
|
||||
onFinish={handleAddResource}
|
||||
onFinish={(values) => {
|
||||
if (editingResource) {
|
||||
handleUpdateResource(values);
|
||||
} else {
|
||||
handleAddResource(values);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
name="resource_name"
|
||||
|
||||
Reference in New Issue
Block a user