import type { HydrogenCustomerRow, HydrogenStationFull } from '../../types'; import { useMemo, useState } from 'react'; import { ChevronRight, Search } from 'lucide-react'; import { SortableColumnHeader, sortBy, toggleSort, type SortDirection } from '../../components/SortableColumnHeader'; import { buildCustomerDrillPayload, buildStationDrillPayload, formatKg as fmtKg, formatYuan as fmtYuan, type OverviewDrillPayload, type OverviewDrillRequest, type OverviewScope, } from '../model'; import { OverviewDrillDialog } from './OverviewDrillDialog'; export function StationSummaryTable({ stations, onSelectStation, scope = 'global', scopeLabel, onDrillRequest, }: { stations: HydrogenStationFull[]; onSelectStation?: (stationId: number) => void; scope?: OverviewScope; scopeLabel?: string | null; onDrillRequest?: (request: OverviewDrillRequest) => void; }) { const [province, setProvince] = useState('all'); const [sortKey, setSortKey] = useState<'name' | 'province' | 'kg' | 'share' | 'revenue' | 'revenueShare'>('kg'); const [sortDirection, setSortDirection] = useState('desc'); const [drill, setDrill] = useState(null); const [selectedStationId, setSelectedStationId] = useState(null); const provinces = useMemo(() => [...new Set(stations.map(station => station.province?.trim()).filter(Boolean) as string[])], [stations]); const filteredStations = province === 'all' ? stations : stations.filter(station => station.province === province); const sortedStations = useMemo(() => sortBy(filteredStations, sortKey, sortDirection, (station, key) => station[key]), [filteredStations, sortDirection, sortKey]); const changeSort = (nextKey: typeof sortKey) => { const next = toggleSort(sortKey, sortDirection, nextKey); setSortKey(next.key); setSortDirection(next.direction); }; const openStation = (station: HydrogenStationFull) => { setSelectedStationId(station.id); if (onDrillRequest) onDrillRequest({ kind: 'station', key: String(station.id), label: station.name, entityId: station.id }); else setDrill(buildStationDrillPayload(station)); }; return ( <> {stations.length > 0 && (
加氢站加氢汇总{scope === 'station' && scopeLabel ? ` · ${scopeLabel}` : ''}
{provinces.map(item => )}
统计范围内共 {stations.length} 站
{sortedStations.map((s, i) => { const kgFmt = fmtKg(s.kg); const revFmt = fmtYuan(s.revenue); return ( openStation(s)} style={{ cursor: 'pointer' }} title="查看加氢站汇总明细"> ); })}
#
{i + 1} {s.name} 钻取 › {s.province ?? '未归属'} {kgFmt.value} {kgFmt.unit}
{(s.share * 100).toFixed(1)}%
¥{revFmt.value} {revFmt.unit}
{(s.revenueShare * 100).toFixed(1)}%
)} { setDrill(null); setSelectedStationId(null); }} onPrimaryAction={selectedStationId && onSelectStation ? () => { const stationId = selectedStationId; setDrill(null); setSelectedStationId(null); onSelectStation(stationId); } : undefined} /> ); } export function CustomerSummaryTable({ customers, scope = 'global', scopeLabel, onDrillRequest, }: { customers: HydrogenCustomerRow[]; scope?: OverviewScope; scopeLabel?: string | null; onDrillRequest?: (request: OverviewDrillRequest) => void; }) { const [sortKey, setSortKey] = useState<'name' | 'payer' | 'kg' | 'cost' | 'revenue'>('kg'); const [sortDirection, setSortDirection] = useState('desc'); const [drill, setDrill] = useState(null); const sortedCustomers = useMemo(() => sortBy(customers, sortKey, sortDirection, (customer, key) => customer[key]), [customers, sortDirection, sortKey]); const changeSort = (nextKey: typeof sortKey) => { const next = toggleSort(sortKey, sortDirection, nextKey); setSortKey(next.key); setSortDirection(next.direction); }; const openCustomer = (customer: HydrogenCustomerRow, index: number) => { if (onDrillRequest) onDrillRequest({ kind: 'customer', key: `${customer.name}-${index}`, label: customer.name }); else setDrill(buildCustomerDrillPayload(customer)); }; return ( <> {customers.length > 0 && (
客户账单汇总{scope === 'station' && scopeLabel ? ` · ${scopeLabel}` : ''} (已收 / 未收:等待客户能源账户和对账单打通后获取) (已收未收打通中)
Top {customers.length}
{sortedCustomers.map((c2, i) => { const kgFmt = fmtKg(c2.kg); const costFmt = fmtYuan(c2.cost); const revFmt = fmtYuan(c2.revenue); return ( openCustomer(c2, i)} style={{ cursor: 'pointer' }} title="点击查看客户账单明细"> ); })}
#
{i + 1} {c2.name} 钻取 › {c2.payer === 'lingniu' ? ( 羚牛 ) : c2.payer === 'mixed' ? ( 混合 ) : ( 客户 )} {kgFmt.value} {kgFmt.unit} ¥{costFmt.value} {costFmt.unit} ¥{revFmt.value} {revFmt.unit}
)} setDrill(null)} /> ); }