import React, { useEffect, useState } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Loader2, FileText, Tag, AlignLeft, Folder } from 'lucide-react'; import { useToast } from '@/components/ui/use-toast'; import type { WorkflowDefinition, WorkflowCategoryResponse } from '../types'; import { saveDefinition, updateDefinition, getWorkflowCategoryList } from '../service'; interface EditModalProps { visible: boolean; onClose: () => void; onSuccess?: () => void; record?: WorkflowDefinition; } const EditModal: React.FC = ({ visible, onClose, onSuccess, record }) => { const { toast } = useToast(); const isEdit = !!record; const [submitting, setSubmitting] = useState(false); const [categories, setCategories] = useState([]); const [formData, setFormData] = useState({ name: '', key: '', categoryId: undefined as number | undefined, description: '', triggers: [] as string[], }); useEffect(() => { if (visible) { loadCategories(); if (record) { setFormData({ name: record.name, key: record.key, categoryId: record.categoryId, description: record.description || '', triggers: record.triggers || [], }); } else { setFormData({ name: '', key: '', categoryId: undefined, description: '', triggers: [], }); } } }, [visible, record]); const loadCategories = async () => { try { const data = await getWorkflowCategoryList(); setCategories(data); } catch (error) { console.error('加载工作流分类失败:', error); toast({ title: '加载失败', description: '加载工作流分类失败', variant: 'destructive', }); } }; const handleClose = () => { if (!submitting) { onClose(); } }; const handleSubmit = async () => { // 验证 if (!formData.name.trim()) { toast({ title: '验证失败', description: '请输入流程名称', variant: 'destructive', }); return; } if (!formData.key.trim()) { toast({ title: '验证失败', description: '请输入流程标识', variant: 'destructive', }); return; } if (!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(formData.key)) { toast({ title: '验证失败', description: '流程标识只能包含字母、数字、下划线和连字符,且必须以字母或下划线开头', variant: 'destructive', }); return; } if (/^xml/i.test(formData.key)) { toast({ title: '验证失败', description: '流程标识不能以xml开头', variant: 'destructive', }); return; } if (!formData.categoryId) { toast({ title: '验证失败', description: '请选择流程分类', variant: 'destructive', }); return; } setSubmitting(true); try { const submitData: WorkflowDefinition = { ...formData, id: record?.id || 0, flowVersion: isEdit ? record.flowVersion : 1, status: isEdit ? record.status : 'DRAFT', graph: record?.graph || { nodes: [], edges: [] }, formConfig: record?.formConfig || { formItems: [] }, } as WorkflowDefinition; if (isEdit && record) { await updateDefinition(record.id, submitData); toast({ title: '更新成功', description: `工作流 "${formData.name}" 已更新`, }); } else { await saveDefinition(submitData); toast({ title: '创建成功', description: `工作流 "${formData.name}" 已创建`, }); } onSuccess?.(); onClose(); } catch (error) { if (error instanceof Error) { toast({ title: isEdit ? '更新失败' : '创建失败', description: error.message, variant: 'destructive', }); } } finally { setSubmitting(false); } }; const selectedCategory = categories.find(c => c.id === formData.categoryId); return ( {isEdit ? '编辑流程' : '新建流程'}
{/* 流程分类 */}
{isEdit && (

编辑时不可修改分类

)}
{/* 流程名称 */}
setFormData(prev => ({ ...prev, name: e.target.value }))} className="h-10" />
{/* 流程标识 */}
setFormData(prev => ({ ...prev, key: e.target.value }))} disabled={isEdit} className="h-10 font-mono" />

只能包含字母、数字、下划线和连字符,建议使用小写字母和下划线

{/* 描述 */}