diff --git a/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx b/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx index 6676c569..3e2bf9a4 100644 --- a/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx +++ b/vehicle-data-platform/apps/web/src/pages/VehicleDetail.tsx @@ -843,6 +843,81 @@ export function VehicleDetail({ onSecondary: () => copyVehicleOperationsSummary() } ]; + const customerServicePackageItems = [ + { + title: '实时监控', + value: online ? '在线' : hasResolvedVIN ? '离线' : '待绑定', + detail: lastSeen === '-' ? '暂无最后上报时间' : `最后上报 ${lastSeen}`, + color: online ? 'green' as const : 'orange' as const, + action: '打开监控', + disabled: !hasResolvedVIN, + onClick: () => onOpenRealtime(resolvedVIN, activeProtocol) + }, + { + title: '轨迹回放', + value: `${formatCompactNumber(overview?.historyCount ?? detail?.history?.total ?? 0)} 条`, + detail: evidenceLocatedSourceCount > 0 ? `${evidenceLocatedSourceCount} 个来源可定位` : '暂无可用定位证据', + color: evidenceLocatedSourceCount > 0 ? 'blue' as const : 'grey' as const, + action: '回放轨迹', + disabled: !hasResolvedVIN, + onClick: () => onOpenHistory(resolvedVIN, activeProtocol) + }, + { + title: '历史数据查询', + value: `${formatCompactNumber(overview?.rawCount ?? detail?.raw?.total ?? 0)} 帧`, + detail: latestRaw?.frameType ? `最新 ${latestRaw.frameType}` : 'RAW 与解析字段证据', + color: (overview?.rawCount ?? detail?.raw?.total ?? 0) > 0 ? 'blue' as const : 'grey' as const, + action: '查询历史', + disabled: !hasResolvedVIN, + onClick: () => onOpenRaw(resolvedVIN, activeProtocol) + }, + { + title: '告警通知', + value: `${qualityCount.toLocaleString()} 项`, + detail: priorityQualityIssue ? `${qualityIssueLabel(priorityQualityIssue.issueType)} / ${priorityQualityIssue.lastSeen || '-'}` : '暂无待通知告警', + color: qualityCount > 0 ? 'orange' as const : 'green' as const, + action: '告警闭环', + disabled: !onOpenQuality || (!hasResolvedVIN && qualityCount <= 0), + onClick: () => onOpenQuality?.(qualityFiltersForCurrentVehicle()) + }, + { + 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: '统计复核', + disabled: !hasResolvedVIN, + onClick: () => onOpenMileage(resolvedVIN, activeProtocol) + } + ]; + const copyCustomerServicePackage = () => { + if (!detail) { + Toast.warning('当前没有可复制的客户服务交付包'); + return; + } + const vehicleName = [archivePlate, displayVIN].filter((item) => item && item !== '-').join(' / ') || displayLookupKey; + const lines = [ + '【单车客户服务交付包】', + `车辆:${vehicleName}`, + `当前范围:${scopeText}`, + `平台能力:实时监控 / 轨迹回放 / 历史数据查询 / 告警通知 / 统计查询`, + `服务状态:${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')}`, + `告警事件:${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'))}` + ]; + copyText(lines.join('\n'), '客户服务交付包'); + }; const qualityTable = (