feat(platform): summarize vehicle source coverage
This commit is contained in:
@@ -11,6 +11,13 @@ type VehicleQuery = {
|
||||
protocol?: string;
|
||||
};
|
||||
|
||||
const sourceCapabilities: Array<{ key: keyof Pick<VehicleSourceStatus, 'hasRealtime' | 'hasHistory' | 'hasRaw' | 'hasMileage'>; label: string }> = [
|
||||
{ key: 'hasRealtime', label: '实时' },
|
||||
{ key: 'hasHistory', label: '历史' },
|
||||
{ key: 'hasRaw', label: 'RAW' },
|
||||
{ key: 'hasMileage', label: '里程' }
|
||||
];
|
||||
|
||||
export function VehicleDetail({
|
||||
vin,
|
||||
onOpenHistory,
|
||||
@@ -66,7 +73,7 @@ export function VehicleDetail({
|
||||
load(nextQuery);
|
||||
}}>
|
||||
<Form.Input field="vin" label="VIN" placeholder="输入 VIN" style={{ width: 280 }} />
|
||||
<Form.Select field="protocol" label="来源协议" placeholder="全部来源" style={{ width: 180 }}>
|
||||
<Form.Select field="protocol" label="数据来源" placeholder="全部来源" style={{ width: 180 }}>
|
||||
<Select.Option value="GB32960">GB32960</Select.Option>
|
||||
<Select.Option value="JT808">JT808</Select.Option>
|
||||
<Select.Option value="YUTONG_MQTT">YUTONG_MQTT</Select.Option>
|
||||
@@ -91,7 +98,7 @@ export function VehicleDetail({
|
||||
{ key: 'OEM', value: summary?.oem || identity?.oem || '-' },
|
||||
{ key: '在线', value: <StatusTag status={online ? 'ok' : 'offline'} /> },
|
||||
{
|
||||
key: '来源协议',
|
||||
key: '数据来源',
|
||||
value: protocols.length > 0 ? <Space>{protocols.map((item) => <Tag key={item} color={item === summary?.primaryProtocol ? 'blue' : 'grey'}>{item}</Tag>)}</Space> : '-'
|
||||
},
|
||||
{ key: '在线来源', value: summary ? `${summary.onlineSourceCount}/${summary.sourceCount}` : '-' },
|
||||
@@ -103,7 +110,34 @@ export function VehicleDetail({
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card bordered title="来源状态" style={{ marginTop: 16 }}>
|
||||
<Card bordered title="数据来源覆盖" style={{ marginTop: 16 }}>
|
||||
{detail?.sourceStatus?.length ? (
|
||||
<div className="vp-source-grid">
|
||||
{detail.sourceStatus.map((source) => (
|
||||
<div key={source.protocol} className="vp-source-card">
|
||||
<div className="vp-source-card-head">
|
||||
<Space>
|
||||
<Tag color={source.protocol === summary?.primaryProtocol ? 'blue' : 'grey'}>{source.protocol}</Tag>
|
||||
<StatusTag status={source.online ? 'ok' : 'offline'} />
|
||||
</Space>
|
||||
<Typography.Text type="tertiary">{source.lastSeen || '无上报'}</Typography.Text>
|
||||
</div>
|
||||
<Space spacing={4} wrap>
|
||||
{sourceCapabilities.map((item) => (
|
||||
<Tag key={item.key} color={source[item.key] ? 'green' : 'grey'}>
|
||||
{item.label}{source[item.key] ? '有' : '无'}
|
||||
</Tag>
|
||||
))}
|
||||
</Space>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<Typography.Text type="secondary">暂未查询到该车辆的数据来源覆盖。</Typography.Text>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
<Card bordered title="来源诊断明细" style={{ marginTop: 16 }}>
|
||||
<Table
|
||||
loading={loading}
|
||||
pagination={false}
|
||||
|
||||
@@ -167,6 +167,28 @@ body {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vp-source-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.vp-source-card {
|
||||
min-height: 86px;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--vp-border);
|
||||
border-radius: var(--vp-radius);
|
||||
background: #fbfcff;
|
||||
}
|
||||
|
||||
.vp-source-card-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.vp-realtime-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user