权限修改

This commit is contained in:
zzy 2022-09-13 09:23:09 +08:00
parent 514d0db8f3
commit 9b8188a288
30 changed files with 1006 additions and 223 deletions

View File

@ -12,7 +12,7 @@ const Settings: LayoutSettings & {
fixedHeader: false, fixedHeader: false,
fixSiderbar: true, fixSiderbar: true,
colorWeak: false, colorWeak: false,
title: 'Pro', title: 'TBG',
pwa: false, pwa: false,
logo: '/pro_icon.svg', logo: '/pro_icon.svg',
iconfontUrl: '', iconfontUrl: '',

View File

@ -11,7 +11,8 @@ export default {
// localhost:8000/api/** -> https://preview.pro.ant.design/api/** // localhost:8000/api/** -> https://preview.pro.ant.design/api/**
'/tbg/api/v1': { '/tbg/api/v1': {
// 要代理的地址 // 要代理的地址
target: 'http://192.168.88.238:9999', // target: 'http://81.71.13.173:9080',
target: 'http://127.0.0.1:9999',
// 配置了这个可以从 http 代理到 https // 配置了这个可以从 http 代理到 https
// 依赖 origin 的功能可能需要这个,比如 cookie // 依赖 origin 的功能可能需要这个,比如 cookie
changeOrigin: true, changeOrigin: true,

View File

@ -10,11 +10,11 @@ export default function access(initialState: {
return { return {
canAdmin: currentUser && currentUser.access === 'admin', canAdmin: currentUser && currentUser.access === 'admin',
normalRouteFilter: (route: any) => { normalRouteFilter: (route: any) => {
return true; // return true;
// if (routeList == null || routeList == undefined || routeList.length == 0) { if (routeList == null || routeList == undefined || routeList.length == 0) {
// return true; return true;
// } }
// return routeList.includes(route.name); return routeList.includes(route.name);
}, },
}; };
} }

View File

@ -4,18 +4,21 @@ import { history } from 'umi';
import RightContent from '@/components/RightContent'; import RightContent from '@/components/RightContent';
import RoutePath from '@/routes/routePath'; import RoutePath from '@/routes/routePath';
import { CACHE_TOKEN } from '@/constants/cacheKey'; import { CACHE_TOKEN } from '@/constants/cacheKey';
// import { getRoleList } from './services/system/role'; import { getRoleList } from './services/system/role';
// ProLayout 支持的api https://procomponents.ant.design/components/layout // ProLayout 支持的api https://procomponents.ant.design/components/layout
// export async function getInitialState() { export async function getInitialState() {
// if (localStorage.getItem(CACHE_TOKEN)) { if (localStorage.getItem(CACHE_TOKEN)) {
// const res = await getRoleList({}); const res = await getRoleList({});
// return { // return {
// routeList: res, // routeList: res,
// }; // };
// } return {
// } routeList: [],
};
}
}
export const layout: RunTimeLayoutConfig = ({ initialState }) => { export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return { return {

View File

@ -1,9 +1,3 @@
.delete-btn {
color: @error-color;
&:hover {
color: @error-color !important;
}
}
.disabled { .disabled {
color: @disabled-color; color: @disabled-color;
cursor: not-allowed; cursor: not-allowed;
@ -11,3 +5,10 @@
color: @disabled-color !important; color: @disabled-color !important;
} }
} }
.confirm-btn {
color: @success-color;
&:hover {
color: @success-color !important;
}
}

View File

@ -17,7 +17,7 @@ const ConfirmButton: React.FC<PropsType> = ({
}) => { }) => {
return ( return (
<Popconfirm title={title} disabled={disabled} onConfirm={onConfirm} okText="是" cancelText="否"> <Popconfirm title={title} disabled={disabled} onConfirm={onConfirm} okText="是" cancelText="否">
<a className={classNames(styles.deleteBtn, disabled ? styles.disabled : '')}>{buttonName}</a> <a className={classNames(styles.confirmBtn, disabled ? styles.disabled : '')}>{buttonName}</a>
</Popconfirm> </Popconfirm>
); );
}; };

View File

@ -0,0 +1,14 @@
.disabled {
color: @disabled-color;
cursor: not-allowed;
&:hover {
color: @disabled-color !important;
}
}
.reject-btn {
color: @error-color;
&:hover {
color: @error-color !important;
}
}

View File

@ -0,0 +1,24 @@
import React from 'react';
import { Popconfirm } from 'antd';
import styles from './index.less';
import classNames from 'classnames';
interface PropsType {
onConfirm: () => void;
title?: string;
buttonName?: string;
disabled?: boolean;
}
const ConfirmButton: React.FC<PropsType> = ({
onConfirm,
disabled = false,
title = '',
buttonName = '',
}) => {
return (
<Popconfirm title={title} disabled={disabled} onConfirm={onConfirm} okText="是" cancelText="否">
<a className={classNames(styles.rejectBtn, disabled ? styles.disabled : '')}>{buttonName}</a>
</Popconfirm>
);
};
export default ConfirmButton;

View File

