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:
1 parent
72bfb0e12d
commit
55f216cfbb
131 files changed
+4049
-1908
No files matched your search
@@ -23,6 +23,7 @@ import { toast } from 'sonner';
|
||||
import { billingApi } from '@/api';
|
||||
import { providerLabels } from './CloudBillingHelpers';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
const emptyRecord = {
|
||||
provider: 'aliyun',
|
||||
@@ -65,7 +66,7 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!form.provider || !form.billing_date || !form.cost) {
|
||||
toast.error('请填写必填字段');
|
||||
toast.error(i18n.t('cloud.billingrecorddi.sd8a97c17'));
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
@@ -81,7 +82,7 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
onSuccess();
|
||||
toast('保存成功');
|
||||
} catch (e) {
|
||||
toast.error('保存失败', { description: (e as JsonData).message });
|
||||
toast.error(i18n.t('kubernetes.msg.saveFailed'), { description: (e as JsonData).message });
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
@@ -91,13 +92,13 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingRecord ? '编辑成本记录' : '记录成本'}</DialogTitle>
|
||||
<DialogDescription>记录一条每日云资源成本</DialogDescription>
|
||||
<DialogTitle>{editingRecord ? i18n.t('cloud.billingrecorddi.s3c91e420') : i18n.t('cloud.recordCost')}</DialogTitle>
|
||||
<DialogDescription> {i18n.t('cloud.billingrecorddi.s09e541fd')} </DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">厂商 *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.sb11d8416')} </Label>
|
||||
<Select value={form.provider} onValueChange={(v) => setForm({ ...form, provider: v })}>
|
||||
<SelectTrigger className="mt-1"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
@@ -108,37 +109,37 @@ export function BillingRecordDialog({ open, onOpenChange, editingRecord, onSucce
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">日期 *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.s3abdefe2')} </Label>
|
||||
<Input type="date" className="mt-1" value={form.billing_date} onChange={(e) => setForm({ ...form, billing_date: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">费用(元) *</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.billingrecorddi.s6f252687')} </Label>
|
||||
<Input type="number" step="0.01" className="mt-1" placeholder="0.00" value={form.cost} onChange={(e) => setForm({ ...form, cost: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">服务</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.colService')} </Label>
|
||||
<Input className="mt-1" placeholder="ECS, RDS..." value={form.service} onChange={(e) => setForm({ ...form, service: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">区域</Label>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.colRegion')} </Label>
|
||||
<Input className="mt-1" placeholder="cn-hangzhou" value={form.region} onChange={(e) => setForm({ ...form, region: e.target.value })} />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">账号名称</Label>
|
||||
<Input className="mt-1" placeholder="主账号" value={form.account_name} onChange={(e) => setForm({ ...form, account_name: e.target.value })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('cloud.accountName')} </Label>
|
||||
<Input className="mt-1" placeholder={i18n.t('cloud.billingrecorddi.s0010795e')} value={form.account_name} onChange={(e) => setForm({ ...form, account_name: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]">备注</Label>
|
||||
<Input className="mt-1" placeholder="可选" value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
|
||||
<Label className="text-sm text-[var(--dg-text-secondary)]"> {i18n.t('monitor.contactGroup.notes')} </Label>
|
||||
<Input className="mt-1" placeholder={i18n.t('rbac.jobRole.placeholder.description')} value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} />
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>取消</Button>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||
<Button onClick={handleSave} disabled={submitting}>
|
||||
{submitting && <Loader2 className="h-4 w-4 mr-1 animate-spin" />}
|
||||
保存
|
||||
|
||||
Reference in new issue
Block a user