From fef4997391366655280f6dd5720634860267adf9 Mon Sep 17 00:00:00 2001 From: attacker Date: Mon, 29 Jun 2026 18:25:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20Approval=20=E5=AE=A1=E6=89=B9?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=85=A8=E9=87=8F=E5=9B=BD=E9=99=85=E5=8C=96?= =?UTF-8?q?=20=E2=80=94=2011=20=E6=96=87=E4=BB=B6=E7=A1=AC=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E4=B8=AD=E6=96=87=E6=94=B9=E7=BF=BB=E8=AF=91=E9=94=AE?= =?UTF-8?q?=20+=20approval=20=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4(136=20?= =?UTF-8?q?=E9=94=AE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 迁移文件: - pages/approval/: ApprovalWorkflowPage + ApprovalCategoryPage + 3 子页面(Resource/App/Permission) - components/approval/: ApprovalFlow + ApprovalProcessTab + ApprovalCreateDialog + ApprovalDetailDialog + ApprovalTemplateTab + helpers 翻译键: approval 命名空间 136 键 (8 子组: category/step/status/col/editor/detail/flow/type/msg) 复用 common.* 通用键 (approve/reject/cancel/save/create/delete/edit/detail/close/loading 等) zh-CN/en-US 完全对齐, 8 命名空间 (common/menu/header/login/dashboard/server/alert/approval) 模式: 组件内 useTranslation() + t(); 模块级常量/helpers 用 i18n.t() labelKey 模式: STATUS_TABS/statusMap 从 label:string 改为 labelKey:string + i18n.t(config.labelKey) --- .../approval/ApprovalCreateDialog.tsx | 30 +-- .../approval/ApprovalDetailDialog.tsx | 26 +-- .../src/components/approval/ApprovalFlow.tsx | 62 +++--- .../approval/ApprovalProcessTab.tsx | 53 +++--- .../approval/ApprovalTemplateTab.tsx | 51 ++--- frontend/src/components/approval/helpers.tsx | 11 +- frontend/src/locales/en-US.json | 156 +++++++++++++++ frontend/src/locales/zh-CN.json | 156 +++++++++++++++ .../src/pages/approval/ApprovalAppPage.tsx | 30 +-- .../pages/approval/ApprovalCategoryPage.tsx | 131 ++++++------- .../pages/approval/ApprovalPermissionPage.tsx | 30 +-- .../pages/approval/ApprovalResourcePage.tsx | 28 +-- .../pages/approval/ApprovalWorkflowPage.tsx | 177 ++++++++++-------- 13 files changed, 649 insertions(+), 292 deletions(-) diff --git a/frontend/src/components/approval/ApprovalCreateDialog.tsx b/frontend/src/components/approval/ApprovalCreateDialog.tsx index 2704be0..164e57a 100644 --- a/frontend/src/components/approval/ApprovalCreateDialog.tsx +++ b/frontend/src/components/approval/ApprovalCreateDialog.tsx @@ -21,6 +21,7 @@ import { } from '@/components/ui/dialog'; import { Loader2 } from 'lucide-react'; import { toast } from 'sonner'; +import { useTranslation } from 'react-i18next'; import { approvalApi } from '@/api'; import { parseFields, APPROVAL_TYPE_OPTIONS } from './helpers'; import type { JsonData } from '@/types/common'; @@ -39,6 +40,7 @@ export function ApprovalCreateDialog({ templates, onSuccess, }: ApprovalCreateDialogProps) { + const { t } = useTranslation(); const [selectedTemplate, setSelectedTemplate] = useState(null); const [formData, setFormData] = useState({}); const [submitting, setSubmitting] = useState(false); @@ -46,13 +48,13 @@ export function ApprovalCreateDialog({ // 提交新建申请 // Logan.Li const handleSubmit = async () => { if (!selectedTemplate) { - toast.error('请先选择申请类型'); + toast.error(t('approval.flow.pleaseSelectType')); return; } const fields = parseFields(selectedTemplate.form_schema); for (const f of fields) { if (f.required && !formData[f.key]) { - toast.error(`请填写${f.label}`); + toast.error(t('approval.flow.pleaseFillField', { label: f.label })); return; } } @@ -63,13 +65,13 @@ export function ApprovalCreateDialog({ title: formData.app_name || selectedTemplate.name, form_data: JSON.stringify(formData), }); - toast.success('申请已提交'); + toast.success(t('approval.msg.submitSuccess')); onOpenChange(false); setSelectedTemplate(null); setFormData({}); onSuccess(); } catch (e) { - toast.error('提交失败', { description: e?.message }); + toast.error(t('approval.msg.submitFailed'), { description: e?.message }); } finally { setSubmitting(false); } @@ -89,9 +91,9 @@ export function ApprovalCreateDialog({ > - 新建资源申请 + {t('approval.flow.newResourceRequest')} - {selectedTemplate ? '请填写申请信息' : '请选择申请类型'} + {selectedTemplate ? t('approval.flow.fillInfo') : t('approval.flow.selectType')} @@ -100,7 +102,7 @@ export function ApprovalCreateDialog({
{APPROVAL_TYPE_OPTIONS.map((opt) => { const tpl = templates.find( - (t) => t.type === opt.value && (t.enabled !== false) + (tm) => tm.type === opt.value && (tm.enabled !== false) ); const Icon = opt.icon; return ( @@ -124,7 +126,7 @@ export function ApprovalCreateDialog({

{opt.label}

- {tpl ? tpl.description || `共 ${parseFields(tpl.form_schema).length} 个字段` : '暂无可用模板'} + {tpl ? tpl.description || t('approval.flow.fieldCount', { count: parseFields(tpl.form_schema).length }) : t('approval.flow.noTemplateAvailable')}

@@ -140,7 +142,7 @@ export function ApprovalCreateDialog({ onClick={() => { setSelectedTemplate(null); setFormData({}); }} className="text-xs text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]" > - ← 返回选择类型 + {t('approval.flow.backToSelect')}
@@ -158,7 +160,7 @@ export function ApprovalCreateDialog({ onValueChange={(val) => setFormData((prev) => ({ ...prev, [field.key]: val }))} > - + {(field.options || []).map((opt: string) => ( @@ -170,7 +172,7 @@ export function ApprovalCreateDialog({ ) : field.type === 'textarea' ? (