mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 修复api-keys页面窗口费率显示问题
This commit is contained in:
@@ -919,6 +919,62 @@ async function calculateKeyStats(keyId, timeRange, startDate, endDate) {
|
|||||||
// 去重(避免日数据和月数据重复计算)
|
// 去重(避免日数据和月数据重复计算)
|
||||||
const uniqueKeys = [...new Set(allKeys)]
|
const uniqueKeys = [...new Set(allKeys)]
|
||||||
|
|
||||||
|
// 获取实时限制数据(窗口数据不受时间范围筛选影响,始终获取当前窗口状态)
|
||||||
|
let dailyCost = 0
|
||||||
|
let currentWindowCost = 0
|
||||||
|
let windowRemainingSeconds = null
|
||||||
|
let windowStartTime = null
|
||||||
|
let windowEndTime = null
|
||||||
|
let allTimeCost = 0
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 先获取 API Key 配置,判断是否需要查询限制相关数据
|
||||||
|
const apiKey = await redis.getApiKey(keyId)
|
||||||
|
const rateLimitWindow = parseInt(apiKey?.rateLimitWindow) || 0
|
||||||
|
const dailyCostLimit = parseFloat(apiKey?.dailyCostLimit) || 0
|
||||||
|
const totalCostLimit = parseFloat(apiKey?.totalCostLimit) || 0
|
||||||
|
|
||||||
|
// 只在启用了每日费用限制时查询
|
||||||
|
if (dailyCostLimit > 0) {
|
||||||
|
dailyCost = await redis.getDailyCost(keyId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只在启用了总费用限制时查询
|
||||||
|
if (totalCostLimit > 0) {
|
||||||
|
const totalCostKey = `usage:cost:total:${keyId}`
|
||||||
|
allTimeCost = parseFloat((await client.get(totalCostKey)) || '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只在启用了窗口限制时查询窗口数据
|
||||||
|
if (rateLimitWindow > 0) {
|
||||||
|
const costCountKey = `rate_limit:cost:${keyId}`
|
||||||
|
const windowStartKey = `rate_limit:window_start:${keyId}`
|
||||||
|
|
||||||
|
currentWindowCost = parseFloat((await client.get(costCountKey)) || '0')
|
||||||
|
|
||||||
|
// 获取窗口开始时间和计算剩余时间
|
||||||
|
const windowStart = await client.get(windowStartKey)
|
||||||
|
if (windowStart) {
|
||||||
|
const now = Date.now()
|
||||||
|
windowStartTime = parseInt(windowStart)
|
||||||
|
const windowDuration = rateLimitWindow * 60 * 1000 // 转换为毫秒
|
||||||
|
windowEndTime = windowStartTime + windowDuration
|
||||||
|
|
||||||
|
// 如果窗口还有效
|
||||||
|
if (now < windowEndTime) {
|
||||||
|
windowRemainingSeconds = Math.max(0, Math.floor((windowEndTime - now) / 1000))
|
||||||
|
} else {
|
||||||
|
// 窗口已过期
|
||||||
|
windowRemainingSeconds = 0
|
||||||
|
currentWindowCost = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn(`⚠️ 获取实时限制数据失败 (key: ${keyId}):`, error.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有使用数据,返回零值但包含窗口数据
|
||||||
if (uniqueKeys.length === 0) {
|
if (uniqueKeys.length === 0) {
|
||||||
return {
|
return {
|
||||||
requests: 0,
|
requests: 0,
|
||||||
@@ -928,7 +984,14 @@ async function calculateKeyStats(keyId, timeRange, startDate, endDate) {
|
|||||||
cacheCreateTokens: 0,
|
cacheCreateTokens: 0,
|
||||||
cacheReadTokens: 0,
|
cacheReadTokens: 0,
|
||||||
cost: 0,
|
cost: 0,
|
||||||
formattedCost: '$0.00'
|
formattedCost: '$0.00',
|
||||||
|
// 实时限制数据(始终返回,不受时间范围影响)
|
||||||
|
dailyCost,
|
||||||
|
currentWindowCost,
|
||||||
|
windowRemainingSeconds,
|
||||||
|
windowStartTime,
|
||||||
|
windowEndTime,
|
||||||
|
allTimeCost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1029,55 +1092,6 @@ async function calculateKeyStats(keyId, timeRange, startDate, endDate) {
|
|||||||
|
|
||||||
const tokens = inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens
|
const tokens = inputTokens + outputTokens + cacheCreateTokens + cacheReadTokens
|
||||||
|
|
||||||
// 获取实时限制数据
|
|
||||||
let dailyCost = 0
|
|
||||||
let currentWindowCost = 0
|
|
||||||
let windowRemainingSeconds = null
|
|
||||||
let windowStartTime = null
|
|
||||||
let windowEndTime = null
|
|
||||||
let allTimeCost = 0
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 获取当日费用
|
|
||||||
dailyCost = await redis.getDailyCost(keyId)
|
|
||||||
|
|
||||||
// 获取历史总费用(用于总费用限制进度条,不受时间范围影响)
|
|
||||||
const totalCostKey = `usage:cost:total:${keyId}`
|
|
||||||
allTimeCost = parseFloat((await client.get(totalCostKey)) || '0')
|
|
||||||
|
|
||||||
// 获取 API Key 配置信息以判断是否需要窗口数据
|
|
||||||
const apiKey = await redis.getApiKey(keyId)
|
|
||||||
// 显式转换为整数,与 apiStats.js 保持一致,避免字符串比较问题
|
|
||||||
const rateLimitWindow = parseInt(apiKey?.rateLimitWindow) || 0
|
|
||||||
|
|
||||||
if (rateLimitWindow > 0) {
|
|
||||||
const costCountKey = `rate_limit:cost:${keyId}`
|
|
||||||
const windowStartKey = `rate_limit:window_start:${keyId}`
|
|
||||||
|
|
||||||
currentWindowCost = parseFloat((await client.get(costCountKey)) || '0')
|
|
||||||
|
|
||||||
// 获取窗口开始时间和计算剩余时间
|
|
||||||
const windowStart = await client.get(windowStartKey)
|
|
||||||
if (windowStart) {
|
|
||||||
const now = Date.now()
|
|
||||||
windowStartTime = parseInt(windowStart)
|
|
||||||
const windowDuration = rateLimitWindow * 60 * 1000 // 转换为毫秒
|
|
||||||
windowEndTime = windowStartTime + windowDuration
|
|
||||||
|
|
||||||
// 如果窗口还有效
|
|
||||||
if (now < windowEndTime) {
|
|
||||||
windowRemainingSeconds = Math.max(0, Math.floor((windowEndTime - now) / 1000))
|
|
||||||
} else {
|
|
||||||
// 窗口已过期
|
|
||||||
windowRemainingSeconds = 0
|
|
||||||
currentWindowCost = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.warn(`⚠️ 获取实时限制数据失败 (key: ${keyId}):`, error.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
requests: totalRequests,
|
requests: totalRequests,
|
||||||
tokens,
|
tokens,
|
||||||
|
|||||||
Reference in New Issue
Block a user