新增代币,NFT等模块功能实现
This commit is contained in:
parent
9b71639ff9
commit
514d0db8f3
|
|
@ -11,7 +11,7 @@ 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.2.11:9999',
|
target: 'http://192.168.88.238:9999',
|
||||||
// 配置了这个可以从 http 代理到 https
|
// 配置了这个可以从 http 代理到 https
|
||||||
// 依赖 origin 的功能可能需要这个,比如 cookie
|
// 依赖 origin 的功能可能需要这个,比如 cookie
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@
|
||||||
"react-helmet-async": "^1.0.4",
|
"react-helmet-async": "^1.0.4",
|
||||||
"umi": "^3.5.0",
|
"umi": "^3.5.0",
|
||||||
"umi-serve": "^1.9.10",
|
"umi-serve": "^1.9.10",
|
||||||
"web3": "^1.7.5"
|
"web3": "^1.7.5",
|
||||||
|
"@metamask/detect-provider": "^1.2.0"
|
||||||
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/pro-cli": "^2.0.2",
|
"@ant-design/pro-cli": "^2.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,20 @@
|
||||||
/**
|
/**
|
||||||
* @see https://umijs.org/zh-CN/plugins/plugin-access
|
* @see https://umijs.org/zh-CN/plugins/plugin-access
|
||||||
* */
|
* */
|
||||||
export default function access(initialState: { currentUser?: API.CurrentUser | undefined }) {
|
|
||||||
const { currentUser } = initialState || {};
|
export default function access(initialState: {
|
||||||
|
currentUser?: API.CurrentUser | undefined;
|
||||||
|
routeList: any;
|
||||||
|
}) {
|
||||||
|
const { currentUser, routeList } = initialState || {};
|
||||||
return {
|
return {
|
||||||
canAdmin: currentUser && currentUser.access === 'admin',
|
canAdmin: currentUser && currentUser.access === 'admin',
|
||||||
|
normalRouteFilter: (route: any) => {
|
||||||
|
return true;
|
||||||
|
// if (routeList == null || routeList == undefined || routeList.length == 0) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return routeList.includes(route.name);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/app.tsx
11
src/app.tsx
|
|
@ -4,8 +4,19 @@ 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';
|
||||||
|
|
||||||
// ProLayout 支持的api https://procomponents.ant.design/components/layout
|
// ProLayout 支持的api https://procomponents.ant.design/components/layout
|
||||||
|
|
||||||
|
// export async function getInitialState() {
|
||||||
|
// if (localStorage.getItem(CACHE_TOKEN)) {
|
||||||
|
// const res = await getRoleList({});
|
||||||
|
// return {
|
||||||
|
// routeList: res,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
|
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
|
||||||
return {
|
return {
|
||||||
rightContentRender: () => <RightContent />,
|
rightContentRender: () => <RightContent />,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "uint256", "name": "initialSupply", "type": "uint256" },
|
||||||
|
{ "internalType": "uint8", "name": "initialDecimals", "type": "uint8" },
|
||||||
|
{ "internalType": "string", "name": "tokenName", "type": "string" },
|
||||||
|
{ "internalType": "string", "name": "tokenSymbol", "type": "string" }
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "constructor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{ "indexed": true, "internalType": "address", "name": "sender", "type": "address" },
|
||||||
|
{ "indexed": true, "internalType": "address", "name": "spender", "type": "address" },
|
||||||
|
{ "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "Approval",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{ "indexed": true, "internalType": "address", "name": "from", "type": "address" },
|
||||||
|
{ "indexed": true, "internalType": "address", "name": "to", "type": "address" },
|
||||||
|
{ "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "Transfer",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "owner", "type": "address" },
|
||||||
|
{ "internalType": "address", "name": "spender", "type": "address" }
|
||||||
|
],
|
||||||
|
"name": "allowance",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "", "type": "address" },
|
||||||
|
{ "internalType": "address", "name": "", "type": "address" }
|
||||||
|
],
|
||||||
|
"name": "allowed",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "spender", "type": "address" },
|
||||||
|
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [{ "internalType": "address", "name": "account", "type": "address" }],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
|
||||||
|
"name": "balances",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "decimals",
|
||||||
|
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "name",
|
||||||
|
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "uint256", "name": "a", "type": "uint256" },
|
||||||
|
{ "internalType": "uint256", "name": "b", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "safeAdd",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "c", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "uint256", "name": "a", "type": "uint256" },
|
||||||
|
{ "internalType": "uint256", "name": "b", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "safeDiv",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "c", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "uint256", "name": "a", "type": "uint256" },
|
||||||
|
{ "internalType": "uint256", "name": "b", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "safeMul",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "c", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "uint256", "name": "a", "type": "uint256" },
|
||||||
|
{ "internalType": "uint256", "name": "b", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "safeSub",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "c", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "symbol",
|
||||||
|
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [],
|
||||||
|
"name": "totalSupply",
|
||||||
|
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "to", "type": "address" },
|
||||||
|
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "transfer",
|
||||||
|
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{ "internalType": "address", "name": "from", "type": "address" },
|
||||||
|
{ "internalType": "address", "name": "to", "type": "address" },
|
||||||
|
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
export enum ContractType {
|
||||||
|
ERC20 = '20',
|
||||||
|
NFT721 = '721',
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
export enum NoticeType {
|
||||||
|
RECHARGE = 10000,
|
||||||
|
WITHDRAW = 20000,
|
||||||
|
NFTCREATE = 30000,
|
||||||
|
NFTTRANSFER = 30010,
|
||||||
|
NFTTDISPOSE = 30020,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export enum WithdrawType {
|
||||||
|
SUCCESS = 10000,
|
||||||
|
FAILED = 20000,
|
||||||
|
PENDDING = 30000,
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,11 @@ 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 } from '@/constants/cacheKey';
|
||||||
|
import access from '@/access';
|
||||||
|
|
||||||
const Login: React.FC = () => {
|
const Login: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
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 });
|
||||||
|
|
@ -19,6 +20,8 @@ const Login: React.FC = () => {
|
||||||
const { query } = history.location;
|
const { query } = history.location;
|
||||||
const { redirect } = query as { redirect: string };
|
const { redirect } = query as { redirect: string };
|
||||||
history.push(redirect || '/');
|
history.push(redirect || '/');
|
||||||
|
refresh();
|
||||||
|
access(initialState);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ const form = createForm({});
|
||||||
|
|
||||||
const AddNftContractModal = ({ onOk, onCancel, ...rest }: AddNftContractModalPropsType) => {
|
const AddNftContractModal = ({ onOk, onCancel, ...rest }: AddNftContractModalPropsType) => {
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
onCancel();
|
onCancel();
|
||||||
|
|
@ -34,25 +36,25 @@ const AddNftContractModal = ({ onOk, onCancel, ...rest }: AddNftContractModalPro
|
||||||
<Form form={form} labelCol={4} wrapperCol={18}>
|
<Form form={form} labelCol={4} wrapperCol={18}>
|
||||||
<SchemaField>
|
<SchemaField>
|
||||||
<SchemaField.String
|
<SchemaField.String
|
||||||
name="contract_name"
|
name="token_name"
|
||||||
title="名称"
|
title="合约名称"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.Number
|
<SchemaField.String
|
||||||
name="contract_address"
|
name="token_symbol"
|
||||||
title="合约"
|
title="合约单位"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="NumberPicker"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.Number
|
<SchemaField.String
|
||||||
name="description"
|
name="description"
|
||||||
title=""
|
title="描述"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="NumberPicker"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
</SchemaField>
|
</SchemaField>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,42 @@
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import Table, { ProColumns, ActionType } from '@/components/Table';
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
// import { fetchTableData } from '@/utils/table';
|
|
||||||
import AddNftContractModal from './components/AddNftContract';
|
import AddNftContractModal from './components/AddNftContract';
|
||||||
|
import { getContractInfo } from '@/services/contract';
|
||||||
|
import { ContractType } from '@/constants/enum/contract';
|
||||||
|
import { deployContract, initWeb3 } from '@/utils/web3';
|
||||||
|
import { createNFTContract, getNFTContractList } from '@/services/nft';
|
||||||
|
import { fetchTableData } from '@/utils/table';
|
||||||
|
|
||||||
const Address: React.FC = () => {
|
const Address: React.FC = () => {
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
const [NftModal, setNftModal] = useState(false);
|
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
|
const [contractData, setContractData] = useState({});
|
||||||
|
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
title: '合约名称',
|
title: '合约名称',
|
||||||
dataIndex: 'time',
|
dataIndex: 'token_name',
|
||||||
width: '10%',
|
width: '15%',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '合约单位',
|
||||||
|
dataIndex: 'token_symbol',
|
||||||
|
width: '15%',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '合约地址',
|
title: '合约地址',
|
||||||
dataIndex: 'address',
|
dataIndex: 'address',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: '20%',
|
width: '50%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'NFT数量',
|
title: '描述',
|
||||||
dataIndex: 'nft_num',
|
dataIndex: 'description',
|
||||||
width: 150,
|
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -35,30 +45,44 @@ const Address: React.FC = () => {
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
search={false}
|
||||||
actionRef={tableRef}
|
actionRef={tableRef}
|
||||||
toolBarActions={[
|
toolBarActions={[
|
||||||
{
|
{
|
||||||
type: 'add',
|
type: 'add',
|
||||||
text: '新建NFT合约',
|
text: '新建NFT合约',
|
||||||
onConfirm: () => {
|
onConfirm: async () => {
|
||||||
setVisible(true);
|
const res = await getContractInfo({ erc: ContractType.NFT721 });
|
||||||
|
if (res.bin != '') {
|
||||||
|
setContractData(res);
|
||||||
|
setVisible(true);
|
||||||
|
} else {
|
||||||
|
message.success('已有NFT合约');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
// request={async (params) => {
|
request={async (params) => {
|
||||||
// // return fetchTableData(, params);
|
const res = await fetchTableData(getNFTContractList, params);
|
||||||
// }}
|
return res;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<AddNftContractModal
|
<AddNftContractModal
|
||||||
visible={NftModal}
|
visible={visible}
|
||||||
onCancel={function () {
|
onCancel={function () {
|
||||||
setNftModal(false);
|
setVisible(false);
|
||||||
}}
|
}}
|
||||||
onOk={async function (val: any): Promise<void> {
|
onOk={async function (val: any): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const params = { ...val };
|
await initWeb3();
|
||||||
// await creatNftAddress(params);
|
const res = await deployContract(contractData.abi, contractData.bin, [
|
||||||
|
val.token_name,
|
||||||
|
val.token_symbol,
|
||||||
|
]);
|
||||||
|
val.address = res;
|
||||||
|
await createNFTContract(val);
|
||||||
message.success('添加成功');
|
message.success('添加成功');
|
||||||
|
setVisible(false);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
message.success('发生错误');
|
message.success('发生错误');
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@ const form = createForm({});
|
||||||
|
|
||||||
const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
|
const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(() => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
onCancel();
|
onCancel();
|
||||||
|
|
@ -33,33 +35,45 @@ const AddNftModal = ({ onOk, onCancel, ...rest }: AddNftModalPropsType) => {
|
||||||
<Modal title="添加NFT" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
|
<Modal title="添加NFT" onOk={handleOk} onCancel={handleCancel} width={800} {...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="nft_name"
|
name="toAddress"
|
||||||
|
title="所有者地址"
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.String
|
||||||
|
name="name"
|
||||||
title="名称"
|
title="名称"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.Number
|
<SchemaField.String
|
||||||
name="contract"
|
name="image"
|
||||||
title="合约"
|
title="图片"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="NumberPicker"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.Number
|
<SchemaField.String
|
||||||
|
name="avatar"
|
||||||
|
title="缩略图"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.String
|
||||||
name="description"
|
name="description"
|
||||||
title="描述"
|
title="描述"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="NumberPicker"
|
x-component="Input"
|
||||||
/>
|
|
||||||
<SchemaField.Number
|
|
||||||
name="img"
|
|
||||||
title="图片"
|
|
||||||
required
|
|
||||||
x-decorator="FormItem"
|
|
||||||
x-component="NumberPicker"
|
|
||||||
/>
|
/>
|
||||||
</SchemaField>
|
</SchemaField>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -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 { fetchTableData } from '@/utils/table';
|
||||||
|
import { Form, FormItem, Input, NumberPicker } from '@formily/antd';
|
||||||
|
|
||||||
|
interface TransferNFTModelPropsType extends ModalProps {
|
||||||
|
onOk: (val: any) => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SchemaField = createSchemaField({
|
||||||
|
components: {
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
NumberPicker,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = createForm({});
|
||||||
|
|
||||||
|
const TransferNFTModel = ({ onOk, onCancel, ...rest }: TransferNFTModelPropsType) => {
|
||||||
|
const handleOk = async () => {
|
||||||
|
form.submit(async () => {
|
||||||
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
onCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal title="转账NFT" onOk={handleOk} onCancel={handleCancel} width={800} {...rest}>
|
||||||
|
<Form form={form} labelCol={4} wrapperCol={18}>
|
||||||
|
<SchemaField>
|
||||||
|
<SchemaField.String
|
||||||
|
name="token_id"
|
||||||
|
title="ID"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.String
|
||||||
|
name="toAddress"
|
||||||
|
title="发送地址"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
</SchemaField>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TransferNFTModel;
|
||||||
|
|
@ -1,34 +1,49 @@
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import Table, { ProColumns, ActionType } from '@/components/Table';
|
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 PaySelectModal from '@/widget/PaySelectModal';
|
import { initWeb3, NFTMint } from '@/utils/web3';
|
||||||
|
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 [NftModal, setNftModal] = useState(false);
|
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [payVisible, setPayVisible] = useState(false);
|
|
||||||
|
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
title: '合约名称',
|
title: 'TokenId',
|
||||||
dataIndex: 'time',
|
dataIndex: 'token_id',
|
||||||
width: '10%',
|
width: '10%',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'NFT名称',
|
title: '所有者地址',
|
||||||
dataIndex: 'address',
|
dataIndex: 'address',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
width: '20%',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'TokenId',
|
title: 'NFT名称',
|
||||||
dataIndex: 'token_id',
|
dataIndex: 'name',
|
||||||
width: 150,
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '图片',
|
||||||
|
dataIndex: 'image',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '缩略图',
|
||||||
|
dataIndex: 'avatar',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'description',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -38,6 +53,7 @@ const Address: React.FC = () => {
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
search={false}
|
||||||
actionRef={tableRef}
|
actionRef={tableRef}
|
||||||
toolBarActions={[
|
toolBarActions={[
|
||||||
{
|
{
|
||||||
|
|
@ -47,17 +63,11 @@ const Address: React.FC = () => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: 'add',
|
|
||||||
text: '分发NFT',
|
|
||||||
onConfirm: () => {
|
|
||||||
setNftModal(true);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]}
|
]}
|
||||||
// request={async (params) => {
|
request={async (params) => {
|
||||||
// // return fetchTableData(, params);
|
const res = await fetchTableData(getNFTList, params);
|
||||||
// }}
|
return res;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<AddNftModal
|
<AddNftModal
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
|
@ -65,34 +75,21 @@ const Address: React.FC = () => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}}
|
}}
|
||||||
onOk={async function (val: any): Promise<void> {
|
onOk={async function (val: any): Promise<void> {
|
||||||
try {
|
await checkTokenId({ token_id: val.token_id });
|
||||||
const params = { ...val };
|
await initWeb3();
|
||||||
// await creatNftAddress(params);
|
const contractInfo = await getContractInfo({ erc: ContractType.NFT721 });
|
||||||
message.success('添加成功');
|
const res = await getNFTContractList();
|
||||||
} catch (e) {
|
await NFTMint({
|
||||||
console.log(e);
|
abi: contractInfo.abi,
|
||||||
message.success('发生错误');
|
address: res.items[0].address,
|
||||||
setVisible(false);
|
toAddress: val.toAddress,
|
||||||
}
|
name: val.name,
|
||||||
}}
|
token_id: val.token_id,
|
||||||
/>
|
});
|
||||||
<PaySelectModal
|
await mintNFT(val);
|
||||||
visible={payVisible}
|
tableRef.current?.reload();
|
||||||
onCancel={function () {
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}}
|
}}
|
||||||
onOk={async function (val: any): Promise<void> {
|
|
||||||
try {
|
|
||||||
const params = { ...val };
|
|
||||||
// await creatNftAddress(params);
|
|
||||||
console.log(params);
|
|
||||||
message.success('添加成功');
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
message.success('发生错误');
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
import React, { useRef } from 'react';
|
||||||
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
|
import { getRecordList } from '@/services/recharge/record';
|
||||||
|
import { fetchTableData } from '@/utils/table';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { ContractType } from '@/constants/enum/contract';
|
||||||
|
|
||||||
|
const NFTTradeList = () => {
|
||||||
|
const tableRef = useRef<ActionType>();
|
||||||
|
const columns: ProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'time',
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'dateRange',
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '交易哈希',
|
||||||
|
dataIndex: 'tx_hash',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'TokenID',
|
||||||
|
dataIndex: 'token_id',
|
||||||
|
width: '10%',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '块编号',
|
||||||
|
dataIndex: 'block_number',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发送地址',
|
||||||
|
dataIndex: 'from_address',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '接受地址',
|
||||||
|
dataIndex: 'to_address',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '充值时间',
|
||||||
|
dataIndex: 'time',
|
||||||
|
hideInSearch: true,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={tableRef}
|
||||||
|
request={async (params) => {
|
||||||
|
console.log('params = ', params);
|
||||||
|
if ((params.time ?? '') !== '') {
|
||||||
|
const start = Date.parse(params.time[0] + ' 00:00:00');
|
||||||
|
const end = Date.parse(params.time[1] + ' 23:59:59');
|
||||||
|
params.start_time = start / 1000;
|
||||||
|
params.end_time = end / 1000;
|
||||||
|
}
|
||||||
|
params.erc = ContractType.NFT721;
|
||||||
|
const res = await fetchTableData(getRecordList, params);
|
||||||
|
for (const key in res.data) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
|
||||||
|
const element = res.data[key];
|
||||||
|
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NFTTradeList;
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
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 { addCoinType, getCoinTypeList, modifyCoinType } from '@/services/recharge/coinType';
|
import { addCoinType, getCoinTypeList, modifyCoinType } from '@/services/recharge/coinType';
|
||||||
|
import { getContractInfo } from '@/services/contract';
|
||||||
import { fetchTableData } from '@/utils/table';
|
import { fetchTableData } from '@/utils/table';
|
||||||
import AddCoinTypeModal from '../components/AddCoinTypeModal';
|
import AddCoinTypeModal from '../components/AddCoinTypeModal';
|
||||||
import EditCoinTypeModal from '../components/EditCoinTypeModal';
|
import EditCoinTypeModal from '../components/EditCoinTypeModal';
|
||||||
|
import { initWeb3, deployContract, transfer } from '@/utils/web3';
|
||||||
|
import { ContractType } from '@/constants/enum/contract';
|
||||||
|
|
||||||
const CoinTypeList = () => {
|
const CoinTypeList = () => {
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
|
|
@ -39,7 +42,7 @@ const CoinTypeList = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '代币发行总量',
|
title: '代币发行总量',
|
||||||
dataIndex: 'num',
|
dataIndex: 'total',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
|
|
@ -64,6 +67,7 @@ const CoinTypeList = () => {
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
search={false}
|
||||||
toolBarActions={[
|
toolBarActions={[
|
||||||
{
|
{
|
||||||
type: 'add',
|
type: 'add',
|
||||||
|
|
@ -84,6 +88,14 @@ const CoinTypeList = () => {
|
||||||
setIsModalVisible(false);
|
setIsModalVisible(false);
|
||||||
}}
|
}}
|
||||||
onOk={async function (val: any): Promise<void> {
|
onOk={async function (val: any): Promise<void> {
|
||||||
|
const res = await getContractInfo({ erc: ContractType.ERC20 });
|
||||||
|
await initWeb3();
|
||||||
|
const result = await deployContract(res.abi, res.bin, [
|
||||||
|
val.num,
|
||||||
|
val.tokenName,
|
||||||
|
val.tokenSymbol,
|
||||||
|
]);
|
||||||
|
val.address = result;
|
||||||
await addCoinType(val);
|
await addCoinType(val);
|
||||||
setIsModalVisible(false);
|
setIsModalVisible(false);
|
||||||
tableRef.current?.reload();
|
tableRef.current?.reload();
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,11 @@ const SchemaField = createSchemaField({
|
||||||
const form = createForm({});
|
const form = createForm({});
|
||||||
|
|
||||||
const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType) => {
|
const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType) => {
|
||||||
const handleOk = () => {
|
const handleOk = async () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
@ -36,21 +38,35 @@ const AddCoinTypeModal = ({ onOk, onCancel, ...rest }: AddCoinTypeModalPropsType
|
||||||
<SchemaField>
|
<SchemaField>
|
||||||
<SchemaField.String
|
<SchemaField.String
|
||||||
name="name"
|
name="name"
|
||||||
|
title="货币名称"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="Input"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="usdt_price"
|
||||||
|
title="usdt比例"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
<SchemaField.Number
|
||||||
|
name="eth_price"
|
||||||
|
title="eth比例"
|
||||||
|
required
|
||||||
|
x-decorator="FormItem"
|
||||||
|
x-component="NumberPicker"
|
||||||
|
/>
|
||||||
|
<SchemaField.String
|
||||||
|
name="tokenName"
|
||||||
title="代币名称"
|
title="代币名称"
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.String
|
<SchemaField.String
|
||||||
name="usdt_price"
|
name="tokenSymbol"
|
||||||
title="usdt比例"
|
title="代币单位"
|
||||||
required
|
|
||||||
x-decorator="FormItem"
|
|
||||||
x-component="Input"
|
|
||||||
/>
|
|
||||||
<SchemaField.String
|
|
||||||
name="eth_price"
|
|
||||||
title="eth比例"
|
|
||||||
required
|
required
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Input"
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,10 @@ const EditCoinTypeModal = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
@ -51,17 +53,17 @@ const EditCoinTypeModal = ({
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Input"
|
||||||
/>
|
/>
|
||||||
<SchemaField.String
|
<SchemaField.Number
|
||||||
name="usdt_price"
|
name="usdt_price"
|
||||||
title="usdt比例"
|
title="usdt比例"
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="NumberPicker"
|
||||||
/>
|
/>
|
||||||
<SchemaField.String
|
<SchemaField.Number
|
||||||
name="eth_price"
|
name="eth_price"
|
||||||
title="eth比例"
|
title="eth比例"
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="NumberPicker"
|
||||||
/>
|
/>
|
||||||
</SchemaField>
|
</SchemaField>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ import React, { useRef } from 'react';
|
||||||
import Table, { ProColumns, ActionType } from '@/components/Table';
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
import { getRecordList } from '@/services/recharge/record';
|
import { getRecordList } from '@/services/recharge/record';
|
||||||
import { fetchTableData } from '@/utils/table';
|
import { fetchTableData } from '@/utils/table';
|
||||||
import { getBalanceAmount } from '@/utils/formatBalance';
|
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { ContractType } from '@/constants/enum/contract';
|
||||||
|
|
||||||
const RecordList = () => {
|
const RecordList = () => {
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
|
|
@ -28,12 +27,6 @@ const RecordList = () => {
|
||||||
width: '10%',
|
width: '10%',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '位数',
|
|
||||||
dataIndex: 'decimals',
|
|
||||||
width: '10%',
|
|
||||||
hideInSearch: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '游戏币类型',
|
title: '游戏币类型',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
|
@ -62,25 +55,20 @@ const RecordList = () => {
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="tx_hash"
|
||||||
actionRef={tableRef}
|
actionRef={tableRef}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
console.log('params = ', params);
|
|
||||||
if ((params.time ?? '') !== '') {
|
if ((params.time ?? '') !== '') {
|
||||||
const start = Date.parse(params.time[0] + ' 00:00:00');
|
const start = Date.parse(params.time[0] + ' 00:00:00');
|
||||||
const end = Date.parse(params.time[1] + ' 23:59:59');
|
const end = Date.parse(params.time[1] + ' 23:59:59');
|
||||||
params.start_time = start / 1000;
|
params.start_time = start / 1000;
|
||||||
params.end_time = end / 1000;
|
params.end_time = end / 1000;
|
||||||
}
|
}
|
||||||
|
params.erc = ContractType.ERC20;
|
||||||
const res = await fetchTableData(getRecordList, params);
|
const res = await fetchTableData(getRecordList, params);
|
||||||
console.log('res = ', res);
|
|
||||||
for (const key in res.data) {
|
for (const key in res.data) {
|
||||||
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
|
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
|
||||||
const element = res.data[key];
|
const element = res.data[key];
|
||||||
element.price = getBalanceAmount(
|
|
||||||
new BigNumber(element.price),
|
|
||||||
element.decimals,
|
|
||||||
).toNumber();
|
|
||||||
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
|
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ const CollectionAddressList = () => {
|
||||||
title: '收款游戏币名称',
|
title: '收款游戏币名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
ellipsis: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ const form = createForm({
|
||||||
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, page_size: 10 });
|
const list = await getCoinTypeList({ page: 1, size: 10 });
|
||||||
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];
|
||||||
|
|
@ -54,8 +54,10 @@ const form = createForm({
|
||||||
|
|
||||||
const AddWalletModal = ({ onOk, onCancel, ...rest }: AddWalletModalPropsType) => {
|
const AddWalletModal = ({ onOk, onCancel, ...rest }: AddWalletModalPropsType) => {
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ 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, page_size: 10 });
|
const list = await getCoinTypeList({ page: 1, size: 10 });
|
||||||
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];
|
||||||
|
|
@ -59,8 +59,10 @@ const EditWalletModal = ({ onOk, onCancel, editModalData, ...rest }: EditWalletM
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,33 @@ import React, { useRef } from 'react';
|
||||||
import Table, { ProColumns, ActionType } from '@/components/Table';
|
import Table, { ProColumns, ActionType } from '@/components/Table';
|
||||||
import { getWithdrawList, solveWithdraw } from '@/services/recharge/withdraw';
|
import { getWithdrawList, solveWithdraw } from '@/services/recharge/withdraw';
|
||||||
import { fetchTableData } from '@/utils/table';
|
import { fetchTableData } from '@/utils/table';
|
||||||
import { getBalanceAmount } from '@/utils/formatBalance';
|
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
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';
|
||||||
|
|
||||||
const WithdrawList = () => {
|
const WithdrawList = () => {
|
||||||
const handleConfirm = async (uuid) => {
|
const handleConfirm = async (uuid) => {
|
||||||
await solveWithdraw({ uuid: uuid });
|
await solveWithdraw({ uuid: uuid });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WithdrawTypeList = [
|
||||||
|
{
|
||||||
|
label: '成功',
|
||||||
|
value: WithdrawType.SUCCESS,
|
||||||
|
status: 'Success',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '失败',
|
||||||
|
value: WithdrawType.FAILED,
|
||||||
|
status: 'Error',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '待处理',
|
||||||
|
value: WithdrawType.PENDDING,
|
||||||
|
status: 'Warning',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -36,6 +53,18 @@ const WithdrawList = () => {
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
width: '10%',
|
width: '10%',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
width: '10%',
|
||||||
|
valueEnum: () => {
|
||||||
|
const options = {};
|
||||||
|
WithdrawTypeList.forEach((item) => {
|
||||||
|
options[item.value] = { text: item.label, status: item.status };
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '时间',
|
title: '时间',
|
||||||
dataIndex: 'time',
|
dataIndex: 'time',
|
||||||
|
|
@ -69,10 +98,6 @@ const WithdrawList = () => {
|
||||||
for (const key in res.data) {
|
for (const key in res.data) {
|
||||||
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
|
if (Object.prototype.hasOwnProperty.call(res.data, key)) {
|
||||||
const element = res.data[key];
|
const element = res.data[key];
|
||||||
element.price = getBalanceAmount(
|
|
||||||
new BigNumber(element.price),
|
|
||||||
element.decimals,
|
|
||||||
).toNumber();
|
|
||||||
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
|
element.time = moment(element.time * 1000).format('YYYY-MM-DD hh:mm:ss');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,8 @@ const AccountManageList = () => {
|
||||||
<div>
|
<div>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="name"
|
||||||
|
search={false}
|
||||||
toolBarActions={[
|
toolBarActions={[
|
||||||
{
|
{
|
||||||
type: 'add',
|
type: 'add',
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
// 创建弹窗
|
// 创建弹窗
|
||||||
import React, { useRef } from 'react';
|
import React, { useEffect, 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 { Form, FormItem, Input, Select } from '@formily/antd';
|
import { Form, FormItem, Input, TreeSelect } from '@formily/antd';
|
||||||
import { addUser } from '@/services/system/accountManage';
|
import { addUser } from '@/services/system/accountManage';
|
||||||
|
import routes from '@/routes';
|
||||||
|
|
||||||
interface AddAccountModalPropsType extends ModalProps {
|
interface AddAccountModalPropsType extends ModalProps {
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
|
@ -15,13 +16,15 @@ const SchemaField = createSchemaField({
|
||||||
components: {
|
components: {
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
TreeSelect,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = createForm({});
|
const form = createForm({});
|
||||||
|
|
||||||
const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => {
|
const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType) => {
|
||||||
|
const [treeData, setTreeData] = useState({});
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
form.submit(async () => {
|
form.submit(async () => {
|
||||||
onOk();
|
onOk();
|
||||||
|
|
@ -35,6 +38,30 @@ 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}>
|
||||||
|
|
@ -64,15 +91,19 @@ const AddAccountModal = ({ onOk, onCancel, ...rest }: AddAccountModalPropsType)
|
||||||
/>
|
/>
|
||||||
<SchemaField.String
|
<SchemaField.String
|
||||||
name="role"
|
name="role"
|
||||||
title="角色"
|
title="权限"
|
||||||
required
|
required
|
||||||
x-validator={{
|
x-validator={{
|
||||||
required: true,
|
required: true,
|
||||||
}}
|
}}
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="TreeSelect"
|
||||||
x-component-props={{
|
x-component-props={{
|
||||||
placeholder: '请选择角色',
|
fieldNames: { label: 'name', children: 'routes', value: 'name' },
|
||||||
|
onChange: onChange,
|
||||||
|
treeCheckable: true,
|
||||||
|
treeData: treeData,
|
||||||
|
placeholder: '请选择权限',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SchemaField>
|
</SchemaField>
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,12 @@ const AddUserModal = ({ onOk, onCancel, editModalData, ...rest }: AddUserModalPr
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
onOk();
|
form.submit(async () => {
|
||||||
const formState = form.getFormState();
|
onOk();
|
||||||
formState.values.role = parseInt(formState.values.role);
|
const formState = form.getFormState();
|
||||||
await updateUser(formState.values);
|
formState.values.role = parseInt(formState.values.role);
|
||||||
|
await addUser(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import DeleteButton from '@/components/Table/DeleteButton';
|
||||||
import { Switch } from 'antd';
|
import { 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';
|
||||||
|
|
||||||
const NoticeList = () => {
|
const NoticeList = () => {
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
|
|
@ -25,12 +26,40 @@ const NoticeList = () => {
|
||||||
tableRef.current?.reload();
|
tableRef.current?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const noticeTypeList = [
|
||||||
|
{
|
||||||
|
label: '充值',
|
||||||
|
value: NoticeType.RECHARGE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '提现',
|
||||||
|
value: NoticeType.WITHDRAW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT创建',
|
||||||
|
value: NoticeType.NFTCREATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT转移',
|
||||||
|
value: NoticeType.NFTTRANSFER,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT销毁',
|
||||||
|
value: NoticeType.NFTTDISPOSE,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
title: '通知码',
|
title: '通知码',
|
||||||
dataIndex: 'code',
|
dataIndex: 'code',
|
||||||
hideInSearch: true,
|
valueEnum: () => {
|
||||||
ellipsis: true,
|
const options = {};
|
||||||
|
noticeTypeList.forEach((item) => {
|
||||||
|
options[item.value] = item.label;
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '通知地址',
|
title: '通知地址',
|
||||||
|
|
@ -74,6 +103,7 @@ const NoticeList = () => {
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
|
search={false}
|
||||||
toolBarActions={[
|
toolBarActions={[
|
||||||
{
|
{
|
||||||
type: 'add',
|
type: 'add',
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,31 @@ 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 { NoticeType } from '@/constants/enum/notice';
|
||||||
|
|
||||||
|
const noticeTypeList = [
|
||||||
|
{
|
||||||
|
label: '充值',
|
||||||
|
value: NoticeType.RECHARGE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '提现',
|
||||||
|
value: NoticeType.WITHDRAW,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT创建',
|
||||||
|
value: NoticeType.NFTCREATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT转移',
|
||||||
|
value: NoticeType.NFTTRANSFER,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NFT销毁',
|
||||||
|
value: NoticeType.NFTTDISPOSE,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
interface AddNoticeModalPropsType extends ModalProps {
|
interface AddNoticeModalPropsType extends ModalProps {
|
||||||
onOk: (val: any) => void;
|
onOk: (val: any) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
|
@ -22,9 +47,11 @@ const form = createForm({});
|
||||||
|
|
||||||
const AddNoticeModal = ({ onOk, onCancel, ...rest }: AddNoticeModalPropsType) => {
|
const AddNoticeModal = ({ onOk, onCancel, ...rest }: AddNoticeModalPropsType) => {
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
formState.values.code = parseInt(formState.values.code);
|
const formState = form.getFormState();
|
||||||
onOk(formState.values);
|
formState.values.code = parseInt(formState.values.code);
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
@ -35,12 +62,15 @@ const AddNoticeModal = ({ onOk, onCancel, ...rest }: AddNoticeModalPropsType) =>
|
||||||
<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}>
|
||||||
<SchemaField>
|
<SchemaField>
|
||||||
<SchemaField.String
|
<SchemaField.Number
|
||||||
name="code"
|
name="code"
|
||||||
title="通知码"
|
title="通知码"
|
||||||
required
|
required
|
||||||
|
x-component-props={{
|
||||||
|
options: noticeTypeList,
|
||||||
|
}}
|
||||||
x-decorator="FormItem"
|
x-decorator="FormItem"
|
||||||
x-component="Input"
|
x-component="Select"
|
||||||
/>
|
/>
|
||||||
<SchemaField.String
|
<SchemaField.String
|
||||||
name="addr"
|
name="addr"
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,10 @@ const EditNoticeModal = ({ onOk, onCancel, editModalData, ...rest }: EditNoticeM
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
const formState = form.getFormState();
|
form.submit(async () => {
|
||||||
onOk(formState.values);
|
const formState = form.getFormState();
|
||||||
|
onOk(formState.values);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,54 @@
|
||||||
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 { fetchTableData } from '@/utils/table';
|
import routes from '@/routes';
|
||||||
import DeleteButton from '@/components/Table/DeleteButton';
|
|
||||||
|
|
||||||
const PermissionsList = () => {
|
const PermissionsList = () => {
|
||||||
const handleEdit = (row: any) => {};
|
|
||||||
|
|
||||||
const handleDelete = async (name: any) => {};
|
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
title: '收款地址',
|
title: '路由名称',
|
||||||
dataIndex: 'address',
|
dataIndex: 'name',
|
||||||
hideInSearch: true,
|
|
||||||
ellipsis: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '收款游戏币类型',
|
|
||||||
dataIndex: 'type',
|
|
||||||
hideInSearch: true,
|
|
||||||
ellipsis: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
valueType: 'option',
|
|
||||||
width: 150,
|
|
||||||
render: (_, row) => [
|
|
||||||
<a
|
|
||||||
key="edit"
|
|
||||||
onClick={() => {
|
|
||||||
handleEdit(row);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</a>,
|
|
||||||
<DeleteButton
|
|
||||||
key="delete"
|
|
||||||
onDelete={() => {
|
|
||||||
handleDelete(row.name);
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const rowSelection = {
|
||||||
|
onChange: (selectedRowKeys: React.Key[], selectedRows: DataType[]) => {
|
||||||
|
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||||
|
},
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
search={false}
|
||||||
toolBarActions={[
|
// rowKey="key"
|
||||||
{
|
// childrenColumnName="routes"
|
||||||
type: 'add',
|
rowSelection={{
|
||||||
onConfirm: () => {},
|
...rowSelection,
|
||||||
},
|
}}
|
||||||
]}
|
// toolBarActions={[
|
||||||
|
// {
|
||||||
|
// type: 'add',
|
||||||
|
// onConfirm: () => {},
|
||||||
|
// },
|
||||||
|
// ]}
|
||||||
actionRef={tableRef}
|
actionRef={tableRef}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
return {};
|
const array = routes;
|
||||||
|
array.forEach((item: any, index) => {
|
||||||
|
if (item.name == '' || item.name == null || item.name == undefined) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
item2.key = parseInt(index + 1 + '' + index2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return { data: array };
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const UserManageList = () => {
|
||||||
const tableRef = useRef<ActionType>();
|
const tableRef = useRef<ActionType>();
|
||||||
const columns: ProColumns<any>[] = [
|
const columns: ProColumns<any>[] = [
|
||||||
{
|
{
|
||||||
title: '用户钱包地址',
|
title: '钱包地址',
|
||||||
dataIndex: 'address',
|
dataIndex: 'address',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
},
|
},
|
||||||
|
|
@ -22,12 +22,6 @@ const UserManageList = () => {
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
toolBarActions={[
|
|
||||||
{
|
|
||||||
type: 'add',
|
|
||||||
onConfirm: () => {},
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
actionRef={tableRef}
|
actionRef={tableRef}
|
||||||
request={async (params) => {
|
request={async (params) => {
|
||||||
const res = await fetchTableData(getUserList, params);
|
const res = await fetchTableData(getUserList, params);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export default [
|
||||||
{
|
{
|
||||||
name: '充值系统',
|
name: '充值系统',
|
||||||
path: RoutePath.RECHARGE,
|
path: RoutePath.RECHARGE,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: RoutePath.RECHARGE,
|
path: RoutePath.RECHARGE,
|
||||||
|
|
@ -22,21 +23,25 @@ export default [
|
||||||
{
|
{
|
||||||
name: '充值订单',
|
name: '充值订单',
|
||||||
path: RoutePath.RECORD.LIST,
|
path: RoutePath.RECORD.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './Recharge/Record/List',
|
component: './Recharge/Record/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '收款地址',
|
name: '收款地址',
|
||||||
path: RoutePath.WALLET.LIST,
|
path: RoutePath.WALLET.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './Recharge/Wallet/List',
|
component: './Recharge/Wallet/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '代币种类',
|
name: '代币种类',
|
||||||
path: RoutePath.COIN_TYPE.LIST,
|
path: RoutePath.COIN_TYPE.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './Recharge/CoinType/List',
|
component: './Recharge/CoinType/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '提现管理',
|
name: '提现管理',
|
||||||
path: RoutePath.WITHDRAW.LIST,
|
path: RoutePath.WITHDRAW.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './Recharge/Withdraw/List',
|
component: './Recharge/Withdraw/List',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -44,6 +49,7 @@ export default [
|
||||||
{
|
{
|
||||||
name: '用户账号',
|
name: '用户账号',
|
||||||
path: RoutePath.USER,
|
path: RoutePath.USER,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: RoutePath.USER,
|
path: RoutePath.USER,
|
||||||
|
|
@ -53,6 +59,7 @@ export default [
|
||||||
{
|
{
|
||||||
name: '用户账号管理',
|
name: '用户账号管理',
|
||||||
path: RoutePath.USER_LIST.LIST,
|
path: RoutePath.USER_LIST.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './User/List',
|
component: './User/List',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -60,6 +67,7 @@ export default [
|
||||||
{
|
{
|
||||||
name: '系统设置',
|
name: '系统设置',
|
||||||
path: RoutePath.SYSTEM,
|
path: RoutePath.SYSTEM,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: RoutePath.SYSTEM,
|
path: RoutePath.SYSTEM,
|
||||||
|
|
@ -69,32 +77,38 @@ export default [
|
||||||
{
|
{
|
||||||
name: '账号管理',
|
name: '账号管理',
|
||||||
path: RoutePath.ACCOUNT.LIST,
|
path: RoutePath.ACCOUNT.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './System/Account/List',
|
component: './System/Account/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '角色管理',
|
name: '角色管理',
|
||||||
path: RoutePath.ROLE.LIST,
|
path: RoutePath.ROLE.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './System/Role/List',
|
component: './System/Role/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '权限管理',
|
name: '权限管理',
|
||||||
path: RoutePath.PERMISSIONS.LIST,
|
path: RoutePath.PERMISSIONS.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './System/Permissions/List',
|
component: './System/Permissions/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '通知管理',
|
name: '通知管理',
|
||||||
path: RoutePath.NOTICE.LIST,
|
path: RoutePath.NOTICE.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './System/Notice/List',
|
component: './System/Notice/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '密钥管理',
|
name: '密钥管理',
|
||||||
path: RoutePath.SECRET_KEY,
|
path: RoutePath.SECRET_KEY,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './System/SecretKey',
|
component: './System/SecretKey',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '数据看板',
|
name: '数据看板',
|
||||||
|
access: 'normalRouteFilter',
|
||||||
path: RoutePath.DATABOARD,
|
path: RoutePath.DATABOARD,
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
|
|
@ -105,21 +119,25 @@ export default [
|
||||||
{
|
{
|
||||||
name: '核心看板',
|
name: '核心看板',
|
||||||
path: RoutePath.COREDATA.LIST,
|
path: RoutePath.COREDATA.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './DataBoard/CoreData/List',
|
component: './DataBoard/CoreData/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '活跃分析',
|
name: '活跃分析',
|
||||||
path: RoutePath.ACTIVEANALYSIS.LIST,
|
path: RoutePath.ACTIVEANALYSIS.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './DataBoard/ActiveAnalysis/List',
|
component: './DataBoard/ActiveAnalysis/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '留存分析',
|
name: '留存分析',
|
||||||
path: RoutePath.RETENTIONANALYSIS.LIST,
|
path: RoutePath.RETENTIONANALYSIS.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './DataBoard/RetentionAnalysis/List',
|
component: './DataBoard/RetentionAnalysis/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '用户充值分析',
|
name: '用户充值分析',
|
||||||
path: RoutePath.RECHARGEANALYSIS.LIST,
|
path: RoutePath.RECHARGEANALYSIS.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './DataBoard/RechargeAnalysis/List',
|
component: './DataBoard/RechargeAnalysis/List',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -127,6 +145,7 @@ export default [
|
||||||
{
|
{
|
||||||
name: 'NFT',
|
name: 'NFT',
|
||||||
path: RoutePath.NFT,
|
path: RoutePath.NFT,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: RoutePath.NFT,
|
path: RoutePath.NFT,
|
||||||
|
|
@ -136,13 +155,21 @@ export default [
|
||||||
{
|
{
|
||||||
name: 'NFT合约管理',
|
name: 'NFT合约管理',
|
||||||
path: RoutePath.NFTCONTRACT.LIST,
|
path: RoutePath.NFTCONTRACT.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './NFT/NftContract/List',
|
component: './NFT/NftContract/List',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'NFT管理',
|
name: 'NFT管理',
|
||||||
path: RoutePath.NFTTOKEN.LIST,
|
path: RoutePath.NFTTOKEN.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
component: './NFT/NftToken/List',
|
component: './NFT/NftToken/List',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'NFT交易',
|
||||||
|
path: RoutePath.NFTTRADE.LIST,
|
||||||
|
access: 'normalRouteFilter',
|
||||||
|
component: './NFT/NftTrade/List',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ const RoutePath = {
|
||||||
NFTTOKEN: {
|
NFTTOKEN: {
|
||||||
LIST: `${NFT}/nfttoken`,
|
LIST: `${NFT}/nfttoken`,
|
||||||
},
|
},
|
||||||
|
NFTTRADE: {
|
||||||
|
LIST: `${NFT}/NFT_trade`,
|
||||||
|
},
|
||||||
DATABOARD: DATABOARD,
|
DATABOARD: DATABOARD,
|
||||||
COREDATA: {
|
COREDATA: {
|
||||||
LIST: `${DATABOARD}/coredata`,
|
LIST: `${DATABOARD}/coredata`,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取合约
|
||||||
|
* @param {object} params
|
||||||
|
* erc 合约类型
|
||||||
|
* @returns {object} data
|
||||||
|
*/
|
||||||
|
export const getContractInfo = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/contract/get',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取NFT合约列表
|
||||||
|
* @param {object} params
|
||||||
|
* @returns {array} data
|
||||||
|
* name 游戏币名称
|
||||||
|
* type 游戏币类型
|
||||||
|
* usdt_price 游戏货币与usdt的比例
|
||||||
|
* eth_price 游戏货币与eth的比例
|
||||||
|
*/
|
||||||
|
export const getNFTContractList = () => {
|
||||||
|
return request.request({
|
||||||
|
url: '/erc721/get',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建NFT合约
|
||||||
|
* @param {object} data
|
||||||
|
*
|
||||||
|
* @returns {array} data
|
||||||
|
*/
|
||||||
|
export const createNFTContract = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/erc721/create',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询token_Id是否存在
|
||||||
|
* @param {object} params
|
||||||
|
*
|
||||||
|
* @returns {array} data
|
||||||
|
*/
|
||||||
|
export const checkTokenId = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/nft/check',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取NFT列表
|
||||||
|
* @param {object} params
|
||||||
|
*
|
||||||
|
* @returns {array} data
|
||||||
|
*/
|
||||||
|
export const getNFTList = (params) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/nft/get',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mintNFT
|
||||||
|
* @param {object} data
|
||||||
|
*
|
||||||
|
* @returns {array} data
|
||||||
|
*/
|
||||||
|
export const mintNFT = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/nft/create',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新NFT信息
|
||||||
|
* @param {object} data
|
||||||
|
*
|
||||||
|
* @returns {array} data
|
||||||
|
*/
|
||||||
|
export const updateNFTInfo = (data) => {
|
||||||
|
return request.request({
|
||||||
|
url: '/nft/update',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -4,7 +4,7 @@ import request from '@/utils/request';
|
||||||
* 获取代币种类列表
|
* 获取代币种类列表
|
||||||
* @param {object} params
|
* @param {object} params
|
||||||
* type 代币种类
|
* type 代币种类
|
||||||
* @returns {array} data
|
* @returns {array} dat
|
||||||
* name 游戏币名称
|
* name 游戏币名称
|
||||||
* type 游戏币类型
|
* type 游戏币类型
|
||||||
* usdt_price 游戏货币与usdt的比例
|
* usdt_price 游戏货币与usdt的比例
|
||||||
|
|
@ -12,7 +12,7 @@ import request from '@/utils/request';
|
||||||
*/
|
*/
|
||||||
export const getCoinTypeList = (params) => {
|
export const getCoinTypeList = (params) => {
|
||||||
return request.request({
|
return request.request({
|
||||||
url: '/token/get',
|
url: '/erc20/get',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
|
|
@ -29,7 +29,7 @@ export const getCoinTypeList = (params) => {
|
||||||
*/
|
*/
|
||||||
export const addCoinType = (data) => {
|
export const addCoinType = (data) => {
|
||||||
return request.request({
|
return request.request({
|
||||||
url: '/token/create',
|
url: '/erc20/create',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
|
@ -46,7 +46,7 @@ export const addCoinType = (data) => {
|
||||||
*/
|
*/
|
||||||
export const modifyCoinType = (data) => {
|
export const modifyCoinType = (data) => {
|
||||||
return request.request({
|
return request.request({
|
||||||
url: '/token/update',
|
url: '/erc20/update',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import request from '@/utils/request';
|
||||||
*/
|
*/
|
||||||
export const getRoleList = (params) => {
|
export const getRoleList = (params) => {
|
||||||
return request.request({
|
return request.request({
|
||||||
url: '/user/role',
|
url: '/user/role/get',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export const fetchTableData = async (
|
||||||
formatObj: any = {},
|
formatObj: any = {},
|
||||||
) => {
|
) => {
|
||||||
params.page = params.current;
|
params.page = params.current;
|
||||||
params.page_size = params.pageSize;
|
params.size = params.pageSize;
|
||||||
delete params.current;
|
delete params.current;
|
||||||
delete params.pageSize;
|
delete params.pageSize;
|
||||||
const res = (await fetch(params)) || {};
|
const res = (await fetch(params)) || {};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
import Web3 from 'web3';
|
||||||
|
import detectEthereumProvider from '@metamask/detect-provider';
|
||||||
|
import { message } from 'antd';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
|
let provider: any;
|
||||||
|
|
||||||
|
export const web3 = new Web3();
|
||||||
|
if (typeof window.ethereum !== 'undefined') {
|
||||||
|
web3.eth.defaultAccount = window.ethereum.selectedAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initWeb3() {
|
||||||
|
provider = await detectEthereumProvider();
|
||||||
|
|
||||||
|
if (!provider) {
|
||||||
|
console.log('请安装MetaMask');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
web3.setProvider(provider);
|
||||||
|
const accounts = await provider.request({
|
||||||
|
method: 'eth_requestAccounts',
|
||||||
|
});
|
||||||
|
web3.eth.defaultAccount = accounts[0];
|
||||||
|
return true;
|
||||||
|
} catch (reason) {
|
||||||
|
switch (reason) {
|
||||||
|
case 'Already processing eth_requestAccounts. Please wait.': // 已有请求存在
|
||||||
|
message.warning('请打开MetaMask完成授权');
|
||||||
|
break;
|
||||||
|
case 'User rejected provider access': //如果用户拒绝了登录请求
|
||||||
|
message.warning('请同意登录请求');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 本不该执行到这里,但是真到这里了,说明发生了意外
|
||||||
|
message.warning('登录出错!err:' + reason);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//发布合约
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param abi 合约ABI
|
||||||
|
* @param bin 合约二进制
|
||||||
|
*/
|
||||||
|
export async function deployContract(abi: string, bin: string, params) {
|
||||||
|
const contract = new web3.eth.Contract(eval('(' + abi + ')'));
|
||||||
|
const result = await contract
|
||||||
|
.deploy({
|
||||||
|
data: '0x' + bin,
|
||||||
|
arguments: params,
|
||||||
|
})
|
||||||
|
.send({ from: web3.eth.defaultAccount + '', gas: 3000000 }, async function (e, contract) {});
|
||||||
|
return result._address;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 代币转账
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param abi 合约ABI
|
||||||
|
* @param address 合约地址
|
||||||
|
* @param toAddress 转账地址
|
||||||
|
*/
|
||||||
|
export async function transfer(abi: string, address: string, toAddress: string) {
|
||||||
|
const contract = new web3.eth.Contract(eval('(' + abi + ')'), address);
|
||||||
|
await contract.methods
|
||||||
|
.transfer(toAddress, new BigNumber(1 * Math.pow(10, 18)))
|
||||||
|
.send({ from: web3.eth.defaultAccount }),
|
||||||
|
function (error, transactionHash) {
|
||||||
|
if (!error) {
|
||||||
|
console.log('transactionHash is ' + transactionHash);
|
||||||
|
} else {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NFT创建
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param abi 合约ABI
|
||||||
|
* @param address 合约地址
|
||||||
|
* @param toAddress 转账地址
|
||||||
|
*/
|
||||||
|
|
||||||
|
export async function NFTMint(params: any) {
|
||||||
|
if (params.toAddress == '' || params.toAddress == null || params.toAddress == undefined) {
|
||||||
|
params.toAddress = web3.eth.defaultAccount;
|
||||||
|
}
|
||||||
|
const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
|
||||||
|
await contract.methods
|
||||||
|
.Mint(params.toAddress, params.token_id)
|
||||||
|
.send({ from: web3.eth.defaultAccount }),
|
||||||
|
function (error, transactionHash) {
|
||||||
|
if (!error) {
|
||||||
|
return transactionHash;
|
||||||
|
} else {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NFT转移
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param abi 合约ABI
|
||||||
|
* @param address 合约地址
|
||||||
|
* @param toAddress 转账地址
|
||||||
|
* @param token_id
|
||||||
|
*/
|
||||||
|
export async function transferNFT(params: any) {
|
||||||
|
const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
|
||||||
|
await contract.methods
|
||||||
|
.safeTransferFrom(web3.eth.defaultAccount, params.toAddress, params.token_id)
|
||||||
|
.send({ from: web3.eth.defaultAccount }),
|
||||||
|
function (error, transactionHash) {
|
||||||
|
if (!error) {
|
||||||
|
return transactionHash;
|
||||||
|
} else {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NFT销毁
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param abi 合约ABI
|
||||||
|
* @param address 合约地址
|
||||||
|
* @param token_id
|
||||||
|
*/
|
||||||
|
export async function burnNFT(params: any) {
|
||||||
|
const contract = new web3.eth.Contract(eval('(' + params.abi + ')'), params.address);
|
||||||
|
await contract.methods.Burn(params.token_id).send({ from: web3.eth.defaultAccount }),
|
||||||
|
function (error, transactionHash) {
|
||||||
|
if (!error) {
|
||||||
|
return transactionHash;
|
||||||
|
} else {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue