feat(platform): add vehicle identity maintenance list
This commit is contained in:
@@ -235,6 +235,44 @@ function vehicleDispatchListText({
|
|||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function vehicleIdentityMaintenanceText({
|
||||||
|
filters,
|
||||||
|
rows,
|
||||||
|
total
|
||||||
|
}: {
|
||||||
|
filters: Record<string, string>;
|
||||||
|
rows: VehicleCoverageRow[];
|
||||||
|
total: number;
|
||||||
|
}) {
|
||||||
|
const maintenanceRows = rows.filter((row) => row.bindingStatus !== 'bound' || vehicleArchiveMissingLabels(row).length > 0);
|
||||||
|
const lines = [
|
||||||
|
'【车辆身份维护清单】',
|
||||||
|
`当前筛选:${vehicleFilterSummary(filters).join(';') || '全部车辆'}`,
|
||||||
|
`当前页待维护:${maintenanceRows.length.toLocaleString()} 辆 / 当前筛选 ${total.toLocaleString()} 辆`,
|
||||||
|
''
|
||||||
|
];
|
||||||
|
maintenanceRows.forEach((row, index) => {
|
||||||
|
const missingLabels = vehicleArchiveMissingLabels(row);
|
||||||
|
const lookupKeys = [
|
||||||
|
row.vin ? `vin=${row.vin}` : '',
|
||||||
|
row.plate ? `plate=${row.plate}` : '',
|
||||||
|
row.phone ? `phone=${row.phone}` : '',
|
||||||
|
row.oem ? `oem=${row.oem}` : ''
|
||||||
|
].filter(Boolean).join(';') || '暂无可用关联键';
|
||||||
|
const action = row.bindingStatus !== 'bound'
|
||||||
|
? '先维护 vehicle_identity_binding 的车牌/手机号到 VIN 映射,再复核实时来源是否归并到车辆服务。'
|
||||||
|
: `补齐档案字段:${missingLabels.join('、')}`;
|
||||||
|
lines.push(
|
||||||
|
`${index + 1}. ${row.plate || '-'} / ${row.vin || '-'} / ${row.phone || '-'} / ${row.oem || '-'}`,
|
||||||
|
` 状态:${vehicleServiceStatus(row).label};绑定:${row.bindingStatus === 'bound' ? '已绑定' : '未绑定'};档案缺项:${missingLabels.join('、') || '无'}`,
|
||||||
|
` 关联键:${lookupKeys}`,
|
||||||
|
` 建议动作:${action}`,
|
||||||
|
` 车辆服务:${appURL(buildAppHash({ page: 'detail', keyword: row.vin, protocol: primaryRowProtocol(row, filters.protocol) }))}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
type VehicleActionRecommendation = {
|
type VehicleActionRecommendation = {
|
||||||
label: string;
|
label: string;
|
||||||
color: 'green' | 'orange' | 'red';
|
color: 'green' | 'orange' | 'red';
|
||||||
@@ -501,6 +539,14 @@ export function Vehicles({
|
|||||||
}
|
}
|
||||||
copyText(vehicleDispatchListText({ filters, rows, total: pagination.total }), '车辆处置清单');
|
copyText(vehicleDispatchListText({ filters, rows, total: pagination.total }), '车辆处置清单');
|
||||||
};
|
};
|
||||||
|
const copyIdentityMaintenanceList = () => {
|
||||||
|
const maintenanceRows = rows.filter((row) => row.bindingStatus !== 'bound' || vehicleArchiveMissingLabels(row).length > 0);
|
||||||
|
if (maintenanceRows.length === 0) {
|
||||||
|
Toast.warning('当前页没有需要维护身份或档案的车辆');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
copyText(vehicleIdentityMaintenanceText({ filters, rows, total: pagination.total }), '车辆身份维护清单');
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFilters(initialFilters);
|
setFilters(initialFilters);
|
||||||
@@ -679,6 +725,7 @@ export function Vehicles({
|
|||||||
<span>当前车辆结果</span>
|
<span>当前车辆结果</span>
|
||||||
<Button size="small" theme="light" onClick={copyGovernanceSummary}>复制治理摘要</Button>
|
<Button size="small" theme="light" onClick={copyGovernanceSummary}>复制治理摘要</Button>
|
||||||
<Button size="small" theme="light" onClick={copyDispatchList}>复制当前页处置清单</Button>
|
<Button size="small" theme="light" onClick={copyDispatchList}>复制当前页处置清单</Button>
|
||||||
|
<Button size="small" theme="light" onClick={copyIdentityMaintenanceList}>复制身份维护清单</Button>
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
style={{ marginTop: 16 }}
|
style={{ marginTop: 16 }}
|
||||||
|
|||||||
@@ -1778,6 +1778,15 @@ test('copies vehicle governance summary from vehicle center', async () => {
|
|||||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时监控:http://localhost:3000/#/realtime?keyword=VIN-GOV-001&protocol=JT808'));
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('实时监控:http://localhost:3000/#/realtime?keyword=VIN-GOV-001&protocol=JT808'));
|
||||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('轨迹回放:http://localhost:3000/#/history?keyword=VIN-GOV-001&protocol=JT808'));
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('轨迹回放:http://localhost:3000/#/history?keyword=VIN-GOV-001&protocol=JT808'));
|
||||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('告警事件:http://localhost:3000/#/alert-events?keyword=VIN-GOV-001&protocol=JT808'));
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('告警事件:http://localhost:3000/#/alert-events?keyword=VIN-GOV-001&protocol=JT808'));
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole('button', { name: '复制身份维护清单' }));
|
||||||
|
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【车辆身份维护清单】'));
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('当前页待维护:1 辆 / 当前筛选 12 辆'));
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('粤A治理1 / VIN-GOV-001 / - / G7s'));
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('档案缺项:缺手机号'));
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('关联键:vin=VIN-GOV-001;plate=粤A治理1;oem=G7s'));
|
||||||
|
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('建议动作:补齐档案字段:缺手机号'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('filters vehicle list from recommended action', async () => {
|
test('filters vehicle list from recommended action', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user