diff --git a/src/pages/smartinspection/components/Inspectiontaskplan/DataAnalysisInspectionManagement.js b/src/pages/smartinspection/components/Inspectiontaskplan/DataAnalysisInspectionManagement.js new file mode 100644 index 0000000..29db40d --- /dev/null +++ b/src/pages/smartinspection/components/Inspectiontaskplan/DataAnalysisInspectionManagement.js @@ -0,0 +1,483 @@ +import { useState } from "react"; +import styles from './InspectionTaskPlan.less'; +import { Button, Card, Col, Row, Table, Tabs, Input, Space, Modal, Tag, Tree } from "antd"; +import { SearchOutlined, DownloadOutlined, PlusOutlined, DownOutlined, RightOutlined, ReloadOutlined } from "@ant-design/icons"; + +// 自定义树节点图标 +const TreeNode = Tree.TreeNode; + +// 设备树数据 +const deviceTreeData = [ + { + title: "407输送机", + key: "407", + expanded: true, + children: [ + { + title: "托辊组 (600)", + key: "407_rollers", + children: [ + { title: "1#托辊组", key: "407_roller_1" }, + { title: "2#托辊组", key: "407_roller_2" }, + { title: "3#托辊组", key: "407_roller_3" }, + { title: "4#托辊组", key: "407_roller_4" } + ] + }, + { + title: "电机 (2)", + key: "407_motors", + children: [ + { title: "1#电机", key: "407_motor_1" }, + { title: "2#电机", key: "407_motor_2" } + ] + }, + { + title: "减速器 (2)", + key: "407_reducers", + children: [ + { title: "1#减速器", key: "407_reducer_1" }, + { title: "2#减速器", key: "407_reducer_2" } + ] + }, + { title: "滚筒 (2)", key: "407_drums" }, + { title: "输送带", key: "407_belt" }, + { title: "物料溜槽", key: "407_chute" } + ] + }, + { + title: "MA501输送机", + key: "MA501", + expanded: false + }, + { + title: "PM105输送机", + key: "PM105", + expanded: false + } +]; + + +const { TabPane } = Tabs; +const { Search } = Input; + +// 数据分析巡检管理组件 +const DataAnalysisInspectionManagement = () => { + const [activeKey, setActiveKey] = useState('1'); + const [query, setQuery] = useState(''); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [detailVisible, setDetailVisible] = useState(false); + const [currentRecord, setCurrentRecord] = useState(null); + const [expandedKeys, setExpandedKeys] = useState(['407', '407_rollers', '407_motors', '407_reducers']); + const [selectedKeys, setSelectedKeys] = useState(['407_roller_1']); + + // 处理树节点展开/折叠 + const onExpand = (expandedKeysValue) => { + setExpandedKeys(expandedKeysValue); + }; + + // 处理树节点选择 + const onSelect = (selectedKeysValue) => { + setSelectedKeys(selectedKeysValue); + }; + + // 渲染设备树 + const renderDeviceTree = () => { + const renderTreeNodes = (data) => { + return data.map((item) => { + if (item.children) { + return ( + + {renderTreeNodes(item.children)} + + ); + } + return ; + }); + }; + + return ( +
+

设备层级导航

