feat(platform): link mileage statistics summary
This commit is contained in:
@@ -3,6 +3,7 @@ import { useEffect, useState } from 'react';
|
||||
import { api } from '../api/client';
|
||||
import type { DailyMileageRow, MileageSummary } from '../api/types';
|
||||
import { PageHeader } from '../components/PageHeader';
|
||||
import { buildAppHash } from '../domain/appRoute';
|
||||
import { buildCsv, downloadCsv, type CsvColumn } from '../domain/csvExport';
|
||||
|
||||
const emptySummary: MileageSummary = {
|
||||
@@ -111,18 +112,26 @@ function exportFileName(filters: Record<string, string>) {
|
||||
return `daily-mileage-${keyword}-${protocol}.csv`;
|
||||
}
|
||||
|
||||
function appURL(hash: string) {
|
||||
return `${window.location.origin}${window.location.pathname}${hash}`;
|
||||
}
|
||||
|
||||
function mileageSummaryText({
|
||||
filters,
|
||||
summary,
|
||||
pageMileageTotal,
|
||||
anomalyCount,
|
||||
peakMileage
|
||||
peakMileage,
|
||||
statisticsURL,
|
||||
vehicleURL
|
||||
}: {
|
||||
filters: Record<string, string>;
|
||||
summary: MileageSummary;
|
||||
pageMileageTotal: number;
|
||||
anomalyCount: number;
|
||||
peakMileage?: DailyMileageRow;
|
||||
statisticsURL: string;
|
||||
vehicleURL?: string;
|
||||
}) {
|
||||
const keyword = filters.keyword?.trim() || '全部车辆';
|
||||
const protocol = filters.protocol?.trim() || '全部来源';
|
||||
@@ -143,7 +152,9 @@ function mileageSummaryText({
|
||||
`当前页里程:${formatKm(pageMileageTotal)} km`,
|
||||
`异常记录:${anomalyCount.toLocaleString()}`,
|
||||
`最大单日:${peak}`,
|
||||
'统计口径:区间总值等于各日里程之和'
|
||||
'统计口径:区间总值等于各日里程之和',
|
||||
`统计查询:${statisticsURL}`,
|
||||
...(vehicleURL ? [`车辆服务:${vehicleURL}`] : [])
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
@@ -259,13 +270,18 @@ export function Mileage({
|
||||
Toast.success(`已导出 ${rows.length} 条里程明细`);
|
||||
};
|
||||
const copyStatisticsSummary = () => {
|
||||
const vehicleURL = currentVehicleKeyword
|
||||
? appURL(buildAppHash({ page: 'detail', keyword: currentVehicleKeyword, protocol: currentProtocol }))
|
||||
: undefined;
|
||||
copyText(
|
||||
mileageSummaryText({
|
||||
filters,
|
||||
summary,
|
||||
pageMileageTotal,
|
||||
anomalyCount: anomalyRows.length,
|
||||
peakMileage
|
||||
peakMileage,
|
||||
statisticsURL: appURL(window.location.hash || buildAppHash({ page: 'mileage', keyword: currentVehicleKeyword, protocol: currentProtocol })),
|
||||
vehicleURL
|
||||
}),
|
||||
'统计摘要'
|
||||
);
|
||||
|
||||
@@ -5698,6 +5698,8 @@ test('copies mileage statistics summary for operations reporting', async () => {
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('异常记录:1'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('最大单日:粤A统计2 / 2026-07-02 / 100 km'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('统计口径:区间总值等于各日里程之和'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('统计查询:http://localhost:3000/#/mileage?keyword=VIN-MILEAGE-COPY&protocol=JT808&dateFrom=2026-07-01&dateTo=2026-07-03'));
|
||||
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('车辆服务:http://localhost:3000/#/detail?keyword=VIN-MILEAGE-COPY&protocol=JT808'));
|
||||
});
|
||||
|
||||
test('exports current mileage page as CSV', async () => {
|
||||
|
||||
Reference in New Issue
Block a user