feat: expand vehicle data platform capabilities

This commit is contained in:
lingniu
2026-07-27 16:46:15 +08:00
parent e3a1f80f86
commit 3c4bece72c
650 changed files with 62155 additions and 2552 deletions
@@ -130,5 +130,48 @@ export async function createMileageWorkbook(input: MileageExportInput) {
});
}
sheet.headerFooter.oddFooter = '&L灵牛车辆数据中台&C第 &P / &N 页&R导出于 ' + localDateTime(exportedAt);
const hydrogenSheet = workbook.addWorksheet('氢能明细', {
views: [{ state: 'frozen', ySplit: 1, activeCell: 'A2', showGridLines: false }],
properties: { defaultRowHeight: 21 }
});
hydrogenSheet.addRow(['日期', '车牌', 'VIN', '总里程 (km)', '纯氢里程 (km)', '耗氢 (kg)', '百公里纯氢耗 (kg/100km)', '来源']);
const hydrogenHeader = hydrogenSheet.getRow(1);
hydrogenHeader.height = 30;
hydrogenHeader.eachCell((cell) => {
cell.font = { name: 'Microsoft YaHei', size: 10, bold: true, color: { argb: 'FF304158' } };
cell.alignment = { vertical: 'middle', horizontal: 'center' };
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFEAF0F7' } };
cell.border = { bottom: { style: 'medium', color: { argb: 'FFC3D0DF' } } };
});
const plateByVIN = new Map(input.vehicles.map((vehicle) => [vehicle.vin, vehicle.plate || '未绑定']));
const energyRows = [...input.mileageRows].sort((left, right) => left.date.localeCompare(right.date) || left.vin.localeCompare(right.vin));
energyRows.forEach((value, index) => {
const row = hydrogenSheet.addRow([
value.date,
plateByVIN.get(value.vin) ?? value.plate ?? '未绑定',
value.vin,
value.dailyMileageKm,
value.pureHydrogenMileageKm ?? null,
value.hydrogenConsumptionKg ?? null,
value.hydrogenConsumptionKgPer100Km ?? null,
value.source ?? ''
]);
row.height = 24;
row.eachCell({ includeEmpty: true }, (cell, columnNumber) => {
cell.font = { name: columnNumber === 3 ? 'Consolas' : 'Microsoft YaHei', size: columnNumber === 3 ? 9 : 10, color: { argb: 'FF34445A' } };
cell.alignment = { vertical: 'middle', horizontal: columnNumber >= 4 && columnNumber <= 7 ? 'right' : 'left' };
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: index % 2 ? 'FFF9FBFD' : 'FFFFFFFF' } };
cell.border = { bottom: { style: 'thin', color: { argb: 'FFE6ECF3' } } };
if (columnNumber >= 4 && columnNumber <= 7) cell.numFmt = '#,##0.0';
});
});
[13, 15, 24, 15, 17, 14, 27, 16].forEach((width, index) => {
hydrogenSheet.getColumn(index + 1).width = width;
});
if (energyRows.length) {
hydrogenSheet.autoFilter = { from: { row: 1, column: 1 }, to: { row: energyRows.length + 1, column: 8 } };
}
hydrogenSheet.headerFooter.oddFooter = sheet.headerFooter.oddFooter;
return workbook;
}