feat: 实现基于滑动窗口的实时RPM/TPM统计

- 添加系统级分钟统计,支持1-60分钟可配置时间窗口
- 新增 getRealtimeSystemMetrics 方法计算滑动窗口内的平均值
- 前端显示实时RPM/TPM,标注时间窗口和数据来源
- 修复 EditApiKeyModal 中模型限制和客户端限制复选框状态错误
- 优化性能:使用Pipeline批量操作替代Promise.all
- TPM包含所有token类型:input、output、cache_creation、cache_read
- 添加降级方案:实时数据不可用时返回历史平均值

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-07-30 14:27:34 +08:00
parent 363d1c3ed3
commit a6ab6b7abe
7 changed files with 237 additions and 103 deletions

View File

@@ -111,9 +111,17 @@
<div class="stat-card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-semibold text-gray-600 mb-1">平均RPM</p>
<p class="text-3xl font-bold text-orange-600">{{ dashboardData.systemRPM || 0 }}</p>
<p class="text-xs text-gray-500 mt-1">分钟请求数</p>
<p class="text-sm font-semibold text-gray-600 mb-1">
实时RPM
<span class="text-xs text-gray-400">({{ dashboardData.metricsWindow }}分钟)</span>
</p>
<p class="text-3xl font-bold text-orange-600">{{ dashboardData.realtimeRPM || 0 }}</p>
<p class="text-xs text-gray-500 mt-1">
每分钟请求数
<span v-if="dashboardData.isHistoricalMetrics" class="text-yellow-600">
<i class="fas fa-exclamation-circle"></i> 历史数据
</span>
</p>
</div>
<div class="stat-icon flex-shrink-0 bg-gradient-to-br from-orange-500 to-orange-600">
<i class="fas fa-tachometer-alt"></i>
@@ -124,9 +132,17 @@
<div class="stat-card">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-semibold text-gray-600 mb-1">平均TPM</p>
<p class="text-3xl font-bold text-rose-600">{{ dashboardData.systemTPM || 0 }}</p>
<p class="text-xs text-gray-500 mt-1">分钟Token数</p>
<p class="text-sm font-semibold text-gray-600 mb-1">
实时TPM
<span class="text-xs text-gray-400">({{ dashboardData.metricsWindow }}分钟)</span>
</p>
<p class="text-3xl font-bold text-rose-600">{{ dashboardData.realtimeTPM || 0 }}</p>
<p class="text-xs text-gray-500 mt-1">
每分钟Token数
<span v-if="dashboardData.isHistoricalMetrics" class="text-yellow-600">
<i class="fas fa-exclamation-circle"></i> 历史数据
</span>
</p>
</div>
<div class="stat-icon flex-shrink-0 bg-gradient-to-br from-rose-500 to-rose-600">
<i class="fas fa-rocket"></i>