18 文件 ~35 处 UI 硬编码中文→t()/i18n.t() 调用: - agent-utils.ts timeAgo() 秒前/分钟前/小时前 - utils.ts formatDistanceToNow() 分钟前/小时前/天前 - request.ts 响应解析失败错误消息 - ActiveSessionsPanel/HistorySessionsPanel RDP 在线/历史会话标签 - MetricsExplorer 清除/已选/最近1小时 - HostMonitor 当前主机 subtitle - AIAnalysisResult 证据链 (新增 useTranslation hook) - capacity-predict.ts 容量预测摘要模板 - ApprovalResourcePage 阿里云/腾讯云/华为云 - ApprovalPermissionPage 堡垒机 - site-monitor/helpers.ts 频率/时间/证书天数格式化 - site-monitor/analytics.ts 证书剩余/检查失败/延迟波动事件 - middleware-monitor MwTargetChartsPanel/MwTrendChart/helpers.ts - snmp-monitor SnmpMetricTrendChart/SnmpDeviceChartsPanel - host-monitor/utils.ts 图表点数标签 + PortPolicyDialog 系统进程说明 新增 34 翻译键 (common.duration.secAgo/hourAgo/dayAgo + common.selected/ responseParseError/rdpActiveSessions/rdpHistorySessions/rdpSessionCount/ evidenceChain/last1Hour/currentHost + monitor.lbl 10键 + monitor.siteMonitor 8键 + approval.provider 3键 + approval.permType 1键 + monitor.portPolicyDialog.systemProcessDesc + aiops.capacity.summary) zh/en 7813→7847 对齐; tsc -b=0, npm build✓ (17.31s), ESLint=0/43/any=0, go build=0, 17/17 测试通过
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import type { JsonData } from "@/types/common";
|
||
import i18n from "@/i18n";
|
||
// Agent 监控相关工具函数(供组件与 API 层共享) // Logan.Li
|
||
|
||
/** 在线判定:3 分钟内有上报视为在线 */
|
||
export function isOnline(lastReport: unknown): boolean {
|
||
if (!lastReport) return false;
|
||
const t = new Date(lastReport as string | number | Date).getTime();
|
||
if (Number.isNaN(t)) return false;
|
||
return Date.now() - t < 3 * 60 * 1000;
|
||
}
|
||
|
||
/** 相对时间格式化("3分钟前" / "2小时前") */
|
||
export function timeAgo(ts: unknown): string {
|
||
if (!ts) return '--';
|
||
const t = new Date(ts as string | number | Date).getTime();
|
||
if (Number.isNaN(t)) return '--';
|
||
const diff = Math.floor((Date.now() - t) / 1000);
|
||
if (diff < 60) return i18n.t('common.duration.secAgo', { count: diff });
|
||
if (diff < 3600) return i18n.t('common.duration.minAgo', { count: Math.floor(diff / 60) });
|
||
if (diff < 86400) return i18n.t('common.duration.hourAgo', { count: Math.floor(diff / 3600) });
|
||
return new Date(ts as string | number | Date).toLocaleString();
|
||
}
|
||
|
||
/** 兼容多种列表响应包装:数组 / {list} / {items} / {data} */
|
||
|
||
export function asList(data: JsonData): JsonData[] {
|
||
if (!data) return [];
|
||
if (Array.isArray(data)) return data;
|
||
if (Array.isArray(data.list)) return data.list;
|
||
if (Array.isArray(data.items)) return data.items;
|
||
if (Array.isArray(data.data)) return data.data;
|
||
return [];
|
||
} |