feat: 资源申请模块重构——清理816行死代码+提取共享helpers+修复类型标签bug

- 删除 CabinetView.tsx(422行) + ResourceModelManager.tsx(394行) 死代码
- 提取 approval/helpers.tsx 共享辅助函数(parseSteps/parseFields/renderFormData/
  getProgressInfo/renderStepProgress/APPROVAL_TYPE_OPTIONS/getInstanceType)
- 修复审批类型标签bug:instance无type字段,需从template.type取
  (getApprovalTypeLabel/Color/Icon 全部改用 getInstanceType(instance))
- ApprovalFlow.tsx 771→666行(低于700限制)
- ApprovalProcessTab.tsx 移除重复helpers+过期类型字典(deploy/server/permission→server_apply/app_deploy)
This commit is contained in:
attacker committed 2026-06-15 08:07:10 +08:00
1 parent 8c4b59510d
commit f70feb360c
5 files changed
+155 -1020

No files matched your search

@@ -9,40 +9,16 @@ import {
XCircle,
Eye,
Loader2,
GitCommit,
Server,
KeyRound,
FileText,
} from 'lucide-react';
function parseSteps(steps: any) {
if (Array.isArray(steps)) return steps;
if (typeof steps === 'string') {
try {
const parsed = JSON.parse(steps);
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
}
return [];
}
// 审批类型字典
const APPROVAL_TYPE_OPTIONS = [
{ value: 'deploy', label: '发布审批', icon: GitCommit, color: 'var(--dg-blue)' },
{ value: 'server', label: '服务器操作', icon: Server, color: 'var(--dg-cyan)' },
{ value: 'permission', label: '权限申请', icon: KeyRound, color: 'var(--dg-purple)' },
];
const getApprovalTypeLabel = (value: string): string =>
APPROVAL_TYPE_OPTIONS.find((o) => o.value === value)?.label || value || '通用审批';
const getApprovalTypeColor = (value: string): string =>
APPROVAL_TYPE_OPTIONS.find((o) => o.value === value)?.color || 'var(--dg-text-secondary)';
const getApprovalTypeIcon = (value: string): React.ElementType =>
APPROVAL_TYPE_OPTIONS.find((o) => o.value === value)?.icon || FileText;
import {
getProgressInfo,
renderStepProgress,
getApprovalTypeLabel,
getApprovalTypeColor,
getApprovalTypeIcon,
getInstanceType,
} from './helpers';
// 状态标签页定义
const STATUS_TABS = [
@@ -92,54 +68,6 @@ function getStatusBadge(status: string) {
);
}
// 获取进度信息
function getProgressInfo(instance: any) {
const steps = parseSteps(instance.steps);
const currentIndex = instance.current_step ?? 0;
const total = steps.length;
const completed = steps.filter((s: any) => s.status === 'approved' || s.status === 'completed').length;
const percentage = total > 0 ? Math.round((completed / total) * 100) : 0;
return { steps, currentIndex, total, completed, percentage };
}
// 渲染审批进度
function renderStepProgress(instance: any) {
const { steps, currentIndex } = getProgressInfo(instance);
if (steps.length === 0) return null;
return (
<div className="flex items-center gap-1 overflow-x-auto">
{steps.map((step: any, index: number) => {
const isCompleted = step.status === 'approved' || step.status === 'completed';
const isCurrent = index === currentIndex;
const isRejected = step.status === 'rejected';
return (
<div key={step.id || index} className="flex items-center">
<div
className={cn(
'flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs whitespace-nowrap',
isCompleted && 'bg-emerald-500/10 text-emerald-400',
isCurrent && !isRejected && 'bg-amber-500/10 text-amber-400 border border-amber-500/30',
isRejected && 'bg-red-500/10 text-red-400',
!isCompleted && !isCurrent && !isRejected && 'bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-muted)]'
)}
>
{isCompleted && <CheckCircle2 className="h-3 w-3" />}
{isRejected && <XCircle className="h-3 w-3" />}
{isCurrent && !isRejected && (
<Loader2 className="h-3 w-3 animate-spin" />
)}
<span>{step.name || step.approver_name || `步骤 ${index + 1}`}</span>
</div>
{index < steps.length - 1 && (
<div className={cn('w-4 h-px', isCompleted ? 'bg-emerald-500/30' : 'bg-[var(--dg-border)]')} />
)}
</div>
);
})}
</div>
);
}
interface ApprovalProcessTabProps {
processes: any[];
filteredInstances: any[];
@@ -218,14 +146,14 @@ export function ApprovalProcessTab({
) : (
<div className="grid grid-cols-1 gap-4">
{filteredInstances.map((instance) => {
const Icon = getApprovalTypeIcon(instance.type);
const Icon = getApprovalTypeIcon(getInstanceType(instance));
const { percentage } = getProgressInfo(instance);
return (
<Card key={instance.id} className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] hover:border-[var(--dg-border)] transition-colors">
<CardContent className="p-4">
<div className="flex items-start justify-between mb-3">
<div className="flex items-start gap-3">
<div className="w-10 h-10 rounded-lg bg-[var(--dg-bg-tertiary)] flex items-center justify-center" style={{ color: getApprovalTypeColor(instance.type) }}>
<div className="w-10 h-10 rounded-lg bg-[var(--dg-bg-tertiary)] flex items-center justify-center" style={{ color: getApprovalTypeColor(getInstanceType(instance)) }}>
<Icon className="h-5 w-5" />
</div>
<div>
@@ -235,8 +163,8 @@ export function ApprovalProcessTab({
</div>
<div className="flex items-center gap-3 text-xs text-[var(--dg-text-muted)]">
<span className="flex items-center gap-1">
<Badge variant="outline" className="text-xs border-[var(--dg-border)]" style={{ color: getApprovalTypeColor(instance.type) }}>
{getApprovalTypeLabel(instance.type)}
<Badge variant="outline" className="text-xs border-[var(--dg-border)]" style={{ color: getApprovalTypeColor(getInstanceType(instance)) }}>
{getApprovalTypeLabel(getInstanceType(instance))}
</Badge>
</span>
<span>申请人:{instance.applicant_name || instance.applicant || '--'}</span>