refactor: expose ETC integration readiness

This commit is contained in:
kkfluous
2026-08-07 15:00:58 +08:00
parent cdf1fd27e7
commit 0fb62135f3
8 changed files with 363 additions and 76 deletions
+84
View File
@@ -757,4 +757,88 @@ app.get('/electric/monthly', async (c) => {
return c.json(data);
});
// =========================================================
// ETC 总览:真实接入状态 + 通行记录/账单基础 KPI
// 不读取或返回同步账号、密码、API 地址等敏感配置。
// =========================================================
app.get('/etc/overview', async (c) => {
const force = c.req.query('force') === '1';
const data = await cached('etc/overview', async () => {
const [[recordRows], [billRows], [configRows], [logRows]] = await Promise.all([
pool.query<RowDataPacket[]>(
`SELECT COUNT(*) AS passageCount,
COUNT(DISTINCT plate_number) AS vehicleCount,
SUM(toll_amount) AS tollAmount,
SUM(service_fee) AS serviceFee,
SUM(total_amount) AS totalAmount,
DATE_FORMAT(MAX(trans_time), '%Y-%m-%d %H:%i:%s') AS latestTransactionTime
FROM etc_toll_record
WHERE del_flag = '0'`,
),
pool.query<RowDataPacket[]>(
`SELECT COUNT(*) AS billCount,
SUM(receivable_amount) AS receivableAmount,
SUM(paid_amount) AS paidAmount
FROM energy_etc_bill
WHERE del_flag = '0'`,
),
pool.query<RowDataPacket[]>(
`SELECT provider_type AS providerType,
sync_enabled AS syncEnabled,
DATE_FORMAT(last_sync_time, '%Y-%m-%d %H:%i:%s') AS lastSyncAt,
last_sync_status AS lastSyncStatus
FROM etc_sync_config
WHERE del_flag = '0'
ORDER BY update_time DESC, id DESC
LIMIT 1`,
),
pool.query<RowDataPacket[]>(
`SELECT DATE_FORMAT(sync_end_time, '%Y-%m-%d %H:%i:%s') AS lastSyncAt,
sync_status AS syncStatus
FROM etc_sync_log
ORDER BY sync_start_time DESC, id DESC
LIMIT 1`,
),
]);
const record = recordRows[0] ?? {};
const bill = billRows[0] ?? {};
const config = configRows[0];
const log = logRows[0];
const rawSyncStatus = log?.syncStatus ?? config?.lastSyncStatus;
const lastSyncStatus = rawSyncStatus === 1
? 'success'
: rawSyncStatus === 0
? 'failed'
: rawSyncStatus === 2
? 'partial'
: rawSyncStatus == null
? 'never'
: 'unknown';
return {
integration: {
providerConfigured: Boolean(config),
syncEnabled: Number(config?.syncEnabled) === 1,
providerType: config?.providerType ? String(config.providerType) : null,
lastSyncAt: log?.lastSyncAt ? String(log.lastSyncAt) : config?.lastSyncAt ? String(config.lastSyncAt) : null,
lastSyncStatus,
},
kpi: {
passageCount: Number(record.passageCount) || 0,
vehicleCount: Number(record.vehicleCount) || 0,
tollAmount: Math.round((Number(record.tollAmount) || 0) * 100) / 100,
serviceFee: Math.round((Number(record.serviceFee) || 0) * 100) / 100,
totalAmount: Math.round((Number(record.totalAmount) || 0) * 100) / 100,
billCount: Number(bill.billCount) || 0,
receivableAmount: Math.round((Number(bill.receivableAmount) || 0) * 100) / 100,
paidAmount: Math.round((Number(bill.paidAmount) || 0) * 100) / 100,
latestTransactionTime: record.latestTransactionTime ? String(record.latestTransactionTime) : null,
},
} as const;
}, { force });
return c.json(data);
});
export default app;