🐞 fix:

This commit is contained in:
john 2024-07-02 18:41:27 +08:00
parent f6cd16f1c6
commit aff0f68989
24 changed files with 768 additions and 347 deletions

View File

@ -1,12 +1,13 @@
### ###
# @LastEditors: John # @LastEditors: John
# @Date: 2024-06-18 10:12:21 # @Date: 2024-06-18 10:12:21
# @LastEditTime: 2024-06-27 15:35:23 # @LastEditTime: 2024-07-02 16:46:51
# @Author: John # @Author: John
### ###
VITE_BASE_URL= VITE_BASE_URL=
VITE_BASE_API_URL=/dev VITE_BASE_API_URL=/dev
VITE_PARTICIPATE_CHAIN_ID=97 VITE_PARTICIPATE_CHAIN_ID=97
VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8 VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8
VITE_RECEIVE_RAMB_CONTRACT_ADDRESS=0x8291A98382d751CdD52460A547eE94ceE8258930
VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63 VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63
VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/ VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/

View File

@ -1,12 +1,13 @@
### ###
# @LastEditors: John # @LastEditors: John
# @Date: 2024-06-24 18:38:45 # @Date: 2024-06-24 18:38:45
# @LastEditTime: 2024-06-25 14:04:37 # @LastEditTime: 2024-07-02 16:49:31
# @Author: John # @Author: John
### ###
VITE_BASE_URL=http://wwwtest.exgo.pro VITE_BASE_URL=http://wwwtest.exgo.pro
VITE_BASE_API_URL=http://wwwtest.exgo.pro VITE_BASE_API_URL=http://wwwtest.exgo.pro
VITE_PARTICIPATE_CHAIN_ID=97 VITE_PARTICIPATE_CHAIN_ID=97
VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8 VITE_PURCHASED_CONTRACT_ADDRESS=0x7aAe4f2CA23482B58D6f9e8d1fBb5e413e7013c8
VITE_RECEIVE_RAMB_CONTRACT_ADDRESS=0x8291A98382d751CdD52460A547eE94ceE8258930
VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63 VITE_NETWORK_USDT_ADDRESS=0xf9A18B7FC8Eb118f8Ad59fBD6eb1A181eaCb4E63
VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/ VITE_CHECK_TRANSACTION_DETAILS_URL=https://testnet.bscscan.com/

View File

@ -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, "use_typescript": true,
"save_dir": "./src/components/iconfont", "save_dir": "./src/components/iconfont",
"trim_icon_prefix": "icon", "trim_icon_prefix": "icon",

View File

