Files
mileage-bonus/energy-h2-bi-board-html/source/data/mockDaily.ts
T

1045 lines
35 KiB
TypeScript

/** 宿主按日视图 (Daily View) 模拟数据 - 包含加氢站、客户、车辆及数据来源穿透明细
*
* 外部车牌主数据对齐:`src/common/energy-h2-external-fleet` 种子
* (粤B12345D / 粤A99888D / 粤E88111D / 粤B99111D / 粤B33888D / 粤E99999D)。
* 分流规则:own → 车辆氢费明细;external → 仅 BI(见 resolveFleetRoute)。
*/
export type StationType = 'self_use' | 'external_sale'; // 自用消费 | 对外销售
export type SourceType = 'api' | 'station_report' | 'lingniu_report'; // API接入 | 站点上报 | 羚牛上报
export type FleetCategory = 'own' | 'external'; // 羚牛车辆 | 外部车辆
export type FleetCategoryFilter = 'all' | 'own' | 'external'; // 全量合并 | 羚牛车辆 | 外部车辆
export type CustomerCategory = 'internal' | 'external'; // 内部客户 | 外部客户
export type DailyVerifyStatus = 'verified' | 'unverified'; // 已核对 | 未核对
export const SOURCE_TYPE_LABEL: Record<SourceType, string> = {
api: 'API接入',
station_report: '站点上报',
lingniu_report: '羚牛上报',
};
export const STATION_TYPE_LABEL: Record<StationType, string> = {
self_use: '自用消费',
external_sale: '对外销售',
};
export const CUSTOMER_CATEGORY_LABEL: Record<CustomerCategory, string> = {
internal: '内部客户',
external: '外部客户',
};
export const DAILY_VERIFY_LABEL: Record<DailyVerifyStatus, string> = {
verified: '已核对',
unverified: '未核对',
};
export interface VehicleRefDetail {
id: string;
time: string;
plateNo: string | null; // 车牌号(内部车必有,外部车可能无)
fleetCategory: FleetCategory; // 羚牛车辆(内部) | 外部车辆
quantityKg: number;
unitPrice: number;
amountYuan: number;
source: SourceType; // 内部: API接入/站点上报/羚牛上报;外部: 仅API接入/站点上报
verifyStatus?: DailyVerifyStatus | null; // 内部车辆必有(已核对/未核对);外部车辆无核对状态
}
export interface CustomerDetail {
customerId: string;
customerName: string;
customerCategory?: CustomerCategory; // 内部客户 | 外部客户
quantityKg: number;
amountYuan: number;
vehicles: VehicleRefDetail[];
}
export interface DailyStationDetail {
stationId: string;
stationName: string;
stationType: StationType; // 自用消费 | 对外销售
unitPrice: number;
quantityKg: number;
amountYuan: number;
prechargeBalance?: number; // 对接站点管理预充值余额
customers: CustomerDetail[];
}
export interface DailyItem {
date: string; // YYYY-MM-DD
shortDate: string; // MM-DD
unitPrice: number;
quantityKg: number;
amountYuan: number;
momPct: number | null; // 环比
stations: DailyStationDetail[];
}
export const MOCK_DAILY_15DAYS: DailyItem[] = [
{
date: '2026-08-08',
shortDate: '08-08',
unitPrice: 30,
quantityKg: 3139.12,
amountYuan: 94173.6,
momPct: 1626.9,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 1800.0,
amountYuan: 54000.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 1100.0,
amountYuan: 33000.0,
vehicles: [
{ id: 'v-101', time: '08:15', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 45.2, unitPrice: 30, amountYuan: 1356, source: 'api', verifyStatus: 'verified' },
{ id: 'v-102', time: '09:30', plateNo: '浙A66666F', fleetCategory: 'own', quantityKg: 54.8, unitPrice: 30, amountYuan: 1644, source: 'lingniu_report', verifyStatus: 'verified' },
{ id: 'v-103', time: '11:20', plateNo: '浙A33333F', fleetCategory: 'own', quantityKg: 40.0, unitPrice: 30, amountYuan: 1200, source: 'station_report', verifyStatus: 'unverified' },
{ id: 'v-104', time: '14:00', plateNo: '浙A99999F', fleetCategory: 'own', quantityKg: 960.0, unitPrice: 30, amountYuan: 28800, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 700.0,
amountYuan: 21000.0,
vehicles: [
{ id: 'v-201', time: '10:10', plateNo: '粤B12345D', fleetCategory: 'external', quantityKg: 350.0, unitPrice: 30, amountYuan: 10500, source: 'station_report', verifyStatus: null },
{ id: 'v-202', time: '15:45', plateNo: null, fleetCategory: 'external', quantityKg: 350.0, unitPrice: 30, amountYuan: 10500, source: 'api', verifyStatus: null },
],
},
],
},
{
stationId: 'st-fs',
stationName: '佛山南海加氢站',
stationType: 'external_sale',
unitPrice: 38,
quantityKg: 1339.12,
amountYuan: 50886.56,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 500.0,
amountYuan: 19000.0,
vehicles: [
{ id: 'v-300', time: '06:50', plateNo: '粤B88666D', fleetCategory: 'own', quantityKg: 500.0, unitPrice: 38, amountYuan: 19000, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qy',
customerName: '广东清运科技有限公司',
quantityKg: 300.0,
amountYuan: 11400.0,
vehicles: [
{ id: 'v-301', time: '07:40', plateNo: '粤E88111D', fleetCategory: 'external', quantityKg: 300.0, unitPrice: 38, amountYuan: 11400, source: 'station_report', verifyStatus: null },
],
},
{
customerId: 'c-dp',
customerName: '东展供应链(广州)有限公司',
quantityKg: 539.12,
amountYuan: 20486.56,
vehicles: [
{ id: 'v-401', time: '16:00', plateNo: '粤A99888D', fleetCategory: 'external', quantityKg: 539.12, unitPrice: 38, amountYuan: 20486.56, source: 'api', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-07',
shortDate: '08-07',
unitPrice: 30,
quantityKg: 1181.78,
amountYuan: 35453.4,
momPct: -62.3,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 681.78,
amountYuan: 20453.4,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 181.78,
amountYuan: 5453.4,
vehicles: [
{ id: 'v-501', time: '09:00', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 81.78, unitPrice: 30, amountYuan: 2453.4, source: 'lingniu_report', verifyStatus: 'verified' },
{ id: 'v-502', time: '14:30', plateNo: '浙A66666F', fleetCategory: 'own', quantityKg: 100.0, unitPrice: 30, amountYuan: 3000.0, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qy',
customerName: '广东清运科技有限公司',
quantityKg: 500.0,
amountYuan: 15000.0,
vehicles: [
{ id: 'v-503', time: '16:10', plateNo: null, fleetCategory: 'external', quantityKg: 500.0, unitPrice: 30, amountYuan: 15000, source: 'station_report', verifyStatus: null },
],
},
],
},
{
stationId: 'st-jj',
stationName: '嘉兴嘉锦加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 500.0,
amountYuan: 15000.0,
customers: [
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 500.0,
amountYuan: 15000.0,
vehicles: [
{ id: 'v-504', time: '11:00', plateNo: '粤B99111D', fleetCategory: 'external', quantityKg: 500.0, unitPrice: 30, amountYuan: 15000, source: 'api', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-06',
shortDate: '08-06',
unitPrice: 30,
quantityKg: 2250.0,
amountYuan: 67500.0,
momPct: 90.4,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 1250.0,
amountYuan: 37500.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 850.0,
amountYuan: 25500.0,
vehicles: [
{ id: 'v-601', time: '10:00', plateNo: '浙A55555F', fleetCategory: 'own', quantityKg: 450.0, unitPrice: 30, amountYuan: 13500, source: 'api', verifyStatus: 'verified' },
{ id: 'v-602', time: '16:00', plateNo: '浙A33333F', fleetCategory: 'own', quantityKg: 400.0, unitPrice: 30, amountYuan: 12000, source: 'lingniu_report', verifyStatus: 'unverified' },
],
},
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 400.0,
amountYuan: 12000.0,
vehicles: [
{ id: 'v-603', time: '17:30', plateNo: '粤B33888D', fleetCategory: 'external', quantityKg: 400.0, unitPrice: 30, amountYuan: 12000, source: 'station_report', verifyStatus: null },
],
},
],
},
{
stationId: 'st-dp',
stationName: '东鹏加氢站(对外)',
stationType: 'external_sale',
unitPrice: 38,
quantityKg: 1000.0,
amountYuan: 38000.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 300.0,
amountYuan: 11400.0,
vehicles: [
{ id: 'v-700', time: '09:10', plateNo: '浙A11222F', fleetCategory: 'own', quantityKg: 300.0, unitPrice: 38, amountYuan: 11400, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-dp',
customerName: '东展供应链(广州)有限公司',
quantityKg: 700.0,
amountYuan: 26600.0,
vehicles: [
{ id: 'v-701', time: '11:30', plateNo: null, fleetCategory: 'external', quantityKg: 700.0, unitPrice: 38, amountYuan: 26600, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-05',
shortDate: '08-05',
unitPrice: 30,
quantityKg: 2720.0,
amountYuan: 81600.0,
momPct: 20.9,
stations: [
{
stationId: 'st-jj',
stationName: '嘉兴嘉锦加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2720.0,
amountYuan: 81600.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 1720.0,
amountYuan: 51600.0,
vehicles: [
{ id: 'v-801', time: '08:00', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 860.0, unitPrice: 30, amountYuan: 25800, source: 'api', verifyStatus: 'verified' },
{ id: 'v-802', time: '15:20', plateNo: '浙A99999F', fleetCategory: 'own', quantityKg: 860.0, unitPrice: 30, amountYuan: 25800, source: 'lingniu_report', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qy',
customerName: '广东清运科技有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-803', time: '18:00', plateNo: '粤E99999D', fleetCategory: 'external', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'api', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-04',
shortDate: '08-04',
unitPrice: 30,
quantityKg: 3150.0,
amountYuan: 94500.0,
momPct: 1.6,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3150.0,
amountYuan: 94500.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-900', time: '07:30', plateNo: '浙A77777F', fleetCategory: 'own', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 2150.0,
amountYuan: 64500.0,
vehicles: [
{ id: 'v-901', time: '09:10', plateNo: '粤B88888D', fleetCategory: 'external', quantityKg: 1075.0, unitPrice: 30, amountYuan: 32250, source: 'station_report', verifyStatus: null },
{ id: 'v-902', time: '16:40', plateNo: '粤B99999D', fleetCategory: 'external', quantityKg: 1075.0, unitPrice: 30, amountYuan: 32250, source: 'api', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-03',
shortDate: '08-03',
unitPrice: 30,
quantityKg: 3100.0,
amountYuan: 93000.0,
momPct: 5.1,
stations: [
{
stationId: 'st-sh',
stationName: '上海金山加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3100.0,
amountYuan: 93000.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2100.0,
amountYuan: 63000.0,
vehicles: [
{ id: 'v-1001', time: '10:30', plateNo: '沪A88111F', fleetCategory: 'own', quantityKg: 2100.0, unitPrice: 30, amountYuan: 63000, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-dp',
customerName: '东展供应链(广州)有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-1002', time: '15:10', plateNo: null, fleetCategory: 'external', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-02',
shortDate: '08-02',
unitPrice: 30,
quantityKg: 2950.0,
amountYuan: 88500.0,
momPct: -18.5,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2950.0,
amountYuan: 88500.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2000.0,
amountYuan: 60000.0,
vehicles: [
{ id: 'v-1101', time: '08:45', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'lingniu_report', verifyStatus: 'verified' },
{ id: 'v-1102', time: '14:15', plateNo: '浙A66666F', fleetCategory: 'own', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qy',
customerName: '广东清运科技有限公司',
quantityKg: 950.0,
amountYuan: 28500.0,
vehicles: [
{ id: 'v-1103', time: '17:00', plateNo: null, fleetCategory: 'external', quantityKg: 950.0, unitPrice: 30, amountYuan: 28500, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-08-01',
shortDate: '08-01',
unitPrice: 30,
quantityKg: 3620.0,
amountYuan: 108600.0,
momPct: 1.1,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2000.0,
amountYuan: 60000.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2000.0,
amountYuan: 60000.0,
vehicles: [
{ id: 'v-1201', time: '09:00', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 2000.0, unitPrice: 30, amountYuan: 60000, source: 'api', verifyStatus: 'verified' },
],
},
],
},
{
stationId: 'st-jj',
stationName: '嘉兴嘉锦加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 1620.0,
amountYuan: 48600.0,
customers: [
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 1620.0,
amountYuan: 48600.0,
vehicles: [
{ id: 'v-1202', time: '11:20', plateNo: '粤B33333D', fleetCategory: 'external', quantityKg: 1620.0, unitPrice: 30, amountYuan: 48600, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-07-31',
shortDate: '07-31',
unitPrice: 30,
quantityKg: 3580.0,
amountYuan: 107400.0,
momPct: -4.5,
stations: [
{
stationId: 'st-jj',
stationName: '嘉兴嘉锦加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3580.0,
amountYuan: 107400.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2580.0,
amountYuan: 77400.0,
vehicles: [
{ id: 'v-1301', time: '10:00', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 2580.0, unitPrice: 30, amountYuan: 77400, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-1302', time: '16:00', plateNo: '粤B55555D', fleetCategory: 'external', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'api', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-07-30',
shortDate: '07-30',
unitPrice: 30,
quantityKg: 3750.0,
amountYuan: 112500.0,
momPct: 8.7,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3750.0,
amountYuan: 112500.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 3750.0,
amountYuan: 112500.0,
vehicles: [
{ id: 'v-1401', time: '08:30', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 3750.0, unitPrice: 30, amountYuan: 112500, source: 'lingniu_report', verifyStatus: 'verified' },
],
},
],
},
],
},
{
date: '2026-07-29',
shortDate: '07-29',
unitPrice: 30,
quantityKg: 3450.0,
amountYuan: 103500.0,
momPct: 15.8,
stations: [
{
stationId: 'st-hz',
stationName: '杭州临安加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3450.0,
amountYuan: 103500.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2450.0,
amountYuan: 73500.0,
vehicles: [
{ id: 'v-1501', time: '13:00', plateNo: '浙A66666F', fleetCategory: 'own', quantityKg: 2450.0, unitPrice: 30, amountYuan: 73500, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-qy',
customerName: '广东清运科技有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-1502', time: '17:40', plateNo: '浙A99111D', fleetCategory: 'external', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-07-28',
shortDate: '07-28',
unitPrice: 30,
quantityKg: 2980.2,
amountYuan: 89406.0,
momPct: -4.5,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2980.2,
amountYuan: 89406.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2980.2,
amountYuan: 89406.0,
vehicles: [
{ id: 'v-1601', time: '15:10', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 2980.2, unitPrice: 30, amountYuan: 89406, source: 'lingniu_report', verifyStatus: 'verified' },
],
},
],
},
],
},
{
date: '2026-07-27',
shortDate: '07-27',
unitPrice: 30,
quantityKg: 3120.0,
amountYuan: 93600.0,
momPct: 33.3,
stations: [
{
stationId: 'st-sh',
stationName: '上海金山加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 3120.0,
amountYuan: 93600.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2120.0,
amountYuan: 63600.0,
vehicles: [
{ id: 'v-1701', time: '11:00', plateNo: '沪A88111F', fleetCategory: 'own', quantityKg: 2120.0, unitPrice: 30, amountYuan: 63600, source: 'api', verifyStatus: 'verified' },
],
},
{
customerId: 'c-dp',
customerName: '东展供应链(广州)有限公司',
quantityKg: 1000.0,
amountYuan: 30000.0,
vehicles: [
{ id: 'v-1702', time: '16:20', plateNo: null, fleetCategory: 'external', quantityKg: 1000.0, unitPrice: 30, amountYuan: 30000, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
{
date: '2026-07-26',
shortDate: '07-26',
unitPrice: 30,
quantityKg: 2340.5,
amountYuan: 70215.0,
momPct: -36.5,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2340.5,
amountYuan: 70215.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2340.5,
amountYuan: 70215.0,
vehicles: [
{ id: 'v-1801', time: '14:20', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 2340.5, unitPrice: 30, amountYuan: 70215, source: 'api', verifyStatus: 'verified' },
],
},
],
},
],
},
{
date: '2026-07-25',
shortDate: '07-25',
unitPrice: 30,
quantityKg: 3683.0, // 峰值
amountYuan: 110490.0,
momPct: null,
stations: [
{
stationId: 'st-jx',
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 2183.0,
amountYuan: 65490.0,
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
quantityKg: 2183.0,
amountYuan: 65490.0,
vehicles: [
{ id: 'v-1901', time: '09:30', plateNo: '浙A88888F', fleetCategory: 'own', quantityKg: 2183.0, unitPrice: 30, amountYuan: 65490, source: 'api', verifyStatus: 'verified' },
],
},
],
},
{
stationId: 'st-jj',
stationName: '嘉兴嘉锦加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: 1500.0,
amountYuan: 45000.0,
customers: [
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
quantityKg: 1500.0,
amountYuan: 45000.0,
vehicles: [
{ id: 'v-1902', time: '16:00', plateNo: '粤B12345D', fleetCategory: 'external', quantityKg: 1500.0, unitPrice: 30, amountYuan: 45000, source: 'station_report', verifyStatus: null },
],
},
],
},
],
},
];
/** 根据任意规范化开始与结束日期 (YYYY-MM-DD) 动态生成完整区间内的 DailyItem 列表 */
export function getDailyDataForRange(normStartStr: string, normEndStr: string): DailyItem[] {
if (!normStartStr || !normEndStr) return MOCK_DAILY_15DAYS;
const startParts = normStartStr.split('-').map(Number);
const endParts = normEndStr.split('-').map(Number);
if (startParts.length !== 3 || endParts.length !== 3) {
return MOCK_DAILY_15DAYS;
}
const start = new Date(startParts[0], startParts[1] - 1, startParts[2]);
const end = new Date(endParts[0], endParts[1] - 1, endParts[2]);
if (isNaN(start.getTime()) || isNaN(end.getTime()) || start > end) {
return MOCK_DAILY_15DAYS;
}
// 限制最大时间跨度 180 天,保证性能
const diffTime = Math.abs(end.getTime() - start.getTime());
const diffDays = Math.min(180, Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1);
const existingMap = new Map<string, DailyItem>();
MOCK_DAILY_15DAYS.forEach((item) => existingMap.set(item.date, item));
const result: DailyItem[] = [];
for (let i = 0; i < diffDays; i++) {
const d = new Date(end.getTime() - i * (1000 * 60 * 60 * 24));
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
const dateStr = `${yyyy}-${mm}-${dd}`;
const shortDate = `${mm}-${dd}`;
if (existingMap.has(dateStr)) {
result.push(existingMap.get(dateStr)!);
} else {
// 稳定拟真生成算法
const seed = yyyy * 10000 + Number(mm) * 100 + Number(dd);
const baseVal = 2200 + (seed % 1400) + (seed % 9) * 60;
const ownKg = Math.round(baseVal * 0.62 * 10) / 10;
const extKg = Math.round(baseVal * 0.38 * 10) / 10;
const totalKg = Math.round((ownKg + extKg) * 10) / 10;
result.push({
date: dateStr,
shortDate,
unitPrice: 30,
quantityKg: totalKg,
amountYuan: Math.round(totalKg * 30 * 10) / 10,
momPct: Math.round(((seed % 24) - 12) * 10) / 10,
stations: [
{
stationId: `st-jx-${dateStr}`,
stationName: '嘉兴中石化滨海加氢站',
stationType: 'self_use',
unitPrice: 30,
quantityKg: ownKg,
amountYuan: Math.round(ownKg * 30),
prechargeBalance: 128500 + (seed % 4000),
customers: [
{
customerId: 'c-ln',
customerName: '羚牛氢能科技(广东)有限公司',
customerCategory: 'internal',
quantityKg: ownKg,
amountYuan: Math.round(ownKg * 30),
vehicles: [
{
id: `v-gen1-${dateStr}`,
time: '08:30',
plateNo: `浙A${(seed % 89999) + 10000}F`,
fleetCategory: 'own',
quantityKg: Math.round(ownKg * 0.65 * 10) / 10,
unitPrice: 30,
amountYuan: Math.round(ownKg * 0.65 * 30),
source: 'api',
verifyStatus: 'verified',
},
{
id: `v-gen2-${dateStr}`,
time: '14:20',
plateNo: `浙A${(seed % 79999) + 10000}F`,
fleetCategory: 'own',
quantityKg: Math.round(ownKg * 0.35 * 10) / 10,
unitPrice: 30,
amountYuan: Math.round(ownKg * 0.35 * 30),
source: 'station_report',
verifyStatus: seed % 2 === 0 ? 'verified' : 'unverified',
},
],
},
],
},
{
stationId: `st-fs-${dateStr}`,
stationName: '佛山南海加氢站',
stationType: 'external_sale',
unitPrice: 35,
quantityKg: extKg,
amountYuan: Math.round(extKg * 35),
prechargeBalance: 92000 + (seed % 3000),
customers: [
{
customerId: 'c-qd',
customerName: '广东氢动力科技服务有限公司',
customerCategory: 'external',
quantityKg: extKg,
amountYuan: Math.round(extKg * 35),
vehicles: [
{
id: `v-gen3-${dateStr}`,
time: '10:15',
plateNo: `粤B${(seed % 89999) + 10000}D`,
fleetCategory: 'external',
quantityKg: Math.round(extKg * 0.7 * 10) / 10,
unitPrice: 35,
amountYuan: Math.round(extKg * 0.7 * 35),
source: 'api',
verifyStatus: null,
},
{
id: `v-gen4-${dateStr}`,
time: '16:40',
plateNo: null,
fleetCategory: 'external',
quantityKg: Math.round(extKg * 0.3 * 10) / 10,
unitPrice: 35,
amountYuan: Math.round(extKg * 0.3 * 35),
source: 'station_report',
verifyStatus: null,
},
],
},
],
},
],
});
}
}
return result;
}
/** 根据车辆归属类型 ('all' | 'own' | 'external') 过滤并重新层层汇总 DailyItem 列表 */
export function filterDailyDataByFleet(
items: DailyItem[],
fleetFilter: FleetCategoryFilter,
): DailyItem[] {
if (fleetFilter === 'all') {
return items;
}
const result: DailyItem[] = [];
for (const day of items) {
const newStations: DailyStationDetail[] = [];
for (const st of day.stations) {
const newCustomers: CustomerDetail[] = [];
for (const cust of st.customers) {
// 过滤出符合 fleetFilter 的车辆明细
const filteredVehicles = (cust.vehicles || []).filter(
(v) => v.fleetCategory === fleetFilter,
);
if (filteredVehicles.length > 0) {
const custQty = filteredVehicles.reduce((sum, v) => sum + v.quantityKg, 0);
const custAmount = filteredVehicles.reduce((sum, v) => sum + v.amountYuan, 0);
newCustomers.push({
...cust,
quantityKg: Math.round(custQty * 100) / 100,
amountYuan: Math.round(custAmount * 100) / 100,
vehicles: filteredVehicles,
});
}
}
if (newCustomers.length > 0) {
const stQty = newCustomers.reduce((sum, c) => sum + c.quantityKg, 0);
const stAmount = newCustomers.reduce((sum, c) => sum + c.amountYuan, 0);
newStations.push({
...st,
quantityKg: Math.round(stQty * 100) / 100,
amountYuan: Math.round(stAmount * 100) / 100,
customers: newCustomers,
});
}
}
if (newStations.length > 0) {
const dayQty = newStations.reduce((sum, s) => sum + s.quantityKg, 0);
const dayAmount = newStations.reduce((sum, s) => sum + s.amountYuan, 0);
result.push({
...day,
quantityKg: Math.round(dayQty * 100) / 100,
amountYuan: Math.round(dayAmount * 100) / 100,
stations: newStations,
});
}
}
// 重新计算动态环比
for (let i = 0; i < result.length; i++) {
const current = result[i];
const prev = result[i + 1]; // items 是按日期倒序
if (prev && prev.quantityKg > 0) {
const pct = ((current.quantityKg - prev.quantityKg) / prev.quantityKg) * 100;
current.momPct = Math.round(pct * 10) / 10;
} else {
current.momPct = null;
}
}
return result;
}
/** 动态计算 Filter 后的 KPI 汇总数据 */
export function calculateDailyKpis(filteredItems: DailyItem[], fleetFilter: FleetCategoryFilter) {
const totalQuantityKg = Math.round(
filteredItems.reduce((acc, item) => acc + item.quantityKg, 0) * 10,
) / 10;
// 统计内部车辆与外部车辆各自的加氢量
let ownKg = 0;
let extKg = 0;
filteredItems.forEach((day) => {
day.stations.forEach((st) => {
st.customers.forEach((cust) => {
cust.vehicles.forEach((vh) => {
if (vh.fleetCategory === 'own') {
ownKg += vh.quantityKg;
} else {
extKg += vh.quantityKg;
}
});
});
});
});
ownKg = Math.round(ownKg * 10) / 10;
extKg = Math.round(extKg * 10) / 10;
let fleetTypeLabel = '全部车辆';
let fleetSubLabel = `内部 ${ownKg.toLocaleString('zh-CN')}Kg · 外部 ${extKg.toLocaleString('zh-CN')}Kg`;
if (fleetFilter === 'own') {
fleetTypeLabel = '羚牛车辆';
fleetSubLabel = '内部车辆归属口径';
} else if (fleetFilter === 'external') {
fleetTypeLabel = '外部车辆';
fleetSubLabel = '外部车辆归属口径';
}
const activeDaysCount = filteredItems.length;
const activeDaysStr = `${activeDaysCount} 天`;
const dailyAvgKgNum = activeDaysCount > 0 ? Math.round((totalQuantityKg / activeDaysCount) * 10) / 10 : 0;
const dailyAvgKgStr = `${dailyAvgKgNum.toLocaleString('zh-CN')} Kg`;
// 站点去重统计
const stationSet = new Set<string>();
filteredItems.forEach((d) => d.stations.forEach((s) => stationSet.add(s.stationId)));
const stationCount = stationSet.size;
// 峰值日与低谷日
let peakItem: DailyItem | null = null;
let troughItem: DailyItem | null = null;
filteredItems.forEach((item) => {
if (!peakItem || item.quantityKg > peakItem.quantityKg) {
peakItem = item;
}
if (!troughItem || item.quantityKg < troughItem.quantityKg) {
troughItem = item;
}
});
const peakDayLabel = peakItem
? `${(peakItem as DailyItem).shortDate} · ${Math.round((peakItem as DailyItem).quantityKg).toLocaleString('zh-CN')}`
: '-';
const troughDayLabel = troughItem
? `${(troughItem as DailyItem).shortDate} · ${Math.round((troughItem as DailyItem).quantityKg).toLocaleString('zh-CN')}`
: '-';
const dateRange = filteredItems.length > 0
? `${filteredItems[filteredItems.length - 1].date}${filteredItems[0].date}`
: '无数据';
return {
totalQuantityKg,
dateRange,
fleetTypeLabel,
fleetSubLabel,
ownKg,
extKg,
activeDays: activeDaysStr,
dailyAvgKg: dailyAvgKgStr,
dailyAvgKgNum,
stationCount,
peakDayLabel,
troughDayLabel,
zeroDaysCount: 0,
};
}