按钮权限整理

This commit is contained in:
zzy 2022-09-14 11:27:48 +08:00
parent cac5714935
commit 4cffaf367e
16 changed files with 250 additions and 173 deletions

BIN
dist.zip

Binary file not shown.

View File

@ -16,5 +16,9 @@ export default function access(initialState: {
} }
return routeList.includes(route.name); return routeList.includes(route.name);
}, },
canShowButton: (buttonName) => {
// return true;
return routeList.includes(buttonName);
},
}; };
} }

View File

@ -7,7 +7,7 @@ import HeaderDropdown from '../HeaderDropdown';
import styles from './index.less'; import styles from './index.less';
import type { MenuInfo } from 'rc-menu/lib/interface'; import type { MenuInfo } from 'rc-menu/lib/interface';
import RoutePath from '@/routes/routePath'; import RoutePath from '@/routes/routePath';
import { CACHE_TOKEN } from '@/constants/cacheKey'; import { CACHE_TOKEN, CACHE_USERNAME } from '@/constants/cacheKey';
import ModifyPasswordModal from '@/components/ModifyPassword/ModifyPasswordModal'; import ModifyPasswordModal from '@/components/ModifyPassword/ModifyPasswordModal';
export type GlobalHeaderRightProps = { export type GlobalHeaderRightProps = {
@ -23,6 +23,7 @@ const loginOut = async () => {
// Note: There may be security issues, please note // Note: There may be security issues, please note
if (window.location.pathname !== RoutePath.LOGIN && !redirect) { if (window.location.pathname !== RoutePath.LOGIN && !redirect) {
localStorage.removeItem(CACHE_TOKEN); localStorage.removeItem(CACHE_TOKEN);
localStorage.removeItem(CACHE_USERNAME);
history.replace({ history.replace({
pathname: RoutePath.LOGIN, pathname: RoutePath.LOGIN,
search: stringify({ search: stringify({
@ -66,7 +67,7 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => {
const currentUser = { const currentUser = {
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
name: 'admin', name: localStorage.getItem(CACHE_USERNAME),
}; };
if (!currentUser || !currentUser.name) { if (!currentUser || !currentUser.name) {

View File

@ -12,9 +12,11 @@ import {
} from 'antd'; } from 'antd';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import ProTable, { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-table'; import ProTable, { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-table';
import { Access, useAccess } from 'umi';
export interface toolBarActionsItem { export interface toolBarActionsItem {
type: 'add' | 'batchDelete'; type: 'add' | 'batchDelete';
permission?: string;
text?: string; text?: string;
onConfirm: (val?: string[]) => void; onConfirm: (val?: string[]) => void;
} }
@ -29,6 +31,8 @@ type Record<K extends keyof any, T> = {
}; };
const Table = <T extends Record<string, any>>(props: PropsType) => { const Table = <T extends Record<string, any>>(props: PropsType) => {
const access = useAccess();
const { const {
columns: columnsProps = [], columns: columnsProps = [],
search: searchProps = {}, search: searchProps = {},
@ -88,7 +92,9 @@ const Table = <T extends Record<string, any>>(props: PropsType) => {
const optionRender = (_: any, val: any, ...rest: any) => { const optionRender = (_: any, val: any, ...rest: any) => {
return ( return (
<Space size={0} split={<Divider type="vertical" />}> <Space size={0} split={<Divider type="vertical" />}>
{(item.render && (item.render(_, val, ...rest) as []))?.map((item2) => item2)} {(item.render && (item.render(_, val, ...rest) as []))?.map((item2) => {
return item2;
})}
</Space> </Space>
); );
}; };
@ -165,28 +171,32 @@ const Table = <T extends Record<string, any>>(props: PropsType) => {
toolBarActions.forEach((item) => { toolBarActions.forEach((item) => {
if (item.type === 'add') { if (item.type === 'add') {
buttonList.push( buttonList.push(
<Button <Access accessible={access.canShowButton(item.permission)}>
key="add" <Button
type="primary" key="add"
onClick={() => { type="primary"
item.onConfirm(); onClick={() => {
}} item.onConfirm();
> }}
<PlusOutlined /> >
{item.text || '添加'} <PlusOutlined />
</Button>, {item.text || '添加'}
</Button>
</Access>,
); );
} else if (item.type === 'batchDelete') { } else if (item.type === 'batchDelete') {
buttonList.push( buttonList.push(
<Button <Access accessible={access.canShowButton(item.permission)}>
key="del" <Button
danger key="del"
onClick={() => { danger
handleBatchDelete(item.onConfirm); onClick={() => {
}} handleBatchDelete(item.onConfirm);
> }}
{item.text || '批量删除'} >
</Button>, {item.text || '批量删除'}
</Button>
</Access>,
); );
} }
}); });

View File

@ -1 +1,2 @@
export const CACHE_TOKEN = 'token'; export const CACHE_TOKEN = 'token';
export const CACHE_USERNAME = 'name';

View File

@ -5,7 +5,7 @@ import { useIntl, history, FormattedMessage, useModel } from 'umi';
import { login } from '@/services/login'; import { login } from '@/services/login';
import defaultSettings from '../../../config/defaultSettings'; import defaultSettings from '../../../config/defaultSettings';
import styles from './index.less'; import styles from './index.less';
import { CACHE_TOKEN } from '@/constants/cacheKey'; import { CACHE_TOKEN, CACHE_USERNAME } from '@/constants/cacheKey';
import access from '@/access'; import access from '@/access';
const Login: React.FC = () => { const Login: React.FC = () => {
@ -13,9 +13,9 @@ const Login: React.FC = () => {
const { initialState, refresh } = useModel('@@initialState'); const { initialState, refresh } = useModel('@@initialState');
const handleSubmit = async (values: API.LoginParams) => { const handleSubmit = async (values: API.LoginParams) => {
// 登录 // 登录
const res: any = await login({ ...values }); const res: any = await login({ ...values });
localStorage.setItem(CACHE_TOKEN, res.token); localStorage.setItem(CACHE_TOKEN, res.token);
localStorage.setItem(CACHE_USERNAME, values.name);
/** 此方法会跳转到 redirect 参数所在的位置 */ /** 此方法会跳转到 redirect 参数所在的位置 */
if (!history) return; if (!history) return;
const { query } = history.location; const { query } = history.location;

View File

@ -51,6 +51,7 @@ const Address: React.FC = () => {
{ {
type: 'add', type: 'add',
text: '新建NFT合约', text: '新建NFT合约',
permission: '新建NFT合约',
onConfirm: async () => { onConfirm: async () => {
const res = await getContractInfo({ erc: ContractType.NFT721 }); const res = await getContractInfo({ erc: ContractType.NFT721 });
if (res.bin != '') { if (res.bin != '') {

View File

@ -50,6 +50,7 @@ const Address: React.FC = () => {
{ {
type: 'add', type: 'add',
text: '添加NFT', text: '添加NFT',
permission: '添加NFT',
onConfirm: () => { onConfirm: () => {
setVisible(true); setVisible(true);
}, },

View File

@ -7,8 +7,10 @@ import AddCoinTypeModal from '../components/AddCoinTypeModal';
import EditCoinTypeModal from '../components/EditCoinTypeModal'; import EditCoinTypeModal from '../components/EditCoinTypeModal';
import { initWeb3, deployContract, transfer } from '@/utils/web3'; import { initWeb3, deployContract, transfer } from '@/utils/web3';
import { ContractType } from '@/constants/enum/contract'; import { ContractType } from '@/constants/enum/contract';
import { Access, useAccess } from 'umi';
const CoinTypeList = () => { const CoinTypeList = () => {
const access = useAccess();
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -51,14 +53,16 @@ const CoinTypeList = () => {
valueType: 'option', valueType: 'option',
width: 150, width: 150,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('代币编辑')}>
key="edit" <a
onClick={() => { key="edit"
handleEdit(row); onClick={() => {
}} handleEdit(row);
> }}
>
</a>,
</a>
</Access>,
], ],
}, },
]; ];
@ -71,6 +75,7 @@ const CoinTypeList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '代币添加',
onConfirm: () => { onConfirm: () => {
setIsModalVisible(true); setIsModalVisible(true);
}, },

View File

@ -11,9 +11,11 @@ import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton'; import DeleteButton from '@/components/Table/DeleteButton';
import AddWalletModal from '../components/AddWalletModal'; import AddWalletModal from '../components/AddWalletModal';
import EditWalletModal from '../components/EditWalletModal'; import EditWalletModal from '../components/EditWalletModal';
import { Access, useAccess } from 'umi';
const CollectionAddressList = () => { const CollectionAddressList = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [isEditModalVisible, setIsEditModalVisible] = useState(false);
@ -47,20 +49,24 @@ const CollectionAddressList = () => {
valueType: 'option', valueType: 'option',
width: 150, width: 150,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('收款地址编辑')}>
key="edit" <a
onClick={() => { key="edit"
handleEdit(row); onClick={() => {
}} handleEdit(row);
> }}
>
</a>,
<DeleteButton </a>
key="delete" </Access>,
onDelete={() => { <Access accessible={access.canShowButton('收款地址删除')}>
handleDelete(row.address); <DeleteButton
}} key="delete"
/>, onDelete={() => {
handleDelete(row.address);
}}
/>
</Access>,
], ],
}, },
]; ];
@ -73,6 +79,7 @@ const CollectionAddressList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '收款地址添加',
onConfirm: () => { onConfirm: () => {
setIsModalVisible(true); setIsModalVisible(true);
}, },

View File

@ -6,9 +6,11 @@ import ConfirmButton from '@/components/Table/ConfirmButton';
import moment from 'moment'; import moment from 'moment';
import { WithdrawType } from '@/constants/enum/withdraw'; import { WithdrawType } from '@/constants/enum/withdraw';
import RejectButton from '@/components/Table/RejectButton'; import RejectButton from '@/components/Table/RejectButton';
import { Access, useAccess } from 'umi';
const WithdrawList = () => { const WithdrawList = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const handleClick = async (uuid, status) => { const handleClick = async (uuid, status) => {
await solveWithdraw({ uuid: uuid, status: status }); await solveWithdraw({ uuid: uuid, status: status });
@ -81,24 +83,28 @@ const WithdrawList = () => {
width: 150, width: 150,
render: (_, row) => [ render: (_, row) => [
row.status === 30000 ? ( row.status === 30000 ? (
<ConfirmButton <Access accessible={access.canShowButton('提现通过')}>
key="confirm" <ConfirmButton
title="确认通过提现?" key="confirm"
buttonName="通过" title="确认通过提现?"
onConfirm={() => { buttonName="通过"
handleClick(row.uuid, WithdrawType.SUCCESS); onConfirm={() => {
}} handleClick(row.uuid, WithdrawType.SUCCESS);
/> }}
/>
</Access>
) : null, ) : null,
row.status === 30000 ? ( row.status === 30000 ? (
<RejectButton <Access accessible={access.canShowButton('提现拒绝')}>
key="confirm" <RejectButton
title="确认拒绝提现?" key="confirm"
buttonName="拒绝" title="确认拒绝提现?"
onConfirm={() => { buttonName="拒绝"
handleClick(row.uuid, WithdrawType.FAILED); onConfirm={() => {
}} handleClick(row.uuid, WithdrawType.FAILED);
/> }}
/>
</Access>
) : null, ) : null,
], ],
}, },

View File

@ -12,6 +12,7 @@ import { Popover, Switch } from 'antd';
import AddAccountModal from '../components/AddAccountModal'; import AddAccountModal from '../components/AddAccountModal';
import EditAccountModal from '../components/EditAccountModal'; import EditAccountModal from '../components/EditAccountModal';
import { getRoleList } from '@/services/system/role'; import { getRoleList } from '@/services/system/role';
import { Access, useAccess } from 'umi';
const AccountManageList = () => { const AccountManageList = () => {
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -27,6 +28,8 @@ const AccountManageList = () => {
await deleteUser({ name: name }); await deleteUser({ name: name });
}; };
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '账号', title: '账号',
@ -53,37 +56,44 @@ const AccountManageList = () => {
valueType: 'option', valueType: 'option',
width: 180, width: 180,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('账号编辑')}>
key="edit" <a
onClick={() => { key="edit"
handleEdit(row); placeholder=""
}} onClick={() => {
> handleEdit(row);
}}
</a>, >
<Popover
content={ </a>
<div> </Access>,
<p>/</p> <Access accessible={access.canShowButton('账号启用禁用')}>
</div> <Popover
} content={
> <div>
<Switch <p>/</p>
key="switch" </div>
defaultChecked={row.status} }
size="small" >
onChange={async (checked) => { <Switch
await changeUserStatus({ name: row.name, status: checked }); key="switch"
defaultChecked={row.status}
size="small"
onChange={async (checked) => {
await changeUserStatus({ name: row.name, status: checked });
}}
/>
</Popover>
</Access>,
<Access accessible={access.canShowButton('账号删除')}>
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.name);
tableRef.current?.reload();
}} }}
/> />
</Popover>, </Access>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.name);
tableRef.current?.reload();
}}
/>,
], ],
}, },
]; ];
@ -96,6 +106,7 @@ const AccountManageList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '账号添加',
onConfirm: () => { onConfirm: () => {
setIsModalVisible(true); setIsModalVisible(true);
}, },

View File

@ -7,9 +7,11 @@ import { Popover, Switch } from 'antd';
import AddNoticeModal from '../components/AddNoticeModal'; import AddNoticeModal from '../components/AddNoticeModal';
import EditNoticeModal from '../components/EditNoticeModal'; import EditNoticeModal from '../components/EditNoticeModal';
import { NoticeType } from '@/constants/enum/notice'; import { NoticeType } from '@/constants/enum/notice';
import { Access, useAccess } from 'umi';
const NoticeList = () => { const NoticeList = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false); const [isEditModalVisible, setIsEditModalVisible] = useState(false);
@ -72,39 +74,44 @@ const NoticeList = () => {
valueType: 'option', valueType: 'option',
width: 180, width: 180,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('通知编辑')}>
key="edit" <a
onClick={() => { key="edit"
handleEdit(row); onClick={() => {
}} handleEdit(row);
> }}
>
</a>,
<Popover </a>
content={ </Access>,
<div> <Access accessible={access.canShowButton('通知启用禁用')}>
<p>/</p> <Popover
</div> content={
} <div>
> <p>/</p>
<Switch </div>
key="switch" }
defaultChecked={row.status} >
size="small" <Switch
onChange={async (checked) => { key="switch"
row.status = checked; defaultChecked={row.status}
await updateNotice(row); size="small"
onChange={async (checked) => {
row.status = checked;
await updateNotice(row);
}}
/>
,
</Popover>
</Access>,
<Access accessible={access.canShowButton('通知删除')}>
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.code);
}} }}
/> />
, </Access>,
</Popover>,
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.code);
}}
/>,
], ],
}, },
]; ];
@ -117,6 +124,7 @@ const NoticeList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '通知添加',
onConfirm: () => { onConfirm: () => {
setIsModalVisible(true); setIsModalVisible(true);
}, },

View File

@ -6,6 +6,7 @@ import { getPermission, upsertPermission } from '@/services/system/permission';
import AddPermissionModal from '../components/AddPermissionModal'; import AddPermissionModal from '../components/AddPermissionModal';
import EditPermissionModal from '../components/EditPermissionModal'; import EditPermissionModal from '../components/EditPermissionModal';
import { message } from 'antd'; import { message } from 'antd';
import { Access, useAccess } from 'umi';
const PermissionsList = () => { const PermissionsList = () => {
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -17,6 +18,7 @@ const PermissionsList = () => {
const [rowData, setRowData] = useState({}); const [rowData, setRowData] = useState({});
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const handleAdd = (row: any) => { const handleAdd = (row: any) => {
setRowData(row); setRowData(row);
@ -111,31 +113,37 @@ const PermissionsList = () => {
valueType: 'option', valueType: 'option',
width: 180, width: 180,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('权限添加')}>
key="add" <a
onClick={() => { key="add"
setIsAddFirst(false); onClick={() => {
handleAdd(row); setIsAddFirst(false);
}} handleAdd(row);
>
</a>,
<a
key="edit"
onClick={() => {
setModalData(row);
handleEdit(row);
}}
>
</a>,
Object.prototype.hasOwnProperty.call(row, 'children') ? null : (
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row);
}} }}
/> >
</a>
</Access>,
<Access accessible={access.canShowButton('权限编辑')}>
<a
key="edit"
onClick={() => {
setModalData(row);
handleEdit(row);
}}
>
</a>
</Access>,
Object.prototype.hasOwnProperty.call(row, 'children') ? null : (
<Access accessible={access.canShowButton('权限删除')}>
<DeleteButton
key="delete"
onDelete={() => {
handleDelete(row);
}}
/>
</Access>
), ),
], ],
}, },
@ -151,6 +159,7 @@ const PermissionsList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '权限添加',
onConfirm: () => { onConfirm: () => {
setIsAddFirst(true); setIsAddFirst(true);
setIsModalVisible(true); setIsModalVisible(true);

View File

@ -6,9 +6,11 @@ import DeleteButton from '@/components/Table/DeleteButton';
import AddRoleModal from '../components/AddRoleModal'; import AddRoleModal from '../components/AddRoleModal';
import EditRoleModal from '../components/EditRoleModal'; import EditRoleModal from '../components/EditRoleModal';
import AuthPermissionsDrawer from '../components/AuthPermissionsDrawer'; import AuthPermissionsDrawer from '../components/AuthPermissionsDrawer';
import { Access, useAccess } from 'umi';
const RoleList = () => { const RoleList = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const access = useAccess();
const [isDrawerVisible, setIsDrawerVisible] = useState(false); const [isDrawerVisible, setIsDrawerVisible] = useState(false);
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -47,28 +49,34 @@ const RoleList = () => {
valueType: 'option', valueType: 'option',
width: 180, width: 180,
render: (_, row) => [ render: (_, row) => [
<a <Access accessible={access.canShowButton('角色编辑')}>
key="edit" <a
onClick={() => { key="edit"
handleEdit(row); onClick={() => {
}} handleEdit(row);
> }}
>
</a>,
<a </a>
key="auth" </Access>,
onClick={() => { <Access accessible={access.canShowButton('角色授权')}>
handleAuth(row); <a
}} key="auth"
> onClick={() => {
handleAuth(row);
</a>, }}
<DeleteButton >
key="delete"
onDelete={() => { </a>
handleDelete(row.id); </Access>,
}} <Access accessible={access.canShowButton('角色删除')}>
/>, <DeleteButton
key="delete"
onDelete={() => {
handleDelete(row.id);
}}
/>
</Access>,
], ],
}, },
]; ];
@ -82,6 +90,7 @@ const RoleList = () => {
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
permission: '角色添加',
onConfirm: () => { onConfirm: () => {
setIsModalVisible(true); setIsModalVisible(true);
}, },

View File

@ -2,10 +2,12 @@ import React, { useState, useEffect } from 'react';
import { Button, Input, Popconfirm } from 'antd'; import { Button, Input, Popconfirm } from 'antd';
import styles from './index.less'; import styles from './index.less';
import { createSecretKey, getSecretKey } from '@/services/system/secretKey'; import { createSecretKey, getSecretKey } from '@/services/system/secretKey';
import { Access, useAccess } from 'umi';
const { TextArea } = Input; const { TextArea } = Input;
const SecretKey: React.FC = () => { const SecretKey: React.FC = () => {
const access = useAccess();
const [secretKey, setSecretKey] = useState(''); const [secretKey, setSecretKey] = useState('');
const create = async () => { const create = async () => {
@ -24,11 +26,13 @@ const SecretKey: React.FC = () => {
return ( return (
<div className={styles.container}> <div className={styles.container}>
<Popconfirm title="确定创建密钥?" onConfirm={create} okText="确定" cancelText="取消"> <Access accessible={access.canShowButton('创建密钥')}>
<Button className={styles.button} type="primary"> <Popconfirm title="确定创建密钥?" onConfirm={create} okText="确定" cancelText="取消">
<Button className={styles.button} type="primary">
</Button>
</Popconfirm> </Button>
</Popconfirm>
</Access>
<TextArea className={styles.textarea} rows={16} value={secretKey} /> <TextArea className={styles.textarea} rows={16} value={secretKey} />
</div> </div>