feat(i18n): 剩余模块全量国际化 — 51% 覆盖率 (231 文件接入 t())

批量转换 163 个文件,3204 处中文替换为 t() 调用:
- Monitor: 日志中心/告警中心/数据源/大屏/站点拨测/SNMP/中间件 全部转换
- Kubernetes: ResourceVisualEditor/NamespaceResourcePage/拓扑/事件 全部转换
- Deploy: 流水线/发布/凭证/RBAC 全部转换
- Server/Cloud/Agent/Task/Layout/UI: 全部转换
- 翻译词典扩展至 6474 行 (22 namespaces, 5000+ keys)
- tsc 编译零错误
This commit is contained in:
attacker committed 2026-07-03 01:51:57 +08:00
1 parent 78c27037e3
commit ecec73989b
166 files changed
+6925 -2800

No files matched your search

@@ -26,8 +26,10 @@ import { kubernetesApi } from '@/api';
import { useToast } from '@/hooks/use-toast';
import { DeploymentDetail } from './DeploymentDetail';
import type { JsonData } from '@/types/common';
import { useTranslation } from 'react-i18next';
export function KubernetesWorkloads() {
const { t } = useTranslation();
const { toast } = useToast();
const [clusters, setClusters] = useState<JsonData[]>([]);
const [selectedCluster, setSelectedCluster] = useState('');
@@ -119,10 +121,10 @@ export function KubernetesWorkloads() {
const newReplicas = (dep.replicas || 0) + delta;
if (newReplicas < 0) return;
await kubernetesApi.scaleDeployment(selectedCluster, dep.namespace, dep.name, newReplicas);
toast({ title: '扩缩容成功', description: `${dep.name} → ${newReplicas} 副本` });
toast({ title: t('kubernetes.kubernetesworkloads.s0b3ea1'), description: t('kubernetes.kubernetesworkloads.scf7f1c', { dep.name: dep.name, newReplicas: newReplicas }) });
loadData();
} catch (e) {
toast({ title: '操作失败', description: e?.message || String(e), variant: 'destructive' });
toast({ title: t('common.operationFailed'), description: e?.message || String(e), variant: 'destructive' });
} finally {
setActionLoading((prev) => { const n = { ...prev }; delete n[key]; return n; });
}
@@ -144,13 +146,13 @@ export function KubernetesWorkloads() {
<div className="space-y-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-[var(--dg-text-primary)]">工作负载</h1>
<p className="text-sm dg-text-muted mt-1">Deployment 与 Pod 运行状态</p>
<h1 className="text-2xl font-bold text-[var(--dg-text-primary)]">{t('menu.workloads')}</h1>
<p className="text-sm dg-text-muted mt-1">{t('kubernetes.kubernetesworkloads.sf90ced')}</p>
</div>
<div className="flex items-center gap-2">
<Select value={selectedCluster} onValueChange={(v) => { setSelectedCluster(v); setSelectedNamespace('all'); }}>
<SelectTrigger className="w-48 h-9 dg-input">
<SelectValue placeholder="选择集群" />
<SelectValue placeholder=t('k8s.topology.selectCluster') />
</SelectTrigger>
<SelectContent className="dg-input">
{clusters.map((c) => (
@@ -160,10 +162,10 @@ export function KubernetesWorkloads() {
</Select>
<Select value={selectedNamespace} onValueChange={setSelectedNamespace}>
<SelectTrigger className="w-40 h-9 dg-input">
<SelectValue placeholder="命名空间" />
<SelectValue placeholder=t('k8s.column.namespace') />
</SelectTrigger>
<SelectContent className="dg-input max-h-[300px]">
<SelectItem value="all">全部命名空间</SelectItem>
<SelectItem value="all">{t('kubernetes.namespace.allNamespaces')}</SelectItem>
{namespaces.map((ns) => (
<SelectItem key={ns} value={ns}>{ns}</SelectItem>
))}
@@ -178,9 +180,9 @@ export function KubernetesWorkloads() {
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{[
{ label: 'Deployment', value: deployments.length, icon: <Boxes className="h-5 w-5" />, color: 'text-rose-400' },
{ label: 'Pod 总数', value: pods.length, icon: <Container className="h-5 w-5" />, color: 'dg-text-blue' },
{ label: t('kubernetes.kubernetesworkloads.s83481f'), value: pods.length, icon: <Container className="h-5 w-5" />, color: 'dg-text-blue' },
{ label: 'Running', value: pods.filter((p) => p.status === 'Running').length, icon: <Container className="h-5 w-5" />, color: 'dg-text-green' },
{ label: '异常', value: pods.filter((p) => ['Failed', 'Pending'].includes(p.status)).length, icon: <Container className="h-5 w-5" />, color: 'dg-text-red' },
{ label: t('common.abnormal'), value: pods.filter((p) => ['Failed', 'Pending'].includes(p.status)).length, icon: <Container className="h-5 w-5" />, color: 'dg-text-red' },
].map((s) => (
<Card key={s.label} className="dg-card">
<CardContent className="p-4">
@@ -198,7 +200,7 @@ export function KubernetesWorkloads() {
<div className="relative w-56">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 dg-text-muted" />
<Input placeholder="搜索..." value={search} onChange={(e) => setSearch(e.target.value)} className="pl-9 h-9 dg-input" />
<Input placeholder=t('kubernetes.kubernetesworkloads.s64e327') value={search} onChange={(e) => setSearch(e.target.value)} className="pl-9 h-9 dg-input" />
</div>
<Tabs value={activeTab} onValueChange={setActiveTab}>
@@ -213,18 +215,18 @@ export function KubernetesWorkloads() {
<Table>
<TableHeader>
<TableRow className="border-[var(--dg-border)] hover:bg-transparent">
<TableHead className="dg-text-secondary">名称</TableHead>
<TableHead className="dg-text-secondary">命名空间</TableHead>
<TableHead className="dg-text-secondary">副本</TableHead>
<TableHead className="dg-text-secondary">镜像</TableHead>
<TableHead className="dg-text-secondary w-[140px]">操作</TableHead>
<TableHead className="dg-text-secondary">{t('common.name')}</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.column.namespace')}</TableHead>
<TableHead className="dg-text-secondary">{t('kubernetes.kubernetesworkloads.s0428b3')}</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.column.image')}</TableHead>
<TableHead className="dg-text-secondary w-[140px]">{t('common.actions')}</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{loading ? (
<TableRow><TableCell colSpan={5} className="text-center dg-text-muted py-12"><Loader2 className="h-5 w-5 animate-spin mx-auto mb-2" />加载中...</TableCell></TableRow>
<TableRow><TableCell colSpan={5} className="text-center dg-text-muted py-12"><Loader2 className="h-5 w-5 animate-spin mx-auto mb-2" />{t('common.loading')}</TableCell></TableRow>
) : filteredDeps.length === 0 ? (
<TableRow><TableCell colSpan={5} className="text-center dg-text-muted py-12"><Boxes className="h-8 w-8 mx-auto mb-2 opacity-50" />暂无 Deployment</TableCell></TableRow>
<TableRow><TableCell colSpan={5} className="text-center dg-text-muted py-12"><Boxes className="h-8 w-8 mx-auto mb-2 opacity-50" />{t('kubernetes.kubernetesworkloads.s5689d3')}</TableCell></TableRow>
) : (
filteredDeps.map((d) => (
<TableRow key={d.id || d.name} className="border-[var(--dg-border)] hover:bg-[var(--dg-bg-hover)] cursor-pointer"
@@ -251,16 +253,16 @@ export function KubernetesWorkloads() {
<TableCell onClick={(e) => e.stopPropagation()}>
<div className="flex items-center gap-0.5">
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-secondary hover:text-[var(--dg-text-primary)]"
title="减少副本" disabled={(d.replicas || 0) <= 0}
title=t('kubernetes.kubernetesworkloads.sd4db1c') disabled={(d.replicas || 0) <= 0}
onClick={() => handleQuickScale(d, -1)}>
<Minus className="h-3.5 w-3.5" />
</Button>
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-secondary hover:text-[var(--dg-text-primary)]"
title="增加副本" onClick={() => handleQuickScale(d, 1)}>
title=t('kubernetes.kubernetesworkloads.se80820') onClick={() => handleQuickScale(d, 1)}>
<Plus className="h-3.5 w-3.5" />
</Button>
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-secondary hover:dg-text-blue"
title="查看详情" onClick={() => setSelectedDeployment({ name: d.name, namespace: d.namespace })}>
title=t('common.viewDetail') onClick={() => setSelectedDeployment({ name: d.name, namespace: d.namespace })}>
<Eye className="h-3.5 w-3.5" />
</Button>
</div>
@@ -280,21 +282,21 @@ export function KubernetesWorkloads() {
<Table>
<TableHeader>
<TableRow className="border-[var(--dg-border)] hover:bg-transparent">
<TableHead className="dg-text-secondary">名称</TableHead>
<TableHead className="dg-text-secondary">命名空间</TableHead>
<TableHead className="dg-text-secondary">状态</TableHead>
<TableHead className="dg-text-secondary">节点</TableHead>
<TableHead className="dg-text-secondary">{t('common.name')}</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.column.namespace')}</TableHead>
<TableHead className="dg-text-secondary">{t('common.status')}</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.tab.nodes')}</TableHead>
<TableHead className="dg-text-secondary">CPU</TableHead>
<TableHead className="dg-text-secondary">内存</TableHead>
<TableHead className="dg-text-secondary">重启</TableHead>
<TableHead className="dg-text-secondary">镜像</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.pods.memory')}</TableHead>
<TableHead className="dg-text-secondary">{t('common.reboot')}</TableHead>
<TableHead className="dg-text-secondary">{t('k8s.column.image')}</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{loading ? (
<TableRow><TableCell colSpan={8} className="text-center dg-text-muted py-12"><Loader2 className="h-5 w-5 animate-spin mx-auto mb-2" />加载中...</TableCell></TableRow>
<TableRow><TableCell colSpan={8} className="text-center dg-text-muted py-12"><Loader2 className="h-5 w-5 animate-spin mx-auto mb-2" />{t('common.loading')}</TableCell></TableRow>
) : filteredPods.length === 0 ? (
<TableRow><TableCell colSpan={8} className="text-center dg-text-muted py-12"><Container className="h-8 w-8 mx-auto mb-2 opacity-50" />暂无 Pod</TableCell></TableRow>
<TableRow><TableCell colSpan={8} className="text-center dg-text-muted py-12"><Container className="h-8 w-8 mx-auto mb-2 opacity-50" />{t('k8s.deploymentDetail.noPod')}</TableCell></TableRow>
) : (
filteredPods.map((p) => (
<TableRow key={p.id} className="border-[var(--dg-border)] hover:bg-[var(--dg-bg-hover)]">