import { useState } from 'react'; import { cn } from '@/lib/utils'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { CheckSquare, Plus, Search, Clock, CheckCircle, XCircle, User, ArrowRight, Settings, Eye, Edit, GitBranch, } from 'lucide-react'; import { approvalFlows, approvalInstances } from '@/mocks/data'; import type { ApprovalFlow as ApprovalFlowType, ApprovalInstance } from '@/types'; export function ApprovalFlowManager() { const [activeTab, setActiveTab] = useState('instances'); const [searchQuery, setSearchQuery] = useState(''); const [statusFilter, setStatusFilter] = useState('all'); const [selectedInstance, setSelectedInstance] = useState(null); const filteredInstances = approvalInstances.filter((instance) => { const matchesSearch = instance.flowName.toLowerCase().includes(searchQuery.toLowerCase()) || instance.applicantName.toLowerCase().includes(searchQuery.toLowerCase()); const matchesStatus = statusFilter === 'all' || instance.status === statusFilter; return matchesSearch && matchesStatus; }); const getStatusBadge = (status: ApprovalInstance['status']) => { const configs = { pending: { label: '审批中', className: 'border-amber-500/30 text-amber-400 bg-amber-500/10', icon: Clock }, approved: { label: '已通过', className: 'border-emerald-500/30 text-emerald-400 bg-emerald-500/10', icon: CheckCircle }, rejected: { label: '已拒绝', className: 'border-red-500/30 text-red-400 bg-red-500/10', icon: XCircle }, }; const config = configs[status]; return ( {config.label} ); }; // 模拟审批流程图 const renderFlowChart = (flow: ApprovalFlowType) => { return (
{flow.nodes.map((node, index) => (

{node.name}

{node.approvers && (

{node.approvers.join(', ')}

)}
{index < flow.nodes.length - 1 && ( )}
))}
); }; return (
{/* Page Header */}

审批流程

工作流管理与审批处理

{/* Stats Cards */}

待审批

{approvalInstances.filter((i) => i.status === 'pending').length}

已通过

{approvalInstances.filter((i) => i.status === 'approved').length}

已拒绝

{approvalInstances.filter((i) => i.status === 'rejected').length}

流程模板

{approvalFlows.length}

{/* Tabs */} 审批实例 流程模板 我的审批 {/* Filters */}
setSearchQuery(e.target.value)} className="pl-9 h-9 bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500" />
{/* Instances Table */}
流程名称 申请人 状态 当前节点 创建时间 完成时间 操作 {filteredInstances.map((instance) => (
{instance.flowName}
{instance.applicantName}
{getStatusBadge(instance.status)} {instance.currentNode} {new Date(instance.createdAt).toLocaleString()} {instance.completedAt ? new Date(instance.completedAt).toLocaleString() : '--'}
{instance.status === 'pending' && ( <> )}
))}
{approvalFlows.map((flow) => (
{flow.name} {flow.description}
{flow.enabled ? '已启用' : '已停用'}
{renderFlowChart(flow)}
创建于 {new Date(flow.createdAt).toLocaleDateString()} {flow.nodes.length} 个节点
))}

暂无待审批事项

当前没有需要您审批的流程

{/* Instance Detail Dialog */} setSelectedInstance(null)}> {selectedInstance?.flowName} 申请人: {selectedInstance?.applicantName} · 创建于{' '} {selectedInstance && new Date(selectedInstance.createdAt).toLocaleString()}
{/* Approval Timeline */}

审批进度

提交申请 {selectedInstance && new Date(selectedInstance.createdAt).toLocaleString()}

申请人: {selectedInstance?.applicantName}

{selectedInstance?.status === 'approved' ? ( ) : selectedInstance?.status === 'rejected' ? ( ) : ( )}
{selectedInstance?.currentNode} {selectedInstance?.completedAt ? new Date(selectedInstance.completedAt).toLocaleString() : '进行中'}

{selectedInstance?.status === 'pending' ? '等待审批人处理' : selectedInstance?.status === 'approved' ? '审批已通过' : '审批已拒绝'}

{selectedInstance?.status === 'pending' && ( <> )}
); }