fix: correct API key cost calculation and UI display issues

- Fix admin panel cost display for "all time" period using permanent Redis key
- Fix user statistics total cost limit to show complete history
- Fix restricted models list overflow with scrollable container

Backend changes:
- src/routes/admin/apiKeys.js: Use allTimeCost for timeRange='all' instead of scanning TTL keys
- src/routes/apiStats.js: Prioritize permanent usage:cost:total key over monthly keys

Frontend changes:
- web/admin-spa/src/components/apistats/LimitConfig.vue: Add overflow-visible and scrolling to model list

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
John Doe
2025-12-12 18:11:02 +03:00
parent 87426133a2
commit baafebbf7b
3 changed files with 87 additions and 52 deletions

View File

@@ -945,6 +945,30 @@ async function calculateKeyStats(keyId, timeRange, startDate, endDate) {
allTimeCost = parseFloat((await client.get(totalCostKey)) || '0')
}
// 🔧 FIX: 对于 "全部时间" 时间范围,直接使用 allTimeCost
// 因为 usage:*:model:daily:* 键有 30 天 TTL旧数据已经过期
if (timeRange === 'all' && allTimeCost > 0) {
logger.debug(`📊 使用 allTimeCost 计算 timeRange='all': ${allTimeCost}`)
return {
requests: 0, // 旧数据详情不可用
tokens: 0,
inputTokens: 0,
outputTokens: 0,
cacheCreateTokens: 0,
cacheReadTokens: 0,
cost: allTimeCost,
formattedCost: CostCalculator.formatCost(allTimeCost),
// 实时限制数据(始终返回,不受时间范围影响)
dailyCost,
currentWindowCost,
windowRemainingSeconds,
windowStartTime,
windowEndTime,
allTimeCost
}
}
// 只在启用了窗口限制时查询窗口数据
if (rateLimitWindow > 0) {
const costCountKey = `rate_limit:cost:${keyId}`