feat(platform): add vehicle data management console
This commit is contained in:
73
vehicle-data-platform/apps/web/src/pages/History.tsx
Normal file
73
vehicle-data-platform/apps/web/src/pages/History.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Button, Card, Form, SideSheet, Space, Table, Tabs, Toast } from '@douyinfe/semi-ui';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { api } from '../api/client';
|
||||
import type { HistoryLocationRow, RawFrameRow } from '../api/types';
|
||||
import { PageHeader } from '../components/PageHeader';
|
||||
|
||||
export function History() {
|
||||
const [locations, setLocations] = useState<HistoryLocationRow[]>([]);
|
||||
const [rawFrames, setRawFrames] = useState<RawFrameRow[]>([]);
|
||||
const [selectedRaw, setSelectedRaw] = useState<RawFrameRow | null>(null);
|
||||
|
||||
const load = (values?: Record<string, string>) => {
|
||||
const params = new URLSearchParams({ limit: '20', includeFields: 'true' });
|
||||
if (values?.vin) params.set('vin', values.vin);
|
||||
if (values?.protocol) params.set('protocol', values.protocol);
|
||||
api.historyLocations(params).then((page) => setLocations(page.items)).catch((error: Error) => Toast.error(error.message));
|
||||
api.rawFrames(params).then((page) => setRawFrames(page.items)).catch((error: Error) => Toast.error(error.message));
|
||||
};
|
||||
|
||||
useEffect(() => load(), []);
|
||||
|
||||
return (
|
||||
<div className="vp-page">
|
||||
<PageHeader title="历史查询" description="位置历史和 RAW 帧历史的分页查询工作台" />
|
||||
<Card bordered>
|
||||
<Form layout="horizontal" onSubmit={(values) => load(values as Record<string, string>)}>
|
||||
<Form.Input field="vin" label="VIN" placeholder="输入 VIN" style={{ width: 260 }} />
|
||||
<Form.Input field="protocol" label="协议" placeholder="GB32960 / JT808 / YUTONG_MQTT" style={{ width: 240 }} />
|
||||
<Space>
|
||||
<Button htmlType="submit" theme="solid" type="primary">查询</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card bordered style={{ marginTop: 16 }}>
|
||||
<Tabs>
|
||||
<Tabs.TabPane tab="位置历史" itemKey="location">
|
||||
<Table
|
||||
rowKey="deviceTime"
|
||||
dataSource={locations}
|
||||
pagination={false}
|
||||
columns={[
|
||||
{ title: 'VIN', dataIndex: 'vin' },
|
||||
{ title: '协议', dataIndex: 'protocol' },
|
||||
{ title: '经度', dataIndex: 'longitude' },
|
||||
{ title: '纬度', dataIndex: 'latitude' },
|
||||
{ title: '速度', dataIndex: 'speedKmh' },
|
||||
{ title: '设备时间', dataIndex: 'deviceTime' }
|
||||
]}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="RAW 帧" itemKey="raw">
|
||||
<Table
|
||||
rowKey="id"
|
||||
dataSource={rawFrames}
|
||||
pagination={false}
|
||||
columns={[
|
||||
{ title: 'ID', dataIndex: 'id' },
|
||||
{ title: 'VIN', dataIndex: 'vin' },
|
||||
{ title: '协议', dataIndex: 'protocol' },
|
||||
{ title: '帧类型', dataIndex: 'frameType' },
|
||||
{ title: '大小', dataIndex: 'rawSizeBytes' },
|
||||
{ title: '操作', render: (_: unknown, row: RawFrameRow) => <Button onClick={() => setSelectedRaw(row)}>字段</Button> }
|
||||
]}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</Card>
|
||||
<SideSheet title="RAW 解析字段" visible={Boolean(selectedRaw)} onCancel={() => setSelectedRaw(null)} width={720}>
|
||||
<pre className="vp-json">{JSON.stringify(selectedRaw?.parsedFields ?? {}, null, 2)}</pre>
|
||||
</SideSheet>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user