fix(ui): show token breakdown when image model uses token billing
Only display image count format when billing_mode is "image". When channel has token pricing, show input/output/cache token details.
This commit is contained in:
@@ -84,8 +84,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell-tokens="{ row }">
|
<template #cell-tokens="{ row }">
|
||||||
<!-- 图片生成请求 -->
|
<!-- 图片生成请求(仅按次计费时显示图片格式) -->
|
||||||
<div v-if="row.image_count > 0" class="flex items-center gap-1.5">
|
<div v-if="row.image_count > 0 && row.billing_mode === 'image'" class="flex items-center gap-1.5">
|
||||||
<svg class="h-4 w-4 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="h-4 w-4 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
@@ -295,11 +295,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-6">
|
<div class="flex items-center justify-between gap-6">
|
||||||
<span class="text-gray-400">{{ t('usage.rate') }}</span>
|
<span class="text-gray-400">{{ t('usage.rate') }}</span>
|
||||||
<span class="font-semibold text-blue-400">{{ (tooltipData?.rate_multiplier || 1).toFixed(2) }}x</span>
|
<span class="font-semibold text-blue-400">{{ formatMultiplier(tooltipData?.rate_multiplier || 1) }}x</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-6">
|
<div class="flex items-center justify-between gap-6">
|
||||||
<span class="text-gray-400">{{ t('usage.accountMultiplier') }}</span>
|
<span class="text-gray-400">{{ t('usage.accountMultiplier') }}</span>
|
||||||
<span class="font-semibold text-blue-400">{{ (tooltipData?.account_rate_multiplier ?? 1).toFixed(2) }}x</span>
|
<span class="font-semibold text-blue-400">{{ formatMultiplier(tooltipData?.account_rate_multiplier ?? 1) }}x</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-6">
|
<div class="flex items-center justify-between gap-6">
|
||||||
<span class="text-gray-400">{{ t('usage.original') }}</span>
|
<span class="text-gray-400">{{ t('usage.original') }}</span>
|
||||||
@@ -382,6 +382,14 @@ const formatCacheTokens = (tokens: number): string => {
|
|||||||
return tokens.toString()
|
return tokens.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 自适应精度:保留足够位数显示有效数字(如 0.001 → "0.001",1.5 → "1.50")
|
||||||
|
const formatMultiplier = (val: number): string => {
|
||||||
|
if (val >= 0.01) return val.toFixed(2)
|
||||||
|
if (val >= 0.001) return val.toFixed(3)
|
||||||
|
if (val >= 0.0001) return val.toFixed(4)
|
||||||
|
return val.toPrecision(2)
|
||||||
|
}
|
||||||
|
|
||||||
const formatUserAgent = (ua: string): string => {
|
const formatUserAgent = (ua: string): string => {
|
||||||
return ua
|
return ua
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ const exportToExcel = async () => {
|
|||||||
log.input_tokens, log.output_tokens, log.cache_read_tokens, log.cache_creation_tokens,
|
log.input_tokens, log.output_tokens, log.cache_read_tokens, log.cache_creation_tokens,
|
||||||
log.input_cost?.toFixed(6) || '0.000000', log.output_cost?.toFixed(6) || '0.000000',
|
log.input_cost?.toFixed(6) || '0.000000', log.output_cost?.toFixed(6) || '0.000000',
|
||||||
log.cache_read_cost?.toFixed(6) || '0.000000', log.cache_creation_cost?.toFixed(6) || '0.000000',
|
log.cache_read_cost?.toFixed(6) || '0.000000', log.cache_creation_cost?.toFixed(6) || '0.000000',
|
||||||
log.rate_multiplier?.toFixed(2) || '1.00', (log.account_rate_multiplier ?? 1).toFixed(2),
|
log.rate_multiplier?.toPrecision(4) || '1.00', (log.account_rate_multiplier ?? 1).toPrecision(4),
|
||||||
log.total_cost?.toFixed(6) || '0.000000', log.actual_cost?.toFixed(6) || '0.000000',
|
log.total_cost?.toFixed(6) || '0.000000', log.actual_cost?.toFixed(6) || '0.000000',
|
||||||
(log.total_cost * (log.account_rate_multiplier ?? 1)).toFixed(6), log.first_token_ms ?? '', log.duration_ms,
|
(log.total_cost * (log.account_rate_multiplier ?? 1)).toFixed(6), log.first_token_ms ?? '', log.duration_ms,
|
||||||
log.request_id || '', log.user_agent || '', log.ip_address || ''
|
log.request_id || '', log.user_agent || '', log.ip_address || ''
|
||||||
|
|||||||
@@ -189,8 +189,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell-tokens="{ row }">
|
<template #cell-tokens="{ row }">
|
||||||
<!-- 图片生成请求 -->
|
<!-- 图片生成请求(仅按次计费时显示图片格式) -->
|
||||||
<div v-if="row.image_count > 0" class="flex items-center gap-1.5">
|
<div v-if="row.image_count > 0 && row.billing_mode === 'image'" class="flex items-center gap-1.5">
|
||||||
<svg
|
<svg
|
||||||
class="h-4 w-4 text-indigo-500"
|
class="h-4 w-4 text-indigo-500"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -464,7 +464,7 @@
|
|||||||
<div class="flex items-center justify-between gap-6">
|
<div class="flex items-center justify-between gap-6">
|
||||||
<span class="text-gray-400">{{ t('usage.rate') }}</span>
|
<span class="text-gray-400">{{ t('usage.rate') }}</span>
|
||||||
<span class="font-semibold text-blue-400"
|
<span class="font-semibold text-blue-400"
|
||||||
>{{ (tooltipData?.rate_multiplier || 1).toFixed(2) }}x</span
|
>{{ formatMultiplier(tooltipData?.rate_multiplier || 1) }}x</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between gap-6">
|
<div class="flex items-center justify-between gap-6">
|
||||||
@@ -669,6 +669,13 @@ const formatCacheTokens = (value: number): string => {
|
|||||||
return value.toLocaleString()
|
return value.toLocaleString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatMultiplier = (val: number): string => {
|
||||||
|
if (val >= 0.01) return val.toFixed(2)
|
||||||
|
if (val >= 0.001) return val.toFixed(3)
|
||||||
|
if (val >= 0.0001) return val.toFixed(4)
|
||||||
|
return val.toPrecision(2)
|
||||||
|
}
|
||||||
|
|
||||||
const loadUsageLogs = async () => {
|
const loadUsageLogs = async () => {
|
||||||
if (abortController) {
|
if (abortController) {
|
||||||
abortController.abort()
|
abortController.abort()
|
||||||
|
|||||||
Reference in New Issue
Block a user