diff --git a/src/assets/business_basic/background1.png b/src/assets/business_basic/background1.png new file mode 100644 index 0000000..2065e2f Binary files /dev/null and b/src/assets/business_basic/background1.png differ diff --git a/src/assets/business_basic/download.png b/src/assets/business_basic/download.png new file mode 100644 index 0000000..17e6519 Binary files /dev/null and b/src/assets/business_basic/download.png differ diff --git a/src/assets/business_basic/fire_fighting1.png b/src/assets/business_basic/fire_fighting1.png new file mode 100644 index 0000000..55eae7d Binary files /dev/null and b/src/assets/business_basic/fire_fighting1.png differ diff --git a/src/assets/business_basic/fire_fighting2.png b/src/assets/business_basic/fire_fighting2.png new file mode 100644 index 0000000..1ab52fd Binary files /dev/null and b/src/assets/business_basic/fire_fighting2.png differ diff --git a/src/assets/business_basic/fire_fighting3.png b/src/assets/business_basic/fire_fighting3.png new file mode 100644 index 0000000..04a941f Binary files /dev/null and b/src/assets/business_basic/fire_fighting3.png differ diff --git a/src/assets/business_basic/img1.png b/src/assets/business_basic/img1.png new file mode 100644 index 0000000..55eae7d Binary files /dev/null and b/src/assets/business_basic/img1.png differ diff --git a/src/assets/business_basic/upload.png b/src/assets/business_basic/upload.png new file mode 100644 index 0000000..9661a47 Binary files /dev/null and b/src/assets/business_basic/upload.png differ diff --git a/src/pages/business_basic/module/EvaluationReport.js b/src/pages/business_basic/module/EvaluationReport.js index 03872f5..e98bee6 100644 --- a/src/pages/business_basic/module/EvaluationReport.js +++ b/src/pages/business_basic/module/EvaluationReport.js @@ -1,300 +1,634 @@ -import React, { useState, useEffect } from 'react'; -import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag } from 'antd'; -import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons'; -import './EvaluationReport.less'; +import React, { useEffect, useRef, useState } from 'react'; +import { Card, Result, CheckCircleOutlined, Button } from 'antd'; +import * as echarts from 'echarts'; +import StandardTable from '@/components/StandardTable'; +import styles from './EvaluationReport.less'; + +import img1 from '@/assets/safe_majorHazard/online_monitoring/img1.png'; +import img2 from '@/assets/safe_majorHazard/online_monitoring/img2.png'; +import img3 from '@/assets/safe_majorHazard/online_monitoring/img3.png'; -const { Option } = Select; const EvaluationReport = () => { - const [form] = Form.useForm(); - const [dataSource, setDataSource] = useState([]); - const [loading, setLoading] = useState(false); - const [modalVisible, setModalVisible] = useState(false); - const [editingRecord, setEditingRecord] = useState(null); - const [pagination, setPagination] = useState({ - current: 1, - pageSize: 10, - total: 0, - }); - - // 模拟数据 - const mockData = [ - { - id: 1, - reportName: '2024年第一季度安全评估报告', - reportType: '季度评估', - assessmentPeriod: '2024-01-01 至 2024-03-31', - assessor: '张三', - status: '已完成', - createTime: '2024-04-01 10:00:00', - description: '对第一季度安全生产情况进行全面评估', - }, - { - id: 2, - reportName: '2024年年度安全评估报告', - reportType: '年度评估', - assessmentPeriod: '2024-01-01 至 2024-12-31', - assessor: '李四', - status: '进行中', - createTime: '2024-01-15 14:30:00', - description: '年度安全生产综合评估', - }, - ]; - - useEffect(() => { - fetchData(); - }, [pagination.current, pagination.pageSize]); - - const fetchData = async () => { - setLoading(true); - try { - // 模拟API调用 - setTimeout(() => { - setDataSource(mockData); - setPagination(prev => ({ ...prev, total: mockData.length })); - setLoading(false); - }, 500); - } catch (error) { - message.error('获取数据失败'); - setLoading(false); - } - }; - - const handleAdd = () => { - setEditingRecord(null); - form.resetFields(); - setModalVisible(true); - }; - - const handleEdit = (record) => { - setEditingRecord(record); - form.setFieldsValue(record); - setModalVisible(true); - }; - - const handleDelete = (record) => { - Modal.confirm({ - title: '确认删除', - content: `确定要删除评估报告"${record.reportName}"吗?`, - onOk: () => { - setDataSource(dataSource.filter(item => item.id !== record.id)); - message.success('删除成功'); - }, + const trendChartRef = useRef(null); + const pieChartRef = useRef(null); + const barChartRef = useRef(null); + + // 表格相关状态 + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + const [loading, setLoading] = useState(false); + const [dataSource, setDataSource] = useState([]); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 5, + total: 0, }); - }; - - const handleView = (record) => { - Modal.info({ - title: '查看评估报告', - content: ( -
-

报告名称:{record.reportName}

-

报告类型:{record.reportType}

-

评估周期:{record.assessmentPeriod}

-

评估人:{record.assessor}

-

状态:{record.status}

-

创建时间:{record.createTime}

-

描述:{record.description}

