🐞 fix:
This commit is contained in:
parent
f6cd16f1c6
commit
aff0f68989
|
@ -1,12 +1,13 @@
|
|||
###
|
||||
# @LastEditors: John
|
||||
# @Date: 2024-06-18 10:12:21
|
||||
# @LastEditTime: 2024-06-27 15:35:23
|
||||
# @LastEditTime: 2024-07-02 16:46:51
|
||||
# @Author: John
|
||||
###
|
||||
VITE_BASE_URL=
|
||||
VITE_BASE_API_URL=/dev
|
||||
VITE_PARTICIPATE_CHAIN_ID=97
|
||||
VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8
|
||||
VITE_RECEIVE_RAMB_CONTRACT_ADDRESS=0x8291A98382d751CdD52460A547eE94ceE8258930
|
||||
VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63
|
||||
VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/
|
|
@ -1,12 +1,13 @@
|
|||
###
|
||||
# @LastEditors: John
|
||||
# @Date: 2024-06-24 18:38:45
|
||||
# @LastEditTime: 2024-06-25 14:04:37
|
||||
# @LastEditTime: 2024-07-02 16:49:31
|
||||
# @Author: John
|
||||
###
|
||||
VITE_BASE_URL=http://wwwtest.exgo.pro
|
||||
VITE_BASE_API_URL=http://wwwtest.exgo.pro
|
||||
VITE_PARTICIPATE_CHAIN_ID=97
|
||||
VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8
|
||||
VITE_RECEIVE_RAMB_CONTRACT_ADDRESS=0x8291A98382d751CdD52460A547eE94ceE8258930
|
||||
VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63
|
||||
VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"symbol_url": "//at.alicdn.com/t/c/font_4589567_vzk80gocu8s.js",
|
||||
"symbol_url": "//at.alicdn.com/t/c/font_4589567_u5yhe33hzt.js",
|
||||
"use_typescript": true,
|
||||
"save_dir": "./src/components/iconfont",
|
||||
"trim_icon_prefix": "icon",
|
||||
|
|
|
@ -19,7 +19,7 @@ import InvitationList from "./pages/InvitationList";
|
|||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useUserStore from "./store/User";
|
||||
import { getUrlQueryParam } from "./utils";
|
||||
import { getUrlParameterByName } from "./utils";
|
||||
import { UrlQueryParamsKey } from "./constants";
|
||||
import { signAndLogin } from "./utils/wallet";
|
||||
import { useAccount } from "wagmi";
|
||||
|
@ -29,7 +29,9 @@ function App() {
|
|||
const { address } = useAccount();
|
||||
useEffect(() => {
|
||||
i18n.changeLanguage(currantLang);
|
||||
UpdateInviteCode(getUrlQueryParam(UrlQueryParamsKey.INVITE_CODE) || "");
|
||||
UpdateInviteCode(
|
||||
getUrlParameterByName(UrlQueryParamsKey.INVITE_CODE) || ""
|
||||
);
|
||||
return () => {};
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import React, { CSSProperties, SVGAttributes, FunctionComponent } from 'react';
|
||||
import { getIconColor } from './helper';
|
||||
|
||||
interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
|
||||
size?: number;
|
||||
color?: string | string[];
|
||||
}
|
||||
|
||||
const DEFAULT_STYLE: CSSProperties = {
|
||||
display: 'block',
|
||||
};
|
||||
|
||||
const IconTransfer: FunctionComponent<Props> = ({ size = 18, color, style: _style, ...rest }) => {
|
||||
const style = _style ? { ...DEFAULT_STYLE, ..._style } : DEFAULT_STYLE;
|
||||
|
||||
return (
|
||||
<svg viewBox="0 0 1024 1024" width={size + 'px'} height={size + 'px'} style={style} {...rest}>
|
||||
<path
|
||||
d="M85.346462 170.653538c0-47.104 38.203077-85.307077 85.307076-85.307076H512c47.143385 0 85.346462 38.203077 85.346462 85.307076v170.692924c0 47.104-38.203077 85.307077-85.346462 85.307076H170.653538a85.346462 85.346462 0 0 1-85.307076-85.307076V170.653538zM426.653538 682.653538c0-47.104 38.203077-85.307077 85.346462-85.307076h341.346462c47.104 0 85.307077 38.203077 85.307076 85.307076v170.692924c0 47.104-38.203077 85.307077-85.307076 85.307076H512a85.346462 85.346462 0 0 1-85.346462-85.307076v-170.692924z"
|
||||
fill={getIconColor(color, 0, '#666666')}
|
||||
/>
|
||||
<path
|
||||
d="M879.064615 287.980308l-30.72 30.72a32.019692 32.019692 0 0 0 45.292308 45.292307l55.138462-55.177846c29.184-29.144615 29.184-76.445538 0-105.629538l-55.138462-55.138462a32.019692 32.019692 0 0 0-45.292308 45.252923l30.72 30.72h-196.411077a32.019692 32.019692 0 0 0 0 63.960616h196.450462zM144.935385 799.980308l30.72 30.72a32.019692 32.019692 0 0 1-45.292308 45.292307l-55.138462-55.177846c-29.184-29.144615-29.184-76.445538 0-105.629538l55.138462-55.138462a32.019692 32.019692 0 0 1 45.292308 45.252923l-30.72 30.72h196.411077a32.019692 32.019692 0 0 1 0 63.960616H144.896z"
|
||||
fill={getIconColor(color, 1, '#FFFFFF')}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconTransfer;
|
|
@ -2,6 +2,7 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import React, { SVGAttributes, FunctionComponent } from 'react';
|
||||
import IconTransfer from './IconTransfer';
|
||||
import IconDiqiu from './IconDiqiu';
|
||||
import IconTuichu from './IconTuichu';
|
||||
import IconChevronsrightshuangyoujiantou from './IconChevronsrightshuangyoujiantou';
|
||||
|
@ -11,6 +12,7 @@ import IconTongdun from './IconTongdun';
|
|||
import IconJindun from './IconJindun';
|
||||
import IconXingdun from './IconXingdun';
|
||||
import IconGuanjun from './IconGuanjun';
|
||||
export { default as IconTransfer } from './IconTransfer';
|
||||
export { default as IconDiqiu } from './IconDiqiu';
|
||||
export { default as IconTuichu } from './IconTuichu';
|
||||
export { default as IconChevronsrightshuangyoujiantou } from './IconChevronsrightshuangyoujiantou';
|
||||
|
@ -21,7 +23,7 @@ export { default as IconJindun } from './IconJindun';
|
|||
export { default as IconXingdun } from './IconXingdun';
|
||||
export { default as IconGuanjun } from './IconGuanjun';
|
||||
|
||||
export type IconNames = 'diqiu' | 'tuichu' | 'chevronsrightshuangyoujiantou' | 'fuzhi' | 'icon_arrow_left' | 'tongdun' | 'jindun' | 'xingdun' | 'guanjun';
|
||||
export type IconNames = 'transfer' | 'diqiu' | 'tuichu' | 'chevronsrightshuangyoujiantou' | 'fuzhi' | 'icon_arrow_left' | 'tongdun' | 'jindun' | 'xingdun' | 'guanjun';
|
||||
|
||||
interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
|
||||
name: IconNames;
|
||||
|
@ -31,6 +33,8 @@ interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
|
|||
|
||||
const IconFont: FunctionComponent<Props> = ({ name, ...rest }) => {
|
||||
switch (name) {
|
||||
case 'transfer':
|
||||
return <IconTransfer {...rest} />;
|
||||
case 'diqiu':
|
||||
return <IconDiqiu {...rest} />;
|
||||
case 'tuichu':
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "payAddr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableInvalidOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableUnauthorizedAccount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "paymentTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "orderId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "hashStr",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "reward",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "buyAddr",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "orderId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RewardSuccess",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "addr",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setUSDCAddress",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "usdc",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract IERC20",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-19 15:48:57
|
||||
* @LastEditTime: 2024-06-27 18:00:07
|
||||
* @LastEditTime: 2024-07-02 17:40:49
|
||||
* @Author: John
|
||||
*/
|
||||
import { config } from "@/components/WalletProvider";
|
||||
|
@ -16,8 +16,10 @@ import { encodeFunctionData } from "viem/utils";
|
|||
import erc20Abi from "@/contract/abi/erc20abi.json";
|
||||
import usdtAbi from "@/contract/abi/USDT.json";
|
||||
import RedDevilsAbi from "@/contract/abi/RedDevils.json";
|
||||
import receiveAbi from "@/contract/abi/receive.json";
|
||||
import i18next from "i18next";
|
||||
import { BaseError } from "wagmi";
|
||||
import { UserIncome } from "@/server/module";
|
||||
|
||||
/**
|
||||
* @description 获取代币余额
|
||||
|
@ -270,19 +272,76 @@ export async function upGradeByContract(amount: bigint, orderID: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* receiveByContract
|
||||
* receiveRMABByContract
|
||||
* @param amount
|
||||
* @param paymentTime
|
||||
* @param orderID
|
||||
* @param hashStr
|
||||
* @returns
|
||||
*/
|
||||
export async function receiveByContract(
|
||||
export async function receiveRMABByContract(
|
||||
amount: bigint,
|
||||
paymentTime: number,
|
||||
orderID: string,
|
||||
hashStr: string
|
||||
) {
|
||||
console.log("pay buy contract params", { amount, orderID });
|
||||
|
||||
return new Promise<string>(async (reslove, reject) => {
|
||||
try {
|
||||
console.log("参数:", amount, paymentTime, orderID, hashStr);
|
||||
estimateGas(config, {
|
||||
to: import.meta.env.VITE_RECEIVE_RAMB_CONTRACT_ADDRESS,
|
||||
data: encodeFunctionData({
|
||||
abi: receiveAbi,
|
||||
functionName: "reward",
|
||||
args: [amount, paymentTime, orderID, hashStr],
|
||||
}),
|
||||
})
|
||||
.then((gas) => {
|
||||
const gasPrice = (gas * 12n) / 10n;
|
||||
console.log("estimate gas:%d , my gas: %d", gas, gasPrice);
|
||||
writeContract(config, {
|
||||
abi: receiveAbi,
|
||||
address: import.meta.env.VITE_PURCHASED_CONTRACT_ADDRESS,
|
||||
functionName: "reward",
|
||||
args: [amount, paymentTime, orderID, hashStr],
|
||||
gas: gasPrice,
|
||||
})
|
||||
.then((receipt) => {
|
||||
console.log("write contract success!, receipt:", receipt);
|
||||
reslove(receipt);
|
||||
})
|
||||
.catch((err: BaseError) => {
|
||||
console.log("reward rmab Transaction err", err);
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
.catch((err: BaseError) => {
|
||||
console.log("reward rmab estimateGas err", err);
|
||||
reject(err);
|
||||
});
|
||||
} catch (err) {
|
||||
reject(new BaseError(`${err}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* receiveUSDTByContract
|
||||
* @param amount
|
||||
* @param paymentTime
|
||||
* @param orderID
|
||||
* @param hashStr
|
||||
* @returns
|
||||
*/
|
||||
export async function receiveUSDTByContract(
|
||||
amount: bigint,
|
||||
paymentTime: number,
|
||||
orderID: string,
|
||||
hashStr: string
|
||||
) {
|
||||
console.log("pay buy contract params", { amount, orderID });
|
||||
console.log("NETWORK_USDT:", import.meta.env.VITE_NETWORK_USDT_ADDRESS);
|
||||
|
||||
return new Promise<string>(async (reslove, reject) => {
|
||||
try {
|
||||
|
@ -323,3 +382,26 @@ export async function receiveByContract(
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* receiveByContract
|
||||
* @param type
|
||||
* @param amount
|
||||
* @param paymentTime
|
||||
* @param orderID
|
||||
* @param hashStr
|
||||
* @returns
|
||||
*/
|
||||
export async function receiveByContract(
|
||||
type: UserIncome["coinId"],
|
||||
amount: bigint,
|
||||
paymentTime: number,
|
||||
orderID: string,
|
||||
hashStr: string
|
||||
) {
|
||||
if (type == 1) {
|
||||
return receiveUSDTByContract(amount, paymentTime, orderID, hashStr);
|
||||
} else if (type == 2) {
|
||||
return receiveRMABByContract(amount, paymentTime, orderID, hashStr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,5 +104,7 @@
|
|||
"没有更多数据了": "没有更多数据了",
|
||||
"升级中": "升级中",
|
||||
"无等级": "无等级",
|
||||
"无效的邀请链接": "无效的邀请链接"
|
||||
"无效的邀请链接": "无效的邀请链接",
|
||||
|
||||
"交易红魔股权NFT": "交易红魔股权NFT"
|
||||
}
|
||||
|
|
|
@ -104,5 +104,6 @@
|
|||
"没有更多数据了": "Keine weiteren Daten",
|
||||
"升级中": "Wird aktualisiert",
|
||||
"无等级": "Keine Bewertung",
|
||||
"无效的邀请链接": "Ungültiger Einladungslink"
|
||||
"无效的邀请链接": "Ungültiger Einladungslink",
|
||||
"交易红魔股权NFT": "Handel mit Red Devil Equity NFT"
|
||||
}
|
||||
|
|
|
@ -104,5 +104,6 @@
|
|||
"没有更多数据了": "No more data",
|
||||
"升级中": "Upgrading",
|
||||
"无等级": "No Grade",
|
||||
"无效的邀请链接": "Invalid invitation link"
|
||||
"无效的邀请链接": "Invalid invitation link",
|
||||
"交易红魔股权NFT": "Trade Red Devil Equity NFT"
|
||||
}
|
||||
|
|
|
@ -104,5 +104,6 @@
|
|||
"没有更多数据了": "これ以上のデータはありません",
|
||||
"升级中": "アップグレード中",
|
||||
"无等级": "グレードなし",
|
||||
"无效的邀请链接": "無効な招待リンクです"
|
||||
"无效的邀请链接": "無効な招待リンクです",
|
||||
"交易红魔股权NFT": "レッドデビル株式NFTを取引する"
|
||||
}
|
||||
|
|
|
@ -104,5 +104,6 @@
|
|||
"没有更多数据了": "沒有更多數據了",
|
||||
"升级中": "升級中",
|
||||
"无等级": "無等級",
|
||||
"无效的邀请链接": "無效的邀請連結"
|
||||
"无效的邀请链接": "無效的邀請連結",
|
||||
"交易红魔股权NFT": "交易紅魔股權NFT"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-17 17:20:03
|
||||
* @LastEditTime: 2024-06-20 11:43:14
|
||||
* @LastEditTime: 2024-07-02 11:38:25
|
||||
* @Author: John
|
||||
*/
|
||||
import "@/i18n/init.ts";
|
||||
|
@ -15,9 +15,9 @@ import EventBusProvider from "./context/EventBusContext.tsx";
|
|||
import { WalletProvider } from "./components/WalletProvider.tsx";
|
||||
import flexible from "./utils/flexible.ts";
|
||||
import VConsole from "vconsole";
|
||||
import { getUrlQueryParam } from "./utils/index.ts";
|
||||
import { getUrlParameterByName } from "./utils/index.ts";
|
||||
|
||||
if (getUrlQueryParam("vconsole") === "1") {
|
||||
if (getUrlParameterByName("vconsole") === "1") {
|
||||
new VConsole();
|
||||
}
|
||||
flexible(window, document);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-18 17:57:13
|
||||
* @LastEditTime: 2024-06-25 16:17:20
|
||||
* @LastEditTime: 2024-07-02 17:43:52
|
||||
* @Author: John
|
||||
*/
|
||||
import Tabs from "antd-mobile/es/components/tabs";
|
||||
import classes from "./AssetRecord.module.css";
|
||||
import { cn, getUrlQueryParam } from "@/utils";
|
||||
import { cn, getUrlParameterByName } from "@/utils";
|
||||
import CapsuleTabs from "antd-mobile/es/components/capsule-tabs";
|
||||
import RecordsItem from "@/components/RecordsItem";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
@ -14,12 +14,11 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|||
import { api_pagling_query_income_record } from "@/server/api";
|
||||
import { IncomeRecord, IncomeRecordType } from "@/server/module";
|
||||
import { Empty, InfiniteScroll } from "antd-mobile";
|
||||
import { CoinName } from "@/constants";
|
||||
|
||||
export default function () {
|
||||
const { t } = useTranslation();
|
||||
const coinId = useMemo(() => getUrlQueryParam("id"), []);
|
||||
const coinName = useMemo(() => getUrlQueryParam("name"), []);
|
||||
const id = useMemo(() => getUrlParameterByName("id"), []);
|
||||
const coinId = useMemo(() => getUrlParameterByName("coinId"), []);
|
||||
const currentType = useRef<1 | 2>(2);
|
||||
const [issueRecords, setIssueRecords] = useState<IncomeRecord["records"]>([]);
|
||||
const [receiveRecord, setReceiveRecord] = useState<IncomeRecord["records"]>(
|
||||
|
@ -35,7 +34,7 @@ export default function () {
|
|||
|
||||
async function getRecord() {
|
||||
return new Promise<void>(async (reslove) => {
|
||||
if (!coinId) return;
|
||||
if (!id) return;
|
||||
|
||||
if (!hasMore.current) return;
|
||||
|
||||
|
@ -43,7 +42,7 @@ export default function () {
|
|||
pageNum.current++;
|
||||
const { data } = await api_pagling_query_income_record().send({
|
||||
queryParams: {
|
||||
id: coinId,
|
||||
id,
|
||||
type: currentType.current,
|
||||
pageNum: pageNum.current,
|
||||
pageSize,
|
||||
|
@ -91,7 +90,7 @@ export default function () {
|
|||
}}
|
||||
>
|
||||
<Tabs.Tab className={classes.tab} title={t("发放记录")} key="1">
|
||||
{coinName == CoinName.USDT && (
|
||||
{coinId == "1" && (
|
||||
<CapsuleTabs
|
||||
onChange={(key) => {
|
||||
switch (key) {
|
||||
|
@ -117,7 +116,7 @@ export default function () {
|
|||
</CapsuleTabs>
|
||||
)}
|
||||
|
||||
{coinName == CoinName.RMOB && (
|
||||
{coinId == "2" && (
|
||||
<CapsuleTabs
|
||||
onChange={(key) => {
|
||||
switch (key) {
|
||||
|
|
|
@ -204,7 +204,7 @@
|
|||
flex-direction: row;
|
||||
align-items: center;
|
||||
li {
|
||||
width: 76px;
|
||||
min-width: 76px;
|
||||
height: 34px;
|
||||
|
||||
opacity: 1;
|
||||
|
@ -220,6 +220,7 @@
|
|||
color: #4d4d4d;
|
||||
text-align: center;
|
||||
line-height: 34px;
|
||||
padding: 0 10px;
|
||||
&.nftToken_tab_active {
|
||||
border-radius: 10px;
|
||||
opacity: 1;
|
||||
|
@ -585,6 +586,43 @@
|
|||
}
|
||||
}
|
||||
|
||||
.equityNft {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 10px 15px;
|
||||
|
||||
border-radius: 14px;
|
||||
opacity: 1;
|
||||
background: #171719;
|
||||
margin-top: 26px;
|
||||
|
||||
> svg {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
|
||||
&:nth-of-type(2) {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
span {
|
||||
opacity: 1;
|
||||
|
||||
font-family: DM Sans;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #ffffff;
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.invite {
|
||||
margin-top: 25px;
|
||||
.invite_top {
|
||||
|
|
|
@ -10,17 +10,16 @@ import usdtBg from "@/assets/usdt_bg.svg";
|
|||
import RMOB_logo from "@/assets/RMOB_logo.svg";
|
||||
import IconFont from "@/components/iconfont";
|
||||
import { BaseError, useAccount } from "wagmi";
|
||||
import { config } from "@/components/WalletProvider";
|
||||
import { createSearchParams, useNavigate } from "react-router-dom";
|
||||
import { Button, Dialog, Empty, Toast } from "antd-mobile";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Dialog, Empty, PullToRefresh, Toast } from "antd-mobile";
|
||||
import { loginOut } from "@/utils/wallet";
|
||||
import { api_claim_income, api_get_homepage_user_data } from "@/server/api";
|
||||
import { UserHomeData } from "@/server/module";
|
||||
import { UserHomeData, UserIncome } from "@/server/module";
|
||||
import { UrlQueryParamsKey } from "@/constants";
|
||||
import { receiveByContract } from "@/contract/utils";
|
||||
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
|
||||
import { ToastHandler } from "antd-mobile/es/components/toast";
|
||||
import { disconnect, getAccount } from "@wagmi/core";
|
||||
import { PullStatus } from "antd-mobile/es/components/pull-to-refresh";
|
||||
export default function () {
|
||||
const { Token, UpdateToken } = useUserStore();
|
||||
const { open } = useWeb3Modal();
|
||||
|
@ -30,7 +29,12 @@ export default function () {
|
|||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const navigate = useNavigate();
|
||||
const [userData, setUserData] = useState<UserHomeData>();
|
||||
|
||||
const statusRecord: Record<PullStatus, string> = {
|
||||
pulling: "Pull down to refresh",
|
||||
canRelease: "Release to refresh immediately",
|
||||
refreshing: "Loading...",
|
||||
complete: "Refresh complete",
|
||||
};
|
||||
const userInviteLink = useMemo(
|
||||
() =>
|
||||
`${location.origin}/#/?${UrlQueryParamsKey.INVITE_CODE}=${
|
||||
|
@ -76,10 +80,23 @@ export default function () {
|
|||
|
||||
return (
|
||||
<>
|
||||
<PullToRefresh
|
||||
onRefresh={async () => {
|
||||
await getHomeData();
|
||||
}}
|
||||
renderText={(status) => {
|
||||
return <div>{statusRecord[status]}</div>;
|
||||
}}
|
||||
disabled={!Token}
|
||||
>
|
||||
<div className={cn(classes.Home, classes.container)}>
|
||||
<div className={classes.userinfo}>
|
||||
<div className={classes.userinfo_top}>
|
||||
<img className={classes.userinfo_top_left} src={logo} alt="" />
|
||||
<img
|
||||
className={classes.userinfo_top_left}
|
||||
src={userData?.userImg || logo}
|
||||
alt=""
|
||||
/>
|
||||
|
||||
{address ? (
|
||||
<div className={classes.userinfo_top_right}>
|
||||
|
@ -176,19 +193,25 @@ export default function () {
|
|||
<span className={classes.userinfo_data_num}>
|
||||
{userData?.mintNumber || 0}
|
||||
</span>
|
||||
<span className={classes.userinfo_data_des}>{t("邀请铸造")}</span>
|
||||
<span className={classes.userinfo_data_des}>
|
||||
{t("邀请铸造")}
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className={classes.userinfo_data_num}>
|
||||
{userData?.presidentNumber || 0}
|
||||
</span>
|
||||
<span className={classes.userinfo_data_des}>{t("团队社长")}</span>
|
||||
<span className={classes.userinfo_data_des}>
|
||||
{t("团队社长")}
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className={classes.userinfo_data_num}>
|
||||
{userData?.airdropNumber || 0}
|
||||
</span>
|
||||
<span className={classes.userinfo_data_des}>{t("邀请空投")}</span>
|
||||
<span className={classes.userinfo_data_des}>
|
||||
{t("邀请空投")}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -279,11 +302,14 @@ export default function () {
|
|||
{userData?.userIncomes.map((v, i) => (
|
||||
<ReceiveCom
|
||||
key={i}
|
||||
coinId={v.coinId}
|
||||
tokenName={v.coinName}
|
||||
tokenNum={v.receive}
|
||||
toReceive={v.collection}
|
||||
onAssetRec={() => {
|
||||
navigate(`/assetrecord?id=${v.id}&name=${v.coinName}`);
|
||||
navigate(
|
||||
`/assetrecord?id=${v.id}&coinId=${v.coinId}`
|
||||
);
|
||||
}}
|
||||
onReceive={async () => {
|
||||
receiveLoadingToast.current = Toast.show({
|
||||
|
@ -300,13 +326,16 @@ export default function () {
|
|||
const buyAmount = BigInt(
|
||||
orderInfo?.claimQuantity || ""
|
||||
);
|
||||
|
||||
receiveByContract(
|
||||
v.coinId,
|
||||
buyAmount,
|
||||
orderInfo.time,
|
||||
orderInfo?.orderNumber,
|
||||
orderInfo.hash
|
||||
)
|
||||
.then((hash) => {
|
||||
if (!hash) return;
|
||||
console.log("领取成功!hash:", hash);
|
||||
getHomeData();
|
||||
startPollingCheckBuyStatus(hash);
|
||||
|
@ -330,6 +359,15 @@ export default function () {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={classes.equityNft}
|
||||
onClick={() => window.open("https://element.market/account")}
|
||||
>
|
||||
<IconFont name="transfer" />
|
||||
<span>{t("交易红魔股权NFT")}</span>
|
||||
<IconFont name="chevronsrightshuangyoujiantou" color={"#FFFFFF"} />
|
||||
</div>
|
||||
|
||||
<div className={classes.invite}>
|
||||
<div className={classes.invite_top}>
|
||||
<span>{t("邀请")}</span>
|
||||
|
@ -404,6 +442,7 @@ export default function () {
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PullToRefresh>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -414,18 +453,20 @@ function ReceiveCom({
|
|||
toReceive,
|
||||
onAssetRec,
|
||||
onReceive,
|
||||
coinId,
|
||||
}: {
|
||||
tokenName: string;
|
||||
tokenNum: number;
|
||||
toReceive: number;
|
||||
onAssetRec: () => void;
|
||||
onReceive: () => void;
|
||||
coinId: UserIncome["coinId"];
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<li className={classes.nftToken_content_token_item}>
|
||||
{tokenName.toUpperCase() == "USDT" && <img src={usdtBg} alt="" />}
|
||||
{tokenName.toUpperCase() == "RMOB" && <img src={RMOB_logo} alt="" />}
|
||||
{coinId == 1 && <img src={usdtBg} alt="" />}
|
||||
{coinId == 2 && <img src={RMOB_logo} alt="" />}
|
||||
<div>
|
||||
<span className={classes.nftToken_content_token_item_tokenName}>
|
||||
{tokenName}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-18 10:28:21
|
||||
* @LastEditTime: 2024-06-25 14:47:34
|
||||
* @LastEditTime: 2024-07-02 11:36:40
|
||||
* @Author: John
|
||||
*/
|
||||
import { GET, POST } from "./client";
|
||||
|
@ -52,7 +52,7 @@ export function api_signUp() {
|
|||
chainType: 2;
|
||||
},
|
||||
any
|
||||
>({ url: "/api/account/signUp", requiresToken: false });
|
||||
>({ url: "/api/account/signUp", requiresToken: false, catchErr: true });
|
||||
}
|
||||
|
||||
// 获取钱包签名串
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-18 10:09:21
|
||||
* @LastEditTime: 2024-06-21 14:47:26
|
||||
* @LastEditTime: 2024-07-02 11:36:28
|
||||
* @Author: John
|
||||
*/
|
||||
import { Client } from "@hyper-fetch/core";
|
||||
|
@ -17,9 +17,11 @@ import i18next from "i18next";
|
|||
function initClient({
|
||||
requiresToken,
|
||||
requiresAddress,
|
||||
catchErr,
|
||||
}: {
|
||||
requiresToken: boolean;
|
||||
requiresAddress: boolean;
|
||||
catchErr: boolean;
|
||||
}) {
|
||||
return new Client({ url: import.meta.env.VITE_BASE_API_URL })
|
||||
.onAuth(async (req) => {
|
||||
|
@ -59,6 +61,7 @@ function initClient({
|
|||
const resData: BASE_RESPONSE = res.data;
|
||||
if (resData.code !== 200 && resData.code !== 0) {
|
||||
if (resData.msg) Toast.show({ content: resData.msg, icon: "fail" });
|
||||
if (catchErr) return res;
|
||||
throw new Error(resData.msg || "client on response error");
|
||||
}
|
||||
return res;
|
||||
|
@ -69,12 +72,14 @@ export const POST = <P = any, R = any, QueryParams = any>({
|
|||
url,
|
||||
requiresToken = true,
|
||||
requiresAddress = true,
|
||||
catchErr = false,
|
||||
}: {
|
||||
url: string;
|
||||
requiresToken?: boolean;
|
||||
requiresAddress?: boolean;
|
||||
catchErr?: boolean;
|
||||
}) => {
|
||||
return initClient({ requiresToken, requiresAddress }).createRequest<
|
||||
return initClient({ requiresToken, requiresAddress, catchErr }).createRequest<
|
||||
BASE_RESPONSE<R>,
|
||||
P,
|
||||
any,
|
||||
|
@ -89,12 +94,14 @@ export const GET = <P = any, R = any>({
|
|||
url,
|
||||
requiresToken = true,
|
||||
requiresAddress = true,
|
||||
catchErr = false,
|
||||
}: {
|
||||
url: string;
|
||||
requiresToken?: boolean;
|
||||
requiresAddress?: boolean;
|
||||
catchErr?: boolean;
|
||||
}) => {
|
||||
return initClient({ requiresToken, requiresAddress }).createRequest<
|
||||
return initClient({ requiresToken, requiresAddress, catchErr }).createRequest<
|
||||
BASE_RESPONSE<R>,
|
||||
any,
|
||||
any,
|
||||
|
|
|
@ -22,7 +22,7 @@ export interface UserHomeData {
|
|||
active: 0 | 1; // "0=非活跃 1=活跃用户"
|
||||
}
|
||||
export interface UserIncome {
|
||||
coinId: number;
|
||||
coinId: 1 | 2; // 1 USDT 2 ROMB
|
||||
coinName: string;
|
||||
collection: number;
|
||||
createTime: string;
|
||||
|
|
|
@ -294,3 +294,21 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* adm-pull-to-refresh */
|
||||
.adm-pull-to-refresh {
|
||||
.adm-pull-to-refresh-head-content {
|
||||
/* 自动布局子元素 */
|
||||
font-family: Space Grotesk;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: normal;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #9e9e9e;
|
||||
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,3 +102,14 @@ export function getLevelName(level: Level, active?: UserHomeData["active"]) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function getUrlParameterByName(name: string, url?: string) {
|
||||
if (!url) url = window.location.href;
|
||||
name = name.replace(/[\[\]]/g, "\\$&");
|
||||
let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
|
||||
results = regex.exec(url);
|
||||
if (!results) return null;
|
||||
if (!results[2]) return "";
|
||||
console.log("url params:", results);
|
||||
return decodeURIComponent(results[2].replace(/\+/g, " "));
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-19 15:55:07
|
||||
* @LastEditTime: 2024-06-26 15:18:22
|
||||
* @LastEditTime: 2024-07-02 11:38:59
|
||||
* @Author: John
|
||||
*/
|
||||
import { config } from "@/components/WalletProvider";
|
||||
|
@ -24,7 +24,7 @@ import {
|
|||
} from "@wagmi/core";
|
||||
import Toast from "antd-mobile/es/components/toast";
|
||||
import i18next from "i18next";
|
||||
import { getUrlQueryParam } from ".";
|
||||
import { getUrlParameterByName } from ".";
|
||||
import { UrlQueryParamsKey } from "@/constants";
|
||||
|
||||
/**
|
||||
|
@ -129,13 +129,13 @@ export async function signAndLogin(address?: `0x${string}`): Promise<void> {
|
|||
loadingToast.close();
|
||||
}
|
||||
} else {
|
||||
const inviteCode = getUrlQueryParam(UrlQueryParamsKey.INVITE_CODE);
|
||||
const inviteCode = getUrlParameterByName(UrlQueryParamsKey.INVITE_CODE);
|
||||
if (!inviteCode) {
|
||||
Toast.show({ icon: "fail", content: i18next.t("无效的邀请链接") });
|
||||
return loginOut();
|
||||
}
|
||||
// 注册
|
||||
await api_signUp().send({
|
||||
const { data } = await api_signUp().send({
|
||||
data: {
|
||||
account: address,
|
||||
publicKey,
|
||||
|
@ -143,7 +143,11 @@ export async function signAndLogin(address?: `0x${string}`): Promise<void> {
|
|||
chainType: 2,
|
||||
},
|
||||
});
|
||||
if (data?.code === 0) {
|
||||
await signAndLogin(address);
|
||||
} else {
|
||||
return loginOut();
|
||||
}
|
||||
reslove();
|
||||
loadingToast.close();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-06-17 17:20:03
|
||||
* @LastEditTime: 2024-06-21 13:50:16
|
||||
* @LastEditTime: 2024-07-02 16:53:48
|
||||
* @Author: John
|
||||
*/
|
||||
/// <reference types="vite/client" />
|
||||
|
@ -12,6 +12,7 @@ interface ImportMetaEnv {
|
|||
readonly VITE_PARTICIPATE_CHAIN_ID: number;
|
||||
readonly VITE_NETWORK_USDT_ADDRESS: `0x${string}`;
|
||||
readonly VITE_PURCHASED_CONTRACT_ADDRESS: `0x${string}`;
|
||||
readonly VITE_RECEIVE_RAMB_CONTRACT_ADDRESS: `0x${string}`;
|
||||
readonly VITE_CHECK_TRANSACTION_DETAILS_URL: string;
|
||||
// 更多环境变量...
|
||||
readonly MODE: "development" | "production" | "test";
|
||||
|
|
Loading…
Reference in New Issue