import React, { useEffect, useState, useRef } from 'react'; import { Search, Plus, Upload, MoreHorizontal, Code, Edit2, Copy, Trash2, Calendar, CloudUpload, File as FileIcon, X, Layout, FilePlus } from 'lucide-react'; import { Button, Input, TableHeader, TableRow, TableHead, TableCell, Dialog, Card } from '../components/UI'; import { useNavigate } from 'react-router-dom'; import { Workflow } from '../types'; import { deleteWorkflow, fetchWorkflows } from '../services/backendApi'; export const WorkflowsPage: React.FC = () => { const navigate = useNavigate(); const [workflows, setWorkflows] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [isUploadOpen, setIsUploadOpen] = useState(false); const [isCreateOpen, setIsCreateOpen] = useState(false); const [activeMenu, setActiveMenu] = useState(null); const [isLoading, setIsLoading] = useState(true); const [newWfName, setNewWfName] = useState(''); const [selectedTemplate, setSelectedTemplate] = useState<'blank' | 'lead'>('blank'); const filteredWorkflows = workflows.filter(wf => wf.name.toLowerCase().includes(searchTerm.toLowerCase()) ); useEffect(() => { const loadWorkflows = async () => { setIsLoading(true); try { const list = await fetchWorkflows(); setWorkflows(list); } catch (error) { console.error(error); alert('加载工作流失败,请检查后端服务。'); } finally { setIsLoading(false); } }; loadWorkflows(); }, []); const handleCreateWorkflow = () => { if (!newWfName.trim()) { alert('请输入工作流名称'); return; } setIsCreateOpen(false); navigate(`/workflows/new?name=${encodeURIComponent(newWfName)}&template=${selectedTemplate}`); }; const handleDeleteWorkflow = async (id: string) => { if (confirm('确定要删除这个工作流吗?')) { try { await deleteWorkflow(id); setWorkflows(prev => prev.filter(w => w.id !== id)); setActiveMenu(null); } catch (error) { console.error(error); alert('删除工作流失败。'); } } }; return (

工作流

setSearchTerm(e.target.value)} />
名称 节点数量 创建时间 更新时间 操作 {!isLoading && filteredWorkflows.map(wf => ( {wf.nodeCount} 个节点 {wf.createdAt} {wf.updatedAt} {activeMenu === wf.id && (
)} ))} {!isLoading && filteredWorkflows.length === 0 && ( 暂无工作流数据 )} {isLoading && ( 加载中... )}
setIsUploadOpen(false)} /> setIsCreateOpen(false)} title="创建新工作流" footer={ <> } >
setNewWfName(e.target.value)} placeholder="例如: Lead Qualification Agent" autoFocus />
setSelectedTemplate('blank')} className={`p-4 rounded-xl border-2 cursor-pointer transition-all flex flex-col items-center text-center space-y-2 ${selectedTemplate === 'blank' ? 'border-primary bg-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10'}`} >
空白模板
从零开始构建
setSelectedTemplate('lead')} className={`p-4 rounded-xl border-2 cursor-pointer transition-all flex flex-col items-center text-center space-y-2 ${selectedTemplate === 'lead' ? 'border-primary bg-primary/10' : 'border-white/5 bg-white/5 hover:bg-white/10'}`} >
销售获客
标准 Lead 转化逻辑
); }; const UploadJsonModal: React.FC<{ isOpen: boolean; onClose: () => void }> = ({ isOpen, onClose }) => { const [dragActive, setDragActive] = useState(false); const [file, setFile] = useState(null); const inputRef = useRef(null); const handleDrag = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setDragActive(e.type === "dragenter" || e.type === "dragover"); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); if (e.dataTransfer.files?.[0]) setFile(e.dataTransfer.files[0]); }; return ( } >
inputRef.current?.click()} > e.target.files?.[0] && setFile(e.target.files[0])} />

{file ? {file.name} : 点击上传 或将 JSON 文件拖拽到此处}

仅支持 .json 格式的工作流配置文件

); };