import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Card, Typography, Button, Space, Tag, Spin, Empty, Timeline, Progress, Divider } from 'antd'; import { ArrowLeftOutlined, CheckCircleOutlined, ClockCircleOutlined, SyncOutlined, CloseCircleOutlined } from '@ant-design/icons'; import axios from 'axios'; import dayjs from 'dayjs'; const { Title, Paragraph, Text } = Typography; // 节点状态配置 const STATUS_CONFIG: Record = { pending: { color: 'default', text: '待开始', icon: , timelineColor: 'gray' }, in_progress: { color: 'processing', text: '进行中', icon: , timelineColor: 'blue' }, completed: { color: 'success', text: '已完成', icon: , timelineColor: 'green' }, cancelled: { color: 'error', text: '已取消', icon: , timelineColor: 'red' }, }; interface Milestone { id: number; node_name: string; node_type: string; status: string; due_date: string; trigger_condition: string; created_at: string; } const ConstructionMilestones: React.FC = () => { const { id: projectId } = useParams<{ id: string }>(); const navigate = useNavigate(); const [isMobile, setIsMobile] = useState(false); const [milestones, setMilestones] = useState([]); const [projectInfo, setProjectInfo] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const checkMobile = () => setIsMobile(window.innerWidth <= 768); checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); useEffect(() => { if (projectId) { fetchMilestones(); fetchProjectInfo(); } }, [projectId]); const fetchMilestones = async () => { setLoading(true); try { const res = await axios.get(`/api/construction/projects/${projectId}/milestones`); if (res.data.success) { setMilestones(res.data.data); } } catch (error) { console.error('获取节点列表失败:', error); } finally { setLoading(false); } }; const fetchProjectInfo = async () => { try { const res = await axios.get(`/api/projects/${projectId}`); if (res.data.success) { setProjectInfo(res.data.data); } } catch (error) { console.error('获取项目信息失败:', error); } }; // 计算进度 const completedCount = milestones.filter(m => m.status === 'completed').length; const totalCount = milestones.length; const progressPercent = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0; const renderTimelineItem = (milestone: Milestone, index: number) => { const statusConfig = STATUS_CONFIG[milestone.status] || STATUS_CONFIG.pending; return ( {statusConfig.icon} } >
{milestone.node_name} {milestone.trigger_condition && ( {milestone.trigger_condition} )}
{statusConfig.text}
{milestone.due_date && ( 计划完成: {dayjs(milestone.due_date).format('YYYY-MM-DD')} )}
); }; return (
{/* 页面头部 */}
{/* 进度概览 */} {!loading && milestones.length > 0 && (
整体进度 {progressPercent}%
{completedCount}
已完成
{totalCount - completedCount}
进行中
{totalCount}
总节点
)} {/* 节点时间线 */} {loading ? (
) : milestones.length === 0 ? ( 节点由项目经理在项目设置中配置 ) : ( {milestones.map((milestone, index) => renderTimelineItem(milestone, index))} )}
); }; export default ConstructionMilestones;