'use client' import { useEffect, useState, useCallback } from 'react' import { Loader2, Zap } from 'lucide-react' import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, BarChart, Bar, Legend, } from 'recharts' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { api } from '@/lib/api-client' import { ApiRequestError } from '@/lib/api-client' import { formatNumber } from '@/lib/utils' import type { UsageRecord, UsageByModel } from '@/lib/types' export default function UsagePage() { const [days, setDays] = useState(7) const [dailyData, setDailyData] = useState([]) const [modelData, setModelData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const fetchData = useCallback(async () => { setLoading(true) setError('') try { const [dailyRes, modelRes] = await Promise.allSettled([ api.usage.daily({ days }), api.usage.byModel({ days }), ]) if (dailyRes.status === 'fulfilled') setDailyData(dailyRes.value) else throw new Error('Failed to fetch daily usage') if (modelRes.status === 'fulfilled') setModelData(modelRes.value) } catch (err) { if (err instanceof ApiRequestError) setError(err.body.message) else setError('加载数据失败') } finally { setLoading(false) } }, [days]) useEffect(() => { fetchData() }, [fetchData]) const lineChartData = dailyData.map((r) => ({ day: r.day.slice(5), Input: r.input_tokens, Output: r.output_tokens, })) const barChartData = modelData.map((r) => ({ model: r.model_id, 请求量: r.count, Input: r.input_tokens, Output: r.output_tokens, })) const totalInput = dailyData.reduce((s, r) => s + r.input_tokens, 0) const totalOutput = dailyData.reduce((s, r) => s + r.output_tokens, 0) const totalRequests = dailyData.reduce((s, r) => s + r.count, 0) if (loading) { return (

加载中...

) } if (error) { return (

{error}

) } return (
{/* 时间范围 */}
时间范围:
{/* 汇总统计 */}

总请求数

{formatNumber(totalRequests)}

Input Tokens

{formatNumber(totalInput)}

Output Tokens

{formatNumber(totalOutput)}

{/* Token 用量趋势 */} Token 用量趋势 {lineChartData.length > 0 ? ( ) : (
暂无数据
)}
{/* 按模型分布 */} 按模型分布 {barChartData.length > 0 ? ( ) : (
暂无数据
)}
) }