feat(platform): add fleet service journey strip
This commit is contained in:
@@ -1840,6 +1840,62 @@ export function Realtime({
|
||||
selectedProtocol: selectedVehicleProtocol,
|
||||
amapConfigured
|
||||
}), '客户车辆地图总控包');
|
||||
const copyMapFleetJourneyPackage = () => copyText([
|
||||
'【车队服务旅程交付包】',
|
||||
`当前筛选:${realtimeFilterSummary(filters).join(';') || '全部车辆'}`,
|
||||
`实时找车:${onlineCount.toLocaleString()} 在线 / ${rows.length.toLocaleString()} 当前页 / ${pagination.total.toLocaleString()} 总计`,
|
||||
`轨迹复盘:${selectedMapRow ? `${selectedMapRow.plate || '-'} / ${selectedMapRow.vin || '-'} / ${selectedVehicleProtocol || selectedMapRow.primaryProtocol || '-'}` : '未选择车辆'}`,
|
||||
`里程核对:${selectedMapRow?.totalMileageKm != null ? `${selectedMapRow.totalMileageKm} km` : '待核对'}`,
|
||||
`导出通知:${mapAttentionRows.length.toLocaleString()} 关注 / ${staleCount.toLocaleString()} 更新超时`,
|
||||
`实时地图:${appURL(buildAppHash({ page: 'map', protocol: filters.protocol, filters }))}`,
|
||||
selectedMapRow && canOpenVehicle(selectedMapRow.vin) ? `车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: selectedMapRow.vin, protocol: selectedVehicleProtocol }))}` : '',
|
||||
selectedMapRow && canOpenVehicle(selectedMapRow.vin) ? `轨迹回放:${appURL(buildAppHash({ page: 'history', keyword: selectedMapRow.vin, protocol: selectedVehicleProtocol }))}` : '',
|
||||
selectedMapRow && canOpenVehicle(selectedMapRow.vin) ? `里程统计:${appURL(buildAppHash({ page: 'mileage', keyword: selectedMapRow.vin, protocol: selectedVehicleProtocol }))}` : '',
|
||||
selectedMapRow && canOpenVehicle(selectedMapRow.vin) ? `历史导出:${appURL(buildAppHash({ page: 'history-query', keyword: selectedMapRow.vin, protocol: selectedVehicleProtocol, filters: { tab: 'raw', includeFields: 'true' } }))}` : '',
|
||||
`告警通知:${appURL(buildAppHash({ page: 'alert-events', filters: { serviceStatus: 'degraded', ...(filters.protocol ? { protocol: filters.protocol } : {}) } }))}`
|
||||
].filter(Boolean).join('\n'), '车队服务旅程交付包');
|
||||
const mapFleetJourneyItems = [
|
||||
{
|
||||
step: '1',
|
||||
title: '实时找车',
|
||||
value: `${onlineCount.toLocaleString()} 在线`,
|
||||
detail: `${locatedCount.toLocaleString()} 辆有定位,先让客户知道当前能看到哪些车。`,
|
||||
color: onlineCount > 0 ? 'green' as const : 'orange' as const,
|
||||
disabled: false,
|
||||
onClick: () => applyFilters({ ...filters, online: 'online' })
|
||||
},
|
||||
{
|
||||
step: '2',
|
||||
title: '轨迹复盘',
|
||||
value: selectedVehicleLabel,
|
||||
detail: selectedMapRow ? `${dataFreshness(selectedMapRow).detail},进入轨迹复盘位置、速度和里程断点。` : '先从地图或车辆列表选择一辆车。',
|
||||
color: selectedMapRow ? 'blue' as const : 'grey' as const,
|
||||
disabled: !selectedMapRow || !canOpenVehicle(selectedMapRow.vin),
|
||||
onClick: () => selectedMapRow && onOpenHistory?.(selectedMapRow.vin, selectedVehicleProtocol)
|
||||
},
|
||||
{
|
||||
step: '3',
|
||||
title: '里程核对',
|
||||
value: selectedMapRow?.totalMileageKm != null ? `${selectedMapRow.totalMileageKm} km` : '待核对',
|
||||
detail: '进入同一车辆的里程统计,核对区间差值、日统计和总里程。',
|
||||
color: selectedMapRow?.totalMileageKm != null ? 'blue' as const : 'orange' as const,
|
||||
disabled: !selectedMapRow || !canOpenVehicle(selectedMapRow.vin),
|
||||
onClick: () => selectedMapRow && (window.location.hash = buildAppHash({
|
||||
page: 'mileage',
|
||||
keyword: selectedMapRow.vin,
|
||||
protocol: selectedVehicleProtocol
|
||||
}))
|
||||
},
|
||||
{
|
||||
step: '4',
|
||||
title: '导出通知',
|
||||
value: `${mapAttentionRows.length.toLocaleString()} 关注`,
|
||||
detail: `${staleCount.toLocaleString()} 辆更新超时,交付前进入告警通知或复制交付包。`,
|
||||
color: mapAttentionRows.length > 0 ? 'orange' as const : 'green' as const,
|
||||
disabled: false,
|
||||
onClick: () => mapAttentionRows.length > 0 && onOpenQuality ? onOpenQuality({ serviceStatus: 'degraded', protocol: filters.protocol }) : copyMapFleetJourneyPackage()
|
||||
}
|
||||
];
|
||||
const copyMapCustomerDecision = () => copyText(mapCustomerDecisionText({
|
||||
filters,
|
||||
rows,
|
||||
@@ -2412,6 +2468,46 @@ export function Realtime({
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
<section className="vp-map-fleet-journey" aria-label="车队服务旅程条">
|
||||
<div className="vp-map-fleet-journey-copy">
|
||||
<Space wrap>
|
||||
<Tag color="blue">车队服务旅程条</Tag>
|
||||
<Tag color={mapAttentionRows.length > 0 ? 'orange' : 'green'}>
|
||||
{mapAttentionRows.length > 0 ? `${mapAttentionRows.length.toLocaleString()} 关注` : '态势稳定'}
|
||||
</Tag>
|
||||
<Tag color={selectedMapRow ? vehicleServiceStatus(selectedMapRow).color : 'grey'}>
|
||||
{selectedMapRow ? selectedVehicleLabel : '未选车'}
|
||||
</Tag>
|
||||
</Space>
|
||||
<Typography.Title heading={5} style={{ margin: 0 }}>
|
||||
把客户常用的四件事固定成一条路径:实时找车、轨迹复盘、里程核对、导出通知。
|
||||
</Typography.Title>
|
||||
<Typography.Text type="secondary">
|
||||
客户不需要理解 32960、808、MQTT 的协议差异,只要沿着这条路径完成看车、复盘、核对和交付。
|
||||
</Typography.Text>
|
||||
<Button size="small" theme="solid" type="primary" icon={<IconCopy />} onClick={copyMapFleetJourneyPackage}>
|
||||
复制旅程交付包
|
||||
</Button>
|
||||
</div>
|
||||
<div className="vp-map-fleet-journey-steps">
|
||||
{mapFleetJourneyItems.map((item) => (
|
||||
<button
|
||||
key={item.step}
|
||||
type="button"
|
||||
className="vp-map-fleet-journey-step"
|
||||
disabled={item.disabled}
|
||||
onClick={item.onClick}
|
||||
aria-label={`车队服务旅程条 ${item.step} ${item.title} ${item.value}`}
|
||||
>
|
||||
<Tag color={item.color}>{item.step}</Tag>
|
||||
<strong>{item.title}</strong>
|
||||
<span>{item.value}</span>
|
||||
<small>{item.detail}</small>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="vp-map-service-rail" aria-label="客户车辆地图总控">
|
||||
<div className="vp-map-service-rail-summary">
|
||||
<Space wrap>
|
||||
|
||||
Reference in New Issue
Block a user