mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
fix: 修复apikeys聚合查询统计问题
This commit is contained in:
@@ -9,16 +9,96 @@
|
|||||||
{{ multiKeyMode ? '限制配置(聚合查询模式)' : '限制配置' }}
|
{{ multiKeyMode ? '限制配置(聚合查询模式)' : '限制配置' }}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<!-- 多 Key 模式下的提示信息 -->
|
<!-- 多 Key 模式下的聚合统计信息 -->
|
||||||
|
<div v-if="multiKeyMode && aggregatedStats" class="space-y-4">
|
||||||
|
<!-- API Keys 概况 -->
|
||||||
<div
|
<div
|
||||||
v-if="multiKeyMode"
|
class="rounded-lg bg-gradient-to-r from-blue-50 to-indigo-50 p-4 dark:from-blue-900/20 dark:to-indigo-900/20"
|
||||||
class="mb-4 rounded-lg bg-yellow-50 p-3 text-sm dark:bg-yellow-900/20"
|
|
||||||
>
|
>
|
||||||
<i class="fas fa-info-circle mr-2 text-yellow-600 dark:text-yellow-400" />
|
<div class="mb-3 flex items-center justify-between">
|
||||||
<span class="text-yellow-700 dark:text-yellow-300">
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||||
聚合查询模式下,限制配置信息不适用于多个 API Key 的组合,因此不显示详细的限制配置。 每个
|
<i class="fas fa-layer-group mr-2 text-blue-500" />
|
||||||
API Key 有独立的限制设置。
|
API Keys 概况
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
|
class="rounded-full bg-blue-100 px-2 py-1 text-xs font-semibold text-blue-700 dark:bg-blue-800 dark:text-blue-200"
|
||||||
|
>
|
||||||
|
{{ aggregatedStats.activeKeys }}/{{ aggregatedStats.totalKeys }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-lg font-bold text-gray-900 dark:text-gray-100">
|
||||||
|
{{ aggregatedStats.totalKeys }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-600 dark:text-gray-400">总计 Keys</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="text-lg font-bold text-green-600">
|
||||||
|
{{ aggregatedStats.activeKeys }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-600 dark:text-gray-400">激活 Keys</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 聚合统计数据 -->
|
||||||
|
<div
|
||||||
|
class="rounded-lg bg-gradient-to-r from-purple-50 to-pink-50 p-4 dark:from-purple-900/20 dark:to-pink-900/20"
|
||||||
|
>
|
||||||
|
<div class="mb-3 flex items-center">
|
||||||
|
<i class="fas fa-chart-pie mr-2 text-purple-500" />
|
||||||
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">聚合统计摘要</span>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-xs text-gray-600 dark:text-gray-400">
|
||||||
|
<i class="fas fa-database mr-1 text-gray-400" />
|
||||||
|
总请求数
|
||||||
|
</span>
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
|
{{ formatNumber(aggregatedStats.usage.requests) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-xs text-gray-600 dark:text-gray-400">
|
||||||
|
<i class="fas fa-coins mr-1 text-yellow-500" />
|
||||||
|
总 Tokens
|
||||||
|
</span>
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
|
{{ formatNumber(aggregatedStats.usage.allTokens) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-xs text-gray-600 dark:text-gray-400">
|
||||||
|
<i class="fas fa-dollar-sign mr-1 text-green-500" />
|
||||||
|
总费用
|
||||||
|
</span>
|
||||||
|
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
|
{{ aggregatedStats.usage.formattedCost }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无效 Keys 提示 -->
|
||||||
|
<div
|
||||||
|
v-if="invalidKeys && invalidKeys.length > 0"
|
||||||
|
class="rounded-lg bg-red-50 p-3 text-sm dark:bg-red-900/20"
|
||||||
|
>
|
||||||
|
<i class="fas fa-exclamation-triangle mr-2 text-red-600 dark:text-red-400" />
|
||||||
|
<span class="text-red-700 dark:text-red-300">
|
||||||
|
{{ invalidKeys.length }} 个无效的 API Key
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<div
|
||||||
|
class="rounded-lg bg-gray-50 p-3 text-xs text-gray-600 dark:bg-gray-800 dark:text-gray-400"
|
||||||
|
>
|
||||||
|
<i class="fas fa-info-circle mr-1" />
|
||||||
|
每个 API Key 有独立的限制设置,聚合模式下不显示单个限制配置
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 仅在单 Key 模式下显示限制配置 -->
|
<!-- 仅在单 Key 模式下显示限制配置 -->
|
||||||
@@ -235,7 +315,7 @@ import { useApiStatsStore } from '@/stores/apistats'
|
|||||||
import WindowCountdown from '@/components/apikeys/WindowCountdown.vue'
|
import WindowCountdown from '@/components/apikeys/WindowCountdown.vue'
|
||||||
|
|
||||||
const apiStatsStore = useApiStatsStore()
|
const apiStatsStore = useApiStatsStore()
|
||||||
const { statsData, multiKeyMode } = storeToRefs(apiStatsStore)
|
const { statsData, multiKeyMode, aggregatedStats, invalidKeys } = storeToRefs(apiStatsStore)
|
||||||
|
|
||||||
// 获取每日费用进度
|
// 获取每日费用进度
|
||||||
const getDailyCostProgress = () => {
|
const getDailyCostProgress = () => {
|
||||||
@@ -253,6 +333,24 @@ const getDailyCostProgressColor = () => {
|
|||||||
if (progress >= 80) return 'bg-yellow-500'
|
if (progress >= 80) return 'bg-yellow-500'
|
||||||
return 'bg-green-500'
|
return 'bg-green-500'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 格式化数字
|
||||||
|
const formatNumber = (num) => {
|
||||||
|
if (typeof num !== 'number') {
|
||||||
|
num = parseInt(num) || 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num === 0) return '0'
|
||||||
|
|
||||||
|
// 大数字使用简化格式
|
||||||
|
if (num >= 1000000) {
|
||||||
|
return (num / 1000000).toFixed(1) + 'M'
|
||||||
|
} else if (num >= 1000) {
|
||||||
|
return (num / 1000).toFixed(1) + 'K'
|
||||||
|
} else {
|
||||||
|
return num.toLocaleString()
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
|||||||
formattedCost: '$0.000000'
|
formattedCost: '$0.000000'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 聚合模式下使用聚合数据
|
||||||
|
if (multiKeyMode.value && aggregatedStats.value) {
|
||||||
|
if (statsPeriod.value === 'daily') {
|
||||||
|
return aggregatedStats.value.dailyUsage || defaultData
|
||||||
|
} else {
|
||||||
|
return aggregatedStats.value.monthlyUsage || defaultData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单个 Key 模式下使用原有逻辑
|
||||||
if (statsPeriod.value === 'daily') {
|
if (statsPeriod.value === 'daily') {
|
||||||
return dailyStats.value || defaultData
|
return dailyStats.value || defaultData
|
||||||
} else {
|
} else {
|
||||||
@@ -364,6 +374,10 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
|||||||
individualStats.value = batchResult.data.individual
|
individualStats.value = batchResult.data.individual
|
||||||
statsData.value = batchResult.data.aggregated // 兼容现有组件
|
statsData.value = batchResult.data.aggregated // 兼容现有组件
|
||||||
|
|
||||||
|
// 设置聚合模式下的日期统计数据,以保证现有组件的兼容性
|
||||||
|
dailyStats.value = batchResult.data.aggregated.dailyUsage || null
|
||||||
|
monthlyStats.value = batchResult.data.aggregated.monthlyUsage || null
|
||||||
|
|
||||||
// 加载聚合的模型统计
|
// 加载聚合的模型统计
|
||||||
await loadBatchModelStats(statsPeriod.value)
|
await loadBatchModelStats(statsPeriod.value)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user