import { useEffect, useState } from 'react'; import { Fuel, Wallet, Coins, CalendarClock } from 'lucide-react'; import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Cell, PieChart, Pie, Tooltip, LabelList } from 'recharts'; import { fetchHydrogenOverview, type HydrogenOverviewResponse } from './api'; interface YAxisTickProps { x?: number; y?: number; index?: number; payload?: { value: string }; } function RankYAxisTick({ x = 0, y = 0, index = 0, payload }: YAxisTickProps) { return ( {index + 1} {payload?.value} ); } const REGION_COLORS = [ '#3b82f6', '#22d3ee', '#a855f7', '#f59e0b', '#10b981', '#ef4444', '#6366f1', '#14b8a6', '#94a3b8', ]; function fmtKg(kg: number) { if (kg >= 1000) return `${(kg / 1000).toFixed(2)}T`; return `${kg.toFixed(2)}Kg`; } function fmtYuanWan(yuan: number) { return `¥${(yuan / 10_000).toFixed(2)}万`; } function fmtYuan(yuan: number) { return `¥${yuan.toLocaleString('zh-CN', { maximumFractionDigits: 2 })}`; } export default function HydrogenOverview() { const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; fetchHydrogenOverview() .then(d => { if (!cancelled) setData(d); }) .catch(e => { if (!cancelled) setError(e instanceof Error ? e.message : String(e)); }); return () => { cancelled = true; }; }, []); if (error) { return
加载失败:{error}
; } if (!data) { return
加载中…
; } const k = data.kpi; const top5 = data.top5; const regions = data.regions; return (
数据自 2025-01-01 起,每 1 分钟更新
{/* 卡 1:年加氢量 */}
年加氢量
{fmtKg(k.yearKg)}
我方 {fmtKg(k.ourYearKg)}
客户产生 {fmtKg(k.customerYearKg)}
{/* 卡 2:年加氢费 */}
年加氢费
{fmtYuanWan(k.yearFee)}
我方 {fmtYuanWan(k.ourYearFee)}
{/* 卡 3:累计羚牛承担 */}
累计羚牛承担
{fmtYuanWan(k.lingniuBornFee)}
{fmtKg(k.lingniuBornKg)}
{/* 卡 4:本月 / 今日 */}
本月 / 今日
本月
{fmtKg(k.monthKg)}
{fmtYuanWan(k.monthFee)}
今日
{fmtKg(k.todayKg)}
{fmtYuan(k.todayFee)}
{/* Top5 加氢站 */}
加氢站加注量 Top5 单位 Kg
} tickLine={false} axisLine={false} /> `${Number(v ?? 0).toLocaleString('zh-CN')} Kg`} contentStyle={{ borderRadius: 12, fontSize: 12 }} /> {top5.map((_, i) => ( ))} `${Number(v ?? 0).toLocaleString('zh-CN', { maximumFractionDigits: 0 })}`} fill="#475569" fontSize={11} fontWeight={700} />
{/* 区域占比环 */}
各区域加氢占比
{regions.map((_, i) => ( ))} `${(Number(v ?? 0) / 1000).toFixed(2)}T`} contentStyle={{ borderRadius: 12, fontSize: 12 }} />
年合计
{(k.yearKg / 1000).toFixed(2)}T
{regions.map((r, i) => (
{r.region} {(r.share * 100).toFixed(1)}%
))}
); }