refactor(i18n): U19 i18n hash 键治理 — 删除 866 死键 + 重命名 21 高频键

死键清理: 从 zh-CN.json 和 en-US.json 移除 866 个重构遗弃的 unreferenced
hash keys (filename.hash 格式)。这些键在组件迁移到语义化键后成为孤儿。

Live 键重命名 (21 个):
  ui.datatable.s1a2b3c4d → selectedCount
  ui.datatable.s2b3c4d5e → columns
  ui.datatable.s3c4d5e6f → totalCount
  aiops.predictive.s{1-3} → metricsTab/capacityTab/costTab
  aiops.predictivecost.s{1-3} → aiFailed/overview/aiInsight
  task.systemtaskspanel.s{1-3} → monitor/cleanup/finops
  aiops.agentcli.s{1-3} → archLayer/archDesc/securityLayer
  system.useldapmanageme.s{1-2} → ouExists/createOuFailed
  common.requestts.sd3ab821c → common.request.tokenExpired
  k8s.editAdvanced.s0c1fec65 → secondsPlaceholder
  k8s.{kubectl,podExec}.sc8107726 → connectErrorAnsi

影响: zh/en 7597→6731 keys 对齐, 文件 328KB→276KB (-16%)
      仍有 172 个 live hash keys 待后续重命名

tsc -b=0, npm build✓ (17.45s), ESLint=0/66/0, go build=0, 17/17 测试通过
This commit is contained in:
attacker committed 2026-07-11 08:08:07 +08:00
1 parent 543365596d
commit bb2b50276a
12 files changed
+74 -73

No files matched your search

@@ -120,9 +120,9 @@ export function AIPredictiveAnalytics() {
};
const pageTabs = [
{ id: 'metrics', label: t('aiops.predictive.s1a2b3c4d') },
{ id: 'capacity', label: t('aiops.predictive.s2b3c4d5e') },
{ id: 'cost', label: t('aiops.predictive.s3c4d5e6f') },
{ id: 'metrics', label: t('aiops.predictive.metricsTab') },
{ id: 'capacity', label: t('aiops.predictive.capacityTab') },
{ id: 'cost', label: t('aiops.predictive.costTab') },
];
return (
@@ -60,7 +60,7 @@ export function PredictiveCostTab({
const res = await aiApi.chat([{ role: 'user', content: prompt }]);
setInsight(res?.content || '');
} catch {
toast.error(t('aiops.predictivecost.s1a2b3c4d'));
toast.error(t('aiops.predictivecost.aiFailed'));
} finally {
setAnalyzing(false);
}
@@ -73,7 +73,7 @@ export function PredictiveCostTab({
<div className="flex items-center justify-between">
<CardTitle className="text-[var(--dg-text-primary)] flex items-center gap-2">
<Wallet className="h-5 w-5 dg-text-emerald" />
{t('aiops.predictivecost.s2b3c4d5e')}
{t('aiops.predictivecost.overview')}
</CardTitle>
{!loading && hasData && (
<Button
@@ -88,7 +88,7 @@ export function PredictiveCostTab({
) : (
<Sparkles className="h-3.5 w-3.5 mr-1" />
)}
{t('aiops.predictivecost.s3c4d5e6f')}
{t('aiops.predictivecost.aiInsight')}
</Button>
)}
</div>
@@ -109,7 +109,7 @@ export function KubectlTerminal({ open, onOpenChange, clusterId, clusterName }:
ws.onerror = () => {
setError(i18n.t('k8s.kubectl.failed'));
setHasOutput(true);
term.write(i18n.t('k8s.kubectl.sc8107726'));
term.write(i18n.t('k8s.kubectl.connectError'));
};
return () => {
@@ -47,7 +47,7 @@ export function TolerationsCard({ tolerations, onAdd, onRemove, onUpdate }: Tole
<option value="PreferNoSchedule">PreferNoSchedule</option>
<option value="NoExecute">NoExecute</option>
</select>
<Input value={t.tolerationSeconds} placeholder={i18n.t('k8s.editAdvanced.s0c1fec65')} disabled={t.effect !== 'NoExecute'}
<Input value={t.tolerationSeconds} placeholder={i18n.t('k8s.editAdvanced.seconds')} disabled={t.effect !== 'NoExecute'}
onChange={e => onUpdate(i, { tolerationSeconds: e.target.value })}
className="h-7 dg-input text-xs font-mono" />
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-red" onClick={() => onRemove(i)}>
@@ -146,7 +146,7 @@ export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
} catch (e) {
const msg = e?.message || '';
if (msg.includes('Already Exists') || msg.includes('68')) {
toast.error(i18n.t('system.useldapmanageme.s1a2b3c4d', { name: ouForm.ou_name }));
toast.error(i18n.t('system.useldapmanageme.ouExists', { name: ouForm.ou_name }));
} else {
toast.error(i18n.t('创建失败: ') + msg);
}
@@ -16,9 +16,9 @@ import {
} from 'lucide-react';
const categoryLabel: Record<string, string> = {
get monitor() { return i18n.t('task.systemtaskspanel.s1a2b3c4d'); },
get cleanup() { return i18n.t('task.systemtaskspanel.s2b3c4d5e'); },
get finops() { return i18n.t('task.systemtaskspanel.s3c4d5e6f'); },
get monitor() { return i18n.t('task.systemtaskspanel.monitor'); },
get cleanup() { return i18n.t('task.systemtaskspanel.cleanup'); },
get finops() { return i18n.t('task.systemtaskspanel.finops'); },
};
function statusBadge(status?: string) {
+3 -3
View File
@@ -412,7 +412,7 @@ export function DataTable<T = Record<string, unknown>>(
)}
{selectable && (selectedIds?.length ?? 0) > 0 && (
<Badge variant="secondary" className="bg-[var(--dg-bg-active)] text-[var(--dg-text-secondary)] border-[var(--dg-border)]">
{i18n.t("ui.datatable.s1a2b3c4d", { count: selectedIds!.length })}
{i18n.t("ui.datatable.selectedCount", { count: selectedIds!.length })}
</Badge>
)}
</div>
@@ -423,7 +423,7 @@ export function DataTable<T = Record<string, unknown>>(
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="h-8 gap-1.5 border-[var(--dg-border)] text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-hover)] hover:text-[var(--dg-text-primary)]">
<Eye className="h-3.5 w-3.5" />
<span className="hidden sm:inline">{i18n.t("ui.datatable.s2b3c4d5e")}</span>
<span className="hidden sm:inline">{i18n.t("ui.datatable.columns")}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)]">
@@ -579,7 +579,7 @@ export function DataTable<T = Record<string, unknown>>(
<div className="flex items-center justify-between gap-2 px-1 py-2 flex-wrap">
<div className="flex items-center gap-3">
<span className="text-sm text-[var(--dg-text-muted)]">
{i18n.t("ui.datatable.s3c4d5e6f", { count: sortedData.length })}
{i18n.t("ui.datatable.totalCount", { count: sortedData.length })}
</span>
{selectable && (selectedIds?.length ?? 0) > 0 && (
<span className="text-sm text-[var(--dg-text-muted)]">