+ + {renderTreeNodes(deviceTreeData)} + +
+ ); + }; + + // 表格列配置 + const columns = [ + { + title: '序号', + dataIndex: 'id', + key: 'id', + width: 80, + align: 'center', + }, + { + title: '设备/部件', + dataIndex: 'device', + key: 'device', + width: 150, + render: (text) => {text}, + }, + { + title: '运行时长', + dataIndex: 'duration', + key: 'duration', + width: 120, + align: 'center', + }, + { + title: '异常类型', + dataIndex: 'type', + key: 'type', + width: 120, + align: 'center', + render: (t) => { + let color = 'green'; + if (t === '温度预警') color = 'orange'; + if (t === '异常') color = 'red'; + return {t}; + }, + }, + { + title: '环境温度', + dataIndex: 'temperature', + key: 'temperature', + width: 120, + align: 'center', + }, + { + title: '处理状态', + dataIndex: 'status', + key: 'status', + width: 120, + align: 'center', + render: (status) => { + let color = '#006665'; + if (status === '待检修') color = '#ff6600'; + return {status}; + }, + }, + ]; + + // 表格数据(示例) + const initialData = [ + { + key: 1, + id: 1, + device: '407输送机1#托辊组', + duration: '300小时', + type: '无异常', + temperature: '25.5℃', + status: '正常', + }, + { + key: 2, + id: 2, + device: '407输送机1#电机', + duration: '280小时', + type: '温度预警', + temperature: '48℃', + status: '待检修', + }, + { + key: 3, + id: 3, + device: '407输送机2#托辊组', + duration: '290小时', + type: '无异常', + temperature: '26.2℃', + status: '正常', + }, + { + key: 4, + id: 4, + device: '407输送机2#电机', + duration: '275小时', + type: '无异常', + temperature: '45℃', + status: '正常', + }, + { + key: 5, + id: 5, + device: '407输送机3#托辊组', + duration: '285小时', + type: '无异常', + temperature: '25.8℃', + status: '正常', + }, + { + key: 6, + id: 6, + device: '407输送机1#减速器', + duration: '310小时', + type: '无异常', + temperature: '32℃', + status: '正常', + }, + { + key: 7, + id: 7, + device: '407输送机2#减速器', + duration: '305小时', + type: '无异常', + temperature: '33℃', + status: '正常', + }, + { + key: 8, + id: 8, + device: '407输送机滚筒', + duration: '315小时', + type: '无异常', + temperature: '28℃', + status: '正常', + }, + { + key: 9, + id: 9, + device: '407输送机输送带', + duration: '320小时', + type: '无异常', + temperature: '27℃', + status: '正常', + }, + { + key: 10, + id: 10, + device: '407输送物料溜槽', + duration: '300小时', + type: '无异常', + temperature: '26℃', + status: '正常', + }, + ]; + + const [data, setData] = useState(initialData); + + function openDetail(record) { + setCurrentRecord(record); + setDetailVisible(true); + } + + function closeDetail() { + setDetailVisible(false); + setCurrentRecord(null); + } + + function handleSearch(value) { + setQuery(value); + // 简单本地过滤示例 — 实际请接后端 + const filtered = initialData.filter((r) => r.device.includes(value) || String(r.id) === value); + setData(filtered); + setPage(1); + } + + function handleExport() { + // 简单 CSV 导出示例 + const headers = ['id', 'device', 'duration', 'type', 'temperature', 'status']; + const rows = data.map((r) => headers.map((h) => (r[h] ?? '')).join(',')); + const csv = [headers.join(','), ...rows].join('\n'); + const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'data_analysis_export.csv'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } + + return ( +
+ + {/* 左侧设备导航树 */} + + + {renderDeviceTree()} + + + + {/* 右侧主要内容区域 */} + + {/* 设备拓扑和环境监测区域 */} + + {/* 设备拓扑可视化 */} + + +
+
+
+
+
+ 正常 +
+
+
+ 预警 +
+
+
+ 异常 +
+
+
+

407/输送机

+

长度 1900mm,宽度 2500mm

+
+
+
+ {/* 设备拓扑图占位 */} +
+
+
+ + + +
+
+
+ + + {/* 巡检区域环境监测 */} + + +
+
+
+
温度
+
26°C
+
+
+
湿度
+
55%RH
+
+
+
甲烷
+
0.0%
+
+
+
一氧化碳
+
4.0ppm
+
+
+
粉尘(PM2.5)
+
16μg/m³
+
+
+
+ {/* 热成像图占位 */} +
+
+ + +
+
+
+
+ +
+ + + + + + } + allowClear + style={{ width: 320 }} + className={styles.searchInput} + /> + + + + + +
数据更新时间:2025-12-15 10:00
+ +
+
+ + + + + + + `共${total}条`, + pageSizeOptions: ['10', '20', '50'], + onChange: (p, ps) => { + setPage(p); + setPageSize(ps); + }, + // 确保分页样式与界面一致 + className: styles.tablePagination + }} + bordered + // 添加表格样式 + className={styles.historyTable} + // 行悬停效果 + onRow={(record) => ({ + onClick: () => openDetail(record), + style: { + cursor: 'pointer', + '&:hover': { + backgroundColor: 'rgba(0, 102, 101, 0.05)' + } + } + })} + /> + + + + +

实时数据监控

+

显示关键指标、趋势图和告警列表(此处为占位)

