|
@@ -0,0 +1,492 @@
|
|
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
|
|
+import { Card, Table, Button, Modal, Form, Input, Select, Space, Tag, message, Row, Col, Tree, Checkbox, Radio } from 'antd';
|
|
|
|
|
+import { EditOutlined, DeleteOutlined, PlusOutlined, KeyOutlined } from '@ant-design/icons';
|
|
|
|
|
+import { permissionClient, rolePermissionClient, roleClient } from '@/client/api';
|
|
|
|
|
+import type { InferResponseType, InferRequestType } from 'hono/client';
|
|
|
|
|
+import dayjs from 'dayjs';
|
|
|
|
|
+
|
|
|
|
|
+const { Option } = Select;
|
|
|
|
|
+const { TextArea } = Input;
|
|
|
|
|
+
|
|
|
|
|
+type PermissionListResponse = InferResponseType<typeof permissionClient.$get, 200>;
|
|
|
|
|
+type PermissionItem = PermissionListResponse['data'][0];
|
|
|
|
|
+type CreatePermissionRequest = InferRequestType<typeof permissionClient.$post>['json'];
|
|
|
|
|
+type UpdatePermissionRequest = InferRequestType<typeof permissionClient[':id']['$put']>['json'];
|
|
|
|
|
+
|
|
|
|
|
+type RoleListResponse = InferResponseType<typeof roleClient.$get, 200>;
|
|
|
|
|
+type RoleItem = RoleListResponse['data'][0];
|
|
|
|
|
+
|
|
|
|
|
+const Permissions: React.FC = () => {
|
|
|
|
|
+ const [permissions, setPermissions] = useState<PermissionItem[]>([]);
|
|
|
|
|
+ const [roles, setRoles] = useState<RoleItem[]>([]);
|
|
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
|
|
+ const [modalVisible, setModalVisible] = useState(false);
|
|
|
|
|
+ const [rolePermissionModalVisible, setRolePermissionModalVisible] = useState(false);
|
|
|
|
|
+ const [editingPermission, setEditingPermission] = useState<PermissionItem | null>(null);
|
|
|
|
|
+ const [selectedRole, setSelectedRole] = useState<RoleItem | null>(null);
|
|
|
|
|
+ const [rolePermissions, setRolePermissions] = useState<number[]>([]);
|
|
|
|
|
+ const [rolePermissionsData, setRolePermissionsData] = useState<any[]>([]);
|
|
|
|
|
+ const [form] = Form.useForm();
|
|
|
|
|
+ const [rolePermissionForm] = Form.useForm();
|
|
|
|
|
+
|
|
|
|
|
+ // 权限类型映射
|
|
|
|
|
+ const permissionTypeMap = {
|
|
|
|
|
+ module: '模块权限',
|
|
|
|
|
+ operation: '操作权限',
|
|
|
|
|
+ data: '数据权限'
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 获取权限列表
|
|
|
|
|
+ const fetchPermissions = async () => {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await permissionClient.$get();
|
|
|
|
|
+ if (response.status === 200) {
|
|
|
|
|
+ const data = await response.json();
|
|
|
|
|
+ setPermissions(data.data);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('获取权限列表失败');
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 获取角色列表
|
|
|
|
|
+ const fetchRoles = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await roleClient.$get();
|
|
|
|
|
+ if (response.status === 200) {
|
|
|
|
|
+ const data = await response.json();
|
|
|
|
|
+ setRoles(data.data);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('获取角色列表失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 获取角色的权限
|
|
|
|
|
+ const fetchRolePermissions = async (roleId: number) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await rolePermissionClient.$get({
|
|
|
|
|
+ query: { roleId }
|
|
|
|
|
+ });
|
|
|
|
|
+ if (response.status === 200) {
|
|
|
|
|
+ const data = await response.json();
|
|
|
|
|
+ setRolePermissionsData(data.data);
|
|
|
|
|
+ setRolePermissions(data.data.map((item: any) => item.permissionId));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('获取角色权限失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ fetchPermissions();
|
|
|
|
|
+ fetchRoles();
|
|
|
|
|
+ }, []);
|
|
|
|
|
+
|
|
|
|
|
+ // 打开编辑模态框
|
|
|
|
|
+ const handleEdit = (record: PermissionItem) => {
|
|
|
|
|
+ setEditingPermission(record);
|
|
|
|
|
+ form.setFieldsValue(record);
|
|
|
|
|
+ setModalVisible(true);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 打开新建模态框
|
|
|
|
|
+ const handleAdd = () => {
|
|
|
|
|
+ setEditingPermission(null);
|
|
|
|
|
+ form.resetFields();
|
|
|
|
|
+ setModalVisible(true);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 打开角色权限配置模态框
|
|
|
|
|
+ const handleRolePermission = (role: RoleItem) => {
|
|
|
|
|
+ setSelectedRole(role);
|
|
|
|
|
+ fetchRolePermissions(role.id);
|
|
|
|
|
+ setRolePermissionModalVisible(true);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 保存权限
|
|
|
|
|
+ const handleSave = async (values: any) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (editingPermission) {
|
|
|
|
|
+ await permissionClient[':id'].$put({
|
|
|
|
|
+ param: { id: editingPermission.id },
|
|
|
|
|
+ json: values as UpdatePermissionRequest
|
|
|
|
|
+ });
|
|
|
|
|
+ message.success('更新权限成功');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await permissionClient.$post({
|
|
|
|
|
+ json: values as CreatePermissionRequest
|
|
|
|
|
+ });
|
|
|
|
|
+ message.success('创建权限成功');
|
|
|
|
|
+ }
|
|
|
|
|
+ setModalVisible(false);
|
|
|
|
|
+ fetchPermissions();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('保存权限失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 删除权限
|
|
|
|
|
+ const handleDelete = async (id: number) => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await permissionClient[':id'].$delete({ param: { id } });
|
|
|
|
|
+ message.success('删除权限成功');
|
|
|
|
|
+ fetchPermissions();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('删除权限失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 保存角色权限
|
|
|
|
|
+ const handleSaveRolePermissions = async (values: any) => {
|
|
|
|
|
+ if (!selectedRole) return;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const permissions = values.permissions.map((p: any) => ({
|
|
|
|
|
+ permissionId: p.permissionId,
|
|
|
|
|
+ dataScopeType: p.dataScopeType,
|
|
|
|
|
+ customDepartments: p.customDepartments || []
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ await rolePermissionClient['batch'].$post({
|
|
|
|
|
+ json: {
|
|
|
|
|
+ roleId: selectedRole.id,
|
|
|
|
|
+ permissions
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ message.success('角色权限更新成功');
|
|
|
|
|
+ setRolePermissionModalVisible(false);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ message.error('保存角色权限失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 表格列定义
|
|
|
|
|
+ const columns = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '权限编码',
|
|
|
|
|
+ dataIndex: 'code',
|
|
|
|
|
+ key: 'code',
|
|
|
|
|
+ width: 200,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '权限名称',
|
|
|
|
|
+ dataIndex: 'name',
|
|
|
|
|
+ key: 'name',
|
|
|
|
|
+ width: 200,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '类型',
|
|
|
|
|
+ dataIndex: 'type',
|
|
|
|
|
+ key: 'type',
|
|
|
|
|
+ width: 100,
|
|
|
|
|
+ render: (type: string) => (
|
|
|
|
|
+ <Tag color={type === 'module' ? 'blue' : type === 'operation' ? 'green' : 'orange'}>
|
|
|
|
|
+ {permissionTypeMap[type as keyof typeof permissionTypeMap]}
|
|
|
|
|
+ </Tag>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '所属模块',
|
|
|
|
|
+ dataIndex: 'module',
|
|
|
|
|
+ key: 'module',
|
|
|
|
|
+ width: 120,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '操作类型',
|
|
|
|
|
+ dataIndex: 'action',
|
|
|
|
|
+ key: 'action',
|
|
|
|
|
+ width: 100,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '描述',
|
|
|
|
|
+ dataIndex: 'description',
|
|
|
|
|
+ key: 'description',
|
|
|
|
|
+ ellipsis: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '状态',
|
|
|
|
|
+ dataIndex: 'isActive',
|
|
|
|
|
+ key: 'isActive',
|
|
|
|
|
+ width: 80,
|
|
|
|
|
+ render: (active: number) => (
|
|
|
|
|
+ <Tag color={active === 1 ? 'green' : 'red'}>
|
|
|
|
|
+ {active === 1 ? '启用' : '禁用'}
|
|
|
|
|
+ </Tag>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '排序',
|
|
|
|
|
+ dataIndex: 'sortOrder',
|
|
|
|
|
+ key: 'sortOrder',
|
|
|
|
|
+ width: 80,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '创建时间',
|
|
|
|
|
+ dataIndex: 'createdAt',
|
|
|
|
|
+ key: 'createdAt',
|
|
|
|
|
+ width: 180,
|
|
|
|
|
+ render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '操作',
|
|
|
|
|
+ key: 'action',
|
|
|
|
|
+ width: 120,
|
|
|
|
|
+ fixed: 'right' as const,
|
|
|
|
|
+ render: (_, record) => (
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ type="link"
|
|
|
|
|
+ icon={<EditOutlined />}
|
|
|
|
|
+ onClick={() => handleEdit(record)}
|
|
|
|
|
+ >
|
|
|
|
|
+ 编辑
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ type="link"
|
|
|
|
|
+ danger
|
|
|
|
|
+ icon={<DeleteOutlined />}
|
|
|
|
|
+ onClick={() => handleDelete(record.id)}
|
|
|
|
|
+ >
|
|
|
|
|
+ 删除
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 角色表格列定义
|
|
|
|
|
+ const roleColumns = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '角色名称',
|
|
|
|
|
+ dataIndex: 'name',
|
|
|
|
|
+ key: 'name',
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '描述',
|
|
|
|
|
+ dataIndex: 'description',
|
|
|
|
|
+ key: 'description',
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '创建时间',
|
|
|
|
|
+ dataIndex: 'createdAt',
|
|
|
|
|
+ key: 'createdAt',
|
|
|
|
|
+ render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '操作',
|
|
|
|
|
+ key: 'action',
|
|
|
|
|
+ render: (_, record) => (
|
|
|
|
|
+ <Button
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ icon={<KeyOutlined />}
|
|
|
|
|
+ onClick={() => handleRolePermission(record)}
|
|
|
|
|
+ >
|
|
|
|
|
+ 配置权限
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 权限数据按模块分组
|
|
|
|
|
+ const permissionTreeData = React.useMemo(() => {
|
|
|
|
|
+ const grouped = permissions.reduce((acc, permission) => {
|
|
|
|
|
+ const module = permission.module || '其他';
|
|
|
|
|
+ if (!acc[module]) {
|
|
|
|
|
+ acc[module] = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ acc[module].push(permission);
|
|
|
|
|
+ return acc;
|
|
|
|
|
+ }, {} as Record<string, PermissionItem[]>);
|
|
|
|
|
+
|
|
|
|
|
+ return Object.entries(grouped).map(([module, items]) => ({
|
|
|
|
|
+ title: module,
|
|
|
|
|
+ key: module,
|
|
|
|
|
+ children: items.map(item => ({
|
|
|
|
|
+ title: `${item.name} (${item.code})`,
|
|
|
|
|
+ key: item.id.toString(),
|
|
|
|
|
+ permission: item,
|
|
|
|
|
+ })),
|
|
|
|
|
+ }));
|
|
|
|
|
+ }, [permissions]);
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="p-6">
|
|
|
|
|
+ <Row gutter={[24, 24]}>
|
|
|
|
|
+ <Col span={24}>
|
|
|
|
|
+ <Card
|
|
|
|
|
+ title="权限管理"
|
|
|
|
|
+ extra={
|
|
|
|
|
+ <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
|
|
|
|
+ 新建权限
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ <Table
|
|
|
|
|
+ columns={columns}
|
|
|
|
|
+ dataSource={permissions}
|
|
|
|
|
+ loading={loading}
|
|
|
|
|
+ rowKey="id"
|
|
|
|
|
+ scroll={{ x: 1200 }}
|
|
|
|
|
+ pagination={{
|
|
|
|
|
+ showSizeChanger: true,
|
|
|
|
|
+ showQuickJumper: true,
|
|
|
|
|
+ showTotal: (total) => `共 ${total} 条记录`,
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+
|
|
|
|
|
+ <Col span={24}>
|
|
|
|
|
+ <Card title="角色权限配置">
|
|
|
|
|
+ <Table
|
|
|
|
|
+ columns={roleColumns}
|
|
|
|
|
+ dataSource={roles}
|
|
|
|
|
+ rowKey="id"
|
|
|
|
|
+ pagination={{
|
|
|
|
|
+ showSizeChanger: true,
|
|
|
|
|
+ showQuickJumper: true,
|
|
|
|
|
+ showTotal: (total) => `共 ${total} 条记录`,
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 权限编辑模态框 */}
|
|
|
|
|
+ <Modal
|
|
|
|
|
+ title={editingPermission ? '编辑权限' : '新建权限'}
|
|
|
|
|
+ open={modalVisible}
|
|
|
|
|
+ onCancel={() => setModalVisible(false)}
|
|
|
|
|
+ footer={null}
|
|
|
|
|
+ width={600}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Form form={form} layout="vertical" onFinish={handleSave}>
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="权限编码"
|
|
|
|
|
+ name="code"
|
|
|
|
|
+ rules={[{ required: true, message: '请输入权限编码' }]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Input placeholder="如: client:create" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="权限名称"
|
|
|
|
|
+ name="name"
|
|
|
|
|
+ rules={[{ required: true, message: '请输入权限名称' }]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Input placeholder="请输入权限名称" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="权限类型"
|
|
|
|
|
+ name="type"
|
|
|
|
|
+ rules={[{ required: true, message: '请选择权限类型' }]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Select placeholder="请选择权限类型">
|
|
|
|
|
+ <Option value="module">模块权限</Option>
|
|
|
|
|
+ <Option value="operation">操作权限</Option>
|
|
|
|
|
+ <Option value="data">数据权限</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="所属模块"
|
|
|
|
|
+ name="module"
|
|
|
|
|
+ rules={[{ required: true, message: '请输入所属模块' }]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Input placeholder="如: client" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="操作类型"
|
|
|
|
|
+ name="action"
|
|
|
|
|
+ rules={[{ required: true, message: '请输入操作类型' }]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Input placeholder="如: create" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="描述"
|
|
|
|
|
+ name="description"
|
|
|
|
|
+ >
|
|
|
|
|
+ <TextArea rows={3} placeholder="请输入权限描述" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item
|
|
|
|
|
+ label="排序"
|
|
|
|
|
+ name="sortOrder"
|
|
|
|
|
+ initialValue={0}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Input type="number" placeholder="请输入排序" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item>
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
|
|
+ 保存
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button onClick={() => setModalVisible(false)}>
|
|
|
|
|
+ 取消
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Form>
|
|
|
|
|
+ </Modal>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 角色权限配置模态框 */}
|
|
|
|
|
+ <Modal
|
|
|
|
|
+ title={`配置权限 - ${selectedRole?.name}`}
|
|
|
|
|
+ open={rolePermissionModalVisible}
|
|
|
|
|
+ onCancel={() => setRolePermissionModalVisible(false)}
|
|
|
|
|
+ width={800}
|
|
|
|
|
+ footer={null}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Form
|
|
|
|
|
+ form={rolePermissionForm}
|
|
|
|
|
+ layout="vertical"
|
|
|
|
|
+ onFinish={handleSaveRolePermissions}
|
|
|
|
|
+ initialValues={{ permissions: rolePermissionsData }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Form.Item label="选择权限">
|
|
|
|
|
+ <Tree
|
|
|
|
|
+ checkable
|
|
|
|
|
+ treeData={permissionTreeData}
|
|
|
|
|
+ checkedKeys={rolePermissions.map(String)}
|
|
|
|
|
+ onCheck={(checkedKeys) => {
|
|
|
|
|
+ const checkedIds = checkedKeys.map(Number);
|
|
|
|
|
+ setRolePermissions(checkedIds);
|
|
|
|
|
+ }}
|
|
|
|
|
+ titleRender={(node) => (
|
|
|
|
|
+ <span>
|
|
|
|
|
+ {node.title}
|
|
|
|
|
+ {node.permission && (
|
|
|
|
|
+ <span style={{ marginLeft: 8, color: '#666', fontSize: 12 }}>
|
|
|
|
|
+ {node.permission.description}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ )}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+
|
|
|
|
|
+ <Form.Item>
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
|
|
+ 保存权限配置
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button onClick={() => setRolePermissionModalVisible(false)}>
|
|
|
|
|
+ 取消
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Form>
|
|
|
|
|
+ </Modal>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export default Permissions;
|