/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import React, { useRef } from 'react'; import { Avatar, Typography, Tag, Card, Button, Banner, Skeleton, Form, Space, Row, Col, Spin, Tooltip, } from '@douyinfe/semi-ui'; import { SiAlipay, SiWechat, SiStripe } from 'react-icons/si'; import { CreditCard, Coins, Wallet, BarChart2, TrendingUp, Receipt, } from 'lucide-react'; import { IconGift } from '@douyinfe/semi-icons'; import { useMinimumLoadingTime } from '../../hooks/common/useMinimumLoadingTime'; import { getCurrencyConfig } from '../../helpers/render'; const { Text } = Typography; const RechargeCard = ({ t, enableOnlineTopUp, enableStripeTopUp, enableCreemTopUp, creemProducts, creemPreTopUp, presetAmounts, selectedPreset, selectPresetAmount, formatLargeNumber, priceRatio, topUpCount, minTopUp, renderQuotaWithAmount, getAmount, setTopUpCount, setSelectedPreset, renderAmount, amountLoading, payMethods, preTopUp, paymentLoading, payWay, redemptionCode, setRedemptionCode, topUp, isSubmitting, topUpLink, openTopUpLink, userState, renderQuota, statusLoading, topupInfo, onOpenHistory, }) => { const onlineFormApiRef = useRef(null); const redeemFormApiRef = useRef(null); const showAmountSkeleton = useMinimumLoadingTime(amountLoading); console.log(' enabled screem ?', enableCreemTopUp, ' products ?', creemProducts); return ( {/* 卡片头部 */}
{t('账户充值')}
{t('多种充值方式,安全便捷')}
{/* 统计数据 */}
{t('账户统计')}
{/* 统计数据 */}
{/* 当前余额 */}
{renderQuota(userState?.user?.quota)}
{t('当前余额')}
{/* 历史消耗 */}
{renderQuota(userState?.user?.used_quota)}
{t('历史消耗')}
{/* 请求次数 */}
{userState?.user?.request_count || 0}
{t('请求次数')}
} > {/* 在线充值表单 */} {statusLoading ? (
) : enableOnlineTopUp || enableStripeTopUp || enableCreemTopUp ? (
(onlineFormApiRef.current = api)} initValues={{ topUpCount: topUpCount }} >
{(enableOnlineTopUp || enableStripeTopUp) && ( { if (value && value >= 1) { setTopUpCount(value); setSelectedPreset(null); await getAmount(value); } }} onBlur={(e) => { const value = parseInt(e.target.value); if (!value || value < 1) { setTopUpCount(1); getAmount(1); } }} formatter={(value) => (value ? `${value}` : '')} parser={(value) => value ? parseInt(value.replace(/[^\d]/g, '')) : 0 } extraText={ } > {t('实付金额:')} {renderAmount()} } style={{ width: '100%' }} /> {payMethods && payMethods.length > 0 ? ( {payMethods.map((payMethod) => { const minTopupVal = Number(payMethod.min_topup) || 0; const isStripe = payMethod.type === 'stripe'; const disabled = (!enableOnlineTopUp && !isStripe) || (!enableStripeTopUp && isStripe) || minTopupVal > Number(topUpCount || 0); const buttonEl = ( ); return disabled && minTopupVal > Number(topUpCount || 0) ? ( {buttonEl} ) : ( {buttonEl} ); })} ) : (
{t('暂无可用的支付方式,请联系管理员配置')}
)}
)} {(enableOnlineTopUp || enableStripeTopUp) && ( {t('选择充值额度')} {(() => { const { symbol, rate, type } = getCurrencyConfig(); if (type === 'USD') return null; return ( (1 $ = {rate.toFixed(2)} {symbol}) ); })()}
} >
{presetAmounts.map((preset, index) => { const discount = preset.discount || topupInfo?.discount?.[preset.value] || 1.0; const originalPrice = preset.value * priceRatio; const discountedPrice = originalPrice * discount; const hasDiscount = discount < 1.0; const actualPay = discountedPrice; const save = originalPrice - discountedPrice; // 根据当前货币类型换算显示金额和数量 const { symbol, rate, type } = getCurrencyConfig(); const statusStr = localStorage.getItem('status'); let usdRate = 7; // 默认CNY汇率 try { if (statusStr) { const s = JSON.parse(statusStr); usdRate = s?.usd_exchange_rate || 7; } } catch (e) {} let displayValue = preset.value; // 显示的数量 let displayActualPay = actualPay; let displaySave = save; if (type === 'USD') { // 数量保持USD,价格从CNY转USD displayActualPay = actualPay / usdRate; displaySave = save / usdRate; } else if (type === 'CNY') { // 数量转CNY,价格已是CNY displayValue = preset.value * usdRate; } else if (type === 'CUSTOM') { // 数量和价格都转自定义货币 displayValue = preset.value * rate; displayActualPay = (actualPay / usdRate) * rate; displaySave = (save / usdRate) * rate; } return ( { selectPresetAmount(preset); onlineFormApiRef.current?.setValue( 'topUpCount', preset.value, ); }} >
{formatLargeNumber(displayValue)} {symbol} {hasDiscount && ( {t('折').includes('off') ? ( (1 - parseFloat(discount)) * 100 ).toFixed(1) : (discount * 10).toFixed(1)} {t('折')} )}
{t('实付')} {symbol} {displayActualPay.toFixed(2)}, {hasDiscount ? `${t('节省')} ${symbol}${displaySave.toFixed(2)}` : `${t('节省')} ${symbol}0.00`}
); })}
)} {/* Creem 充值区域 */} {enableCreemTopUp && creemProducts.length > 0 && (
{creemProducts.map((product, index) => ( creemPreTopUp(product)} className='cursor-pointer !rounded-2xl transition-all hover:shadow-md border-gray-200 hover:border-gray-300' bodyStyle={{ textAlign: 'center', padding: '16px' }} >
{product.name}
{t('充值额度')}: {product.quota}
{product.currency === 'EUR' ? '€' : '$'}{product.price}
))}
)}
) : ( )}
{/* 兑换码充值 */} {t('兑换码充值')} } >
(redeemFormApiRef.current = api)} initValues={{ redemptionCode: redemptionCode }} > setRedemptionCode(value)} prefix={} suffix={
} showClear style={{ width: '100%' }} extraText={ topUpLink && ( {t('在找兑换码?')} {t('购买兑换码')} ) } />
); }; export default RechargeCard;