import React, { useState, useEffect } from 'react'; import { Card, Typography, Button, Space, Tag, Progress, Empty, Spin, message, Row, Col, Divider } from 'antd'; import { FileTextOutlined, CameraOutlined, ScheduleOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import axios from 'axios'; import dayjs from 'dayjs'; import { useAuthStore } from '../../store/authStore'; const { Title, Paragraph, Text } = Typography; // 天气图标映射 const WEATHER_ICONS: Record = { sunny: '☀️ 晴', cloudy: '⛅ 多云', rainy: '🌧️ 雨', stormy: '⛈️ 雷暴', windy: '💨 大风', }; // 项目状态映射 const STATUS_CONFIG: Record = { pending: { color: 'default', text: '待开始' }, active: { color: 'processing', text: '施工中' }, completed: { color: 'success', text: '完工' }, suspended: { color: 'warning', text: '暂停' }, cancelled: { color: 'error', text: '已取消' }, }; interface Project { id: number; project_code: string; name: string; customer_name: string; status: string; start_date: string; expected_end_date: string; contract_amount: number; currency: string; manager_name: string; progress_percentage: number; latest_log?: { id: number; log_date: string; weather: string; work_content: string; }; } const ConstructionList: React.FC = () => { const [isMobile, setIsMobile] = useState(false); const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(true); const navigate = useNavigate(); const { user } = useAuthStore(); useEffect(() => { const checkMobile = () => setIsMobile(window.innerWidth <= 768); checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); useEffect(() => { fetchProjects(); }, []); const fetchProjects = async () => { setLoading(true); try { const res = await axios.get('/api/construction/my-projects'); if (res.data.success) { setProjects(res.data.data); } } catch (error) { console.error('获取项目列表失败:', error); message.error('获取项目列表失败'); } finally { setLoading(false); } }; const formatCurrency = (amount: number, currency: string = 'CNY') => { const symbols: Record = { CNY: '¥', USD: '$', LAK: '₭', THB: '฿', }; const symbol = symbols[currency] || '¥'; return `${symbol}${(amount || 0).toLocaleString('zh-CN', { minimumFractionDigits: 0 })}`; }; const isToday = (dateStr: string) => { return dayjs(dateStr).isSame(dayjs(), 'day'); }; const renderProjectCard = (project: Project) => { const statusConfig = STATUS_CONFIG[project.status] || STATUS_CONFIG.pending; const hasTodayLog = project.latest_log && isToday(project.latest_log.log_date); return ( {/* 项目头部 */}
🎯 {project.name}
客户: {project.customer_name || '未指定'}
{statusConfig.text}
{/* 进度条 */}
施工进度 {Math.round((project.progress_percentage || 0))}%
{/* 最新日志状态 */} {project.status === 'active' && (
{hasTodayLog ? ( <> 今日日志: {project.latest_log?.work_content?.substring(0, 30)}... ) : ( <> ⚠️ 今日日志: 未填写 )}
)} {/* 操作按钮 */}
); }; return (
{/* 页面标题 */}
施工管理
查看和管理您的施工项目
{/* 项目列表 */} {loading ? (
加载中...
) : projects.length === 0 ? ( 请联系管理员为您分配施工项目 ) : (
我的施工项目 ({projects.length}) {projects.map(project => renderProjectCard(project))}
)}
); }; export default ConstructionList;