feat(platform): refine history query workbench
This commit is contained in:
@@ -903,6 +903,17 @@ export function History({
|
|||||||
...(day ? { dateFrom: day, dateTo: nextDate(day) } : {})
|
...(day ? { dateFrom: day, dateTo: nextDate(day) } : {})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const openQueryTab = (tab: HistoryTabKey) => {
|
||||||
|
const nextFilters = tab === 'fields' ? { ...filters, includeFields: true } : filters;
|
||||||
|
setActiveTab(tab);
|
||||||
|
setFilters(nextFilters);
|
||||||
|
onFiltersChange?.(nextFilters, tab);
|
||||||
|
if (tab === 'location') {
|
||||||
|
loadLocations(nextFilters, 1, locationPagination.pageSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadRawFrames(nextFilters, 1, rawPagination.pageSize, tab === 'fields');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="vp-page">
|
<div className="vp-page">
|
||||||
@@ -923,6 +934,72 @@ export function History({
|
|||||||
<Tag color={currentProtocol ? 'blue' : 'green'}>当前来源:{currentProtocol || '全部来源'}</Tag>
|
<Tag color={currentProtocol ? 'blue' : 'green'}>当前来源:{currentProtocol || '全部来源'}</Tag>
|
||||||
<Typography.Text type="tertiary">{scopeDescription}</Typography.Text>
|
<Typography.Text type="tertiary">{scopeDescription}</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
|
{mode === 'query' ? (
|
||||||
|
<Card bordered title="历史查询与导出工作台">
|
||||||
|
<div className="vp-history-query-workbench">
|
||||||
|
<div className="vp-history-query-summary">
|
||||||
|
<Space wrap>
|
||||||
|
<Tag color="blue">客户查询</Tag>
|
||||||
|
<Tag color={activeTab === 'location' ? 'green' : 'blue'}>
|
||||||
|
{activeTab === 'location' ? '位置历史' : activeTab === 'raw' ? '原始记录' : '字段明细'}
|
||||||
|
</Tag>
|
||||||
|
</Space>
|
||||||
|
<Typography.Text strong>{currentVehicleKeyword || '全部车辆'}</Typography.Text>
|
||||||
|
<Typography.Text type="secondary">
|
||||||
|
面向车辆服务的历史数据检索入口。先按车辆和时间缩小范围,再导出位置、原始记录或字段明细,用于客户问询、BI 核对和问题追溯。
|
||||||
|
</Typography.Text>
|
||||||
|
<Space wrap>
|
||||||
|
<Button size="small" theme="solid" type="primary" onClick={() => openQueryTab('location')}>查询位置历史</Button>
|
||||||
|
<Button size="small" onClick={() => openQueryTab('raw')}>查询原始记录</Button>
|
||||||
|
<Button size="small" onClick={() => openQueryTab('fields')}>查询字段明细</Button>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
<div className="vp-history-query-grid">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
label: '位置记录',
|
||||||
|
value: locations.total.toLocaleString(),
|
||||||
|
detail: `${validLocations.length.toLocaleString()} 个有效坐标,可用于轨迹和定位复盘。`,
|
||||||
|
action: '导出位置',
|
||||||
|
color: 'green' as const,
|
||||||
|
onClick: exportLocations
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '原始记录',
|
||||||
|
value: `${(rawFrames.total ?? 0).toLocaleString()} 帧`,
|
||||||
|
detail: '保存协议接入后的原始证据,可按车辆和时间追溯。',
|
||||||
|
action: '导出原始',
|
||||||
|
color: 'blue' as const,
|
||||||
|
onClick: exportRawFrames
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '字段明细',
|
||||||
|
value: rawFieldRows.length.toLocaleString(),
|
||||||
|
detail: selectedFieldCount > 0 ? `已裁剪 ${selectedFieldCount.toLocaleString()} 个字段。` : '可勾选字段明细或填写字段裁剪后查询。',
|
||||||
|
action: '导出字段',
|
||||||
|
color: rawFieldRows.length > 0 ? 'green' as const : 'grey' as const,
|
||||||
|
onClick: exportRawFields
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '服务联动',
|
||||||
|
value: currentVehicleKeyword ? '单车' : '批量',
|
||||||
|
detail: currentVehicleKeyword ? '可进入车辆服务、轨迹回放和里程核对。' : '输入 VIN、车牌或手机号后可进入单车服务。',
|
||||||
|
action: '车辆服务',
|
||||||
|
color: currentVehicleKeyword ? 'blue' as const : 'grey' as const,
|
||||||
|
onClick: () => currentVehicleKeyword && onOpenVehicle(currentVehicleKeyword, currentProtocol)
|
||||||
|
}
|
||||||
|
].map((item) => (
|
||||||
|
<div key={item.label} className="vp-history-query-item">
|
||||||
|
<Tag color={item.color}>{item.label}</Tag>
|
||||||
|
<strong>{item.value}</strong>
|
||||||
|
<Typography.Text type="secondary">{item.detail}</Typography.Text>
|
||||||
|
<Button size="small" disabled={item.label === '服务联动' && !currentVehicleKeyword} onClick={item.onClick}>{item.action}</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
) : null}
|
||||||
<Card bordered>
|
<Card bordered>
|
||||||
<Form key={JSON.stringify(filters)} initValues={filters} layout="horizontal" onSubmit={(values) => submit(values)}>
|
<Form key={JSON.stringify(filters)} initValues={filters} layout="horizontal" onSubmit={(values) => submit(values)}>
|
||||||
<Form.Input field="keyword" label="车辆关键词" placeholder="VIN / 车牌 / 手机号" style={{ width: 260 }} />
|
<Form.Input field="keyword" label="车辆关键词" placeholder="VIN / 车牌 / 手机号" style={{ width: 260 }} />
|
||||||
@@ -959,7 +1036,7 @@ export function History({
|
|||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
) : null}
|
) : null}
|
||||||
<Card bordered title="轨迹运营影响" style={{ marginTop: 16 }}>
|
<Card bordered title={mode === 'query' ? '历史数据质量' : '轨迹运营影响'} style={{ marginTop: 16 }}>
|
||||||
<div className="vp-trajectory-impact-board">
|
<div className="vp-trajectory-impact-board">
|
||||||
<div className="vp-trajectory-impact-summary">
|
<div className="vp-trajectory-impact-summary">
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
@@ -1024,7 +1101,7 @@ export function History({
|
|||||||
bordered
|
bordered
|
||||||
title={(
|
title={(
|
||||||
<Space>
|
<Space>
|
||||||
<span>轨迹回放作业台</span>
|
<span>{mode === 'query' ? '轨迹预览与证据' : '轨迹回放作业台'}</span>
|
||||||
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyTrajectorySummary}>复制轨迹摘要</Button>
|
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyTrajectorySummary}>复制轨迹摘要</Button>
|
||||||
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyHistoryEvidencePackage}>复制数据复核包</Button>
|
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyHistoryEvidencePackage}>复制数据复核包</Button>
|
||||||
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyTrajectoryReviewPackage}>复制轨迹复盘包</Button>
|
<Button size="small" theme="light" icon={<IconCopy />} onClick={copyTrajectoryReviewPackage}>复制轨迹复盘包</Button>
|
||||||
|
|||||||
@@ -1996,6 +1996,48 @@ button.vp-realtime-command-item:focus-visible {
|
|||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vp-history-query-workbench {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(260px, 0.68fr) minmax(0, 1.32fr);
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-history-query-summary {
|
||||||
|
min-height: 176px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid rgba(58, 104, 240, 0.24);
|
||||||
|
border-radius: var(--vp-radius);
|
||||||
|
background: #f6f8ff;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-history-query-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-history-query-item {
|
||||||
|
min-height: 176px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid var(--vp-border);
|
||||||
|
border-radius: var(--vp-radius);
|
||||||
|
background: #fbfcff;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-history-query-item strong {
|
||||||
|
color: var(--vp-text);
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 26px;
|
||||||
|
font-weight: 700;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
.vp-playback-layout {
|
.vp-playback-layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) 260px;
|
grid-template-columns: minmax(0, 1fr) 260px;
|
||||||
@@ -2961,6 +3003,8 @@ button.vp-realtime-command-item:focus-visible {
|
|||||||
.vp-trajectory-anomaly-grid,
|
.vp-trajectory-anomaly-grid,
|
||||||
.vp-trajectory-impact-board,
|
.vp-trajectory-impact-board,
|
||||||
.vp-trajectory-impact-grid,
|
.vp-trajectory-impact-grid,
|
||||||
|
.vp-history-query-workbench,
|
||||||
|
.vp-history-query-grid,
|
||||||
.vp-source-fusion-grid,
|
.vp-source-fusion-grid,
|
||||||
.vp-source-fusion-facts,
|
.vp-source-fusion-facts,
|
||||||
.vp-vehicle-map-layout,
|
.vp-vehicle-map-layout,
|
||||||
|
|||||||
Reference in New Issue
Block a user