|
@@ -922,6 +922,50 @@ export function renderQuotaWithAmount(amount) {
|
|
|
return '$' + 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) {
|
|
export function renderQuota(quota, digits = 2) {
|
|
|
let quotaPerUnit = localStorage.getItem('quota_per_unit');
|
|
let quotaPerUnit = localStorage.getItem('quota_per_unit');
|
|
|
const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD';
|
|
const quotaDisplayType = localStorage.getItem('quota_display_type') || 'USD';
|
|
@@ -1084,14 +1128,20 @@ export function renderModelPrice(
|
|
|
user_group_ratio,
|
|
user_group_ratio,
|
|
|
);
|
|
);
|
|
|
groupRatio = effectiveGroupRatio;
|
|
groupRatio = effectiveGroupRatio;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取货币配置
|
|
|
|
|
+ const { symbol, rate } = getCurrencyConfig();
|
|
|
|
|
|
|
|
if (modelPrice !== -1) {
|
|
if (modelPrice !== -1) {
|
|
|
|
|
+ const displayPrice = (modelPrice * rate).toFixed(6);
|
|
|
|
|
+ const displayTotal = (modelPrice * groupRatio * rate).toFixed(6);
|
|
|
return i18next.t(
|
|
return i18next.t(
|
|
|
- '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}',
|
|
|
|
|
|
|
+ '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}',
|
|
|
{
|
|
{
|
|
|
- price: modelPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: displayPrice,
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
- total: modelPrice * groupRatio,
|
|
|
|
|
|
|
+ total: displayTotal,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
@@ -1127,19 +1177,21 @@ export function renderModelPrice(
|
|
|
<>
|
|
<>
|
|
|
<article>
|
|
<article>
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('输入价格:${{price}} / 1M tokens{{audioPrice}}', {
|
|
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ {i18next.t('输入价格:{{symbol}}{{price}} / 1M tokens{{audioPrice}}', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
audioPrice: audioInputSeperatePrice
|
|
audioPrice: audioInputSeperatePrice
|
|
|
- ? `,音频 $${audioInputPrice} / 1M tokens`
|
|
|
|
|
|
|
+ ? `,音频 ${symbol}${(audioInputPrice * rate).toFixed(6)} / 1M tokens`
|
|
|
: '',
|
|
: '',
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
completionRatio: completionRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1147,10 +1199,11 @@ export function renderModelPrice(
|
|
|
{cacheTokens > 0 && (
|
|
{cacheTokens > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
cacheRatio: cacheRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1159,11 +1212,12 @@ export function renderModelPrice(
|
|
|
{image && imageOutputTokens > 0 && (
|
|
{image && imageOutputTokens > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
ratio: groupRatio,
|
|
|
- total: imageRatioPrice * groupRatio,
|
|
|
|
|
|
|
+ total: (imageRatioPrice * groupRatio * rate).toFixed(6),
|
|
|
imageRatio: imageRatio,
|
|
imageRatio: imageRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1171,22 +1225,25 @@ export function renderModelPrice(
|
|
|
)}
|
|
)}
|
|
|
{webSearch && webSearchCallCount > 0 && (
|
|
{webSearch && webSearchCallCount > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('Web搜索价格:${{price}} / 1K 次', {
|
|
|
|
|
- price: webSearchPrice,
|
|
|
|
|
|
|
+ {i18next.t('Web搜索价格:{{symbol}}{{price}} / 1K 次', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (webSearchPrice * rate).toFixed(6),
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
)}
|
|
)}
|
|
|
{fileSearch && fileSearchCallCount > 0 && (
|
|
{fileSearch && fileSearchCallCount > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('文件搜索价格:${{price}} / 1K 次', {
|
|
|
|
|
- price: fileSearchPrice,
|
|
|
|
|
|
|
+ {i18next.t('文件搜索价格:{{symbol}}{{price}} / 1K 次', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (fileSearchPrice * rate).toFixed(6),
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
)}
|
|
)}
|
|
|
{imageGenerationCall && imageGenerationCallPrice > 0 && (
|
|
{imageGenerationCall && imageGenerationCallPrice > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('图片生成调用:${{price}} / 1次', {
|
|
|
|
|
- price: imageGenerationCallPrice,
|
|
|
|
|
|
|
+ {i18next.t('图片生成调用:{{symbol}}{{price}} / 1次', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (imageGenerationCallPrice * rate).toFixed(6),
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
)}
|
|
)}
|
|
@@ -1196,50 +1253,55 @@ export function renderModelPrice(
|
|
|
let inputDesc = '';
|
|
let inputDesc = '';
|
|
|
if (image && imageOutputTokens > 0) {
|
|
if (image && imageOutputTokens > 0) {
|
|
|
inputDesc = i18next.t(
|
|
inputDesc = i18next.t(
|
|
|
- '(输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * ${{price}}',
|
|
|
|
|
|
|
+ '(输入 {{nonImageInput}} tokens + 图片输入 {{imageInput}} tokens * {{imageRatio}} / 1M tokens * {{symbol}}{{price}}',
|
|
|
{
|
|
{
|
|
|
nonImageInput: inputTokens - imageOutputTokens,
|
|
nonImageInput: inputTokens - imageOutputTokens,
|
|
|
imageInput: imageOutputTokens,
|
|
imageInput: imageOutputTokens,
|
|
|
imageRatio: imageRatio,
|
|
imageRatio: imageRatio,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
} else if (cacheTokens > 0) {
|
|
} else if (cacheTokens > 0) {
|
|
|
inputDesc = i18next.t(
|
|
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,
|
|
nonCacheInput: inputTokens - cacheTokens,
|
|
|
cacheInput: cacheTokens,
|
|
cacheInput: cacheTokens,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
- cachePrice: cacheRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
|
|
+ cachePrice: (cacheRatioPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
} else if (audioInputSeperatePrice && audioInputTokens > 0) {
|
|
} else if (audioInputSeperatePrice && audioInputTokens > 0) {
|
|
|
inputDesc = i18next.t(
|
|
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,
|
|
nonAudioInput: inputTokens - audioInputTokens,
|
|
|
audioInput: audioInputTokens,
|
|
audioInput: audioInputTokens,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
- audioPrice: audioInputPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
|
|
+ audioPrice: (audioInputPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
} else {
|
|
} else {
|
|
|
inputDesc = i18next.t(
|
|
inputDesc = i18next.t(
|
|
|
- '(输入 {{input}} tokens / 1M tokens * ${{price}}',
|
|
|
|
|
|
|
+ '(输入 {{input}} tokens / 1M tokens * {{symbol}}{{price}}',
|
|
|
{
|
|
{
|
|
|
input: inputTokens,
|
|
input: inputTokens,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 构建输出部分描述
|
|
// 构建输出部分描述
|
|
|
const outputDesc = i18next.t(
|
|
const outputDesc = i18next.t(
|
|
|
- '输出 {{completion}} tokens / 1M tokens * ${{compPrice}}) * {{ratioType}} {{ratio}}',
|
|
|
|
|
|
|
+ '输出 {{completion}} tokens / 1M tokens * {{symbol}}{{compPrice}}) * {{ratioType}} {{ratio}}',
|
|
|
{
|
|
{
|
|
|
completion: completionTokens,
|
|
completion: completionTokens,
|
|
|
- compPrice: completionRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ compPrice: (completionRatioPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
@@ -1249,10 +1311,11 @@ export function renderModelPrice(
|
|
|
const extraServices = [
|
|
const extraServices = [
|
|
|
webSearch && webSearchCallCount > 0
|
|
webSearch && webSearchCallCount > 0
|
|
|
? i18next.t(
|
|
? i18next.t(
|
|
|
- ' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}} {{ratio}}',
|
|
|
|
|
|
|
+ ' + Web搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}',
|
|
|
{
|
|
{
|
|
|
count: webSearchCallCount,
|
|
count: webSearchCallCount,
|
|
|
- price: webSearchPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (webSearchPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
@@ -1260,10 +1323,11 @@ export function renderModelPrice(
|
|
|
: '',
|
|
: '',
|
|
|
fileSearch && fileSearchCallCount > 0
|
|
fileSearch && fileSearchCallCount > 0
|
|
|
? i18next.t(
|
|
? i18next.t(
|
|
|
- ' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * {{ratioType}} {{ratio}}',
|
|
|
|
|
|
|
+ ' + 文件搜索 {{count}}次 / 1K 次 * {{symbol}}{{price}} * {{ratioType}} {{ratio}}',
|
|
|
{
|
|
{
|
|
|
count: fileSearchCallCount,
|
|
count: fileSearchCallCount,
|
|
|
- price: fileSearchPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (fileSearchPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
@@ -1271,9 +1335,10 @@ export function renderModelPrice(
|
|
|
: '',
|
|
: '',
|
|
|
imageGenerationCall && imageGenerationCallPrice > 0
|
|
imageGenerationCall && imageGenerationCallPrice > 0
|
|
|
? i18next.t(
|
|
? i18next.t(
|
|
|
- ' + 图片生成调用 ${{price}} / 1次 * {{ratioType}} {{ratio}}',
|
|
|
|
|
|
|
+ ' + 图片生成调用 {{symbol}}{{price}} / 1次 * {{ratioType}} {{ratio}}',
|
|
|
{
|
|
{
|
|
|
- price: imageGenerationCallPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (imageGenerationCallPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
@@ -1282,12 +1347,13 @@ export function renderModelPrice(
|
|
|
].join('');
|
|
].join('');
|
|
|
|
|
|
|
|
return i18next.t(
|
|
return i18next.t(
|
|
|
- '{{inputDesc}} + {{outputDesc}}{{extraServices}} = ${{total}}',
|
|
|
|
|
|
|
+ '{{inputDesc}} + {{outputDesc}}{{extraServices}} = {{symbol}}{{total}}',
|
|
|
{
|
|
{
|
|
|
inputDesc,
|
|
inputDesc,
|
|
|
outputDesc,
|
|
outputDesc,
|
|
|
extraServices,
|
|
extraServices,
|
|
|
- total: price.toFixed(6),
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ total: (price * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
})()}
|
|
})()}
|
|
@@ -1318,10 +1384,14 @@ export function renderLogContent(
|
|
|
label: ratioLabel,
|
|
label: ratioLabel,
|
|
|
useUserGroupRatio: useUserGroupRatio,
|
|
useUserGroupRatio: useUserGroupRatio,
|
|
|
} = getEffectiveRatio(groupRatio, user_group_ratio);
|
|
} = getEffectiveRatio(groupRatio, user_group_ratio);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取货币配置
|
|
|
|
|
+ const { symbol, rate } = getCurrencyConfig();
|
|
|
|
|
|
|
|
if (modelPrice !== -1) {
|
|
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,
|
|
ratioType: ratioLabel,
|
|
|
ratio,
|
|
ratio,
|
|
|
});
|
|
});
|
|
@@ -1414,14 +1484,19 @@ export function renderAudioModelPrice(
|
|
|
user_group_ratio,
|
|
user_group_ratio,
|
|
|
);
|
|
);
|
|
|
groupRatio = effectiveGroupRatio;
|
|
groupRatio = effectiveGroupRatio;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取货币配置
|
|
|
|
|
+ const { symbol, rate } = getCurrencyConfig();
|
|
|
|
|
+
|
|
|
// 1 ratio = $0.002 / 1K tokens
|
|
// 1 ratio = $0.002 / 1K tokens
|
|
|
if (modelPrice !== -1) {
|
|
if (modelPrice !== -1) {
|
|
|
return i18next.t(
|
|
return i18next.t(
|
|
|
- '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}',
|
|
|
|
|
|
|
+ '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}',
|
|
|
{
|
|
{
|
|
|
- price: modelPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (modelPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
- total: modelPrice * groupRatio,
|
|
|
|
|
|
|
+ total: (modelPrice * groupRatio * rate).toFixed(6),
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
@@ -1456,16 +1531,18 @@ export function renderAudioModelPrice(
|
|
|
<>
|
|
<>
|
|
|
<article>
|
|
<article>
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('提示价格:${{price}} / 1M tokens', {
|
|
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ {i18next.t('提示价格:{{symbol}}{{price}} / 1M tokens', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
completionRatio: completionRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1473,10 +1550,11 @@ export function renderAudioModelPrice(
|
|
|
{cacheTokens > 0 && (
|
|
{cacheTokens > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
cacheRatio: cacheRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1484,20 +1562,22 @@ export function renderAudioModelPrice(
|
|
|
)}
|
|
)}
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
audioRatio: audioRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
audioRatio: audioRatio,
|
|
|
audioCompRatio: audioCompletionRatio,
|
|
audioCompRatio: audioCompletionRatio,
|
|
|
},
|
|
},
|
|
@@ -1506,48 +1586,52 @@ export function renderAudioModelPrice(
|
|
|
<p>
|
|
<p>
|
|
|
{cacheTokens > 0
|
|
{cacheTokens > 0
|
|
|
? i18next.t(
|
|
? 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,
|
|
nonCacheInput: inputTokens - cacheTokens,
|
|
|
cacheInput: cacheTokens,
|
|
cacheInput: cacheTokens,
|
|
|
- cachePrice: inputRatioPrice * cacheRatio,
|
|
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ cachePrice: (inputRatioPrice * cacheRatio * rate).toFixed(6),
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
completion: completionTokens,
|
|
completion: completionTokens,
|
|
|
- compPrice: completionRatioPrice,
|
|
|
|
|
- total: textPrice.toFixed(6),
|
|
|
|
|
|
|
+ compPrice: (completionRatioPrice * rate).toFixed(6),
|
|
|
|
|
+ total: (textPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
: i18next.t(
|
|
: 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,
|
|
input: inputTokens,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
completion: completionTokens,
|
|
completion: completionTokens,
|
|
|
- compPrice: completionRatioPrice,
|
|
|
|
|
- total: textPrice.toFixed(6),
|
|
|
|
|
|
|
+ compPrice: (completionRatioPrice * rate).toFixed(6),
|
|
|
|
|
+ total: (textPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
input: audioInputTokens,
|
|
|
completion: audioCompletionTokens,
|
|
completion: audioCompletionTokens,
|
|
|
- audioInputPrice: audioRatio * inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ audioInputPrice: (audioRatio * inputRatioPrice * rate).toFixed(6),
|
|
|
audioCompPrice:
|
|
audioCompPrice:
|
|
|
- audioRatio * audioCompletionRatio * inputRatioPrice,
|
|
|
|
|
- total: audioPrice.toFixed(6),
|
|
|
|
|
|
|
+ (audioRatio * audioCompletionRatio * inputRatioPrice * rate).toFixed(6),
|
|
|
|
|
+ total: (audioPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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),
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
@@ -1584,15 +1668,19 @@ export function renderClaudeModelPrice(
|
|
|
user_group_ratio,
|
|
user_group_ratio,
|
|
|
);
|
|
);
|
|
|
groupRatio = effectiveGroupRatio;
|
|
groupRatio = effectiveGroupRatio;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取货币配置
|
|
|
|
|
+ const { symbol, rate } = getCurrencyConfig();
|
|
|
|
|
|
|
|
if (modelPrice !== -1) {
|
|
if (modelPrice !== -1) {
|
|
|
return i18next.t(
|
|
return i18next.t(
|
|
|
- '模型价格:${{price}} * {{ratioType}}:{{ratio}} = ${{total}}',
|
|
|
|
|
|
|
+ '模型价格:{{symbol}}{{price}} * {{ratioType}}:{{ratio}} = {{symbol}}{{total}}',
|
|
|
{
|
|
{
|
|
|
- price: modelPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (modelPrice * rate).toFixed(6),
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
- total: modelPrice * groupRatio,
|
|
|
|
|
|
|
+ total: (modelPrice * groupRatio * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
|
} else {
|
|
} else {
|
|
@@ -1621,28 +1709,31 @@ export function renderClaudeModelPrice(
|
|
|
<>
|
|
<>
|
|
|
<article>
|
|
<article>
|
|
|
<p>
|
|
<p>
|
|
|
- {i18next.t('提示价格:${{price}} / 1M tokens', {
|
|
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ {i18next.t('提示价格:{{symbol}}{{price}} / 1M tokens', {
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
})}
|
|
})}
|
|
|
</p>
|
|
</p>
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
ratio: completionRatio,
|
|
|
- total: completionRatioPrice,
|
|
|
|
|
|
|
+ total: (completionRatioPrice * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
|
{cacheTokens > 0 && (
|
|
{cacheTokens > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
ratio: cacheRatio,
|
|
|
- total: cacheRatioPrice,
|
|
|
|
|
|
|
+ total: (cacheRatioPrice * rate).toFixed(2),
|
|
|
cacheRatio: cacheRatio,
|
|
cacheRatio: cacheRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1651,11 +1742,12 @@ export function renderClaudeModelPrice(
|
|
|
{cacheCreationTokens > 0 && (
|
|
{cacheCreationTokens > 0 && (
|
|
|
<p>
|
|
<p>
|
|
|
{i18next.t(
|
|
{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,
|
|
ratio: cacheCreationRatio,
|
|
|
- total: cacheCreationRatioPrice,
|
|
|
|
|
|
|
+ total: (cacheCreationRatioPrice * rate).toFixed(6),
|
|
|
cacheCreationRatio: cacheCreationRatio,
|
|
cacheCreationRatio: cacheCreationRatio,
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
@@ -1665,33 +1757,35 @@ export function renderClaudeModelPrice(
|
|
|
<p>
|
|
<p>
|
|
|
{cacheTokens > 0 || cacheCreationTokens > 0
|
|
{cacheTokens > 0 || cacheCreationTokens > 0
|
|
|
? i18next.t(
|
|
? 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,
|
|
nonCacheInput: nonCachedTokens,
|
|
|
cacheInput: cacheTokens,
|
|
cacheInput: cacheTokens,
|
|
|
cacheRatio: cacheRatio,
|
|
cacheRatio: cacheRatio,
|
|
|
cacheCreationInput: cacheCreationTokens,
|
|
cacheCreationInput: cacheCreationTokens,
|
|
|
cacheCreationRatio: cacheCreationRatio,
|
|
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,
|
|
completion: completionTokens,
|
|
|
- compPrice: completionRatioPrice,
|
|
|
|
|
|
|
+ compPrice: (completionRatioPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
- total: price.toFixed(6),
|
|
|
|
|
|
|
+ total: (price * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)
|
|
)
|
|
|
: i18next.t(
|
|
: 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,
|
|
input: inputTokens,
|
|
|
- price: inputRatioPrice,
|
|
|
|
|
|
|
+ symbol: symbol,
|
|
|
|
|
+ price: (inputRatioPrice * rate).toFixed(6),
|
|
|
completion: completionTokens,
|
|
completion: completionTokens,
|
|
|
- compPrice: completionRatioPrice,
|
|
|
|
|
|
|
+ compPrice: (completionRatioPrice * rate).toFixed(6),
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
ratioType: ratioLabel,
|
|
ratioType: ratioLabel,
|
|
|
- total: price.toFixed(6),
|
|
|
|
|
|
|
+ total: (price * rate).toFixed(6),
|
|
|
},
|
|
},
|
|
|
)}
|
|
)}
|
|
|
</p>
|
|
</p>
|
|
@@ -1716,10 +1810,14 @@ export function renderClaudeLogContent(
|
|
|
user_group_ratio,
|
|
user_group_ratio,
|
|
|
);
|
|
);
|
|
|
groupRatio = effectiveGroupRatio;
|
|
groupRatio = effectiveGroupRatio;
|
|
|
|
|
+
|
|
|
|
|
+ // 获取货币配置
|
|
|
|
|
+ const { symbol, rate } = getCurrencyConfig();
|
|
|
|
|
|
|
|
if (modelPrice !== -1) {
|
|
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,
|
|
ratioType: ratioLabel,
|
|
|
ratio: groupRatio,
|
|
ratio: groupRatio,
|
|
|
});
|
|
});
|