refactor(stage5): 合并重复实现,移除失效的演示能力

Excel 导出(原先 4 份各自拼装 workbook)
- 新增 src/shared/xlsx.ts 作为唯一实现:文件名统一 .xlsx、sheet 名截断到 31 字符,
  对外提供 buildAoaSheet / buildJsonSheet / writeWorkbook / exportAoaSheet / exportJsonSheet。
  只收敛"组装与写出"这一层,各调用方仍自行决定列宽、冻结与数字格式,导出样式不变。
- 迁移 assets(内联 json_to_sheet + writeFile)、mileage/xlsx-export、
  hydrogen 的两份 helper(prototype-download.ts 与 download-xls.js,均已删除)。

高德地图(原先 2 份近乎逐行复制)
- 新增 src/shared/amap.ts:SDK 版本、插件列表、安全码注入、底图参数、
  控件位置与热力图色带只在此处定义;两个画布只保留各自的半径/透明度。
- 图例渐变条原先把同一组色值又写了一遍,改为复用 shared 的常量,图例与地图不会漂移。

数值格式化
- 两个下钻视图各自复制了同样的 formatNumber/format(共 42 处调用),
  统一到 hydrogen/model/display-format.ts 的 formatFixed;默认路径与既有行为逐字一致。
- 原 display-format.ts 里的 finiteNumber/formatNumber/formatScaled 无任何生产调用方,
  只被自己的测试引用;改为 formatFixed + blankForMissing 显式选项,
  既保留了"真零 vs 不可用"的区分能力,也不再留无人使用的导出。测试同步重写。

失效的演示能力
- Blur / DemoModeProvider 恒为 enabled=false,等于永久 no-op:
  移除 13 个文件里 50 处 <Blur> 包裹(渲染结果不变)、删除 components/Blur.tsx
  与 Shell 中的 Provider,调用方直接渲染原表达式。

未做(刻意)
- src/lib/cn.ts 不引入 tailwind-merge:全仓只有 2 处调用,不值得新增传递依赖。已在文档说明。

架构守护新增 2 条:只有 shared/amap.ts 可加载高德 SDK;
modules/** 不得再出现 book_new / book_append_sheet / writeFile(。

lint / test(137) / build 全绿,可达性仍为 0 未引用文件。
This commit is contained in:
dsh-agent
2026-09-11 10:28:32 +08:00
parent 5d14a28b0f
commit 507bc90ed2
33 changed files with 334 additions and 318 deletions
+6 -7
View File
@@ -1,4 +1,5 @@
import * as XLSX from 'xlsx';
import { buildAoaSheet, writeWorkbook } from '../../shared/xlsx';
import type { MonitoringVehicle } from './types';
interface ExportContext {
@@ -74,7 +75,7 @@ export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportCont
}),
];
const ws = XLSX.utils.aoa_to_sheet(summaryData);
const ws = buildAoaSheet(summaryData);
const numFixedCols = BASE_HEADERS.length;
const wsCols: { wch: number }[] = [
@@ -114,10 +115,8 @@ export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportCont
}
}
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, '车辆汇总');
// 每日明细 sheet:保留原有格式
const sheets: Array<{ name: string; sheet: XLSX.WorkSheet }> = [{ name: '车辆汇总', sheet: ws }];
if (dayKeys.length > 0) {
const detailHeaders = [
'车牌号', '数据来源', '客户', '业务部门', '项目', '租赁状态', '运营区域',
@@ -140,7 +139,7 @@ export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportCont
v.totalKm != null ? v.totalKm : '',
]),
];
const detailWs = XLSX.utils.aoa_to_sheet(detailData);
const detailWs = buildAoaSheet(detailData);
detailWs['!cols'] = [
{ wch: 12 },
{ wch: 16 },
@@ -160,7 +159,7 @@ export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportCont
if (detailWs[ref]?.t === 'n') detailWs[ref].z = '0.##########';
}
}
XLSX.utils.book_append_sheet(wb, detailWs, '每日明细');
sheets.push({ name: '每日明细', sheet: detailWs });
}
const now = new Date();
@@ -178,5 +177,5 @@ export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportCont
? '统计时间'
: isRange ? '区间' : '今日';
const filename = `里程看板_${dateTag}_${hh}${mm}_${sortLabel}.xlsx`;
XLSX.writeFile(wb, filename);
writeWorkbook(sheets, filename);
}