import { useState } from 'react'; import { Plus, Edit2, Eye, ToggleLeft, ToggleRight, GitBranch, Users, CheckCircle, ArrowRight, Shield, Trash2, X, ChevronDown, ChevronUp, Save, Play } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { workflows as initialWorkflows, dbTypeColorMap } from '@/lib/mock'; type StepType = 'submit' | 'audit' | 'execute'; type FlowStep = { id: string; name: string; type: StepType; assignees: string[]; mode?: 'any' | 'all'; description?: string; }; type WorkflowDetail = { id: number; name: string; dbTypes: string[]; steps: FlowStep[]; description: string; enabled: boolean; conditions?: string[]; }; const stepTypeLabels: Record = { submit: '提交阶段', audit: '审核阶段', execute: '执行阶段', }; const stepTypeColors: Record = { submit: 'bg-blue-500/15 text-blue-400 border-blue-500/30', audit: 'bg-purple-500/15 text-purple-400 border-purple-500/30', execute: 'bg-green-500/15 text-green-400 border-green-500/30', }; const stepTypeIcons: Record = { submit: Users, audit: Shield, execute: Play, }; const defaultSteps: FlowStep[] = [ { id: 'step-1', name: '提交阶段', type: 'submit', assignees: ['工单提交人'], description: '申请人提交 SQL 变更工单' }, { id: 'step-2', name: '一级审批', type: 'audit', assignees: ['部门负责人'], mode: 'any', description: '部门负责人进行一级审批' }, { id: 'step-3', name: '二级审批', type: 'audit', assignees: ['DBA 团队'], mode: 'any', description: 'DBA 进行二级审批' }, { id: 'step-4', name: 'SQL 执行', type: 'execute', assignees: ['DBA 执行人'], description: '审批通过后执行 SQL 变更' }, ]; export default function WorkflowPage() { const [items, setItems] = useState( initialWorkflows.map(w => ({ ...w, steps: defaultSteps.slice(0, Math.min(w.steps + 2, defaultSteps.length)), })) ); const [previewWorkflow, setPreviewWorkflow] = useState(null); const [showCreateModal, setShowCreateModal] = useState(false); const [editingWorkflow, setEditingWorkflow] = useState(null); const [expandedId, setExpandedId] = useState(null); // 新建/编辑表单状态 const [formName, setFormName] = useState(''); const [formDesc, setFormDesc] = useState(''); const [formDbTypes, setFormDbTypes] = useState(['mysql']); const [formSteps, setFormSteps] = useState([defaultSteps[0]]); const [formConditions, setFormConditions] = useState(''); const dbTypes = ['mysql', 'postgres', 'redis', 'mongo']; const resetForm = () => { setFormName(''); setFormDesc(''); setFormDbTypes(['mysql']); setFormSteps([{ ...defaultSteps[0] }]); setFormConditions(''); }; const openCreate = () => { resetForm(); setEditingWorkflow(null); setShowCreateModal(true); }; const openEdit = (wf: WorkflowDetail) => { setFormName(wf.name); setFormDesc(wf.description); setFormDbTypes(wf.dbTypes); setFormSteps([...wf.steps]); setFormConditions(wf.conditions?.join(', ') || ''); setEditingWorkflow(wf); setShowCreateModal(true); }; const toggleWorkflow = (id: number) => { setItems(prev => prev.map(w => w.id === id ? { ...w, enabled: !w.enabled } : w)); }; const deleteWorkflow = (id: number) => { setItems(prev => prev.filter(w => w.id !== id)); }; const addStep = () => { const types: StepType[] = ['audit', 'execute']; const nextType = types[Math.min(formSteps.length - 1, types.length - 1)]; setFormSteps(prev => [...prev, { id: `step-${Date.now()}`, name: nextType === 'audit' ? `第 ${prev.filter(s => s.type === 'audit').length + 1} 级审批` : '执行阶段', type: nextType, assignees: nextType === 'audit' ? ['审批人'] : ['DBA 执行人'], mode: 'any', description: '', }]); }; const removeStep = (stepId: string) => { if (formSteps.length <= 1) return; setFormSteps(prev => prev.filter(s => s.id !== stepId)); }; const updateStep = (stepId: string, updates: Partial) => { setFormSteps(prev => prev.map(s => s.id === stepId ? { ...s, ...updates } : s)); }; const moveStep = (index: number, direction: 'up' | 'down') => { if (direction === 'up' && index === 0) return; if (direction === 'down' && index === formSteps.length - 1) return; const newIndex = direction === 'up' ? index - 1 : index + 1; setFormSteps(prev => { const arr = [...prev]; [arr[index], arr[newIndex]] = [arr[newIndex], arr[index]]; return arr; }); }; const saveWorkflow = () => { if (!formName.trim()) return; const conditions = formConditions ? formConditions.split(',').map(s => s.trim()).filter(Boolean) : []; if (editingWorkflow) { setItems(prev => prev.map(w => w.id === editingWorkflow.id ? { ...w, name: formName, description: formDesc, dbTypes: formDbTypes, steps: [...formSteps], conditions: conditions.length > 0 ? conditions : undefined, } : w)); } else { const newWf: WorkflowDetail = { id: Date.now(), name: formName, description: formDesc, dbTypes: formDbTypes, steps: [...formSteps], enabled: true, conditions: conditions.length > 0 ? conditions : undefined, }; setItems(prev => [...prev, newWf]); } setShowCreateModal(false); }; const toggleDbType = (dt: string) => { setFormDbTypes(prev => prev.includes(dt) ? prev.filter(d => d !== dt) : [...prev, dt] ); }; return (

审批流程配置

配置多级审批流程模板,支持提交阶段、审核阶段、执行阶段的自定义配置

{[ { label: '流程总数', value: items.length, icon: GitBranch, color: 'text-blue-400', bg: 'bg-blue-400/10' }, { label: '已启用', value: items.filter(w => w.enabled).length, icon: CheckCircle, color: 'text-green-400', bg: 'bg-green-400/10' }, { label: '多级审批', value: items.filter(w => w.steps.filter(s => s.type === 'audit').length > 1).length, icon: Users, color: 'text-purple-400', bg: 'bg-purple-400/10' }, { label: '单级审批', value: items.filter(w => w.steps.filter(s => s.type === 'audit').length === 1).length, icon: Shield, color: 'text-orange-400', bg: 'bg-orange-400/10' }, ].map((s, i) => (
{s.value}
{s.label}
))}
{items.map(wf => { const isExpanded = expandedId === wf.id; return (

{wf.name}

{wf.enabled ? '已启用' : '已禁用'} {wf.steps.length} 个阶段

{wf.description}

适用数据库: {wf.dbTypes.map(dt => ( {dt.toUpperCase()} ))}
{/* 流程可视化 */}
{wf.steps.map((step, i) => { const StepIcon = stepTypeIcons[step.type]; return (
{step.name}
{step.assignees.join(' / ')}
{i < wf.steps.length - 1 && }
); })}
{/* 展开详情 */} {isExpanded && (

流程步骤详情

{wf.steps.map((step) => { const StepIcon = stepTypeIcons[step.type]; return (
{step.name} {stepTypeLabels[step.type]} {step.mode && ( {step.mode === 'any' ? '或签(任一人)' : '会签(全部人)'} )}

{step.description}

执行人: {step.assignees.map((a, j) => ( {a} ))}
); })} {wf.conditions && (
触发条件: {wf.conditions.map(c => ( {c} ))}
)}
)}
); })}
{/* 预览弹窗 */} {previewWorkflow && (
setPreviewWorkflow(null)}>
e.stopPropagation()}>

{previewWorkflow.name} - 流程预览

{previewWorkflow.steps.map((step, i) => { const StepIcon = stepTypeIcons[step.type]; return (
{step.name} {stepTypeLabels[step.type]}

{step.description || '该阶段暂无详细描述'}

负责人: {step.assignees.map((a, j) => ( {a}{j < step.assignees.length - 1 ? ' / ' : ''} ))} {step.mode && ( {step.mode === 'any' ? '或签' : '会签'} )}
{i < previewWorkflow.steps.length - 1 && }
); })}
)} {/* 新建/编辑流程弹窗 */} {showCreateModal && (
setShowCreateModal(false)}>
e.stopPropagation()}>

{editingWorkflow ? '编辑流程' : '新建流程'}

{/* 基本信息 */}

基本信息

setFormName(e.target.value)} className="w-full px-3 py-2 bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg text-sm focus:outline-none focus:border-blue-500" placeholder="例如:钱包平台 SQL 变更流程" />