|
|
|
@@ -235,60 +235,70 @@ const RechargeCard = ({ |
|
|
|
{(enableOnlineTopUp || enableStripeTopUp || enableWechatTopUp || enableAlipayTopUp) && ( |
|
|
|
<Row gutter={12}> |
|
|
|
<Col xs={24} sm={24} md={24} lg={10} xl={10}> |
|
|
|
<Form.InputNumber |
|
|
|
field='topUpCount' |
|
|
|
label={t('充值数量')} |
|
|
|
disabled={!enableOnlineTopUp && !enableStripeTopUp && !enableWechatTopUp && !enableAlipayTopUp} |
|
|
|
placeholder={ |
|
|
|
t('充值数量,最低 ') + renderQuotaWithAmount(minTopUp) |
|
|
|
} |
|
|
|
value={topUpCount} |
|
|
|
min={minTopUp} |
|
|
|
max={999999999} |
|
|
|
step={1} |
|
|
|
precision={0} |
|
|
|
onChange={async (value) => { |
|
|
|
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={ |
|
|
|
<Skeleton |
|
|
|
loading={showAmountSkeleton} |
|
|
|
active |
|
|
|
{(() => { |
|
|
|
const { symbol: curSymbol, rate: curRate, type: curType } = getCurrencyConfig(); |
|
|
|
const needsConvert = curType !== 'USD' && curType !== 'TOKENS'; |
|
|
|
const displayMin = needsConvert ? Math.ceil(minTopUp * curRate) : minTopUp; |
|
|
|
return ( |
|
|
|
<Form.InputNumber |
|
|
|
field='topUpCount' |
|
|
|
label={t('充值数量')} |
|
|
|
disabled={!enableOnlineTopUp && !enableStripeTopUp && !enableWechatTopUp && !enableAlipayTopUp} |
|
|
|
placeholder={ |
|
|
|
<Skeleton.Title |
|
|
|
style={{ |
|
|
|
width: 120, |
|
|
|
height: 20, |
|
|
|
borderRadius: 6, |
|
|
|
}} |
|
|
|
/> |
|
|
|
t('充值数量,最低 ') + displayMin |
|
|
|
} |
|
|
|
> |
|
|
|
<Text type='secondary' className='text-red-600'> |
|
|
|
{t('实付金额:')} |
|
|
|
<span style={{ color: 'red' }}> |
|
|
|
{renderAmount()} |
|
|
|
</span> |
|
|
|
</Text> |
|
|
|
</Skeleton> |
|
|
|
} |
|
|
|
style={{ width: '100%' }} |
|
|
|
/> |
|
|
|
value={needsConvert ? Math.round(topUpCount * curRate) : topUpCount} |
|
|
|
min={displayMin} |
|
|
|
max={needsConvert ? Math.round(999999999 * curRate) : 999999999} |
|
|
|
step={needsConvert ? curRate : 1} |
|
|
|
precision={0} |
|
|
|
onChange={async (displayValue) => { |
|
|
|
const rawValue = needsConvert ? Math.round(displayValue / curRate) : displayValue; |
|
|
|
if (rawValue && rawValue >= 1) { |
|
|
|
setTopUpCount(rawValue); |
|
|
|
setSelectedPreset(null); |
|
|
|
await getAmount(rawValue); |
|
|
|
} |
|
|
|
}} |
|
|
|
onBlur={(e) => { |
|
|
|
const displayVal = parseInt(e.target.value); |
|
|
|
const rawVal = needsConvert ? Math.round(displayVal / curRate) : displayVal; |
|
|
|
if (!rawVal || rawVal < 1) { |
|
|
|
setTopUpCount(1); |
|
|
|
getAmount(1); |
|
|
|
} |
|
|
|
}} |
|
|
|
formatter={(value) => (value ? `${value}` : '')} |
|
|
|
parser={(value) => |
|
|
|
value ? parseInt(value.replace(/[^\d]/g, '')) : 0 |
|
|
|
} |
|
|
|
suffix={curSymbol} |
|
|
|
style={{ width: '100%' }} |
|
|
|
extraText={ |
|
|
|
<Skeleton |
|
|
|
loading={showAmountSkeleton} |
|
|
|
active |
|
|
|
placeholder={ |
|
|
|
<Skeleton.Title |
|
|
|
style={{ |
|
|
|
width: 120, |
|
|
|
height: 20, |
|
|
|
borderRadius: 6, |
|
|
|
}} |
|
|
|
/> |
|
|
|
} |
|
|
|
> |
|
|
|
<Text type='secondary' className='text-red-600'> |
|
|
|
{t('实付金额:')} |
|
|
|
<span style={{ color: 'red' }}> |
|
|
|
{renderAmount()} |
|
|
|
</span> |
|
|
|
</Text> |
|
|
|
</Skeleton> |
|
|
|
} |
|
|
|
/> |
|
|
|
); |
|
|
|
})()} |
|
|
|
</Col> |
|
|
|
<Col xs={24} sm={24} md={24} lg={14} xl={14}> |
|
|
|
<Form.Slot label={t('选择支付方式')}> |
|
|
|
@@ -377,7 +387,6 @@ const RechargeCard = ({ |
|
|
|
{(() => { |
|
|
|
const { symbol, rate, type } = getCurrencyConfig(); |
|
|
|
if (type === 'USD') return null; |
|
|
|
|
|
|
|
return ( |
|
|
|
<span |
|
|
|
style={{ |
|
|
|
@@ -393,6 +402,11 @@ const RechargeCard = ({ |
|
|
|
</div> |
|
|
|
} |
|
|
|
> |
|
|
|
{(() => { |
|
|
|
const { symbol: pSymbol, rate: pRate, type: pType } = getCurrencyConfig(); |
|
|
|
const needsConvert = pType !== 'USD' && pType !== 'TOKENS'; |
|
|
|
|
|
|
|
return ( |
|
|
|
<div className='grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2'> |
|
|
|
{presetAmounts.map((preset, index) => { |
|
|
|
const discount = |
|
|
|
@@ -403,34 +417,9 @@ const RechargeCard = ({ |
|
|
|
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; |
|
|
|
} |
|
|
|
const displayValue = needsConvert ? preset.value * pRate : preset.value; |
|
|
|
const displayActualPay = pType === 'USD' ? actualPay / pRate : actualPay; |
|
|
|
const displaySave = pType === 'USD' ? save / pRate : save; |
|
|
|
|
|
|
|
return ( |
|
|
|
<Card |
|
|
|
@@ -449,7 +438,7 @@ const RechargeCard = ({ |
|
|
|
selectPresetAmount(preset); |
|
|
|
onlineFormApiRef.current?.setValue( |
|
|
|
'topUpCount', |
|
|
|
preset.value, |
|
|
|
needsConvert ? Math.round(preset.value * pRate) : preset.value, |
|
|
|
); |
|
|
|
}} |
|
|
|
> |
|
|
|
@@ -459,7 +448,7 @@ const RechargeCard = ({ |
|
|
|
style={{ margin: '0 0 8px 0' }} |
|
|
|
> |
|
|
|
<Coins size={18} /> |
|
|
|
{formatLargeNumber(displayValue)} {symbol} |
|
|
|
{formatLargeNumber(displayValue)} {pSymbol} |
|
|
|
{hasDiscount && ( |
|
|
|
<Tag style={{ marginLeft: 4 }} color='green'> |
|
|
|
{t('折').includes('off') |
|
|
|
@@ -476,17 +465,19 @@ const RechargeCard = ({ |
|
|
|
margin: '4px 0', |
|
|
|
}} |
|
|
|
> |
|
|
|
{t('实付')} {symbol} |
|
|
|
{t('实付')} {pSymbol} |
|
|
|
{displayActualPay.toFixed(2)}, |
|
|
|
{hasDiscount |
|
|
|
? `${t('节省')} ${symbol}${displaySave.toFixed(2)}` |
|
|
|
: `${t('节省')} ${symbol}0.00`} |
|
|
|
? `${t('节省')} ${pSymbol}${displaySave.toFixed(2)}` |
|
|
|
: `${t('节省')} ${pSymbol}0.00`} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
); |
|
|
|
})} |
|
|
|
</div> |
|
|
|
); |
|
|
|
})()} |
|
|
|
</Form.Slot> |
|
|
|
)} |
|
|
|
|
|
|
|
|