import type { AccessProtocolThreshold, AccessThresholdConfig, AccessVehicleRow } from '../../api/types'; const accessTimeFormatter = new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); export const accessStateLabels: Record = { online: '在线', offline: '离线', never_reported: '从未上报', unknown: '未知' }; export function formatSeconds(value: number | null | undefined) { if (value === null || value === undefined || !Number.isFinite(value)) return '—'; const sign = value < 0 ? '-' : ''; const seconds = Math.abs(Math.round(value)); if (seconds < 60) return `${sign}${seconds} 秒`; if (seconds < 3600) return `${sign}${Math.floor(seconds / 60)} 分 ${seconds % 60} 秒`; const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); return `${sign}${hours} 小时${minutes ? ` ${minutes} 分` : ''}`; } export function formatAccessTime(value: string) { if (!value) return '—'; const parsed = new Date(value); if (Number.isNaN(parsed.getTime())) return '—'; return accessTimeFormatter.format(parsed).replace(/\//g, '-'); } export function thresholdForProtocol(config: AccessThresholdConfig, protocol: string) { return config.protocols.find((item) => item.protocol === protocol)?.thresholdSec ?? config.defaultThresholdSec; } export function updateProtocolThreshold(items: AccessProtocolThreshold[], protocol: string, thresholdSec: number) { const next = items.filter((item) => item.protocol !== protocol); next.push({ protocol, thresholdSec }); return next.sort((a, b) => a.protocol.localeCompare(b.protocol)); } export function accessRowsToCSV(rows: AccessVehicleRow[]) { const protocolColumns = ['GB32960', 'JT808', 'YUTONG_MQTT'].flatMap((protocol) => [`${protocol}接入状态`, `${protocol}接入厂家`, `${protocol}首次接入`, `${protocol}最新上报`, `${protocol}离线秒数`]); const columns = ['综合状态', '车牌', 'VIN', '品牌', '车型', '企业', '真实接入协议', '资料待维护', ...protocolColumns]; const quote = (value: unknown) => `"${String(value ?? '').replace(/"/g, '""')}"`; const lines = rows.map((row) => { const protocolValues = ['GB32960', 'JT808', 'YUTONG_MQTT'].flatMap((protocol) => { const status = row.protocolStatuses.find((item) => item.protocol === protocol); return [status?.connected ? accessStateLabels[status.onlineState] : '无来源', status?.provider, status?.firstSeenAt, status?.latestReceivedAt, status?.freshnessSec]; }); return [row.connectionState, row.plate, row.vin, row.oem, row.model, row.company, row.actualProtocols.join('/'), row.masterDataIssues.join('/'), ...protocolValues].map(quote).join(','); }); return `\uFEFF${columns.map(quote).join(',')}\n${lines.join('\n')}`; }