import { Button, Input, Nav, Space, Tag, Toast } from '@douyinfe/semi-ui'; import { IconActivity, IconBarChartHStroked, IconHistogram, IconHome, IconMapPin, IconSearch, IconServer, IconSetting, IconBell, IconPulse } from '@douyinfe/semi-icons'; import type { ReactNode } from 'react'; import { useState } from 'react'; import type { VehicleSourceConsistency, VehicleServiceStatus } from '../api/types'; import { isAMapConfigured } from '../config/appConfig'; export type PageKey = 'dashboard' | 'vehicles' | 'map' | 'realtime' | 'detail' | 'history' | 'history-query' | 'mileage' | 'alert-events' | 'quality' | 'notification-rules' | 'ops-quality'; const navItems = [ { itemKey: 'dashboard', text: '运营驾驶舱', icon: }, { itemKey: 'map', text: '实时地图', icon: }, { itemKey: 'vehicles', text: '车辆中心', icon: }, { itemKey: 'realtime', text: '实时数据', icon: }, { itemKey: 'detail', text: '车辆档案', icon: }, { itemKey: 'history', text: '轨迹回放', icon: }, { itemKey: 'history-query', text: '历史查询', icon: }, { itemKey: 'mileage', text: '统计查询', icon: }, { itemKey: 'alert-events', text: '告警事件', icon: }, { itemKey: 'notification-rules', text: '通知规则', icon: }, { itemKey: 'ops-quality', text: '运维质量', icon: } ]; function linkHealthClassName(count: number | null) { if (count == null) { return ''; } return count > 0 ? 'vp-link-health-button-warning' : 'vp-link-health-button-ok'; } function alertButtonLabel(linkIssueCount: number | null, activeRuleCount?: number | null, p0RuleCount?: number | null) { const activeCount = Number.isFinite(Number(activeRuleCount)) ? Number(activeRuleCount) : 0; const p0Count = Number.isFinite(Number(p0RuleCount)) ? Number(p0RuleCount) : 0; if (p0Count > 0) { return `告警事件 P0 ${p0Count.toLocaleString()} / 活跃 ${activeCount.toLocaleString()}`; } if (activeCount > 0) { return `告警事件 ${activeCount.toLocaleString()}类规则`; } if (linkIssueCount == null) { return '告警事件'; } return linkIssueCount > 0 ? `告警事件 ${linkIssueCount}项关注` : '告警事件正常'; } function alertButtonClassName(linkIssueCount: number | null, activeRuleCount?: number | null, p0RuleCount?: number | null) { const activeCount = Number.isFinite(Number(activeRuleCount)) ? Number(activeRuleCount) : 0; const p0Count = Number.isFinite(Number(p0RuleCount)) ? Number(p0RuleCount) : 0; if (p0Count > 0 || activeCount > 0 || (linkIssueCount ?? 0) > 0) { return 'vp-link-health-button-warning'; } return linkHealthClassName(linkIssueCount); } export function AppShell({ activePage, linkIssueCount, activeAlertRuleCount, p0AlertRuleCount, platformRelease, currentVehicleStatus, currentVehicleLabel, currentVehicleConsistency, onChange, onVehicleSearch, children }: { activePage: PageKey; linkIssueCount: number | null; activeAlertRuleCount?: number | null; p0AlertRuleCount?: number | null; platformRelease?: string; currentVehicleStatus?: VehicleServiceStatus; currentVehicleLabel?: string; currentVehicleConsistency?: VehicleSourceConsistency; onChange: (page: PageKey) => void; onVehicleSearch: (keyword: string) => void | Promise; children: ReactNode; }) { const [keyword, setKeyword] = useState(''); const [searching, setSearching] = useState(false); const amapConfigured = isAMapConfigured(); const alertLabel = alertButtonLabel(linkIssueCount, activeAlertRuleCount, p0AlertRuleCount); const alertClassName = alertButtonClassName(linkIssueCount, activeAlertRuleCount, p0AlertRuleCount); const selectedPage = activePage === 'quality' ? 'alert-events' : activePage; const search = () => { const value = keyword.trim(); if (!value) { Toast.warning('请输入 VIN / 车牌 / 手机号'); return; } setSearching(true); Promise.resolve(onVehicleSearch(value)).finally(() => setSearching(false)); }; return (
} placeholder="搜索 VIN / 车牌 / 手机号" value={keyword} onChange={setKeyword} onEnterPress={search} style={{ width: 320 }} /> {currentVehicleLabel ? {currentVehicleLabel} : null} {currentVehicleStatus ? ( 当前车辆:{currentVehicleStatus.title} ) : null} {currentVehicleConsistency ? ( 一致性:{currentVehicleConsistency.title || `${currentVehicleConsistency.onlineSourceCount}/${currentVehicleConsistency.sourceCount} 来源`} ) : null} 生产环境 {platformRelease ? 版本 {platformRelease} : null} 32960 / 808 / MQTT 归一 {amapConfigured ? '地图就绪' : '地图待配置'}
{children}
); }