-
4.env
-
3config/webpackDevServer.config.js
-
5package.json
-
2public/index.html
-
8src/api/axios_config.ts
-
37src/api/index.ts
-
40src/api/service.ts
-
BINsrc/assets/FIL.png
-
BINsrc/assets/USDT.png
-
18src/assets/iconfont/iconfont.css
-
2src/assets/iconfont/iconfont.js
-
21src/assets/iconfont/iconfont.json
-
BINsrc/assets/iconfont/iconfont.ttf
-
BINsrc/assets/iconfont/iconfont.woff
-
BINsrc/assets/iconfont/iconfont.woff2
-
BINsrc/assets/recharge.png
-
BINsrc/assets/record.png
-
BINsrc/assets/team.png
-
BINsrc/assets/withdraw.png
-
20src/components/BackBar.tsx
-
324src/contract/IERC20.d.ts
-
203src/contract/IERC20__factory.ts
-
4src/hooks/useConnectWallet.ts
-
15src/hooks/useCopy.ts
-
61src/pages/personal/AccountAssetsCard.tsx
-
69src/pages/personal/index.tsx
-
162src/pages/recharge/index.tsx
-
303src/pages/record/index.tsx
-
76src/pages/withdraw/index.tsx
-
19src/router/layout/Navbar.tsx
-
6src/router/layout/Notify.tsx
-
12src/router/layout/index.tsx
-
16src/router/routes.tsx
-
32src/store/index.ts
-
1src/styles/global.scss
-
16src/styles/layout.scss
-
90src/styles/personal.scss
-
71src/styles/recharge.scss
-
1src/styles/theme.scss
-
25src/types/store.d.ts
-
22src/utils/copy.ts
-
63src/utils/index.ts
-
21src/utils/wei.ts
-
532yarn.lock
@ -1,5 +1,5 @@ |
|||
SKIP_PREFLIGHT_CHECK=true |
|||
GENERATE_SOURCEMAP=false |
|||
REACT_APP_BASE_URL='http://14.29.101.215:30304' |
|||
REACT_APP_BASE_URL='http://14.29.101.215:30307' |
|||
REACT_APP_SHARE_LINK='http://14.29.101.215:30305/#/' |
|||
REACT_APP_SIGN_KEY='finance_ad123' |
|||
REACT_APP_SIGN_KEY='9527nft9527_@fsdgfsx' |
@ -1,15 +1,38 @@ |
|||
import { PerformSignin, PerformSNonce } from "~/types" |
|||
import request from './service' |
|||
import { PerformSignin, PerformSNonce } from "~/types"; |
|||
import request from "./service"; |
|||
|
|||
/** |
|||
* @description 获取随机数 |
|||
*/ |
|||
export const getNonce = (query: PerformSNonce) => request({ |
|||
url: '/v1/nonce', |
|||
data: query |
|||
}) |
|||
export const getNonce = (query: PerformSNonce) => |
|||
request({ |
|||
url: "/v1/nonce", |
|||
data: query, |
|||
}); |
|||
|
|||
/** |
|||
* @description 签名 |
|||
*/ |
|||
export const performSignin = (query: PerformSignin) => request({ url: '/v1/signin', data: query }) |
|||
export const performSignin = (query: PerformSignin) => |
|||
request({ url: "/v1/signin", data: query }); |
|||
|
|||
/** |
|||
* @description 上传图片 |
|||
*/ |
|||
export const uploadImage = (file: File) => { |
|||
const body = new FormData(); |
|||
console.log(body); |
|||
|
|||
body.append("img", file); |
|||
return request({ url: "/v1/uploadImg", data: body }) |
|||
}; |
|||
|
|||
/** |
|||
* @description 用户信息 |
|||
*/ |
|||
export const accountInfo = () => request({ url: '/v1/account' }) |
|||
|
|||
/** |
|||
* @description coin list |
|||
*/ |
|||
export const coin_list = () => request({ url: '/v1/tokenList' }) |
After Width: 40 | Height: 40 | Size: 1.3 KiB |
After Width: 60 | Height: 60 | Size: 2.1 KiB |
2
src/assets/iconfont/iconfont.js
File diff suppressed because it is too large
View File
After Width: 120 | Height: 120 | Size: 4.3 KiB |
After Width: 120 | Height: 120 | Size: 3.9 KiB |
After Width: 120 | Height: 120 | Size: 3.5 KiB |
After Width: 120 | Height: 120 | Size: 4.3 KiB |
@ -0,0 +1,20 @@ |
|||
import { useRouter } from "~/hooks/useRouter"; |
|||
|
|||
interface BackBarProps { |
|||
title: string |
|||
} |
|||
|
|||
const BackBar = ({ title }: BackBarProps) => { |
|||
|
|||
const { push } = useRouter(); |
|||
|
|||
return ( |
|||
<div className="row-between"> |
|||
<div style={{ flex: 1 }} className="iconfont icon-arrow-left-bold fz-24" onClick={() => push(-1)}></div> |
|||
<div style={{ flex: 1 }} className='tac fz-20 fz-wb-550'>{title}</div> |
|||
<div style={{ flex: 1 }}></div> |
|||
</div> |
|||
) |
|||
}; |
|||
|
|||
export default BackBar; |
@ -0,0 +1,324 @@ |
|||
/* Autogenerated file. Do not edit manually. */ |
|||
/* tslint:disable */ |
|||
/* eslint-disable */ |
|||
|
|||
import { |
|||
ethers, |
|||
EventFilter, |
|||
Signer, |
|||
BigNumber, |
|||
BigNumberish, |
|||
PopulatedTransaction, |
|||
BaseContract, |
|||
ContractTransaction, |
|||
Overrides, |
|||
CallOverrides, |
|||
} from "ethers"; |
|||
import { BytesLike } from "@ethersproject/bytes"; |
|||
import { Listener, Provider } from "@ethersproject/providers"; |
|||
import { FunctionFragment, EventFragment, Result } from "@ethersproject/abi"; |
|||
import type { TypedEventFilter, TypedEvent, TypedListener } from "./common"; |
|||
|
|||
interface IERC20Interface extends ethers.utils.Interface { |
|||
functions: { |
|||
"allowance(address,address)": FunctionFragment; |
|||
"approve(address,uint256)": FunctionFragment; |
|||
"balanceOf(address)": FunctionFragment; |
|||
"totalSupply()": FunctionFragment; |
|||
"transfer(address,uint256)": FunctionFragment; |
|||
"transferFrom(address,address,uint256)": FunctionFragment; |
|||
}; |
|||
|
|||
encodeFunctionData( |
|||
functionFragment: "allowance", |
|||
values: [string, string] |
|||
): string; |
|||
encodeFunctionData( |
|||
functionFragment: "approve", |
|||
values: [string, BigNumberish] |
|||
): string; |
|||
encodeFunctionData(functionFragment: "balanceOf", values: [string]): string; |
|||
encodeFunctionData( |
|||
functionFragment: "totalSupply", |
|||
values?: undefined |
|||
): string; |
|||
encodeFunctionData( |
|||
functionFragment: "transfer", |
|||
values: [string, BigNumberish] |
|||
): string; |
|||
encodeFunctionData( |
|||
functionFragment: "transferFrom", |
|||
values: [string, string, BigNumberish] |
|||
): string; |
|||
|
|||
decodeFunctionResult(functionFragment: "allowance", data: BytesLike): Result; |
|||
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result; |
|||
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result; |
|||
decodeFunctionResult( |
|||
functionFragment: "totalSupply", |
|||
data: BytesLike |
|||
): Result; |
|||
decodeFunctionResult(functionFragment: "transfer", data: BytesLike): Result; |
|||
decodeFunctionResult( |
|||
functionFragment: "transferFrom", |
|||
data: BytesLike |
|||
): Result; |
|||
|
|||
events: { |
|||
"Approval(address,address,uint256)": EventFragment; |
|||
"Transfer(address,address,uint256)": EventFragment; |
|||
}; |
|||
|
|||
getEvent(nameOrSignatureOrTopic: "Approval"): EventFragment; |
|||
getEvent(nameOrSignatureOrTopic: "Transfer"): EventFragment; |
|||
} |
|||
|
|||
export type ApprovalEvent = TypedEvent< |
|||
[string, string, BigNumber] & { |
|||
owner: string; |
|||
spender: string; |
|||
value: BigNumber; |
|||
} |
|||
>; |
|||
|
|||
export type TransferEvent = TypedEvent< |
|||
[string, string, BigNumber] & { from: string; to: string; value: BigNumber } |
|||
>; |
|||
|
|||
export class IERC20 extends BaseContract { |
|||
connect(signerOrProvider: Signer | Provider | string): this; |
|||
attach(addressOrName: string): this; |
|||
deployed(): Promise<this>; |
|||
|
|||
listeners<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter?: TypedEventFilter<EventArgsArray, EventArgsObject> |
|||
): Array<TypedListener<EventArgsArray, EventArgsObject>>; |
|||
off<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>, |
|||
listener: TypedListener<EventArgsArray, EventArgsObject> |
|||
): this; |
|||
on<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>, |
|||
listener: TypedListener<EventArgsArray, EventArgsObject> |
|||
): this; |
|||
once<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>, |
|||
listener: TypedListener<EventArgsArray, EventArgsObject> |
|||
): this; |
|||
removeListener<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject>, |
|||
listener: TypedListener<EventArgsArray, EventArgsObject> |
|||
): this; |
|||
removeAllListeners<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
eventFilter: TypedEventFilter<EventArgsArray, EventArgsObject> |
|||
): this; |
|||
|
|||
listeners(eventName?: string): Array<Listener>; |
|||
off(eventName: string, listener: Listener): this; |
|||
on(eventName: string, listener: Listener): this; |
|||
once(eventName: string, listener: Listener): this; |
|||
removeListener(eventName: string, listener: Listener): this; |
|||
removeAllListeners(eventName?: string): this; |
|||
|
|||
queryFilter<EventArgsArray extends Array<any>, EventArgsObject>( |
|||
event: TypedEventFilter<EventArgsArray, EventArgsObject>, |
|||
fromBlockOrBlockhash?: string | number | undefined, |
|||
toBlock?: string | number | undefined |
|||
): Promise<Array<TypedEvent<EventArgsArray & EventArgsObject>>>; |
|||
|
|||
interface: IERC20Interface; |
|||
|
|||
functions: { |
|||
allowance( |
|||
owner: string, |
|||
spender: string, |
|||
overrides?: CallOverrides |
|||
): Promise<[BigNumber]>; |
|||
|
|||
approve( |
|||
spender: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
|
|||
balanceOf(account: string, overrides?: CallOverrides): Promise<[BigNumber]>; |
|||
|
|||
totalSupply(overrides?: CallOverrides): Promise<[BigNumber]>; |
|||
|
|||
transfer( |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
|
|||
transferFrom( |
|||
from: string, |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
}; |
|||
|
|||
allowance( |
|||
owner: string, |
|||
spender: string, |
|||
overrides?: CallOverrides |
|||
): Promise<BigNumber>; |
|||
|
|||
approve( |
|||
spender: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
|
|||
balanceOf(account: string, overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
totalSupply(overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
transfer( |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
|
|||
transferFrom( |
|||
from: string, |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<ContractTransaction>; |
|||
|
|||
callStatic: { |
|||
allowance( |
|||
owner: string, |
|||
spender: string, |
|||
overrides?: CallOverrides |
|||
): Promise<BigNumber>; |
|||
|
|||
approve( |
|||
spender: string, |
|||
amount: BigNumberish, |
|||
overrides?: CallOverrides |
|||
): Promise<boolean>; |
|||
|
|||
balanceOf(account: string, overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
totalSupply(overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
transfer( |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: CallOverrides |
|||
): Promise<boolean>; |
|||
|
|||
transferFrom( |
|||
from: string, |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: CallOverrides |
|||
): Promise<boolean>; |
|||
}; |
|||
|
|||
filters: { |
|||
"Approval(address,address,uint256)"( |
|||
owner?: string | null, |
|||
spender?: string | null, |
|||
value?: null |
|||
): TypedEventFilter< |
|||
[string, string, BigNumber], |
|||
{ owner: string; spender: string; value: BigNumber } |
|||
>; |
|||
|
|||
Approval( |
|||
owner?: string | null, |
|||
spender?: string | null, |
|||
value?: null |
|||
): TypedEventFilter< |
|||
[string, string, BigNumber], |
|||
{ owner: string; spender: string; value: BigNumber } |
|||
>; |
|||
|
|||
"Transfer(address,address,uint256)"( |
|||
from?: string | null, |
|||
to?: string | null, |
|||
value?: null |
|||
): TypedEventFilter< |
|||
[string, string, BigNumber], |
|||
{ from: string; to: string; value: BigNumber } |
|||
>; |
|||
|
|||
Transfer( |
|||
from?: string | null, |
|||
to?: string | null, |
|||
value?: null |
|||
): TypedEventFilter< |
|||
[string, string, BigNumber], |
|||
{ from: string; to: string; value: BigNumber } |
|||
>; |
|||
}; |
|||
|
|||
estimateGas: { |
|||
allowance( |
|||
owner: string, |
|||
spender: string, |
|||
overrides?: CallOverrides |
|||
): Promise<BigNumber>; |
|||
|
|||
approve( |
|||
spender: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<BigNumber>; |
|||
|
|||
balanceOf(account: string, overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
totalSupply(overrides?: CallOverrides): Promise<BigNumber>; |
|||
|
|||
transfer( |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<BigNumber>; |
|||
|
|||
transferFrom( |
|||
from: string, |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<BigNumber>; |
|||
}; |
|||
|
|||
populateTransaction: { |
|||
allowance( |
|||
owner: string, |
|||
spender: string, |
|||
overrides?: CallOverrides |
|||
): Promise<PopulatedTransaction>; |
|||
|
|||
approve( |
|||
spender: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<PopulatedTransaction>; |
|||
|
|||
balanceOf( |
|||
account: string, |
|||
overrides?: CallOverrides |
|||
): Promise<PopulatedTransaction>; |
|||
|
|||
totalSupply(overrides?: CallOverrides): Promise<PopulatedTransaction>; |
|||
|
|||
transfer( |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<PopulatedTransaction>; |
|||
|
|||
transferFrom( |
|||
from: string, |
|||
to: string, |
|||
amount: BigNumberish, |
|||
overrides?: Overrides & { from?: string | Promise<string> } |
|||
): Promise<PopulatedTransaction>; |
|||
}; |
|||
} |
@ -0,0 +1,203 @@ |
|||
/* Autogenerated file. Do not edit manually. */ |
|||
/* tslint:disable */ |
|||
/* eslint-disable */ |
|||
|
|||
import { Contract, Signer, utils } from "ethers"; |
|||
import type { Provider } from "@ethersproject/providers"; |
|||
import type { IERC20, IERC20Interface } from "./IERC20"; |
|||
|
|||
export const _abi = [ |
|||
{ |
|||
anonymous: false, |
|||
inputs: [ |
|||
{ |
|||
indexed: true, |
|||
internalType: "address", |
|||
name: "owner", |
|||
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", |
|||
}, |
|||
{ |
|||
inputs: [ |
|||
{ |
|||
internalType: "address", |
|||
name: "owner", |
|||
type: "address", |
|||
}, |
|||
{ |
|||
internalType: "address", |
|||
name: "spender", |
|||
type: "address", |
|||
}, |
|||
], |
|||
name: "allowance", |
|||
outputs: [ |
|||
{ |
|||
internalType: "uint256", |
|||
name: "", |
|||
type: "uint256", |
|||
}, |
|||
], |
|||
stateMutability: "view", |
|||
type: "function", |
|||
}, |
|||
{ |
|||
inputs: [ |
|||
{ |
|||
internalType: "address", |
|||
name: "spender", |
|||
type: "address", |
|||
}, |
|||
{ |
|||
internalType: "uint256", |
|||
name: "amount", |
|||
type: "uint256", |
|||
}, |
|||
], |
|||
name: "approve", |
|||
outputs: [ |
|||
{ |
|||
internalType: "bool", |
|||
name: "", |
|||
type: "bool", |
|||
}, |
|||
], |
|||
stateMutability: "nonpayable", |
|||
type: "function", |
|||
}, |
|||
{ |
|||
inputs: [ |
|||
{ |
|||
internalType: "address", |
|||
name: "account", |
|||
type: "address", |
|||
}, |
|||
], |
|||
name: "balanceOf", |
|||
outputs: [ |
|||
{ |
|||
internalType: "uint256", |
|||
name: "", |
|||
type: "uint256", |
|||
}, |
|||
], |
|||
stateMutability: "view", |
|||
type: "function", |
|||
}, |
|||
{ |
|||
inputs: [], |
|||
name: "totalSupply", |
|||
outputs: [ |
|||
{ |
|||
internalType: "uint256", |
|||
name: "", |
|||
type: "uint256", |
|||
}, |
|||
], |
|||
stateMutability: "view", |
|||
type: "function", |
|||
}, |
|||
{ |
|||
inputs: [ |
|||
{ |
|||
internalType: "address", |
|||
name: "to", |
|||
type: "address", |
|||
}, |
|||
{ |
|||
internalType: "uint256", |
|||
name: "amount", |
|||
type: "uint256", |
|||
}, |
|||
], |
|||
name: "transfer", |
|||
outputs: [ |
|||
{ |
|||
internalType: "bool", |
|||
name: "", |
|||
type: "bool", |
|||
}, |
|||
], |
|||
stateMutability: "nonpayable", |
|||
type: "function", |
|||
}, |
|||
{ |
|||
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", |
|||
}, |
|||
], |
|||
stateMutability: "nonpayable", |
|||
type: "function", |
|||
}, |
|||
]; |
|||
|
|||
export class IERC20__factory { |
|||
static readonly abi = _abi; |
|||
static createInterface(): IERC20Interface { |
|||
return new utils.Interface(_abi) as IERC20Interface; |
|||
} |
|||
static connect(address: string, signerOrProvider: Signer | Provider): IERC20 { |
|||
return new Contract(address, _abi, signerOrProvider) as IERC20; |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
import { Toast } from 'react-vant'; |
|||
import { copy } from "../utils/copy"; |
|||
|
|||
const useCopyLink = () => { |
|||
|
|||
const copyVal = (address: any) => { |
|||
copy(address, () => { |
|||
Toast.success('复制成功'); |
|||
}) |
|||
}; |
|||
|
|||
return { copyVal } |
|||
}; |
|||
|
|||
export default useCopyLink; |
@ -0,0 +1,61 @@ |
|||
import '~/styles/personal.scss' |
|||
import { useMemo } from "react"; |
|||
import { useRouter } from "~/hooks/useRouter"; |
|||
|
|||
const AccountAssetsCard = () => { |
|||
|
|||
const { push } = useRouter(); |
|||
|
|||
const balanceList = useMemo(() => [ |
|||
{ title: 'USDT资产', value: 0, symbol: 'USDT' }, |
|||
{ title: 'FIL资产', value: 0, symbol: 'FIL' }, |
|||
], []); |
|||
|
|||
const menu = useMemo(() => [ |
|||
{ title: '充值', icon: require('~/assets/recharge.png'), path: '/recharge' }, |
|||
{ title: '提现', icon: require('~/assets/withdraw.png'), path: '/withdraw' }, |
|||
{ title: '账单', icon: require('~/assets/record.png'), path: '/record' }, |
|||
{ title: '团队', icon: require('~/assets/team.png'), path: '/team' }, |
|||
], []); |
|||
|
|||
return ( |
|||
<div className="account-assets"> |
|||
<div> |
|||
<div className='card'> |
|||
<div> |
|||
<div className='sub-color'>总资产估值</div> |
|||
<div className='mt-5px'><span className='fz-24 fz-wb-550'>1429.32</span> <span>USDT</span></div> |
|||
</div> |
|||
<div className='row-items'> |
|||
{ |
|||
balanceList.map((item, index) => ( |
|||
<div key={index} className="text-center mr-4"> |
|||
<div className='sub-color'>{item.title}</div> |
|||
<div className='mt-5px' style={{ wordBreak: 'break-word' }}> |
|||
<div className='mt-5px'> |
|||
<span className='fz-24 fz-wb-550'>{item.value}</span> |
|||
<span className='ml-5px'>{item.symbol}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
)) |
|||
} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
{/* */} |
|||
<div className='mt-2 menu'> |
|||
{ |
|||
menu.map((item, index) => ( |
|||
<div key={index} className="row-between" onClick={() => push(item.path)}> |
|||
<img src={item.icon} alt="" /> |
|||
<div className='fz-14 ml-5px'>{item.title}</div> |
|||
</div> |
|||
)) |
|||
} |
|||
</div> |
|||
</div> |
|||
) |
|||
}; |
|||
|
|||
export default AccountAssetsCard; |
@ -1,42 +1,45 @@ |
|||
import { Divider } from 'react-vant' |
|||
import '~/styles/personal.scss' |
|||
import AccountAssetsCard from './AccountAssetsCard' |
|||
|
|||
const Personal = () => { |
|||
|
|||
return ( |
|||
<div className='plr-2 cart'> |
|||
|
|||
{/* <div className='fz-wb-550 mtb-2'>购物车</div> |
|||
<div> |
|||
{ |
|||
Array.from({ length: 5 }).map((_, index) => ( |
|||
<div className='row-items mt-3' key={index}> |
|||
<img src={require('~/assets/cover.png')} className="cover" alt="" /> |
|||
<div className='box p-2'> |
|||
<div className='fz-14'>The Unkown</div> |
|||
<div className='row-items mt-5px'> |
|||
<div className='price-tag'>ETH 2.25</div> |
|||
<div className='user-tag ml-1'> |
|||
<img src={require('~/assets/user.png')} className="img" alt="" /> |
|||
<div className='ml-3px'>iamjackrider</div> |
|||
</div> |
|||
</div> |
|||
<div className='fz-12 sub-text mt-1'>Top Bid is By You</div> |
|||
<div className='fz-12 sub-text mt-1'>Time Remaining</div> |
|||
<div className='row-items mt-5px'> |
|||
<div className='timing-box fz-12'> |
|||
<i className='iconfont icon-clock fz-12 fz-wb-550' style={{ color: '#F96900' }} /> |
|||
<Divider type='vertical' style={{ borderColor: '#C4C4C4' }} className="ml-5px" /> |
|||
<div className='ml-5px fz-wb-550' style={{ color: '#F96900' }}>00:02:30</div> |
|||
</div> |
|||
<div className='ml-4 row-center delete'> |
|||
<i className='iconfont icon-delete'></i> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div className='personal'> |
|||
{/* <Uploader |
|||
maxCount={1} |
|||
maxSize={500 * 1024} |
|||
onOversize={() => Toast.info('文件大小不能超过500kb')} |
|||
upload={upload} |
|||
/> */} |
|||
<div className='plr-2 '> |
|||
<div className='mt-3'> |
|||
<AccountAssetsCard /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div className='mt-2 assets-box'> |
|||
<div>资产</div> |
|||
<Divider style={{ margin: 0, borderColor: "#d8d8d8" }} /> |
|||
<div className='mt-1 row-between fz-14 sub-text'> |
|||
<div>名称</div> |
|||
<div>可用</div> |
|||
</div> |
|||
<div className='row-between mt-2'> |
|||
<div className='row'> |
|||
<img src={require('~/assets/USDT.png')} className='symbol-img' alt="" /> |
|||
<div className='ml-1'> |
|||
<div className='fz-wb-550'>USDT</div> |
|||
<div className='fz-14 sub-text mt-5px'>TetherUS</div> |
|||
</div> |
|||
)) |
|||
} */} |
|||
{/* </div> */} |
|||
</div> |
|||
<div className='tar'> |
|||
<div className='fz-wb-550'>100</div> |
|||
<div className='sub-text fz-14 mt-5px'>$429.32</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
) |
|||
} |
|||
|
@ -0,0 +1,162 @@ |
|||
import '~/styles/recharge.scss' |
|||
import { observer } from 'mobx-react' |
|||
import store from '../../store' |
|||
import { useMemo, useRef, useState } from 'react' |
|||
import { useRouter } from '../../hooks/useRouter' |
|||
import { ethers } from 'ethers' |
|||
import { Button, Toast } from 'react-vant' |
|||
import { switchNetWork } from '../../utils' |
|||
import { IERC20__factory } from '../../contract/IERC20__factory' |
|||
import { toWei } from '../../utils/wei' |
|||
import BackBar from '~/components/BackBar' |
|||
|
|||
const Recharge = () => { |
|||
|
|||
const { coinIndex, coinList, userInfo } = store.state |
|||
const { push } = useRouter() |
|||
const inputRef = useRef<HTMLInputElement>(null); |
|||
const currentCoin = useMemo(() => coinList[coinIndex], [coinIndex, coinList]) |
|||
const [loading, setLoading] = useState(false); |
|||
|
|||
const provider = useMemo(() => { |
|||
if (window.ethereum) { |
|||
return new ethers.providers.Web3Provider(window.ethereum) |
|||
}; |
|||
return null; |
|||
}, []); |
|||
|
|||
const handleTransferParams = async () => { |
|||
let from = window.ethereum.selectedAddress; |
|||
let toAddress = userInfo.deposit_address; |
|||
let contractAddress = currentCoin.address; |
|||
if (!provider) { |
|||
Toast.info('請檢查網絡是否正常'); |
|||
return -1 |
|||
} |
|||
if (!inputRef.current) { |
|||
Toast.info('請稍後重試'); |
|||
return -1 |
|||
} |
|||
let value = inputRef.current.value; |
|||
if (!value) { |
|||
Toast.info('請輸入數量'); |
|||
return -1 |
|||
} |
|||
let _contract = IERC20__factory.connect(contractAddress as string, provider); |
|||
|
|||
// 判断 gas 余额
|
|||
let eth = await provider.getBalance(from) |
|||
const needGas = toWei("0.01") |
|||
|
|||
if (eth.lt(needGas)) { |
|||
Toast.info('Gas 費不足 0.01'); |
|||
return -1 |
|||
} |
|||
|
|||
// 判断代币余额
|
|||
let balanceToken = await _contract.balanceOf(from) |
|||
let currToken = toWei(value) |
|||
|
|||
if (balanceToken.lt(currToken)) { |
|||
Toast.info('Token 餘額不足'); |
|||
return -1 |
|||
} |
|||
|
|||
let { to, data } = await _contract.populateTransaction.transfer(toAddress, toWei(value)); |
|||
let requestData = { |
|||
from, |
|||
to, |
|||
data, |
|||
value: '0x0' |
|||
}; |
|||
return requestData; |
|||
}; |
|||
|
|||
const handleExchange = async () => { |
|||
if (!provider || loading) return; |
|||
let value = inputRef.current?.value; |
|||
if (!value) { |
|||
Toast.info('請輸入數量'); |
|||
return; |
|||
}; |
|||
|
|||
setLoading(true); |
|||
try { |
|||
let isNode = await switchNetWork(); |
|||
if (!isNode) return; |
|||
let data = await handleTransferParams(); |
|||
if (data == -1) { |
|||
// Toast.info('请检查网络是否正常');
|
|||
setLoading(false); |
|||
return; |
|||
} |
|||
|
|||
let txHash = await window.ethereum.request({ |
|||
method: 'eth_sendTransaction', |
|||
params: [ |
|||
data |
|||
] |
|||
}); |
|||
let tx = await provider.getTransaction(txHash); |
|||
let { status } = await tx.wait(); |
|||
setLoading(false); |
|||
if (status === 1) { |
|||
Toast.success('充值成功'); |
|||
setTimeout(() => { |
|||
push(-1) |
|||
}, 1000) |
|||
} else { |
|||
Toast.fail('充值失敗'); |
|||
} |
|||
} catch (error) { |
|||
setLoading(false); |
|||
} |
|||
}; |
|||
|
|||
|
|||
return ( |
|||
<div className='recharge plr-2'> |
|||
<BackBar title='充值' /> |
|||
<div className='container row-center mt-2'> |
|||
<div className='box plr-2 row-between' onClick={() => push('/choose')}> |
|||
<div className='row-items'> |
|||
{ |
|||
currentCoin && <img src={require(`~/assets/${currentCoin.symbol}.png`)} alt="" /> |
|||
} |
|||
<div className='fz-wb-550 ml-1'>{currentCoin && currentCoin.symbol}</div> |
|||
</div> |
|||
<div> |
|||
<i className='iconfont icon-arrow-right-bold'></i> |
|||
</div> |
|||
</div> |
|||
<div className='box-img row-center'> |
|||
<i className='iconfont icon-datijilu fz-22'></i> |
|||
</div> |
|||
</div> |
|||
<div className='mt-2'> |
|||
<div className='white-bg p-2 r-1'> |
|||
<div className='fz-14'>主網</div> |
|||
<div className='mt-1 fz-wb-550'>BNB Smart Chain(BEP20)</div> |
|||
</div> |
|||
<div className='mt-2 white-bg r-1 p-2'> |
|||
<div className='fz-14' style={{ color: '#828284' }}>數量</div> |
|||
<div className='mt-1 input-box plr-1'> |
|||
<input type="number" placeholder='請輸入數量' ref={inputRef} /> |
|||
<div className='row-items'> |
|||
{ |
|||
currentCoin && <img src={require(`~/assets/${currentCoin.symbol}.png`)} alt="" /> |
|||
} |
|||
<div className='ml-5px'>{currentCoin && currentCoin.symbol}</div> |
|||
{/* <div className='primary-color ml-5px'>最大</div> */} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div className='mt-3'> |
|||
<Button className='button' onClick={handleExchange} loading={loading} loadingType="ball" >確認</Button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
export default observer(Recharge) |
@ -0,0 +1,303 @@ |
|||
import { useEffect, useMemo, useState } from "react"; |
|||
import useCopyLink from "~/hooks/useCopy"; |
|||
import { getTime, splitAddress } from "~/utils"; |
|||
import store from "~/store"; |
|||
import { observer } from "mobx-react"; |
|||
import { useRouter } from "~/hooks/useRouter"; |
|||
import BackBar from "~/components/BackBar"; |
|||
import { Cell, Empty, List, Tabs } from "react-vant"; |
|||
import { debounce } from 'lodash'; |
|||
import '~/styles/personal.scss'; |
|||
|
|||
const Record = () => { |
|||
|
|||
const { token } = store.state; |
|||
const recordTabs = useMemo(() => ['充值', '提现', '收益'], []); |
|||
const [recordIndex, setRecordIndex] = useState(0); |
|||
const { copyVal } = useCopyLink(); |
|||
const { push } = useRouter(); |
|||
const [query, setQuery] = useState([ |
|||
{ page: 1, page_size: 20 }, |
|||
{ page: 1, page_size: 20 }, |
|||
{ page: 1, page_size: 20 }, |
|||
]); |
|||
const [finished, setFinished] = useState<boolean[]>([true, true, true]); |
|||
const [assetsRecord, setAssetsRecord] = useState([ |
|||
[] as any[], |
|||
[] as any[], |
|||
[] as any[], |
|||
]); |
|||
|
|||
const getAssetsRecord = debounce(async () => { |
|||
|
|||
// let res: any = await assets_record({ type: recordIndex + 1, ...query[recordIndex] });
|
|||
let res: any = {}; |
|||
if (res.code === 0) { |
|||
if (res.data.length < 20) { |
|||
if (assetsRecord[recordIndex].length <= 0) { |
|||
assetsRecord[recordIndex] = res.data |
|||
} else { |
|||
assetsRecord[recordIndex] = [...assetsRecord[recordIndex], ...res.data] |
|||
} |
|||
finished[recordIndex] = true |
|||
setFinished([...finished]); |
|||
setAssetsRecord([...assetsRecord]); |
|||
return |
|||
} |
|||
query[recordIndex].page = query[recordIndex].page + 1 |
|||
if (assetsRecord[recordIndex].length <= 0) { |
|||
assetsRecord[recordIndex] = res.data |
|||
} else { |
|||
assetsRecord[recordIndex] = [...assetsRecord[recordIndex], ...res.data] |
|||
}; |
|||
finished[recordIndex] = false; |
|||
setFinished([...finished]); |
|||
setAssetsRecord([...assetsRecord]); |
|||
setQuery([...query]); |
|||
}; |
|||
}, 200); |
|||
|
|||
const renderItem = (index: number) => { |
|||
let el = [ |
|||
<RechargeRecord list={assetsRecord[recordIndex]} copy={copyVal} finished={finished[recordIndex]} getData={getAssetsRecord} />, |
|||
<WithdrawRecord list={assetsRecord[recordIndex]} copy={copyVal} finished={finished[recordIndex]} getData={getAssetsRecord} />, |
|||
<TransferRecord list={assetsRecord[recordIndex]} finished={finished[recordIndex]} getData={getAssetsRecord} />, |
|||
<OrderRecord list={assetsRecord[recordIndex]} finished={finished[recordIndex]} getData={getAssetsRecord} />, |
|||
<ProfitPositionRecord list={assetsRecord[recordIndex]} finished={finished[recordIndex]} getData={getAssetsRecord} />, |
|||
<MonthlyFeeRecord list={assetsRecord[recordIndex]} finished={finished[recordIndex]} getData={getAssetsRecord} /> |
|||
]; |
|||
return el[index]; |
|||
}; |
|||
|
|||
useEffect(() => { |
|||
// token && assetsRecord[recordIndex].length <= 0 && getAssetsRecord();
|
|||
// !token && push('/', null, true);
|
|||
// !token && setFinished([true, true, true, true, true, true]);
|
|||
}, [recordIndex, token]); |
|||
|
|||
|
|||
return ( |
|||
<div className="plr-2 record"> |
|||
<BackBar |
|||
title='账单' |
|||
/> |
|||
<Tabs |
|||
swipeable |
|||
type="capsule" |
|||
background="rgb(248,247,255)" |
|||
sticky |
|||
offsetTop={window.innerWidth / 430 * 60} |
|||
onChange={(_, index) => setRecordIndex(index)} |
|||
align="start" |
|||
className="tabs" |
|||
lazyRender |
|||
> |
|||
{ |
|||
recordTabs.map((item, index) => ( |
|||
<Tabs.TabPane |
|||
key={index} |
|||
title={item} |
|||
titleStyle={{ width: 70, height: 30, padding: 0 }} |
|||
> |
|||
{renderItem(index)} |
|||
</Tabs.TabPane> |
|||
)) |
|||
} |
|||
</Tabs> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
interface ChildProps { |
|||
list: any[], |
|||
copy?: Function, |
|||
finished: boolean, |
|||
getData: Function |
|||
} |
|||
|
|||
const RechargeRecord = ( |
|||
{ list, copy, finished, getData }: ChildProps |
|||
) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map(item => ( |
|||
<Cell key={item.id} className="ptb-1"> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|||
<div> |
|||
<div className='fz-wb-550'>{item.status === -3 ? '激活赠送' : '充值'}</div> |
|||
<div className='sub-color fz-14 mt-6px'>{getTime(item.time * 1000)}</div> |
|||
<div className='sub-color fz-14'> |
|||
交易哈希:{splitAddress(item.order, 10)} |
|||
<i className='iconfont icon-fuzhi ml-5px' onClick={() => copy && copy(item.order)}></i> |
|||
</div> |
|||
</div> |
|||
<div className='column-justify-between tae'> |
|||
<div className='green-color'>+{item.amount} {item.symbol}</div> |
|||
<div |
|||
className={`${item.status >= 0 ? 'blue-color' : 'red-color'}`} |
|||
> |
|||
{item.status !== -3 && (item.status === 3 ? '完成' : item.type >= 0 ? '确认中' : '失败')} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
) |
|||
} |
|||
|
|||
const WithdrawRecord = ({ list, finished, getData, copy }: ChildProps) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map((item, index) => ( |
|||
<Cell className='ptb-1' key={item.id}> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|||
<div> |
|||
<div className='fz-wb-550'>提现</div> |
|||
<div className='fz-wb-550'>手续费</div> |
|||
<div className='sub-color fz-14'>{getTime(item.time * 1000)}</div> |
|||
<div className='sub-color fz-14'> |
|||
交易哈希:{item.order && splitAddress(item.order, 10)} |
|||
{item.order && <i className='iconfont icon-fuzhi ml-5px' onClick={() => { |
|||
copy && copy(item.order) |
|||
}}></i>} |
|||
</div> |
|||
</div> |
|||
<div className='column-justify-between tae'> |
|||
<div className='red-color'> |
|||
<div>{item.amount} {item.symbol}</div> |
|||
<div>{item.amount_fee} {item.symbol_fee}</div> |
|||
</div> |
|||
<div className='blue-color'>{item.status === 5 ? '完成' : '审核中'}</div> |
|||
</div> |
|||
</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
|
|||
) |
|||
} |
|||
|
|||
const TransferRecord = ({ list, finished, getData }: ChildProps) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map((item, index) => ( |
|||
<Cell className="ptb-1" key={item.id}> |
|||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|||
<div> |
|||
<div className='fz-wb-550'>划转 {item.name}</div> |
|||
<div className='fz-wb-550'>手续费</div> |
|||
<div className='sub-color fz-14 mt-6px'>{getTime(item.time * 1000)}</div> |
|||
</div> |
|||
<div className='column-justify-between tae'> |
|||
<div> |
|||
<div className={Number(item.amount) < 0 ? 'red-color' : 'green-color'}>{Number(item.amount) >= 0 && '+'}{item.amount} {item.symbol}</div> |
|||
<div className='red-color'>{item.amount_fee} {item.symbol_fee}</div> |
|||
</div> |
|||
<div className='blue-color'>完成</div> |
|||
</div> |
|||
</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
) |
|||
} |
|||
|
|||
const OrderRecord = ( |
|||
{ list, finished, getData }: ChildProps |
|||
) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<> |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map(item => ( |
|||
<Cell className="ptb-1" key={item.id}> |
|||
<div className="row-between"> |
|||
<div className="fz-14">ID {item.order}</div> |
|||
<div className="sub-color fz-14">{getTime(item.time * 1000)}</div> |
|||
</div> |
|||
<div className="row-between mt-6px fz-wb-550"> |
|||
<div>{item.type === 1 ? '主单盈亏' : '对冲单盈亏'}</div> |
|||
<div className={Number(item.amount) >= 0 ? "green-color" : 'red-color'}>{Number(item.amount) >= 0 && '+'}{item.amount} {item.symbol}</div> |
|||
</div> |
|||
<div className="row-between mt-6px fz-wb-550"> |
|||
<div>保险赔付</div> |
|||
<div className={Number(item.rebate_amount) >= 0 ? "green-color" : 'red-color'}>{Number(item.rebate_amount) >= 0 && '+'}{item.rebate_amount} {item.symbol}</div> |
|||
</div> |
|||
<div className="row-between mt-6px fz-wb-550"> |
|||
<div>结算费</div> |
|||
<div className="red-color">{item.settle_fee} {item.symbol_fee}</div> |
|||
</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
</> |
|||
) |
|||
} |
|||
|
|||
const ProfitPositionRecord = ({ list, getData, finished }: ChildProps) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map(item => ( |
|||
<Cell className="ptb-1" key={item.id}> |
|||
<div className="row-between"> |
|||
<div className="fz-14">ID {item.order}</div> |
|||
<div className="sub-color fz-14">{getTime(item.time * 1000)}</div> |
|||
</div> |
|||
<div className="row-between mt-6px fz-wb-550"> |
|||
<div>{item.name}</div> |
|||
<div className="green-color">{Number(item.amount) >= 0 && '+'}{item.amount} {item.symbol}</div> |
|||
</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
) |
|||
} |
|||
|
|||
const MonthlyFeeRecord = ({ list, finished, getData }: ChildProps) => { |
|||
|
|||
if (list.length <= 0 || Object.keys(list).length <= 0) return <Empty description="暂无记录" />; |
|||
|
|||
return ( |
|||
<List finished={finished} onLoad={() => getData()} errorText="请求失败,点击重新加载" offset={10}> |
|||
{ |
|||
list.map(item => ( |
|||
<Cell className="ptb-1" key={item.id}> |
|||
<div className="row-between fz-wb-550"> |
|||
<div>{item.name}</div> |
|||
<div className="red-color">{Number(item.amount) >= 0 && '+'}{item.amount} {item.symbol}</div> |
|||
</div> |
|||
<div className="fz-14 sub-color">{getTime(item.time * 1000)}</div> |
|||
</Cell> |
|||
)) |
|||
} |
|||
</List> |
|||
) |
|||
} |
|||
|
|||
|
|||
export default observer(Record); |
@ -0,0 +1,76 @@ |
|||
import '~/styles/recharge.scss' |
|||
import { observer } from 'mobx-react' |
|||
import store from '../../store' |
|||
import { useMemo, useRef, useState } from 'react' |
|||
import { useRouter } from '../../hooks/useRouter' |
|||
import { Button } from 'react-vant' |
|||
import BackBar from '~/components/BackBar' |
|||
|
|||
const Recharge = () => { |
|||
|
|||
const { coinIndex, coinList } = store.state |
|||
const { push } = useRouter() |
|||
const inputRef = useRef<HTMLInputElement>(null); |
|||
const currentCoin = useMemo(() => coinList[coinIndex], [coinIndex, coinList]) |
|||
const [loading, setLoading] = useState(false); |
|||
|
|||
return ( |
|||
<div className='recharge plr-2'> |
|||
<BackBar title='提现' /> |
|||
<div className='container row-center mt-2'> |
|||
<div className='box plr-2 row-between' onClick={() => push('/choose')}> |
|||
<div className='row-items'> |
|||
{ |
|||
currentCoin && <img src={require(`~/assets/${currentCoin.symbol}.png`)} alt="" /> |
|||
} |
|||
<div className='fz-wb-550 ml-1'>{currentCoin && currentCoin.symbol}</div> |
|||
</div> |
|||
<div> |
|||
<i className='iconfont icon-arrow-right-bold'></i> |
|||
</div> |
|||
</div> |
|||
<div className='box-img row-center'> |
|||
<i className='iconfont icon-datijilu fz-22'></i> |
|||
</div> |
|||
</div> |
|||
<div className='mt-2'> |
|||
|
|||
<div className='mt-2 white-bg r-1 p-2'> |
|||
<div className='fz-14'>提现地址</div> |
|||
<div className='mt-1 input-box plr-1'> |
|||
<div className='fz-14'>0xasdasd;lasdljaslkdjklasdjlkasjdlk</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div className='white-bg p-2 r-1 mt-2'> |
|||
<div className='fz-14'>主網</div> |
|||
<div className='mt-1 fz-wb-550'>BNB Smart Chain(BEP20)</div> |
|||
</div> |
|||
|
|||
|
|||
<div className='mt-2 white-bg r-1 p-2'> |
|||
<div className='fz-14'>数量</div> |
|||
<div className='mt-1 input-box plr-1'> |
|||
<input /> |
|||
<div className='row-items'> |
|||
<div className='ml-1 fz-14'>FIL</div> |
|||
<div className='ml-2 fz-14 primary'>最大</div> |
|||
</div> |
|||
</div> |
|||
<div className='tar sub-text fz-14 mt-5px'>可用余额:0 USDT</div> |
|||
</div> |
|||
|
|||
<div className='mt-2 fz-14'> |
|||
<div>手续费</div> |
|||
<div className='mt-5px'>0.1000 FIL</div> |
|||
</div> |
|||
|
|||
<div className='mt-3'> |
|||
<Button className='button' loading={loading} loadingType="ball" >提现</Button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
export default observer(Recharge) |
@ -1,60 +1,56 @@ |
|||
.cart{ |
|||
|
|||
.cover{ |
|||
@include img-size(170px,170px) |
|||
} |
|||
.personal{ |
|||
|
|||
.box{ |
|||
height: 151px; |
|||
width: 100%; |
|||
background-color: $white; |
|||
box-shadow: 8px 8px 20px 0px rgba(0, 0, 0, 0.1); |
|||
border-top-right-radius: 10px; |
|||
border-bottom-right-radius: 10px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: calc($height - 60px); |
|||
|
|||
.price-tag{ |
|||
padding: 0px 8px; |
|||
height: 18px; |
|||
.account-assets{ |
|||
.card{ |
|||
width: 100%; |
|||
border-radius: 10px; |
|||
height: 174px; |
|||
background-color: $white; |
|||
padding: 20px 30px; |
|||
display: flex; |
|||
align-items: center; |
|||
background: linear-gradient(114deg, #320D6D 0%, #8A4CED 108%); |
|||
color: $white; |
|||
border-radius: 50px; |
|||
font-size: 12px; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
color: $black; |
|||
} |
|||
|
|||
.user-tag{ |
|||
padding: 0px 8px 0px 0px; |
|||
height: 18px; |
|||
|
|||
.menu{ |
|||
display: flex; |
|||
align-items: center; |
|||
background-color: #F1F1F1; |
|||
border-radius: 50px; |
|||
font-size: 12px; |
|||
.img{ |
|||
@include img-size(15px,15px); |
|||
border-radius:8px |
|||
justify-content: space-between; |
|||
text-align: center; |
|||
img{ |
|||
@include img-size(40px,40px) |
|||
} |
|||
} |
|||
} |
|||
|
|||
.timing-box{ |
|||
width: 85px; |
|||
height: 20px; |
|||
border-radius: 20px; |
|||
background-color: #f1f1f1; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
.assets-box{ |
|||
height: 100%; |
|||
width: 100%; |
|||
flex: 1; |
|||
height: 100%; |
|||
border-radius: 25px 25px 0px 0px; |
|||
background-color: $white; |
|||
overflow: hidden; |
|||
overflow-y: scroll; |
|||
padding: 20px; |
|||
|
|||
.delete{ |
|||
width: 22px; |
|||
height: 22px; |
|||
border-radius: 12px; |
|||
background-color: #f1f1f1; |
|||
color:#F96900; |
|||
.symbol-img{ |
|||
@include img-size(24px,24px) |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
.record{ |
|||
.tabs{ |
|||
padding: 10px 0px; |
|||
.rv-tabs__nav--capsule .rv-tab.rv-tab--active .rv-tab__text { |
|||
background-color: #EAEAEA; |
|||
color: #727272; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,71 @@ |
|||
.recharge{ |
|||
.container{ |
|||
|
|||
.box{ |
|||
flex:1; |
|||
width: 100%; |
|||
height: 48px; |
|||
background-color: $white; |
|||
border-radius: 10px; |
|||
img{ |
|||
width: 20px; |
|||
height: 20px; |
|||
object-fit: cover; |
|||
} |
|||
} |
|||
.box-img{ |
|||
width: 48px; |
|||
height: 48px; |
|||
background-color: $white; |
|||
border-radius: 10px; |
|||
margin-left: 10px; |
|||
} |
|||
} |
|||
|
|||
.input-box{ |
|||
width: 100%; |
|||
height: 50px; |
|||
border-radius: 10px; |
|||
display: flex; |
|||
border: 1px solid #898989; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
white-space: nowrap; |
|||
|
|||
input{ |
|||
border: none; |
|||
background: none; |
|||
width: 100%; |
|||
} |
|||
|
|||
img{ |
|||
width: 20px; |
|||
height: 20px; |
|||
object-fit: cover; |
|||
margin-left: 10px; |
|||
} |
|||
} |
|||
|
|||
.border{ |
|||
width: 100%; |
|||
padding: 13px; |
|||
border: 1px solid #434343; |
|||
border-radius: 10px; |
|||
overflow: hidden; |
|||
overflow-x: scroll; |
|||
&::-webkit-scrollbar{ |
|||
display: none; |
|||
} |
|||
} |
|||
|
|||
.r-1{ |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
.button{ |
|||
width: 100%; |
|||
height: 53px; |
|||
background-color: $primary; |
|||
border-radius: 16px; |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
|
|||
export function copy(value: string, cb: Function) { |
|||
// 动态创建 textarea 标签
|
|||
const textarea: any = document.createElement('textarea') |
|||
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
|
|||
textarea.readOnly = 'readonly' |
|||
textarea.style.position = 'absolute' |
|||
textarea.style.left = '-9999px' |
|||
// 将要 copy 的值赋给 textarea 标签的 value 属性
|
|||
// 网上有些例子是赋值给innerText,这样也会赋值成功,但是识别不了\r\n的换行符,赋值给value属性就可以
|
|||
textarea.value = value |
|||
// 将 textarea 插入到 body 中
|
|||
document.body.appendChild(textarea) |
|||
// 选中值并复制
|
|||
textarea.select() |
|||
textarea.setSelectionRange(0, textarea.value.length) |
|||
document.execCommand('Copy') |
|||
document.body.removeChild(textarea) |
|||
if (cb && Object.prototype.toString.call(cb) === '[object Function]') { |
|||
cb() |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
import { BigNumberish, ethers, BigNumber } from "ethers"; |
|||
|
|||
export const wei = { |
|||
Zero: BigNumber.from(0), |
|||
MaxUint256: BigNumber.from("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ), |
|||
MinInt256: BigNumber.from("-0x8000000000000000000000000000000000000000000000000000000000000000"), |
|||
MaxInt256: BigNumber.from("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
AddressZero: "0x0000000000000000000000000000000000000000", |
|||
} as any; |
|||
|
|||
export const toWei = (value: string) => { |
|||
return ethers.utils.parseUnits(value, 18); |
|||
}; |
|||
|
|||
export const toBig = (value: string) => { |
|||
return BigNumber.from(value); |
|||
}; |
|||
|
|||
export const toString = (value: BigNumberish, int?: number) => { |
|||
return ethers.utils.formatUnits(value, int || 18); |
|||
}; |