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 }) => (
); 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) => (
), }, ]; // 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} >
{ try { setLoading(true); if (modalType === 'add') { await handleAdd(values); } else { await handleUpdate(values); } setModalVisible(false); form.resetFields(); } catch (error) { console.error(error); } finally { setLoading(false); } }} > {renderFormItems()}
{/* 添加角色 Modal */} { setRoleModalVisible(false); roleForm.resetFields(); }} onOk={() => roleForm.submit()} >
{/* 添加资源 Modal */} { setResourceModalVisible(false); setEditingResource(null); resourceForm.resetFields(); }} onOk={() => resourceForm.submit()} zIndex={1100} >
{ if (editingResource) { handleUpdateResource(values); } else { handleAddResource(values); } }} >
); }