feat(platform): frame mileage online impact for customers

This commit is contained in:
lingniu
2026-07-06 04:58:08 +08:00
parent 286840c19c
commit e314f8330f
2 changed files with 18 additions and 18 deletions

View File

@@ -526,7 +526,7 @@ function onlineStatusHandoffText({
? protocolStats.map((item) => `${item.protocol} ${item.online.toLocaleString()}/${item.total.toLocaleString()}`).join('') ? protocolStats.map((item) => `${item.protocol} ${item.online.toLocaleString()}/${item.total.toLocaleString()}`).join('')
: '-'; : '-';
return [ return [
'【车辆在线状态交接】', '【车辆在线状态说明】',
`车辆范围:${keyword}`, `车辆范围:${keyword}`,
`数据通道:${protocol}`, `数据通道:${protocol}`,
`在线概览:${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`, `在线概览:${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`,
@@ -570,7 +570,7 @@ function onlineOperationsReportText({
return Number(row.offlineDurationMinutes ?? 0) > Number(current.offlineDurationMinutes ?? 0) ? row : current; return Number(row.offlineDurationMinutes ?? 0) > Number(current.offlineDurationMinutes ?? 0) ? row : current;
}, undefined); }, undefined);
return [ return [
'【在线统计运营态势】', '【在线影响评估】',
`车辆范围:${keyword}`, `车辆范围:${keyword}`,
`数据通道:${protocol}`, `数据通道:${protocol}`,
`在线概览:${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`, `在线概览:${summary.onlineVehicleCount.toLocaleString()} 在线 / ${summary.offlineVehicleCount.toLocaleString()} 离线 / 在线率 ${formatPercent(summary.onlineRatePercent)}`,
@@ -722,7 +722,7 @@ export function Mileage({
const publishAuditConclusion = publishBlockedCount > 0 ? '阻断发布' : publishReviewCount > 0 ? '复核后发布' : '可发布'; const publishAuditConclusion = publishBlockedCount > 0 ? '阻断发布' : publishReviewCount > 0 ? '复核后发布' : '可发布';
const publishAuditColor = publishBlockedCount > 0 ? 'red' as const : publishReviewCount > 0 ? 'orange' as const : 'green' as const; const publishAuditColor = publishBlockedCount > 0 ? 'red' as const : publishReviewCount > 0 ? 'orange' as const : 'green' as const;
const statisticsImpactColor = publishAuditColor; const statisticsImpactColor = publishAuditColor;
const statisticsImpactLevel = publishAuditConclusion === '可发布' ? '可运营发布' : publishAuditConclusion === '阻断发布' ? '发布阻断' : '影响待复核'; const statisticsImpactLevel = publishAuditConclusion === '可发布' ? '可交付报表' : publishAuditConclusion === '阻断发布' ? '发布阻断' : '影响待复核';
const mileageDeliveryState = publishAuditConclusion === '可发布' && confidenceStatus === '可用于 BI' const mileageDeliveryState = publishAuditConclusion === '可发布' && confidenceStatus === '可用于 BI'
? '可交付' ? '可交付'
: publishAuditConclusion === '阻断发布' ? '暂缓交付' : '复核后交付'; : publishAuditConclusion === '阻断发布' ? '暂缓交付' : '复核后交付';
@@ -749,7 +749,7 @@ export function Mileage({
{ {
label: '异常影响', label: '异常影响',
value: `${anomalyRows.length.toLocaleString()}`, value: `${anomalyRows.length.toLocaleString()}`,
detail: anomalyRows.length > 0 ? '异常会影响BI与运营日报,需要回到证据复核。' : '当前明细未命中异常标记。', detail: anomalyRows.length > 0 ? '异常会影响客户报表和 BI 口径,需要回到证据复核。' : '当前明细未命中异常标记。',
color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const color: anomalyRows.length > 0 ? 'orange' as const : 'green' as const
}, },
{ {
@@ -763,7 +763,7 @@ export function Mileage({
{ {
label: '交付结论', label: '交付结论',
value: mileageDeliveryState, value: mileageDeliveryState,
detail: mileageDeliveryState === '可交付' ? '可进入客户查询、BI发布和运营日报。' : mileageDeliveryState === '暂缓交付' ? '存在阻断项,先完成证据复核。' : '需补齐闭合、覆盖、异常或在线证据后交付。', detail: mileageDeliveryState === '可交付' ? '可进入客户查询、BI发布和报表交付。' : mileageDeliveryState === '暂缓交付' ? '存在阻断项,先完成证据复核。' : '需补齐闭合、覆盖、异常或在线证据后交付。',
color: mileageDeliveryColor, color: mileageDeliveryColor,
action: '复制决策', action: '复制决策',
onClick: () => copyMileageDecision() onClick: () => copyMileageDecision()
@@ -1022,7 +1022,7 @@ export function Mileage({
step: '05', step: '05',
title: '明细导出', title: '明细导出',
value: `${rows.length.toLocaleString()} 当前页`, value: `${rows.length.toLocaleString()} 当前页`,
detail: '导出明细并附带统计口径支撑BI、客户复盘和运营日报。', detail: '导出明细并附带统计口径,支撑 BI 核对、客户复盘和报表交付。',
action: '导出明细', action: '导出明细',
color: rows.length > 0 ? 'blue' as const : 'grey' as const, color: rows.length > 0 ? 'blue' as const : 'grey' as const,
disabled: rows.length === 0, disabled: rows.length === 0,
@@ -1101,7 +1101,7 @@ export function Mileage({
{ {
title: '导出明细证据', title: '导出明细证据',
value: `${rows.length.toLocaleString()} 条当前页`, value: `${rows.length.toLocaleString()} 条当前页`,
detail: `覆盖 ${formatPercent(pageCoverageRate)}用于客户复盘、BI核对和运营日报附件。`, detail: `覆盖 ${formatPercent(pageCoverageRate)}用于客户复盘、BI 核对和报附件。`,
action: '导出CSV', action: '导出CSV',
color: rows.length > 0 ? 'blue' as const : 'grey' as const, color: rows.length > 0 ? 'blue' as const : 'grey' as const,
disabled: rows.length === 0, disabled: rows.length === 0,
@@ -1390,7 +1390,7 @@ export function Mileage({
rows: onlineRows, rows: onlineRows,
total: onlinePagination.total total: onlinePagination.total
}), }),
'在线状态交接' '在线状态说明'
); );
}; };
const copyOnlineOperationsReport = () => { const copyOnlineOperationsReport = () => {
@@ -1406,7 +1406,7 @@ export function Mileage({
statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })), statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
vehicleURL vehicleURL
}), }),
'在线统计运营态势' '在线影响评估'
); );
}; };
const mileageDeliveryConsoleItems = [ const mileageDeliveryConsoleItems = [
@@ -1414,7 +1414,7 @@ export function Mileage({
label: '交付状态', label: '交付状态',
value: mileageDeliveryState, value: mileageDeliveryState,
detail: mileageDeliveryState === '可交付' detail: mileageDeliveryState === '可交付'
? '可进入客户查询、BI发布和运营日报。' ? '可进入客户查询、BI发布和报表交付。'
: mileageDeliveryState === '暂缓交付' : mileageDeliveryState === '暂缓交付'
? '存在阻断项,先完成闭合和异常复核。' ? '存在阻断项,先完成闭合和异常复核。'
: '复核闭合、覆盖、异常或在线影响后再交付。', : '复核闭合、覆盖、异常或在线影响后再交付。',
@@ -1504,7 +1504,7 @@ export function Mileage({
{ {
label: '报表导出', label: '报表导出',
value: `${rows.length.toLocaleString()}`, value: `${rows.length.toLocaleString()}`,
detail: '导出当前明细作为客户对账、BI核对和运营日报附件。', detail: '导出当前明细作为客户对账、BI 核对和报附件。',
color: rows.length > 0 ? 'blue' as const : 'grey' as const, color: rows.length > 0 ? 'blue' as const : 'grey' as const,
action: '导出CSV', action: '导出CSV',
disabled: rows.length === 0, disabled: rows.length === 0,
@@ -1575,7 +1575,7 @@ export function Mileage({
{ {
title: '发布判断', title: '发布判断',
value: publishAuditConclusion, value: publishAuditConclusion,
detail: publishAuditConclusion === '可发布' ? '当前统计范围可进入运营日报或 BI 口径。' : '发布前需要补齐闭合、覆盖、异常或在线证据。', detail: publishAuditConclusion === '可发布' ? '当前统计范围可进入客户报表或 BI 口径。' : '发布前需要补齐闭合、覆盖、异常或在线证据。',
color: publishAuditColor, color: publishAuditColor,
primaryAction: 'BI口径', primaryAction: 'BI口径',
secondaryAction: '发布审计', secondaryAction: '发布审计',
@@ -2476,7 +2476,7 @@ export function Mileage({
<Card <Card
bordered bordered
loading={onlineLoading} loading={onlineLoading}
title={<Space><span>线</span><Button size="small" onClick={copyOnlineOperationsReport}>线</Button></Space>} title={<Space><span>线</span><Button size="small" onClick={copyOnlineOperationsReport}>线</Button></Space>}
style={{ marginTop: 16 }} style={{ marginTop: 16 }}
> >
<div className="vp-online-ops-board"> <div className="vp-online-ops-board">

View File

@@ -9968,8 +9968,8 @@ test('shows vehicle-first statistics domains for one vehicle service', async ()
expect(screen.getByText('闭合影响')).toBeInTheDocument(); expect(screen.getByText('闭合影响')).toBeInTheDocument();
expect(screen.getByText('异常影响')).toBeInTheDocument(); expect(screen.getByText('异常影响')).toBeInTheDocument();
expect(screen.getAllByText('发布判断').length).toBeGreaterThanOrEqual(1); expect(screen.getAllByText('发布判断').length).toBeGreaterThanOrEqual(1);
expect(screen.getByText('在线统计运营态势')).toBeInTheDocument(); expect(screen.getByText('在线影响评估')).toBeInTheDocument();
expect(screen.getByRole('button', { name: '复制在线态势' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: '复制在线影响' })).toBeInTheDocument();
expect(screen.getByText('离线车辆')).toBeInTheDocument(); expect(screen.getByText('离线车辆')).toBeInTheDocument();
expect(screen.getAllByText('来源覆盖').length).toBeGreaterThanOrEqual(1); expect(screen.getAllByText('来源覆盖').length).toBeGreaterThanOrEqual(1);
expect(screen.getByText('当前页离线')).toBeInTheDocument(); expect(screen.getByText('当前页离线')).toBeInTheDocument();
@@ -9994,8 +9994,8 @@ test('shows vehicle-first statistics domains for one vehicle service', async ()
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('决策结论:复核后交付')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('决策结论:复核后交付'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('客户判断路径:')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('客户判断路径:'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('1. 先看区间闭合:区间总值必须等于每日里程之和。')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('1. 先看区间闭合:区间总值必须等于每日里程之和。'));
fireEvent.click(screen.getByRole('button', { name: '复制在线态势' })); fireEvent.click(screen.getByRole('button', { name: '复制在线影响' }));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【在线统计运营态势】')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【在线影响评估】'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆范围VIN-STATS-SERVICE')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆范围VIN-STATS-SERVICE'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('数据通道JT808')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('数据通道JT808'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('在线概览3 在线 / 1 离线 / 在线率 75%')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('在线概览3 在线 / 1 离线 / 在线率 75%'));
@@ -10015,7 +10015,7 @@ test('shows vehicle-first statistics domains for one vehicle service', async ()
expect(screen.getByText('粤A离线1')).toBeInTheDocument(); expect(screen.getByText('粤A离线1')).toBeInTheDocument();
expect(screen.getAllByText('2 小时').length).toBeGreaterThan(0); expect(screen.getAllByText('2 小时').length).toBeGreaterThan(0);
fireEvent.click(screen.getByRole('button', { name: '复制在线状态清单' })); fireEvent.click(screen.getByRole('button', { name: '复制在线状态清单' }));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【车辆在线状态交接】')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【车辆在线状态说明】'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆范围VIN-STATS-SERVICE')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆范围VIN-STATS-SERVICE'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('在线概览3 在线 / 1 离线 / 在线率 75%')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('在线概览3 在线 / 1 离线 / 在线率 75%'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('来源在线JT808 2/3GB32960 1/2')); expect(writeText).toHaveBeenCalledWith(expect.stringContaining('来源在线JT808 2/3GB32960 1/2'));