大改造:施工进度系统+模板管理+物流收货+分包评分

- 新增5张数据库表:logistics_records, receiving_confirms, project_type_templates, project_phases, subcontractor_events
- 修改3张表:projects(增加type_template_id/current_phase/phase_progress), purchase_orders(增加expected_delivery_date/receiving_status), subcontractors(增加score/initial_score)
- 插入5套预设工程模板(配电安装/架空线路/电缆敷设/变电站/小型工程)
- 后端新增:模板管理API、项目阶段管理API、收货确认API、分包商事件API
- 后端修改:项目创建/预算签约支持模板选择,自动初始化阶段
- 前端新增:工程模板设计器(后台管理)、施工总览页、施工进度页(手机友好)
- 前端修改:项目详情页重构为7个Tab,增加施工进度预览条和进入施工管理按钮
- 菜单更新:施工管理增加施工总览子菜单,后台管理增加工程模板管理
This commit is contained in:
root
2026-05-15 12:25:08 +08:00
parent fad28741bd
commit cc5d96e226
13 changed files with 1761 additions and 648 deletions
+22 -23
View File
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { Tabs, Card, Descriptions, Button, Table, Tag, Progress, Space, message, Spin, Select, Menu, Dropdown, Modal, Form, Input, InputNumber, Switch, Upload, DatePicker } from 'antd'
import dayjs from 'dayjs'
import { DownOutlined, UploadOutlined } from '@ant-design/icons'
import { DownOutlined, UploadOutlined, ToolOutlined } from '@ant-design/icons'
import {
ArrowLeftOutlined,
EditOutlined,
@@ -945,13 +945,19 @@ const ProjectDetail: React.FC = () => {
<h2 style={{ margin: 0 }}>{project.name}</h2>
<Space style={{ marginTop: 8 }}>
{getStatusTag(project.status)}
<span>进度: 60%</span>
{/* 从付款节点中查找质保金节点,显示质保金金额 */}
{project.current_phase && <Tag color="blue">: {project.current_phase}</Tag>}
{project.phase_progress > 0 && <span>: {project.phase_progress}%</span>}
<span>: ¥{(milestones.find(m => m.milestone_name === '质保金')?.amount || 0).toLocaleString()}</span>
</Space>
</div>
<Button icon={<EditOutlined />}></Button>
<Space>
<Button icon={<ToolOutlined />} type="primary" onClick={() => navigate(`/construction/progress/${id}`)}></Button>
<Button icon={<EditOutlined />} onClick={() => setBasicInfoEditModalVisible(true)}></Button>
</Space>
</div>
{project.phase_progress > 0 && (
<Progress percent={project.phase_progress} style={{ marginTop: 12 }} strokeColor="#1890ff" />
)}
</Card>
{isMobile ? (
@@ -962,13 +968,12 @@ const ProjectDetail: React.FC = () => {
onChange={setActiveTab}
options={[
{ value: 'basic', label: '基本信息' },
{ value: 'contract', label: '合同详情' },
{ value: 'contract', label: '合同与收款' },
{ value: 'subcontract', label: '分包管理' },
{ value: 'material', label: '材料管理' },
{ value: 'milestone', label: '施工节点' },
{ value: 'log', label: '施工日志' },
{ value: 'finance', label: '财务信息' },
{ value: 'warranty', label: '质保金' }
{ value: 'finance', label: '财务收支' },
{ value: 'warranty', label: '质保金' },
{ value: 'log', label: '施工日志' }
]}
/>
<div style={{ marginTop: 16 }}>
@@ -976,10 +981,9 @@ const ProjectDetail: React.FC = () => {
{activeTab === 'contract' && <ContractTab />}
{activeTab === 'subcontract' && <SubcontractTab />}
{activeTab === 'material' && <MaterialTab />}
{activeTab === 'milestone' && <MilestoneTab />}
{activeTab === 'log' && <LogTab />}
{activeTab === 'finance' && <FinanceTab />}
{activeTab === 'warranty' && <WarrantyTab />}
{activeTab === 'log' && <LogTab />}
</div>
</div>
) : (
@@ -995,7 +999,7 @@ const ProjectDetail: React.FC = () => {
},
{
key: 'contract',
label: <span><FileTextOutlined /> </span>,
label: <span><FileTextOutlined /> </span>,
children: <ContractTab />
},
{
@@ -1008,25 +1012,20 @@ const ProjectDetail: React.FC = () => {
label: <span><DatabaseOutlined /> </span>,
children: <MaterialTab />
},
{
key: 'milestone',
label: <span><CheckCircleOutlined /> </span>,
children: <MilestoneTab />
},
{
key: 'log',
label: <span><FileSearchOutlined /> </span>,
children: <LogTab />
},
{
key: 'finance',
label: <span><DollarOutlined /> </span>,
label: <span><DollarOutlined /> </span>,
children: <FinanceTab />
},
{
key: 'warranty',
label: <span><SafetyOutlined /> </span>,
children: <WarrantyTab />
},
{
key: 'log',
label: <span><FileSearchOutlined /> </span>,
children: <LogTab />
}
]}
/>