From 92d7020b366bbf9e492938260399ea117ad950da Mon Sep 17 00:00:00 2001 From: lingniu Date: Fri, 3 Jul 2026 21:37:32 +0800 Subject: [PATCH] feat(platform): route vehicle searches to detail --- vehicle-data-platform/apps/web/src/App.tsx | 33 ++++++++++++------- .../apps/web/src/layout/AppShell.tsx | 27 +++++++++++++-- .../apps/web/src/pages/VehicleDetail.tsx | 14 ++++---- .../apps/web/src/pages/Vehicles.tsx | 12 +++---- 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/vehicle-data-platform/apps/web/src/App.tsx b/vehicle-data-platform/apps/web/src/App.tsx index a9648657..5c832aa7 100644 --- a/vehicle-data-platform/apps/web/src/App.tsx +++ b/vehicle-data-platform/apps/web/src/App.tsx @@ -8,20 +8,31 @@ import { Realtime } from './pages/Realtime'; import { VehicleDetail } from './pages/VehicleDetail'; import { Vehicles } from './pages/Vehicles'; -const pages: Record = { - dashboard: , - vehicles: , - realtime: , - detail: , - history: , - mileage: , - quality: -}; - export default function App() { const [activePage, setActivePage] = useState('dashboard'); + const [activeVin, setActiveVin] = useState('LB9A32A24R0LS1426'); + + const openVehicle = (vin: string) => { + const nextVin = vin.trim(); + if (!nextVin) { + return; + } + setActiveVin(nextVin); + setActivePage('detail'); + }; + + const pages: Record = { + dashboard: , + vehicles: , + realtime: , + detail: , + history: , + mileage: , + quality: + }; + return ( - + {pages[activePage]} ); diff --git a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx index 6e3479f1..e3381109 100644 --- a/vehicle-data-platform/apps/web/src/layout/AppShell.tsx +++ b/vehicle-data-platform/apps/web/src/layout/AppShell.tsx @@ -1,4 +1,4 @@ -import { Badge, Button, Input, Nav, Space, Tag, Typography } from '@douyinfe/semi-ui'; +import { Badge, Button, Input, Nav, Space, Tag, Toast, Typography } from '@douyinfe/semi-ui'; import { IconActivity, IconBarChartHStroked, @@ -10,6 +10,7 @@ import { IconSetting } from '@douyinfe/semi-icons'; import type { ReactNode } from 'react'; +import { useState } from 'react'; export type PageKey = 'dashboard' | 'vehicles' | 'realtime' | 'detail' | 'history' | 'mileage' | 'quality'; @@ -26,12 +27,25 @@ const navItems = [ export function AppShell({ activePage, onChange, + onVehicleSearch, children }: { activePage: PageKey; onChange: (page: PageKey) => void; + onVehicleSearch: (keyword: string) => void; children: ReactNode; }) { + const [keyword, setKeyword] = useState(''); + + const search = () => { + const value = keyword.trim(); + if (!value) { + Toast.warning('请输入 VIN / 车牌 / 手机号'); + return; + } + onVehicleSearch(value); + }; + return (
@@ -50,8 +64,15 @@ export function AppShell({
- } placeholder="搜索 VIN / 车牌 / 手机号" style={{ width: 320 }} /> - + } + placeholder="搜索 VIN / 车牌 / 手机号" + value={keyword} + onChange={setKeyword} + onEnterPress={search} + style={{ width: 320 }} + /> + 生产环境 diff --git a/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx b/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx index b4f863e1..d7bfc2dc 100644 --- a/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx +++ b/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx @@ -11,12 +11,8 @@ type VehicleQuery = { protocol?: string; }; -const defaultQuery: VehicleQuery = { - vin: 'LB9A32A24R0LS1426' -}; - -export function VehicleDetail() { - const [query, setQuery] = useState(defaultQuery); +export function VehicleDetail({ vin }: { vin: string }) { + const [query, setQuery] = useState({ vin }); const [detail, setDetail] = useState(null); const [loading, setLoading] = useState(false); @@ -38,8 +34,10 @@ export function VehicleDetail() { }; useEffect(() => { - load(defaultQuery); - }, []); + const nextQuery = { vin }; + setQuery(nextQuery); + load(nextQuery); + }, [vin]); const identity = detail?.identity; const latest = detail?.realtime[0]; diff --git a/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx b/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx index 0421d70d..29594b5d 100644 --- a/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Vehicles.tsx @@ -1,4 +1,4 @@ -import { Button, Card, Form, Select, SideSheet, Space, Table, TextArea, Toast } from '@douyinfe/semi-ui'; +import { Button, Card, Form, Select, Space, Table, Toast } from '@douyinfe/semi-ui'; import { useEffect, useMemo, useState } from 'react'; import { api } from '../api/client'; import type { VehicleRow } from '../api/types'; @@ -6,10 +6,9 @@ import { DataEmpty } from '../components/DataEmpty'; import { PageHeader } from '../components/PageHeader'; import { StatusTag } from '../components/StatusTag'; -export function Vehicles() { +export function Vehicles({ onOpenVehicle }: { onOpenVehicle: (vin: string) => void }) { const [rows, setRows] = useState([]); const [loading, setLoading] = useState(true); - const [selected, setSelected] = useState(null); const load = (values?: Record) => { setLoading(true); @@ -35,9 +34,9 @@ export function Vehicles() { { title: '最后在线', dataIndex: 'lastSeen', width: 170 }, { title: '位置', dataIndex: 'locationText' }, { title: '绑定分', dataIndex: 'bindingScore', width: 90 }, - { title: '操作', render: (_: unknown, row: VehicleRow) => } + { title: '操作', render: (_: unknown, row: VehicleRow) => } ], - [] + [onOpenVehicle] ); return ( @@ -64,9 +63,6 @@ export function Vehicles() { )} - setSelected(null)} width={520}> -