import { FAULT_WEEKLY_METRICS, type FaultWeeklyQuery, type FaultWeeklyResponse } from '../../../shared/assets/faults.js'; import { faultAnalysis, type ScopedFault } from './model.js'; import { parseFaultTrendQuery } from './trend.js'; export function parseFaultWeeklyQuery(params: Record): FaultWeeklyQuery { const range = parseFaultTrendQuery({ start: params.start, end: params.end, granularity: 'day', period: params.day }); const metric = params.metric || 'reported'; if (!Object.hasOwn(FAULT_WEEKLY_METRICS, metric)) throw new Error('无效周报指标'); return { start: range.start, end: range.end, day: range.period, metric: metric as FaultWeeklyQuery['metric'] }; } function eventDay(row: ScopedFault, metric: FaultWeeklyQuery['metric']) { return (metric === 'reported' ? row.reportedAt : metric === 'received' ? row.receivedAt : row.status === '已归档' ? row.archivedAt : null)?.slice(0, 10); } export function faultWeeklyReport(rows: ScopedFault[], query: FaultWeeklyQuery, updatedAt: string): FaultWeeklyResponse { const days = new Map(); for (let time = Date.parse(query.start); time <= Date.parse(query.end); time += 86400000) { const date = new Date(time).toISOString().slice(0, 10); days.set(date, { date, reported: 0, received: 0, closed: 0 }); } const totals = { reported: 0, received: 0, closed: 0 }; for (const row of rows) for (const metric of Object.keys(FAULT_WEEKLY_METRICS) as FaultWeeklyQuery['metric'][]) { const day = days.get(eventDay(row, metric) || ''); if (day) { day[metric]++; totals[metric]++; } } return { start: query.start, end: query.end, updatedAt, totals, days: [...days.values()] }; } export function faultWeeklyAnalysis(rows: ScopedFault[], query: FaultWeeklyQuery, updatedAt: string) { return faultAnalysis(rows.filter(row => { const date = eventDay(row, query.metric); return date && date >= query.start && date <= query.end && (!query.day || date === query.day); }), 'ledger', updatedAt); }