feat(platform-web): surface vehicle service summary
This commit is contained in:
@@ -2,7 +2,7 @@ import { Button, Card, Col, Form, Row, Select, Space, Spin, Table, Tag, Toast, T
|
||||
import { IconSearch } from '@douyinfe/semi-icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { api } from '../api/client';
|
||||
import type { DashboardSummary, LinkHealth, ProtocolStat, QualityIssueRow, ServiceStatusStat, VehicleCoverageRow, VehicleRealtimeRow } from '../api/types';
|
||||
import type { DashboardSummary, LinkHealth, ProtocolStat, QualityIssueRow, ServiceStatusStat, VehicleCoverageRow, VehicleRealtimeRow, VehicleServiceSummary } from '../api/types';
|
||||
import { PageHeader } from '../components/PageHeader';
|
||||
import { StatusTag } from '../components/StatusTag';
|
||||
import { qualityIssueVehicleLookup } from '../domain/vehicleLookup';
|
||||
@@ -31,6 +31,10 @@ function formatLag(value?: number | null) {
|
||||
return value == null ? '未接入' : value.toLocaleString();
|
||||
}
|
||||
|
||||
function formatCount(value?: number | null) {
|
||||
return value == null ? '0' : value.toLocaleString();
|
||||
}
|
||||
|
||||
function rowServiceStatus(row: { serviceStatus?: { title: string; severity: string }; onlineSourceCount: number; sourceCount: number }) {
|
||||
if (row.serviceStatus) {
|
||||
return {
|
||||
@@ -49,6 +53,7 @@ function rowServiceStatus(row: { serviceStatus?: { title: string; severity: stri
|
||||
|
||||
export function Dashboard({ onOpenVehicle, onOpenQuality }: { onOpenVehicle: (vin: string) => void; onOpenQuality: () => void }) {
|
||||
const [summary, setSummary] = useState<DashboardSummary | null>(null);
|
||||
const [serviceSummary, setServiceSummary] = useState<VehicleServiceSummary | null>(null);
|
||||
const [coverage, setCoverage] = useState<VehicleCoverageRow[]>([]);
|
||||
const [locations, setLocations] = useState<VehicleRealtimeRow[]>([]);
|
||||
const [qualityIssues, setQualityIssues] = useState<QualityIssueRow[]>([]);
|
||||
@@ -74,12 +79,14 @@ export function Dashboard({ onOpenVehicle, onOpenQuality }: { onOpenVehicle: (vi
|
||||
useEffect(() => {
|
||||
Promise.all([
|
||||
api.dashboardSummary(),
|
||||
api.vehicleServiceSummary(),
|
||||
api.vehicleCoverage(new URLSearchParams({ limit: '8' })),
|
||||
api.vehicleRealtime(new URLSearchParams({ limit: '8' })),
|
||||
api.qualityIssues(new URLSearchParams({ limit: '5' }))
|
||||
])
|
||||
.then(([nextSummary, coveragePage, locationPage, qualityPage]) => {
|
||||
.then(([nextSummary, nextServiceSummary, coveragePage, locationPage, qualityPage]) => {
|
||||
setSummary(nextSummary);
|
||||
setServiceSummary(nextServiceSummary);
|
||||
setCoverage(coveragePage.items);
|
||||
setLocations(locationPage.items);
|
||||
setQualityIssues(qualityPage.items);
|
||||
@@ -89,10 +96,10 @@ export function Dashboard({ onOpenVehicle, onOpenQuality }: { onOpenVehicle: (vi
|
||||
}, []);
|
||||
|
||||
const kpis = [
|
||||
{ label: '在线车辆', value: summary?.onlineVehicles ?? 0 },
|
||||
{ label: '今日活跃', value: summary?.activeToday ?? 0 },
|
||||
{ label: '今日帧数', value: summary?.frameToday.toLocaleString() ?? '0' },
|
||||
{ label: '质量问题', value: summary?.issueVehicles ?? 0 }
|
||||
{ label: '总车辆', value: formatCount(serviceSummary?.totalVehicles) },
|
||||
{ label: '在线车辆', value: formatCount(serviceSummary?.onlineVehicles ?? summary?.onlineVehicles) },
|
||||
{ label: '多源车辆', value: formatCount(serviceSummary?.multiSourceVehicles) },
|
||||
{ label: '身份未绑定', value: formatCount(serviceSummary?.identityRequiredVehicles) }
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -112,7 +119,7 @@ export function Dashboard({ onOpenVehicle, onOpenQuality }: { onOpenVehicle: (vi
|
||||
<Card title="车辆服务状态" bordered>
|
||||
<Table
|
||||
pagination={false}
|
||||
dataSource={summary?.serviceStatuses ?? []}
|
||||
dataSource={serviceSummary?.serviceStatuses ?? summary?.serviceStatuses ?? []}
|
||||
columns={[
|
||||
{
|
||||
title: '状态',
|
||||
@@ -139,7 +146,7 @@ export function Dashboard({ onOpenVehicle, onOpenQuality }: { onOpenVehicle: (vi
|
||||
<Card title="数据来源在线分布" bordered>
|
||||
<Table
|
||||
pagination={false}
|
||||
dataSource={summary?.protocols ?? []}
|
||||
dataSource={serviceSummary?.protocols ?? summary?.protocols ?? []}
|
||||
columns={[
|
||||
{ title: '数据来源', dataIndex: 'protocol' },
|
||||
{ title: '在线', dataIndex: 'online' },
|
||||
|
||||
Reference in New Issue
Block a user