import {
|
CheckCircleOutlined,
|
CloseCircleOutlined,
|
InfoCircleOutlined,
|
PlusOutlined,
|
SafetyCertificateOutlined,
|
} from '@ant-design/icons';
|
import {
|
Alert,
|
App as AntdApp,
|
Avatar,
|
Card,
|
Col,
|
Descriptions,
|
Divider,
|
Row,
|
Space,
|
Table,
|
Tag,
|
} from 'antd';
|
import type { TableProps } from 'antd';
|
import AuthButton from '@/components/AuthButton';
|
import { PERMISSION, PERMISSION_LABELS } from '@/constants/permissions';
|
import { usePermission } from '@/hooks/usePermission';
|
import './ButtonPermission.scss';
|
|
interface PermissionRow {
|
key: string;
|
code: string;
|
label: string;
|
granted: boolean;
|
}
|
|
export default function ButtonPermission() {
|
const { user, permissions, isSuperAdmin } = usePermission();
|
const { message } = AntdApp.useApp();
|
|
const permissionRows: PermissionRow[] = Object.entries(PERMISSION_LABELS).map(
|
([code, label]) => ({
|
key: code,
|
code,
|
label,
|
granted: isSuperAdmin || permissions.includes(code),
|
}),
|
);
|
|
const notify = (name: string) => {
|
message.success(`${name}按钮已点击,当前账号拥有该权限`);
|
};
|
|
const columns: TableProps<PermissionRow>['columns'] = [
|
{
|
title: '权限码',
|
dataIndex: 'code',
|
width: 260,
|
render: (value: string) => <code className="permission-code">{value}</code>,
|
},
|
{ title: '权限说明', dataIndex: 'label' },
|
{
|
title: '当前账号',
|
dataIndex: 'granted',
|
width: 130,
|
render: (granted: boolean) =>
|
granted ? (
|
<Tag icon={<CheckCircleOutlined />} color="success" bordered={false}>
|
已授权
|
</Tag>
|
) : (
|
<Tag icon={<CloseCircleOutlined />} bordered={false}>
|
未授权
|
</Tag>
|
),
|
},
|
];
|
|
return (
|
<div className="button-permission-page">
|
<div className="page-header">
|
<div>
|
<h1 className="page-header__title">按钮权限</h1>
|
<p className="page-header__desc">
|
按钮通过权限码决定显示、隐藏或禁用,与路由守卫使用同一套权限数据。
|
</p>
|
</div>
|
<div className="page-header__actions">
|
<Tag color="purple" bordered={false}>
|
当前账号:{user?.nickname}
|
</Tag>
|
</div>
|
</div>
|
|
<Alert
|
className="button-permission-alert"
|
type="warning"
|
showIcon
|
message="用不同账号登录体验权限差异"
|
description="admin / admin123 拥有全部权限(*);user / user123 仅拥有查看类权限。切换账号后,侧边栏菜单和按钮会同步变化。"
|
/>
|
|
<Row gutter={[16, 16]}>
|
<Col xs={24} xl={16}>
|
<Card className="permission-demo-card" variant="borderless" title="按钮权限演示">
|
<p className="permission-demo-card__hint">
|
下面这些按钮都绑定了 <code>permission</code> 属性,没有对应权限时默认直接隐藏。
|
</p>
|
|
<Space wrap size={[10, 10]}>
|
<AuthButton
|
type="primary"
|
icon={<PlusOutlined />}
|
permission={PERMISSION.USER_ADD}
|
onClick={() => notify('新增用户')}
|
>
|
新增用户
|
</AuthButton>
|
<AuthButton
|
permission={PERMISSION.USER_EDIT}
|
onClick={() => notify('编辑用户')}
|
>
|
编辑用户
|
</AuthButton>
|
<AuthButton
|
danger
|
permission={PERMISSION.USER_DELETE}
|
onClick={() => notify('删除用户')}
|
>
|
删除用户
|
</AuthButton>
|
<AuthButton
|
permission={PERMISSION.ORDER_EXPORT}
|
onClick={() => notify('导出订单')}
|
>
|
导出订单
|
</AuthButton>
|
<AuthButton
|
permission={PERMISSION.CUSTOMER_ADD}
|
onClick={() => notify('新增客户')}
|
>
|
新增客户
|
</AuthButton>
|
<AuthButton
|
permission={PERMISSION.USER_VIEW}
|
onClick={() => notify('查看用户')}
|
>
|
查看用户(两个账号均可见)
|
</AuthButton>
|
</Space>
|
|
<Divider />
|
|
<p className="permission-demo-card__hint">
|
也可以使用 <code>fallback="disabled"</code> 保留按钮但置灰:
|
</p>
|
<Space wrap size={[10, 10]}>
|
<AuthButton
|
permission={PERMISSION.PERMISSION_EDIT}
|
fallback="disabled"
|
onClick={() => notify('编辑权限配置')}
|
>
|
编辑权限配置(禁用态)
|
</AuthButton>
|
</Space>
|
</Card>
|
</Col>
|
|
<Col xs={24} xl={8}>
|
<Card className="permission-account-card" variant="borderless" title="当前账号">
|
<div className="permission-account">
|
<Avatar size={56} className="permission-account__avatar">
|
{user?.nickname?.charAt(0) ?? 'U'}
|
</Avatar>
|
<div className="permission-account__meta">
|
<strong>{user?.nickname}</strong>
|
<span>@{user?.username}</span>
|
</div>
|
</div>
|
|
<Descriptions
|
className="permission-account__desc"
|
column={1}
|
size="small"
|
items={[
|
{
|
key: 'role',
|
label: '角色',
|
children: (
|
<Tag color={isSuperAdmin ? 'purple' : 'blue'} bordered={false}>
|
{isSuperAdmin ? '超级管理员' : '普通用户'}
|
</Tag>
|
),
|
},
|
{
|
key: 'scope',
|
label: '权限范围',
|
children: isSuperAdmin ? '全部权限(*)' : `${permissions.length} 项权限`,
|
},
|
]}
|
/>
|
|
<div className="permission-tags">
|
<div className="permission-tags__title">
|
<SafetyCertificateOutlined /> 已授予的权限码
|
</div>
|
<Space wrap size={[6, 6]}>
|
{isSuperAdmin ? (
|
<Tag color="purple" bordered={false}>
|
* 全部权限
|
</Tag>
|
) : (
|
permissions.map((permission) => (
|
<Tag key={permission} bordered={false}>
|
{permission}
|
</Tag>
|
))
|
)}
|
</Space>
|
</div>
|
|
<div className="permission-note">
|
<InfoCircleOutlined />
|
<span>前端权限只负责界面展示,真实项目仍需后端对接口做二次鉴权。</span>
|
</div>
|
</Card>
|
</Col>
|
</Row>
|
|
<Card className="table-card permission-list-card" variant="borderless" title="权限码清单">
|
<Table<PermissionRow>
|
rowKey="key"
|
columns={columns}
|
dataSource={permissionRows}
|
pagination={false}
|
scroll={{ x: 640 }}
|
/>
|
</Card>
|
</div>
|
);
|
}
|