import { useEffect, useState } from 'react'; import { Wallet, CalendarClock } from 'lucide-react'; import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Cell, Tooltip } from 'recharts'; import { fetchElectricOverview, type ElectricOverviewResponse } from './api'; import RotatingFooterHint from '../../components/RotatingFooterHint'; function fmtYuan(yuan: number) { return `¥${yuan.toLocaleString('zh-CN', { maximumFractionDigits: 2 })}`; } function fmtKwh(kwh: number) { return `${kwh.toLocaleString('zh-CN', { maximumFractionDigits: 2 })} 度`; } export default function ElectricOverview() { const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; fetchElectricOverview() .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 trendData = data.trend; // 当电能数据滞后(本月无数据走 fallback)时,柱图标题显示实际月份 const trendMonthLabel = trendData[0]?.date.slice(0, 7); const currentMonth = new Date().toISOString().slice(0, 7); const chartTitle = trendMonthLabel && trendMonthLabel !== currentMonth ? `${trendMonthLabel} 每日充电` : '本月每日充电'; return (
龙王路停车场充电站,期初 2025-01-01,手工导入每日更新
{/* 横向 mini KPI 头 */}
累计
{fmtYuan(k.totalFee)}
{fmtKwh(k.totalKwh)}
本月
{fmtYuan(k.monthFee)}
{fmtKwh(k.monthKwh)}
{/* 本月每日充电柱图 */}
{chartTitle} 单位 元
v.slice(5)} tick={{ fontSize: 10, fill: '#94a3b8' }} tickLine={false} axisLine={false} interval="preserveStartEnd" minTickGap={8} /> [`¥${Number(v ?? 0).toLocaleString('zh-CN', { maximumFractionDigits: 2 })}`, '充电费用']} labelFormatter={(d) => `日期 ${d}`} contentStyle={{ borderRadius: 12, fontSize: 12 }} cursor={{ fill: 'rgba(59, 130, 246, 0.06)' }} /> {trendData.map((_, i) => ( ))}
); }