+
+
图表占位
+
告警列表占位
+
+
+
+ + + + + + {currentRecord ? ( +
+

设备:{currentRecord.device}

+

运行时长:{currentRecord.duration}

+

异常类型:{currentRecord.type}

+

环境温度:{currentRecord.temperature}

+

处理状态:{currentRecord.status}

+
趋势图/更多信息占位
+
+ ) : null} +
+ + ); +}; + +export default DataAnalysisInspectionManagement; \ No newline at end of file diff --git a/src/pages/smartinspection/components/Inspectiontaskplan/InspectionTaskPlan.less b/src/pages/smartinspection/components/Inspectiontaskplan/InspectionTaskPlan.less index a44332a..8b0a8e4 100644 --- a/src/pages/smartinspection/components/Inspectiontaskplan/InspectionTaskPlan.less +++ b/src/pages/smartinspection/components/Inspectiontaskplan/InspectionTaskPlan.less @@ -249,4 +249,318 @@ box-shadow: -2px 4px 10px 0px rgba(145, 145, 145, 0.05), -7px 17px 18px 0px rgba(145, 145, 145, 0.04), -15px 37px 24px 0px rgba(145, 145, 145, 0.03); +} + +// 设备树样式 +.deviceTreeCard { + height: calc(100vh - 200px); + overflow-y: auto; + background: rgba(255, 255, 255, 0.3); + border: 1px solid; + border-image-source: conic-gradient(from 102.21deg at 52.75% 38.75%, rgba(249, 249, 249, 0.5) -32.95deg, rgba(64, 64, 64, 0.5) 10.52deg, rgba(64, 64, 64, 0.35) 32.12deg, #FFFFFF 60.28deg, rgba(255, 255, 255, 0.5) 107.79deg, rgba(64, 64, 64, 0.35) 187.59deg, #F9F9F9 207.58deg, #FFFFFF 287.31deg, rgba(249, 249, 249, 0.5) 327.05deg, rgba(64, 64, 64, 0.5) 370.52deg); + backdrop-filter: blur(15px); + box-shadow: -2px 4px 10px 0px rgba(145, 145, 145, 0.05), + -7px 17px 18px 0px rgba(145, 145, 145, 0.04), + -15px 37px 24px 0px rgba(145, 145, 145, 0.03); +} + +.deviceTreeContainer { + h3 { + font-size: 16px; + font-weight: bold; + color: #006665; + margin-bottom: 16px; + } + + :global(.ant-tree) { + background: transparent; + } + + :global(.ant-tree-node-content-wrapper) { + color: #006665; + } + + :global(.ant-tree-node-selected) { + background-color: rgba(0, 102, 101, 0.1) !important; + } +} + +// 拓扑可视化样式 +.topologyContainer { + height: 300px; + background: rgba(255, 255, 255, 0.3); + border: 1px solid; + border-image-source: conic-gradient(from 102.21deg at 52.75% 38.75%, rgba(249, 249, 249, 0.5) -32.95deg, rgba(64, 64, 64, 0.5) 10.52deg, rgba(64, 64, 64, 0.35) 32.12deg, #FFFFFF 60.28deg, rgba(255, 255, 255, 0.5) 107.79deg, rgba(64, 64, 64, 0.35) 187.59deg, #F9F9F9 207.58deg, #FFFFFF 287.31deg, rgba(249, 249, 249, 0.5) 327.05deg, rgba(64, 64, 64, 0.5) 370.52deg); + backdrop-filter: blur(15px); + box-shadow: -2px 4px 10px 0px rgba(145, 145, 145, 0.05), + -7px 17px 18px 0px rgba(145, 145, 145, 0.04), + -15px 37px 24px 0px rgba(145, 145, 145, 0.03); +} + +.topologyContent { + height: 100%; + display: flex; + flex-direction: column; +} + +.topologyInfo { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; +} + +.statusIndicators { + display: flex; + gap: 16px; +} + +.statusItem { + display: flex; + align-items: center; + gap: 4px; + font-size: 14px; +} + +.statusDot { + width: 10px; + height: 10px; + border-radius: 50%; +} + +.deviceInfo { + text-align: right; + font-size: 14px; + color: #006665; + + p { + margin: 0; + } +} + +.topologyImage { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(255, 255, 255, 0.5); + border-radius: 4px; + margin-bottom: 16px; +} + +.conveyorBelt { + width: 80%; + height: 60px; + background-color: #e0e0e0; + border-radius: 4px; + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: repeating-linear-gradient(90deg, + transparent, + transparent 20px, + rgba(0, 0, 0, 0.1) 20px, + rgba(0, 0, 0, 0.1) 22px); + border-radius: 4px; + } +} + +.topologyControls { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.controlBtn { + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + background-color: rgba(0, 102, 101, 0.1); + border: 1px solid rgba(0, 102, 101, 0.3); + color: #006665; + + &:hover { + background-color: rgba(0, 102, 101, 0.2); + } +} + +/* 环境监测样式 */ +.environmentContainer { + .ant-card-head { + background-color: #006665; + color: #fff; + } + + .ant-card-body { + padding: 16px; + } +} + +.dashboardMetrics { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-bottom: 16px; + + .metricItem { + flex: 1; + min-width: 80px; + text-align: center; + background-color: rgba(255, 255, 255, 0.9); + padding: 8px; + border-radius: 4px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + + .metricLabel { + font-size: 12px; + color: #666; + margin-bottom: 4px; + } + + .metricValue { + font-size: 16px; + font-weight: bold; + color: #006665; + } + } +} + +.thermalImageContainer { + position: relative; + width: 100%; + height: 160px; + background-color: #f0f2f5; + border-radius: 4px; + overflow: hidden; + + .thermalImage { + width: 100%; + height: 100%; + background: linear-gradient(135deg, #006665 0%, #00b3b1 50%, #ff6b35 100%); + opacity: 0.8; + display: flex; + align-items: center; + justify-content: center; + color: #fff; + font-size: 14px; + } + + .thermalControls { + position: absolute; + bottom: 8px; + right: 8px; + display: flex; + gap: 4px; + + .controlBtn { + width: 28px; + height: 28px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background-color: rgba(0, 102, 101, 0.8); + border-color: rgba(0, 102, 101, 0.8); + color: #fff; + font-size: 16px; + + &:hover { + background-color: rgba(0, 102, 101, 1); + border-color: rgba(0, 102, 101, 1); + color: #fff; + } + } + } +} + +/* 历史数据表格样式 */ +.historyTable { + width: 100%; + border-collapse: separate; + border-spacing: 0; + + .ant-table-thead>tr>th { + background-color: rgba(0, 102, 101, 0.1); + color: #006665; + font-weight: bold; + border: 1px solid rgba(0, 102, 101, 0.2); + } + + .ant-table-tbody>tr>td { + border: 1px solid rgba(0, 102, 101, 0.2); + vertical-align: middle; + } + + .ant-table-tbody>tr:hover>td { + background-color: rgba(0, 102, 101, 0.05); + } +} + +/* 表格分页样式 */ +.tablePagination { + .ant-pagination-item-active a { + color: #006665; + border-color: #006665; + } + + .ant-pagination-item-active { + border-color: #006665; + } + + .ant-pagination-item:hover { + border-color: #006665; + } + + .ant-pagination-item:hover a { + color: #006665; + } +} + +/* 数据更新时间样式 */ +.dataUpdateTime { + font-size: 14px; + color: #666; + margin-top: 8px; +} + +/* 搜索框和按钮样式 */ +.searchContainer { + .ant-input { + border-color: rgba(0, 102, 101, 0.2); + } + + .ant-input:focus { + border-color: #006665; + box-shadow: 0 0 0 2px rgba(0, 102, 101, 0.2); + } + + .ant-btn-primary { + background-color: #006665; + border-color: #006665; + + &:hover { + background-color: #00807f; + border-color: #00807f; + } + } + + .ant-btn { + border-color: #006665; + color: #006665; + + &:hover { + border-color: #00807f; + color: #00807f; + background-color: rgba(0, 102, 101, 0.05); + } + } } \ No newline at end of file diff --git a/src/pages/smartinspection/components/Inspectiontaskplan/SmartInspectionPlan.js b/src/pages/smartinspection/components/Inspectiontaskplan/SmartInspectionPlan.js index d0f1015..fe4fc1e 100644 --- a/src/pages/smartinspection/components/Inspectiontaskplan/SmartInspectionPlan.js +++ b/src/pages/smartinspection/components/Inspectiontaskplan/SmartInspectionPlan.js @@ -20,6 +20,8 @@ import inspectionBg from '@/assets/img/Rectangle 34624130.svg' import taskPlanBg from '@/assets/img/image 674 1.svg' import { DeleteOutlined, DownOutlined, EditOutlined, ExportOutlined, EyeOutlined, PlusOutlined, RedoOutlined, ReloadOutlined as IconRefresh, SearchOutlined as IconSearch } from "@ant-design/icons"; import TemperatureHumidityGauges from '../ReusableGauges/ReusableGauges'; +// 新增导入 +import DataAnalysisInspectionManagement from './DataAnalysisInspectionManagement'; const { Search } = Input // TaskCard 组件 - 用于显示巡检任务卡片 @@ -2493,6 +2495,10 @@ const items = [ label: , key: '巡检管理', }, + { + label: , + key: '数据分析巡检管理', + }, ] const InspectionManagement = () => { const [activeTab, setActiveTab] = useState('实时监控'); @@ -2873,6 +2879,7 @@ const list = { '智能巡检范围监控': , '巡检内容': , '任务规划与执行流程': , + '数据分析巡检管理': , // 添加新组件 } const InspectionTaskPlan = () => { const [current, setCurrent] = useState('智能巡检范围监控')