124 lines
4.5 KiB
TypeScript
124 lines
4.5 KiB
TypeScript
import type { CustomerType } from './types';
|
|
|
|
export type HydrogenDrillLevel = 'overview' | 'station' | 'customer';
|
|
|
|
export interface HydrogenDrillContext {
|
|
level: HydrogenDrillLevel;
|
|
year?: number;
|
|
stationId?: number;
|
|
stationName?: string;
|
|
customerName?: string;
|
|
vehicleScope: CustomerType;
|
|
startDate?: string;
|
|
endDate?: string;
|
|
selectedDate?: string;
|
|
orderPage?: number;
|
|
}
|
|
|
|
interface LocationParts {
|
|
pathname: string;
|
|
search: string;
|
|
hash: string;
|
|
}
|
|
|
|
const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
|
|
function validDate(value: string | null): string | undefined {
|
|
if (!value || !DATE_PATTERN.test(value)) return undefined;
|
|
const timestamp = Date.parse(`${value}T00:00:00+08:00`);
|
|
return Number.isFinite(timestamp) ? value : undefined;
|
|
}
|
|
|
|
function positiveInteger(value: string | null): number | undefined {
|
|
if (!value || !/^\d+$/.test(value)) return undefined;
|
|
const parsed = Number(value);
|
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
}
|
|
|
|
function stationId(value: string | null): number | undefined {
|
|
if (!value || !/^\d+$/.test(value)) return undefined;
|
|
const parsed = Number(value);
|
|
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : undefined;
|
|
}
|
|
|
|
export function parseHydrogenDrillContext(search: string): HydrogenDrillContext {
|
|
const params = new URLSearchParams(search);
|
|
const requestedLevel = params.get('hydrogenLevel');
|
|
const parsedStationId = stationId(params.get('hydrogenStation'));
|
|
const parsedStationName = params.get('hydrogenStationName')?.trim() || undefined;
|
|
const rawCustomerName = params.get('hydrogenCustomer')?.trim();
|
|
const customerName = rawCustomerName && rawCustomerName.length <= 128
|
|
? rawCustomerName
|
|
: undefined;
|
|
const context: HydrogenDrillContext = {
|
|
level: requestedLevel === 'station' && parsedStationId !== undefined
|
|
? 'station'
|
|
: requestedLevel === 'customer' && customerName
|
|
? 'customer'
|
|
: 'overview',
|
|
vehicleScope: params.get('hydrogenScope') === 'external' ? 'external' : 'lingniu',
|
|
};
|
|
|
|
const year = positiveInteger(params.get('hydrogenYear'));
|
|
if (year && year >= 2000 && year <= 2100) context.year = year;
|
|
if (context.level === 'station') {
|
|
context.stationId = parsedStationId;
|
|
if (parsedStationName) context.stationName = parsedStationName;
|
|
}
|
|
if (context.level === 'customer') context.customerName = customerName;
|
|
const startDate = validDate(params.get('hydrogenStart'));
|
|
const endDate = validDate(params.get('hydrogenEnd'));
|
|
const selectedDate = validDate(params.get('hydrogenDate'));
|
|
if (startDate) context.startDate = startDate;
|
|
if (endDate) context.endDate = endDate;
|
|
const rangeStart = startDate && endDate ? (startDate <= endDate ? startDate : endDate) : undefined;
|
|
const rangeEnd = startDate && endDate ? (startDate <= endDate ? endDate : startDate) : undefined;
|
|
if (selectedDate && (!rangeStart || !rangeEnd || (selectedDate >= rangeStart && selectedDate <= rangeEnd))) {
|
|
context.selectedDate = selectedDate;
|
|
const orderPage = positiveInteger(params.get('hydrogenPage'));
|
|
if (orderPage && orderPage > 1) context.orderPage = orderPage;
|
|
}
|
|
return context;
|
|
}
|
|
|
|
export function buildHydrogenDrillUrl(
|
|
location: LocationParts,
|
|
context: HydrogenDrillContext,
|
|
): string {
|
|
const params = new URLSearchParams(location.search);
|
|
for (const key of [
|
|
'hydrogenLevel',
|
|
'hydrogenYear',
|
|
'hydrogenStation',
|
|
'hydrogenStationName',
|
|
'hydrogenCustomer',
|
|
'hydrogenScope',
|
|
'hydrogenStart',
|
|
'hydrogenEnd',
|
|
'hydrogenDate',
|
|
'hydrogenPage',
|
|
]) {
|
|
params.delete(key);
|
|
}
|
|
|
|
if (context.level !== 'overview') params.set('hydrogenLevel', context.level);
|
|
if (context.year) params.set('hydrogenYear', String(context.year));
|
|
if (context.level === 'station' && context.stationId !== undefined) {
|
|
params.set('hydrogenStation', String(context.stationId));
|
|
if (context.stationName) params.set('hydrogenStationName', context.stationName);
|
|
}
|
|
if (context.level === 'customer' && context.customerName) {
|
|
params.set('hydrogenCustomer', context.customerName);
|
|
}
|
|
params.set('hydrogenScope', context.vehicleScope);
|
|
if (context.startDate) params.set('hydrogenStart', context.startDate);
|
|
if (context.endDate) params.set('hydrogenEnd', context.endDate);
|
|
if (context.selectedDate) params.set('hydrogenDate', context.selectedDate);
|
|
if (context.selectedDate && context.orderPage && context.orderPage > 1) {
|
|
params.set('hydrogenPage', String(context.orderPage));
|
|
}
|
|
|
|
const query = params.toString();
|
|
return `${location.pathname}${query ? `?${query}` : ''}${location.hash}`;
|
|
}
|