import type { Dispatch, SetStateAction } from 'react'; import { ArrowDown, ArrowUp, Minimize2, RotateCcw } from 'lucide-react'; import { motion } from 'motion/react'; import Blur from '../../../../components/Blur'; import type { MileageSourceGroup, MonitoringFilters, MonitoringStats, MonitoringVehicle } from '../../types'; import { vehicleStatisticTime } from '../oneos-time'; import { MILEAGE_SOURCE_META, vehicleSourceDisplay } from '../source-display'; type SortBy = 'today' | 'total' | 'statisticTime'; type SortOrder = 'asc' | 'desc'; export default function FullscreenMonitoring({ forceLandscape, fullscreenStats, sortBy, sourcePriority, onRefresh, fullscreenLoading, onToggleFullscreen, filterTargetNames, onFilterTargetNamesChange, filterOptions, filterPlates, filterCustomer, onFilterCustomerChange, filterBrands, onFilterBrandsChange, filterRentStatus, onFilterRentStatusChange, filterDept, onFilterDeptChange, departments, sortOrder, onSortByChange, onSortOrderChange, fullscreenVehicles, isHighMileageAlert, relativeNow, }: { forceLandscape: boolean; fullscreenStats: MonitoringStats; sortBy: SortBy; sourcePriority: MileageSourceGroup[]; onRefresh: () => void; fullscreenLoading: boolean; onToggleFullscreen: () => void; filterTargetNames: string[]; onFilterTargetNamesChange: Dispatch>; filterOptions: MonitoringFilters; filterPlates: string[]; filterCustomer: string; onFilterCustomerChange: (value: string) => void; filterBrands: string[]; onFilterBrandsChange: (value: string[]) => void; filterRentStatus: string; onFilterRentStatusChange: (value: string) => void; filterDept: string; onFilterDeptChange: (value: string) => void; departments: string[]; sortOrder: SortOrder; onSortByChange: Dispatch>; onSortOrderChange: Dispatch>; fullscreenVehicles: MonitoringVehicle[]; isHighMileageAlert: (vehicle: MonitoringVehicle) => boolean; relativeNow: number; }) { return ( {/* Top bar: compact inline KPI */}

全屏监控

区间 {Math.round(fullscreenStats.totalToday).toLocaleString()} km | 累计 {Math.round(fullscreenStats.totalAll).toLocaleString()} km | 车辆 {fullscreenStats.vehicleCount} | {(fullscreenStats.vehicleCount > 0 ? (sortBy === 'total' ? fullscreenStats.totalAll : fullscreenStats.totalToday) / fullscreenStats.vehicleCount : 0).toFixed(0)} km | 来源 {sourcePriority.map(group => MILEAGE_SOURCE_META[group].label).join(' > ')}
{/* Batch selector + legend */}
{filterOptions.targetNames.map(n => ( ))}
在线 离线 未对接
{/* Table Area */}
{fullscreenLoading && (
加载中...
)} {fullscreenVehicles.map((v) => { const highMileageAlert = isHighMileageAlert(v); const statisticTime = vehicleStatisticTime(v, relativeNow); const sourceDisplay = vehicleSourceDisplay(v); return ( ); })}
状态
车牌号 {filterPlates.length === 0 ? '全部' : `已选 ${filterPlates.length}`}
客户 { const val = e.target.value.trim(); onFilterCustomerChange(val || 'All'); e.target.value = ''; }} onKeyDown={(e) => { if (e.key === 'Enter') { const val = (e.target as HTMLInputElement).value.trim(); onFilterCustomerChange(val || 'All'); (e.target as HTMLInputElement).value = ''; } }} />
品牌 { const val = e.target.value.trim(); if (val) { onFilterBrandsChange(filterBrands.includes(val) ? filterBrands.filter(b => b !== val) : [...filterBrands, val]); } e.target.value = ''; }} onKeyDown={(e) => { if (e.key === 'Enter') { const val = (e.target as HTMLInputElement).value.trim(); if (val) { onFilterBrandsChange(filterBrands.includes(val) ? filterBrands.filter(b => b !== val) : [...filterBrands, val]); } (e.target as HTMLInputElement).value = ''; } }} />
租赁状态
部门
{ if (sortBy === 'today') { onSortOrderChange(sortOrder === 'desc' ? 'asc' : 'desc'); } else { onSortByChange('today'); onSortOrderChange('desc'); } }} >
区间里程 {sortBy === 'today' && ( sortOrder === 'desc' ? : )}
{ if (sortBy === 'total') { onSortOrderChange(sortOrder === 'desc' ? 'asc' : 'desc'); } else { onSortByChange('total'); onSortOrderChange('desc'); } }} >
累计里程 {sortBy === 'total' && ( sortOrder === 'desc' ? : )}
{v.plate}
{sourceDisplay.label}
{statisticTime.label}
{v.customer || '-'} {v.brand || '-'} {v.rentStatus || '-'} {v.department || '-'} {(v.isDataSynced || v.totalKm != null) ? <>{v.mileageAnomaly ? '数据异常' : Math.max(0, v.dailyKm || 0).toLocaleString()} {v.mileageAnomaly ? '' : 'km'} : 未对接} {v.totalKm != null ? <>{v.totalKm.toLocaleString()} km : 未对接}
); }