@ -19,7 +19,7 @@ import InvitationList from "./pages/InvitationList";
import { useEffect } from "react"; import { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import useUserStore from "./store/User"; import useUserStore from "./store/User";
import { getUrlQueryParam } from "./utils"; import { getUrlParameterByName } from "./utils";
import { UrlQueryParamsKey } from "./constants"; import { UrlQueryParamsKey } from "./constants";
import { signAndLogin } from "./utils/wallet"; import { signAndLogin } from "./utils/wallet";
import { useAccount } from "wagmi"; import { useAccount } from "wagmi";
@ -29,7 +29,9 @@ function App() {
const { address } = useAccount(); const { address } = useAccount();
useEffect(() => { useEffect(() => {
i18n.changeLanguage(currantLang); i18n.changeLanguage(currantLang);
UpdateInviteCode(getUrlQueryParam(UrlQueryParamsKey.INVITE_CODE) || ""); UpdateInviteCode(
getUrlParameterByName(UrlQueryParamsKey.INVITE_CODE) || ""
);
return () => {}; return () => {};
}, []); }, []);

View File

@ -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;

View File

@ -2,6 +2,7 @@
/* eslint-disable */ /* eslint-disable */
import React, { SVGAttributes, FunctionComponent } from 'react'; import React, { SVGAttributes, FunctionComponent } from 'react';
import IconTransfer from './IconTransfer';
import IconDiqiu from './IconDiqiu'; import IconDiqiu from './IconDiqiu';
import IconTuichu from './IconTuichu'; import IconTuichu from './IconTuichu';
import IconChevronsrightshuangyoujiantou from './IconChevronsrightshuangyoujiantou'; import IconChevronsrightshuangyoujiantou from './IconChevronsrightshuangyoujiantou';
@ -11,6 +12,7 @@ import IconTongdun from './IconTongdun';
import IconJindun from './IconJindun'; import IconJindun from './IconJindun';
import IconXingdun from './IconXingdun'; import IconXingdun from './IconXingdun';
import IconGuanjun from './IconGuanjun'; import IconGuanjun from './IconGuanjun';
export { default as IconTransfer } from './IconTransfer';
export { default as IconDiqiu } from './IconDiqiu'; export { default as IconDiqiu } from './IconDiqiu';
export { default as IconTuichu } from './IconTuichu'; export { default as IconTuichu } from './IconTuichu';
export { default as IconChevronsrightshuangyoujiantou } from './IconChevronsrightshuangyoujiantou'; 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 IconXingdun } from './IconXingdun';
export { default as IconGuanjun } from './IconGuanjun'; 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'> { interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
name: IconNames; name: IconNames;
@ -31,6 +33,8 @@ interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
const IconFont: FunctionComponent<Props> = ({ name, ...rest }) => { const IconFont: FunctionComponent<Props> = ({ name, ...rest }) => {
switch (name) { switch (name) {
case 'transfer':
return <IconTransfer {...rest} />;
case 'diqiu': case 'diqiu':
return <IconDiqiu {...rest} />; return <IconDiqiu {...rest} />;
case 'tuichu': case 'tuichu':

View File

@ -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"
}
]

View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-19 15:48:57 * @Date: 2024-06-19 15:48:57
* @LastEditTime: 2024-06-27 18:00:07 * @LastEditTime: 2024-07-02 17:40:49
* @Author: John * @Author: John
*/ */
import { config } from "@/components/WalletProvider"; import { config } from "@/components/WalletProvider";
@ -16,8 +16,10 @@ import { encodeFunctionData } from "viem/utils";
import erc20Abi from "@/contract/abi/erc20abi.json"; import erc20Abi from "@/contract/abi/erc20abi.json";
import usdtAbi from "@/contract/abi/USDT.json"; import usdtAbi from "@/contract/abi/USDT.json";
import RedDevilsAbi from "@/contract/abi/RedDevils.json"; import RedDevilsAbi from "@/contract/abi/RedDevils.json";
import receiveAbi from "@/contract/abi/receive.json";
import i18next from "i18next"; import i18next from "i18next";
import { BaseError } from "wagmi"; import { BaseError } from "wagmi";
import { UserIncome } from "@/server/module";
/** /**
* @description * @description
@ -270,19 +272,76 @@ export async function upGradeByContract(amount: bigint, orderID: string) {
} }
/** /**
* receiveByContract * receiveRMABByContract
* @param amount * @param amount
* @param paymentTime
* @param orderID * @param orderID
* @param hashStr
* @returns * @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, amount: bigint,
paymentTime: number, paymentTime: number,
orderID: string, orderID: string,
hashStr: string hashStr: string
) { ) {
console.log("pay buy contract params", { amount, orderID }); 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) => { return new Promise<string>(async (reslove, reject) => {
try { 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);
}
}

View File

@ -104,5 +104,7 @@
"没有更多数据了": "没有更多数据了", "没有更多数据了": "没有更多数据了",
"升级中": "升级中", "升级中": "升级中",
"无等级": "无等级", "无等级": "无等级",
"无效的邀请链接": "无效的邀请链接" "无效的邀请链接": "无效的邀请链接",
"交易红魔股权NFT": "交易红魔股权NFT"
} }

View File

@ -104,5 +104,6 @@
"没有更多数据了": "Keine weiteren Daten", "没有更多数据了": "Keine weiteren Daten",
"升级中": "Wird aktualisiert", "升级中": "Wird aktualisiert",
"无等级": "Keine Bewertung", "无等级": "Keine Bewertung",
"无效的邀请链接": "Ungültiger Einladungslink" "无效的邀请链接": "Ungültiger Einladungslink",
"交易红魔股权NFT": "Handel mit Red Devil Equity NFT"
} }

View File

@ -104,5 +104,6 @@
"没有更多数据了": "No more data", "没有更多数据了": "No more data",
"升级中": "Upgrading", "升级中": "Upgrading",
"无等级": "No Grade", "无等级": "No Grade",
"无效的邀请链接": "Invalid invitation link" "无效的邀请链接": "Invalid invitation link",
"交易红魔股权NFT": "Trade Red Devil Equity NFT"
} }

View File

@ -104,5 +104,6 @@
"没有更多数据了": "これ以上のデータはありません", "没有更多数据了": "これ以上のデータはありません",
"升级中": "アップグレード中", "升级中": "アップグレード中",
"无等级": "グレードなし", "无等级": "グレードなし",
"无效的邀请链接": "無効な招待リンクです" "无效的邀请链接": "無効な招待リンクです",
"交易红魔股权NFT": "レッドデビル株式NFTを取引する"
} }

View File

@ -104,5 +104,6 @@
"没有更多数据了": "沒有更多數據了", "没有更多数据了": "沒有更多數據了",
"升级中": "升級中", "升级中": "升級中",
"无等级": "無等級", "无等级": "無等級",
"无效的邀请链接": "無效的邀請連結" "无效的邀请链接": "無效的邀請連結",
"交易红魔股权NFT": "交易紅魔股權NFT"
} }

View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-17 17:20:03 * @Date: 2024-06-17 17:20:03
* @LastEditTime: 2024-06-20 11:43:14 * @LastEditTime: 2024-07-02 11:38:25
* @Author: John * @Author: John
*/ */
import "@/i18n/init.ts"; import "@/i18n/init.ts";
@ -15,9 +15,9 @@ import EventBusProvider from "./context/EventBusContext.tsx";
import { WalletProvider } from "./components/WalletProvider.tsx"; import { WalletProvider } from "./components/WalletProvider.tsx";
import flexible from "./utils/flexible.ts"; import flexible from "./utils/flexible.ts";
import VConsole from "vconsole"; 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(); new VConsole();
} }
flexible(window, document); flexible(window, document);

View File

@ -1,12 +1,12 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-18 17:57:13 * @Date: 2024-06-18 17:57:13
* @LastEditTime: 2024-06-25 16:17:20 * @LastEditTime: 2024-07-02 17:43:52
* @Author: John * @Author: John
*/ */
import Tabs from "antd-mobile/es/components/tabs"; import Tabs from "antd-mobile/es/components/tabs";
import classes from "./AssetRecord.module.css"; 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 CapsuleTabs from "antd-mobile/es/components/capsule-tabs";
import RecordsItem from "@/components/RecordsItem"; import RecordsItem from "@/components/RecordsItem";
import { useTranslation } from "react-i18next"; 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 { api_pagling_query_income_record } from "@/server/api";
import { IncomeRecord, IncomeRecordType } from "@/server/module"; import { IncomeRecord, IncomeRecordType } from "@/server/module";
import { Empty, InfiniteScroll } from "antd-mobile"; import { Empty, InfiniteScroll } from "antd-mobile";
import { CoinName } from "@/constants";
export default function () { export default function () {
const { t } = useTranslation(); const { t } = useTranslation();
const coinId = useMemo(() => getUrlQueryParam("id"), []); const id = useMemo(() => getUrlParameterByName("id"), []);
const coinName = useMemo(() => getUrlQueryParam("name"), []); const coinId = useMemo(() => getUrlParameterByName("coinId"), []);
const currentType = useRef<1 | 2>(2); const currentType = useRef<1 | 2>(2);
const [issueRecords, setIssueRecords] = useState<IncomeRecord["records"]>([]); const [issueRecords, setIssueRecords] = useState<IncomeRecord["records"]>([]);
const [receiveRecord, setReceiveRecord] = useState<IncomeRecord["records"]>( const [receiveRecord, setReceiveRecord] = useState<IncomeRecord["records"]>(
@ -35,7 +34,7 @@ export default function () {
async function getRecord() { async function getRecord() {
return new Promise<void>(async (reslove) => { return new Promise<void>(async (reslove) => {
if (!coinId) return; if (!id) return;
if (!hasMore.current) return; if (!hasMore.current) return;
@ -43,7 +42,7 @@ export default function () {
pageNum.current++; pageNum.current++;
const { data } = await api_pagling_query_income_record().send({ const { data } = await api_pagling_query_income_record().send({
queryParams: { queryParams: {
id: coinId, id,
type: currentType.current, type: currentType.current,
pageNum: pageNum.current, pageNum: pageNum.current,
pageSize, pageSize,
@ -91,7 +90,7 @@ export default function () {
}} }}
> >
<Tabs.Tab className={classes.tab} title={t("发放记录")} key="1"> <Tabs.Tab className={classes.tab} title={t("发放记录")} key="1">
{coinName == CoinName.USDT && ( {coinId == "1" && (
<CapsuleTabs <CapsuleTabs
onChange={(key) => { onChange={(key) => {
switch (key) { switch (key) {
@ -117,7 +116,7 @@ export default function () {
</CapsuleTabs> </CapsuleTabs>
)} )}
{coinName == CoinName.RMOB && ( {coinId == "2" && (
<CapsuleTabs <CapsuleTabs
onChange={(key) => { onChange={(key) => {
switch (key) { switch (key) {

View File

@ -204,7 +204,7 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
li { li {
width: 76px; min-width: 76px;
height: 34px; height: 34px;
opacity: 1; opacity: 1;
@ -220,6 +220,7 @@
color: #4d4d4d; color: #4d4d4d;
text-align: center; text-align: center;
line-height: 34px; line-height: 34px;
padding: 0 10px;
&.nftToken_tab_active { &.nftToken_tab_active {
border-radius: 10px; border-radius: 10px;
opacity: 1; 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 { .invite {
margin-top: 25px; margin-top: 25px;
.invite_top { .invite_top {

View File

@ -10,17 +10,16 @@ import usdtBg from "@/assets/usdt_bg.svg";
import RMOB_logo from "@/assets/RMOB_logo.svg"; import RMOB_logo from "@/assets/RMOB_logo.svg";
import IconFont from "@/components/iconfont"; import IconFont from "@/components/iconfont";
import { BaseError, useAccount } from "wagmi"; import { BaseError, useAccount } from "wagmi";
import { config } from "@/components/WalletProvider"; import { useNavigate } from "react-router-dom";
import { createSearchParams, useNavigate } from "react-router-dom"; import { Button, Dialog, Empty, PullToRefresh, Toast } from "antd-mobile";
import { Button, Dialog, Empty, Toast } from "antd-mobile";
import { loginOut } from "@/utils/wallet"; import { loginOut } from "@/utils/wallet";
import { api_claim_income, api_get_homepage_user_data } from "@/server/api"; 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 { UrlQueryParamsKey } from "@/constants";
import { receiveByContract } from "@/contract/utils"; import { receiveByContract } from "@/contract/utils";
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus"; import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
import { ToastHandler } from "antd-mobile/es/components/toast"; 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 () { export default function () {
const { Token, UpdateToken } = useUserStore(); const { Token, UpdateToken } = useUserStore();
const { open } = useWeb3Modal(); const { open } = useWeb3Modal();
@ -30,7 +29,12 @@ export default function () {
const [tabIndex, setTabIndex] = useState(0); const [tabIndex, setTabIndex] = useState(0);
const navigate = useNavigate(); const navigate = useNavigate();
const [userData, setUserData] = useState<UserHomeData>(); 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( const userInviteLink = useMemo(
() => () =>
`${location.origin}/#/?${UrlQueryParamsKey.INVITE_CODE}=${ `${location.origin}/#/?${UrlQueryParamsKey.INVITE_CODE}=${
@ -76,334 +80,369 @@ export default function () {
return ( return (
<> <>
<div className={cn(classes.Home, classes.container)}> <PullToRefresh
<div className={classes.userinfo}> onRefresh={async () => {
<div className={classes.userinfo_top}> await getHomeData();
<img className={classes.userinfo_top_left} src={logo} alt="" /> }}
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={userData?.userImg || logo}
alt=""
/>
{address ? ( {address ? (
<div className={classes.userinfo_top_right}> <div className={classes.userinfo_top_right}>
<div className={classes.userinfo_top_right_wallet}> <div className={classes.userinfo_top_right_wallet}>
<span>{shortenString(address, 6, 4)}</span> <span>{shortenString(address, 6, 4)}</span>
<IconFont <IconFont
onClick={async () => { onClick={async () => {
loginOut(); loginOut();
}}
name="tuichu"
className={classes.userinfo_top_right_wallet_disconnect}
color={"#fff"}
/>
</div>
<div className={classes.userinfo_top_right_btns}>
{userData && (
<>
<div className={classes.userinfo_top_right_btns_item}>
{userData.level == 0 && (
<>
<IconFont
name="tongdun"
className={classes.userinfo_top_right_btns_icon}
/>
<span>{t("无等级")}</span>
</>
)}
{userData.level == 1 && (
<>
<IconFont
name="jindun"
className={classes.userinfo_top_right_btns_icon}
/>
{userData.active === 0 && (
<span>{t("普通非活跃")}</span>
)}
{userData.active === 1 && (
<span>{t("普通活跃")}</span>
)}
</>
)}
{userData.level == 2 && (
<>
<IconFont
name="xingdun"
className={classes.userinfo_top_right_btns_icon}
/>
<span>{t("社长")}</span>
</>
)}
{userData.level == 3 && (
<>
<IconFont
name="guanjun"
className={classes.userinfo_top_right_btns_icon}
/>
<span>{t("基金会社长")}</span>
</>
)}
</div>
<div
className={classes.userinfo_top_right_btns_item}
onClick={() => {
navigate("/levelup");
}}
>
<span>{t("升级")}</span>
<IconFont
name="chevronsrightshuangyoujiantou"
className={classes.userinfo_top_right_btns_icon}
color={"#fff"}
/>
</div>
</>
)}
</div>
</div>
) : (
<>
<div
className={classes.userinfo_top_right_connect}
onClick={() => {
open();
}} }}
name="tuichu" >
className={classes.userinfo_top_right_wallet_disconnect} <span>{t("链接钱包")}</span>
color={"#fff"} </div>
/> </>
</div> )}
<div className={classes.userinfo_top_right_btns}> </div>
{userData && ( <ul className={classes.userinfo_data}>
<> <li>
<div className={classes.userinfo_top_right_btns_item}> <span className={classes.userinfo_data_num}>
{userData.level == 0 && ( {userData?.mintNumber || 0}
<> </span>
<IconFont <span className={classes.userinfo_data_des}>
name="tongdun" {t("邀请铸造")}
className={classes.userinfo_top_right_btns_icon} </span>
/> </li>
<span>{t("无等级")}</span> <li>
</> <span className={classes.userinfo_data_num}>
)} {userData?.presidentNumber || 0}
{userData.level == 1 && ( </span>
<> <span className={classes.userinfo_data_des}>
<IconFont {t("团队社长")}
name="jindun" </span>
className={classes.userinfo_top_right_btns_icon} </li>
/> <li>
{userData.active === 0 && ( <span className={classes.userinfo_data_num}>
<span>{t("普通非活跃")}</span> {userData?.airdropNumber || 0}
)} </span>
{userData.active === 1 && ( <span className={classes.userinfo_data_des}>
<span>{t("普通活跃")}</span> {t("邀请空投")}
)} </span>
</> </li>
)} </ul>
{userData.level == 2 && (
<>
<IconFont
name="xingdun"
className={classes.userinfo_top_right_btns_icon}
/>
<span>{t("社长")}</span>
</>
)}
{userData.level == 3 && (
<>
<IconFont
name="guanjun"
className={classes.userinfo_top_right_btns_icon}
/>
<span>{t("基金会社长")}</span>
</>
)}
</div>
<div
className={classes.userinfo_top_right_btns_item}
onClick={() => {
navigate("/levelup");
}}
>
<span>{t("升级")}</span>
<IconFont
name="chevronsrightshuangyoujiantou"
className={classes.userinfo_top_right_btns_icon}
color={"#fff"}
/>
</div>
</>
)}
</div>
</div>
) : (
<>
<div
className={classes.userinfo_top_right_connect}
onClick={() => {
open();
}}
>
<span>{t("链接钱包")}</span>
</div>
</>
)}
</div> </div>
<ul className={classes.userinfo_data}>
<li>
<span className={classes.userinfo_data_num}>
{userData?.mintNumber || 0}
</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>
</li>
<li>
<span className={classes.userinfo_data_num}>
{userData?.airdropNumber || 0}
</span>
<span className={classes.userinfo_data_des}>{t("邀请空投")}</span>
</li>
</ul>
</div>
<div className={classes.nftToken}> <div className={classes.nftToken}>
<ul className={classes.nftToken_tab}> <ul className={classes.nftToken_tab}>
<li <li
className={tabIndex == 0 ? classes.nftToken_tab_active : ""} className={tabIndex == 0 ? classes.nftToken_tab_active : ""}
onClick={() => setTabIndex(0)} onClick={() => setTabIndex(0)}
> >
NFT NFT
</li> </li>
<li <li
className={tabIndex == 1 ? classes.nftToken_tab_active : ""} className={tabIndex == 1 ? classes.nftToken_tab_active : ""}
onClick={() => setTabIndex(1)} onClick={() => setTabIndex(1)}
> >
{t("收益")} {t("收益")}
</li> </li>
</ul> </ul>
<div className={classes.nftToken_content}> <div className={classes.nftToken_content}>
{tabIndex == 0 && ( {tabIndex == 0 && (
<> <>
{address ? ( {address ? (
<> <>
{userData?.nftId ? ( {userData?.nftId ? (
<div className={classes.nftToken_content_nft}> <div className={classes.nftToken_content_nft}>
<div className={classes.nftToken_content_nft_top}> <div className={classes.nftToken_content_nft_top}>
<span># {userData?.nftId}</span> <span># {userData?.nftId}</span>
<span <span
onClick={() => {
navigate("/mint");
}}
>
{t("铸造 NFT")}
<IconFont
name="chevronsrightshuangyoujiantou"
color={"#F3BE3C"}
/>
</span>
</div>
<img
className={classes.nftToken_content_nft_img}
src={nftBg}
alt=""
/>
<span className={classes.nftToken_content_nft_des}>
{t("Min结束后按照规则进行空投。")}
</span>
</div>
) : (
<div className={classes.nftToken_content_nft_mint}>
<div
className={classes.nftToken_content_nft_mint_btn}
onClick={() => { onClick={() => {
navigate("/mint"); navigate("/mint");
}} }}
> >
{t("铸造 NFT")} <span>{t("铸造 NFT")}</span>
<IconFont <IconFont
className={
classes.nftToken_content_nft_mint_btn_icon
}
name="chevronsrightshuangyoujiantou" name="chevronsrightshuangyoujiantou"
color={"#F3BE3C"} color={"#fff"}
/> />
</span> </div>
<span>{t("铸造 NFT 获得代币空投")}</span>
</div> </div>
<img )}
className={classes.nftToken_content_nft_img} </>
src={nftBg} ) : (
alt="" <>
/> <div className={classes.nftToken_content_userDisconnect}>
<span className={classes.nftToken_content_nft_des}> <span>{t("钱包未链接,无法向您显示 NFT")}</span>
{t("Min结束后按照规则进行空投。")}
</span>
</div> </div>
) : ( </>
<div className={classes.nftToken_content_nft_mint}> )}
<div </>
className={classes.nftToken_content_nft_mint_btn} )}
{tabIndex == 1 && (
<div className={classes.nftToken_content_token}>
<div className={classes.nftToken_content_token_top}>
<span>{t("总收益= 已领取 + 待领取")}</span>
</div>
<ul className={classes.nftToken_content_token_list}>
{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}&coinId=${v.coinId}`
);
}}
onReceive={async () => {
receiveLoadingToast.current = Toast.show({
icon: "loading",
duration: 0,
content: t("领取中"),
maskClickable: false,
});
const { data } = await api_claim_income().send({
queryParams: { id: v.id },
});
const orderInfo = data?.data;
if (!orderInfo?.orderNumber) return;
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);
})
.catch(async (err: BaseError) => {
receiveLoadingToast.current?.close();
Toast.show({
content: err.shortMessage,
icon: "fail",
});
});
}}
/>
))}
{(userData?.userIncomes.length == 0 ||
!userData?.userIncomes) && <Empty />}
</ul>
</div>
)}
</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>
{address && (
<span
onClick={() => {
navigate("/invitationlist");
}}
>
{t("邀请列表")}{" "}
<IconFont
name="chevronsrightshuangyoujiantou"
color={"#F3BE3C"}
/>
</span>
)}
</div>
<div className={classes.invite_content}>
<span>{t("邀请链接")}</span>
<div className={classes.invite_content_link}>
{address ? (
<>
{userData?.nftId ? (
<>
<span>{shortenString(userInviteLink, 15, 15)}</span>
<IconFont
onClick={() => { onClick={() => {
navigate("/mint"); copyText(userInviteLink);
}} }}
> className={classes.invite_content_icon}
<span>{t("铸造 NFT")}</span> name="fuzhi"
<IconFont color={"#fff"}
className={ />{" "}
classes.nftToken_content_nft_mint_btn_icon </>
} ) : (
name="chevronsrightshuangyoujiantou" <>
color={"#fff"} <span>{t("MINT Nft 获取邀请链接")}</span>
/> </>
</div>
<span>{t("铸造 NFT 获得代币空投")}</span>
</div>
)} )}
</> </>
) : ( ) : (
<> <>
<div className={classes.nftToken_content_userDisconnect}> <span>{t("链接钱包获取邀请链接")}</span>
<span>{t("钱包未链接,无法向您显示 NFT")}</span>
</div>
</> </>
)} )}
</>
)}
{tabIndex == 1 && (
<div className={classes.nftToken_content_token}>
<div className={classes.nftToken_content_token_top}>
<span>{t("总收益= 已领取 + 待领取")}</span>
</div>
<ul className={classes.nftToken_content_token_list}>
{userData?.userIncomes.map((v, i) => (
<ReceiveCom
key={i}
tokenName={v.coinName}
tokenNum={v.receive}
toReceive={v.collection}
onAssetRec={() => {
navigate(`/assetrecord?id=${v.id}&name=${v.coinName}`);
}}
onReceive={async () => {
receiveLoadingToast.current = Toast.show({
icon: "loading",
duration: 0,
content: t("领取中"),
maskClickable: false,
});
const { data } = await api_claim_income().send({
queryParams: { id: v.id },
});
const orderInfo = data?.data;
if (!orderInfo?.orderNumber) return;
const buyAmount = BigInt(
orderInfo?.claimQuantity || ""
);
receiveByContract(
buyAmount,
orderInfo.time,
orderInfo?.orderNumber,
orderInfo.hash
)
.then((hash) => {
console.log("领取成功hash:", hash);
getHomeData();
startPollingCheckBuyStatus(hash);
})
.catch(async (err: BaseError) => {
receiveLoadingToast.current?.close();
Toast.show({
content: err.shortMessage,
icon: "fail",
});
});
}}
/>
))}
{(userData?.userIncomes.length == 0 ||
!userData?.userIncomes) && <Empty />}
</ul>
</div> </div>
)}
</div>
</div>
<div className={classes.invite}> <span>
<div className={classes.invite_top}> {t(
<span>{t("邀请")}</span> "普通会员每邀请铸造一个NFT可获得一份空投福利推荐铸造20个NFT的可升级为会长团队中拥有20位会长可升级为基金会社长邀请越多级别越高福利越多。"
{address && ( )}
<span
onClick={() => {
navigate("/invitationlist");
}}
>
{t("邀请列表")}{" "}
<IconFont
name="chevronsrightshuangyoujiantou"
color={"#F3BE3C"}
/>
</span> </span>
)}
</div>
<div className={classes.invite_content}>
<span>{t("邀请链接")}</span>
<div className={classes.invite_content_link}>
{address ? (
<>
{userData?.nftId ? (
<>
<span>{shortenString(userInviteLink, 15, 15)}</span>
<IconFont
onClick={() => {
copyText(userInviteLink);
}}
className={classes.invite_content_icon}
name="fuzhi"
color={"#fff"}
/>{" "}
</>
) : (
<>
<span>{t("MINT Nft 获取邀请链接")}</span>
</>
)}
</>
) : (
<>
<span>{t("链接钱包获取邀请链接")}</span>
</>
)}
</div> </div>
</div>
<span> <div className={classes.dataDisclosure}>
{t( <span>{t("数据披露")}</span>
"普通会员每邀请铸造一个NFT可获得一份空投福利推荐铸造20个NFT的可升级为会长团队中拥有20位会长可升级为基金会社长邀请越多级别越高福利越多。" <ul className={classes.dataDisclosure_content}>
)} <li className={classes.dataDisclosure_content_item}>
</span> <span>{t("资金池")}</span>
<span>{userData?.pools || 0}</span>
</li>
<li className={classes.dataDisclosure_content_item}>
<span>{t("社长席位")}</span>
<span>{userData?.president || 0}</span>
</li>
<li className={classes.dataDisclosure_content_item}>
<span>{t("基金会社长席位")}</span>
<span>{userData?.foundation || 0}</span>
</li>
</ul>
</div> </div>
</div> </div>
</PullToRefresh>
<div className={classes.dataDisclosure}>
<span>{t("数据披露")}</span>
<ul className={classes.dataDisclosure_content}>
<li className={classes.dataDisclosure_content_item}>
<span>{t("资金池")}</span>
<span>{userData?.pools || 0}</span>
</li>
<li className={classes.dataDisclosure_content_item}>
<span>{t("社长席位")}</span>
<span>{userData?.president || 0}</span>
</li>
<li className={classes.dataDisclosure_content_item}>
<span>{t("基金会社长席位")}</span>
<span>{userData?.foundation || 0}</span>
</li>
</ul>
</div>
</div>
</> </>
); );
} }
@ -414,18 +453,20 @@ function ReceiveCom({
toReceive, toReceive,
onAssetRec, onAssetRec,
onReceive, onReceive,
coinId,
}: { }: {
tokenName: string; tokenName: string;
tokenNum: number; tokenNum: number;
toReceive: number; toReceive: number;
onAssetRec: () => void; onAssetRec: () => void;
onReceive: () => void; onReceive: () => void;
coinId: UserIncome["coinId"];
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<li className={classes.nftToken_content_token_item}> <li className={classes.nftToken_content_token_item}>
{tokenName.toUpperCase() == "USDT" && <img src={usdtBg} alt="" />} {coinId == 1 && <img src={usdtBg} alt="" />}
{tokenName.toUpperCase() == "RMOB" && <img src={RMOB_logo} alt="" />} {coinId == 2 && <img src={RMOB_logo} alt="" />}
<div> <div>
<span className={classes.nftToken_content_token_item_tokenName}> <span className={classes.nftToken_content_token_item_tokenName}>
{tokenName} {tokenName}

View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-18 10:28:21 * @Date: 2024-06-18 10:28:21
* @LastEditTime: 2024-06-25 14:47:34 * @LastEditTime: 2024-07-02 11:36:40
* @Author: John * @Author: John
*/ */
import { GET, POST } from "./client"; import { GET, POST } from "./client";
@ -52,7 +52,7 @@ export function api_signUp() {
chainType: 2; chainType: 2;
}, },
any any
>({ url: "/api/account/signUp", requiresToken: false }); >({ url: "/api/account/signUp", requiresToken: false, catchErr: true });
} }
// 获取钱包签名串 // 获取钱包签名串

View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-18 10:09:21 * @Date: 2024-06-18 10:09:21
* @LastEditTime: 2024-06-21 14:47:26 * @LastEditTime: 2024-07-02 11:36:28
* @Author: John * @Author: John
*/ */
import { Client } from "@hyper-fetch/core"; import { Client } from "@hyper-fetch/core";
@ -17,9 +17,11 @@ import i18next from "i18next";
function initClient({ function initClient({
requiresToken, requiresToken,
requiresAddress, requiresAddress,
catchErr,
}: { }: {
requiresToken: boolean; requiresToken: boolean;
requiresAddress: boolean; requiresAddress: boolean;
catchErr: boolean;
}) { }) {
return new Client({ url: import.meta.env.VITE_BASE_API_URL }) return new Client({ url: import.meta.env.VITE_BASE_API_URL })
.onAuth(async (req) => { .onAuth(async (req) => {
@ -59,6 +61,7 @@ function initClient({
const resData: BASE_RESPONSE = res.data; const resData: BASE_RESPONSE = res.data;
if (resData.code !== 200 && resData.code !== 0) { if (resData.code !== 200 && resData.code !== 0) {
if (resData.msg) Toast.show({ content: resData.msg, icon: "fail" }); if (resData.msg) Toast.show({ content: resData.msg, icon: "fail" });
if (catchErr) return res;
throw new Error(resData.msg || "client on response error"); throw new Error(resData.msg || "client on response error");
} }
return res; return res;
@ -69,12 +72,14 @@ export const POST = <P = any, R = any, QueryParams = any>({
url, url,
requiresToken = true, requiresToken = true,
requiresAddress = true, requiresAddress = true,
catchErr = false,
}: { }: {
url: string; url: string;
requiresToken?: boolean; requiresToken?: boolean;
requiresAddress?: boolean; requiresAddress?: boolean;
catchErr?: boolean;
}) => { }) => {
return initClient({ requiresToken, requiresAddress }).createRequest< return initClient({ requiresToken, requiresAddress, catchErr }).createRequest<
BASE_RESPONSE<R>, BASE_RESPONSE<R>,
P, P,
any, any,
@ -89,12 +94,14 @@ export const GET = <P = any, R = any>({
url, url,
requiresToken = true, requiresToken = true,
requiresAddress = true, requiresAddress = true,
catchErr = false,
}: { }: {
url: string; url: string;
requiresToken?: boolean; requiresToken?: boolean;
requiresAddress?: boolean; requiresAddress?: boolean;
catchErr?: boolean;
}) => { }) => {
return initClient({ requiresToken, requiresAddress }).createRequest< return initClient({ requiresToken, requiresAddress, catchErr }).createRequest<
BASE_RESPONSE<R>, BASE_RESPONSE<R>,
any, any,
any, any,

View File

@ -22,7 +22,7 @@ export interface UserHomeData {
active: 0 | 1; // "0=非活跃 1=活跃用户" active: 0 | 1; // "0=非活跃 1=活跃用户"
} }
export interface UserIncome { export interface UserIncome {
coinId: number; coinId: 1 | 2; // 1 USDT 2 ROMB
coinName: string; coinName: string;
collection: number; collection: number;
createTime: string; createTime: string;

View File

@ -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;
}
}

View File

@ -102,3 +102,14 @@ export function getLevelName(level: Level, active?: UserHomeData["active"]) {
break; 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, " "));
}

View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-19 15:55:07 * @Date: 2024-06-19 15:55:07
* @LastEditTime: 2024-06-26 15:18:22 * @LastEditTime: 2024-07-02 11:38:59
* @Author: John * @Author: John
*/ */
import { config } from "@/components/WalletProvider"; import { config } from "@/components/WalletProvider";
@ -24,7 +24,7 @@ import {
} from "@wagmi/core"; } from "@wagmi/core";
import Toast from "antd-mobile/es/components/toast"; import Toast from "antd-mobile/es/components/toast";
import i18next from "i18next"; import i18next from "i18next";
import { getUrlQueryParam } from "."; import { getUrlParameterByName } from ".";
import { UrlQueryParamsKey } from "@/constants"; import { UrlQueryParamsKey } from "@/constants";
/** /**
@ -129,13 +129,13 @@ export async function signAndLogin(address?: `0x${string}`): Promise<void> {
loadingToast.close(); loadingToast.close();
} }
} else { } else {
const inviteCode = getUrlQueryParam(UrlQueryParamsKey.INVITE_CODE); const inviteCode = getUrlParameterByName(UrlQueryParamsKey.INVITE_CODE);
if (!inviteCode) { if (!inviteCode) {
Toast.show({ icon: "fail", content: i18next.t("无效的邀请链接") }); Toast.show({ icon: "fail", content: i18next.t("无效的邀请链接") });
return loginOut(); return loginOut();
} }
// 注册 // 注册
await api_signUp().send({ const { data } = await api_signUp().send({
data: { data: {
account: address, account: address,
publicKey, publicKey,
@ -143,7 +143,11 @@ export async function signAndLogin(address?: `0x${string}`): Promise<void> {
chainType: 2, chainType: 2,
}, },
}); });
await signAndLogin(address); if (data?.code === 0) {
await signAndLogin(address);
} else {
return loginOut();
}
reslove(); reslove();
loadingToast.close(); loadingToast.close();
} }

3
src/vite-env.d.ts vendored
View File

@ -1,7 +1,7 @@
/* /*
* @LastEditors: John * @LastEditors: John
* @Date: 2024-06-17 17:20:03 * @Date: 2024-06-17 17:20:03
* @LastEditTime: 2024-06-21 13:50:16 * @LastEditTime: 2024-07-02 16:53:48
* @Author: John * @Author: John
*/ */
/// <reference types="vite/client" /> /// <reference types="vite/client" />
@ -12,6 +12,7 @@ interface ImportMetaEnv {
readonly VITE_PARTICIPATE_CHAIN_ID: number; readonly VITE_PARTICIPATE_CHAIN_ID: number;
readonly VITE_NETWORK_USDT_ADDRESS: `0x${string}`; readonly VITE_NETWORK_USDT_ADDRESS: `0x${string}`;
readonly VITE_PURCHASED_CONTRACT_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 VITE_CHECK_TRANSACTION_DETAILS_URL: string;
// 更多环境变量... // 更多环境变量...
readonly MODE: "development" | "production" | "test"; readonly MODE: "development" | "production" | "test";