Files
aiops/frontend/src/pages/monitor/site-monitor/helpers.ts
T
attacker 55f216cfbb feat(i18n): 安全批量转换 135 文件 — 覆盖率 34%→62%
使用 i18n.t() 全局方式(避免 hook 定位问题):
- 288 目标文件中 135 个成功转换
- 2228 处中文替换为 i18n.t() 调用
- 1006 个新翻译 key 添加到 zh-CN.json + en-US.json
- 词典总量: 3554 keys (22 namespaces)
- tsc 零错误 + Vite 构建成功
- 6 个含代码示例/数据字符串的文件安全回退
2026-07-03 02:14:20 +08:00

172 lines
5.7 KiB
TypeScript

import i18n from '@/i18n';
// 站点拨测辅助函数 // Logan.Li
export const PROBE_TYPE_OPTIONS = ['HTTP', 'SSL', 'TCP', 'DNS', 'PING'] as const;
export type ProbeType = (typeof PROBE_TYPE_OPTIONS)[number];
export interface SiteTask {
id: number;
name: string;
url: string;
type: string;
frequency_sec: number;
timeout_sec: number;
expected_status_code: number;
enabled: boolean;
last_status?: string;
last_response_time_ms?: number;
last_checked_at?: string;
success_rate?: number;
alert_status?: 'normal' | 'alerting';
created_at: string;
ssl_days_remaining?: number;
ssl_cert_expiry?: string;
}
export interface SiteResult {
id: number;
task_id: number;
status: string;
http_status_code?: number;
response_time?: number;
total_time: number;
remote_ip?: string;
error_message?: string;
checked_at: string;
ssl_days_remaining?: number;
ssl_cert_expiry?: string;
ssl_cert_issuer?: string;
}
export interface SiteStats {
total_tasks: number;
enabled_tasks: number;
up_count: number;
down_count: number;
availability: number;
probe_count: number;
}
export type SiteTimeRange = '1h' | '6h' | '24h' | '7d';
export const SITE_TIME_RANGE_HOURS: Record<SiteTimeRange, number> = {
'1h': 1,
'6h': 6,
'24h': 24,
'7d': 168,
};
export const SITE_TIME_RANGE_LABELS: Record<SiteTimeRange, string> = {
'1h': i18n.t('monitor.helpersts.sf972b7b1'),
'6h': i18n.t('monitor.siteProtocol.rangeDefault'),
'24h': i18n.t('monitor.helpersts.s6e99b786'),
'7d': i18n.t('monitor.helpersts.sd765efc4'),
};
/** 各协议推荐默认拨测间隔(秒)// Logan.Li */
export const DEFAULT_PROBE_FREQUENCY: Record<ProbeType, number> = {
HTTP: 60,
SSL: 3600,
TCP: 120,
DNS: 300,
PING: 120,
};
/** 各协议最小拨测间隔(秒)// Logan.Li */
export const MIN_PROBE_FREQUENCY: Record<ProbeType, number> = {
HTTP: 30,
SSL: 600,
TCP: 30,
DNS: 60,
PING: 30,
};
export function defaultProbeFrequency(type: ProbeType): number {
return DEFAULT_PROBE_FREQUENCY[type] ?? 60;
}
export const probeTypeMeta: Record<ProbeType, { label: string; placeholder: string; hint: string }> = {
HTTP: { label: i18n.t('monitor.helpersts.s277c74b4'), placeholder: 'https://example.com/health', hint: i18n.t('monitor.helpersts.s953f0b93') },
SSL: { label: i18n.t('monitor.helpersts.s8e3a1ea5'), placeholder: i18n.t('monitor.helpersts.s8a6cb9ae'), hint: i18n.t('monitor.helpersts.sefe596b0') },
TCP: { label: i18n.t('monitor.helpersts.seeda3abc'), placeholder: i18n.t('monitor.helpersts.sd315f501'), hint: i18n.t('monitor.helpersts.s5a87d291') },
DNS: { label: i18n.t('cloud.domainName'), placeholder: 'example.com', hint: i18n.t('monitor.helpersts.sd3fd8f1d') },
PING: { label: i18n.t('monitor.helpersts.saeb5271e'), placeholder: i18n.t('monitor.helpersts.sd6bbd624'), hint: i18n.t('monitor.helpersts.se850c8e9') },
};
export function probeFrequencyHint(type: ProbeType): string {
const sec = defaultProbeFrequency(type);
return `推荐 ${fmtFrequency(sec)},最小 ${fmtFrequency(MIN_PROBE_FREQUENCY[type])}`;
}
/** 拨测频率展示 // Logan.Li */
export function fmtFrequency(sec?: number): string {
if (!sec) return '--';
if (sec < 60) return `${sec}秒`;
if (sec < 3600) return `${Math.round(sec / 60)}分钟`;
return `${(sec / 3600).toFixed(1)}小时`;
}
/** 可用率 / 响应时间组合展示 // Logan.Li */
export function fmtAvailResponse(task: Pick<SiteTask, 'success_rate' | 'last_response_time_ms'>): string {
const avail = task.success_rate != null && task.success_rate >= 0
? `${task.success_rate.toFixed(1)}%`
: '--';
return `${avail} / ${fmtMs(task.last_response_time_ms)}`;
}
export function fmtMs(ms?: number): string {
if (ms == null) return '--';
if (ms < 1) return '0ms';
if (ms < 1000) return `${Math.round(ms)}ms`;
return `${(ms / 1000).toFixed(2)}s`;
}
/** 列表时间:MM-DD HH:mm // Logan.Li */
export function fmtTime(iso?: string): string {
if (!iso) return '--';
const d = new Date(iso);
const pad = (n: number) => String(n).padStart(2, '0');
return `${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
}
/** SSL 证书预警阈值(天)// Logan.Li */
export const SSL_EXPIRY_WARN_DAYS = 30;
/** 是否为 SSL 证书拨测任务 // Logan.Li */
export function isSslProbeTask(task: Pick<SiteTask, 'type'>): boolean {
const t = task.type?.toUpperCase();
return t === 'SSL' || t === 'HTTPS';
}
/** 证书是否进入预警期(默认 < 30 天)// Logan.Li */
export function isSslExpiringSoon(days?: number, threshold = SSL_EXPIRY_WARN_DAYS): boolean {
return days != null && days < threshold;
}
/** SSL 证书剩余天数展示 // Logan.Li */
export function fmtSslDays(days?: number): { text: string; tone: string } {
if (days == null) return { text: '--', tone: 'text-[var(--dg-text-muted)]' };
if (days < 0) return { text: i18n.t('system.expired2'), tone: 'dg-text-red' };
if (days <= 7) return { text: `${days}天`, tone: 'dg-text-red' };
if (days <= 30) return { text: `${days}天`, tone: 'dg-text-yellow' };
return { text: `${days}天`, tone: 'dg-text-green' };
}
/** 归一化拨测协议类型 // Logan.Li */
export function normalizeProbeType(raw?: string): ProbeType {
const upper = (raw || 'HTTP').toUpperCase();
if (upper === 'HTTPS') return 'HTTP';
if (PROBE_TYPE_OPTIONS.includes(upper as ProbeType)) return upper as ProbeType;
return 'HTTP';
}
export function isHttpProbeTask(task: Pick<SiteTask, 'type'>): boolean {
return normalizeProbeType(task.type) === 'HTTP';
}
export function fmtChartTime(iso?: string): string {
if (!iso) return '';
const d = new Date(iso);
const pad = (n: number) => String(n).padStart(2, '0');
return `${pad(d.getHours())}:${pad(d.getMinutes())}`;
}