feat(platform): align customer mileage service wording

This commit is contained in:
lingniu
2026-07-06 06:19:40 +08:00
parent e847e1c7e8
commit 536d37ca9b
9 changed files with 316 additions and 316 deletions

View File

@@ -227,7 +227,7 @@ function focusVehicleFromIssue(row: QualityIssueRow): FocusVehicleService {
realtimeEvidence: `来源 ${qualityProtocolLabel(row.protocol)} / 最后 ${row.lastSeen || '-'}`,
historyEvidence: filters.dateFrom ? `${filters.dateFrom}${filters.dateTo}` : '待确认时间窗',
alertEvidence: row.detail || qualityIssueLabel(row.issueType),
statisticEvidence: '统计查询需回溯车辆口径',
statisticEvidence: '里程统计需回溯车辆口径',
issueType: row.issueType
};
}
@@ -475,7 +475,7 @@ export function Dashboard({
onClick: () => onOpenHistory()
},
{
title: '统计查询',
title: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 辆可统计`,
detail: '按自定义时间查询区间里程、日里程和异常记录。',
action: '查看统计',
@@ -513,9 +513,9 @@ export function Dashboard({
},
{
step: '04',
title: '统计查询',
title: '里程统计',
detail: '用同一时间窗核对区间里程和每日统计。',
action: '统计查询',
action: '里程统计',
onClick: () => onOpenMileage({})
},
{
@@ -592,7 +592,7 @@ export function Dashboard({
detail: '同一时间窗贯穿轨迹、统计、原始记录和告警,不需要跨页面重复输入。',
color: 'blue' as const,
primaryAction: '轨迹回放',
secondaryAction: '统计查询',
secondaryAction: '里程统计',
onPrimary: () => openTimeMonitorHistory(),
onSecondary: () => openTimeMonitorMileage()
},
@@ -659,10 +659,10 @@ export function Dashboard({
onClick: () => onOpenQuality()
},
{
title: '统计查询',
title: '里程统计',
status: `统计车辆 ${formatCount(serviceSummary?.totalVehicles)}`,
color: 'green' as const,
description: '提供里程等运营统计查询,保证区间总值与每日统计口径闭合。',
description: '提供里程等运营里程统计,保证区间总值与每日里程口径闭合。',
action: '查看统计',
onClick: () => onOpenMileage()
}
@@ -731,11 +731,11 @@ export function Dashboard({
onClick: () => onOpenQuality()
},
{
title: '统计复核',
title: '里程复核',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
color: 'green' as const,
detail: '核对统计查询口径,保证区间统计和每日统计闭合。',
action: '统计查询',
detail: '核对里程口径,保证区间统计和每日统计闭合。',
action: '里程统计',
onClick: () => onOpenMileage()
}
];
@@ -841,13 +841,13 @@ export function Dashboard({
]
},
{
title: '统计查询',
title: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆口径`,
meta: '区间闭合复核',
color: 'green' as const,
detail: '统计指标先按车辆口径闭合,再回溯轨迹和原始记录。',
actions: [
{ label: '打开统计查询', onClick: () => onOpenMileage() },
{ label: '打开里程统计', onClick: () => onOpenMileage() },
{ label: '查看车辆中心', onClick: () => onOpenVehicles({}) }
]
}
@@ -998,7 +998,7 @@ export function Dashboard({
`范围:${timeMonitorSummary}`,
`交付结论:${timeMonitorDeliveryStatus.label}${timeMonitorDeliveryStatus.detail}`,
`时间窗判定:${dayRangeText(scope.dateFrom, scope.dateTo)}`,
'平台能力:实时地图 / 轨迹回放 / 统计查询 / 历史数据查询 / 告警通知',
'平台能力:实时地图 / 轨迹回放 / 里程统计 / 历史数据查询 / 告警通知',
`车辆范围:${scope.keyword || '全部车辆'}`,
`数据通道:${scope.protocol || '全部数据通道'}`,
`时间范围:${scope.dateFrom || '-'}${scope.dateTo || '-'}`,
@@ -1011,7 +1011,7 @@ export function Dashboard({
'下一步动作:',
...timeMonitorDeliveryActions.map((item, index) => `${index + 1}. ${item.label}${item.value}${item.detail}`),
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`历史数据查询:${appURL(buildAppHash({ page: 'history-query', keyword: scope.keyword, protocol: scope.protocol, filters: rawFilters }))}`,
`告警通知:${appURL(buildAppHash({ page: 'alert-events', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`实时地图:${appURL(buildAppHash({ page: 'map', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`
@@ -1028,7 +1028,7 @@ export function Dashboard({
onClick: openTimeMonitorHistory
},
{
label: '统计查询',
label: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '用同一范围核对区间里程和日统计闭合。',
action: '查看统计',
@@ -1076,7 +1076,7 @@ export function Dashboard({
label: '核对里程',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '用同一范围核对区间里程、日统计和 BI 口径。',
action: '统计查询',
action: '里程统计',
color: 'green' as const,
onClick: openTimeMonitorMileage
},
@@ -1174,7 +1174,7 @@ export function Dashboard({
},
{
label: '核对里程',
action: '统计查询',
action: '里程统计',
color: 'green' as const,
disabled: false,
onClick: openTimeMonitorMileage
@@ -1195,11 +1195,11 @@ export function Dashboard({
`作业范围:${timeMonitorSummary}`,
`交付SLA${timeMonitorWindowLabel}内完成轨迹复盘、统计核对、历史导出和告警说明`,
`交付状态:${timeMonitorDeliveryStatus.label}${timeMonitorDeliveryStatus.detail}`,
'交付物:轨迹回放链接 / 统计查询链接 / 历史导出链接 / 告警复盘链接',
'交付物:轨迹回放链接 / 里程统计链接 / 历史导出链接 / 告警复盘链接',
`升级条件:${formatCount(summary?.issueVehicles)} 告警车辆需要先进入告警复盘`,
`责任动作:${timeMonitorHasAlerts ? '先处理告警,再交付证据' : '先完成客户复盘,再按需导出证据'}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`历史导出:${appURL(buildAppHash({ page: 'history-query', keyword: scope.keyword, protocol: scope.protocol, filters: rawFilters }))}`,
`告警复盘:${appURL(buildAppHash({ page: 'alert-events', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`
];
@@ -1225,7 +1225,7 @@ export function Dashboard({
{
label: '交付物',
value: '轨迹/统计/导出/告警',
detail: '交付轨迹回放、统计查询、历史导出和告警复盘四个入口。',
detail: '交付轨迹回放、里程统计、历史导出和告警复盘四个入口。',
action: '导出证据',
color: timeMonitorHasHistory ? 'blue' as const : 'orange' as const,
onClick: openTimeMonitorRaw
@@ -1248,7 +1248,7 @@ export function Dashboard({
onClick: openTimeMonitorHistory
},
{
label: '统计查询',
label: '里程统计',
value: timeMonitorWindowLabel,
detail: '用同一时间窗核对区间里程、日报闭合和异常点。',
color: 'green' as const,
@@ -1321,7 +1321,7 @@ export function Dashboard({
owner: '告警 / 统计',
evidence: `告警 ${formatCount(summary?.issueVehicles)},统计车辆 ${formatCount(serviceSummary?.totalVehicles)}`,
detail: '断链、缺字段、里程异常和离线时长进入通知、统计和复核工作流。',
action: '统计查询',
action: '里程统计',
onClick: () => onOpenMileage()
}
];
@@ -1367,11 +1367,11 @@ export function Dashboard({
onSecondary: () => onOpenQuality(highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {})
},
{
title: '统计查询',
title: '里程统计',
objective: '按车辆口径查询里程等指标,保证区间统计和日统计可闭合。',
evidence: `车辆口径 ${formatCount(serviceSummary?.totalVehicles)} / 区间统计可追溯轨迹证据`,
sla: '统计值必须能追溯轨迹和原始记录',
primaryAction: '统计查询',
primaryAction: '里程统计',
secondaryAction: '车辆中心',
onPrimary: () => onOpenMileage(),
onSecondary: () => onOpenVehicles({})
@@ -1398,7 +1398,7 @@ export function Dashboard({
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: highPriorityFilters?.keyword, protocol: highPriorityFilters?.protocol, filters: highPriorityFilters }))}`,
`原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: highPriorityFilters?.keyword, protocol: highPriorityFilters?.protocol, filters: { ...highPriorityFilters, tab: 'raw', includeFields: 'true' } }))}`,
`告警事件:${appURL(buildAppHash({ page: 'alert-events', filters: highPriorityIssue?.issueType ? { issueType: highPriorityIssue.issueType } : {} }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}`,
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: highPriorityLookupKey, protocol: highPriorityIssue?.protocol }))}`
].filter(Boolean);
copyText(lines.join('\n'), '客户交付摘要');
@@ -1438,7 +1438,7 @@ export function Dashboard({
`轨迹回放:${appURL(buildAppHash({ page: 'history' }))}`,
`历史查询:${appURL(buildAppHash({ page: 'history-query', filters: { tab: 'raw', includeFields: 'true' } }))}`,
`告警事件:${appURL(buildAppHash({ page: 'alert-events' }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage' }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage' }))}`,
`运维质量:${appURL(buildAppHash({ page: 'ops-quality' }))}`
];
copyText(lines.join('\n'), '数据流转图');
@@ -1462,7 +1462,7 @@ export function Dashboard({
`实时监控:${appURL(buildAppHash({ page: 'realtime', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`,
`原始记录:${appURL(buildAppHash({ page: 'history-query', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol, filters: { ...commonFilters, tab: 'raw', includeFields: 'true' } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol }))}`,
`告警事件:${appURL(buildAppHash({ page: 'alert-events', keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol, filters: focusVehicle.issueType ? { issueType: focusVehicle.issueType } : {} }))}`
];
copyText(lines.join('\n'), '重点车辆服务处置卡');
@@ -1563,10 +1563,10 @@ export function Dashboard({
{
title: '自定义时间复盘',
value: taskTimeMonitorSummary,
detail: '一个时间窗贯穿轨迹回放、统计查询、历史查询和告警复盘,适合客户问询与 BI 核对。',
detail: '一个时间窗贯穿轨迹回放、里程统计、历史查询和告警复盘,适合客户问询与 BI 核对。',
color: 'blue' as const,
primaryAction: '轨迹复盘',
secondaryAction: '统计查询',
secondaryAction: '里程统计',
onPrimary: () => openTimeMonitorHistory(),
onSecondary: () => openTimeMonitorMileage()
},
@@ -1601,7 +1601,7 @@ export function Dashboard({
{
title: '复盘时间',
value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo),
detail: '同一个时间窗贯穿轨迹回放、统计查询、原始记录和告警复盘。',
detail: '同一个时间窗贯穿轨迹回放、里程统计、原始记录和告警复盘。',
action: '轨迹回放',
color: 'blue' as const,
onClick: openTimeMonitorHistory
@@ -1653,10 +1653,10 @@ export function Dashboard({
},
{
step: '4',
title: '复盘统计',
title: '复盘里程',
value: `${formatCount(summary?.activeToday)} 活跃`,
detail: '用轨迹、位置历史和里程统计回答这段时间发生了什么。',
action: '轨迹统计',
action: '轨迹里程',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -1689,7 +1689,7 @@ export function Dashboard({
`车辆中心:${appURL(buildAppHash({ page: 'vehicles' }))}`,
`实时地图:${appURL(buildAppHash({ page: 'map', filters: { online: 'online' } }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`,
`历史数据:${appURL(buildAppHash({ page: 'history-query', keyword: scope.keyword, protocol: scope.protocol, filters: rawFilters }))}`,
`告警事件:${appURL(buildAppHash({ page: 'alert-events', keyword: scope.keyword, protocol: scope.protocol, filters: scope }))}`
];
@@ -1753,8 +1753,8 @@ export function Dashboard({
{
label: '里程统计',
value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo),
detail: '核对区间里程、每日闭合、异常记录和 BI 统计口径。',
action: '统计查询',
detail: '核对区间里程、每日闭合、异常记录和 BI 里程口径。',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -1791,9 +1791,9 @@ export function Dashboard({
onClick: openTimeMonitorHistory
},
{
title: '统计查询',
title: '里程统计',
description: '按车辆口径核对区间里程、日统计和异常来源。',
action: '统计查询',
action: '里程统计',
evidence: `${formatCount(serviceSummary?.totalVehicles)} 辆可统计`,
onClick: openTimeMonitorMileage
},
@@ -1833,7 +1833,7 @@ export function Dashboard({
label: 'Mileage',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '按车辆口径查询区间里程、日统计和异常断点。',
action: '查统计',
action: '查里程',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -1917,7 +1917,7 @@ export function Dashboard({
label: '里程周报模板',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '按车辆口径复用里程统计,支撑周报、对账和 BI 复核。',
action: '统计查询',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2066,7 +2066,7 @@ export function Dashboard({
question: '这段时间跑了多少',
answer: `${dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo)},用同一时间窗核对区间里程和每日统计。`,
metric: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
action: '查统计查询',
action: '查里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2189,7 +2189,7 @@ export function Dashboard({
title: '查这段时间',
value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo),
detail: '同窗查看轨迹和里程统计',
action: '轨迹统计',
action: '轨迹里程',
color: 'blue' as const,
onClick: openTimeMonitorHistory
},
@@ -2304,10 +2304,10 @@ export function Dashboard({
onClick: openTimeMonitorHistory
},
{
label: '统计查询',
label: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '按车辆口径核对区间里程、日统计和异常来源。',
action: '查统计',
action: '查里程',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2432,8 +2432,8 @@ export function Dashboard({
{
label: '里程能耗',
value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo),
detail: '用同一时间窗核对里程、运行状态和能耗相关统计口径。',
action: '统计查询',
detail: '用同一时间窗核对里程、运行状态和能耗相关里程口径。',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
}
@@ -2477,7 +2477,7 @@ export function Dashboard({
title: '核对时间窗里程',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '按同一时间范围核对区间里程、每日统计和 BI 口径。',
action: '统计查询',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2527,7 +2527,7 @@ export function Dashboard({
label: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '核对区间里程、每日统计和 BI 展示口径。',
action: '统计查询',
action: '里程统计',
color: 'green' as const,
onClick: openTimeMonitorMileage
},
@@ -2569,7 +2569,7 @@ export function Dashboard({
label: '里程统计',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '以车辆为对象核对区间里程、每日统计和 BI 口径。',
action: '统计查询',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2602,7 +2602,7 @@ export function Dashboard({
{
label: '里程统计',
value: dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo),
detail: '核对区间里程、每日里程和客户 BI 统计口径。',
detail: '核对区间里程、每日里程和客户 BI 里程口径。',
action: '核对里程',
color: 'blue' as const,
onClick: openTimeMonitorMileage
@@ -2671,7 +2671,7 @@ export function Dashboard({
question: '里程怎么算',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '查询区间里程、每日里程和统计闭合情况,支撑 BI 口径复核。',
action: '统计查询',
action: '里程统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
},
@@ -2715,7 +2715,7 @@ export function Dashboard({
label: '里程统计',
question: '里程是否可信',
value: `${formatCount(serviceSummary?.totalVehicles)} 车辆`,
detail: '面向客户核对区间里程、每日汇总和 BI 统计口径。',
detail: '面向客户核对区间里程、每日汇总和 BI 里程口径。',
action: '核对统计',
color: 'blue' as const,
onClick: openTimeMonitorMileage
@@ -2874,7 +2874,7 @@ export function Dashboard({
title={focusMode === 'time-window' ? '自定义时间监控' : '车辆服务工作台'}
description={focusMode === 'time-window'
? '把客户选择的一辆车和一个时间窗固定下来,同时进入实时地图、轨迹回放、里程统计、历史导出和告警复盘。'
: '面向客户的车辆地图、实时监控、轨迹回放、统计查询、自定义时间窗复盘、历史查询、告警通知和数据导出'}
: '面向客户的车辆地图、实时监控、轨迹回放、里程统计、自定义时间窗复盘、历史查询、告警通知和数据导出'}
/>
<Spin spinning={loading}>
{focusMode === 'overview' ? (
@@ -2919,7 +2919,7 @@ export function Dashboard({
<div className="vp-customer-service-overview-copy">
<Typography.Text strong></Typography.Text>
<Typography.Text type="secondary">
使
使
</Typography.Text>
</div>
<div className="vp-customer-service-overview-grid">
@@ -3242,7 +3242,7 @@ export function Dashboard({
<Space wrap>
<Button size="small" theme="solid" type="primary" aria-label="车辆地图态势 打开实时地图" onClick={() => onOpenMap({ online: 'online' })}></Button>
<Button size="small" theme="light" type="primary" aria-label="车辆地图态势 回放轨迹" onClick={openTimeMonitorHistory}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="warning" onClick={() => onOpenQuality()}></Button>
</Space>
</div>
@@ -3372,7 +3372,7 @@ export function Dashboard({
</Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
</div>
<div className="vp-customer-saved-view-library-grid">
@@ -3845,7 +3845,7 @@ export function Dashboard({
</Space>
<Typography.Title heading={3} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
</div>
<VehicleMap
@@ -3995,10 +3995,10 @@ export function Dashboard({
<Tag color={timeMonitorScope().keyword ? 'green' : 'grey'}>{timeMonitorScope().keyword ? '单车' : '全域'}</Tag>
</Space>
<strong>{timeMonitorSummary}</strong>
<span></span>
<span></span>
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={openTimeMonitorHistory}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorRaw}></Button>
</Space>
</div>
@@ -4022,7 +4022,7 @@ export function Dashboard({
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}>使</Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={copyCustomerServiceGuide}></Button>
@@ -4075,12 +4075,12 @@ export function Dashboard({
</Form>
<div className="vp-time-monitor-actions">
<Button theme="solid" type="primary" onClick={openTimeMonitorHistory}></Button>
<Button theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button theme="light" type="primary" onClick={openTimeMonitorRaw}></Button>
<Button theme="light" type="warning" onClick={openTimeMonitorAlerts}></Button>
</div>
<Typography.Text type="secondary">
</Typography.Text>
<div className="vp-time-review-package">
<div className="vp-time-review-summary">
@@ -4095,7 +4095,7 @@ export function Dashboard({
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={copyTimeMonitorReviewPackage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorHistory}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorMileage}></Button>
<Button size="small" theme="light" type="primary" onClick={openTimeMonitorRaw}></Button>
<Button size="small" theme="light" type="warning" onClick={openTimeMonitorAlerts}></Button>
</Space>
@@ -4261,7 +4261,7 @@ export function Dashboard({
{[
{ title: '今天车辆轨迹', detail: '查看当天活跃车辆的轨迹、速度和里程断点。', action: '查今天', onClick: openTimeMonitorHistory },
{ title: '历史时间窗', detail: '按任意起止时间查询位置历史、原始记录和字段明细。', action: '自定义查询', onClick: openTimeMonitorRaw },
{ title: '统计查询', detail: '按车辆和时间范围核对区间里程、日统计和异常点。', action: '统计查询', onClick: openTimeMonitorMileage },
{ title: '里程统计', detail: '按车辆和时间范围核对区间里程、日统计和异常点。', action: '里程统计', onClick: openTimeMonitorMileage },
{ title: '告警复盘', detail: '按车辆或事件回放告警发生前后的轨迹和数据证据。', action: '告警事件', onClick: openTimeMonitorAlerts }
].map((item) => (
<button key={item.title} type="button" className="vp-time-monitor-item" onClick={item.onClick} aria-label={`时间监控 ${item.title}`}>
@@ -4472,7 +4472,7 @@ export function Dashboard({
<Button size="small" theme="light" aria-label="重点车辆 实时监控" disabled={!focusVehicle.lookupKey} onClick={() => onOpenRealtime({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '' })}></Button>
<Button size="small" theme="light" aria-label="重点车辆 轨迹回放" disabled={!focusVehicle.lookupKey} onClick={() => onOpenHistory({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '' })}></Button>
<Button size="small" theme="light" aria-label="重点车辆 原始记录" disabled={!focusVehicle.lookupKey} onClick={() => onOpenHistory({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '', tab: 'raw', includeFields: 'true' })}></Button>
<Button size="small" theme="light" aria-label="重点车辆 统计查询" disabled={!focusVehicle.lookupKey} onClick={() => onOpenMileage({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '' })}></Button>
<Button size="small" theme="light" aria-label="重点车辆 里程统计" disabled={!focusVehicle.lookupKey} onClick={() => onOpenMileage({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '' })}></Button>
<Button size="small" theme="light" type="warning" aria-label="重点车辆 告警事件" onClick={() => onOpenQuality({ keyword: focusVehicle.lookupKey, protocol: focusVehicle.protocol ?? '', ...(focusVehicle.issueType ? { issueType: focusVehicle.issueType } : {}) })}></Button>
</Space>
</div>

View File

@@ -361,7 +361,7 @@ function historyEvidencePackageText({
`历史位置:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'location' } }))}`,
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: vehicle, protocol }))}`
].join('\n');
}
@@ -398,7 +398,7 @@ function deliveryPackageText({
return [
'【客户查询导出包】',
`交付状态:${deliveryState}`,
'交付物:轨迹报告 / 位置历史 / 统计查询 / 明细证据 / 字段裁剪 / 质量提示',
'交付物:轨迹报告 / 位置历史 / 里程统计 / 明细证据 / 字段裁剪 / 质量提示',
`车辆范围:${vehicle || '全部车辆'}`,
`数据通道:${protocol || '全部数据通道'}`,
`时间范围:${filters.dateFrom?.trim() || '-'}${filters.dateTo?.trim() || '-'}`,
@@ -411,7 +411,7 @@ function deliveryPackageText({
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: vehicle, protocol }))}`
].join('\n');
}
@@ -420,7 +420,7 @@ function deliveryCoverRecommendation(fieldCount: number, validPointCount: number
if (fieldCount > 0 && validPointCount === 0) return '优先导出字段证据,并补查轨迹位置。';
if (validPointCount > 0) return '优先交付轨迹报告和位置历史,再附带字段证据。';
if (rawCount > 0) return '先交付明细证据,并补充客户需要的字段裁剪。';
if (locationCount > 0) return '先交付位置历史,并补充统计查询说明。';
if (locationCount > 0) return '先交付位置历史,并补充里程统计说明。';
return '先锁定车辆和时间窗,再查询位置或明细证据。';
}
@@ -459,7 +459,7 @@ function deliveryCoverText({
'【客户数据交付封面包】',
`交付主题:${vehicle} / ${protocol} / ${rangeFrom}${rangeTo}`,
`交付结论:${deliveryState}`,
'交付物:轨迹报告 / 位置历史 CSV / 明细证据 CSV / 字段裁剪 CSV / 统计查询链接 / 质量提示',
'交付物:轨迹报告 / 位置历史 CSV / 明细证据 CSV / 字段裁剪 CSV / 里程统计链接 / 质量提示',
`当前证据:位置 ${locationCount.toLocaleString()} 条 / 有效坐标 ${validPointCount.toLocaleString()} 点 / 明细 ${rawCount.toLocaleString()} 帧 / 字段 ${fieldCount.toLocaleString()}`,
`质量提示:断点 ${anomalySummary.gapCount.toLocaleString()} / 里程回退 ${anomalySummary.mileageRollbackCount.toLocaleString()} / 超速 ${anomalySummary.overspeedCount.toLocaleString()}`,
`建议动作:${deliveryCoverRecommendation(fieldCount, validPointCount, rawCount, locationCount)}`,
@@ -467,7 +467,7 @@ function deliveryCoverText({
`位置历史:${appURL(buildAppHash({ page: 'history-query', keyword, protocol: protocolFilter, filters: { ...evidenceFilters, tab: 'location' } }))}`,
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword, protocol: protocolFilter, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword, protocol: protocolFilter, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword, protocol: protocolFilter, filters: evidenceFilters }))}`
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword, protocol: protocolFilter, filters: evidenceFilters }))}`
].join('\n');
}
@@ -498,7 +498,7 @@ function scheduledHistoryReportPlanText({
`数据通道:${protocol || '全部数据通道'}`,
`时间范围:${filters.dateFrom?.trim() || '-'}${filters.dateTo?.trim() || '-'}`,
'推荐频率:日报用于客户复盘,周报用于客户对账,临时导出用于问题解释。',
'交付内容:轨迹报告 / 位置历史 CSV / 明细证据 CSV / 字段裁剪 CSV / 统计查询链接 / 质量提示。',
'交付内容:轨迹报告 / 位置历史 CSV / 明细证据 CSV / 字段裁剪 CSV / 里程统计链接 / 质量提示。',
`当前数据量:位置 ${locationCount.toLocaleString()} 条,有效定位 ${validPointCount.toLocaleString()},明细证据 ${rawCount.toLocaleString()} 帧,字段裁剪 ${fieldCount.toLocaleString()} 个。`,
`质量提示:断点 ${anomalySummary.gapCount.toLocaleString()} / 里程回退 ${anomalySummary.mileageRollbackCount.toLocaleString()} / 超速 ${anomalySummary.overspeedCount.toLocaleString()}`,
'交付前检查:先锁定车辆和时间窗,再确认字段裁剪、分页覆盖和异常说明。',
@@ -506,7 +506,7 @@ function scheduledHistoryReportPlanText({
`位置历史:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'location' } }))}`,
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`
].join('\n');
}
@@ -592,7 +592,7 @@ function trajectoryReviewPackageText({
...(filters.dateTo?.trim() ? { dateTo: filters.dateTo.trim() } : {})
};
const anomalyAction = anomalySummary.gapCount > 0 || anomalySummary.mileageRollbackCount > 0 || anomalySummary.overspeedCount > 0
? '建议核对明细证据、字段裁剪、当日统计查询,并确认平台是否存在断链或补发。'
? '建议核对明细证据、字段裁剪、当日里程统计,并确认平台是否存在断链或补发。'
: '当前页未发现明显断点、里程回退或速度异常,可作为轨迹复盘依据使用。';
return [
'【客户轨迹复盘包】',
@@ -615,7 +615,7 @@ function trajectoryReviewPackageText({
`历史位置:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'location' } }))}`,
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: vehicle, protocol }))}`
].join('\n');
}
@@ -737,12 +737,12 @@ function trajectoryCustomerDecisionText({
'1. 先看轨迹覆盖:确认是否有足够有效坐标。',
'2. 再看时间断点:断点会影响定位连续性和客户解释。',
'3. 再看里程速度:区间里程、速度和轨迹方向需要能互相解释。',
'4. 最后回到依据:异常点必须打开明细证据、字段裁剪和统计查询复核。',
'4. 最后回到依据:异常点必须打开明细证据、字段裁剪和里程统计复核。',
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`历史查询导出:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'location' } }))}`,
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: vehicle, protocol, filters: { ...evidenceFilters, tab: 'fields', includeFields: 'true', ...(filters.fields?.trim() ? { fields: filters.fields.trim() } : {}) } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vehicle, protocol, filters: evidenceFilters }))}`,
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: vehicle, protocol }))}`
].join('\n');
}
@@ -1027,9 +1027,9 @@ export function History({
{
label: '里程速度',
value: formatNumber(mileageDelta, ' km'),
detail: `最高速度 ${formatNumber(maxSpeed, ' km/h')},用于和统计查询互相解释。`,
detail: `最高速度 ${formatNumber(maxSpeed, ' km/h')},用于和里程统计互相解释。`,
color: isFiniteNumber(mileageDelta) ? 'blue' as const : 'grey' as const,
action: '统计查询',
action: '里程统计',
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
},
@@ -1063,11 +1063,11 @@ export function History({
onClick: () => openQueryTab('location')
},
{
title: '统计查询',
title: '里程统计',
value: formatNumber(mileageDelta, ' km'),
detail: '进入统计查询核对区间里程和日统计闭合。',
detail: '进入里程统计核对区间里程和日统计闭合。',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
action: '统计查询',
action: '里程统计',
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
},
@@ -1112,8 +1112,8 @@ export function History({
{
title: '统计核对',
value: formatNumber(mileageDelta, ' km'),
detail: '把同一时间窗带到统计查询,核对区间里程和日报闭合。',
action: '统计查询',
detail: '把同一时间窗带到里程统计,核对区间里程和日报闭合。',
action: '里程统计',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
@@ -1271,7 +1271,7 @@ export function History({
title: '里程对账',
value: formatNumber(mileageDelta, ' km'),
detail: '跳到同一车辆和时间窗的里程统计,核对区间差值和日报闭合。',
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
@@ -1310,7 +1310,7 @@ export function History({
value: formatNumber(mileageDelta, ' km'),
detail: '带着车辆和时间窗进入统计页,核对区间里程。',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
action: '统计查询',
action: '里程统计',
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
},
@@ -1469,7 +1469,7 @@ export function History({
{
title: '周报对账包',
value: '客户对账',
detail: '按固定车辆范围沉淀周报计划,交付轨迹、统计查询链接和异常说明。',
detail: '按固定车辆范围沉淀周报计划,交付轨迹、里程统计链接和异常说明。',
action: '复制周报计划',
color: 'blue' as const,
disabled: false,
@@ -1584,7 +1584,7 @@ export function History({
question: '这段时间跑了多少公里?',
answer: formatNumber(mileageDelta, ' km'),
evidence: `最高速度 ${formatNumber(maxSpeed, ' km/h')}`,
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
disabled: !onOpenMileage,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
@@ -1728,7 +1728,7 @@ export function History({
`明细证据:${appURL(buildAppHash({ page: 'history-query', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`字段裁剪:${appURL(buildAppHash({ page: 'history-query', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: fieldFilters }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: evidenceFilters }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: evidenceFilters }))}`
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol, filters: evidenceFilters }))}`
];
copyText(lines.join('\n'), '客户导出向导包');
};
@@ -1994,7 +1994,7 @@ export function History({
title: '里程核对',
value: formatNumber(mileageDelta, ' km'),
detail: '把同一车辆和时间窗带到统计页,核对区间差值与日报闭合。',
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
disabled: !onOpenMileage || !currentVehicleKeyword,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
@@ -2060,7 +2060,7 @@ export function History({
title: '核对里程',
value: formatNumber(mileageDelta, ' km'),
detail: '跳到同一车辆和时间窗的里程统计,检查区间差值。',
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const,
disabled: !onOpenMileage || !currentVehicleKeyword,
onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })
@@ -2308,7 +2308,7 @@ export function History({
},
{
label: '统计核对',
action: '统计查询',
action: '里程统计',
detail: `区间里程 ${formatNumber(mileageDelta, ' km')}`,
color: isFiniteNumber(mileageDelta) ? 'blue' as const : 'grey' as const,
disabled: !onOpenMileage || !currentVehicleKeyword,
@@ -2827,7 +2827,7 @@ export function History({
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
CSV
CSV
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={() => openQueryTab('location')}></Button>
@@ -3203,7 +3203,7 @@ export function History({
{[
{ title: '轨迹复盘', value: validLocations.length > 0 ? '可播放' : '待查询', detail: '回放路线、速度和里程断点。', action: '播放轨迹', color: validLocations.length > 0 ? 'green' as const : 'orange' as const, disabled: validLocations.length === 0, onClick: () => openQueryTab('location') },
{ title: '明细证据', value: `${(rawFrames.total ?? 0).toLocaleString()}`, detail: '查看轨迹背后的接入证据。', action: '查看证据', color: (rawFrames.total ?? 0) > 0 ? 'blue' as const : 'grey' as const, disabled: false, onClick: () => openQueryTab('raw') },
{ title: '统计查询', value: formatNumber(mileageDelta, ' km'), detail: '进入同一时间窗的统计查询。', action: '统计复核', color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const, disabled: !onOpenMileage, onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) }) },
{ title: '里程统计', value: formatNumber(mileageDelta, ' km'), detail: '进入同一时间窗的里程统计。', action: '里程复核', color: isFiniteNumber(mileageDelta) ? 'green' as const : 'grey' as const, disabled: !onOpenMileage, onClick: () => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) }) },
{ title: '客户导出', value: deliveryState, detail: '复制交付说明或导出 CSV 证据。', action: '复制交付', color: deliveryStateColor, disabled: false, onClick: copyDeliveryPackage }
].map((item) => (
<button key={item.title} type="button" className="vp-trip-action" disabled={item.disabled} onClick={item.onClick} aria-label={`轨迹回放工作台 ${item.title} ${item.action}`}>
@@ -3228,7 +3228,7 @@ export function History({
<Tag color={deliveryStateColor}>{deliveryState}</Tag>
<Tag color={amapConfigured ? 'green' : 'orange'}>{amapConfigured ? '高德地图可用' : '坐标预览'}</Tag>
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
@@ -3236,7 +3236,7 @@ export function History({
<Button size="small" theme="solid" type="primary" icon={<IconCopy />} onClick={copyTrajectoryDecision}></Button>
<Button size="small" disabled={validLocations.length === 0} onClick={() => openQueryTab('location')}></Button>
<Button size="small" disabled={(rawFrames.total ?? 0) === 0} onClick={() => openQueryTab('raw')}></Button>
<Button size="small" disabled={!onOpenMileage} onClick={() => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })}></Button>
<Button size="small" disabled={!onOpenMileage} onClick={() => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })}></Button>
</Space>
</div>
<div className="vp-trajectory-decision-grid">
@@ -3347,7 +3347,7 @@ export function History({
</Button>
<Button size="small" disabled={!onOpenMileage} onClick={() => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })}>
</Button>
</Space>
</div>
@@ -3562,12 +3562,12 @@ export function History({
</Space>
<Typography.Text strong>{currentVehicleKeyword || '全部车辆'}</Typography.Text>
<Typography.Text type="secondary">
</Typography.Text>
<Space wrap>
<Button size="small" icon={<IconCopy />} onClick={copyTrajectoryImpactPackage}></Button>
<Button size="small" disabled={!currentVehicleKeyword} onClick={() => onOpenVehicle(currentVehicleKeyword, currentProtocol)}></Button>
<Button size="small" disabled={!onOpenMileage} onClick={() => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })}></Button>
<Button size="small" disabled={!onOpenMileage} onClick={() => onOpenMileage?.({ keyword: currentVehicleKeyword, protocol: currentProtocol, ...(filters.dateFrom ? { dateFrom: filters.dateFrom } : {}), ...(filters.dateTo ? { dateTo: filters.dateTo } : {}) })}></Button>
</Space>
</div>
<div className="vp-trajectory-impact-grid">
@@ -3801,9 +3801,9 @@ export function History({
))}
</div>
<div className="vp-trajectory-anomaly-action">
<Tag color={hasTrajectoryAnomaly ? 'orange' : 'green'}>{hasTrajectoryAnomaly ? '建议核对明细证据和当日统计查询' : '轨迹质量可用'}</Tag>
<Tag color={hasTrajectoryAnomaly ? 'orange' : 'green'}>{hasTrajectoryAnomaly ? '建议核对明细证据和当日里程统计' : '轨迹质量可用'}</Tag>
<Typography.Text type="secondary">
{hasTrajectoryAnomaly ? '异常点会影响轨迹回放、定位复盘和区间里程判断,请结合字段裁剪与统计查询交叉确认。' : '当前页轨迹未发现明显断点、里程回退或速度异常。'}
{hasTrajectoryAnomaly ? '异常点会影响轨迹回放、定位复盘和区间里程判断,请结合字段裁剪与里程统计交叉确认。' : '当前页轨迹未发现明显断点、里程回退或速度异常。'}
</Typography.Text>
</div>
</Card>
@@ -3849,7 +3849,7 @@ export function History({
render: (_: unknown, row: HistoryLocationRow) => (
<Space wrap>
<Button disabled={!canOpenVehicle(row.vin)} onClick={() => onOpenVehicle(row.vin, row.protocol)}></Button>
<Button disabled={!canOpenVehicle(row.vin) || !onOpenMileage} onClick={() => openLocationMileage(row)}></Button>
<Button disabled={!canOpenVehicle(row.vin) || !onOpenMileage} onClick={() => openLocationMileage(row)}></Button>
<Button disabled={!canOpenVehicle(row.vin) || !onOpenRaw} onClick={() => openLocationRaw(row)}></Button>
</Space>
)
@@ -3894,7 +3894,7 @@ export function History({
render: (_: unknown, row: RawFrameRow) => (
<Space wrap>
<Button onClick={() => setSelectedRaw(row)}></Button>
<Button disabled={!canOpenVehicle(row.vin) || !onOpenMileage} onClick={() => openRawMileage(row)}></Button>
<Button disabled={!canOpenVehicle(row.vin) || !onOpenMileage} onClick={() => openRawMileage(row)}></Button>
<Button disabled={!canOpenVehicle(row.vin)} onClick={() => onOpenVehicle(row.vin, row.protocol)}></Button>
</Space>
)

View File

@@ -188,8 +188,8 @@ function mileageSummaryText({
`当前页里程:${formatKm(pageMileageTotal)} km`,
`异常记录:${anomalyCount.toLocaleString()}`,
`最大单日:${peak}`,
'统计口径:区间总值等于各日里程之和',
`统计查询${statisticsURL}`,
'里程口径:区间总值等于各日里程之和',
`里程统计:${statisticsURL}`,
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
].join('\n');
}
@@ -249,7 +249,7 @@ function mileageDeliveryPackageText({
`在线影响:${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
`发布判断:${publishAuditConclusion}`,
`可信度:${confidenceStatus}`,
'统计口径:日里程按首末总里程差值计算,区间总值应等于每日里程之和',
'里程口径:日里程按首末总里程差值计算,区间总值应等于每日里程之和',
`里程统计:${statisticsURL}`,
`轨迹复核:${appURL(buildAppHash({ page: 'history', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}) } }))}`,
`历史明细:${appURL(buildAppHash({ page: 'history-query', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
@@ -368,7 +368,7 @@ function mileageReconciliationControlText({
`覆盖率:${formatPercent(pageCoverageRate)}`,
`在线影响:${onlineSummary.onlineVehicleCount.toLocaleString()} 在线 / ${onlineSummary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(onlineSummary.onlineRatePercent)}`,
`轨迹证明:${peak}`,
`统计查询${statisticsURL}`,
`里程统计:${statisticsURL}`,
`报表导出:${statisticsURL}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}) } }))}`,
`历史明细:${appURL(buildAppHash({ page: 'history-query', keyword: filters.keyword?.trim() || '', protocol: filters.protocol?.trim() || '', filters: { ...(dateFrom ? { dateFrom } : {}), ...(dateTo ? { dateTo } : {}), tab: 'raw', includeFields: 'true' } }))}`,
@@ -413,7 +413,7 @@ function mileageBIPublishText({
`车辆范围:${keyword}`,
`数据通道:${protocol}`,
`日期范围:${dateRange}`,
`统计口径:日里程按首末总里程差值计算,区间总值等于每日里程之和`,
`里程口径:日里程按首末总里程差值计算,区间总值等于每日里程之和`,
`累计里程:${formatKm(summary.totalMileageKm)} km`,
`明细合计:${formatKm(pageMileageTotal)} km`,
`闭合状态:${closureStatus}${closureDeltaKm == null ? '' : `,差值 ${formatKm(Math.abs(closureDeltaKm))} km`}`,
@@ -422,7 +422,7 @@ function mileageBIPublishText({
`通道一致性:${sourceConsistencyText}`,
`统计车辆:${summary.vehicleCount.toLocaleString()},记录:${summary.recordCount.toLocaleString()},来源:${summary.sourceCount.toLocaleString()}`,
`发布风险:${publishable ? '当前筛选范围闭合且无异常记录' : '存在分页未全量、异常记录或闭合差值,需要先复核轨迹和历史明细'}`,
`统计查询${statisticsURL}`,
`里程统计:${statisticsURL}`,
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
].join('\n');
}
@@ -470,7 +470,7 @@ function statisticsImpactText({
`异常记录:${anomalyCount.toLocaleString()}`,
`当前页覆盖:${formatPercent(pageCoverageRate)}`,
`业务影响:${publishAuditConclusion === '可发布' ? '当前统计范围可进入运营和BI口径' : '当前统计范围需要先复核轨迹、历史明细和离线车辆影响'}`,
`统计查询${statisticsURL}`,
`里程统计:${statisticsURL}`,
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
].join('\n');
}
@@ -528,7 +528,7 @@ function mileagePublishAuditReport({
` 动作:${item.action}`
].join('\n')),
'',
`统计查询${statisticsURL}`,
`里程统计:${statisticsURL}`,
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
].join('\n');
}
@@ -554,7 +554,7 @@ function mileageEvidencePackageText(row: DailyMileageRow) {
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: row.vin, protocol: row.source }))}`,
`轨迹证据:${appURL(buildAppHash({ page: 'history', keyword: row.vin, protocol: row.source, filters: evidenceFilters }))}`,
`历史明细:${appURL(buildAppHash({ page: 'history-query', keyword: row.vin, protocol: row.source, filters: { ...evidenceFilters, tab: 'raw', includeFields: 'true' } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: row.vin, protocol: row.source, filters: evidenceFilters }))}`
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: row.vin, protocol: row.source, filters: evidenceFilters }))}`
].join('\n');
}
@@ -642,7 +642,7 @@ function onlineOperationsReportText({
'1. 在线率下降时先检查实时在线状态、数据接入和最后上报时间',
'2. 离线车辆优先打开车辆服务,核对实时、轨迹、历史明细和告警记录',
'3. 统计发布前确认离线车辆是否影响当日里程和区间闭合',
`统计查询${statisticsURL}`,
`里程统计:${statisticsURL}`,
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
].join('\n');
}
@@ -1074,7 +1074,7 @@ export function Mileage({
step: '05',
title: '明细导出',
value: `${rows.length.toLocaleString()} 当前页`,
detail: '导出明细并附带统计口径,支撑 BI 核对、客户复盘和报表交付。',
detail: '导出明细并附带里程口径,支撑 BI 核对、客户复盘和报表交付。',
action: '导出明细',
color: rows.length > 0 ? 'blue' as const : 'grey' as const,
disabled: rows.length === 0,
@@ -1133,7 +1133,7 @@ export function Mileage({
];
const mileageDeliveryNavigation = [
{
title: '确认统计口径',
title: '确认里程口径',
value: `${formatKm(summary.totalMileageKm)} km`,
detail: `范围 ${mileageRangeText},闭合状态 ${closureStatus},发布判断 ${publishAuditConclusion}`,
action: '复制统计摘要',
@@ -1914,7 +1914,7 @@ export function Mileage({
return (
<div className="vp-page">
<PageHeader
title="统计查询"
title="里程统计"
description="按车辆查询里程、在线影响、区间闭合、异常复核和数据交付"
actions={(
<Button disabled={!currentVehicleKeyword} onClick={() => onOpenVehicle(currentVehicleKeyword, currentProtocol)}>
@@ -2206,18 +2206,18 @@ export function Mileage({
<div className="vp-scope-bar">
<span className="vp-scope-label">{currentVehicleKeyword || '-'}</span>
<Tag color={currentProtocol ? 'blue' : 'green'}>{currentProtocol || '全部数据通道'}</Tag>
<Typography.Text type="tertiary">线</Typography.Text>
<Typography.Text type="tertiary">线</Typography.Text>
</div>
<Card bordered className="vp-mileage-customer-query-board" bodyStyle={{ padding: 0 }}>
<div className="vp-mileage-customer-query-summary">
<Space wrap>
<Tag color="blue"></Tag>
<Tag color="blue"></Tag>
<Tag color={mileageDeliveryColor}>{mileageDeliveryState}</Tag>
<Tag color={closureStatusColor}>{closureStatus}</Tag>
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={copyStatisticsSummary}></Button>
@@ -2234,7 +2234,7 @@ export function Mileage({
className="vp-mileage-customer-query-step"
disabled={item.disabled}
onClick={item.onClick}
aria-label={`客户统计查询 ${item.title} ${item.action}`}
aria-label={`客户里程统计 ${item.title} ${item.action}`}
>
<span>{item.step}</span>
<Tag color={item.color}>{item.title}</Tag>
@@ -2543,7 +2543,7 @@ export function Mileage({
<Tag color={statisticsImpactColor}>{statisticsImpactLevel}</Tag>
<div className="vp-monitor-metric-value">{summary.vehicleCount.toLocaleString()} </div>
<Typography.Text type="secondary">
{summary.recordCount.toLocaleString()} {formatKm(summary.totalMileageKm)} km {offlineVehicleCount.toLocaleString()} 线
{summary.recordCount.toLocaleString()} {formatKm(summary.totalMileageKm)} km {offlineVehicleCount.toLocaleString()} 线
</Typography.Text>
<Space wrap>
<Tag color={confidenceColor}>{confidenceStatus}</Tag>
@@ -2711,7 +2711,7 @@ export function Mileage({
)}
</div>
<div className="vp-mileage-side-card">
<div className="vp-mileage-side-title"></div>
<div className="vp-mileage-side-title"></div>
<Typography.Text type="secondary">
</Typography.Text>
@@ -2813,7 +2813,7 @@ export function Mileage({
<div className="vp-stat-closure-action">
<Tag color={closureStatusColor}>{closureStatus}</Tag>
<Typography.Text type="secondary">
{closurePassed && anomalyRows.length === 0 ? '当前统计口径可直接用于 BI 里程口径;若存在跨通道差异,再进入车辆服务查看统计依据。' : '统计进入 BI 前需要结合异常记录、轨迹回放和历史明细完成复核。'}
{closurePassed && anomalyRows.length === 0 ? '当前里程口径可直接用于 BI 里程口径;若存在跨通道差异,再进入车辆服务查看统计依据。' : '统计进入 BI 前需要结合异常记录、轨迹回放和历史明细完成复核。'}
</Typography.Text>
<Space wrap>
<Button size="small" onClick={copyStatisticsSummary}></Button>
@@ -3003,7 +3003,7 @@ export function Mileage({
]}
/>
</Card>
<Card bordered title="统计口径" style={{ marginTop: 16 }}>
<Card bordered title="里程口径" style={{ marginTop: 16 }}>
<div className="vp-table-toolbar">
<Space wrap>
<Tag color="blue"></Tag>

View File

@@ -422,7 +422,7 @@ function realtimeDutyHandoffText({
` 车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: row.vin, protocol }))}`,
` 实时监控:${appURL(buildAppHash({ page: 'realtime', keyword: row.vin, protocol }))}`,
` 轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: row.vin, protocol }))}`,
` 统计查询${appURL(buildAppHash({ page: 'mileage', keyword: row.vin, protocol }))}`,
` 里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: row.vin, protocol }))}`,
` 历史查询:${protocol ? rawFrameAPIURL(row, protocol) : '-'}`
);
});
@@ -507,7 +507,7 @@ function mapCustomerPackageText({
`实时地图:${appURL(buildAppHash({ page: 'map', protocol: filters.protocol, filters }))}`,
selectedVIN ? `车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `统计查询${appURL(buildAppHash({ page: 'mileage', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `历史数据:${appURL(buildAppHash({ page: 'history-query', keyword: selectedVIN, protocol: selectedProtocol, filters: { tab: 'raw', includeFields: 'true' } }))}` : '',
selectedVIN ? `告警通知:${appURL(buildAppHash({ page: 'alert-events', keyword: selectedVIN, protocol: selectedProtocol }))}` : ''
].filter(Boolean).join('\n');
@@ -547,7 +547,7 @@ function mapExecutiveControlPackageText({
`实时地图:${appURL(buildAppHash({ page: 'map', protocol: filters.protocol, filters: { ...filters, online: filters.online || 'online' } }))}`,
selectedVIN ? `轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
`围栏告警:${appURL(buildAppHash({ page: 'alert-events', filters: { serviceStatus: 'degraded', ...(filters.protocol ? { protocol: filters.protocol } : {}) } }))}`,
selectedVIN ? `统计查询${appURL(buildAppHash({ page: 'mileage', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: selectedVIN, protocol: selectedProtocol }))}` : '',
selectedVIN ? `历史导出:${appURL(buildAppHash({ page: 'history-query', keyword: selectedVIN, protocol: selectedProtocol, filters: { tab: 'raw', includeFields: 'true' } }))}` : ''
].filter(Boolean).join('\n');
}
@@ -569,7 +569,7 @@ function selectedMapVehicleHandoffText(row: VehicleRealtimeRow, protocol: string
`车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: vin, protocol }))}`,
`实时地图:${appURL(buildAppHash({ page: 'map', keyword: vin, protocol }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: vin, protocol }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', keyword: vin, protocol }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: vin, protocol }))}`,
`历史数据:${appURL(buildAppHash({ page: 'history-query', keyword: vin, protocol, filters: { tab: 'raw', includeFields: 'true' } }))}`,
`告警通知:${appURL(buildAppHash({ page: 'alert-events', keyword: vin, protocol }))}`
].join('\n');
@@ -871,7 +871,7 @@ export function Realtime({
`实时状态:${timeWindowRow ? `${vehicleServiceStatus(timeWindowRow).label} / ${dataFreshness(timeWindowRow).detail}` : '未选车辆'}`,
`轨迹回放:${timeWindowReady ? window.location.origin + window.location.pathname + buildAppHash({ page: 'history', keyword: timeWindowKeyword, protocol: timeWindowProtocol, filters: timeWindowFilters() }) : '-'}`,
`历史数据:${timeWindowReady ? window.location.origin + window.location.pathname + buildAppHash({ page: 'history-query', keyword: timeWindowKeyword, protocol: timeWindowProtocol, filters: timeWindowFilters({ tab: 'raw', includeFields: 'true' }) }) : '-'}`,
`统计查询${timeWindowReady ? window.location.origin + window.location.pathname + buildAppHash({ page: 'mileage', keyword: timeWindowKeyword, protocol: timeWindowProtocol, filters: timeWindowFilters() }) : '-'}`,
`里程统计:${timeWindowReady ? window.location.origin + window.location.pathname + buildAppHash({ page: 'mileage', keyword: timeWindowKeyword, protocol: timeWindowProtocol, filters: timeWindowFilters() }) : '-'}`,
`告警通知:${timeWindowReady ? window.location.origin + window.location.pathname + buildAppHash({ page: 'alert-events', keyword: timeWindowKeyword, protocol: timeWindowProtocol, filters: timeWindowFilters() }) : '-'}`
].join('\n'), '客户时间窗复盘包');
const timeWindowWorkItems = [
@@ -894,7 +894,7 @@ export function Realtime({
onClick: openTimeWindowRaw
},
{
title: '统计查询',
title: '里程统计',
value: timeWindowRow?.totalMileageKm != null ? `${timeWindowRow.totalMileageKm} km` : '待核对',
detail: '核对区间里程、日里程和总里程差值。',
action: '查看统计',
@@ -942,7 +942,7 @@ export function Realtime({
title: '里程核对',
value: timeWindowRow?.totalMileageKm != null ? `${timeWindowRow.totalMileageKm} km` : '待核对',
detail: '用同一时间窗进入里程统计,核对区间差值和日统计闭合。',
action: '统计查询',
action: '里程统计',
color: timeWindowRow?.totalMileageKm != null ? 'blue' as const : 'orange' as const,
disabled: !timeWindowReady,
onClick: openTimeWindowMileage
@@ -1192,10 +1192,10 @@ export function Realtime({
onClick: () => selectedMapRow && onOpenHistory?.(selectedMapRow.vin, selectedVehicleProtocol)
},
{
title: '统计查询',
title: '里程统计',
value: selectedMapRow?.totalMileageKm != null ? `${selectedMapRow.totalMileageKm} km` : '无里程',
detail: '进入单车统计查询,核对日里程和区间差值。',
action: '统计查询',
detail: '进入单车里程统计,核对日里程和区间差值。',
action: '里程统计',
color: selectedMapRow?.totalMileageKm != null ? 'blue' as const : 'orange' as const,
disabled: !selectedMapRow || !canOpenVehicle(selectedMapRow.vin),
onClick: () => {
@@ -1299,10 +1299,10 @@ export function Realtime({
onClick: () => selectedMapRow && onOpenHistory?.(selectedMapRow.vin, selectedVehicleProtocol)
},
{
title: '统计查询',
title: '里程统计',
value: selectedMapRow?.totalMileageKm != null ? `${selectedMapRow.totalMileageKm} km` : '待选车',
detail: '按选中车辆进入统计查询,核对区间里程和日报闭合。',
action: '统计查询',
detail: '按选中车辆进入里程统计,核对区间里程和日报闭合。',
action: '里程统计',
color: selectedMapRow?.totalMileageKm != null ? 'blue' as const : 'grey' as const,
disabled: !selectedMapRow || !canOpenVehicle(selectedMapRow.vin),
onClick: () => {
@@ -1612,7 +1612,7 @@ export function Realtime({
{
label: '选车复盘',
value: selectedVehicleLabel,
detail: selectedMapRow ? `${vehicleServiceStatus(selectedMapRow).label}${dataFreshness(selectedMapRow).detail}` : '从地图或车辆列表选择一辆车后进入轨迹、统计查询和历史查询。',
detail: selectedMapRow ? `${vehicleServiceStatus(selectedMapRow).label}${dataFreshness(selectedMapRow).detail}` : '从地图或车辆列表选择一辆车后进入轨迹、里程统计和历史查询。',
color: selectedMapRow ? vehicleServiceStatus(selectedMapRow).color : 'grey' as const,
action: '轨迹回放',
disabled: !selectedMapRow || !canOpenVehicle(selectedMapRow.vin),
@@ -1982,7 +1982,7 @@ export function Realtime({
step: '04',
title: '单车复盘',
value: selectedMapRow?.plate || selectedMapRow?.vin || '未选车',
detail: selectedMapRow ? '围绕选中车辆回放轨迹、统计查询和告警。' : '先在地图或表格中选择一辆可查询车辆。',
detail: selectedMapRow ? '围绕选中车辆回放轨迹、里程统计和告警。' : '先在地图或表格中选择一辆可查询车辆。',
action: '轨迹回放',
color: selectedMapRow ? 'blue' as const : 'grey' as const,
onClick: () => selectedMapRow && onOpenHistory?.(selectedMapRow.vin, selectedVehicleProtocol),
@@ -2145,7 +2145,7 @@ export function Realtime({
onClick: () => selectedMapRow && onOpenHistory?.(selectedMapRow.vin, selectedVehicleProtocol)
},
{
label: '统计查询',
label: '里程统计',
value: selectedMapRow?.totalMileageKm != null ? `${selectedMapRow.totalMileageKm} km` : '无里程',
detail: '核对单车总里程、日里程和区间闭合。',
color: selectedMapRow?.totalMileageKm != null ? 'blue' as const : 'grey' as const,
@@ -2191,7 +2191,7 @@ export function Realtime({
level: selectedMapRow ? '单车' : '选车',
title: selectedMapRow ? '复盘选中车辆' : '先选择一辆车',
value: selectedMapRow?.plate || selectedMapRow?.vin || '等待选车',
detail: selectedMapRow ? `${vehicleServiceStatus(selectedMapRow).label}${dataFreshness(selectedMapRow).detail}` : '从地图或实时列表选择车辆后,进入轨迹、统计查询、历史和告警。',
detail: selectedMapRow ? `${vehicleServiceStatus(selectedMapRow).label}${dataFreshness(selectedMapRow).detail}` : '从地图或实时列表选择车辆后,进入轨迹、里程统计、历史和告警。',
action: selectedMapRow ? '轨迹回放' : '查看车辆',
color: selectedMapRow ? vehicleServiceStatus(selectedMapRow).color : 'blue' as const,
disabled: selectedMapRow ? !canOpenVehicle(selectedMapRow.vin) : false,
@@ -2301,7 +2301,7 @@ export function Realtime({
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" disabled={!timeWindowReady} onClick={openTimeWindowHistory}></Button>
@@ -2462,7 +2462,7 @@ export function Realtime({
<div className="vp-map-command-side-card">
<Typography.Text strong></Typography.Text>
<Typography.Text type="secondary">
</Typography.Text>
</div>
</aside>
@@ -2713,7 +2713,7 @@ export function Realtime({
<Tag color={amapConfigured ? 'green' : 'orange'}>{amapConfigured ? 'Live Map 可用' : '坐标预览'}</Tag>
<Tag color={mapAttentionRows.length > 0 ? 'orange' : 'green'}>{mapAttentionRows.length.toLocaleString()} </Tag>
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}> Live Map 线线</Typography.Title>
<Typography.Title heading={5} style={{ margin: 0 }}> Live Map 线线</Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
@@ -2963,7 +2963,7 @@ export function Realtime({
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}>{selectedVehicleLabel}</Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
</div>
<div className="vp-map-selected-service-actions">
@@ -3051,7 +3051,7 @@ export function Realtime({
</Space>
<Typography.Text strong>{selectedVehicleLabel}</Typography.Text>
<Typography.Text type="secondary">
线
线
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" icon={<IconCopy />} onClick={copyMapCustomerPackage}></Button>
@@ -3340,7 +3340,7 @@ export function Realtime({
</Space>
<Typography.Title heading={5} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary">
线
线
</Typography.Text>
<Space wrap>
<Button size="small" theme="solid" type="primary" onClick={() => applyFilters({ ...filters, online: 'online' })}>线</Button>

View File

@@ -85,7 +85,7 @@ function sourceFusionRow(source: VehicleSourceStatus, realtime: RealtimeLocation
hasLocation ? '定位数据' : '',
source.hasHistory ? '轨迹回放' : '',
source.hasRaw ? '历史数据' : '',
hasMileage ? '统计口径' : ''
hasMileage ? '里程口径' : ''
].filter(Boolean);
return {
source,
@@ -462,10 +462,10 @@ export function VehicleDetail({
`最新上报:${lastSeen}`,
`轨迹证据:${overview?.historyCount ?? detail.history.total ?? 0}`,
`历史数据:${overview?.rawCount ?? detail.raw.total ?? 0}`,
`统计查询${overview?.mileageCount ?? detail.mileage.total ?? 0}`,
`里程统计:${overview?.mileageCount ?? detail.mileage.total ?? 0}`,
`告警事件:${qualityCount.toLocaleString()}`,
`轨迹回放:${vehicleServiceURL(buildAppHash({ page: 'history', keyword: filters.keyword, protocol: filters.protocol, filters }))}`,
`统计查询${vehicleServiceURL(buildAppHash({ page: 'mileage', keyword: filters.keyword, protocol: filters.protocol, filters }))}`,
`里程统计:${vehicleServiceURL(buildAppHash({ page: 'mileage', keyword: filters.keyword, protocol: filters.protocol, filters }))}`,
`历史导出:${vehicleServiceURL(buildAppHash({ page: 'history-query', keyword: rawFilters.keyword, protocol: rawFilters.protocol, filters: rawFilters }))}`,
`告警通知:${vehicleServiceURL(buildAppHash({ page: 'alert-events', keyword: filters.keyword, protocol: filters.protocol, filters }))}`
];
@@ -500,7 +500,7 @@ export function VehicleDetail({
`实时:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '诊断摘要');
};
@@ -532,7 +532,7 @@ export function VehicleDetail({
`实时监控:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '数据通道归并矩阵');
};
@@ -681,7 +681,7 @@ export function VehicleDetail({
`实时监控:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '统一车辆服务摘要');
};
@@ -708,7 +708,7 @@ export function VehicleDetail({
`实时监控:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '车辆服务档案');
};
@@ -736,7 +736,7 @@ export function VehicleDetail({
`实时监控:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '车辆服务摘要');
};
@@ -786,11 +786,11 @@ export function VehicleDetail({
]
},
{
title: '统计复核',
title: '里程复核',
value: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)} 条统计`,
meta: formatCompactNumber(evidenceMileageDelta, ' km 差异'),
color: isFiniteNumber(evidenceMileageDelta) && Math.abs(evidenceMileageDelta) > 1 ? 'orange' as const : 'green' as const,
detail: '核对统计口径,确认区间总值、每日里程与数据通道是否闭合。',
detail: '核对里程口径,确认区间总值、每日里程与数据通道是否闭合。',
disabled: !hasResolvedVIN,
actions: [
{ label: '查看统计', onClick: () => onOpenMileage(resolvedVIN, activeProtocol) }
@@ -819,8 +819,8 @@ export function VehicleDetail({
{
title: '核对里程',
value: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)}`,
detail: '进入统计查询,核对区间里程、日里程和统计闭合。',
action: '统计查询',
detail: '进入里程统计,核对区间里程、日里程和统计闭合。',
action: '里程统计',
color: (overview?.mileageCount ?? detail?.mileage?.total ?? 0) > 0 ? 'green' as const : 'grey' as const,
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
@@ -878,10 +878,10 @@ export function VehicleDetail({
onClick: () => onOpenQuality?.(qualityFiltersForCurrentVehicle())
},
{
title: '复核统计口径',
title: '复核里程口径',
evidence: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)} 条统计,证据里程差 ${formatCompactNumber(evidenceMileageDelta, ' km')}`,
acceptance: '区间里程、每日里程和轨迹总里程可以互相解释。',
action: '统计查询',
action: '里程统计',
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
}
@@ -907,7 +907,7 @@ export function VehicleDetail({
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`告警事件:${vehicleServiceURL(buildAppHash({ page: 'alert-events', keyword: resolvedVIN, protocol: activeProtocol }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`,
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`,
`车辆服务:${vehicleServiceURL(vehicleServiceHash('detail'))}`
];
copyText(lines.join('\n'), '单车处理清单');
@@ -947,11 +947,11 @@ export function VehicleDetail({
onSecondary: () => exportVehicleReport()
},
{
title: '复核统计查询',
title: '复核里程统计',
value: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)} 条统计`,
detail: `证据里程差 ${formatCompactNumber(evidenceMileageDelta, ' km')},确认区间和日统计能闭合。`,
color: isFiniteNumber(evidenceMileageDelta) && Math.abs(evidenceMileageDelta) > 1 ? 'orange' as const : 'green' as const,
primaryAction: '统计查询',
primaryAction: '里程统计',
secondaryAction: '诊断摘要',
disabled: !hasResolvedVIN,
onPrimary: () => onOpenMileage(resolvedVIN, activeProtocol),
@@ -1007,11 +1007,11 @@ export function VehicleDetail({
onClick: () => onOpenQuality?.(qualityFiltersForCurrentVehicle())
},
{
title: '统计查询',
title: '里程统计',
value: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)}`,
detail: `里程差 ${formatCompactNumber(evidenceMileageDelta, ' km')}`,
color: isFiniteNumber(evidenceMileageDelta) && Math.abs(evidenceMileageDelta) > 1 ? 'orange' as const : 'green' as const,
action: '统计复核',
action: '里程复核',
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
}
@@ -1039,7 +1039,7 @@ export function VehicleDetail({
title: '里程与能源',
value: `${formatCompactNumber(latest?.totalMileageKm, ' km')}`,
detail: `SOC ${formatCompactNumber(latest?.socPercent, '%')} / 速度 ${formatCompactNumber(latest?.speedKmh, ' km/h')}`,
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(latest?.totalMileageKm) ? 'green' as const : 'orange' as const,
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
@@ -1101,10 +1101,10 @@ export function VehicleDetail({
onClick: () => onOpenQuality?.(qualityFiltersForCurrentVehicle())
},
{
title: '统计口径',
title: '里程口径',
value: `${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)}`,
detail: `证据里程差 ${formatCompactNumber(evidenceMileageDelta, ' km')}`,
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(evidenceMileageDelta) && Math.abs(evidenceMileageDelta) > 1 ? 'orange' as const : 'green' as const,
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
@@ -1138,7 +1138,7 @@ export function VehicleDetail({
{
question: '这辆车跑了多少?',
answer: `${formatCompactNumber(latest?.totalMileageKm, ' km')} / ${formatCompactNumber(overview?.mileageCount ?? detail?.mileage?.total ?? 0)} 条统计`,
action: '统计查询',
action: '里程统计',
color: isFiniteNumber(latest?.totalMileageKm) ? 'green' as const : 'orange' as const,
disabled: !hasResolvedVIN,
onClick: () => onOpenMileage(resolvedVIN, activeProtocol)
@@ -1170,21 +1170,21 @@ export function VehicleDetail({
'【单车客户服务交付包】',
`车辆:${vehicleName}`,
`当前范围:${scopeText}`,
`平台能力:实时监控 / 轨迹回放 / 历史数据查询 / 告警通知 / 统计查询`,
`平台能力:实时监控 / 轨迹回放 / 历史数据查询 / 告警通知 / 里程统计`,
`服务状态:${customerStatusTitle(serviceStatus?.title) || serviceConclusion.status}`,
`服务说明:${serviceStatus?.detail ?? serviceConclusion.risk}`,
`在线数据通道:${evidenceSourceCount > 0 ? `${evidenceOnlineSourceCount}/${evidenceSourceCount}` : '-'}`,
`最新上报:${lastSeen}`,
`轨迹证据:${overview?.historyCount ?? detail.history.total ?? 0}`,
`历史数据:${overview?.rawCount ?? detail.raw.total ?? 0}`,
`统计查询${overview?.mileageCount ?? detail.mileage.total ?? 0} 条,证据差异 ${formatCompactNumber(evidenceMileageDelta, ' km')}`,
`里程统计:${overview?.mileageCount ?? detail.mileage.total ?? 0} 条,证据差异 ${formatCompactNumber(evidenceMileageDelta, ' km')}`,
`告警事件:${qualityCount.toLocaleString()}`,
`车辆服务:${vehicleServiceURL(vehicleServiceHash('detail'))}`,
`实时监控:${vehicleServiceURL(vehicleServiceHash('realtime'))}`,
`轨迹回放:${vehicleServiceURL(vehicleServiceHash('history'))}`,
`历史数据查询:${vehicleServiceURL(vehicleServiceHash('history-query', { tab: 'raw', includeFields: 'true' }))}`,
`告警通知:${vehicleServiceURL(buildAppHash({ page: 'alert-events', keyword: resolvedVIN, protocol: activeProtocol }))}`,
`统计查询${vehicleServiceURL(vehicleServiceHash('mileage'))}`
`里程统计:${vehicleServiceURL(vehicleServiceHash('mileage'))}`
];
copyText(lines.join('\n'), '客户服务交付包');
};
@@ -1243,7 +1243,7 @@ export function VehicleDetail({
return (
<div className="vp-page">
<PageHeader title="车辆服务" description="以车辆为主对象查看实时位置、轨迹回放、统计查询、告警通知和历史数据" />
<PageHeader title="车辆服务" description="以车辆为主对象查看实时位置、轨迹回放、里程统计、告警通知和历史数据" />
<Card bordered>
<Form key={formKey} initValues={query} layout="horizontal" onSubmit={(values) => {
const nextQuery = { keyword: String(values.keyword ?? ''), protocol: String(values.protocol ?? '') };
@@ -1267,7 +1267,7 @@ export function VehicleDetail({
<Button disabled={!hasResolvedVIN} onClick={() => onOpenRealtime(resolvedVIN, activeProtocol)}></Button>
<Button disabled={!hasResolvedVIN} onClick={() => onOpenHistory(resolvedVIN, activeProtocol)}></Button>
<Button disabled={!hasResolvedVIN} onClick={() => onOpenRaw(resolvedVIN, activeProtocol)}></Button>
<Button disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
<Button disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
</Space>
</Form>
</Card>
@@ -1302,7 +1302,7 @@ export function VehicleDetail({
{[archivePlate, displayVIN].filter((item) => item && item !== '-').join(' / ') || displayLookupKey}
</Typography.Title>
<Typography.Text type="secondary">
SOC
SOC
</Typography.Text>
<div className="vp-single-vehicle-action-bar" aria-label="客户单车操作台">
<div className="vp-single-vehicle-action-head">
@@ -1413,7 +1413,7 @@ export function VehicleDetail({
<div className="vp-single-vehicle-time-window-actions">
{[
{ title: '轨迹回放', value: vehicleTimeWindowText, detail: '按同一时间窗回放位置、速度和里程断点。', action: '轨迹回放', color: 'blue' as const, onClick: openVehicleWindowHistory },
{ title: '里程统计', value: vehicleTimeWindowText, detail: '核对区间里程、日统计和总里程差值。', action: '统计查询', color: 'green' as const, onClick: openVehicleWindowMileage },
{ title: '里程统计', value: vehicleTimeWindowText, detail: '核对区间里程、日统计和总里程差值。', action: '里程统计', color: 'green' as const, onClick: openVehicleWindowMileage },
{ title: '历史数据导出', value: vehicleTimeWindowText, detail: '导出 RAW 与解析字段证据,缩小复盘范围。', action: '历史导出', color: 'blue' as const, onClick: openVehicleWindowRaw },
{ title: '告警通知', value: vehicleTimeWindowText, detail: '查看这辆车在同一范围内的风险事件。', action: '告警通知', color: qualityCount > 0 ? 'orange' as const : 'green' as const, onClick: openVehicleWindowAlerts }
].map((item) => (
@@ -1510,7 +1510,7 @@ export function VehicleDetail({
<Button size="small" theme="solid" type="primary" disabled={!hasResolvedVIN} onClick={() => onOpenRealtime(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenHistory(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenRaw(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
</div>
</div>
<div className="vp-unified-service-grid">
@@ -1591,14 +1591,14 @@ export function VehicleDetail({
{[archivePlate, displayVIN].filter((item) => item && item !== '-').join(' / ') || displayLookupKey}
</Typography.Title>
<Typography.Text type="secondary">
</Typography.Text>
<div className="vp-customer-service-links">
<Button size="small" theme="solid" type="primary" disabled={!hasResolvedVIN} onClick={() => onOpenRealtime(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenHistory(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenRaw(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!onOpenQuality || (!hasResolvedVIN && qualityCount <= 0)} onClick={() => onOpenQuality?.(qualityFiltersForCurrentVehicle())}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
<Button size="small" theme="light" disabled={!hasResolvedVIN} onClick={() => onOpenMileage(resolvedVIN, activeProtocol)}></Button>
</div>
</div>
<div className="vp-customer-service-grid">

View File

@@ -298,13 +298,13 @@ function vehicleCustomerLookupText({
`在线车辆:${(summary?.onlineVehicles ?? 0).toLocaleString()};待绑定:${(summary?.unboundVehicles ?? 0).toLocaleString()};暂无来源:${(summary?.noDataVehicles ?? 0).toLocaleString()};档案不完整:${(summary?.archiveIncompleteVehicles ?? 0).toLocaleString()}`,
'',
serviceMode === '单车服务'
? '推荐路径:先看车辆档案和实时监控,再按需要进入轨迹回放、统计查询、历史数据导出。'
? '推荐路径:先看车辆档案和实时监控,再按需要进入轨迹回放、里程统计、历史数据导出。'
: '推荐路径:先筛在线/离线/无来源/待绑定车辆,再进入地图态势或导出处置清单。',
`车辆服务:${appURL(scopeHash)}`,
`实时监控:${appURL(buildAppHash({ page: 'realtime', ...singleVehicleFilters }))}`,
`车辆地图:${appURL(buildAppHash({ page: 'map', keyword: filters.keyword, protocol: filters.protocol, filters: mapFilters }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', ...singleVehicleFilters, filters: { tab: 'location' } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', ...singleVehicleFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', ...singleVehicleFilters }))}`,
`历史数据:${appURL(buildAppHash({ page: 'history', ...singleVehicleFilters, filters: { tab: 'raw', includeFields: 'true' } }))}`
];
return lines.join('\n');
@@ -347,13 +347,13 @@ function vehicleCustomerServicePackageText({
`车辆地图:${appURL(buildAppHash({ page: 'map', keyword: filters.keyword, protocol: filters.protocol, filters: mapFilters }))}`,
`实时监控:${appURL(buildAppHash({ page: 'realtime', ...singleVehicleFilters, filters: filters.keyword?.trim() ? undefined : { ...filters, online: filters.online || 'online' } }))}`,
`轨迹回放:${appURL(buildAppHash({ page: 'history', ...singleVehicleFilters, filters: { tab: 'location' } }))}`,
`统计查询${appURL(buildAppHash({ page: 'mileage', ...singleVehicleFilters }))}`,
`里程统计:${appURL(buildAppHash({ page: 'mileage', ...singleVehicleFilters }))}`,
`告警通知:${appURL(buildAppHash({ page: 'alert-events', ...singleVehicleFilters, filters }))}`,
`历史数据导出:${appURL(buildAppHash({ page: 'history', ...singleVehicleFilters, filters: { tab: 'raw', includeFields: 'true' } }))}`,
'',
'交付口径:',
'1. 客户先看地图与实时状态,判断车辆是否在线和位置是否可信',
'2. 单车问题进入轨迹回放和统计查询,确认时间窗内发生了什么',
'2. 单车问题进入轨迹回放和里程统计,确认时间窗内发生了什么',
'3. 异常车辆进入告警通知,带上原始记录和历史数据作为证据',
'4. 对外交付时优先使用车辆口径,协议来源只作为证据说明'
].join('\n');
@@ -697,7 +697,7 @@ export function Vehicles({
onClick: () => onOpenHistory?.({ ...serviceScopeFilters, tab: 'location' })
},
{
label: '统计查询',
label: '里程统计',
value: filters.keyword?.trim() ? '区间核对' : '车辆口径',
detail: filters.keyword?.trim() ? '按当前车辆核对区间里程、日里程和统计结果。' : '输入车辆后查看时间窗统计结果。',
color: filters.keyword?.trim() ? 'green' as const : 'grey' as const,
@@ -819,7 +819,7 @@ export function Vehicles({
{
title: '报表交付',
value: `${rows.length.toLocaleString()} 当前页`,
detail: '导出当前车辆池清单,作为客户报表和后续轨迹统计入口。',
detail: '导出当前车辆池清单,作为客户报表和后续轨迹里程入口。',
action: '导出清单',
color: rows.length > 0 ? 'blue' as const : 'grey' as const,
onClick: exportVehicles
@@ -891,11 +891,11 @@ export function Vehicles({
onClick: () => onOpenHistory?.({ ...serviceScopeFilters, tab: 'location' })
},
{
label: '统计查询',
label: '里程统计',
value: filters.keyword?.trim() ? '区间复核' : '单车后可用',
detail: '核对时间窗里程、日里程和累计口径,支撑 BI 与客户问询。',
color: filters.keyword?.trim() ? 'orange' as const : 'grey' as const,
action: '统计查询',
action: '里程统计',
disabled: !onOpenMileage || !filters.keyword?.trim(),
onClick: () => onOpenMileage?.(serviceScopeFilters)
},
@@ -985,10 +985,10 @@ export function Vehicles({
onClick: () => onOpenHistory?.({ ...serviceScopeFilters, tab: 'location' })
},
{
title: '统计查询',
title: '里程统计',
value: filters.keyword?.trim() ? '区间统计' : '单车后可用',
detail: '按车辆和时间窗核对里程、位置和业务统计口径。',
action: '查询统计',
detail: '按车辆和时间窗核对里程、位置和业务里程口径。',
action: '查询里程',
color: filters.keyword?.trim() ? 'orange' as const : 'grey' as const,
disabled: !onOpenMileage || !filters.keyword?.trim(),
onClick: () => onOpenMileage?.(serviceScopeFilters)
@@ -1199,7 +1199,7 @@ export function Vehicles({
return (
<div className="vp-page">
<PageHeader title="车辆服务" description="围绕车辆完成实时监控、地图查看、轨迹回放、统计查询和数据导出,协议来源只作为证据过滤条件" />
<PageHeader title="车辆服务" description="围绕车辆完成实时监控、地图查看、轨迹回放、里程统计和数据导出,协议来源只作为证据过滤条件" />
<section className="vp-fleet-command-center" aria-label="客户车队指挥台">
<div className="vp-fleet-command-copy">
<Space wrap>
@@ -1236,7 +1236,7 @@ export function Vehicles({
<Tag color="blue"></Tag>
<Tag color={filters.keyword?.trim() ? 'green' : 'grey'}>{filters.keyword?.trim() ? '单车地图' : '车辆池地图'}</Tag>
</Space>
<strong></strong>
<strong></strong>
<span>线</span>
</div>
<div className="vp-vehicle-amap-foundation-grid">
@@ -1506,7 +1506,7 @@ export function Vehicles({
</Space>
<strong>{filters.keyword?.trim() || `${(summary?.totalVehicles ?? pagination.total).toLocaleString()} 辆车`}</strong>
<span>
GB32960808 MQTT
GB32960808 MQTT
</span>
<Space wrap>
<Button size="small" theme="solid" type="primary" icon={<IconCopy />} onClick={copyCustomerServicePackage}></Button>