import { Button, Card, Col, message, Row, Space, Table, Tag, Tree, Typography } from "antd"; import type { DataNode } from "antd/es/tree"; import { useEffect, useMemo, useState } from "react"; import { listPermissions, listRolePermissions, listRoles, saveRolePermissions } from "../api"; import type { SysPermission, SysRole } from "../types"; const { Title, Text } = Typography; type PermissionNode = SysPermission & { key: number; children?: PermissionNode[] }; function buildPermissionTree(list: SysPermission[]): PermissionNode[] { const map = new Map(); const roots: PermissionNode[] = []; list.forEach((item) => { map.set(item.permId, { ...item, key: item.permId, children: [] }); }); map.forEach((node) => { if (node.parentId && map.has(node.parentId)) { map.get(node.parentId)!.children!.push(node); } else { roots.push(node); } }); const sortNodes = (nodes: PermissionNode[]) => { nodes.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); nodes.forEach((n) => n.children && sortNodes(n.children)); }; sortNodes(roots); return roots; } function toTreeData(nodes: PermissionNode[]): DataNode[] { return nodes.map((node) => ({ key: node.permId, title: ( {node.name} {node.permType === "button" && 按钮} ), children: node.children ? toTreeData(node.children) : undefined })); } export default function RolePermissionBinding() { const [roles, setRoles] = useState([]); const [permissions, setPermissions] = useState([]); const [loadingRoles, setLoadingRoles] = useState(false); const [loadingPerms, setLoadingPerms] = useState(false); const [saving, setSaving] = useState(false); const [selectedRoleId, setSelectedRoleId] = useState(null); const [checkedPermIds, setCheckedPermIds] = useState([]); const selectedRole = useMemo( () => roles.find((r) => r.roleId === selectedRoleId) || null, [roles, selectedRoleId] ); const loadRoles = async () => { setLoadingRoles(true); try { const list = await listRoles(); setRoles(list || []); } finally { setLoadingRoles(false); } }; const loadPermissions = async () => { setLoadingPerms(true); try { const list = await listPermissions(); setPermissions(list || []); } catch (e) { message.error("加载权限失败,请确认接口已实现"); } finally { setLoadingPerms(false); } }; const loadRolePermissions = async (roleId: number) => { try { const list = await listRolePermissions(roleId); setCheckedPermIds(list || []); } catch (e) { setCheckedPermIds([]); message.error("加载角色权限失败,请确认接口已实现"); } }; useEffect(() => { loadRoles(); loadPermissions(); }, []); useEffect(() => { if (selectedRoleId) { loadRolePermissions(selectedRoleId); } else { setCheckedPermIds([]); } }, [selectedRoleId]); const treeData = useMemo(() => toTreeData(buildPermissionTree(permissions)), [permissions]); const handleSave = async () => { if (!selectedRoleId) { message.warning("请先选择角色"); return; } setSaving(true); try { await saveRolePermissions(selectedRoleId, checkedPermIds); message.success("角色权限绑定已保存"); } catch (e) { message.error("保存失败,请确认接口已实现"); } finally { setSaving(false); } }; return (
角色权限绑定 为角色配置菜单与按钮权限
setSelectedRoleId(keys[0] as number) }} pagination={{ pageSize: 8 }} columns={[ { title: "ID", dataIndex: "roleId", width: 80 }, { title: "角色编码", dataIndex: "roleCode" }, { title: "角色名称", dataIndex: "roleName" }, { title: "状态", dataIndex: "status", width: 90, render: (v) => (v === 1 ? 启用 : 禁用) } ]} /> {selectedRole ? `当前角色:${selectedRole.roleName}` : "未选择角色"} } > setCheckedPermIds(keys as number[])} defaultExpandAll /> {!permissions.length && !loadingPerms && (
暂无权限数据
)}
); }