|
|
@@ -4,7 +4,6 @@ import { Link } from "@/i18n/navigation";
|
|
|
import { useEffect, useMemo, useState } from "react";
|
|
|
import { fetchWalletBalance } from "@/lib/account-api";
|
|
|
import {
|
|
|
- fetchSavedWithdrawAccounts,
|
|
|
fetchWithdrawBankOptions,
|
|
|
fetchWithdrawChannels,
|
|
|
submitWithdrawApply,
|
|
|
@@ -74,13 +73,8 @@ function isCardType(type: string): boolean {
|
|
|
return type === "CHANNEL_TYPE_CARD";
|
|
|
}
|
|
|
|
|
|
-function needsSavedAccount(type: string): boolean {
|
|
|
- return (
|
|
|
- type === "BANK" ||
|
|
|
- type === "BANK_TELEGRAPHIC" ||
|
|
|
- type === "CHANNEL_TYPE_CARD" ||
|
|
|
- type === "DIGITAL_CURRENCY"
|
|
|
- );
|
|
|
+function isDigitalCurrencyType(type: string): boolean {
|
|
|
+ return type === "DIGITAL_CURRENCY";
|
|
|
}
|
|
|
|
|
|
function savedAccountType(type: string): number | null {
|
|
|
@@ -95,16 +89,16 @@ export default function WithdrawApplyPage() {
|
|
|
const [channels, setChannels] = useState<WithdrawChannel[]>([]);
|
|
|
const [channelsLoading, setChannelsLoading] = useState(false);
|
|
|
const [channelsError, setChannelsError] = useState<string | null>(null);
|
|
|
- const [savedAccountsError, setSavedAccountsError] = useState<string | null>(null);
|
|
|
const [walletBalance, setWalletBalance] = useState<number | null>(null);
|
|
|
const [walletBalanceLoading, setWalletBalanceLoading] = useState(false);
|
|
|
|
|
|
- const [savedAccounts, setSavedAccounts] = useState<SavedWithdrawAccount[]>([]);
|
|
|
+ const [savedAccounts] = useState<SavedWithdrawAccount[]>([]);
|
|
|
const [bankOptions, setBankOptions] = useState<WithdrawBankOption[]>([]);
|
|
|
|
|
|
const [selectedChannelId, setSelectedChannelId] = useState("");
|
|
|
const [selectedSavedId, setSelectedSavedId] = useState("");
|
|
|
const [selectedBankCode, setSelectedBankCode] = useState("");
|
|
|
+ const [addressName, setAddressName] = useState("");
|
|
|
const [address, setAddress] = useState("");
|
|
|
const [amount, setAmount] = useState("");
|
|
|
const [agree, setAgree] = useState(false);
|
|
|
@@ -157,7 +151,7 @@ export default function WithdrawApplyPage() {
|
|
|
return savedAccounts.filter((item) => item.type === type);
|
|
|
}, [savedAccounts, selectedChannel]);
|
|
|
|
|
|
- const shouldRequireSavedAccount = Boolean(selectedChannel && needsSavedAccount(selectedChannel.type));
|
|
|
+ const shouldRequireSavedAccount = false;
|
|
|
const shouldShowSavedAccountSelector = shouldRequireSavedAccount && filteredSavedAccounts.length > 0;
|
|
|
const isBankTelegraphic = selectedChannel?.type === "BANK_TELEGRAPHIC";
|
|
|
const needCpf = selectedChannel?.code === "PAY_RETAILER_REMIT_PAY_KEY_BRW";
|
|
|
@@ -165,6 +159,7 @@ export default function WithdrawApplyPage() {
|
|
|
function resetApplyForm() {
|
|
|
setSelectedSavedId("");
|
|
|
setSelectedBankCode("");
|
|
|
+ setAddressName("");
|
|
|
setAddress("");
|
|
|
setAmount("");
|
|
|
setAgree(false);
|
|
|
@@ -218,28 +213,6 @@ export default function WithdrawApplyPage() {
|
|
|
};
|
|
|
}, []);
|
|
|
|
|
|
- useEffect(() => {
|
|
|
- if (!applyDialogOpen) return;
|
|
|
- let cancelled = false;
|
|
|
- async function loadSavedAccounts() {
|
|
|
- setSavedAccountsError(null);
|
|
|
- try {
|
|
|
- const list = await fetchSavedWithdrawAccounts();
|
|
|
- if (cancelled) return;
|
|
|
- setSavedAccounts(list);
|
|
|
- } catch (e) {
|
|
|
- if (cancelled) return;
|
|
|
- const err = e as Error;
|
|
|
- setSavedAccountsError(err?.message || "收款信息加载失败");
|
|
|
- setSavedAccounts([]);
|
|
|
- }
|
|
|
- }
|
|
|
- void loadSavedAccounts();
|
|
|
- return () => {
|
|
|
- cancelled = true;
|
|
|
- };
|
|
|
- }, [applyDialogOpen]);
|
|
|
-
|
|
|
useEffect(() => {
|
|
|
if (!selectedChannel || !applyDialogOpen) {
|
|
|
setBankOptions([]);
|
|
|
@@ -248,6 +221,7 @@ export default function WithdrawApplyPage() {
|
|
|
}
|
|
|
const currentChannel = selectedChannel;
|
|
|
setSelectedSavedId("");
|
|
|
+ setAddressName("");
|
|
|
setAddress("");
|
|
|
setAgree(false);
|
|
|
setAgreeExtra(false);
|
|
|
@@ -311,6 +285,8 @@ export default function WithdrawApplyPage() {
|
|
|
return `提款金额不能高于 ${selectedChannel.maxAmount}`;
|
|
|
}
|
|
|
if (isWalletType(selectedChannel.type) && !address.trim()) return "请填写提款地址";
|
|
|
+ if (isDigitalCurrencyType(selectedChannel.type) && !addressName.trim()) return "请填写区块链名称";
|
|
|
+ if (isDigitalCurrencyType(selectedChannel.type) && !address.trim()) return "请填写钱包地址";
|
|
|
if (shouldRequireSavedAccount && filteredSavedAccounts.length === 0) {
|
|
|
return "当前通道暂无可用收款信息,请更换通道或先补充收款信息";
|
|
|
}
|
|
|
@@ -353,6 +329,7 @@ export default function WithdrawApplyPage() {
|
|
|
};
|
|
|
if (selectedBankCode) payload.bankCode = selectedBankCode;
|
|
|
if (address.trim()) payload.address = address.trim();
|
|
|
+ if (addressName.trim()) payload.addressName = addressName.trim();
|
|
|
if (selectedSavedAccount) {
|
|
|
payload.id = selectedSavedAccount.id;
|
|
|
payload.bankUname = selectedSavedAccount.bankUname;
|
|
|
@@ -587,6 +564,12 @@ export default function WithdrawApplyPage() {
|
|
|
{walletBalanceLoading ? "加载中..." : `$${(walletBalance ?? 0).toFixed(2)}`}
|
|
|
</span>
|
|
|
</div>
|
|
|
+ <div className="mt-3 rounded-lg border border-[var(--border)] bg-slate-50 px-3 py-2 text-sm text-[var(--navy)]">
|
|
|
+ 已选通道:
|
|
|
+ <span className="ml-1 font-semibold">
|
|
|
+ {selectedChannel.name || selectedChannel.enName || selectedChannel.code}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
|
|
|
{selectedChannel.introduce || selectedChannel.enIntroduce ? (
|
|
|
<div
|
|
|
@@ -772,12 +755,6 @@ export default function WithdrawApplyPage() {
|
|
|
</p>
|
|
|
) : null}
|
|
|
|
|
|
- {savedAccountsError && shouldRequireSavedAccount ? (
|
|
|
- <p className="mt-1 text-xs text-[var(--muted)]">
|
|
|
- 收款信息加载失败,可先切换其他通道后重试。
|
|
|
- </p>
|
|
|
- ) : null}
|
|
|
-
|
|
|
{isWalletType(selectedChannel.type) ? (
|
|
|
<div className="mt-3">
|
|
|
<label className="text-sm font-medium text-[var(--navy)]">提款地址</label>
|
|
|
@@ -789,6 +766,27 @@ export default function WithdrawApplyPage() {
|
|
|
</div>
|
|
|
) : null}
|
|
|
|
|
|
+ {isDigitalCurrencyType(selectedChannel.type) ? (
|
|
|
+ <div className="mt-3 grid gap-3 md:grid-cols-2">
|
|
|
+ <div>
|
|
|
+ <label className="text-sm font-medium text-[var(--navy)]">区块链名称</label>
|
|
|
+ <input
|
|
|
+ value={addressName}
|
|
|
+ onChange={(e) => setAddressName(e.target.value)}
|
|
|
+ className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <label className="text-sm font-medium text-[var(--navy)]">钱包地址</label>
|
|
|
+ <input
|
|
|
+ value={address}
|
|
|
+ onChange={(e) => setAddress(e.target.value)}
|
|
|
+ className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
{isBankTelegraphic ? (
|
|
|
<div className="mt-3 grid gap-3 md:grid-cols-2">
|
|
|
<div>
|