diff --git a/src/components/monitor/DailyTrendChart.tsx b/src/components/monitor/DailyTrendChart.tsx index 46d33b3..e6bf1eb 100644 --- a/src/components/monitor/DailyTrendChart.tsx +++ b/src/components/monitor/DailyTrendChart.tsx @@ -14,6 +14,8 @@ interface DailyTrendChartProps { interface DailyStat { date: string; requests: number; + successRequests: number; + failedRequests: number; inputTokens: number; outputTokens: number; reasoningTokens: number; @@ -29,19 +31,33 @@ export function DailyTrendChart({ data, loading, isDark, timeRange }: DailyTrend const dailyStats: Record = {}; + // 辅助函数:获取本地日期字符串 YYYY-MM-DD + const getLocalDateString = (timestamp: string): string => { + const date = new Date(timestamp); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + }; + Object.values(data.apis).forEach((apiData) => { Object.values(apiData.models).forEach((modelData) => { modelData.details.forEach((detail) => { - const date = new Date(detail.timestamp).toISOString().split('T')[0]; + // 使用本地日期而非 UTC 日期 + const date = getLocalDateString(detail.timestamp); if (!dailyStats[date]) { dailyStats[date] = { requests: 0, + successRequests: 0, + failedRequests: 0, inputTokens: 0, outputTokens: 0, reasoningTokens: 0, @@ -49,10 +65,16 @@ export function DailyTrendChart({ data, loading, isDark, timeRange }: DailyTrend }; } dailyStats[date].requests++; - dailyStats[date].inputTokens += detail.tokens.input_tokens || 0; - dailyStats[date].outputTokens += detail.tokens.output_tokens || 0; - dailyStats[date].reasoningTokens += detail.tokens.reasoning_tokens || 0; - dailyStats[date].cachedTokens += detail.tokens.cached_tokens || 0; + if (detail.failed) { + dailyStats[date].failedRequests++; + } else { + dailyStats[date].successRequests++; + // 只统计成功请求的 Token + dailyStats[date].inputTokens += detail.tokens.input_tokens || 0; + dailyStats[date].outputTokens += detail.tokens.output_tokens || 0; + dailyStats[date].reasoningTokens += detail.tokens.reasoning_tokens || 0; + dailyStats[date].cachedTokens += detail.tokens.cached_tokens || 0; + } }); }); }); diff --git a/src/components/monitor/HourlyTokenChart.tsx b/src/components/monitor/HourlyTokenChart.tsx index 227e124..99dbfaf 100644 --- a/src/components/monitor/HourlyTokenChart.tsx +++ b/src/components/monitor/HourlyTokenChart.tsx @@ -48,10 +48,13 @@ export function HourlyTokenChart({ data, loading, isDark }: HourlyTokenChartProp hourlyStats[hour] = { total: 0, input: 0, output: 0, reasoning: 0, cached: 0 }; }); - // 收集每小时的 Token 数据 + // 收集每小时的 Token 数据(只统计成功请求) Object.values(data.apis).forEach((apiData) => { Object.values(apiData.models).forEach((modelData) => { modelData.details.forEach((detail) => { + // 跳过失败请求,失败请求的 Token 数据不准确 + if (detail.failed) return; + const timestamp = new Date(detail.timestamp); if (timestamp < cutoffTime) return;