|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import React, { useEffect, useState, useContext, useRef } from 'react'; |
|
|
import { |
|
|
API, |
|
|
showError, |
|
|
showInfo, |
|
|
showSuccess, |
|
|
renderQuota, |
|
|
renderQuotaWithAmount, |
|
|
copy, |
|
|
getQuotaPerUnit, |
|
|
} from '../../helpers'; |
|
|
import { Modal, Toast } from '@douyinfe/semi-ui'; |
|
|
import { useTranslation } from 'react-i18next'; |
|
|
import { UserContext } from '../../context/User'; |
|
|
import { StatusContext } from '../../context/Status'; |
|
|
|
|
|
import RechargeCard from './RechargeCard'; |
|
|
import InvitationCard from './InvitationCard'; |
|
|
import TransferModal from './modals/TransferModal'; |
|
|
import PaymentConfirmModal from './modals/PaymentConfirmModal'; |
|
|
import TopupHistoryModal from './modals/TopupHistoryModal'; |
|
|
|
|
|
const TopUp = () => { |
|
|
const { t } = useTranslation(); |
|
|
const [userState, userDispatch] = useContext(UserContext); |
|
|
const [statusState] = useContext(StatusContext); |
|
|
|
|
|
const [redemptionCode, setRedemptionCode] = useState(''); |
|
|
const [amount, setAmount] = useState(0.0); |
|
|
const [minTopUp, setMinTopUp] = useState(statusState?.status?.min_topup || 1); |
|
|
const [topUpCount, setTopUpCount] = useState( |
|
|
statusState?.status?.min_topup || 1, |
|
|
); |
|
|
const [topUpLink, setTopUpLink] = useState( |
|
|
statusState?.status?.top_up_link || '', |
|
|
); |
|
|
const [enableOnlineTopUp, setEnableOnlineTopUp] = useState( |
|
|
statusState?.status?.enable_online_topup || false, |
|
|
); |
|
|
const [priceRatio, setPriceRatio] = useState(statusState?.status?.price || 1); |
|
|
|
|
|
const [enableStripeTopUp, setEnableStripeTopUp] = useState( |
|
|
statusState?.status?.enable_stripe_topup || false, |
|
|
); |
|
|
const [statusLoading, setStatusLoading] = useState(true); |
|
|
|
|
|
|
|
|
const [creemProducts, setCreemProducts] = useState([]); |
|
|
const [enableCreemTopUp, setEnableCreemTopUp] = useState(false); |
|
|
const [creemOpen, setCreemOpen] = useState(false); |
|
|
const [selectedCreemProduct, setSelectedCreemProduct] = useState(null); |
|
|
|
|
|
const [isSubmitting, setIsSubmitting] = useState(false); |
|
|
const [open, setOpen] = useState(false); |
|
|
const [payWay, setPayWay] = useState(''); |
|
|
const [amountLoading, setAmountLoading] = useState(false); |
|
|
const [paymentLoading, setPaymentLoading] = useState(false); |
|
|
const [confirmLoading, setConfirmLoading] = useState(false); |
|
|
const [payMethods, setPayMethods] = useState([]); |
|
|
|
|
|
const affFetchedRef = useRef(false); |
|
|
|
|
|
|
|
|
const [affLink, setAffLink] = useState(''); |
|
|
const [openTransfer, setOpenTransfer] = useState(false); |
|
|
const [transferAmount, setTransferAmount] = useState(0); |
|
|
|
|
|
|
|
|
const [openHistory, setOpenHistory] = useState(false); |
|
|
|
|
|
|
|
|
const [presetAmounts, setPresetAmounts] = useState([]); |
|
|
const [selectedPreset, setSelectedPreset] = useState(null); |
|
|
|
|
|
|
|
|
const [topupInfo, setTopupInfo] = useState({ |
|
|
amount_options: [], |
|
|
discount: {}, |
|
|
}); |
|
|
|
|
|
const topUp = async () => { |
|
|
if (redemptionCode === '') { |
|
|
showInfo(t('请输入兑换码!')); |
|
|
return; |
|
|
} |
|
|
setIsSubmitting(true); |
|
|
try { |
|
|
const res = await API.post('/api/user/topup', { |
|
|
key: redemptionCode, |
|
|
}); |
|
|
const { success, message, data } = res.data; |
|
|
if (success) { |
|
|
showSuccess(t('兑换成功!')); |
|
|
Modal.success({ |
|
|
title: t('兑换成功!'), |
|
|
content: t('成功兑换额度:') + renderQuota(data), |
|
|
centered: true, |
|
|
}); |
|
|
if (userState.user) { |
|
|
const updatedUser = { |
|
|
...userState.user, |
|
|
quota: userState.user.quota + data, |
|
|
}; |
|
|
userDispatch({ type: 'login', payload: updatedUser }); |
|
|
} |
|
|
setRedemptionCode(''); |
|
|
} else { |
|
|
showError(message); |
|
|
} |
|
|
} catch (err) { |
|
|
showError(t('请求失败')); |
|
|
} finally { |
|
|
setIsSubmitting(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const openTopUpLink = () => { |
|
|
if (!topUpLink) { |
|
|
showError(t('超级管理员未设置充值链接!')); |
|
|
return; |
|
|
} |
|
|
window.open(topUpLink, '_blank'); |
|
|
}; |
|
|
|
|
|
const preTopUp = async (payment) => { |
|
|
if (payment === 'stripe') { |
|
|
if (!enableStripeTopUp) { |
|
|
showError(t('管理员未开启Stripe充值!')); |
|
|
return; |
|
|
} |
|
|
} else { |
|
|
if (!enableOnlineTopUp) { |
|
|
showError(t('管理员未开启在线充值!')); |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
setPayWay(payment); |
|
|
setPaymentLoading(true); |
|
|
try { |
|
|
if (payment === 'stripe') { |
|
|
await getStripeAmount(); |
|
|
} else { |
|
|
await getAmount(); |
|
|
} |
|
|
|
|
|
if (topUpCount < minTopUp) { |
|
|
showError(t('充值数量不能小于') + minTopUp); |
|
|
return; |
|
|
} |
|
|
setOpen(true); |
|
|
} catch (error) { |
|
|
showError(t('获取金额失败')); |
|
|
} finally { |
|
|
setPaymentLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const onlineTopUp = async () => { |
|
|
if (payWay === 'stripe') { |
|
|
|
|
|
if (amount === 0) { |
|
|
await getStripeAmount(); |
|
|
} |
|
|
} else { |
|
|
|
|
|
if (amount === 0) { |
|
|
await getAmount(); |
|
|
} |
|
|
} |
|
|
|
|
|
if (topUpCount < minTopUp) { |
|
|
showError('充值数量不能小于' + minTopUp); |
|
|
return; |
|
|
} |
|
|
setConfirmLoading(true); |
|
|
try { |
|
|
let res; |
|
|
if (payWay === 'stripe') { |
|
|
|
|
|
res = await API.post('/api/user/stripe/pay', { |
|
|
amount: parseInt(topUpCount), |
|
|
payment_method: 'stripe', |
|
|
}); |
|
|
} else { |
|
|
|
|
|
res = await API.post('/api/user/pay', { |
|
|
amount: parseInt(topUpCount), |
|
|
payment_method: payWay, |
|
|
}); |
|
|
} |
|
|
|
|
|
if (res !== undefined) { |
|
|
const { message, data } = res.data; |
|
|
if (message === 'success') { |
|
|
if (payWay === 'stripe') { |
|
|
|
|
|
window.open(data.pay_link, '_blank'); |
|
|
} else { |
|
|
|
|
|
let params = data; |
|
|
let url = res.data.url; |
|
|
let form = document.createElement('form'); |
|
|
form.action = url; |
|
|
form.method = 'POST'; |
|
|
let isSafari = |
|
|
navigator.userAgent.indexOf('Safari') > -1 && |
|
|
navigator.userAgent.indexOf('Chrome') < 1; |
|
|
if (!isSafari) { |
|
|
form.target = '_blank'; |
|
|
} |
|
|
for (let key in params) { |
|
|
let input = document.createElement('input'); |
|
|
input.type = 'hidden'; |
|
|
input.name = key; |
|
|
input.value = params[key]; |
|
|
form.appendChild(input); |
|
|
} |
|
|
document.body.appendChild(form); |
|
|
form.submit(); |
|
|
document.body.removeChild(form); |
|
|
} |
|
|
} else { |
|
|
showError(data); |
|
|
} |
|
|
} else { |
|
|
showError(res); |
|
|
} |
|
|
} catch (err) { |
|
|
console.log(err); |
|
|
showError(t('支付请求失败')); |
|
|
} finally { |
|
|
setOpen(false); |
|
|
setConfirmLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const creemPreTopUp = async (product) => { |
|
|
if (!enableCreemTopUp) { |
|
|
showError(t('管理员未开启 Creem 充值!')); |
|
|
return; |
|
|
} |
|
|
setSelectedCreemProduct(product); |
|
|
setCreemOpen(true); |
|
|
}; |
|
|
|
|
|
const onlineCreemTopUp = async () => { |
|
|
if (!selectedCreemProduct) { |
|
|
showError(t('请选择产品')); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!selectedCreemProduct.productId) { |
|
|
showError(t('产品配置错误,请联系管理员')); |
|
|
return; |
|
|
} |
|
|
setConfirmLoading(true); |
|
|
try { |
|
|
const res = await API.post('/api/user/creem/pay', { |
|
|
product_id: selectedCreemProduct.productId, |
|
|
payment_method: 'creem', |
|
|
}); |
|
|
if (res !== undefined) { |
|
|
const { message, data } = res.data; |
|
|
if (message === 'success') { |
|
|
processCreemCallback(data); |
|
|
} else { |
|
|
showError(data); |
|
|
} |
|
|
} else { |
|
|
showError(res); |
|
|
} |
|
|
} catch (err) { |
|
|
console.log(err); |
|
|
showError(t('支付请求失败')); |
|
|
} finally { |
|
|
setCreemOpen(false); |
|
|
setConfirmLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const processCreemCallback = (data) => { |
|
|
|
|
|
window.open(data.checkout_url, '_blank'); |
|
|
}; |
|
|
|
|
|
const getUserQuota = async () => { |
|
|
let res = await API.get(`/api/user/self`); |
|
|
const { success, message, data } = res.data; |
|
|
if (success) { |
|
|
userDispatch({ type: 'login', payload: data }); |
|
|
} else { |
|
|
showError(message); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
const getTopupInfo = async () => { |
|
|
try { |
|
|
const res = await API.get('/api/user/topup/info'); |
|
|
const { message, data, success } = res.data; |
|
|
if (success) { |
|
|
setTopupInfo({ |
|
|
amount_options: data.amount_options || [], |
|
|
discount: data.discount || {}, |
|
|
}); |
|
|
|
|
|
|
|
|
let payMethods = data.pay_methods || []; |
|
|
try { |
|
|
if (typeof payMethods === 'string') { |
|
|
payMethods = JSON.parse(payMethods); |
|
|
} |
|
|
if (payMethods && payMethods.length > 0) { |
|
|
|
|
|
payMethods = payMethods.filter((method) => { |
|
|
return method.name && method.type; |
|
|
}); |
|
|
|
|
|
payMethods = payMethods.map((method) => { |
|
|
|
|
|
const normalizedMinTopup = Number(method.min_topup); |
|
|
method.min_topup = Number.isFinite(normalizedMinTopup) |
|
|
? normalizedMinTopup |
|
|
: 0; |
|
|
|
|
|
|
|
|
if ( |
|
|
method.type === 'stripe' && |
|
|
(!method.min_topup || method.min_topup <= 0) |
|
|
) { |
|
|
const stripeMin = Number(data.stripe_min_topup); |
|
|
if (Number.isFinite(stripeMin)) { |
|
|
method.min_topup = stripeMin; |
|
|
} |
|
|
} |
|
|
|
|
|
if (!method.color) { |
|
|
if (method.type === 'alipay') { |
|
|
method.color = 'rgba(var(--semi-blue-5), 1)'; |
|
|
} else if (method.type === 'wxpay') { |
|
|
method.color = 'rgba(var(--semi-green-5), 1)'; |
|
|
} else if (method.type === 'stripe') { |
|
|
method.color = 'rgba(var(--semi-purple-5), 1)'; |
|
|
} else { |
|
|
method.color = 'rgba(var(--semi-primary-5), 1)'; |
|
|
} |
|
|
} |
|
|
return method; |
|
|
}); |
|
|
} else { |
|
|
payMethods = []; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setPayMethods(payMethods); |
|
|
const enableStripeTopUp = data.enable_stripe_topup || false; |
|
|
const enableOnlineTopUp = data.enable_online_topup || false; |
|
|
const enableCreemTopUp = data.enable_creem_topup || false; |
|
|
const minTopUpValue = enableOnlineTopUp |
|
|
? data.min_topup |
|
|
: enableStripeTopUp |
|
|
? data.stripe_min_topup |
|
|
: 1; |
|
|
setEnableOnlineTopUp(enableOnlineTopUp); |
|
|
setEnableStripeTopUp(enableStripeTopUp); |
|
|
setEnableCreemTopUp(enableCreemTopUp); |
|
|
setMinTopUp(minTopUpValue); |
|
|
setTopUpCount(minTopUpValue); |
|
|
|
|
|
|
|
|
try { |
|
|
console.log(' data is ?', data); |
|
|
console.log(' creem products is ?', data.creem_products); |
|
|
const products = JSON.parse(data.creem_products || '[]'); |
|
|
setCreemProducts(products); |
|
|
} catch (e) { |
|
|
setCreemProducts([]); |
|
|
} |
|
|
|
|
|
|
|
|
if (topupInfo.amount_options.length === 0) { |
|
|
setPresetAmounts(generatePresetAmounts(minTopUpValue)); |
|
|
} |
|
|
|
|
|
|
|
|
getAmount(minTopUpValue); |
|
|
} catch (e) { |
|
|
console.log('解析支付方式失败:', e); |
|
|
setPayMethods([]); |
|
|
} |
|
|
|
|
|
|
|
|
if (data.amount_options && data.amount_options.length > 0) { |
|
|
const customPresets = data.amount_options.map((amount) => ({ |
|
|
value: amount, |
|
|
discount: data.discount[amount] || 1.0, |
|
|
})); |
|
|
setPresetAmounts(customPresets); |
|
|
} |
|
|
} else { |
|
|
console.error('获取充值配置失败:', data); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('获取充值配置异常:', error); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
const getAffLink = async () => { |
|
|
const res = await API.get('/api/user/aff'); |
|
|
const { success, message, data } = res.data; |
|
|
if (success) { |
|
|
let link = `${window.location.origin}/register?aff=${data}`; |
|
|
setAffLink(link); |
|
|
} else { |
|
|
showError(message); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
const transfer = async () => { |
|
|
if (transferAmount < getQuotaPerUnit()) { |
|
|
showError(t('划转金额最低为') + ' ' + renderQuota(getQuotaPerUnit())); |
|
|
return; |
|
|
} |
|
|
const res = await API.post(`/api/user/aff_transfer`, { |
|
|
quota: transferAmount, |
|
|
}); |
|
|
const { success, message } = res.data; |
|
|
if (success) { |
|
|
showSuccess(message); |
|
|
setOpenTransfer(false); |
|
|
getUserQuota().then(); |
|
|
} else { |
|
|
showError(message); |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
const handleAffLinkClick = async () => { |
|
|
await copy(affLink); |
|
|
showSuccess(t('邀请链接已复制到剪切板')); |
|
|
}; |
|
|
|
|
|
useEffect(() => { |
|
|
if (!userState?.user?.id) { |
|
|
getUserQuota().then(); |
|
|
} |
|
|
setTransferAmount(getQuotaPerUnit()); |
|
|
}, []); |
|
|
|
|
|
useEffect(() => { |
|
|
if (affFetchedRef.current) return; |
|
|
affFetchedRef.current = true; |
|
|
getAffLink().then(); |
|
|
}, []); |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
getTopupInfo().then(); |
|
|
}, []); |
|
|
|
|
|
useEffect(() => { |
|
|
if (statusState?.status) { |
|
|
|
|
|
|
|
|
|
|
|
setTopUpLink(statusState.status.top_up_link || ''); |
|
|
setPriceRatio(statusState.status.price || 1); |
|
|
|
|
|
setStatusLoading(false); |
|
|
} |
|
|
}, [statusState?.status]); |
|
|
|
|
|
const renderAmount = () => { |
|
|
return amount + ' ' + t('元'); |
|
|
}; |
|
|
|
|
|
const getAmount = async (value) => { |
|
|
if (value === undefined) { |
|
|
value = topUpCount; |
|
|
} |
|
|
setAmountLoading(true); |
|
|
try { |
|
|
const res = await API.post('/api/user/amount', { |
|
|
amount: parseFloat(value), |
|
|
}); |
|
|
if (res !== undefined) { |
|
|
const { message, data } = res.data; |
|
|
if (message === 'success') { |
|
|
setAmount(parseFloat(data)); |
|
|
} else { |
|
|
setAmount(0); |
|
|
Toast.error({ content: '错误:' + data, id: 'getAmount' }); |
|
|
} |
|
|
} else { |
|
|
showError(res); |
|
|
} |
|
|
} catch (err) { |
|
|
console.log(err); |
|
|
} |
|
|
setAmountLoading(false); |
|
|
}; |
|
|
|
|
|
const getStripeAmount = async (value) => { |
|
|
if (value === undefined) { |
|
|
value = topUpCount; |
|
|
} |
|
|
setAmountLoading(true); |
|
|
try { |
|
|
const res = await API.post('/api/user/stripe/amount', { |
|
|
amount: parseFloat(value), |
|
|
}); |
|
|
if (res !== undefined) { |
|
|
const { message, data } = res.data; |
|
|
if (message === 'success') { |
|
|
setAmount(parseFloat(data)); |
|
|
} else { |
|
|
setAmount(0); |
|
|
Toast.error({ content: '错误:' + data, id: 'getAmount' }); |
|
|
} |
|
|
} else { |
|
|
showError(res); |
|
|
} |
|
|
} catch (err) { |
|
|
console.log(err); |
|
|
} finally { |
|
|
setAmountLoading(false); |
|
|
} |
|
|
}; |
|
|
|
|
|
const handleCancel = () => { |
|
|
setOpen(false); |
|
|
}; |
|
|
|
|
|
const handleTransferCancel = () => { |
|
|
setOpenTransfer(false); |
|
|
}; |
|
|
|
|
|
const handleOpenHistory = () => { |
|
|
setOpenHistory(true); |
|
|
}; |
|
|
|
|
|
const handleHistoryCancel = () => { |
|
|
setOpenHistory(false); |
|
|
}; |
|
|
|
|
|
const handleCreemCancel = () => { |
|
|
setCreemOpen(false); |
|
|
setSelectedCreemProduct(null); |
|
|
}; |
|
|
|
|
|
|
|
|
const selectPresetAmount = (preset) => { |
|
|
setTopUpCount(preset.value); |
|
|
setSelectedPreset(preset.value); |
|
|
|
|
|
|
|
|
const discount = preset.discount || topupInfo.discount[preset.value] || 1.0; |
|
|
const discountedAmount = preset.value * priceRatio * discount; |
|
|
setAmount(discountedAmount); |
|
|
}; |
|
|
|
|
|
|
|
|
const formatLargeNumber = (num) => { |
|
|
return num.toString(); |
|
|
}; |
|
|
|
|
|
|
|
|
const generatePresetAmounts = (minAmount) => { |
|
|
const multipliers = [1, 5, 10, 30, 50, 100, 300, 500]; |
|
|
return multipliers.map((multiplier) => ({ |
|
|
value: minAmount * multiplier, |
|
|
})); |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<div className='w-full max-w-7xl mx-auto relative min-h-screen lg:min-h-0 mt-[60px] px-2'> |
|
|
{/* 划转模态框 */} |
|
|
<TransferModal |
|
|
t={t} |
|
|
openTransfer={openTransfer} |
|
|
transfer={transfer} |
|
|
handleTransferCancel={handleTransferCancel} |
|
|
userState={userState} |
|
|
renderQuota={renderQuota} |
|
|
getQuotaPerUnit={getQuotaPerUnit} |
|
|
transferAmount={transferAmount} |
|
|
setTransferAmount={setTransferAmount} |
|
|
/> |
|
|
|
|
|
{/* 充值确认模态框 */} |
|
|
<PaymentConfirmModal |
|
|
t={t} |
|
|
open={open} |
|
|
onlineTopUp={onlineTopUp} |
|
|
handleCancel={handleCancel} |
|
|
confirmLoading={confirmLoading} |
|
|
topUpCount={topUpCount} |
|
|
renderQuotaWithAmount={renderQuotaWithAmount} |
|
|
amountLoading={amountLoading} |
|
|
renderAmount={renderAmount} |
|
|
payWay={payWay} |
|
|
payMethods={payMethods} |
|
|
amountNumber={amount} |
|
|
discountRate={topupInfo?.discount?.[topUpCount] || 1.0} |
|
|
/> |
|
|
|
|
|
{/* 充值账单模态框 */} |
|
|
<TopupHistoryModal |
|
|
visible={openHistory} |
|
|
onCancel={handleHistoryCancel} |
|
|
t={t} |
|
|
/> |
|
|
|
|
|
{/* Creem 充值确认模态框 */} |
|
|
<Modal |
|
|
title={t('确定要充值 $')} |
|
|
visible={creemOpen} |
|
|
onOk={onlineCreemTopUp} |
|
|
onCancel={handleCreemCancel} |
|
|
maskClosable={false} |
|
|
size='small' |
|
|
centered |
|
|
confirmLoading={confirmLoading} |
|
|
> |
|
|
{selectedCreemProduct && ( |
|
|
<> |
|
|
<p> |
|
|
{t('产品名称')}:{selectedCreemProduct.name} |
|
|
</p> |
|
|
<p> |
|
|
{t('价格')}:{selectedCreemProduct.currency === 'EUR' ? '€' : '$'}{selectedCreemProduct.price} |
|
|
</p> |
|
|
<p> |
|
|
{t('充值额度')}:{selectedCreemProduct.quota} |
|
|
</p> |
|
|
<p>{t('是否确认充值?')}</p> |
|
|
</> |
|
|
)} |
|
|
</Modal> |
|
|
|
|
|
{} |
|
|
<div className='space-y-6'> |
|
|
<div className='grid grid-cols-1 lg:grid-cols-12 gap-6'> |
|
|
{/* 左侧充值区域 */} |
|
|
<div className='lg:col-span-7 space-y-6 w-full'> |
|
|
<RechargeCard |
|
|
t={t} |
|
|
enableOnlineTopUp={enableOnlineTopUp} |
|
|
enableStripeTopUp={enableStripeTopUp} |
|
|
enableCreemTopUp={enableCreemTopUp} |
|
|
creemProducts={creemProducts} |
|
|
creemPreTopUp={creemPreTopUp} |
|
|
presetAmounts={presetAmounts} |
|
|
selectedPreset={selectedPreset} |
|
|
selectPresetAmount={selectPresetAmount} |
|
|
formatLargeNumber={formatLargeNumber} |
|
|
priceRatio={priceRatio} |
|
|
topUpCount={topUpCount} |
|
|
minTopUp={minTopUp} |
|
|
renderQuotaWithAmount={renderQuotaWithAmount} |
|
|
getAmount={getAmount} |
|
|
setTopUpCount={setTopUpCount} |
|
|
setSelectedPreset={setSelectedPreset} |
|
|
renderAmount={renderAmount} |
|
|
amountLoading={amountLoading} |
|
|
payMethods={payMethods} |
|
|
preTopUp={preTopUp} |
|
|
paymentLoading={paymentLoading} |
|
|
payWay={payWay} |
|
|
redemptionCode={redemptionCode} |
|
|
setRedemptionCode={setRedemptionCode} |
|
|
topUp={topUp} |
|
|
isSubmitting={isSubmitting} |
|
|
topUpLink={topUpLink} |
|
|
openTopUpLink={openTopUpLink} |
|
|
userState={userState} |
|
|
renderQuota={renderQuota} |
|
|
statusLoading={statusLoading} |
|
|
topupInfo={topupInfo} |
|
|
onOpenHistory={handleOpenHistory} |
|
|
/> |
|
|
</div> |
|
|
|
|
|
{/* 右侧信息区域 */} |
|
|
<div className='lg:col-span-5'> |
|
|
<InvitationCard |
|
|
t={t} |
|
|
userState={userState} |
|
|
renderQuota={renderQuota} |
|
|
setOpenTransfer={setOpenTransfer} |
|
|
affLink={affLink} |
|
|
handleAffLinkClick={handleAffLinkClick} |
|
|
/> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default TopUp; |
|
|
|