feat(usage): 修复缓存命中率计算并新增用户端 API 格式统计

- 新增 input_context_expr() 按 api_format 区分 input_tokens 语义
  (OpenAI/Gemini input_tokens 已含 cache_read,Claude 需额外加上)
- 缓存命中率统一改为基于归一化后的 total_input_context 计算
- 用户 /me/usage 接口新增 summary_by_api_format 后端聚合字段
- 前端 API 格式统计改用后端聚合数据,移除前端逐条记录手动统计
- 提取 formatHitRate 到 utils/format.ts 消除三处重复定义
- 移除 PoolManager 中未使用的 select_key 方法

Co-Authored-By: AAEE86 <[email protected]>
This commit is contained in:
fawney19
2026-03-14 00:33:19 +08:00
co-authored by AAEE86
parent e9678ea899
commit bdfe4adc98
14 changed files with 281 additions and 247 deletions
@@ -21,6 +21,12 @@
<TableHead class="h-8 px-2 text-right">
费用
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存Token
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存命中率
</TableHead>
<TableHead class="h-8 px-2 text-right">
平均响应
</TableHead>
@@ -29,7 +35,7 @@
<TableBody>
<TableRow v-if="data.length === 0">
<TableCell
:colspan="5"
:colspan="7"
class="text-center py-6 text-muted-foreground px-2"
>
暂无API格式统计数据
@@ -59,6 +65,12 @@
</span>
</div>
</TableCell>
<TableCell class="text-right py-2 px-2">
{{ formatTokens(item.cache_read_tokens || 0) }}
</TableCell>
<TableCell class="text-right py-2 px-2 text-muted-foreground">
{{ formatHitRate(item.cache_hit_rate) }}
</TableCell>
<TableCell class="text-right text-muted-foreground py-2 px-2">
{{ item.avgResponseTime }}
</TableCell>
@@ -77,7 +89,7 @@ import TableBody from '@/components/ui/table-body.vue'
import TableRow from '@/components/ui/table-row.vue'
import TableHead from '@/components/ui/table-head.vue'
import TableCell from '@/components/ui/table-cell.vue'
import { formatTokens, formatCurrency } from '@/utils/format'
import { formatTokens, formatCurrency, formatHitRate } from '@/utils/format'
import { formatApiFormat } from '@/api/endpoints/types/api-format'
import type { ApiFormatStatsItem } from '../types'
@@ -85,5 +97,4 @@ defineProps<{
data: ApiFormatStatsItem[]
isAdmin: boolean
}>()
</script>
@@ -21,6 +21,12 @@
<TableHead class="h-8 px-2 text-right">
费用
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存Token
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存命中率
</TableHead>
<TableHead class="h-8 px-2 text-right">
效率
</TableHead>
@@ -29,7 +35,7 @@
<TableBody>
<TableRow v-if="data.length === 0">
<TableCell
:colspan="5"
:colspan="7"
class="text-center py-6 text-muted-foreground px-2"
>
暂无模型统计数据
@@ -59,6 +65,12 @@
</span>
</div>
</TableCell>
<TableCell class="text-right py-2 px-2">
{{ formatTokens(model.cache_read_tokens || 0) }}
</TableCell>
<TableCell class="text-right py-2 px-2 text-muted-foreground">
{{ formatHitRate(model.cache_hit_rate) }}
</TableCell>
<TableCell class="text-right text-muted-foreground py-2 px-2">
{{ model.costPerToken }}
</TableCell>
@@ -77,7 +89,7 @@ import TableBody from '@/components/ui/table-body.vue'
import TableRow from '@/components/ui/table-row.vue'
import TableHead from '@/components/ui/table-head.vue'
import TableCell from '@/components/ui/table-cell.vue'
import { formatTokens, formatCurrency } from '@/utils/format'
import { formatTokens, formatCurrency, formatHitRate } from '@/utils/format'
import type { EnhancedModelStatsItem } from '../types'
defineProps<{
@@ -21,6 +21,12 @@
<TableHead class="h-8 px-2 text-right">
费用
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存Token
</TableHead>
<TableHead class="h-8 px-2 text-right">
缓存命中率
</TableHead>
<TableHead class="h-8 px-2 text-right">
成功率
</TableHead>
@@ -32,7 +38,7 @@
<TableBody>
<TableRow v-if="data.length === 0">
<TableCell
:colspan="6"
:colspan="8"
class="text-center py-6 text-muted-foreground px-2"
>
暂无提供商统计数据
@@ -62,6 +68,12 @@
</span>
</div>
</TableCell>
<TableCell class="text-right py-2 px-2">
{{ formatTokens(provider.cacheReadTokens || 0) }}
</TableCell>
<TableCell class="text-right py-2 px-2 text-muted-foreground">
{{ formatHitRate(provider.cacheHitRate) }}
</TableCell>
<TableCell class="text-right py-2 px-2">
<span :class="getSuccessRateClass(provider.successRate)">{{ provider.successRate }}%</span>
</TableCell>
@@ -83,7 +95,7 @@ import TableBody from '@/components/ui/table-body.vue'
import TableRow from '@/components/ui/table-row.vue'
import TableHead from '@/components/ui/table-head.vue'
import TableCell from '@/components/ui/table-cell.vue'
import { formatTokens, formatCurrency } from '@/utils/format'
import { formatTokens, formatCurrency, formatHitRate } from '@/utils/format'
import type { ProviderStatsItem } from '../types'
defineProps<{