feat(platform): refine history query workbench
This commit is contained in:
@@ -903,6 +903,17 @@ export function History({
|
||||
...(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 (
|
||||
<div className="vp-page">
|
||||
@@ -923,6 +934,72 @@ export function History({
|
||||
<Tag color={currentProtocol ? 'blue' : 'green'}>当前来源:{currentProtocol || '全部来源'}</Tag>
|
||||
<Typography.Text type="tertiary">{scopeDescription}</Typography.Text>
|
||||
</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>
|
||||
<Form key={JSON.stringify(filters)} initValues={filters} layout="horizontal" onSubmit={(values) => submit(values)}>
|
||||
<Form.Input field="keyword" label="车辆关键词" placeholder="VIN / 车牌 / 手机号" style={{ width: 260 }} />
|
||||
@@ -959,7 +1036,7 @@ export function History({
|
||||
</Space>
|
||||
</Card>
|
||||
) : 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-summary">
|
||||
<Space wrap>
|
||||
@@ -1024,7 +1101,7 @@ export function History({
|
||||
bordered
|
||||
title={(
|
||||
<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={copyHistoryEvidencePackage}>复制数据复核包</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;
|
||||
}
|
||||
|
||||
.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 {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 260px;
|
||||
@@ -2961,6 +3003,8 @@ button.vp-realtime-command-item:focus-visible {
|
||||
.vp-trajectory-anomaly-grid,
|
||||
.vp-trajectory-impact-board,
|
||||
.vp-trajectory-impact-grid,
|
||||
.vp-history-query-workbench,
|
||||
.vp-history-query-grid,
|
||||
.vp-source-fusion-grid,
|
||||
.vp-source-fusion-facts,
|
||||
.vp-vehicle-map-layout,
|
||||
|
||||
Reference in New Issue
Block a user