refactor(i18n): U28 多模块 phantom key 清零 — theme/middleware-monitor/site-monitor/analytics/cost-predict/predict-types/agentAlertHelper/export-audit/AgentCLIMessages/copy-button 10 文件 74 phantom key → 语义化键, 新增 4 命名空间 (theme/agent.alerts.metric*/audit.*) + 扩展 3 命名空间 (monitor.lbl.mw*/site*/aiops.predict*), zh/en 7294→7358 +64 键对齐, phantom key 103→29 (残留全为 JSX 模板表达式/ANSI 转义码误匹配), tsc -b=0, npm build✓ (17.40s), ESLint=0/53/0, go build=0, 17/17 测试通过
This commit is contained in:
1 parent
b812b3b20c
commit
b2715ca3bd
12 files changed
+206
-74
No files matched your search
@@ -13,12 +13,12 @@ export const METRIC_OPTIONS = [
|
||||
{ value: 'cpu_iowait', label: i18n.t('agent.alertHelper.netInBps'), icon: Cpu },
|
||||
{ value: 'mem', label: i18n.t('kubernetes.cluster.memoryUsage'), icon: MemoryStick },
|
||||
{ value: 'mem_available', label: i18n.t('agent.alertHelper.memAvailable'), icon: MemoryStick },
|
||||
{ value: 'swap', label: i18n.t('Swap 使用率'), icon: MemoryStick },
|
||||
{ value: 'load1', label: i18n.t('1分钟负载'), icon: Gauge },
|
||||
{ value: 'swap', label: i18n.t('agent.alerts.metricSwap'), icon: MemoryStick },
|
||||
{ value: 'load1', label: i18n.t('agent.alerts.metricLoad1'), icon: Gauge },
|
||||
{ value: 'disk', label: i18n.t('monitor.hostDisk'), icon: HardDrive },
|
||||
{ value: 'disk_inode', label: i18n.t('Inode 使用率'), icon: HardDrive },
|
||||
{ value: 'disk_inode', label: i18n.t('agent.alerts.metricInode'), icon: HardDrive },
|
||||
{ value: 'disk_io_util', label: i18n.t('agent.alertHelper.diskIOUtil'), icon: HardDrive },
|
||||
{ value: 'tcp_established', label: i18n.t('TCP 已建立'), icon: Network },
|
||||
{ value: 'tcp_established', label: i18n.t('agent.alerts.metricTcpEst'), icon: Network },
|
||||
{ value: 'tcp_time_wait', label: 'TCP TIME_WAIT', icon: Network },
|
||||
{ value: 'tcp_close_wait', label: 'TCP CLOSE_WAIT', icon: Network },
|
||||
{ value: 'net_rx_bps', label: i18n.t('monitor.hostNetIn'), icon: Network },
|
||||
|
||||
@@ -253,7 +253,7 @@ export function MessageView({ item, inRoundGroup = false }: { item: ChatItem; in
|
||||
return (
|
||||
<div className="flex gap-2 rounded-lg bg-red-500/10 border border-red-500/30 p-3">
|
||||
<AlertTriangle className="w-5 h-5 dg-text-red shrink-0 mt-0.5" />
|
||||
<div className="text-sm text-[var(--dg-text-primary)] whitespace-pre-wrap">{item.content || i18n.t('发生错误')}</div>
|
||||
<div className="text-sm text-[var(--dg-text-primary)] whitespace-pre-wrap">{item.content || i18n.t('aiops.agentCliErrorOccurred')}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -309,10 +309,10 @@ function ToolBlock({ item, inRoundGroup }: { item: ChatItem; inRoundGroup?: bool
|
||||
{item.duration && <div className="text-[10px] dg-text-muted">{i18n.t('aiops.durationLabel', { duration: item.duration })}</div>}
|
||||
{(item.toolName === 'analyze_output' || looksLikeMarkdown(item.output)) ? (
|
||||
<div className="bg-[var(--dg-bg-primary)]/40 rounded px-2 py-1.5 max-h-80 overflow-y-auto">
|
||||
<AgentMarkdown content={item.output || i18n.t('(无输出)')} />
|
||||
<AgentMarkdown content={item.output || i18n.t('aiops.agentCliNoOutput')} />
|
||||
</div>
|
||||
) : (
|
||||
<pre className="text-xs text-[var(--dg-text-secondary)] bg-[var(--dg-bg-primary)]/40 rounded px-2 py-1.5 overflow-x-auto max-h-80 whitespace-pre-wrap">{item.output || i18n.t('(无输出)')}</pre>
|
||||
<pre className="text-xs text-[var(--dg-text-secondary)] bg-[var(--dg-bg-primary)]/40 rounded px-2 py-1.5 overflow-x-auto max-h-80 whitespace-pre-wrap">{item.output || i18n.t('aiops.agentCliNoOutput')}</pre>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -83,15 +83,15 @@ function costTrendFromSlope(slope: number): 'up' | 'down' | 'stable' {
|
||||
/** 成本优化建议 */
|
||||
export function costRecommendation(trend: 'up' | 'down' | 'stable', ratio: number): string {
|
||||
if (trend === 'up' && ratio >= 0.85) {
|
||||
return i18n.t('排查内存泄漏,优化进程内存配置,考虑增加节点');
|
||||
return i18n.t('aiops.predictMemLeak');
|
||||
}
|
||||
if (trend === 'up') {
|
||||
return i18n.t('排查内存泄漏,优化进程内存配置,考虑增加节点');
|
||||
return i18n.t('aiops.predictMemLeak');
|
||||
}
|
||||
if (trend === 'down') {
|
||||
return i18n.t('排查内存泄漏,优化进程内存配置,考虑增加节点');
|
||||
return i18n.t('aiops.predictMemLeak');
|
||||
}
|
||||
return i18n.t('你是 AIOps 容量规划专家。基于以下服务器资源容量预测数据,给出综合风险评估与可执行的运维建议:');
|
||||
return i18n.t('aiops.predictutilsts.sa3b5c7d9');
|
||||
}
|
||||
|
||||
/** 预算风险建议 */
|
||||
@@ -256,7 +256,7 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
|
||||
const allRatio =
|
||||
summary.predictedMonthEnd > 0 ? summary.monthCost / summary.predictedMonthEnd : 0;
|
||||
dimensionForecasts.push({
|
||||
dimension: i18n.t('清理历史数据和日志,实施数据归档策略,扩容磁盘'),
|
||||
dimension: i18n.t('aiops.predictDiskFull'),
|
||||
currentMonth: summary.monthCost,
|
||||
predictedMonthEnd: summary.predictedMonthEnd,
|
||||
dailyAvg: summary.dailyAvg,
|
||||
@@ -302,7 +302,7 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
|
||||
|
||||
const metric = (rule.metric === 'daily' ? 'daily' : 'monthly') as 'daily' | 'monthly';
|
||||
const ruleProvider = String(rule.provider || '');
|
||||
const providerLabel = ruleProvider ? PROVIDER_LABELS[ruleProvider] || ruleProvider : i18n.t('24小时后');
|
||||
const providerLabel = ruleProvider ? PROVIDER_LABELS[ruleProvider] || ruleProvider : i18n.t('aiops.predictIn24h');
|
||||
|
||||
let current = 0;
|
||||
let predicted = 0;
|
||||
@@ -339,7 +339,7 @@ export function computeCostPredictions(input: ComputeCostPredictionsInput): Comp
|
||||
if (current >= threshold) probability += 25;
|
||||
probability = Math.max(5, Math.min(92, probability));
|
||||
|
||||
let timeframe = metric === 'daily' ? i18n.t('未来24小时') : i18n.t('aiops.predictutilsts.sd4e5f6g7');
|
||||
let timeframe = metric === 'daily' ? i18n.t('aiops.predictNext24h') : i18n.t('aiops.predictutilsts.sd4e5f6g7');
|
||||
if (slope > 0.01 && threshold > current) {
|
||||
const days = (threshold - current) / slope;
|
||||
if (days < 1) timeframe = metric === 'daily' ? i18n.t('aiops.predictutilsts.se5f6g7h8') : i18n.t('aiops.predictutilsts.sf6g7h8i9');
|
||||
|
||||
@@ -120,16 +120,16 @@ export interface ComputeCostPredictionsInput {
|
||||
|
||||
/** 指标定义:后端 metric name → 展示标签 / 告警表达式前缀 / 阈值 */
|
||||
export const METRIC_DEFS = [
|
||||
{ key: 'cpu', label: i18n.t('CPU使用率'), exprKey: 'cpu_usage', threshold: 85 },
|
||||
{ key: 'cpu', label: i18n.t('aiops.predictCpuUsage'), exprKey: 'cpu_usage', threshold: 85 },
|
||||
{ key: 'memory', label: i18n.t('aiops.predictTypes.memUsage'), exprKey: 'memory_usage', threshold: 85 },
|
||||
{ key: 'disk', label: i18n.t('aiops.predictTypes.diskUsage'), exprKey: 'disk_usage', threshold: 90 },
|
||||
] as const;
|
||||
|
||||
export const TIME_RANGE_LABELS: Record<string, string> = {
|
||||
'1h': i18n.t('1小时后'),
|
||||
'24h': i18n.t('24小时后'),
|
||||
'7d': i18n.t('7天后'),
|
||||
'30d': i18n.t('30天后'),
|
||||
'1h': i18n.t('aiops.predictIn1h'),
|
||||
'24h': i18n.t('aiops.predictIn24h'),
|
||||
'7d': i18n.t('aiops.predictIn7d'),
|
||||
'30d': i18n.t('aiops.predictIn30d'),
|
||||
};
|
||||
|
||||
export const TIME_RANGE_HOURS: Record<string, number> = {
|
||||
|
||||
@@ -23,7 +23,7 @@ function escapeCsv(s: string): string {
|
||||
// exportAuditReportCsv 导出会话审计报告 CSV // Logan.Li
|
||||
export function exportAuditReportCsv(meta: ReplaySessionMeta, commands: CommandBookmark[]) {
|
||||
const lines: string[] = [
|
||||
i18n.t('# 终端会话审计报告'),
|
||||
i18n.t('audit.reportTitle'),
|
||||
`会话ID,${meta.id}`,
|
||||
`用户,${escapeCsv(meta.username || '')}`,
|
||||
`目标主机,${escapeCsv(meta.server_name || '')}`,
|
||||
@@ -33,7 +33,7 @@ export function exportAuditReportCsv(meta: ReplaySessionMeta, commands: CommandB
|
||||
`时长(秒),${meta.duration || 0}`,
|
||||
`录制大小,${meta.record_size || 0}`,
|
||||
'',
|
||||
i18n.t('# 终端会话审计报告'),
|
||||
i18n.t('audit.reportTitle'),
|
||||
];
|
||||
for (const c of commands) {
|
||||
lines.push(`${c.label},${escapeCsv(c.command)},${c.highRisk ? '是' : '否'}`);
|
||||
@@ -55,7 +55,7 @@ export interface CommandExportRow {
|
||||
|
||||
// exportCommandsListCsv 导出命令列表 CSV // Logan.Li
|
||||
export function exportCommandsListCsv(commands: CommandExportRow[]) {
|
||||
const lines: string[] = [i18n.t('时间,用户,命令,输出大小,会话ID,高危')];
|
||||
const lines: string[] = [i18n.t('audit.csvHeader')];
|
||||
for (const c of commands) {
|
||||
const ts = c.timestamp || c.created_at || '';
|
||||
const highRisk = isHighRiskCommand(c.command || '');
|
||||
|
||||
@@ -42,7 +42,7 @@ export function CopyButton({
|
||||
} else {
|
||||
toast({
|
||||
title: i18n.t('monitor.logPanel.copyFailed'),
|
||||
description: i18n.t('请手动选中内容后复制'),
|
||||
description: i18n.t('common.copyManually'),
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user