feat(i18n): Approval 审批模块全量国际化 — 11 文件硬编码中文改翻译键 + approval 命名空间(136 键)
迁移文件: - 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)
This commit is contained in:
1 parent
61a1f32e64
commit
fef4997391
13 files changed
+649
-292
No files matched your search
@@ -3,6 +3,8 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/com
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Filter, Edit, GitBranch, ArrowRight } from 'lucide-react';
|
||||
import i18n from 'i18next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { JsonData } from '@/types/common';
|
||||
|
||||
function parseSteps(steps: JsonData) {
|
||||
@@ -18,24 +20,26 @@ function parseSteps(steps: JsonData) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 审批类型字典
|
||||
const APPROVAL_TYPE_OPTIONS = [
|
||||
{ value: 'deploy', label: '发布审批', color: 'var(--dg-blue)' },
|
||||
{ value: 'server', label: '服务器操作', color: 'var(--dg-cyan)' },
|
||||
{ value: 'permission', label: '权限申请', color: 'var(--dg-purple)' },
|
||||
];
|
||||
// 审批类型字典 (labels resolved at render via i18n)
|
||||
const APPROVAL_TYPE_META: Record<string, { key: string; color: string }> = {
|
||||
deploy: { key: 'approval.type.deploy', color: 'var(--dg-blue)' },
|
||||
server: { key: 'approval.type.server', color: 'var(--dg-cyan)' },
|
||||
permission: { key: 'approval.type.permission', color: 'var(--dg-purple)' },
|
||||
};
|
||||
|
||||
const getApprovalTypeLabel = (value: string): string =>
|
||||
APPROVAL_TYPE_OPTIONS.find((o) => o.value === value)?.label || value || '通用审批';
|
||||
const getApprovalTypeLabel = (value: string): string => {
|
||||
const meta = APPROVAL_TYPE_META[value];
|
||||
return meta ? i18n.t(meta.key) : (value || i18n.t('approval.type.general'));
|
||||
};
|
||||
|
||||
const getApprovalTypeColor = (value: string): string =>
|
||||
APPROVAL_TYPE_OPTIONS.find((o) => o.value === value)?.color || 'var(--dg-text-secondary)';
|
||||
APPROVAL_TYPE_META[value]?.color || 'var(--dg-text-secondary)';
|
||||
|
||||
// 模拟审批流程图
|
||||
function renderFlowChart(flow: JsonData) {
|
||||
const nodes = parseSteps(flow.steps);
|
||||
if (nodes.length === 0) {
|
||||
return <div className="text-[var(--dg-text-muted)] text-center py-4">暂无流程节点</div>;
|
||||
return <div className="text-[var(--dg-text-muted)] text-center py-4">{i18n.t('approval.noFlowNodes')}</div>;
|
||||
}
|
||||
return (
|
||||
<div className="flex items-center gap-2 overflow-x-auto py-4">
|
||||
@@ -77,13 +81,14 @@ export function ApprovalTemplateTab({
|
||||
templateTypeFilter,
|
||||
setTemplateTypeFilter,
|
||||
}: ApprovalTemplateTabProps) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
{/* 类型筛选 */}
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<div className="flex items-center gap-1.5 text-sm text-[var(--dg-text-secondary)]">
|
||||
<Filter className="h-4 w-4" />
|
||||
<span>类型筛选:</span>
|
||||
<span>{t('approval.flow.filterType')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-lg p-1">
|
||||
<button
|
||||
@@ -95,21 +100,21 @@ export function ApprovalTemplateTab({
|
||||
: 'text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)]'
|
||||
)}
|
||||
>
|
||||
全部类型
|
||||
{t('approval.flow.allTypes')}
|
||||
</button>
|
||||
{APPROVAL_TYPE_OPTIONS.map((opt) => (
|
||||
{Object.entries(APPROVAL_TYPE_META).map(([val, meta]) => (
|
||||
<button
|
||||
key={opt.value}
|
||||
onClick={() => setTemplateTypeFilter(opt.value)}
|
||||
key={val}
|
||||
onClick={() => setTemplateTypeFilter(val)}
|
||||
className={cn(
|
||||
'px-3 py-1.5 rounded-md text-sm transition-colors flex items-center gap-1.5',
|
||||
templateTypeFilter === opt.value
|
||||
templateTypeFilter === val
|
||||
? 'bg-[var(--dg-bg-hover)] text-[var(--dg-text-primary)] font-medium'
|
||||
: 'text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)]'
|
||||
)}
|
||||
>
|
||||
<span style={{ color: opt.color }}>●</span>
|
||||
{opt.label}
|
||||
<span style={{ color: meta.color }}>●</span>
|
||||
{getApprovalTypeLabel(val)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -121,8 +126,8 @@ export function ApprovalTemplateTab({
|
||||
<CardContent className="p-8">
|
||||
<div className="text-center">
|
||||
<GitBranch className="h-12 w-12 mx-auto text-[var(--dg-text-muted)] mb-4" />
|
||||
<h3 className="text-lg font-medium text-[var(--dg-text-secondary)] mb-2">暂无流程模板</h3>
|
||||
<p className="text-sm text-[var(--dg-text-muted)]">当前筛选条件下没有匹配的模板</p>
|
||||
<h3 className="text-lg font-medium text-[var(--dg-text-secondary)] mb-2">{t('approval.noTemplates')}</h3>
|
||||
<p className="text-sm text-[var(--dg-text-muted)]">{t('approval.noTemplatesDesc')}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -160,7 +165,7 @@ export function ApprovalTemplateTab({
|
||||
: 'border-[var(--dg-border)] text-[var(--dg-text-secondary)] bg-[var(--dg-bg-tertiary)]'
|
||||
}
|
||||
>
|
||||
{flow.status === 1 || flow.status === 'active' || flow.status === true ? '已启用' : '已停用'}
|
||||
{flow.status === 1 || flow.status === 'active' || flow.status === true ? t('approval.status.enabled') : t('approval.status.disabled')}
|
||||
</Badge>
|
||||
<Button variant="ghost" size="icon" className="h-8 w-8 text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)]">
|
||||
<Edit className="h-4 w-4" />
|
||||
@@ -173,8 +178,8 @@ export function ApprovalTemplateTab({
|
||||
{renderFlowChart(flow)}
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4 text-sm text-[var(--dg-text-muted)]">
|
||||
<span>创建于 {flow.created_at ? new Date(flow.created_at).toLocaleDateString() : '--'}</span>
|
||||
<span>{parseSteps(flow.steps).length} 个节点</span>
|
||||
<span>{t('approval.flow.createdOn')} {flow.created_at ? new Date(flow.created_at).toLocaleDateString() : '--'}</span>
|
||||
<span>{t('approval.flow.nodeCount', { count: parseSteps(flow.steps).length })}</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in new issue
Block a user