-
- ), - width: 600, - }); - }; - - const handleSubmit = async (values) => { - try { - if (editingRecord) { - // 编辑 - setDataSource(dataSource.map(item => - item.id === editingRecord.id ? { ...item, ...values } : item - )); - message.success('编辑成功'); - } else { - // 新增 - const newRecord = { - id: Date.now(), - ...values, - status: '进行中', - createTime: new Date().toLocaleString(), - }; - setDataSource([...dataSource, newRecord]); - message.success('添加成功'); - } - setModalVisible(false); - form.resetFields(); - } catch (error) { - message.error('操作失败'); - } - }; - - const columns = [ - { - title: '报告名称', - dataIndex: 'reportName', - key: 'reportName', - width: 200, - }, - { - title: '报告类型', - dataIndex: 'reportType', - key: 'reportType', - width: 120, - }, - { - title: '评估周期', - dataIndex: 'assessmentPeriod', - key: 'assessmentPeriod', - width: 200, - }, - { - title: '评估人', - dataIndex: 'assessor', - key: 'assessor', - width: 100, - }, - { - title: '状态', - dataIndex: 'status', - key: 'status', - width: 100, - render: (status) => ( - - {status} - - ), - }, - { - title: '创建时间', - dataIndex: 'createTime', - key: 'createTime', - width: 150, - }, - { - title: '操作', - key: 'action', - width: 200, - render: (_, record) => ( - - - - - - ), - }, - ]; - - return ( -
- } onClick={handleAdd}> - 新增报告 - + + // 隐患趋势分析折线图 + useEffect(() => { + if (trendChartRef.current) { + const chart = echarts.init(trendChartRef.current); + + const option = { + color: ['#FF4D4F', '#FAAD14', '#52C41A'], + legend: { + data: ['重大隐患', '一般隐患', '轻微隐患'], + top: "5px", + left: "center", + itemGap: 20, + textStyle: { + fontSize: 10 + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top: '20%', + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], + axisLabel: { + fontSize: 10 + } + }, + yAxis: { + type: 'value', + axisLabel: { + fontSize: 10 + } + }, + series: [ + { + name: '重大隐患', + type: 'line', + smooth: true, + symbol: 'circle', + symbolSize: 6, + lineStyle: { + width: 2, + color: '#FF4D4F' + }, + itemStyle: { + color: '#FF4D4F', + borderColor: '#FF4D4F', + borderWidth: 2 + }, + data: [12, 8, 15, 10, 18, 14, 20, 16, 22, 19, 25, 21] + }, + { + name: '一般隐患', + type: 'line', + smooth: true, + symbol: 'circle', + symbolSize: 6, + lineStyle: { + width: 2, + color: '#FAAD14' + }, + itemStyle: { + color: '#FAAD14', + borderColor: '#FAAD14', + borderWidth: 2 + }, + data: [25, 30, 28, 35, 32, 38, 40, 36, 42, 38, 45, 41] + }, + { + name: '轻微隐患', + type: 'line', + smooth: true, + symbol: 'circle', + symbolSize: 6, + lineStyle: { + width: 2, + color: '#52C41A' + }, + itemStyle: { + color: '#52C41A', + borderColor: '#52C41A', + borderWidth: 2 + }, + data: [45, 50, 48, 55, 52, 58, 60, 56, 62, 58, 65, 61] + } + ] + }; + + chart.setOption(option); + + const handleResize = () => { + if (chart && !chart.isDisposed()) { + chart.resize(); + } + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + if (chart && !chart.isDisposed()) { + chart.dispose(); + } + }; + } + }, []); + + // 隐患类型分布玫瑰饼图 + useEffect(() => { + if (pieChartRef.current) { + const chart = echarts.init(pieChartRef.current); + + const option = { + color: ['#FF4D4F', '#FAAD14', '#52C41A', '#1890FF', '#722ED1', '#13C2C2'], + legend: { + orient: 'vertical', + left: 'left', + top: 'center', + textStyle: { + fontSize: 10 + } + }, + series: [ + { + name: '隐患类型', + type: 'pie', + radius: ['20%', '70%'], + center: ['60%', '50%'], + roseType: 'area', + itemStyle: { + borderRadius: 5, + borderColor: '#fff', + borderWidth: 2 + }, + label: { + show: true, + formatter: '{b}: {c}', + fontSize: 10 + }, + data: [ + { value: 35, name: '设备故障' }, + { value: 28, name: '操作失误' }, + { value: 22, name: '环境因素' }, + { value: 18, name: '管理缺陷' }, + { value: 15, name: '设计缺陷' }, + { value: 12, name: '其他' } + ] + } + ] + }; + + chart.setOption(option); + + const handleResize = () => { + if (chart && !chart.isDisposed()) { + chart.resize(); + } + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + if (chart && !chart.isDisposed()) { + chart.dispose(); + } + }; + } + }, []); + + // 隐患整改情况柱状图 + useEffect(() => { + if (barChartRef.current) { + const chart = echarts.init(barChartRef.current); + + const option = { + color: ['#FF4D4F', '#FAAD14', '#1890FF', '#52C41A', '#722ED1'], + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top: '10%', + containLabel: true + }, + xAxis: { + type: 'category', + data: ['待处理', '处理中', '待审核', '已完成', '已关闭'], + axisLabel: { + fontSize: 10 + } + }, + yAxis: { + type: 'value', + axisLabel: { + fontSize: 10 + } + }, + series: [ + { + name: '数量', + type: 'bar', + data: [25, 18, 12, 35, 8], + itemStyle: { + borderRadius: [4, 4, 0, 0] + }, + barWidth: '60%' + } + ] + }; + + chart.setOption(option); + + const handleResize = () => { + if (chart && !chart.isDisposed()) { + chart.resize(); + } + }; + + window.addEventListener('resize', handleResize); + + return () => { + window.removeEventListener('resize', handleResize); + if (chart && !chart.isDisposed()) { + chart.dispose(); + } + }; } - > - - `第 ${range[0]}-${range[1]} 条/共 ${total} 条`, - onChange: (page, pageSize) => { - setPagination(prev => ({ - ...prev, - current: page, - pageSize: pageSize || prev.pageSize, - })); - }, - }} - /> - - - { - setModalVisible(false); - form.resetFields(); - }} - onOk={() => form.submit()} - width={600} - > -
- - - - - - - - - - - - - - - - - - - - -
- - ); + }, []); + + // 表格列定义 + const columns = [ + { + title: '编号', + dataIndex: 'id', + key: 'id', + width: 80, + render: (text, record, index) => { + const page = pagination.current || 1; + const pageSize = pagination.pageSize || 5; + const number = (page - 1) * pageSize + index + 1; + return `0${number}`.slice(-2); + } + }, + { + title: '报告名称', + dataIndex: 'reportName', + key: 'reportName', + width: 200, + }, + { + title: '类型', + dataIndex: 'type', + key: 'type', + width: 120, + }, + { + title: '上传时间', + dataIndex: 'uploadTime', + key: 'uploadTime', + width: 150, + }, + { + title: '版本', + dataIndex: 'version', + key: 'version', + width: 80, + }, + { + title: '状态', + dataIndex: 'status', + key: 'status', + width: 100, + render: (text) => { + const statusMap = { + '已完成': { color: '#52C41A', bg: '#F6FFED' }, + '处理中': { color: '#FAAD14', bg: '#FFFBE6' }, + '待审核': { color: '#1890FF', bg: '#E6F7FF' } + }; + const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' }; + return ( + + {text} + + ); + } + }, + { + title: '上传人', + dataIndex: 'uploader', + key: 'uploader', + width: 100, + }, + { + title: '操作', + key: 'action', + width: 80, + render: (_, record) => ( +
+ +
+ ), + }, + ]; + + // 模拟数据 + const mockData = [ + { + key: '1', + id: '001', + reportName: '2024年第一季度安全评估报告', + type: '季度报告', + uploadTime: '2024-01-15 08:30:25', + version: 'V1.0', + status: '已完成', + uploader: '张三', + }, + { + key: '2', + id: '002', + reportName: '重大危险源专项评估报告', + type: '专项报告', + uploadTime: '2024-01-15 09:15:10', + version: 'V2.1', + status: '处理中', + uploader: '李四', + }, + { + key: '3', + id: '003', + reportName: '年度安全风险评估报告', + type: '年度报告', + uploadTime: '2024-01-15 10:45:30', + version: 'V1.5', + status: '待审核', + uploader: '王五', + }, + { + key: '4', + id: '004', + reportName: '设备安全评估报告', + type: '设备报告', + uploadTime: '2024-01-15 11:20:45', + version: 'V1.2', + status: '已完成', + uploader: '赵六', + }, + { + key: '5', + id: '005', + reportName: '应急预案评估报告', + type: '应急报告', + uploadTime: '2024-01-15 12:10:20', + version: 'V3.0', + status: '已完成', + uploader: '孙七', + }, + { + key: '6', + id: '006', + reportName: '环境安全评估报告', + type: '环境报告', + uploadTime: '2024-01-15 13:25:15', + version: 'V1.8', + status: '处理中', + uploader: '周八', + }, + { + key: '7', + id: '007', + reportName: '人员安全培训评估报告', + type: '培训报告', + uploadTime: '2024-01-15 14:10:30', + version: 'V2.3', + status: '待审核', + uploader: '吴九', + }, + { + key: '8', + id: '008', + reportName: '消防安全评估报告', + type: '消防报告', + uploadTime: '2024-01-15 15:45:20', + version: 'V1.1', + status: '已完成', + uploader: '郑十', + }, + { + key: '9', + id: '009', + reportName: '化学品安全评估报告', + type: '化学品报告', + uploadTime: '2024-01-15 16:30:45', + version: 'V2.0', + status: '处理中', + uploader: '钱十一', + }, + { + key: '10', + id: '010', + reportName: '职业健康安全评估报告', + type: '职业健康报告', + uploadTime: '2024-01-15 17:15:10', + version: 'V1.6', + status: '已完成', + uploader: '陈十二', + }, + { + key: '11', + id: '011', + reportName: '安全管理制度评估报告', + type: '制度报告', + uploadTime: '2024-01-15 18:20:35', + version: 'V1.3', + status: '待审核', + uploader: '刘十三', + }, + { + key: '12', + id: '012', + reportName: '安全投入评估报告', + type: '投入报告', + uploadTime: '2024-01-15 19:05:50', + version: 'V1.9', + status: '已完成', + uploader: '黄十四', + }, + ]; + + // 初始化数据 + useEffect(() => { + setPagination(prev => ({ ...prev, total: mockData.length })); + }, []); + + // 根据分页获取当前页数据 + const getCurrentPageData = () => { + const { current, pageSize } = pagination; + const startIndex = (current - 1) * pageSize; + const endIndex = startIndex + pageSize; + return mockData.slice(startIndex, endIndex); + }; + + // 表格选择变化 + const onSelectChange = (newSelectedRowKeys, newSelectedRows) => { + setSelectedRowKeys(newSelectedRowKeys); + setSelectedRows(newSelectedRows); + }; + + // 分页变化处理 + const handleTableChange = (pagination) => { + setPagination(prev => ({ + ...prev, + current: pagination.current, + pageSize: pagination.pageSize, + })); + }; + + return ( +
+ {/* 第一个大块 - 高度16% */} +
+
+
+ {/* 块1 */} +
+
+
总危险源数量
+
65
+
+ + 较昨日 +2 +
+
+
+ 总危险源数量 +
+
+ + {/* 块2 */} +
+
+
高风险设备
+
65
+
+ + 较昨日 +2 +
+
+
+ 高风险设备 +
+
+ + {/* 块3 */} +
+
+
今日预警次数
+
65
+
+ + 较昨日 +2 +
+
+
+ 今日预警次数 +
+
+ + {/* 块4 */} +
+
+
未处理预警
+
65
+
+ + 较昨日 +2 +
+
+
+ 未处理预警 +
+
+
+
+
+ + {/* 第二个大块 - 三个图表块 */} +
+
+ {/* 第一个小块 - 隐患趋势分析 */} +
+
+
+
隐患趋势分析
+
+
+
+ + {/* 第二个小块 - 隐患类型分布 */} +
+
+
+
隐患类型分布
+
+
+
+ + {/* 第三小块 - 隐患整改情况 */} +
+
+
+
隐患整改情况
+
+
+
+
+
+ + {/* 第三大块 - 评估报告表格 */} +
+ {/* 首行 左侧标题左对齐 右侧按钮右对齐 */} +
+
+
+
评估报告
+
+
+ + {/* 表格 5行8列 带页码 每页5条数据 */} +
+ + `共 ${total} 条`, + }} + scroll={{ x: 1000 }} + /> +
+
+
+ ); }; -export default EvaluationReport; +export default EvaluationReport; \ No newline at end of file diff --git a/src/pages/business_basic/module/EvaluationReport.less b/src/pages/business_basic/module/EvaluationReport.less index 4186bb8..9ac7a4d 100644 --- a/src/pages/business_basic/module/EvaluationReport.less +++ b/src/pages/business_basic/module/EvaluationReport.less @@ -1,115 +1,225 @@ -.evaluation-report { - padding: 20px; - - .ant-card { - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - border-radius: 6px; - - .ant-card-head { - border-bottom: 1px solid #f0f0f0; - - .ant-card-head-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } +.Econtainer { + padding: 8px 6px 0px 6px; + height: 100%; + display: flex; + flex-direction: column; + gap: 10px; - .ant-card-body { - padding: 20px; - } - } - - .ant-table { - .ant-table-thead > tr > th { - background-color: #fafafa; - font-weight: 600; - color: #262626; - border-bottom: 1px solid #f0f0f0; - } + // 第一个大块 - 高度16% + .EcontainerTop { + height: 16%; + border-radius: 4px; + display: flex; + flex-direction: column; - .ant-table-tbody > tr > td { - border-bottom: 1px solid #f0f0f0; - } + .sectionContent { + height: 100%; + display: flex; + flex-direction: column; - .ant-table-tbody > tr:hover > td { - background-color: #f5f5f5; - } - } - - .ant-btn { - border-radius: 4px; - - &.ant-btn-primary { - background-color: #1890ff; - border-color: #1890ff; - - &:hover { - background-color: #40a9ff; - border-color: #40a9ff; - } - } + .blocksContainer { + flex: 1; + display: flex; + gap: 10px; + height: 100%; - &.ant-btn-link { - padding: 4px 8px; - height: auto; - - &:hover { - background-color: #f5f5f5; - } - } - } - - .ant-tag { - border-radius: 4px; - font-size: 12px; - padding: 2px 8px; - } - - .ant-modal { - .ant-modal-header { - border-bottom: 1px solid #f0f0f0; - - .ant-modal-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } + .blockItem { + flex: 1; + height: 100%; + display: flex; + background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 92.55%); + border-radius: 4px; + border: 2px solid #FFFFFF; - .ant-modal-body { - padding: 24px; - } + .blockLeft { + width: 60%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + padding: 15px; + padding-left: 20px; + gap: 8px; + + .blockTitle { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + line-height: 1.2; + } + + .blockNumber { + font-family: PingFang SC; + font-weight: 700; + font-size: 24px; + color: #333333; + line-height: 1.2; + } + + .blockChange { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #1269FF; + line-height: 1.2; + display: flex; + align-items: center; + gap: 4px; - .ant-form-item-label > label { - font-weight: 500; - color: #262626; + .arrow { + font-size: 14px; + font-weight: bold; + } + + .checkIcon { + font-size: 16px; + color: #1269FF; + } + } + } + + .blockRight { + flex: 1; + height: 100%; + background-color: transparent; + border-radius: 0 4px 4px 0; + display: flex; + align-items: center; + justify-content: center; + + .blockImage { + height: 130%; + object-fit: contain; + margin-right: -10px; + } + } + } + } + } } - .ant-input, - .ant-select-selector { - border-radius: 4px; - border: 1px solid #d9d9d9; - - &:hover { - border-color: #40a9ff; - } - - &:focus, - &.ant-select-focused .ant-select-selector { - border-color: #40a9ff; - box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); - } + // 第二个大块 - 三个图表块 + .EcontainerMiddle { + height: 30%; + border-radius: 4px; + background-color: #fff; + display: flex; + flex-direction: column; + + .sectionContent { + height: 100%; + display: flex; + flex-direction: row; + gap: 10px; + padding: 10px; + + .chartBlock { + flex: 1; + height: 100%; + background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 53.01%); + border: 2px solid #fff; + border-radius: 4px; + display: flex; + flex-direction: column; + font-family: PingFang SC; + font-size: 14px; + color: #333333; + + .chartTitle { + display: flex; + align-items: center; + gap: 8px; + font-weight: 500; + font-size: 14px; + color: #333333; + padding: 10px 15px 5px 15px; + + .titleIcon { + width: 3px; + height: 14px; + background-color: #2E4CD4; + } + } + + .chartContainer { + flex: 1; + width: 100%; + height: 120%; + // // min-height: 200px; + } + } + } } - } - - .ant-pagination { - margin-top: 16px; - text-align: right; - - .ant-pagination-total-text { - color: #8c8c8c; - margin-right: 16px; + + // 第三大块 - 评估报告表格 + .EcontainerBottom { + flex: 1; + background-color: #fff; + border-radius: 4px; + display: flex; + flex-direction: column; + padding: 10px; + + .tableHeader { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; + + .tableTitle { + display: flex; + align-items: center; + gap: 8px; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 14px; + background-color: #2E4CD4; + } + } + } + + .tableContainer { + flex: 1; + overflow: hidden; + + :global(.ant-table-wrapper) { + height: 100%; + } + + :global(.ant-table) { + height: 100%; + } + + :global(.ant-table-container) { + height: 100%; + } + + :global(.ant-table-body) { + height: calc(100% - 55px); // 减去表头高度 + overflow-y: auto; + } + + :global(.ant-table-tbody > tr > td) { + padding: 8px 16px; + font-size: 12px; + } + + :global(.ant-table-thead > tr > th) { + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + background-color: #fafafa; + } + + :global(.ant-pagination) { + margin-top: 10px; + text-align: right; + } + } } - } } diff --git a/src/pages/business_basic/module/OnlineMonitoring.js b/src/pages/business_basic/module/OnlineMonitoring.js index adfae54..047b795 100644 --- a/src/pages/business_basic/module/OnlineMonitoring.js +++ b/src/pages/business_basic/module/OnlineMonitoring.js @@ -1,344 +1,715 @@ -import React, { useState, useEffect } from 'react'; -import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag, Badge } from 'antd'; -import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, PlayCircleOutlined, PauseCircleOutlined } from '@ant-design/icons'; -import './OnlineMonitoring.less'; -const { Option } = Select; +import React, { useEffect, useRef, useState } from 'react'; +import { Card, Result, Select, Button } from 'antd'; +import * as echarts from 'echarts'; +import StandardTable from '@/components/StandardTable'; +import styles from './OnlineMonitoring.less'; + +import alarm0 from '@/assets/safe_majorHazard/online_monitoring/alarm0.png'; +import alarm1 from '@/assets/safe_majorHazard/online_monitoring/alarm1.png'; +import alarm2 from '@/assets/safe_majorHazard/online_monitoring/alarm2.png'; +import alarm3 from '@/assets/safe_majorHazard/online_monitoring/alarm3.png'; +import exportIcon from '@/assets/safe_majorHazard/online_monitoring/export.png'; +import deleteIcon from '@/assets/safe_majorHazard/online_monitoring/delete.png'; const OnlineMonitoring = () => { - const [form] = Form.useForm(); - const [dataSource, setDataSource] = useState([]); - const [loading, setLoading] = useState(false); - const [modalVisible, setModalVisible] = useState(false); - const [editingRecord, setEditingRecord] = useState(null); - const [pagination, setPagination] = useState({ - current: 1, - pageSize: 10, - total: 0, - }); + const chartRef = useRef(null); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + const [loading, setLoading] = useState(false); + const [dataSource, setDataSource] = useState([]); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 5, + total: 0, + }); - // 模拟数据 - const mockData = [ - { - id: 1, - deviceName: '温度传感器-001', - deviceType: '温度传感器', - location: '生产车间A区', - status: '在线', - lastUpdate: '2024-01-15 14:30:25', - value: '25.6°C', - threshold: '30°C', - description: '监测生产车间温度变化', - }, - { - id: 2, - deviceName: '压力传感器-002', - deviceType: '压力传感器', - location: '储罐区B区', - status: '离线', - lastUpdate: '2024-01-15 12:15:30', - value: '--', - threshold: '2.5MPa', - description: '监测储罐压力状态', - }, - { - id: 3, - deviceName: '气体检测器-003', - deviceType: '气体检测器', - location: '危险品仓库', - status: '在线', - lastUpdate: '2024-01-15 14:32:10', - value: '正常', - threshold: '50ppm', - description: '监测有害气体浓度', - }, - ]; + useEffect(() => { + if (chartRef.current) { + const chart = echarts.init(chartRef.current); - useEffect(() => { - fetchData(); - }, [pagination.current, pagination.pageSize]); + const option = { + color: ['#04A7F3', '#E7C42C', '#EC6941'], - const fetchData = async () => { - setLoading(true); - try { - // 模拟API调用 - setTimeout(() => { - setDataSource(mockData); - setPagination(prev => ({ ...prev, total: mockData.length })); - setLoading(false); - }, 500); - } catch (error) { - message.error('获取数据失败'); - setLoading(false); - } - }; + legend: { + data: ['液位', '温度', '压力'], + top: "-3px", + left: "center", + itemGap: 40, // 图例间距 + textStyle: { + fontSize: 10 + } + }, + grid: { + left: '2%', + right: '4%', + bottom: '2%', + top: '12%', + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['0:00', '2:00', '4:00', '6:00', '8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'], + axisLabel: { + fontSize: 10 + } + }, + yAxis: { + type: 'value', + min: 0, + max: 500, + axisLabel: { + formatter: '{value}', + fontSize: 10 + } + }, + series: [ + { + name: '液位', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#04A7F3' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(4, 167, 243, 0.3)' }, + { offset: 1, color: 'rgba(4, 167, 243, 0)' } + ] + } + }, + symbol: 'none', // 不显示数据点 + data: [120, 200, 150, 300, 250, 400, 350, 280, 320, 180, 220, 160, 140] + }, + { + name: '温度', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#E7C42C' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(231, 196, 44, 0.3)' }, + { offset: 1, color: 'rgba(231, 196, 44, 0)' } + ] + } + }, + symbol: 'none', + data: [80, 120, 100, 180, 160, 220, 200, 150, 170, 90, 110, 85, 75] + }, + { + name: '压力', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#EC6941' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 1, + x2: 0, + y2: 0, + colorStops: [ + { offset: 0, color: 'rgba(236, 105, 65, 0)' }, + { offset: 1, color: 'rgba(236, 105, 65, 0.3)' } + ] + } + }, + symbol: 'none', + data: [200, 300, 250, 450, 400, 430, 480, 420, 480, 280, 320, 260, 240] + } + ] + }; - const handleAdd = () => { - setEditingRecord(null); - form.resetFields(); - setModalVisible(true); - }; + chart.setOption(option); - const handleEdit = (record) => { - setEditingRecord(record); - form.setFieldsValue(record); - setModalVisible(true); - }; + // 响应式调整 - 使用ResizeObserver监听容器尺寸变化 + let resizeTimer = null; + const handleResize = () => { + // 防抖处理,避免频繁调用resize + if (resizeTimer) { + clearTimeout(resizeTimer); + } + resizeTimer = setTimeout(() => { + chart.resize(); + }, 100); + }; + + // 监听窗口大小变化 + window.addEventListener('resize', handleResize); + + // 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题) + let resizeObserver = null; + if (window.ResizeObserver) { + resizeObserver = new ResizeObserver(() => { + // 使用setTimeout确保DOM更新完成后再调整图表 + setTimeout(() => { + handleResize(); + }, 0); + }); + resizeObserver.observe(chartRef.current); + } - const handleDelete = (record) => { - Modal.confirm({ - title: '确认删除', - content: `确定要删除监控设备"${record.deviceName}"吗?`, - onOk: () => { - setDataSource(dataSource.filter(item => item.id !== record.id)); - message.success('删除成功'); - }, - }); - }; + return () => { + window.removeEventListener('resize', handleResize); + if (resizeObserver) { + resizeObserver.disconnect(); + } + if (resizeTimer) { + clearTimeout(resizeTimer); + } + chart.dispose(); + }; + } + }, []); - const handleView = (record) => { - Modal.info({ - title: '查看监控设备详情', - content: ( -
-

设备名称:{record.deviceName}

-

设备类型:{record.deviceType}

-

安装位置:{record.location}

-

运行状态: - -

-

当前数值:{record.value}

-

阈值设置:{record.threshold}

-

最后更新:{record.lastUpdate}

-

设备描述:{record.description}

-
- ), - width: 600, - }); - }; + // 表格列定义 + const columns = [ + { + title: '编号', + dataIndex: 'id', + key: 'id', + width: 80, + render: (text, record, index) => { + const page = pagination.current || 1; + const pageSize = pagination.pageSize || 5; + const number = (page - 1) * pageSize + index + 1; + return `0${number}`.slice(-2); + } + }, + { + title: '报警时间', + dataIndex: 'alarmTime', + key: 'alarmTime', + width: 150, + }, + { + title: '报警传感器名称', + dataIndex: 'sensorName', + key: 'sensorName', + width: 150, + }, + { + title: '报警类型', + dataIndex: 'alarmType', + key: 'alarmType', + width: 120, + }, + { + title: '报警内容', + dataIndex: 'alarmContent', + key: 'alarmContent', + width: 200, + }, + { + title: '优先级', + dataIndex: 'priority', + key: 'priority', + width: 80, + render: (text) => { + const colorMap = { + '高': '#FF4D4F', + '中': '#FAAD14', + '低': '#52C41A' + }; + return {text}; + } + }, + { + title: '处理状态', + dataIndex: 'status', + key: 'status', + width: 100, + render: (text) => { + const statusMap = { + '未处理': { color: '#FF4D4F', bg: '#FFF2F0' }, + '处理中': { color: '#FAAD14', bg: '#FFFBE6' }, + '已处理': { color: '#52C41A', bg: '#F6FFED' } + }; + const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' }; + return ( + + {text} + + ); + } + }, + { + title: '处理时间', + dataIndex: 'processTime', + key: 'processTime', + width: 150, + }, + { + title: '处理人', + dataIndex: 'processor', + key: 'processor', + width: 100, + }, + { + title: '操作', + key: 'action', + width: 120, + render: (_, record) => ( +
+ +
+ ), + }, + ]; - const handleStartStop = (record) => { - const newStatus = record.status === '在线' ? '离线' : '在线'; - setDataSource(dataSource.map(item => - item.id === record.id ? { ...item, status: newStatus } : item - )); - message.success(`设备已${newStatus === '在线' ? '启动' : '停止'}`); - }; + // 模拟数据 + const mockData = [ + { + key: '1', + id: '001', + alarmTime: '2024-01-15 08:30:25', + sensorName: 'LNG储罐', + alarmType: '温度超限', + alarmContent: '储罐温度超过安全阈值', + priority: '高', + status: '未处理', + processTime: '-', + processor: '-', + }, + { + key: '2', + id: '002', + alarmTime: '2024-01-15 09:15:10', + sensorName: 'LNG储罐', + alarmType: '压力异常', + alarmContent: '管道压力异常波动', + priority: '中', + status: '处理中', + processTime: '2024-01-15 09:20:00', + processor: '张三', + }, + { + key: '3', + id: '003', + alarmTime: '2024-01-15 10:45:30', + sensorName: 'LNG储罐', + alarmType: '液位异常', + alarmContent: '储罐液位低于警戒线', + priority: '高', + status: '已处理', + processTime: '2024-01-15 11:00:15', + processor: '李四', + }, + { + key: '4', + id: '004', + alarmTime: '2024-01-15 11:20:45', + sensorName: 'LNG储罐', + alarmType: '气体泄漏', + alarmContent: '检测到可燃气体泄漏', + priority: '高', + status: '未处理', + processTime: '-', + processor: '-', + }, + { + key: '5', + id: '005', + alarmTime: '2024-01-15 12:10:20', + sensorName: 'LNG储罐', + alarmType: '设备振动', + alarmContent: '设备异常振动', + priority: '低', + status: '已处理', + processTime: '2024-01-15 12:30:00', + processor: '王五', + }, + { + key: '6', + id: '006', + alarmTime: '2024-01-15 13:25:15', + sensorName: 'LNG管道', + alarmType: '流量异常', + alarmContent: '管道流量异常波动', + priority: '中', + status: '未处理', + processTime: '-', + processor: '-', + }, + { + key: '7', + id: '007', + alarmTime: '2024-01-15 14:10:30', + sensorName: 'LNG储罐', + alarmType: '温度异常', + alarmContent: '储罐温度异常升高', + priority: '高', + status: '处理中', + processTime: '2024-01-15 14:15:00', + processor: '赵六', + }, + { + key: '8', + id: '008', + alarmTime: '2024-01-15 15:45:20', + sensorName: 'LNG管道', + alarmType: '压力超限', + alarmContent: '管道压力超过安全阈值', + priority: '高', + status: '已处理', + processTime: '2024-01-15 16:00:00', + processor: '孙七', + }, + { + key: '9', + id: '009', + alarmTime: '2024-01-15 16:30:45', + sensorName: 'LNG储罐', + alarmType: '液位超限', + alarmContent: '储罐液位超过警戒线', + priority: '中', + status: '未处理', + processTime: '-', + processor: '-', + }, + { + key: '10', + id: '010', + alarmTime: '2024-01-15 17:15:10', + sensorName: 'LNG管道', + alarmType: '泄漏检测', + alarmContent: '检测到轻微气体泄漏', + priority: '低', + status: '已处理', + processTime: '2024-01-15 17:30:00', + processor: '周八', + }, + { + key: '11', + id: '011', + alarmTime: '2024-01-15 18:20:35', + sensorName: 'LNG储罐', + alarmType: '设备故障', + alarmContent: '储罐阀门异常关闭', + priority: '高', + status: '处理中', + processTime: '2024-01-15 18:25:00', + processor: '吴九', + }, + { + key: '12', + id: '012', + alarmTime: '2024-01-15 19:05:50', + sensorName: 'LNG管道', + alarmType: '温度异常', + alarmContent: '管道温度异常下降', + priority: '中', + status: '未处理', + processTime: '-', + processor: '-', + }, + ]; - const handleSubmit = async (values) => { - try { - if (editingRecord) { - // 编辑 - setDataSource(dataSource.map(item => - item.id === editingRecord.id ? { ...item, ...values } : item - )); - message.success('编辑成功'); - } else { - // 新增 - const newRecord = { - id: Date.now(), - ...values, - status: '离线', - lastUpdate: new Date().toLocaleString(), - value: '--', - }; - setDataSource([...dataSource, newRecord]); - message.success('添加成功'); - } - setModalVisible(false); - form.resetFields(); - } catch (error) { - message.error('操作失败'); - } - }; + // 初始化数据 + useEffect(() => { + setPagination(prev => ({ ...prev, total: mockData.length })); + }, []); - const columns = [ - { - title: '设备名称', - dataIndex: 'deviceName', - key: 'deviceName', - width: 150, - }, - { - title: '设备类型', - dataIndex: 'deviceType', - key: 'deviceType', - width: 120, - }, - { - title: '安装位置', - dataIndex: 'location', - key: 'location', - width: 150, - }, - { - title: '运行状态', - dataIndex: 'status', - key: 'status', - width: 100, - render: (status) => ( - - ), - }, - { - title: '当前数值', - dataIndex: 'value', - key: 'value', - width: 100, - }, - { - title: '阈值设置', - dataIndex: 'threshold', - key: 'threshold', - width: 100, - }, - { - title: '最后更新', - dataIndex: 'lastUpdate', - key: 'lastUpdate', - width: 150, - }, - { - title: '操作', - key: 'action', - width: 250, - render: (_, record) => ( - - - - - - - ), - }, - ]; + // 根据分页获取当前页数据 + const getCurrentPageData = () => { + const { current, pageSize } = pagination; + const startIndex = (current - 1) * pageSize; + const endIndex = startIndex + pageSize; + return mockData.slice(startIndex, endIndex); + }; - return ( -
- } onClick={handleAdd}> - 新增设备 - - } - > -
- `第 ${range[0]}-${range[1]} 条/共 ${total} 条`, - onChange: (page, pageSize) => { - setPagination(prev => ({ - ...prev, - current: page, - pageSize: pageSize || prev.pageSize, - })); - }, - }} - /> - + // 表格选择变化 + const onSelectChange = (newSelectedRowKeys, newSelectedRows) => { + setSelectedRowKeys(newSelectedRowKeys); + setSelectedRows(newSelectedRows); + }; + + // 分页变化处理 + const handleTableChange = (pagination) => { + setPagination(prev => ({ + ...prev, + current: pagination.current, + pageSize: pagination.pageSize, + })); + }; - { - setModalVisible(false); - form.resetFields(); - }} - onOk={() => form.submit()} - width={600} - > -
- - - + // 导出功能 + const handleExport = () => { + console.log('导出数据'); + // 这里可以添加导出逻辑 + }; - - - + // 批量删除功能 + const handleBatchDelete = () => { + if (selectedRowKeys.length === 0) { + console.log('没有选中任何行'); + // 可以在这里添加提示用户选择行的逻辑 + return; + } + console.log('批量删除', selectedRowKeys); + // 这里可以添加批量删除逻辑 + }; + + return ( +
+
+
+
+
+
+ alarm0 +
+
+
总报警
+
1456
+
+
+ 未处理 6 +
+
+ 处理中 10 +
+
+
+
+
+
+ alarm1 +
+
+
一级报警
+
357
+
+
+ 未处理 6 +
+
+ 处理中 10 +
+
+
+
+
+
+ alarm2 +
+
+
二级报警
+
401
+
+
+ 未处理 6 +
+
+ 处理中 10 +
+
+
+
+
+
+ alarm3 +
+
+
三级报警
+
556
+
+
+ 未处理 6 +
+
+ 处理中 10 +
+
+
+
+
+
+
+
+
+
预警看板
+
+
+
检测对象
+ - +
+
+
+
+
+
+
+
实时数据采集
+
+
+ 总数: 1378 +
+
- - - +
+
+
储罐液化装置区
+
R值: 1765
+
编号:XXXXXXXX
+
+
+
+
+
+
三级
+
危险等级
+
+
+
+
+
+
+
+
储罐液化装置区
+
R值: 1765
+
编号:XXXXXXXX
+
+
+
+
+
+
一级
+
危险等级
+
+
+
+
+
+
+
+
储罐液化装置区
+
R值: 1765
+
编号:XXXXXXXX
+
+
+
+
+
+
二级
+
危险等级
+
+
+
+
+
+
+
+
储罐液化装置区
+
R值: 1765
+
编号:XXXXXXXX
+
+
+
+
+
+
三级
+
危险等级
+
+
+
+
+
+
+
+ {/* 表格 */} +
+ {/* 首行 左侧标题左对齐 右侧按钮右对齐 */} +
+
+
+
报警信息列表
+
+
+ + + +
+
- - - - - -
- ); + {/* 表格 5行10列 带页码 每页5条数据 */} +
+ + `共 ${total} 条`, + }} + scroll={{ x: 1200 }} + /> +
+
+
+ ); }; -export default OnlineMonitoring; +export default OnlineMonitoring; \ No newline at end of file diff --git a/src/pages/business_basic/module/OnlineMonitoring.less b/src/pages/business_basic/module/OnlineMonitoring.less index 680ed76..283ce83 100644 --- a/src/pages/business_basic/module/OnlineMonitoring.less +++ b/src/pages/business_basic/module/OnlineMonitoring.less @@ -1,157 +1,919 @@ -.online-monitoring { - padding: 20px; - - .ant-card { - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - border-radius: 6px; - - .ant-card-head { - border-bottom: 1px solid #f0f0f0; - - .ant-card-head-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } +.Ocontainer { + padding: 8px 6px 0px 6px; + height: 100%; + display: flex; + flex-direction: column; - .ant-card-body { - padding: 20px; - } - } - - .ant-table { - .ant-table-thead > tr > th { - background-color: #fafafa; - font-weight: 600; - color: #262626; - border-bottom: 1px solid #f0f0f0; - } + .OcontainerTop { + display: flex; - .ant-table-tbody > tr > td { - border-bottom: 1px solid #f0f0f0; - } + height: 50%; + margin-bottom: 5px; - .ant-table-tbody > tr:hover > td { - background-color: #f5f5f5; - } - } - - .ant-btn { - border-radius: 4px; - - &.ant-btn-primary { - background-color: #1890ff; - border-color: #1890ff; - - &:hover { - background-color: #40a9ff; - border-color: #40a9ff; - } - } + .OcontainerTopLeft { + width: 72%; + height: 100%; + // background-color: pink; + margin-right: 10px; + // display: flex; - &.ant-btn-link { - padding: 4px 8px; - height: auto; - - &:hover { - background-color: #f5f5f5; - } - } - } + .OcontainerTopLeftTop { + width: 100%; + height: 35%; + display: flex; + gap: 12px; - .ant-badge { - .ant-badge-status-dot { - width: 8px; - height: 8px; - } - - .ant-badge-status-text { - margin-left: 8px; - font-size: 12px; - } - } - - .ant-modal { - .ant-modal-header { - border-bottom: 1px solid #f0f0f0; - - .ant-modal-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } + .alarmO { + flex: 1; + height: 100%; + background-color: #F4F7FF; + border: 1px solid #AED3FF; + border-bottom: 0px solid #AED3FF; + border-radius: 4px; + box-shadow: 0px 2px 31px 0px #5382FE33 inset; + display: flex; - .ant-modal-body { - padding: 24px; - } + .alarmOLeft { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } - .ant-form-item-label > label { - font-weight: 500; - color: #262626; - } + .alarmORight { + flex: 1; + width: 35%; + height: 100%; + display: flex; + flex-direction: column; + margin-left: 2px; + gap: 18px; + + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + font-size: 12px; + line-height: 100%; + letter-spacing: 0%; + color: #333333; + + .alarmORightText1 { + margin-top: 15px; + } + + + .alarmORightText2 { + font-weight: 700; + font-size: 16px; + } + + .alarmORightText3 { + display: flex; + gap: 22px; + } + + } + + + + } + + .alarmTw { + flex: 1; + height: 100%; + background-color: #FFF5f4; + border: 1px solid #FFC5BC; + border-bottom: 0px solid #FFC5BC; + border-radius: 4px; + box-shadow: 0px 2px 31px 0px #FE5F4C33 inset; + display: flex; + + .alarmTwLeft { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .alarmTwRight { + flex: 1; + width: 35%; + height: 100%; + display: flex; + flex-direction: column; + margin-left: 2px; + gap: 18px; + + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + font-size: 12px; + line-height: 100%; + letter-spacing: 0%; + color: #333333; + + .alarmTwRightText1 { + margin-top: 15px; + } + + .alarmTwRightText2 { + font-weight: 700; + font-size: 16px; + } + + .alarmTwRightText3 { + display: flex; + gap: 22px; + } + } + } + + .alarmTh { + flex: 1; + height: 100%; + background-color: #FFF7F2; + border: 1px solid #FFD9B2; + border-bottom: 0px solid #FFD9B2; + border-radius: 4px; + box-shadow: 0px 2px 31px 0px #FD883C33 inset; + display: flex; + + .alarmThLeft { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .alarmThRight { + flex: 1; + width: 35%; + height: 100%; + display: flex; + flex-direction: column; + margin-left: 2px; + gap: 18px; + + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + font-size: 12px; + line-height: 100%; + letter-spacing: 0%; + color: #333333; + + .alarmThRightText1 { + margin-top: 15px; + } + + .alarmThRightText2 { + font-weight: 700; + font-size: 16px; + } + + .alarmThRightText3 { + display: flex; + gap: 22px; + } + } + } + + .alarmF { + flex: 1; + height: 100%; + background-color: #EFF9FF; + border: 1px solid #89E1FF; + border-bottom: 0px solid #89E1FF; + border-radius: 4px; + box-shadow: 0px 2px 31px 0px #22A4FD33 inset; + display: flex; + + .alarmFLeft { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + } + + .alarmFRight { + flex: 1; + width: 35%; + height: 100%; + display: flex; + flex-direction: column; + margin-left: 2px; + gap: 18px; + + font-family: PingFang SC; + font-weight: 400; + font-style: Regular; + font-size: 12px; + line-height: 100%; + letter-spacing: 0%; + color: #333333; + + .alarmFRightText1 { + margin-top: 15px; + } + + .alarmFRightText2 { + font-weight: 700; + font-size: 16px; + } + + .alarmFRightText3 { + display: flex; + gap: 22px; + } + } + } + } + + .OcontainerTopLeftBottom { + margin-top: 12px; + background-color: #fff; + width: 100%; + height: 60%; + + .OcontainerTopLeftBottomTitle { + display: flex; + justify-content: space-between; + align-items: center; + // padding: 8px 15px; + padding: 8px 15px 0px 15px; + + .titleLeft { + display: flex; + align-items: center; + gap: 8px; + font-family: PingFang SC; + font-weight: 500; + font-style: Medium; + font-size: 14px; + line-height: 100%; + letter-spacing: 0%; + + + .titleIcon { + width: 3px; + height: 16px; + background-color: #2E4CD4; + } + } + + .titleRight { + display: flex; + align-items: center; + gap: 8px; + + font-family: PingFang SC; + font-style: Medium; + font-size: 13px; + line-height: 100%; + letter-spacing: 0%; + + + .selectBox { + padding: 4px 8px; + border: 1px solid #d9d9d9; + border-radius: 4px; + background-color: #fff; + font-size: 12px; + color: #333; + outline: none; + + &:focus { + border-color: #2E4CD4; + } + } + } + } + + .OcontainerTopLeftBottomChart { + flex: 1; + width: 100%; + height: 75%; + } + } + } + + .OcontainerTopRight { + flex: 1; + height: calc(100% - 3.3px); + background-color: #fff; + background-image: url('@/assets/safe_majorHazard/online_monitoring/backTopRight.png'); + background-size: 100% auto; + display: flex; + flex-direction: column; + overflow-y: auto; + + .realTimeDataHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 15px; + margin-bottom: 10px; + + .titleLeft { + display: flex; + align-items: center; + gap: 8px; + font-family: PingFang SC; + font-weight: 500; + font-style: Medium; + font-size: 14px; + line-height: 100%; + letter-spacing: 0%; + + .titleIcon { + width: 3px; + height: 16px; + background-color: #2E4CD4; + } + } + + .totalCount { + font-family: PingFang SC; + font-weight: 400; + font-size: 13px; + color: #333333; + } + } + + .dataItem { + height: 23%; + flex-shrink: 0; + border: 1px solid #89E1FF; + border-radius: 2px; + margin: 0 15px; + margin-bottom: 6px; + display: flex; + align-items: center; + justify-content: center; + font-family: PingFang SC; + font-size: 14px; + // color: #666; + background-color: #EFF9FF; + + &:last-child { + // margin-bottom: 1px; + } + } + + .dataItem1 { + height: 25%; + flex-shrink: 0; + border: 1px solid #89E1FF; + border-radius: 4px; + margin: 0 15px; + margin-bottom: 6px; + display: flex; + align-items: center; + padding: 0px 15px; + background-color: #EFF9FF; + + .dataItemLeft { + width: 65%; + display: flex; + flex-direction: column; + gap: 8px; + + .areaName { + + font-family: PingFang SC; + font-weight: 400; + font-size: 13px; + color: #333333; + line-height: 2.2; + } + + .rValue { + font-family: PingFang SC; + font-weight: 400; + font-size: 14px; + color: #666666; + line-height: 0.2; + } + + .codeNumber { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + } + } + + .dataItemRight { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + + .circleContainer { + position: relative; + height: 80%; + aspect-ratio: 1; // 强制宽高比1:1 + + .outerCircle { + + width: 100%; + height: 100%; + background-color: rgba(51, 176, 253, 0.3); + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + .innerCircle { + width: 70%; + height: 70%; + background-color: rgba(4, 128, 251, 0.8); + border-radius: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .levelText { + font-family: PingFang SC; + font-weight: 500; + font-size: 11px; + color: #FFFFFF; + line-height: 1.4; + margin-top: -4px; + } + + .riskText { + font-family: PingFang SC; + font-weight: 300; + font-size: 8px; + color: #FFFFFF; + line-height: 1; + } + } + } + } + } + } + + .dataItem2 { + height: 25%; + flex-shrink: 0; + border: 1px solid rgba(255, 197, 188, 1); + border-radius: 4px; + margin: 0 15px; + margin-bottom: 6px; + display: flex; + align-items: center; + padding: 0px 15px; + background-color: #fff5f4; + + .dataItemLeft { + width: 65%; + display: flex; + flex-direction: column; + gap: 8px; + + .areaName { + font-family: PingFang SC; + font-weight: 400; + font-size: 13px; + color: #333333; + line-height: 2.2; + } + + .rValue { + font-family: PingFang SC; + font-weight: 400; + font-size: 14px; + color: #666666; + line-height: 0.2; + } + + .codeNumber { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + } + } + + .dataItemRight { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + + .circleContainer { + position: relative; + height: 80%; + aspect-ratio: 1; + + .outerCircle { + width: 100%; + height: 100%; + background-color: rgba(254, 214, 209, 1); + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + .innerCircle { + width: 70%; + height: 70%; + background-color: rgba(253, 41, 14, 1); + border-radius: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .levelText { + font-family: PingFang SC; + font-weight: 500; + font-size: 11px; + color: #FFFFFF; + line-height: 1.4; + margin-top: -4px; + } + + .riskText { + font-family: PingFang SC; + font-weight: 300; + font-size: 8px; + color: #FFFFFF; + line-height: 1; + } + } + } + } + } + } + + .dataItem3 { + height: 25%; + flex-shrink: 0; + border: 1px solid rgba(255, 217, 178, 1); + border-radius: 4px; + margin: 0 15px; + margin-bottom: 6px; + display: flex; + align-items: center; + padding: 0px 15px; + background-color: #fef6f1; + + .dataItemLeft { + width: 65%; + display: flex; + flex-direction: column; + gap: 8px; + + .areaName { + font-family: PingFang SC; + font-weight: 400; + font-size: 13px; + color: #333333; + line-height: 2.2; + } + + .rValue { + font-family: PingFang SC; + font-weight: 400; + font-size: 14px; + color: #666666; + line-height: 0.2; + } + + .codeNumber { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + } + } + + .dataItemRight { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + + .circleContainer { + position: relative; + height: 80%; + aspect-ratio: 1; + + .outerCircle { + width: 100%; + height: 100%; + background-color: rgba(255, 234, 218, 1); + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + .innerCircle { + width: 70%; + height: 70%; + background-color: rgba(252, 103, 18, 1); + border-radius: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .levelText { + font-family: PingFang SC; + font-weight: 500; + font-size: 11px; + color: #FFFFFF; + line-height: 1.4; + margin-top: -4px; + } + + .riskText { + font-family: PingFang SC; + font-weight: 300; + font-size: 8px; + color: #FFFFFF; + line-height: 1; + } + } + } + } + } + } + + .dataItem4 { + height: 25%; + flex-shrink: 0; + border: 1px solid #89E1FF; + border-radius: 4px; + margin: 0 15px; + margin-bottom: 6px; + display: flex; + align-items: center; + padding: 0px 15px; + background-color: #EFF9FF; + + .dataItemLeft { + width: 65%; + display: flex; + flex-direction: column; + gap: 8px; + + .areaName { + font-family: PingFang SC; + font-weight: 400; + font-size: 13px; + color: #333333; + line-height: 2.2; + } + + .rValue { + font-family: PingFang SC; + font-weight: 400; + font-size: 14px; + color: #666666; + line-height: 0.2; + } + + .codeNumber { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + } + } + + .dataItemRight { + width: 35%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + + .circleContainer { + position: relative; + height: 80%; + aspect-ratio: 1; + + .outerCircle { + width: 100%; + height: 100%; + background-color: rgba(51, 176, 253, 0.3); + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + + .innerCircle { + width: 70%; + height: 70%; + background-color: rgba(4, 128, 251, 0.8); + border-radius: 50%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + .levelText { + font-family: PingFang SC; + font-weight: 500; + font-size: 11px; + color: #FFFFFF; + line-height: 1.4; + margin-top: -4px; + } + + .riskText { + font-family: PingFang SC; + font-weight: 300; + font-size: 8px; + color: #FFFFFF; + line-height: 1; + } + } + } + } + } + } + } - .ant-input, - .ant-select-selector { - border-radius: 4px; - border: 1px solid #d9d9d9; - - &:hover { - border-color: #40a9ff; - } - - &:focus, - &.ant-select-focused .ant-select-selector { - border-color: #40a9ff; - box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); - } - } - } - - .ant-pagination { - margin-top: 16px; - text-align: right; - - .ant-pagination-total-text { - color: #8c8c8c; - margin-right: 16px; - } - } - - // 状态指示器样式 - .status-indicator { - display: inline-flex; - align-items: center; - gap: 4px; - - &.online { - color: #52c41a; - } - - &.offline { - color: #ff4d4f; - } - } - - // 数值显示样式 - .value-display { - font-weight: 500; - - &.normal { - color: #52c41a; - } - - &.warning { - color: #faad14; - } - - &.danger { - color: #ff4d4f; } - - &.unknown { - color: #8c8c8c; + + .OcontainerBottom { + background-color: #fff; + flex: 1; + padding: 8px 15px 5px 15px; + display: flex; + flex-direction: column; + + .tableHeader { + display: flex; + justify-content: space-between; + align-items: center; + // margin-bottom: 15px; + padding-bottom: 5px; + // border-bottom: 1px solid #f0f0f0; + + .tableTitle { + display: flex; + align-items: center; + gap: 8px; + font-family: PingFang SC; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 16px; + background-color: #2E4CD4; + } + } + + .tableActions { + display: flex; + gap: 8px; + + // 自定义按钮样式 + :global(.ant-btn) { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + + &:hover { + background-color: #f5f5f5 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:focus { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:active { + background-color: #e6e6e6 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + // 主要按钮样式 + &.ant-btn-primary { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + + &:hover { + background-color: #f5f5f5 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:focus { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:active { + background-color: #e6e6e6 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + } + + // 危险按钮样式 + &.ant-btn-dangerous { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + + &:hover { + background-color: #f5f5f5 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:focus { + background-color: #ffffff !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + + &:active { + background-color: #e6e6e6 !important; + border-color: #DFE4F6 !important; + color: #333333 !important; + box-shadow: none !important; + } + } + + // 禁用状态 + &:disabled { + background-color: #f5f5f5 !important; + border-color: #d9d9d9 !important; + color: #bfbfbf !important; + box-shadow: none !important; + } + } + } + } + + .tableContainer { + flex: 1; + overflow: hidden; + + :global(.ant-table) { + font-size: 12px; + } + + :global(.ant-table-thead > tr > th) { + background-color: #f5f5fa; + font-weight: 500; + font-size: 14px; + color: #333333; + border-bottom: 1px solid #f0f0f0; + padding: 8px 12px; + text-align: center; + } + + :global(.ant-table-tbody > tr > td) { + padding: 8px 12px; + border-bottom: 1px solid #f0f0f0; + text-align: center; + } + + :global(.ant-table-tbody > tr:hover > td) { + background-color: #f5f5f5; + } + + :global(.ant-pagination) { + margin-top: 16px; + text-align: right; + } + } } - } -} + +} \ No newline at end of file diff --git a/src/pages/business_basic/module/ResponsibilityImplementation.js b/src/pages/business_basic/module/ResponsibilityImplementation.js index e8daf90..f9235eb 100644 --- a/src/pages/business_basic/module/ResponsibilityImplementation.js +++ b/src/pages/business_basic/module/ResponsibilityImplementation.js @@ -1,13 +1,26 @@ import React from 'react'; -import { Card, Result, Timeline,Statistic, Table,Row, Input,Button,Col, Select} from 'antd'; +import { Card, Statistic, Table,Row, Input,Button,Col, Select} from 'antd'; +import { PhoneOutlined, IdcardOutlined } from '@ant-design/icons'; import StandardTable from '@/components/StandardTable'; import styles from './ResponsibilityImplementation.less'; - +import upload from '@/assets/business_basic/upload.png'; +import download from '@/assets/business_basic/download.png'; +import fire_fighting1 from '@/assets/business_basic/fire_fighting1.png'; +import fire_fighting2 from '@/assets/business_basic/fire_fighting2.png'; +import fire_fighting3 from '@/assets/business_basic/fire_fighting3.png'; +import frameIcon from '@/assets/business_basic/Frame.png'; +import background1 from '@/assets/business_basic/background1.png'; const ResponsibilityImplementation = () => { + // 搜索处理函数 + const onSearch = (value) => { + console.log('搜索内容:', value); + // 这里可以添加实际的搜索逻辑 + }; + const columns = [ { title:"编号", @@ -108,7 +121,7 @@ const ResponsibilityImplementation = () => {
{/* 警告提示框 */}
- 警告 + 警告 有5个消防设备需要维护,3个资质证书即将到期,请及时处理。 @@ -125,11 +138,11 @@ const ResponsibilityImplementation = () => {
@@ -138,52 +151,98 @@ const ResponsibilityImplementation = () => { {/* 第二行:图片占位 */}
-
🏢
-
组织架构图
+ 消防1 +
+ 消防2 + 消防3 +
+
- {/* 第一块:标题 + 下拉选择框 + 导出按钮 */} + {/* 第一行:标题 + 搜索栏 + 下拉选择框 */}
-
履职时间轴
+
成员信息管理
- +
- {/* 第二块:图片内容 */} + {/* 第二行:三个小块 */}
-
-
📊
-
数据图表
+
+
+
+
+ {/* 第一个块:姓名和单位 */} +
+
张明
+
东义区消防队
+
+ + {/* 第二个块:电话 */} +
+ + 132****3847 +
+ + {/* 第三个块:身份证 */} +
+ + 1304************10 +
+ + {/* 第四个块:职位标签 */} +
+
+
队长
+
消防工程师
+
+
+ + {/* 第五个块:证书状态 */} +
+
+
消防工程师
+
证书3天后到期
+
+
+ + {/* 第六个块:操作按钮 */} +
+
+ + +
+
+
+
+
+
+
待开发
+
+
+
待开发
+
diff --git a/src/pages/business_basic/module/ResponsibilityImplementation.less b/src/pages/business_basic/module/ResponsibilityImplementation.less index 91ffca9..c6d7b35 100644 --- a/src/pages/business_basic/module/ResponsibilityImplementation.less +++ b/src/pages/business_basic/module/ResponsibilityImplementation.less @@ -34,12 +34,12 @@ margin-bottom: 10px; gap: 10px; - .containerOneLeft{ + .containerOneLeft { background-color: white; width: calc(50% - 5px); display: flex; flex-direction: column; - padding: 15px; + padding: 5px 15px; border: 1px solid #f0f0f0; border-radius: 4px; @@ -47,7 +47,7 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 15px; + // margin-bottom: 15px; .titleLeft { display: flex; @@ -73,12 +73,13 @@ display: flex; align-items: center; gap: 4px; + height: 28px; border: 1px solid #DFE4F6; border-radius: 4px; color: #2E4CD4; font-weight: 500; font-size: 12px; - padding: 4px 8px; + padding: 0px 8px; background: transparent; cursor: pointer; transition: all 0.2s; @@ -89,7 +90,8 @@ } .btnIcon { - font-size: 12px; + width: 12px; + height: 12px; } } } @@ -100,36 +102,58 @@ display: flex; align-items: center; justify-content: center; - background-color: #fafafa; - border: 1px dashed #d9d9d9; - border-radius: 4px; .imagePlaceholder { display: flex; flex-direction: column; align-items: center; - gap: 8px; - color: #999999; - .imageIcon { - font-size: 32px; - opacity: 0.6; + .imageIcon1 { + transform: scale(0.9) translateY(-5px); // 稍微向上移动 + object-fit: contain; + } + + + .imageRow { + display: flex; + justify-content: space-between; + // width: 100%; + margin-bottom: 10px; + // padding-bottom: 20px; + // gap: 12px; + + .imageIcon2 { + height: 55%; + transform: scale(0.7) translateY(-25%) translateX(20%); // 稍微向上移动 + object-fit: contain; + background-color: #EFF5FE; + // padding-bottom: 20px; + } + + .imageIcon3 { + height: 40%; + transform: scale(0.65) translateY(-32%) translateX(4%); // 向上移动10px + object-fit: contain; + padding-bottom: 20px; + // background-color: #EFF5FE; + + } } .imageText { - font-size: 14px; + font-size: 12px; font-weight: 400; } } } } - .containerOneRight{ + .containerOneRight { background-color: white; width: calc(50% - 5px); display: flex; flex-direction: column; - padding: 15px; + padding: 5px 15px; border: 1px solid #f0f0f0; border-radius: 4px; @@ -137,7 +161,7 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 15px; + margin-bottom: 10px; .rightTopLeft { display: flex; @@ -161,18 +185,56 @@ } .rightTopRight { - .exportBtn { - background-color: #2E4CD4 !important; - border-color: #2E4CD4 !important; - color: #fff !important; - font-size: 14px !important; - font-weight: 500 !important; - height: 32px; - padding: 0 16px; + .searchGroup { + display: flex; + gap: 8px; + align-items: center; - &:hover { - background-color: #1e3bb8 !important; - border-color: #1e3bb8 !important; + .searchInput { + width: 200px; + height: 32px; + + :global(.ant-input) { + height: 32px; + border-radius: 4px; + border: 1px solid #d9d9d9; + font-size: 14px; + + &:focus { + border-color: #2E4CD4; + box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2); + } + } + + :global(.ant-input-suffix) { + color: #999999; + font-size: 14px; + } + } + + .organizationSelect { + width: 120px; + height: 32px; + + :global(.ant-select-selector) { + height: 32px !important; + border-radius: 4px !important; + border: 1px solid #d9d9d9 !important; + + &:hover { + border-color: #2E4CD4 !important; + } + + &:focus { + border-color: #2E4CD4 !important; + box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2) !important; + } + } + + :global(.ant-select-selection-item) { + line-height: 30px !important; + font-size: 14px !important; + } } } } @@ -180,42 +242,191 @@ .rightBottomSection { flex: 1; - display: flex; - align-items: center; - justify-content: center; + padding: 5px 15px; + width: 100%; + height: 100%; - .imagePlaceholder { + .threeBlocksContainer { display: flex; - flex-direction: column; - align-items: center; - justify-content: center; + gap: 20px; width: 100%; height: 100%; - background-color: #f5f5f5; - border: 2px dashed #d9d9d9; - border-radius: 4px; - .imageIcon { - font-size: 48px; - margin-bottom: 10px; - } + .blockItem { + width: 100%; + height: 100%; + flex: 1; + display: flex; + justify-content: center; + background: url('@/assets/business_basic/background1.png') no-repeat center center; + background-size: 100% auto; - .imageText { - font-size: 14px; - color: #999999; + .blockContent { + // background-color: pink; + font-size: 12px; + color: #666666; + font-weight: 400; + width: 100%; + height: 100%; + } + + // 新的6个横向块样式 + .backgroundContainer { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + gap: 8px; + .infoBlock { + width: 100%; + display: flex; + justify-content: flex-start; + white-space: nowrap; + .nameText { + font-size: 12px; + font-weight: 500; + color: #333333; + margin-left: 10px; + margin-right: 10px; + margin-top: 15px; + } + + + .unitText { + font-size: 10px; + font-weight: 400; + color: #666666; + margin-top: 18px; + } + + .infoIcon { + font-size: 10px; + color: #666666; + margin-left: 10px; + margin-right: 10px; + } + + .infoText { + font-size: 10px; + font-weight: 400; + color: #666666; + + } + + } + + .tagContainer { + display: flex; + gap: 8px; + align-items: center; + } + + .tagBlue1 { + background-color: #D5E5FF; + color: #1269FF; + font-size: 10px; + font-weight: 400; + padding: 4px 8px; + border-radius: 4px; + white-space: nowrap; + margin-left: 10px; + } + .tagBlue2 { + background-color: #D5E5FF; + color: #1269FF; + font-size: 10px; + font-weight: 400; + padding: 4px 8px; + border-radius: 4px; + white-space: nowrap; + + } + .tagBlue3 { + background-color: #D5E5FF; + color: #1269FF; + font-size: 10px; + font-weight: 400; + padding: 4px 8px; + border-radius: 4px; + white-space: nowrap; + margin-left: 10px; + + } + + .tagYellow { + background-color: #FFF8E2; + color: #FFC403; + font-size: 10px; + font-weight: 400; + padding: 4px 8px; + border-radius: 4px; + white-space: nowrap; + } + + .actionBlock { + width: 100%; + height: 50%; + background-color: #BDD6FDCC; + display: flex; + align-items: center; + justify-content: center; + } + + .buttonContainer { + display: flex; + gap: 15px; + align-items: center; + justify-content: center; + width: 100%; + + .editBtn { + height: 80%; + background-color: #1269FF; + color: #fff; + font-size: 10px; + font-weight: 400; + border: none; + border-radius: 2px; + cursor: pointer; + padding: 2px 15px; + + &:hover { + background-color: #0f5ae0; + } + } + + .deleteBtn { + height: 80%; + background-color: #FF5F60; + color: #fff; + font-size: 10px; + font-weight: 400; + border: none; + border-radius: 2px; + cursor: pointer; + padding: 2px 15px; + + &:hover { + background-color: #ff4a4b; + } + } + } + + + } } } } } } - - .containerTwo{ + + .containerTwo { flex: 1; background-color: white; display: flex; flex-direction: column; - padding: 15px; + padding: 5px 15px; border: 1px solid #f0f0f0; border-radius: 4px; @@ -266,7 +477,7 @@ gap: 8px; :global(.ant-btn) { - height: 32px; + height: 28px; padding: 0 16px; border-radius: 4px; font-size: 14px; @@ -324,7 +535,8 @@ } -.rightTopSelect{ +.rightTopSelect { + // 下拉框本身的样式 :global(.ant-select-selector) { background-color: #f8f9fa !important; @@ -332,17 +544,17 @@ border-radius: 6px !important; height: 32px !important; min-height: 32px !important; - + &:hover { border-color: #2E4CD4 !important; } - + &:focus { border-color: #2E4CD4 !important; box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2) !important; } } - + // 下拉框内的文字样式 :global(.ant-select-selection-item) { color: #333333 !important; @@ -350,13 +562,13 @@ font-weight: 500 !important; line-height: 30px !important; } - + // 下拉箭头样式 :global(.ant-select-arrow) { color: #666666 !important; font-size: 12px !important; } - + // 下拉菜单容器样式 :global(.ant-select-dropdown) { background-color: #ffffff !important; @@ -365,7 +577,7 @@ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important; padding: 4px 0 !important; } - + // 下拉选项样式 :global(.ant-select-item) { color: #333333 !important; @@ -373,19 +585,19 @@ padding: 8px 12px !important; border-radius: 4px !important; margin: 2px 8px !important; - + &:hover { background-color: #f0f2ff !important; color: #2E4CD4 !important; } - + &.ant-select-item-option-selected { background-color: #e6f7ff !important; color: #2E4CD4 !important; font-weight: 600 !important; } } - + // 选中状态的样式 :global(.ant-select-focused .ant-select-selector) { border-color: #2E4CD4 !important; @@ -399,12 +611,12 @@ align-items: center; gap: 8px; padding: 4px 0; - + .optionIcon { font-size: 16px; color: #2E4CD4; } - + .optionText { font-size: 14px; color: #333333; diff --git a/src/pages/business_basic/module/RiskAssessment.js b/src/pages/business_basic/module/RiskAssessment.js index 1895bfa..ad4430f 100644 --- a/src/pages/business_basic/module/RiskAssessment.js +++ b/src/pages/business_basic/module/RiskAssessment.js @@ -1,425 +1,720 @@ -import React, { useState, useEffect } from 'react'; -import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag, Rate, Progress } from 'antd'; -import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; -import './RiskAssessment.less'; -const { Option } = Select; +import React, { useEffect, useRef, useState } from 'react'; +import { Card, Result, Select, Button } from 'antd'; +import { CheckCircleOutlined } from '@ant-design/icons'; +import * as echarts from 'echarts'; +import StandardTable from '@/components/StandardTable'; +import styles from './RiskAssessment.less'; +// import './RiskAssessment.less'; -const RiskAssessment = () => { - const [form] = Form.useForm(); - const [dataSource, setDataSource] = useState([]); - const [loading, setLoading] = useState(false); - const [modalVisible, setModalVisible] = useState(false); - const [editingRecord, setEditingRecord] = useState(null); - const [pagination, setPagination] = useState({ - current: 1, - pageSize: 10, - total: 0, - }); +import img1 from '@/assets/safe_majorHazard/online_monitoring/img1.png'; +import img2 from '@/assets/safe_majorHazard/online_monitoring/img2.png'; +import img3 from '@/assets/safe_majorHazard/online_monitoring/img3.png'; +import map1 from '@/assets/safe_majorHazard/online_monitoring/map.png'; +import risk1 from '@/assets/safe_majorHazard/online_monitoring/risk1.png'; +import risk2 from '@/assets/safe_majorHazard/online_monitoring/risk2.png'; +import risk3 from '@/assets/safe_majorHazard/online_monitoring/risk3.png'; - // 模拟数据 - const mockData = [ - { - id: 1, - riskName: '化学品泄漏风险', - riskType: '环境风险', - riskLevel: '高', - probability: 4, - impact: 5, - riskScore: 20, - assessor: '张三', - assessDate: '2024-01-15', - status: '待处理', - description: '生产过程中化学品可能发生泄漏,造成环境污染', - controlMeasures: '加强设备维护,安装泄漏检测装置', - }, - { - id: 2, - riskName: '设备故障风险', - riskType: '设备风险', - riskLevel: '中', - probability: 3, - impact: 3, - riskScore: 9, - assessor: '李四', - assessDate: '2024-01-10', - status: '已处理', - description: '关键设备可能发生故障,影响生产安全', - controlMeasures: '定期维护保养,建立备件库存', - }, - { - id: 3, - riskName: '人员操作风险', - riskType: '人员风险', - riskLevel: '低', - probability: 2, - impact: 2, - riskScore: 4, - assessor: '王五', - assessDate: '2024-01-08', - status: '监控中', - description: '操作人员误操作可能导致安全事故', - controlMeasures: '加强培训,完善操作规程', - }, - ]; - useEffect(() => { - fetchData(); - }, [pagination.current, pagination.pageSize]); +const RiskAssessment = () => { + const chartRef = useRef(null); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [selectedRows, setSelectedRows] = useState([]); + const [loading, setLoading] = useState(false); + const [dataSource, setDataSource] = useState([]); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 5, + total: 0, + }); - const fetchData = async () => { - setLoading(true); - try { - // 模拟API调用 - setTimeout(() => { - setDataSource(mockData); - setPagination(prev => ({ ...prev, total: mockData.length })); - setLoading(false); - }, 500); - } catch (error) { - message.error('获取数据失败'); - setLoading(false); - } - }; + useEffect(() => { + if (chartRef.current) { + const chart = echarts.init(chartRef.current); + + // 强制初始化时调整大小 + setTimeout(() => { + if (chart && !chart.isDisposed()) { + chart.resize(); + } + }, 100); - const handleAdd = () => { - setEditingRecord(null); - form.resetFields(); - setModalVisible(true); - }; + const option = { + color: ['#FF2526', '#FF8800', '#FFC403', '#65E5F9'], - const handleEdit = (record) => { - setEditingRecord(record); - form.setFieldsValue(record); - setModalVisible(true); - }; + legend: { + data: ['重大风险', '较高风险', '一般风险', '低风险'], + top: "-3px", + left: "center", + itemGap: 40, // 图例间距 + textStyle: { + fontSize: 10 + } + }, + grid: { + left: '2%', + right: '4%', + bottom: '2%', + top: '12%', + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['9/22', '9/23', '9/24', '9/25', '9/26', '9/27', '9/28'], + axisLabel: { + fontSize: 10 + } + }, + yAxis: { + type: 'value', + min: 0, + max: 30, + axisLabel: { + formatter: '{value}', + fontSize: 10 + } + }, + series: [ + { + name: '重大风险', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#FF2526' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(38, 12, 12, 0.4)' }, + { offset: 1, color: 'rgba(255, 37, 38, 0)' } + ] + } + }, + symbol: 'none', + data: [8, 15, 12, 22, 18, 26, 20] + }, + { + name: '较高风险', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#FF8800' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(255, 136, 0, 0.4)' }, + { offset: 1, color: 'rgba(255, 136, 0, 0)' } + ] + } + }, + symbol: 'none', + data: [5, 8, 6, 12, 10, 15, 13] + }, + { + name: '一般风险', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#FFC403' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(255, 196, 3, 0.4)' }, + { offset: 1, color: 'rgba(255, 196, 3, 0)' } + ] + } + }, + symbol: 'none', + data: [12, 18, 15, 25, 22, 24, 26] + }, + { + name: '低风险', + type: 'line', + smooth: true, + lineStyle: { + width: 1.5, + color: '#65E5F9' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: 'rgba(101, 229, 249, 0.4)' }, + { offset: 1, color: 'rgba(101, 229, 249, 0)' } + ] + } + }, + symbol: 'none', + data: [3, 5, 7, 9, 6, 8, 4] + } + ] + }; - const handleDelete = (record) => { - Modal.confirm({ - title: '确认删除', - content: `确定要删除风险评估"${record.riskName}"吗?`, - onOk: () => { - setDataSource(dataSource.filter(item => item.id !== record.id)); - message.success('删除成功'); - }, - }); - }; + chart.setOption(option); - const handleView = (record) => { - Modal.info({ - title: '查看风险评估详情', - content: ( -
-

风险名称:{record.riskName}

-

风险类型:{record.riskType}

-

风险等级: - - {record.riskLevel} - -

-

发生概率: - - ({record.probability}/5) -

-

影响程度: - - ({record.impact}/5) -

-

风险评分:{record.riskScore}

-

评估人:{record.assessor}

-

评估日期:{record.assessDate}

-

处理状态: - - {record.status} - -

-

风险描述:{record.description}

-

控制措施:{record.controlMeasures}

-
- ), - width: 700, - }); - }; + // 响应式调整 - 使用多种方式监听容器尺寸变化 + let resizeTimer = null; + const handleResize = () => { + // 防抖处理,避免频繁调用resize + if (resizeTimer) { + clearTimeout(resizeTimer); + } + resizeTimer = setTimeout(() => { + if (chart && !chart.isDisposed()) { + chart.resize(); + } + }, 50); // 减少延迟时间 + }; + + // 监听窗口大小变化 + window.addEventListener('resize', handleResize); + + // 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题) + let resizeObserver = null; + if (window.ResizeObserver) { + resizeObserver = new ResizeObserver((entries) => { + for (let entry of entries) { + // 使用requestAnimationFrame确保在下一帧执行 + requestAnimationFrame(() => { + handleResize(); + }); + } + }); + resizeObserver.observe(chartRef.current); + } - const handleSubmit = async (values) => { - try { - const riskScore = values.probability * values.impact; - const riskLevel = riskScore >= 16 ? '高' : riskScore >= 9 ? '中' : '低'; - - const formData = { - ...values, - riskScore, - riskLevel, - }; + // 额外监听父容器的尺寸变化 + const parentContainer = chartRef.current?.parentElement; + let parentObserver = null; + if (parentContainer && window.ResizeObserver) { + parentObserver = new ResizeObserver((entries) => { + for (let entry of entries) { + requestAnimationFrame(() => { + handleResize(); + }); + } + }); + parentObserver.observe(parentContainer); + } - if (editingRecord) { - // 编辑 - setDataSource(dataSource.map(item => - item.id === editingRecord.id ? { ...item, ...formData } : item - )); - message.success('编辑成功'); - } else { - // 新增 - const newRecord = { - id: Date.now(), - ...formData, - assessor: '当前用户', - assessDate: new Date().toISOString().split('T')[0], - status: '待处理', - }; - setDataSource([...dataSource, newRecord]); - message.success('添加成功'); - } - setModalVisible(false); - form.resetFields(); - } catch (error) { - message.error('操作失败'); - } - }; + // 使用MutationObserver监听DOM结构变化(菜单展开收起时) + const mutationObserver = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'attributes' && + (mutation.attributeName === 'class' || mutation.attributeName === 'style')) { + // 延迟执行,确保DOM更新完成 + setTimeout(() => { + handleResize(); + }, 200); + } + }); + }); - const getRiskLevelColor = (level) => { - switch (level) { - case '高': return 'red'; - case '中': return 'orange'; - case '低': return 'green'; - default: return 'default'; - } - }; + // 监听整个页面的class和style变化 + mutationObserver.observe(document.body, { + attributes: true, + attributeFilter: ['class', 'style'], + subtree: true + }); - const getStatusColor = (status) => { - switch (status) { - case '已处理': return 'green'; - case '待处理': return 'red'; - case '监控中': return 'blue'; - default: return 'default'; - } - }; + return () => { + window.removeEventListener('resize', handleResize); + if (resizeObserver) { + resizeObserver.disconnect(); + } + if (parentObserver) { + parentObserver.disconnect(); + } + if (mutationObserver) { + mutationObserver.disconnect(); + } + if (resizeTimer) { + clearTimeout(resizeTimer); + } + if (chart && !chart.isDisposed()) { + chart.dispose(); + } + }; + } + }, []); - const columns = [ - { - title: '风险名称', - dataIndex: 'riskName', - key: 'riskName', - width: 150, - }, - { - title: '风险类型', - dataIndex: 'riskType', - key: 'riskType', - width: 120, - }, - { - title: '风险等级', - dataIndex: 'riskLevel', - key: 'riskLevel', - width: 100, - render: (level) => ( - - {level} - - ), - }, - { - title: '风险评分', - dataIndex: 'riskScore', - key: 'riskScore', - width: 100, - render: (score) => ( -
- = 16 ? 'exception' : score >= 9 ? 'active' : 'success'} - showInfo={false} - /> - {score} -
- ), - }, - { - title: '发生概率', - dataIndex: 'probability', - key: 'probability', - width: 120, - render: (probability) => ( -
- - ({probability}/5) -
- ), - }, - { - title: '影响程度', - dataIndex: 'impact', - key: 'impact', - width: 120, - render: (impact) => ( -
- - ({impact}/5) -
- ), - }, - { - title: '处理状态', - dataIndex: 'status', - key: 'status', - width: 100, - render: (status) => ( - - {status} - - ), - }, - { - title: '评估人', - dataIndex: 'assessor', - key: 'assessor', - width: 100, - }, - { - title: '评估日期', - dataIndex: 'assessDate', - key: 'assessDate', - width: 120, - }, - { - title: '操作', - key: 'action', - width: 200, - render: (_, record) => ( - - - - - - ), - }, - ]; + // 表格列定义 + const columns = [ + { + title: '编号', + dataIndex: 'id', + key: 'id', + width: 80, + render: (text, record, index) => { + const page = pagination.current || 1; + const pageSize = pagination.pageSize || 5; + const number = (page - 1) * pageSize + index + 1; + return `0${number}`.slice(-2); + } + }, + { + title: '设备编号', + dataIndex: 'deviceId', + key: 'deviceId', + width: 120, + }, + { + title: '风险等级', + dataIndex: 'riskLevel', + key: 'riskLevel', + width: 100, + render: (text) => { + const colorMap = { + '高': '#FF4D4F', + '中': '#FAAD14', + '低': '#52C41A' + }; + return {text}; + } + }, + { + title: '预警时间', + dataIndex: 'warningTime', + key: 'warningTime', + width: 150, + }, + { + title: '主要原因', + dataIndex: 'mainReason', + key: 'mainReason', + width: 200, + }, + { + title: '处理状态', + dataIndex: 'status', + key: 'status', + width: 100, + render: (text) => { + const statusMap = { + '未处理': { color: '#FF4D4F', bg: '#FFF2F0' }, + '处理中': { color: '#FAAD14', bg: '#FFFBE6' }, + '已处理': { color: '#52C41A', bg: '#F6FFED' } + }; + const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' }; + return ( + + {text} + + ); + } + }, + { + title: '操作', + key: 'action', + width: 120, + render: (_, record) => ( +
+ + +
+ ), + }, + ]; - return ( -
- } onClick={handleAdd}> - 新增评估 - - } - > -
- `第 ${range[0]}-${range[1]} 条/共 ${total} 条`, - onChange: (page, pageSize) => { - setPagination(prev => ({ - ...prev, - current: page, - pageSize: pageSize || prev.pageSize, - })); - }, - }} - /> - + // 模拟数据 + const mockData = [ + { + key: '1', + id: '001', + deviceId: 'DEV-001', + riskLevel: '高', + warningTime: '2024-01-15 08:30:25', + mainReason: '设备温度异常升高', + status: '未处理', + }, + { + key: '2', + id: '002', + deviceId: 'DEV-002', + riskLevel: '中', + warningTime: '2024-01-15 09:15:10', + mainReason: '压力波动超出正常范围', + status: '处理中', + }, + { + key: '3', + id: '003', + deviceId: 'DEV-003', + riskLevel: '高', + warningTime: '2024-01-15 10:45:30', + mainReason: '液位传感器故障', + status: '已处理', + }, + { + key: '4', + id: '004', + deviceId: 'DEV-004', + riskLevel: '高', + warningTime: '2024-01-15 11:20:45', + mainReason: '检测到气体泄漏', + status: '未处理', + }, + { + key: '5', + id: '005', + deviceId: 'DEV-005', + riskLevel: '低', + warningTime: '2024-01-15 12:10:20', + mainReason: '设备振动异常', + status: '已处理', + }, + { + key: '6', + id: '006', + deviceId: 'DEV-006', + riskLevel: '中', + warningTime: '2024-01-15 13:25:15', + mainReason: '流量传感器读数异常', + status: '未处理', + }, + { + key: '7', + id: '007', + deviceId: 'DEV-007', + riskLevel: '高', + warningTime: '2024-01-15 14:10:30', + mainReason: '储罐压力超限', + status: '处理中', + }, + { + key: '8', + id: '008', + deviceId: 'DEV-008', + riskLevel: '中', + warningTime: '2024-01-15 15:45:20', + mainReason: '管道温度异常', + status: '已处理', + }, + { + key: '9', + id: '009', + deviceId: 'DEV-009', + riskLevel: '高', + warningTime: '2024-01-15 16:30:45', + mainReason: '阀门控制系统故障', + status: '未处理', + }, + { + key: '10', + id: '010', + deviceId: 'DEV-010', + riskLevel: '低', + warningTime: '2024-01-15 17:15:10', + mainReason: '轻微泄漏检测', + status: '已处理', + }, + { + key: '11', + id: '011', + deviceId: 'DEV-011', + riskLevel: '高', + warningTime: '2024-01-15 18:20:35', + mainReason: '安全阀异常开启', + status: '处理中', + }, + { + key: '12', + id: '012', + deviceId: 'DEV-012', + riskLevel: '中', + warningTime: '2024-01-15 19:05:50', + mainReason: '液位计读数不稳定', + status: '未处理', + }, + ]; + + // 初始化数据 + useEffect(() => { + setPagination(prev => ({ ...prev, total: mockData.length })); + }, []); + + // 根据分页获取当前页数据 + const getCurrentPageData = () => { + const { current, pageSize } = pagination; + const startIndex = (current - 1) * pageSize; + const endIndex = startIndex + pageSize; + return mockData.slice(startIndex, endIndex); + }; + + // 表格选择变化 + const onSelectChange = (newSelectedRowKeys, newSelectedRows) => { + setSelectedRowKeys(newSelectedRowKeys); + setSelectedRows(newSelectedRows); + }; + + // 分页变化处理 + const handleTableChange = (pagination) => { + setPagination(prev => ({ + ...prev, + current: pagination.current, + pageSize: pagination.pageSize, + })); + }; + + return ( +
+ {/* 第一个div - 高度20% */} +
+
+
+ {/* 块1 */} +
+
+
总危险源数量
+
65
+
+ + 较昨日 +2 +
+
+
+ 总危险源数量 +
+
+ + {/* 块2 */} +
+
+
高风险设备
+
65
+
+ + 较昨日 +2 +
+
+
+ 高风险设备 +
+
+ + {/* 块3 */} +
+
+
今日预警次数
+
65
+
+ + 较昨日 +2 +
+
+
+ 今日预警次数 +
+
- { - setModalVisible(false); - form.resetFields(); - }} - onOk={() => form.submit()} - width={700} - > -
- - - + {/* 块4 */} +
+
+
未处理预警
+
65
+
+ + 较昨日 +2 +
+
+
+ 未处理预警 +
+
- - - + {/* 块5 */} +
+
+
已处理预警
+
65
+
+ + 已完成 +
+
+
+ 已处理预警 +
+
+
+
+
- - - + +
+
+
+
+ +
+
+ 危险源风险热力分布 +
+ +
+
+
+
+
- - - +
+
- - - + {/* 第三个div - 占满剩余位置 */} +
+
+
+ {/* 第一行块 - 蓝色方块加标题 */} +
+
+
风险评估参数
+
+ + {/* 第二行块 - 图片 */} +
+ {/* 风险评估图 */} +
+ + {/* 第三行块 */} +
+
风险等级
+
高风险
+
+ + {/* 第四行块 */} +
+
评估时间
+
2024-01-15
+
+ + {/* 第五行块 */} +
+
评估人员
+
张三
+
+
+ +
+ {/* 表格 */} +
+
+
+
最新预警信息
+
+
- - - - - -
- ); -}; + {/* 表格 */} +
+ + `共 ${total} 条`, + }} + scroll={{ x: 1200 }} + /> +
+
+
+ + + ); +}; -export default RiskAssessment; +export default RiskAssessment; \ No newline at end of file diff --git a/src/pages/business_basic/module/RiskAssessment.less b/src/pages/business_basic/module/RiskAssessment.less index ea268cc..ab8ffe0 100644 --- a/src/pages/business_basic/module/RiskAssessment.less +++ b/src/pages/business_basic/module/RiskAssessment.less @@ -1,241 +1,418 @@ -.risk-assessment { - padding: 20px; - - .ant-card { - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - border-radius: 6px; - - .ant-card-head { - border-bottom: 1px solid #f0f0f0; - - .ant-card-head-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } +.Rcontainer { + padding: 8px 6px 0px 6px; + height: 100%; + display: flex; + flex-direction: column; + gap: 10px; - .ant-card-body { - padding: 20px; - } - } - - .ant-table { - .ant-table-thead > tr > th { - background-color: #fafafa; - font-weight: 600; - color: #262626; - border-bottom: 1px solid #f0f0f0; - } + // 第一个div - 高度20% + .RcontainerTop { + height: 16%; + // background-color: #fff; + border-radius: 4px; + display: flex; + flex-direction: column; - .ant-table-tbody > tr > td { - border-bottom: 1px solid #f0f0f0; - } + .sectionContent { + height: 100%; + display: flex; + flex-direction: column; + // padding: 15px; - .ant-table-tbody > tr:hover > td { - background-color: #f5f5f5; - } - } - - .ant-btn { - border-radius: 4px; - - &.ant-btn-primary { - background-color: #1890ff; - border-color: #1890ff; - - &:hover { - background-color: #40a9ff; - border-color: #40a9ff; - } - } + .blocksContainer { + flex: 1; + display: flex; + gap: 10px; + height: 100%; - &.ant-btn-link { - padding: 4px 8px; - height: auto; - - &:hover { - background-color: #f5f5f5; - } - } - } - - .ant-tag { - border-radius: 4px; - font-size: 12px; - padding: 2px 8px; - } - - .ant-rate { - font-size: 14px; - - .ant-rate-star { - margin-right: 2px; - } - } + .blockItem { + flex: 1; + height: 100%; + display: flex; + background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 92.55%); + border-radius: 4px; + border: 2px solid #FFFFFF; - .ant-progress { - .ant-progress-bg { - border-radius: 2px; - } - - &.ant-progress-small { - .ant-progress-text { - font-size: 10px; - } - } - } - - .ant-modal { - .ant-modal-header { - border-bottom: 1px solid #f0f0f0; - - .ant-modal-title { - font-size: 16px; - font-weight: 600; - color: #262626; - } - } + .blockLeft { + width: 60%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + padding: 15px; + padding-left: 20px; + gap: 8px; - .ant-modal-body { - padding: 24px; - } + .blockTitle { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #666666; + line-height: 1.2; + } - .ant-form-item-label > label { - font-weight: 500; - color: #262626; - } + .blockNumber { + font-family: PingFang SC; + font-weight: 700; + font-size: 24px; + color: #333333; + line-height: 1.2; + } - .ant-input, - .ant-select-selector { - border-radius: 4px; - border: 1px solid #d9d9d9; - - &:hover { - border-color: #40a9ff; - } - - &:focus, - &.ant-select-focused .ant-select-selector { - border-color: #40a9ff; - box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); - } - } - } - - .ant-pagination { - margin-top: 16px; - text-align: right; - - .ant-pagination-total-text { - color: #8c8c8c; - margin-right: 16px; - } - } - - // 风险等级颜色 - .risk-level-high { - color: #ff4d4f; - font-weight: 600; - } - - .risk-level-medium { - color: #faad14; - font-weight: 600; - } - - .risk-level-low { - color: #52c41a; - font-weight: 600; - } - - // 状态指示器 - .status-indicator { - display: inline-flex; - align-items: center; - gap: 4px; - - &.processed { - color: #52c41a; - } - - &.pending { - color: #ff4d4f; - } - - &.monitoring { - color: #1890ff; - } - } + .blockChange { + font-family: PingFang SC; + font-weight: 400; + font-size: 12px; + color: #1269FF; + line-height: 1.2; + display: flex; + align-items: center; + gap: 4px; - // 评分显示 - .score-display { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; - - .score-value { - font-weight: 600; - font-size: 14px; - } - - .score-label { - font-size: 12px; - color: #8c8c8c; - } - } + .arrow { + font-size: 14px; + font-weight: bold; + } - // 概率和影响程度显示 - .rate-display { - display: flex; - flex-direction: column; - align-items: center; - gap: 4px; - - .rate-stars { - display: flex; - align-items: center; - gap: 2px; + .checkIcon { + font-size: 16px; + color: #1269FF; + } + } + } + + .blockRight { + flex: 1; + height: 100%; + background-color: transparent; + border-radius: 0 4px 4px 0; + display: flex; + align-items: center; + justify-content: center; + + .blockImage { + // width: 80%; + height: 130%; + // height: 80%; + object-fit: contain; + margin-right: -10px; + } + } + } + } + } } - - .rate-text { - font-size: 12px; - color: #8c8c8c; + + // 第二个div - 高度30% + .RcontainerMiddle { + height: 30%; + border-radius: 4px; + display: flex; + flex-direction: column; + + .sectionContent { + height: 100%; + display: flex; + display: flex; + gap: 10px; + height: 100%; + + + + .middleBlock1 { + flex: 1; + height: 100%; + background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 53.01%); + + border: 2px solid #fff; + border-radius: 4px; + position: relative; + padding: 0px 10px 10px 2px; + font-family: PingFang SC; + font-size: 14px; + color: #333333; + + .block1Header { + position: absolute; + top: 5px; + left: 10px; + right: 10px; + display: flex; + justify-content: space-between; + align-items: center; + z-index: 10; + + .block1Title { + display: flex; + align-items: center; + gap: 8px; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 14px; + background-color: #2E4CD4; + } + } + + .block1Select { + width: 100px; + + :global(.ant-select-selector) { + height: 28px !important; + font-size: 12px !important; + } + + :global(.ant-select-selection-item) { + line-height: 26px !important; + font-size: 12px !important; + } + } + } + + .riskLegend { + position: absolute; + Top: 18px; + left: 50%; + transform: translateX(-50%); + display: flex; + justify-content: center; + align-items: center; + gap: 10px; + z-index: 10; + + .legendItem { + display: flex; + align-items: center; + gap: 5px; + + .legendDot { + width: 8px; + height: 8px; + border-radius: 50%; + } + + .legendText { + font-size: 12px; + color: #333; + font-weight: 400; + } + } + } + + .block1Chart { + width: 100%; + height: 100%; + margin-top: 20px; + + .mapImage { + margin-top: 7%; + width: 90%; + height: 77%; + object-fit: cover; + border-radius: 4px; + display: block; + margin-left: auto; + margin-right: auto; + } + } + } + + .middleBlock2 { + flex: 1; + height: 100%; + // background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 53.01%); + // border: 2px solid #fff; + background-color: #fff; + // border-radius: 4px; + display: flex; + flex-direction: column; + font-family: PingFang SC; + font-size: 14px; + color: #333333; + padding: 5px 10px 5px 10px; + + .middleBlock2Title { + display: flex; + justify-content: space-between; + align-items: center; + // margin-bottom: 10px; + + .titleLeft { + display: flex; + align-items: center; + gap: 8px; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 14px; + background-color: #2E4CD4; + } + } + + .titleRight { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; + color: #666; + } + } + + .middleBlock2Chart { + width: 100%; + height: 100%; + // min-height: 200px; + } + } + + } } - } - - // 风险矩阵样式 - .risk-matrix { - display: grid; - grid-template-columns: repeat(5, 1fr); - gap: 8px; - margin: 16px 0; - - .matrix-cell { - padding: 8px; - text-align: center; - border: 1px solid #d9d9d9; - border-radius: 4px; - font-size: 12px; - - &.high-risk { - background-color: #fff2f0; - border-color: #ff4d4f; - color: #ff4d4f; - } - - &.medium-risk { - background-color: #fffbe6; - border-color: #faad14; - color: #faad14; - } - - &.low-risk { - background-color: #f6ffed; - border-color: #52c41a; - color: #52c41a; - } + + // 第三个div - 占满剩余位置 + .RcontainerBottom { + flex: 1; // 占满剩余空间 + display: flex; + flex-direction: column; + + .sectionContent { + display: flex; + flex-direction: row; + gap: 10px; + padding: 0; + + .leftBlock { + width: 30%; + height: 100%; + background: url('@/assets/safe_majorHazard/online_monitoring/risk3.png') no-repeat center center; + background-size: cover; + padding: 0; + display: flex; + flex-direction: column; + gap: 10px; + padding: 15px; + + .leftBlockTitle { + display: flex; + align-items: center; + gap: 8px; + font-family: PingFang SC; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 16px; + background-color: #2E4CD4; + } + } + + .leftBlockImage { + height: 40%; + width: 100%; + border-radius: 4px; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + height: 80%; + } + + .leftBlockItem { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + padding: 10px; + // background-color: #f5f5f5; + border-radius: 4px; + font-family: PingFang SC; + + .itemTitle { + font-size: 12px; + color: #666666; + margin-bottom: 5px; + } + + .itemValue { + font-size: 14px; + color: #333333; + font-weight: 500; + } + } + } + + .rightBlock { + width: 68%; + height: 100%; + background-color: #fff; + padding: 0; + display: flex; + flex-direction: column; + + .tableHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 15px 5px 15px; + + .tableTitle { + display: flex; + align-items: center; + gap: 8px; + font-family: PingFang SC; + font-weight: 500; + font-size: 14px; + color: #333333; + + .titleIcon { + width: 3px; + height: 16px; + background-color: #2E4CD4; + } + } + } + + .tableContainer { + flex: 1; + overflow: hidden; + + :global(.ant-table) { + font-size: 12px; + } + + :global(.ant-table-thead > tr > th) { + background-color: #f5f5fa; + font-weight: 500; + font-size: 14px; + color: #333333; + border-bottom: 1px solid #f0f0f0; + padding: 8px 12px; + text-align: center; + } + + :global(.ant-table-tbody > tr > td) { + padding: 8px 12px; + border-bottom: 1px solid #f0f0f0; + text-align: center; + } + + :global(.ant-table-tbody > tr:hover > td) { + background-color: #f5f5f5; + } + + :global(.ant-pagination) { + margin-top: 16px; + text-align: right; + } + } + } + } } - } -} +} \ No newline at end of file