feat(platform): add time window service audit

This commit is contained in:
lingniu
2026-07-05 03:13:08 +08:00
parent 9d41c52cac
commit 1de268942c
3 changed files with 122 additions and 0 deletions

View File

@@ -125,6 +125,16 @@ function previousDateString(value: string) {
return `${year}-${month}-${day}`;
}
function dayRangeText(dateFrom?: string, dateTo?: string) {
if (!dateFrom && !dateTo) return '未限定时间';
if (!dateFrom || !dateTo) return '单边时间窗';
const start = new Date(`${dateFrom}T00:00:00+08:00`).getTime();
const end = new Date(`${dateTo}T00:00:00+08:00`).getTime();
if (!Number.isFinite(start) || !Number.isFinite(end)) return '时间格式待确认';
const days = Math.max(0, Math.round((end - start) / 86400000));
return days <= 0 ? '同日或倒置时间窗' : `${days} 天窗口`;
}
function priorityIssueVehicleLabel(row: QualityIssueRow) {
const identity = row.vin?.trim() && row.vin !== 'unknown' ? row.vin.trim() : row.phone?.trim();
return [row.plate?.trim(), identity].filter(Boolean).join(' / ') || row.sourceEndpoint || '-';
@@ -806,12 +816,41 @@ export function Dashboard({
color: (summary?.issueVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const
}
];
const timeMonitorScopeValue = timeMonitorScope();
const timeMonitorWindowLabel = dayRangeText(timeMonitorScopeValue.dateFrom, timeMonitorScopeValue.dateTo);
const timeMonitorChecklist = [
{
label: '范围可解释',
value: timeMonitorScopeValue.keyword ? '单车聚焦' : '全域巡检',
detail: `${timeMonitorScopeValue.protocol || '全部数据通道'} / ${timeMonitorWindowLabel}`,
color: timeMonitorScopeValue.dateFrom && timeMonitorScopeValue.dateTo ? 'green' as const : 'orange' as const
},
{
label: '轨迹可复盘',
value: `${formatCount(summary?.activeToday)} 活跃车辆`,
detail: '可进入轨迹页核对位置、速度、里程断点和停驶片段。',
color: (summary?.activeToday ?? 0) > 0 ? 'green' as const : 'orange' as const
},
{
label: '数据可导出',
value: `${formatCount(summary?.frameToday)} 今日数据`,
detail: '历史查询默认带 RAW 与解析字段,支持按字段缩小导出体积。',
color: (summary?.frameToday ?? 0) > 0 ? 'blue' as const : 'orange' as const
},
{
label: '异常可闭环',
value: `${formatCount(summary?.issueVehicles)} 告警车辆`,
detail: highPriorityIssue ? `${qualityIssueLabel(highPriorityIssue.issueType)} / ${priorityIssueVehicleLabel(highPriorityIssue)}` : '当前没有高优先级告警。',
color: (summary?.issueVehicles ?? 0) > 0 ? 'orange' as const : 'green' as const
}
];
const copyTimeMonitorReviewPackage = () => {
const scope = timeMonitorScope();
const rawFilters = { ...scope, tab: 'raw', includeFields: 'true' };
const lines = [
'【客户时间窗复盘包】',
`范围:${timeMonitorSummary}`,
`时间窗判定:${dayRangeText(scope.dateFrom, scope.dateTo)}`,
'平台能力:实时地图 / 轨迹回放 / 里程统计 / 历史数据查询 / 告警通知',
`车辆范围:${scope.keyword || '全部车辆'}`,
`数据通道:${scope.protocol || '全部数据通道'}`,
@@ -820,6 +859,8 @@ export function Dashboard({
`统计证据:车辆口径 ${formatCount(serviceSummary?.totalVehicles)},用于区间里程和日统计闭合`,
`历史证据:今日数据 ${formatCount(summary?.frameToday)},用于 RAW 与解析字段复核`,
`告警事件:${formatCount(summary?.issueVehicles)} 辆车存在告警`,
'交付核对:',
...timeMonitorChecklist.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: 'history-query', keyword: scope.keyword, protocol: scope.protocol, filters: rawFilters }))}`,
@@ -1390,6 +1431,23 @@ export function Dashboard({
))}
</div>
</div>
<div className="vp-time-audit-strip">
<div className="vp-time-audit-head">
<Typography.Text strong></Typography.Text>
<Typography.Text type="secondary">
</Typography.Text>
</div>
<div className="vp-time-audit-grid">
{timeMonitorChecklist.map((item) => (
<div key={item.label} className="vp-time-audit-item">
<Tag color={item.color}>{item.label}</Tag>
<strong>{item.value}</strong>
<span>{item.detail}</span>
</div>
))}
</div>
</div>
<div className="vp-time-monitor-workbench">
<div className="vp-time-monitor-scope">
<Space wrap>