refactor: align electric overview drilldown

This commit is contained in:
kkfluous
2026-08-07 15:18:58 +08:00
parent 08097f7c29
commit 21f5e5388a
9 changed files with 90 additions and 29 deletions
+10 -9
View File
@@ -5,6 +5,7 @@ import hydrogenPool from '../../hydrogen-db.js';
import { cached } from './cache.js';
import {
parseHydrogenCustomerKind,
parseElectricVehicleScope,
parseHydrogenCustomerName,
parseHydrogenStationId,
parseEnergyDate,
@@ -602,14 +603,13 @@ app.get('/electric/orders', async (c) => {
if (date === null) return c.json({ error: 'date 必须是有效的 YYYY-MM-DD 日期' }, 400);
const customerParam = c.req.query('customer');
if (customerParam !== undefined && customerParam !== 'lingniu' && customerParam !== 'external') {
return c.json({ error: 'customer 必须是 lingniu 或 external' }, 400);
}
const customer = customerParam === 'external' ? 'external' : 'lingniu';
const vehicleKind = customer === 'lingniu' ? 'internal' : 'external';
const customer = parseElectricVehicleScope(customerParam);
if (customer === null) return c.json({ error: 'customer 必须是 all、lingniu 或 external' }, 400);
const vehicleKind = customer === 'all' ? null : customer === 'lingniu' ? 'internal' : 'external';
const kindClause = vehicleKind === null ? '' : 'AND vehicle_kind = ?';
const data = await cached(`electric/orders?date=${date}&customer=${customer}`, async () => {
const params = [date, date, vehicleKind];
const params = vehicleKind === null ? [date, date] : [date, date, vehicleKind];
const [[summaryRows], [detailRows]] = await Promise.all([
pool.query<RowDataPacket[]>(
`SELECT COUNT(*) AS recordCount,
@@ -617,7 +617,7 @@ app.get('/electric/orders', async (c) => {
SUM(fee) AS totalFee
FROM bi_ele_charge_record
WHERE start_time >= ? AND start_time < DATE_ADD(?, INTERVAL 1 DAY)
AND vehicle_kind = ?`,
${kindClause}`,
params,
),
pool.query<RowDataPacket[]>(
@@ -634,7 +634,7 @@ app.get('/electric/orders', async (c) => {
fee AS totalFee
FROM bi_ele_charge_record
WHERE start_time >= ? AND start_time < DATE_ADD(?, INTERVAL 1 DAY)
AND vehicle_kind = ?
${kindClause}
ORDER BY start_time DESC, id DESC
LIMIT 501`,
params,
@@ -674,7 +674,8 @@ app.get('/electric/orders', async (c) => {
// 缺失日期补零
// =========================================================
app.get('/electric/monthly', async (c) => {
const customer = parseHydrogenCustomerKind(c.req.query('customer'));
const customer = parseElectricVehicleScope(c.req.query('customer'));
if (customer === null) return c.json({ error: 'customer 必须是 all、lingniu 或 external' }, 400);
const range = (c.req.query('range') || 'last15') as Range;
const dateRange = resolveDateRange(range, c.req.query('startDate'), c.req.query('endDate'));
const force = c.req.query('force') === '1';
+14 -5
View File
@@ -3,6 +3,7 @@ import test from 'node:test';
import app from './index.js';
import {
parseHydrogenCustomerKind,
parseElectricVehicleScope,
parseHydrogenCustomerName,
parseHydrogenStationId,
parseEnergyDate,
@@ -23,6 +24,14 @@ test('defaults unknown customer scopes to lingniu', () => {
assert.equal(parseHydrogenCustomerKind(undefined), 'lingniu');
});
test('parses explicit electric vehicle scopes', () => {
assert.equal(parseElectricVehicleScope('all'), 'all');
assert.equal(parseElectricVehicleScope('lingniu'), 'lingniu');
assert.equal(parseElectricVehicleScope('external'), 'external');
assert.equal(parseElectricVehicleScope(undefined), 'lingniu');
assert.equal(parseElectricVehicleScope('unknown'), null);
});
test('normalizes bounded customer names for exact matching', () => {
assert.equal(parseHydrogenCustomerName(' 武汉客户 '), '武汉客户');
assert.equal(parseHydrogenCustomerName('未指定客户'), '未指定客户');
@@ -48,15 +57,15 @@ test('parses only valid energy calendar dates', () => {
assert.equal(parseEnergyDate(undefined), null);
});
test('rejects invalid electric order drill filters before querying data', async () => {
test('rejects invalid electric drill filters before querying data', async () => {
const invalidDate = await app.request('/electric/orders?date=2026-02-31&customer=lingniu');
assert.equal(invalidDate.status, 400);
assert.deepEqual(await invalidDate.json(), { error: 'date 必须是有效的 YYYY-MM-DD 日期' });
const invalidScope = await app.request('/electric/orders?date=2026-07-28&customer=all');
const invalidScope = await app.request('/electric/orders?date=2026-07-28&customer=unknown');
assert.equal(invalidScope.status, 400);
assert.deepEqual(await invalidScope.json(), { error: 'customer 必须是 lingniu 或 external' });
assert.deepEqual(await invalidScope.json(), { error: 'customer 必须是 all、lingniu 或 external' });
const unknownScope = await app.request('/electric/orders?date=2026-07-28&customer=unknown');
assert.equal(unknownScope.status, 400);
const invalidMonthlyScope = await app.request('/electric/monthly?customer=unknown');
assert.equal(invalidMonthlyScope.status, 400);
});
+7
View File
@@ -1,10 +1,17 @@
export type HydrogenCustomerKind = 'external' | 'lingniu' | 'all';
export type ElectricVehicleScope = 'external' | 'lingniu' | 'all';
export function parseHydrogenCustomerKind(value: string | undefined): HydrogenCustomerKind {
if (value === 'external' || value === 'all') return value;
return 'lingniu';
}
export function parseElectricVehicleScope(value: string | undefined): ElectricVehicleScope | null {
if (value === undefined) return 'lingniu';
if (value === 'external' || value === 'lingniu' || value === 'all') return value;
return null;
}
export function parseHydrogenStationId(value: string | undefined): number | null {
if (value == null || !/^\d+$/.test(value)) return null;
const parsed = Number(value);