From d24d68a9168a77d97e242fe404d3ab591168729a Mon Sep 17 00:00:00 2001 From: fengsilin Date: Fri, 24 Apr 2026 16:12:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(i18n):=20=E4=BF=AE=E5=A4=8D=E4=BB=A4?= =?UTF-8?q?=E7=89=8C=E5=92=8C=E5=85=85=E5=80=BC=E9=A1=B5=E9=9D=A2=E8=B4=A7?= =?UTF-8?q?=E5=B8=81=E6=98=BE=E7=A4=BA=E4=B8=8D=E4=B8=80=E8=87=B4=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 令牌创建:快捷选项标签根据系统货币设置动态生成,替换硬编码美元 - 充值页面:输入框显示值与预设卡片统一换算为本地货币,内部值仍为原始单位 - 使用 getQuotaPerUnit() 替代魔数 500000 - 消除 RechargeCard 中 getCurrencyConfig() 的 N+1 重复调用 Co-Authored-By: Claude Opus 4.7 --- .../table/tokens/modals/EditTokenModal.jsx | 21 ++- web/src/components/topup/RechargeCard.jsx | 163 +++++++++--------- 2 files changed, 90 insertions(+), 94 deletions(-) diff --git a/web/src/components/table/tokens/modals/EditTokenModal.jsx b/web/src/components/table/tokens/modals/EditTokenModal.jsx index f477916..73ad619 100644 --- a/web/src/components/table/tokens/modals/EditTokenModal.jsx +++ b/web/src/components/table/tokens/modals/EditTokenModal.jsx @@ -27,7 +27,9 @@ import { renderQuotaWithPrompt, getModelCategories, selectFilter, + getCurrencyConfig, } from '../../../../helpers'; +import { getQuotaPerUnit } from '../../../../helpers/quota'; import { useIsMobile } from '../../../../hooks/common/useIsMobile'; import { Button, @@ -519,14 +521,17 @@ const EditTokenModal = (props) => { ? [] : [{ required: true, message: t('请输入额度') }] } - data={[ - { value: 500000, label: '1$' }, - { value: 5000000, label: '10$' }, - { value: 25000000, label: '50$' }, - { value: 50000000, label: '100$' }, - { value: 250000000, label: '500$' }, - { value: 500000000, label: '1000$' }, - ]} + data={(() => { + const { symbol, rate, type } = getCurrencyConfig(); + const unit = getQuotaPerUnit(); + return [1, 10, 50, 100, 500, 1000].map((usd) => { + const value = Math.round(usd * unit); + const label = type === 'TOKENS' + ? `${Math.round(usd * unit / 1000)}K` + : `${symbol}${Math.round(usd * rate)}`; + return { value, label }; + }); + })()} /> diff --git a/web/src/components/topup/RechargeCard.jsx b/web/src/components/topup/RechargeCard.jsx index a9907fe..c13ae3d 100644 --- a/web/src/components/topup/RechargeCard.jsx +++ b/web/src/components/topup/RechargeCard.jsx @@ -234,60 +234,70 @@ const RechargeCard = ({ {(enableOnlineTopUp || enableStripeTopUp || enableWechatTopUp) && ( - { - 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={ - { + const { symbol: curSymbol, rate: curRate, type: curType } = getCurrencyConfig(); + const needsConvert = curType !== 'USD' && curType !== 'TOKENS'; + const displayMin = needsConvert ? Math.ceil(minTopUp * curRate) : minTopUp; + return ( + + t('充值数量,最低 ') + displayMin } - > - - {t('实付金额:')} - - {renderAmount()} - - - - } - 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={ + + } + > + + {t('实付金额:')} + + {renderAmount()} + + + + } + /> + ); + })()} @@ -374,7 +384,6 @@ const RechargeCard = ({ {(() => { const { symbol, rate, type } = getCurrencyConfig(); if (type === 'USD') return null; - return ( } > + {(() => { + const { symbol: pSymbol, rate: pRate, type: pType } = getCurrencyConfig(); + const needsConvert = pType !== 'USD' && pType !== 'TOKENS'; + + return (
{presetAmounts.map((preset, index) => { const discount = @@ -400,34 +414,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 ( @@ -456,7 +445,7 @@ const RechargeCard = ({ style={{ margin: '0 0 8px 0' }} > - {formatLargeNumber(displayValue)} {symbol} + {formatLargeNumber(displayValue)} {pSymbol} {hasDiscount && ( {t('折').includes('off') @@ -473,17 +462,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`}
); })} + ); + })()}
)}