diff --git a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx index 59ec89d6..9af30226 100644 --- a/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx +++ b/web/src/components/table/usage-logs/UsageLogsColumnDefs.jsx @@ -419,7 +419,7 @@ export const getLogsColumns = ({ }, { key: COLUMN_KEYS.PROMPT, - title: t('提示'), + title: t('输入'), dataIndex: 'prompt_tokens', render: (text, record, index) => { return record.type === 0 || record.type === 2 || record.type === 5 ? ( @@ -431,7 +431,7 @@ export const getLogsColumns = ({ }, { key: COLUMN_KEYS.COMPLETION, - title: t('补全'), + title: t('输出'), dataIndex: 'completion_tokens', render: (text, record, index) => { return parseInt(text) > 0 && diff --git a/web/src/components/topup/RechargeCard.jsx b/web/src/components/topup/RechargeCard.jsx index ee251a0b..85a4220e 100644 --- a/web/src/components/topup/RechargeCard.jsx +++ b/web/src/components/topup/RechargeCard.jsx @@ -37,6 +37,7 @@ import { SiAlipay, SiWechat, SiStripe } from 'react-icons/si'; import { CreditCard, Coins, Wallet, BarChart2, TrendingUp } from 'lucide-react'; import { IconGift } from '@douyinfe/semi-icons'; import { useMinimumLoadingTime } from '../../hooks/common/useMinimumLoadingTime'; +import { getCurrencyConfig } from '../../helpers/render'; const { Text } = Typography; @@ -343,25 +344,8 @@ const RechargeCard = ({
{t('选择充值额度')} {(() => { - const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD'; - if (quotaDisplayType === 'USD') return null; - - const statusStr = localStorage.getItem('status'); - let symbol = '¥'; - let rate = 7; - - try { - if (statusStr) { - const s = JSON.parse(statusStr); - if (quotaDisplayType === 'CNY') { - rate = s?.usd_exchange_rate || 7; - symbol = '¥'; - } else if (quotaDisplayType === 'CUSTOM') { - rate = s?.custom_currency_exchange_rate || 1; - symbol = s?.custom_currency_symbol || '¤'; - } - } - } catch (e) {} + const { symbol, rate, type } = getCurrencyConfig(); + if (type === 'USD') return null; return ( @@ -385,15 +369,9 @@ const RechargeCard = ({ const save = originalPrice - discountedPrice; // 根据当前货币类型换算显示金额和数量 - const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD'; - let symbol = '¥'; - let displayValue = preset.value; // 显示的数量 - let displayActualPay = actualPay; - let displaySave = save; - - // 获取汇率 + const { symbol, rate, type } = getCurrencyConfig(); const statusStr = localStorage.getItem('status'); - let usdRate = 7; // 默认汇率 1 USD = 7 CNY + let usdRate = 7; // 默认CNY汇率 try { if (statusStr) { const s = JSON.parse(statusStr); @@ -401,35 +379,22 @@ const RechargeCard = ({ } } catch (e) {} - if (quotaDisplayType === 'USD') { - symbol = '$'; - // 数量和价格都保持美元(系统默认) - displayValue = preset.value; + let displayValue = preset.value; // 显示的数量 + let displayActualPay = actualPay; + let displaySave = save; + + if (type === 'USD') { + // 数量保持USD,价格从CNY转USD displayActualPay = actualPay / usdRate; displaySave = save / usdRate; - } else if (quotaDisplayType === 'CNY') { - symbol = '¥'; - // 数量需要换算为人民币 + } else if (type === 'CNY') { + // 数量转CNY,价格已是CNY displayValue = preset.value * usdRate; - // 价格已经是人民币,保持不变 - displayActualPay = actualPay; - displaySave = save; - } else if (quotaDisplayType === 'CUSTOM') { - let customSymbol = '¤'; - let customRate = 1; - try { - if (statusStr) { - const s = JSON.parse(statusStr); - customSymbol = s?.custom_currency_symbol || '¤'; - customRate = s?.custom_currency_exchange_rate || 1; - } - } catch (e) {} - symbol = customSymbol; - // 数量从USD转为自定义货币 - displayValue = preset.value * customRate; - // 价格从CNY先转USD再转自定义货币 - displayActualPay = (actualPay / usdRate) * customRate; - displaySave = (save / usdRate) * customRate; + } else if (type === 'CUSTOM') { + // 数量和价格都转自定义货币 + displayValue = preset.value * rate; + displayActualPay = (actualPay / usdRate) * rate; + displaySave = (save / usdRate) * rate; } return ( diff --git a/web/src/helpers/render.jsx b/web/src/helpers/render.jsx index 6559b1b6..b5fcb4d6 100644 --- a/web/src/helpers/render.jsx +++ b/web/src/helpers/render.jsx @@ -922,6 +922,50 @@ export function renderQuotaWithAmount(amount) { return '$' + amount; } +/** + * 获取当前货币配置信息 + * @returns {Object} - { symbol, rate, type } + */ +export function getCurrencyConfig() { + const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD'; + const statusStr = localStorage.getItem('status'); + + let symbol = '$'; + let rate = 1; + + if (quotaDisplayType === 'CNY') { + symbol = '¥'; + try { + if (statusStr) { + const s = JSON.parse(statusStr); + rate = s?.usd_exchange_rate || 7; + } + } catch (e) {} + } else if (quotaDisplayType === 'CUSTOM') { + try { + if (statusStr) { + const s = JSON.parse(statusStr); + symbol = s?.custom_currency_symbol || '¤'; + rate = s?.custom_currency_exchange_rate || 1; + } + } catch (e) {} + } + + return { symbol, rate, type: quotaDisplayType }; +} + +/** + * 将美元金额转换为当前选择的货币 + * @param {number} usdAmount - 美元金额 + * @param {number} digits - 小数位数 + * @returns {string} - 格式化后的货币字符串 + */ +export function convertUSDToCurrency(usdAmount, digits = 2) { + const { symbol, rate } = getCurrencyConfig(); + const convertedAmount = usdAmount * rate; + return symbol + convertedAmount.toFixed(digits); +} + export function renderQuota(quota, digits = 2) { let quotaPerUnit = localStorage.getItem('quota_per_unit'); const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD'; @@ -1084,14 +1128,20 @@ export function renderModelPrice( user_group_ratio, ); groupRatio = effectiveGroupRatio; + + // 获取货币配置 + const { symbol, rate } = getCurrencyConfig(); if (modelPrice !== -1) { + const displayPrice = (modelPrice * rate).toFixed(6); + const displayTotal = (modelPrice * groupRatio * rate).toFixed(6); return i18next.t( - '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}', + '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}', { - price: modelPrice, + symbol: symbol, + price: displayPrice, ratio: groupRatio, - total: modelPrice * groupRatio, + total: displayTotal, ratioType: ratioLabel, }, ); @@ -1127,19 +1177,21 @@ export function renderModelPrice( <>

- {i18next.t('输入价格:${{price}} / 1M tokens{{audioPrice}}', { - price: inputRatioPrice, + {i18next.t('输入价格:{{symbol}}{{price}} / 1M tokens{{audioPrice}}', { + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), audioPrice: audioInputSeperatePrice - ? `,音频 $${audioInputPrice} / 1M tokens` + ? `,音频 ${symbol}${(audioInputPrice * rate).toFixed(6)} / 1M tokens` : '', })}

{i18next.t( - '输出价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})', + '输出价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})', { - price: inputRatioPrice, - total: completionRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (completionRatioPrice * rate).toFixed(6), completionRatio: completionRatio, }, )} @@ -1147,10 +1199,11 @@ export function renderModelPrice( {cacheTokens > 0 && (

{i18next.t( - '缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', + '缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', { - price: inputRatioPrice, - total: inputRatioPrice * cacheRatio, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (inputRatioPrice * cacheRatio * rate).toFixed(6), cacheRatio: cacheRatio, }, )} @@ -1159,11 +1212,12 @@ export function renderModelPrice( {image && imageOutputTokens > 0 && (

{i18next.t( - '图片输入价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (图片倍率: {{imageRatio}})', + '图片输入价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (图片倍率: {{imageRatio}})', { - price: imageRatioPrice, + symbol: symbol, + price: (imageRatioPrice * rate).toFixed(6), ratio: groupRatio, - total: imageRatioPrice * groupRatio, + total: (imageRatioPrice * groupRatio * rate).toFixed(6), imageRatio: imageRatio, }, )} @@ -1171,22 +1225,25 @@ export function renderModelPrice( )} {webSearch && webSearchCallCount > 0 && (

- {i18next.t('Web搜索价格:${{price}} / 1K 次', { - price: webSearchPrice, + {i18next.t('Web搜索价格:{{symbol}}{{price}} / 1K 次', { + symbol: symbol, + price: (webSearchPrice * rate).toFixed(6), })}

)} {fileSearch && fileSearchCallCount > 0 && (

- {i18next.t('文件搜索价格:${{price}} / 1K 次', { - price: fileSearchPrice, + {i18next.t('文件搜索价格:{{symbol}}{{price}} / 1K 次', { + symbol: symbol, + price: (fileSearchPrice * rate).toFixed(6), })}

)} {imageGenerationCall && imageGenerationCallPrice > 0 && (

- {i18next.t('图片生成调用:${{price}} / 1次', { - price: imageGenerationCallPrice, + {i18next.t('图片生成调用:{{symbol}}{{price}} / 1次', { + symbol: symbol, + price: (imageGenerationCallPrice * rate).toFixed(6), })}

)} @@ -1196,50 +1253,55 @@ export function renderModelPrice( let inputDesc = ''; if (image && imageOutputTokens > 0) { inputDesc = i18next.t( - '(输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}}', + '(输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * {{symbol}}{{price}}', { nonImageInput: inputTokens - imageOutputTokens, imageInput: imageOutputTokens, imageRatio: imageRatio, - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), }, ); } else if (cacheTokens > 0) { inputDesc = i18next.t( - '(输入 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}}', + '(输入 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}}', { nonCacheInput: inputTokens - cacheTokens, cacheInput: cacheTokens, - price: inputRatioPrice, - cachePrice: cacheRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + cachePrice: (cacheRatioPrice * rate).toFixed(6), }, ); } else if (audioInputSeperatePrice && audioInputTokens > 0) { inputDesc = i18next.t( - '(输入 {{nonAudioInput}} tokens / 1M tokens * ${{price}} + 音频输入 {{audioInput}} tokens / 1M tokens * ${{audioPrice}}', + '(输入 {{nonAudioInput}} tokens / 1M tokens * {{symbol}}{{price}} + 音频输入 {{audioInput}} tokens / 1M tokens * {{symbol}}{{audioPrice}}', { nonAudioInput: inputTokens - audioInputTokens, audioInput: audioInputTokens, - price: inputRatioPrice, - audioPrice: audioInputPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + audioPrice: (audioInputPrice * rate).toFixed(6), }, ); } else { inputDesc = i18next.t( - '(输入 {{input}} tokens / 1M tokens * ${{price}}', + '(输入 {{input}} tokens / 1M tokens * {{symbol}}{{price}}', { input: inputTokens, - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), }, ); } // 构建输出部分描述 const outputDesc = i18next.t( - '输出 {{completion}} tokens / 1M tokens * ${{compPrice}}) * {{ratioType}} {{ratio}}', + '输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}', { completion: completionTokens, - compPrice: completionRatioPrice, + symbol: symbol, + compPrice: (completionRatioPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, }, @@ -1249,10 +1311,11 @@ export function renderModelPrice( const extraServices = [ webSearch && webSearchCallCount > 0 ? i18next.t( - ' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}} {{ratio}}', + ' + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}', { count: webSearchCallCount, - price: webSearchPrice, + symbol: symbol, + price: (webSearchPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, }, @@ -1260,10 +1323,11 @@ export function renderModelPrice( : '', fileSearch && fileSearchCallCount > 0 ? i18next.t( - ' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}} {{ratio}}', + ' + 文件搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}', { count: fileSearchCallCount, - price: fileSearchPrice, + symbol: symbol, + price: (fileSearchPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, }, @@ -1271,9 +1335,10 @@ export function renderModelPrice( : '', imageGenerationCall && imageGenerationCallPrice > 0 ? i18next.t( - ' + 图片生成调用 ${{price}} / 1次 * {{ratioType}} {{ratio}}', + ' + 图片生成调用 {{symbol}}{{price}} / 1次 * {{ratioType}} {{ratio}}', { - price: imageGenerationCallPrice, + symbol: symbol, + price: (imageGenerationCallPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, }, @@ -1282,12 +1347,13 @@ export function renderModelPrice( ].join(''); return i18next.t( - '{{inputDesc}} + {{outputDesc}}{{extraServices}} = ${{total}}', + '{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}', { inputDesc, outputDesc, extraServices, - total: price.toFixed(6), + symbol: symbol, + total: (price * rate).toFixed(6), }, ); })()} @@ -1318,10 +1384,14 @@ export function renderLogContent( label: ratioLabel, useUserGroupRatio: useUserGroupRatio, } = getEffectiveRatio(groupRatio, user_group_ratio); + + // 获取货币配置 + const { symbol, rate } = getCurrencyConfig(); if (modelPrice !== -1) { - return i18next.t('模型价格 ${{price}},{{ratioType}} {{ratio}}', { - price: modelPrice, + return i18next.t('模型价格 {{symbol}}{{price}},{{ratioType}} {{ratio}}', { + symbol: symbol, + price: (modelPrice * rate).toFixed(6), ratioType: ratioLabel, ratio, }); @@ -1414,14 +1484,19 @@ export function renderAudioModelPrice( user_group_ratio, ); groupRatio = effectiveGroupRatio; + + // 获取货币配置 + const { symbol, rate } = getCurrencyConfig(); + // 1 ratio = $0.002 / 1K tokens if (modelPrice !== -1) { return i18next.t( - '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}', + '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}', { - price: modelPrice, + symbol: symbol, + price: (modelPrice * rate).toFixed(6), ratio: groupRatio, - total: modelPrice * groupRatio, + total: (modelPrice * groupRatio * rate).toFixed(6), ratioType: ratioLabel, }, ); @@ -1456,16 +1531,18 @@ export function renderAudioModelPrice( <>

- {i18next.t('提示价格:${{price}} / 1M tokens', { - price: inputRatioPrice, + {i18next.t('提示价格:{{symbol}}{{price}} / 1M tokens', { + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), })}

{i18next.t( - '补全价格:${{price}} * {{completionRatio}} = ${{total}} / 1M tokens (补全倍率: {{completionRatio}})', + '补全价格:{{symbol}}{{price}} * {{completionRatio}} = {{symbol}}{{total}} / 1M tokens (补全倍率: {{completionRatio}})', { - price: inputRatioPrice, - total: completionRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (completionRatioPrice * rate).toFixed(6), completionRatio: completionRatio, }, )} @@ -1473,10 +1550,11 @@ export function renderAudioModelPrice( {cacheTokens > 0 && (

{i18next.t( - '缓存价格:${{price}} * {{cacheRatio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', + '缓存价格:{{symbol}}{{price}} * {{cacheRatio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', { - price: inputRatioPrice, - total: inputRatioPrice * cacheRatio, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (inputRatioPrice * cacheRatio * rate).toFixed(6), cacheRatio: cacheRatio, }, )} @@ -1484,20 +1562,22 @@ export function renderAudioModelPrice( )}

{i18next.t( - '音频提示价格:${{price}} * {{audioRatio}} = ${{total}} / 1M tokens (音频倍率: {{audioRatio}})', + '音频提示价格:{{symbol}}{{price}} * {{audioRatio}} = {{symbol}}{{total}} / 1M tokens (音频倍率: {{audioRatio}})', { - price: inputRatioPrice, - total: inputRatioPrice * audioRatio, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (inputRatioPrice * audioRatio * rate).toFixed(6), audioRatio: audioRatio, }, )}

{i18next.t( - '音频补全价格:${{price}} * {{audioRatio}} * {{audioCompRatio}} = ${{total}} / 1M tokens (音频补全倍率: {{audioCompRatio}})', + '音频补全价格:{{symbol}}{{price}} * {{audioRatio}} * {{audioCompRatio}} = {{symbol}}{{total}} / 1M tokens (音频补全倍率: {{audioCompRatio}})', { - price: inputRatioPrice, - total: inputRatioPrice * audioRatio * audioCompletionRatio, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), + total: (inputRatioPrice * audioRatio * audioCompletionRatio * rate).toFixed(6), audioRatio: audioRatio, audioCompRatio: audioCompletionRatio, }, @@ -1506,48 +1586,52 @@ export function renderAudioModelPrice(

{cacheTokens > 0 ? i18next.t( - '文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}', + '文字提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} = {{symbol}}{{total}}', { nonCacheInput: inputTokens - cacheTokens, cacheInput: cacheTokens, - cachePrice: inputRatioPrice * cacheRatio, - price: inputRatioPrice, + symbol: symbol, + cachePrice: (inputRatioPrice * cacheRatio * rate).toFixed(6), + price: (inputRatioPrice * rate).toFixed(6), completion: completionTokens, - compPrice: completionRatioPrice, - total: textPrice.toFixed(6), + compPrice: (completionRatioPrice * rate).toFixed(6), + total: (textPrice * rate).toFixed(6), }, ) : i18next.t( - '文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}', + '文字提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 文字补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} = {{symbol}}{{total}}', { input: inputTokens, - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), completion: completionTokens, - compPrice: completionRatioPrice, - total: textPrice.toFixed(6), + compPrice: (completionRatioPrice * rate).toFixed(6), + total: (textPrice * rate).toFixed(6), }, )}

{i18next.t( - '音频提示 {{input}} tokens / 1M tokens * ${{audioInputPrice}} + 音频补全 {{completion}} tokens / 1M tokens * ${{audioCompPrice}} = ${{total}}', + '音频提示 {{input}} tokens / 1M tokens * {{symbol}}{{audioInputPrice}} + 音频补全 {{completion}} tokens / 1M tokens * {{symbol}}{{audioCompPrice}} = {{symbol}}{{total}}', { input: audioInputTokens, completion: audioCompletionTokens, - audioInputPrice: audioRatio * inputRatioPrice, + symbol: symbol, + audioInputPrice: (audioRatio * inputRatioPrice * rate).toFixed(6), audioCompPrice: - audioRatio * audioCompletionRatio * inputRatioPrice, - total: audioPrice.toFixed(6), + (audioRatio * audioCompletionRatio * inputRatioPrice * rate).toFixed(6), + total: (audioPrice * rate).toFixed(6), }, )}

{i18next.t( - '总价:文字价格 {{textPrice}} + 音频价格 {{audioPrice}} = ${{total}}', + '总价:文字价格 {{textPrice}} + 音频价格 {{audioPrice}} = {{symbol}}{{total}}', { - total: price.toFixed(6), - textPrice: textPrice.toFixed(6), - audioPrice: audioPrice.toFixed(6), + symbol: symbol, + total: (price * rate).toFixed(6), + textPrice: (textPrice * rate).toFixed(6), + audioPrice: (audioPrice * rate).toFixed(6), }, )}

@@ -1584,15 +1668,19 @@ export function renderClaudeModelPrice( user_group_ratio, ); groupRatio = effectiveGroupRatio; + + // 获取货币配置 + const { symbol, rate } = getCurrencyConfig(); if (modelPrice !== -1) { return i18next.t( - '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}', + '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}', { - price: modelPrice, + symbol: symbol, + price: (modelPrice * rate).toFixed(6), ratioType: ratioLabel, ratio: groupRatio, - total: modelPrice * groupRatio, + total: (modelPrice * groupRatio * rate).toFixed(6), }, ); } else { @@ -1621,28 +1709,31 @@ export function renderClaudeModelPrice( <>

- {i18next.t('提示价格:${{price}} / 1M tokens', { - price: inputRatioPrice, + {i18next.t('提示价格:{{symbol}}{{price}} / 1M tokens', { + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), })}

{i18next.t( - '补全价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens', + '补全价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens', { - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), ratio: completionRatio, - total: completionRatioPrice, + total: (completionRatioPrice * rate).toFixed(6), }, )}

{cacheTokens > 0 && (

{i18next.t( - '缓存价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', + '缓存价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存倍率: {{cacheRatio}})', { - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), ratio: cacheRatio, - total: cacheRatioPrice, + total: (cacheRatioPrice * rate).toFixed(2), cacheRatio: cacheRatio, }, )} @@ -1651,11 +1742,12 @@ export function renderClaudeModelPrice( {cacheCreationTokens > 0 && (

{i18next.t( - '缓存创建价格:${{price}} * {{ratio}} = ${{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})', + '缓存创建价格:{{symbol}}{{price}} * {{ratio}} = {{symbol}}{{total}} / 1M tokens (缓存创建倍率: {{cacheCreationRatio}})', { - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), ratio: cacheCreationRatio, - total: cacheCreationRatioPrice, + total: (cacheCreationRatioPrice * rate).toFixed(6), cacheCreationRatio: cacheCreationRatio, }, )} @@ -1665,33 +1757,35 @@ export function renderClaudeModelPrice(

{cacheTokens > 0 || cacheCreationTokens > 0 ? i18next.t( - '提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * {{ratioType}} {{ratio}} = ${{total}}', + '提示 {{nonCacheInput}} tokens / 1M tokens * {{symbol}}{{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * {{symbol}}{{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * {{symbol}}{{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}', { nonCacheInput: nonCachedTokens, cacheInput: cacheTokens, cacheRatio: cacheRatio, cacheCreationInput: cacheCreationTokens, cacheCreationRatio: cacheCreationRatio, - cachePrice: cacheRatioPrice, - cacheCreationPrice: cacheCreationRatioPrice, - price: inputRatioPrice, + symbol: symbol, + cachePrice: (cacheRatioPrice * rate).toFixed(2), + cacheCreationPrice: (cacheCreationRatioPrice * rate).toFixed(6), + price: (inputRatioPrice * rate).toFixed(6), completion: completionTokens, - compPrice: completionRatioPrice, + compPrice: (completionRatioPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, - total: price.toFixed(6), + total: (price * rate).toFixed(6), }, ) : i18next.t( - '提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * {{ratioType}} {{ratio}} = ${{total}}', + '提示 {{input}} tokens / 1M tokens * {{symbol}}{{price}} + 补全 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}} * {{ratioType}} {{ratio}} = {{symbol}}{{total}}', { input: inputTokens, - price: inputRatioPrice, + symbol: symbol, + price: (inputRatioPrice * rate).toFixed(6), completion: completionTokens, - compPrice: completionRatioPrice, + compPrice: (completionRatioPrice * rate).toFixed(6), ratio: groupRatio, ratioType: ratioLabel, - total: price.toFixed(6), + total: (price * rate).toFixed(6), }, )}

@@ -1716,10 +1810,14 @@ export function renderClaudeLogContent( user_group_ratio, ); groupRatio = effectiveGroupRatio; + + // 获取货币配置 + const { symbol, rate } = getCurrencyConfig(); if (modelPrice !== -1) { - return i18next.t('模型价格 ${{price}},{{ratioType}} {{ratio}}', { - price: modelPrice, + return i18next.t('模型价格 {{symbol}}{{price}},{{ratioType}} {{ratio}}', { + symbol: symbol, + price: (modelPrice * rate).toFixed(6), ratioType: ratioLabel, ratio: groupRatio, });