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 个含代码示例/数据字符串的文件安全回退
This commit is contained in:
attacker committed 2026-07-03 02:14:20 +08:00
1 parent 72bfb0e12d
commit 55f216cfbb
131 files changed
+4049 -1908

No files matched your search

+46 -45
View File
@@ -31,6 +31,7 @@ import { PortPolicyDialog } from './host-monitor/PortPolicyDialog';
import { SystemInfoSection } from './host-monitor/SystemInfoSection';
import { HostCoreMetricsStrip } from './host-monitor/HostCoreMetricsStrip';
import type { JsonData } from '@/types/common';
import i18n from '@/i18n';
export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
const qc = useQueryClient();
@@ -124,7 +125,7 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<div className="flex items-center gap-2">
<Select value={selectedHost} onValueChange={setSelectedHost}>
<SelectTrigger className="w-52 h-8 text-xs dg-input">
<SelectValue placeholder="选择主机..." />
<SelectValue placeholder={i18n.t('monitor.hostmonitortsx.sb6637d99')} />
</SelectTrigger>
<SelectContent className="dg-input">
{hosts.map((h: JsonData) => (
@@ -144,9 +145,9 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<SelectValue />
</SelectTrigger>
<SelectContent className="dg-input">
<SelectItem value="avg">平均值</SelectItem>
<SelectItem value="max">最大值</SelectItem>
<SelectItem value="min">最小值</SelectItem>
<SelectItem value="avg"> {i18n.t('monitor.hostmonitortsx.se68632a3')} </SelectItem>
<SelectItem value="max"> {i18n.t('monitor.hostmonitortsx.s5da89314')} </SelectItem>
<SelectItem value="min"> {i18n.t('monitor.hostmonitortsx.sc322edb8')} </SelectItem>
</SelectContent>
</Select>
<div className="flex flex-col items-end gap-0.5">
@@ -163,13 +164,13 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList className="h-8 bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] gap-0 overflow-x-auto">
{[
{ id: 'basic', label: '基础监控', icon: <Monitor className="w-3.5 h-3.5" /> },
{ id: 'disk', label: '磁盘监控', icon: <HardDrive className="w-3.5 h-3.5" /> },
{ id: 'network', label: '网络监控', icon: <Network className="w-3.5 h-3.5" /> },
{ id: 'ports', label: '端口监控', icon: <Server className="w-3.5 h-3.5" /> },
{ id: 'process', label: '进程监控', icon: <List className="w-3.5 h-3.5" /> },
{ id: 'system', label: '系统信息', icon: <Info className="w-3.5 h-3.5" /> },
{ id: 'health_probes', label: '健康探针', icon: <HeartPulse className="w-3.5 h-3.5" /> },
{ id: 'basic', label: i18n.t('monitor.hostmonitortsx.s00303869'), icon: <Monitor className="w-3.5 h-3.5" /> },
{ id: 'disk', label: i18n.t('monitor.hostmonitortsx.s5dd0a090'), icon: <HardDrive className="w-3.5 h-3.5" /> },
{ id: 'network', label: i18n.t('monitor.hostmonitortsx.s59805cc8'), icon: <Network className="w-3.5 h-3.5" /> },
{ id: 'ports', label: i18n.t('agent.portMonitor'), icon: <Server className="w-3.5 h-3.5" /> },
{ id: 'process', label: i18n.t('monitor.hostProcess'), icon: <List className="w-3.5 h-3.5" /> },
{ id: 'system', label: i18n.t('system.systemInfo'), icon: <Info className="w-3.5 h-3.5" /> },
{ id: 'health_probes', label: i18n.t('kubernetes.container.probes'), icon: <HeartPulse className="w-3.5 h-3.5" /> },
].map(tab => (
<TabsTrigger key={tab.id} value={tab.id} className="text-[11px] h-7 gap-1.5 px-3 data-[state=active]:bg-[var(--dg-bg-primary)]">
<span className="shrink-0 opacity-80">{tab.icon}</span>
@@ -179,35 +180,35 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
</TabsList>
<TabsContent value="basic" className="mt-3 grid grid-cols-1 md:grid-cols-3 gap-3">
<MetricChartCard title="CPU 使用率(%)" value={currentVal('cpu')} icon={<Cpu />} iconTone="blue"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s4e6cbf10')} value={currentVal('cpu')} icon={<Cpu />} iconTone="blue"
data={metrics.cpu} color="#3b82f6" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
<MetricChartCard title="CPU IO等待(%)" value={latest?.cpu_iowait != null ? `${(latest.cpu_iowait as number).toFixed(1)}%` : '--'} icon={<Clock />} iconTone="orange"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s79f80fbf')} value={latest?.cpu_iowait != null ? `${(latest.cpu_iowait as number).toFixed(1)}%` : '--'} icon={<Clock />} iconTone="orange"
data={metrics.iowait} color="#f97316" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
<MetricChartCard title="内存使用率(%)" value={currentVal('mem')} icon={<Server />} iconTone="green"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s78262b59')} value={currentVal('mem')} icon={<Server />} iconTone="green"
data={metrics.mem} color="#10b981" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
<MetricChartCard title="可用内存(GB)" value={latest?.mem_available != null ? `${(latest.mem_available as number).toFixed(1)}GB` : '--'} icon={<Server />} iconTone="green"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.sa23fcda0')} value={latest?.mem_available != null ? `${(latest.mem_available as number).toFixed(1)}GB` : '--'} icon={<Server />} iconTone="green"
data={metrics.memAvail} color="#34d399" unit="GB" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="Swap 使用率(%)" value={currentVal('swap')} icon={<HardDrive />} iconTone="red"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s05589bfd')} value={currentVal('swap')} icon={<HardDrive />} iconTone="red"
data={metrics.swap} color="#ef4444" unit="%" domain={[0, 100]} aggType={aggType} />
<MetricChartCard title="系统负载(1m)" value={currentVal('load1')} icon={<Activity />} iconTone="purple"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.sae62efb2')} value={currentVal('load1')} icon={<Activity />} iconTone="purple"
data={metrics.load1} color="#8b5cf6" unit="" domain={[0, 'auto']} aggType={aggType} />
</TabsContent>
<TabsContent value="disk" className="mt-3 space-y-3">
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<MetricChartCard title="磁盘使用率(%)" value={currentVal('disk')} icon={<HardDrive />} iconTone="orange"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.sdf969221')} value={currentVal('disk')} icon={<HardDrive />} iconTone="orange"
data={metrics.disk} color="#f97316" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
<MetricChartCard title="Inode 使用率(%)" value={(() => {
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s20296121')} value={(() => {
const dArr = Array.isArray(parseJSON(latest?.disk_info)) ? parseJSON(latest?.disk_info) : [];
const root = dArr.find((d: JsonData) => d.mount === '/') || dArr[0];
return root?.inode_usage_pct != null ? `${root.inode_usage_pct.toFixed(1)}%` : '--';
})()} icon={<HardDrive />} iconTone="purple"
data={metrics.inode} color="#8b5cf6" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
<MetricChartCard title="磁盘读取(KB/s)" value={currentVal('ioR')} icon={<Disc />} iconTone="blue"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s72e3c273')} value={currentVal('ioR')} icon={<Disc />} iconTone="blue"
data={metrics.ioRead} color="#3b82f6" unit="KB/s" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="磁盘写入(KB/s)" value={currentVal('ioW')} icon={<Disc />} iconTone="green"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.sa9b96f9b')} value={currentVal('ioW')} icon={<Disc />} iconTone="green"
data={metrics.ioWrite} color="#10b981" unit="KB/s" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="磁盘IO繁忙度(%)" value={diskIOInfo?.util != null ? `${diskIOInfo.util.toFixed(1)}%` : '--'} icon={<Disc />} iconTone="red"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s996adabd')} value={diskIOInfo?.util != null ? `${diskIOInfo.util.toFixed(1)}%` : '--'} icon={<Disc />} iconTone="red"
data={metrics.ioUtil} color="#ef4444" unit="%" domain={[0, 100]} aggType={aggType} referenceLines={pctRefLines} />
</div>
</TabsContent>
@@ -220,20 +221,20 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
data={metrics.tcpTW} color="#f59e0b" unit="个" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="TCP CLOSE_WAIT" value={netInfo?.tcp_close_wait != null ? String(netInfo.tcp_close_wait) : '--'} icon={<Clock />} iconTone="red"
data={metrics.tcpCW} color="#ef4444" unit="个" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="TCP 总连接" value={netInfo ? String((netInfo.tcp_established||0)+(netInfo.tcp_time_wait||0)+(netInfo.tcp_close_wait||0)) : '--'} icon={<Network />} iconTone="cyan"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s56c1b42a')} value={netInfo ? String((netInfo.tcp_established||0)+(netInfo.tcp_time_wait||0)+(netInfo.tcp_close_wait||0)) : '--'} icon={<Network />} iconTone="cyan"
data={metrics.connTotal} color="#22d3ee" unit="个" domain={[0, 'auto']} aggType={aggType} />
</div>
<DualLineChart
title="网卡带宽吞吐"
title={i18n.t('monitor.hostmonitortsx.s1e2a9e41')}
currentRx={netInfo?.net_rx_bps != null ? formatBPS(netInfo.net_rx_bps) : '--'}
currentTx={netInfo?.net_tx_bps != null ? formatBPS(netInfo.net_tx_bps) : '--'}
rxData={metrics.rx} txData={metrics.tx}
aggType={aggType} unit="KB/s"
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3 mt-3">
<MetricChartCard title="网卡接收错误" value={netInfo?.net_rx_errors != null ? String(netInfo.net_rx_errors) : '--'} icon={<XCircle />} iconTone="red"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.s9f7e9902')} value={netInfo?.net_rx_errors != null ? String(netInfo.net_rx_errors) : '--'} icon={<XCircle />} iconTone="red"
data={metrics.rxErr} color="#ef4444" unit="个" domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="网卡发送错误" value={netInfo?.net_tx_errors != null ? String(netInfo.net_tx_errors) : '--'} icon={<XCircle />} iconTone="orange"
<MetricChartCard title={i18n.t('monitor.hostmonitortsx.sb2ffd58e')} value={netInfo?.net_tx_errors != null ? String(netInfo.net_tx_errors) : '--'} icon={<XCircle />} iconTone="orange"
data={metrics.txErr} color="#f97316" unit="个" domain={[0, 'auto']} aggType={aggType} />
</div>
</TabsContent>
@@ -269,10 +270,10 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<table className="w-full text-xs">
<thead>
<tr className="text-[var(--dg-text-muted)] border-b border-[var(--dg-border)]">
<th className="py-1.5 text-left font-medium">端口</th>
<th className="py-1.5 text-left font-medium">协议</th>
<th className="py-1.5 text-left font-medium">进程</th>
<th className="py-1.5 text-right font-medium">状态</th>
<th className="py-1.5 text-left font-medium"> {i18n.t('system.ldapPort')} </th>
<th className="py-1.5 text-left font-medium"> {i18n.t('kubernetes.service.protocol')} </th>
<th className="py-1.5 text-left font-medium"> {i18n.t('monitor.hostmonitortsx.sf88522cf')} </th>
<th className="py-1.5 text-right font-medium"> {i18n.t('system.terminalStatus')} </th>
</tr>
</thead>
<tbody>
@@ -315,11 +316,11 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<table className="w-full text-xs">
<thead>
<tr className="text-[var(--dg-text-muted)] border-b border-[var(--dg-border)]">
<th className="py-1.5 text-left font-medium w-[40%]">进程名称 / CMD</th>
<th className="py-1.5 text-left font-medium w-[40%]"> {i18n.t('monitor.hostmonitortsx.s23ecaf10')} </th>
<th className="py-1.5 text-right font-medium w-[8%]">PID</th>
<th className="py-1.5 text-right font-medium w-[16%]">内存使用率(%)</th>
<th className="py-1.5 text-right font-medium w-[16%]"> {i18n.t('monitor.hostmonitortsx.s78262b59')} </th>
<th className="py-1.5 text-right font-medium w-[16%]">CPU使用率(%)</th>
<th className="py-1.5 text-right font-medium w-[20%]">打开文件数</th>
<th className="py-1.5 text-right font-medium w-[20%]"> {i18n.t('monitor.hostmonitortsx.s8fe5ed35')} </th>
</tr>
</thead>
<tbody>
@@ -336,7 +337,7 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
</span>
<button
className="opacity-0 group-hover/cmd:opacity-100 transition-opacity p-0.5 hover:dg-text-cyan shrink-0"
title="复制命令行"
title={i18n.t('monitor.hostmonitortsx.s92cb88ae')}
onClick={async (e) => {
e.stopPropagation();
try {
@@ -398,15 +399,15 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<>
<div className="flex items-center gap-4 mb-3 text-xs">
<div>
<span className="text-[var(--dg-text-muted)]">已分配 </span>
<span className="text-[var(--dg-text-muted)]"> {i18n.t('deploy.toast.assigned')} </span>
<span className="font-mono text-[var(--dg-text-primary)] font-semibold">{fdInfo.allocated.toLocaleString()}</span>
</div>
<div>
<span className="text-[var(--dg-text-muted)]">上限 </span>
<span className="font-mono text-[var(--dg-text-primary)] font-semibold">{fdInfo.max === -1 ? '无限制' : fdInfo.max?.toLocaleString() || '—'}</span>
<span className="text-[var(--dg-text-muted)]"> {i18n.t('monitor.metricCatalog.colMax')} </span>
<span className="font-mono text-[var(--dg-text-primary)] font-semibold">{fdInfo.max === -1 ? i18n.t('monitor.hostmonitortsx.sbc436447') : fdInfo.max?.toLocaleString() || '—'}</span>
</div>
<div>
<span className="text-[var(--dg-text-muted)]">使用率 </span>
<span className="text-[var(--dg-text-muted)]"> {i18n.t('server.usage')} </span>
<span className={`font-mono font-semibold ${fdInfo.usage_pct > 80 ? 'text-rose-400' : 'dg-text-purple'}`}>
{fdInfo.usage_pct != null ? `${fdInfo.usage_pct.toFixed(1)}%` : '—'}
</span>
@@ -416,11 +417,11 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
<ZoomableAreaChart
ref={fdChartRef}
data={metrics.fd.map((d) => ({ ...d, value: d[aggType] }))}
series={[{ dataKey: 'value', color: '#a78bfa', label: 'FD 使用率' }]}
series={[{ dataKey: 'value', color: '#a78bfa', label: i18n.t('monitor.hostmonitortsx.s28130dec') }]}
yDomain={[0, 'auto']}
unit="%"
chartId="fd-usage"
title="FD 文件句柄使用率"
title={i18n.t('monitor.hostmonitortsx.sc026a1ea')}
subtitle={fdInfo?.usage_pct != null ? `当前 ${fdInfo.usage_pct.toFixed(1)}%` : undefined}
height={160}
toolbarPlacement="header"
@@ -430,7 +431,7 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
)}
</>
) : (
<div className="text-center py-4 text-xs text-[var(--dg-text-muted)]">等待数据…</div>
<div className="text-center py-4 text-xs text-[var(--dg-text-muted)]"> {i18n.t('monitor.hostmonitortsx.sae1a30b7')} </div>
)}
</CardContent>
</Card>
@@ -476,7 +477,7 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
</div>
</div>
) : (
<div className="text-center py-4 text-xs text-[var(--dg-text-muted)]">等待数据…</div>
<div className="text-center py-4 text-xs text-[var(--dg-text-muted)]"> {i18n.t('monitor.hostmonitortsx.sae1a30b7')} </div>
)}
</CardContent>
</Card>
@@ -529,12 +530,12 @@ export function HostMonitor({ embedded = false }: { embedded?: boolean }) {
return (
<PageShell
variant="workspace"
title="主机监控"
subtitle={selectedHost ? `当前主机: ${selectedHost}` : '选择主机查看监控指标'}
title={i18n.t('monitor.alertRulesTab.catHost')}
subtitle={selectedHost ? `当前主机: ${selectedHost}` : i18n.t('monitor.hostmonitortsx.s8d493048')}
icon={<Server className="h-5 w-5" />}
toolbar={toolbar}
loading={loading && !history.length}
loadingLabel="加载监控数据..."
loadingLabel={i18n.t('monitor.hostmonitortsx.sc23e802e')}
contentClassName="space-y-3"
>
{monitorBody}