@ -13,6 +13,7 @@ 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);
/** 此方法会跳转到 redirect 参数所在的位置 */ /** 此方法会跳转到 redirect 参数所在的位置 */

View File

@ -1,13 +1,19 @@
import React, { useRef } from 'react'; import React, { useRef, useState } from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
// import { fetchTableData } from '@/utils/table'; // import { fetchTableData } from '@/utils/table';
import { Form, FormItem, Input, NumberPicker } from '@formily/antd'; import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
import { Button } from 'antd';
import { initWeb3, NFTMint } from '@/utils/web3';
import { getContractInfo } from '@/services/contract';
import { getNFTContractList, mintNFT } from '@/services/nft';
import { ContractType } from '@/constants/enum/contract';
interface AddNftModalPropsType extends ModalProps { interface AddNftModalPropsType extends ModalProps {
onOk: (val: any) => void; onOk: () => void;
onCancel: () => void; onCancel: () => void;
// loading: boolean;
} }
const SchemaField = createSchemaField({ const SchemaField = createSchemaField({
@ -21,10 +27,26 @@ const SchemaField = createSchemaField({
const form = createForm({}); const form = createForm({});
const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => { const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
const handleOk = () => { const [loading, setLoading] = useState(false);
form.submit(() => {
const handleOk = async () => {
form.submit(async () => {
setLoading(true);
const formState = form.getFormState(); const formState = form.getFormState();
onOk(formState.values); await initWeb3();
const contractInfo = await getContractInfo({ erc: ContractType.NFT721 });
const res = await getNFTContractList();
const tx_hash = await NFTMint({
abi: contractInfo.abi,
address: res.items[0].address,
toAddress: formState.values.toAddress,
name: formState.values.name,
});
console.log('tx_hash = ', tx_hash);
formState.values.tx_hash = tx_hash;
await mintNFT(formState.values);
setLoading(false);
onOk();
}); });
}; };
const handleCancel = () => { const handleCancel = () => {
@ -32,15 +54,21 @@ const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
}; };
return ( return (
<Modal title="添加NFT" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}> <Modal
title="添加NFT"
width={800}
footer={[
<Button key="cancel" onClick={handleCancel}>
</Button>,
<Button key="submit" type="primary" loading={loading} onClick={handleOk}>
</Button>,
]}
{...rest}
>
<Form form={form} labelCol={4} wrapperCol={18}> <Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField> <SchemaField>
<SchemaField.Number
name="token_id"
title="ID"
x-decorator="FormItem"
x-component="NumberPicker"
/>
<SchemaField.String <SchemaField.String
name="toAddress" name="toAddress"
title="所有者地址" title="所有者地址"

View File

@ -3,22 +3,13 @@ import Table, { ProColumns, ActionType } from '@/components/Table';
import { message } from 'antd'; import { message } from 'antd';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import AddNftModal from './components/AddNftModel'; import AddNftModal from './components/AddNftModel';
import { initWeb3, NFTMint } from '@/utils/web3'; import { getNFTList } from '@/services/nft';
import { getContractInfo } from '@/services/contract';
import { ContractType } from '@/constants/enum/contract';
import { checkTokenId, getNFTContractList, getNFTList, mintNFT } from '@/services/nft';
const Address: React.FC = () => { const Address: React.FC = () => {
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{
title: 'TokenId',
dataIndex: 'token_id',
width: '10%',
hideInSearch: true,
},
{ {
title: '所有者地址', title: '所有者地址',
dataIndex: 'address', dataIndex: 'address',
@ -74,19 +65,7 @@ const Address: React.FC = () => {
onCancel={function () { onCancel={function () {
setVisible(false); setVisible(false);
}} }}
onOk={async function (val: any): Promise<void> { onOk={async function (): Promise<void> {
await checkTokenId({ token_id: val.token_id });
await initWeb3();
const contractInfo = await getContractInfo({ erc: ContractType.NFT721 });
const res = await getNFTContractList();
await NFTMint({
abi: contractInfo.abi,
address: res.items[0].address,
toAddress: val.toAddress,
name: val.name,
token_id: val.token_id,
});
await mintNFT(val);
tableRef.current?.reload(); tableRef.current?.reload();
setVisible(false); setVisible(false);
}} }}

View File

@ -3,7 +3,7 @@ import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd'; import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
interface EditCoinTypeModalPropsType extends ModalProps { interface EditCoinTypeModalPropsType extends ModalProps {
editModalData: any; editModalData: any;
@ -15,7 +15,7 @@ const SchemaField = createSchemaField({
components: { components: {
FormItem, FormItem,
Input, Input,
Select, NumberPicker,
}, },
}); });

View File

@ -10,7 +10,7 @@ const RecordList = () => {
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '时间', title: '时间',
dataIndex: 'time', dataIndex: 'searchTime',
hideInTable: true, hideInTable: true,
valueType: 'dateRange', valueType: 'dateRange',
ellipsis: true, ellipsis: true,
@ -55,12 +55,11 @@ const RecordList = () => {
return ( return (
<Table <Table
columns={columns} columns={columns}
rowKey="tx_hash"
actionRef={tableRef} actionRef={tableRef}
request={async (params) => { request={async (params) => {
if ((params.time ?? '') !== '') { if ((params.searchTime ?? '') !== '') {
const start = Date.parse(params.time[0] + ' 00:00:00'); const start = Date.parse(params.searchTime[0] + ' 00:00:00');
const end = Date.parse(params.time[1] + ' 23:59:59'); const end = Date.parse(params.searchTime[1] + ' 23:59:59');
params.start_time = start / 1000; params.start_time = start / 1000;
params.end_time = end / 1000; params.end_time = end / 1000;
} }

View File

@ -1,5 +1,5 @@
// 创建弹窗 // 创建弹窗
import React, { useRef } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'; import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core';
import { FormProvider, createSchemaField } from '@formily/react'; import { FormProvider, createSchemaField } from '@formily/react';
import { getCoinTypeList } from '@/services/recharge/coinType'; import { getCoinTypeList } from '@/services/recharge/coinType';
@ -20,39 +20,50 @@ const SchemaField = createSchemaField({
}, },
}); });
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('name', async (field) => {
const list = await getCoinTypeList({ page: 1, size: 10 });
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.name,
value: element.name,
};
option.push(item);
}
return option;
});
},
});
const AddWalletModal = ({ onOk, onCancel, ...rest }: AddWalletModalPropsType) => { const AddWalletModal = ({ onOk, onCancel, ...rest }: AddWalletModalPropsType) => {
const [coinTypeData, setCoinTypeData] = useState({});
const getSelectData = async () => {
const list = await getCoinTypeList({ page: 1, size: 10 });
setCoinTypeData(list);
};
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('name', async (field) => {
const list = coinTypeData;
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.name,
value: element.name,
};
option.push(item);
}
return option;
});
},
});
useEffect(() => {
getSelectData();
}, []);
const handleOk = () => { const handleOk = () => {
form.submit(async () => { form.submit(async () => {
const formState = form.getFormState(); const formState = form.getFormState();

View File

@ -1,5 +1,5 @@
// 修改弹窗 // 修改弹窗
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect, useState } from 'react';
import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'; import { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core';
import { getCoinTypeList } from '@/services/recharge/coinType'; import { getCoinTypeList } from '@/services/recharge/coinType';
import { FormProvider, createSchemaField } from '@formily/react'; import { FormProvider, createSchemaField } from '@formily/react';
@ -22,6 +22,13 @@ const SchemaField = createSchemaField({
}); });
const EditWalletModal = ({ onOk, onCancel, editModalData, ...rest }: EditWalletModalPropsType) => { const EditWalletModal = ({ onOk, onCancel, editModalData, ...rest }: EditWalletModalPropsType) => {
const [coinTypeData, setCoinTypeData] = useState({});
const getSelectData = async () => {
const list = await getCoinTypeList({ page: 1, size: 10 });
setCoinTypeData(list);
};
const useAsyncDataSource = ( const useAsyncDataSource = (
pattern: FormPathPattern, pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>, service: (field: Field) => Promise<{ label: string; value: any }[]>,
@ -39,7 +46,8 @@ const EditWalletModal = ({ onOk, onCancel, editModalData, ...rest }: EditWalletM
effects: () => { effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('name', async (field) => { useAsyncDataSource('name', async (field) => {
const list = await getCoinTypeList({ page: 1, size: 10 }); getSelectData();
const list = coinTypeData;
const option = []; const option = [];
for (let index = 0; index < list.items.length; index++) { for (let index = 0; index < list.items.length; index++) {
const element = list.items[index]; const element = list.items[index];

View File

@ -5,10 +5,14 @@ import { fetchTableData } from '@/utils/table';
import ConfirmButton from '@/components/Table/ConfirmButton'; 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';
const WithdrawList = () => { const WithdrawList = () => {
const handleConfirm = async (uuid) => { const tableRef = useRef<ActionType>();
await solveWithdraw({ uuid: uuid });
const handleClick = async (uuid, status) => {
await solveWithdraw({ uuid: uuid, status: status });
tableRef.current?.reload();
}; };
const WithdrawTypeList = [ const WithdrawTypeList = [
@ -29,7 +33,6 @@ const WithdrawList = () => {
}, },
]; ];
const tableRef = useRef<ActionType>();
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '提现订单号', title: '提现订单号',
@ -51,6 +54,7 @@ const WithdrawList = () => {
{ {
title: '类型', title: '类型',
dataIndex: 'type', dataIndex: 'type',
hideInSearch: true,
width: '10%', width: '10%',
}, },
{ {
@ -76,14 +80,26 @@ const WithdrawList = () => {
valueType: 'option', valueType: 'option',
width: 150, width: 150,
render: (_, row) => [ render: (_, row) => [
<ConfirmButton row.status === 30000 ? (
key="confirm" <ConfirmButton
title="确认通过提现?" key="confirm"
buttonName="通过" title="确认通过提现?"
onConfirm={() => { buttonName="通过"
handleConfirm(row.uuid); onConfirm={() => {
}} handleClick(row.uuid, WithdrawType.SUCCESS);
/>, }}
/>
) : null,
row.status === 30000 ? (
<RejectButton
key="confirm"
title="确认拒绝提现?"
buttonName="拒绝"
onConfirm={() => {
handleClick(row.uuid, WithdrawType.FAILED);
}}
/>
) : null,
], ],
}, },
]; ];

View File

@ -8,7 +8,7 @@ import {
} from '@/services/system/accountManage'; } from '@/services/system/accountManage';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton'; import DeleteButton from '@/components/Table/DeleteButton';
import { Switch } from 'antd'; 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';
@ -52,14 +52,22 @@ const AccountManageList = () => {
> >
</a>, </a>,
<Switch <Popover
key="switch" content={
defaultChecked={row.status} <div>
size="small" <p>/</p>
onChange={async (checked) => { </div>
await changeUserStatus({ name: row.name, status: checked }); }
}} >
/>, <Switch
key="switch"
defaultChecked={row.status}
size="small"
onChange={async (checked) => {
await changeUserStatus({ name: row.name, status: checked });
}}
/>
</Popover>,
<DeleteButton <DeleteButton
key="delete" key="delete"
onDelete={() => { onDelete={() => {

View File

@ -1,11 +1,12 @@
// 创建弹窗 // 创建弹窗
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { createForm } from '@formily/core'; import { createForm, FormPathPattern, onFieldReact } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, TreeSelect } from '@formily/antd'; import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser } from '@/services/system/accountManage'; import { addUser } from '@/services/system/accountManage';
import routes from '@/routes'; import { action } from '@formily/reactive';
import { getRoleList } from '@/services/system/role';
interface AddAccountModalPropsType extends ModalProps { interface AddAccountModalPropsType extends ModalProps {
onCancel: () => void; onCancel: () => void;
@ -16,14 +17,53 @@ const SchemaField = createSchemaField({
components: { components: {
FormItem, FormItem,
Input, Input,
TreeSelect, Select,
}, },
}); });
const form = createForm({});
const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => { const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => {
const [treeData, setTreeData] = useState({}); const [roleListData, setRoleListData] = useState({});
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('role', async (field) => {
const list = roleListData;
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.role_name,
value: element.id,
};
option.push(item);
}
return option;
});
},
});
const getSelectData = async () => {
const list = await getRoleList({ page: 1, size: 10 });
setRoleListData(list);
};
useEffect(() => {
getSelectData();
}, []);
const handleOk = async () => { const handleOk = async () => {
form.submit(async () => { form.submit(async () => {
@ -38,30 +78,6 @@ const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType)
onCancel(); onCancel();
}; };
const onChange = (newValue: string[]) => {};
useEffect(() => {
const array = routes;
array.forEach((item: any, index) => {
if (item.name == '' || item.name == null || item.name == undefined) {
array.splice(index, 1);
console.log('array.splice(index, 1);');
}
item.key = index + 1;
if (Object.prototype.hasOwnProperty.call(item, 'routes')) {
item.routes?.forEach((item2: any, index2: number) => {
if (item2.name == '' || item2.name == null || item2.name == undefined) {
item.routes.splice(index2, 1);
console.log('item.routes.splice(index2, 1);');
}
item2.key = parseInt(index + 1 + '' + index2);
});
}
});
console.log('array = ', array);
setTreeData(array);
}, []);
return ( return (
<Modal title="添加管理账号" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}> <Modal title="添加管理账号" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}> <Form form={form} labelCol={4} wrapperCol={18}>
@ -91,19 +107,12 @@ const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType)
/> />
<SchemaField.String <SchemaField.String
name="role" name="role"
title="权限" title="角色"
required required
x-validator={{
required: true,
}}
x-decorator="FormItem" x-decorator="FormItem"
x-component="TreeSelect" x-component="Select"
x-component-props={{ x-component-props={{
fieldNames: { label: 'name', children: 'routes', value: 'name' }, placeholder: '请选择角色',
onChange: onChange,
treeCheckable: true,
treeData: treeData,
placeholder: '请选择权限',
}} }}
/> />
</SchemaField> </SchemaField>

View File

@ -1,12 +1,14 @@
// 创建弹窗 // 创建弹窗
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect, useState } from 'react';
import { createForm } from '@formily/core'; import { createForm, FormPathPattern, onFieldReact } from '@formily/core';
import { createSchemaField } from '@formily/react'; import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal'; import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd'; import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser, updateUser } from '@/services/system/accountManage'; import { updateUser } from '@/services/system/accountManage';
import { getRoleList } from '@/services/system/role';
import { action } from '@formily/reactive';
interface AddUserModalPropsType extends ModalProps { interface EditAccountModalPropsType extends ModalProps {
editModalData: any; editModalData: any;
onCancel: () => void; onCancel: () => void;
onOk: () => void; onOk: () => void;
@ -20,9 +22,52 @@ const SchemaField = createSchemaField({
}, },
}); });
const form = createForm({}); const EditAccountModal = ({
onOk,
onCancel,
editModalData,
...rest
}: EditAccountModalPropsType) => {
const [roleListData, setRoleListData] = useState({});
const getSelectData = async () => {
const list = await getRoleList({ page: 1, size: 10 });
setRoleListData(list);
};
const useAsyncDataSource = (
pattern: FormPathPattern,
service: (field: Field) => Promise<{ label: string; value: any }[]>,
) => {
onFieldReact(pattern, (field) => {
service(field).then(
action.bound((data) => {
field.dataSource = data;
}),
);
});
};
const form = createForm({
effects: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
useAsyncDataSource('role', async (field) => {
getSelectData();
const list = roleListData;
const option = [];
for (let index = 0; index < list.items.length; index++) {
const element = list.items[index];
const item = {
label: element.role_name,
value: element.id,
};
option.push(item);
}
return option;
});
},
});
const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPropsType) => {
useEffect(() => { useEffect(() => {
form.setInitialValues(editModalData); form.setInitialValues(editModalData);
}); });
@ -32,7 +77,7 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
onOk(); onOk();
const formState = form.getFormState(); const formState = form.getFormState();
formState.values.role = parseInt(formState.values.role); formState.values.role = parseInt(formState.values.role);
await addUser(formState.values); await updateUser(formState.values);
}); });
}; };
@ -70,7 +115,7 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
title="角色" title="角色"
required required
x-decorator="FormItem" x-decorator="FormItem"
x-component="Input" x-component="Select"
x-component-props={{ x-component-props={{
placeholder: '请选择角色', placeholder: '请选择角色',
}} }}
@ -81,4 +126,4 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
); );
}; };
export default AddUserModal; export default EditAccountModal;

View File

@ -1,54 +1,224 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import routes from '@/routes'; import routes from '@/routes';
import DeleteButton from '@/components/Table/DeleteButton';
import { getPermission, upsertPermission } from '@/services/system/permission';
import AddPermissionModal from '../components/AddPermissionModal';
import EditPermissionModal from '../components/EditPermissionModal';
const PermissionsList = () => { const PermissionsList = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
const [permissionsData, setPermissionsData] = useState(Array);
const [isAddFirst, setIsAddFirst] = useState(false);
const [modalData, setModalData] = useState({});
const [rowData, setRowData] = useState({});
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const handleAdd = (row: any) => {
setRowData(row);
setIsModalVisible(true);
};
const handleEdit = (row: any) => {
setRowData(row);
setIsEditModalVisible(true);
};
const deleteLoopChildren = (rowData, children) => {
debugger;
for (let index = 0; index < children.length; index++) {
const childrenElement = children[index];
if (rowData.name == childrenElement.name) {
children.splice(index, 1);
return true;
} else {
if (Object.prototype.hasOwnProperty.call(childrenElement, 'children')) {
deleteLoopChildren(rowData, childrenElement.children);
} else {
continue;
}
}
}
};
const handleDelete = async (row: any) => {
for (let index = 0; index < permissionsData.length; index++) {
const element = permissionsData[index];
if (row.name == element.name) {
permissionsData.splice(index, 1);
break;
} else {
const result = deleteLoopChildren(row, element.children);
if (result) {
break;
}
}
}
await upsertPermission(permissionsData);
tableRef.current?.reload();
};
const addLoopChildren = (rowData, children) => {
for (let index = 0; index < children.length; index++) {
let childrenElement = children[index];
if (rowData.name == childrenElement.name) {
if (Object.prototype.hasOwnProperty.call(childrenElement, 'children')) {
childrenElement = rowData;
} else {
childrenElement.children = rowData;
}
return true;
} else {
if (Object.prototype.hasOwnProperty.call(childrenElement, 'children')) {
addLoopChildren(rowData, childrenElement.children);
} else {
continue;
}
}
}
};
const editLoopChildren = (val, rowData, children) => {
for (let index = 0; index < children.length; index++) {
const childrenElement = children[index];
if (rowData.name == childrenElement.name) {
childrenElement.name = val.name;
return true;
} else {
if (Object.prototype.hasOwnProperty.call(childrenElement, 'children')) {
editLoopChildren(val, rowData, childrenElement.children);
} else {
continue;
}
}
}
};
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '路由名称', title: '权限名',
dataIndex: 'name', dataIndex: 'name',
}, },
]; {
const rowSelection = { title: '操作',
onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => { valueType: 'option',
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows); width: 180,
render: (_, row) => [
<a
key="add"
onClick={() => {
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);
}}
/>
),
],
}, },
}; ];
return ( return (
<div> <div>
<Table <Table
columns={columns} columns={columns}
search={false} search={false}
// rowKey="key" rowKey="name"
// childrenColumnName="routes"
rowSelection={{
...rowSelection,
}}
// toolBarActions={[
// {
// type: 'add',
// onConfirm: () => {},
// },
// ]}
actionRef={tableRef} actionRef={tableRef}
toolBarActions={[
{
type: 'add',
onConfirm: () => {
setIsAddFirst(true);
setIsModalVisible(true);
},
},
]}
request={async (params) => { request={async (params) => {
const array = routes; const res = await getPermission({});
array.forEach((item: any, index) => { const data = JSON.parse(res.items);
if (item.name == '' || item.name == null || item.name == undefined) { setPermissionsData(data);
array.splice(index, 1); return { data: data };
} }}
item.key = index + 1; />
if (Object.prototype.hasOwnProperty.call(item, 'routes')) { <AddPermissionModal
item.routes?.forEach((item2: any, index2: number) => { visible={isModalVisible}
if (item2.name == '' || item2.name == null || item2.name == undefined) { onCancel={function () {
item.routes.splice(index2, 1); setIsModalVisible(false);
} }}
item2.key = parseInt(index + 1 + '' + index2); onOk={async function (val) {
if (isAddFirst) {
permissionsData.push(val);
} else {
if (Object.prototype.hasOwnProperty.call(rowData, 'children')) {
const result = rowData.children.find(function (value, index, arr) {
return value.name === val.name;
}); });
if (!result) {
rowData.children.push(val);
} else {
console.log('已有改权限名');
}
} else {
rowData.children = [val];
} }
}); for (let index = 0; index < permissionsData.length; index++) {
return { data: array }; const element = permissionsData[index];
if (rowData.name == element.name) {
permissionsData[index] = rowData;
break;
} else {
const result = addLoopChildren(rowData, element.children);
if (result) {
break;
}
}
}
}
await upsertPermission(permissionsData);
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditPermissionModal
visible={isEditModalVisible}
editModalData={modalData}
onCancel={function () {
setIsEditModalVisible(false);
}}
onOk={async function (val) {
for (let index = 0; index < permissionsData.length; index++) {
const element = permissionsData[index];
if (rowData.name == element.name) {
permissionsData[index].name = val.name;
break;
} else {
const result = editLoopChildren(val, rowData, element.children);
if (result) {
break;
}
}
}
await upsertPermission(permissionsData);
setIsEditModalVisible(false);
tableRef.current?.reload();
}} }}
/> />
</div> </div>

View File

@ -0,0 +1,51 @@
// 创建弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input } from '@formily/antd';
interface AddPermissionModalPropsType extends ModalProps {
onCancel: () => void;
onOk: (val: any) => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
},
});
const form = createForm({});
const AddPermissionModal = ({ onOk, onCancel, ...rest }: AddPermissionModalPropsType) => {
const handleOk = async () => {
form.submit(async () => {
const formState = form.getFormState();
onOk(formState.values);
});
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="添加权限" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="name"
title="权限名"
required
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddPermissionModal;

View File

@ -0,0 +1,61 @@
// 创建弹窗
import React, { useEffect, useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input } from '@formily/antd';
interface EditPermissionModalPropsType extends ModalProps {
editModalData: any;
onCancel: () => void;
onOk: (val: any) => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
},
});
const form = createForm({});
const EditPermissionModal = ({
onOk,
onCancel,
editModalData,
...rest
}: EditPermissionModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = async () => {
form.submit(async () => {
const formState = form.getFormState();
onOk(formState.values);
});
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="编辑权限" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="name"
title="权限名"
required
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default EditPermissionModal;

View File

@ -1,16 +1,32 @@
import React, { useRef } from 'react'; import React, { useRef, useState } from 'react';
import Table, { ProColumns, ActionType } from '@/components/Table'; import Table, { ProColumns, ActionType } from '@/components/Table';
import { getRoleList, deleteRole } from '@/services/system/role'; import { getRoleList, deleteRole, createRole, updateRole } from '@/services/system/role';
import { fetchTableData } from '@/utils/table'; import { fetchTableData } from '@/utils/table';
import DeleteButton from '@/components/Table/DeleteButton'; import DeleteButton from '@/components/Table/DeleteButton';
import AddRoleModal from '../components/AddRoleModal';
import EditRoleModal from '../components/EditRoleModal';
import AuthPermissionsDrawer from '../components/AuthPermissionsDrawer';
const RoleList = () => { const RoleList = () => {
const handleEdit = (row: any) => {};
const handleAuth = (row: any) => {};
const handleDelete = async (role: any) => {
await deleteRole({ role: role });
};
const tableRef = useRef<ActionType>(); const tableRef = useRef<ActionType>();
const [isDrawerVisible, setIsDrawerVisible] = useState(false);
const [isModalVisible, setIsModalVisible] = useState(false);
const [isEditModal, setIsEditModal] = useState(false);
const [modalData, setModalData] = useState({});
const handleEdit = (row: any) => {
setModalData(row);
setIsEditModal(true);
};
const handleAuth = (row: any) => {
setIsDrawerVisible(true);
};
const handleDelete = async (id: any) => {
await deleteRole({ id: id });
tableRef.current?.reload();
};
const columns: ProColumns<any>[] = [ const columns: ProColumns<any>[] = [
{ {
title: '角色名称', title: '角色名称',
@ -19,8 +35,8 @@ const RoleList = () => {
ellipsis: true, ellipsis: true,
}, },
{ {
title: '用户类型', title: '备注',
dataIndex: 'role', dataIndex: 'remark',
hideInSearch: true, hideInSearch: true,
ellipsis: true, ellipsis: true,
}, },
@ -48,21 +64,25 @@ const RoleList = () => {
<DeleteButton <DeleteButton
key="delete" key="delete"
onDelete={() => { onDelete={() => {
handleDelete(row.role); handleDelete(row.id);
}} }}
/>, />,
], ],
}, },
]; ];
return ( return (
<div> <div>
<Table <Table
columns={columns} columns={columns}
rowKey="id" rowKey="id"
search={false}
toolBarActions={[ toolBarActions={[
{ {
type: 'add', type: 'add',
onConfirm: () => {}, onConfirm: () => {
setIsModalVisible(true);
},
}, },
]} ]}
actionRef={tableRef} actionRef={tableRef}
@ -71,6 +91,38 @@ const RoleList = () => {
return res; return res;
}} }}
/> />
<AddRoleModal
visible={isModalVisible}
onCancel={function () {
setIsModalVisible(false);
}}
onOk={async function (val): Promise<void> {
await createRole(val);
setIsModalVisible(false);
tableRef.current?.reload();
}}
/>
<EditRoleModal
visible={isEditModal}
editModalData={modalData}
onCancel={function () {
setIsEditModal(false);
}}
onOk={async function (val): Promise<void> {
await updateRole(val);
setIsEditModal(false);
tableRef.current?.reload();
}}
/>
<AuthPermissionsDrawer
visible={isDrawerVisible}
onCancel={function () {
setIsDrawerVisible(false);
}}
onOk={function () {
console.log('onOk');
}}
/>
</div> </div>
); );
}; };

View File

@ -0,0 +1,58 @@
// 创建弹窗
import React, { useRef } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input } from '@formily/antd';
interface AddRoleModalPropsType extends ModalProps {
onCancel: () => void;
onOk: (val: any) => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
},
});
const form = createForm({});
const AddRoleModal = ({ onOk, onCancel, ...rest }: AddRoleModalPropsType) => {
const handleOk = async () => {
form.submit(async () => {
const formState = form.getFormState();
onOk(formState.values);
});
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="添加角色" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="role_name"
title="角色名"
required
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="remark"
title="备注"
required
x-decorator="FormItem"
x-component="Input"
/>
</SchemaField>
</Form>
</Modal>
);
};
export default AddRoleModal;

View File

@ -0,0 +1,116 @@
// 创建弹窗
import React, { useRef, useState } from 'react';
import { Form, FormItem, Input } from '@formily/antd';
import { Button, Drawer, DrawerProps, message, Space } from 'antd';
import { ActionType, ProColumns } from '@ant-design/pro-table';
import Table from '@/components/Table';
import { TableRowSelection } from 'antd/lib/table/interface';
import routes from '@/routes';
import { getPermission } from '@/services/system/permission';
interface AuthPermissionsDrawerPropsType extends DrawerProps {
onCancel: () => void;
onOk: (val: any) => void;
}
const columnsPermissions: ProColumns<any>[] = [
{
title: '路由名称',
dataIndex: 'name',
},
];
const valueMap = {};
function loops(list, parent) {
return (list || []).map(({ children, name }) => {
// console.log('children = ', children);
const node = (valueMap[name] = {
parent,
name,
});
node.children = loops(children, node);
return node;
});
}
function getPath(name) {
const path = [];
let current = valueMap[name];
while (current) {
path.unshift(current.name);
current = current.parent;
}
return path;
}
const AuthPermissionsDrawer = ({ onOk, onCancel, ...rest }: AuthPermissionsDrawerPropsType) => {
const tableRef = useRef<ActionType>();
const [selectedKeys, setSelectedKeys] = useState(['']);
const [postSelectedKeys, setPostSelectedKeys] = useState([]);
const rowSelection: TableRowSelection<DataType> = {
onChange: (selectedRowKeys, selectedRows) => {
setSelectedKeys(selectedRowKeys);
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
onSelect: (record, selected, selectedRows) => {
const path = getPath(record.name);
const newArray = selectedKeys.concat(path);
setPostSelectedKeys(newArray);
},
// onSelectAll: (selected, selectedRows, changeRows) => {
// console.log(selected, selectedRows, changeRows);
// },
};
const handleOk = () => {
if (postSelectedKeys.length == 0) {
message.warning('请选择权限。');
return;
}
onOk(postSelectedKeys);
};
const handleCancel = () => {
onCancel();
};
return (
<Drawer
onClose={handleCancel}
width={400}
{...rest}
extra={
<Space>
<Button onClick={handleCancel}>Cancel</Button>
<Button type="primary" onClick={handleOk}>
OK
</Button>
</Space>
}
>
<Table
columns={columnsPermissions}
rowKey="name"
search={false}
pagination={false}
rowSelection={{
...rowSelection,
hideSelectAll: true,
checkStrictly: false,
selectedRowKeys: selectedKeys,
}}
actionRef={tableRef}
request={async (params) => {
const res = await getPermission({});
const treeData = JSON.parse(res.items);
loops(treeData, null);
return { data: treeData };
}}
/>
</Drawer>
);
};
export default AuthPermissionsDrawer;

View File

@ -0,0 +1,71 @@
// 创建弹窗
import React, { useRef, useEffect } from 'react';
import { createForm } from '@formily/core';
import { createSchemaField } from '@formily/react';
import Modal, { ModalProps } from '@/components/Modal';
import { Form, FormItem, Input, Select } from '@formily/antd';
import { addUser, updateUser } from '@/services/system/accountManage';
interface EditRoleModalPropsType extends ModalProps {
editModalData: any;
onCancel: () => void;
onOk: (val: any) => void;
}
const SchemaField = createSchemaField({
components: {
FormItem,
Input,
Select,
},
});
const form = createForm({});
const EditRoleModal = ({ onOk, onCancel, editModalData, ...rest }: EditRoleModalPropsType) => {
useEffect(() => {
form.setInitialValues(editModalData);
});
const handleOk = async () => {
form.submit(async () => {
const formState = form.getFormState();
onOk(formState.values);
});
};
const handleCancel = () => {
onCancel();
};
return (
<Modal title="编辑角色" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
<Form form={form} labelCol={4} wrapperCol={18}>
<SchemaField>
<SchemaField.String
name="role_name"
title="角色名"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入账号名',
}}
/>
<SchemaField.String
name="remark"
title="备注"
required
x-decorator="FormItem"
x-component="Input"
x-component-props={{
placeholder: '请输入密码',
}}
/>
</SchemaField>
</Form>
</Modal>
);
};
export default EditRoleModal;

View File

@ -21,7 +21,7 @@
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/> />
<title>Pro</title> <title>TBG</title>
<link rel="icon" href="<%= context.config.publicPath +'logo.png'%>" type="image/png" /> <link rel="icon" href="<%= context.config.publicPath +'logo.png'%>" type="image/png" />
</head> </head>
<body> <body>

View File

@ -0,0 +1,27 @@
import request from '@/utils/request';
/**
*
* @param {object} params
* @returns {array} data
*/
export const getPermission = (params) => {
return request.request({
url: '/permission/get',
method: 'get',
params,
});
};
/**
*
* @param {object} params
* @returns {array} data
*/
export const upsertPermission = (data) => {
return request.request({
url: '/permission/upsert',
method: 'post',
data,
});
};

View File

@ -9,12 +9,42 @@ import request from '@/utils/request';
*/ */
export const getRoleList = (params) => { export const getRoleList = (params) => {
return request.request({ return request.request({
url: '/user/role/get', url: '/role/get',
method: 'get', method: 'get',
params, params,
}); });
}; };
/**
*
* @param {object} params
* role_name
* remark
* @returns {array} data
*/
export const createRole = (data) => {
return request.request({
url: '/role/create',
method: 'post',
data,
});
};
/**
*
* @param {object} params
* role_name
* remark
* @returns {array} data
*/
export const updateRole = (data) => {
return request.request({
url: '/role/update',
method: 'post',
data,
});
};
/** /**
* *
* @param {object} params * @param {object} params
@ -23,7 +53,7 @@ export const getRoleList = (params) => {
*/ */
export const deleteRole = (data) => { export const deleteRole = (data) => {
return request.request({ return request.request({
url: '/user/role/delete', url: '/role/delete',
method: 'post', method: 'post',
data, data,
}); });

View File

@ -70,14 +70,13 @@ export async function transfer(abi: string, address: string, toAddress: string)
const contract = new web3.eth.Contract(eval('(' + abi + ')'), address); const contract = new web3.eth.Contract(eval('(' + abi + ')'), address);
await contract.methods await contract.methods
.transfer(toAddress, new BigNumber(1 * Math.pow(10, 18))) .transfer(toAddress, new BigNumber(1 * Math.pow(10, 18)))
.send({ from: web3.eth.defaultAccount }), .send({ from: web3.eth.defaultAccount }, function (error, transactionHash) {
function (error, transactionHash) {
if (!error) { if (!error) {
console.log('transactionHash is ' + transactionHash); console.log('transactionHash is ' + transactionHash);
} else { } else {
console.log(error); console.log(error);
} }
}; });
} }
// NFT创建 // NFT创建
@ -92,17 +91,18 @@ export async function NFTMint(params: any) {
if (params.toAddress == '' || params.toAddress == null || params.toAddress == undefined) { if (params.toAddress == '' || params.toAddress == null || params.toAddress == undefined) {
params.toAddress = web3.eth.defaultAccount; params.toAddress = web3.eth.defaultAccount;
} }
let tx_hash = '';
const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address); const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
await contract.methods await contract.methods
.Mint(params.toAddress, params.token_id) .Mint(params.toAddress)
.send({ from: web3.eth.defaultAccount }), .send({ from: web3.eth.defaultAccount }, function (error, transactionHash) {
function (error, transactionHash) {
if (!error) { if (!error) {
return transactionHash; tx_hash = transactionHash;
} else { } else {
console.log(error); console.log(error);
} }
}; });
return tx_hash;
} }
// NFT转移 // NFT转移