diff --git a/config/routes.js b/config/routes.js
index b2e1d63..dc7441b 100644
--- a/config/routes.js
+++ b/config/routes.js
@@ -30,6 +30,12 @@ export default [
name: 'basic',
component: './business_basic/basic',
},
+ // 消防重点部位管理
+ {
+ path: '/topnavbar00/business/firekeynotearea',
+ name: 'firekeynotearea',
+ component: './business_firekeynotearea/FireKeynoteArea',
+ },
// 安全管理基础信息
{
path: '/topnavbar00/business/basicinformation',
diff --git a/src/assets/business_firekeynotearea/eqicon1.png b/src/assets/business_firekeynotearea/eqicon1.png
new file mode 100644
index 0000000..03c5873
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon1.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon2.png b/src/assets/business_firekeynotearea/eqicon2.png
new file mode 100644
index 0000000..2231524
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon2.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon3.png b/src/assets/business_firekeynotearea/eqicon3.png
new file mode 100644
index 0000000..d642214
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon3.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon4.png b/src/assets/business_firekeynotearea/eqicon4.png
new file mode 100644
index 0000000..e161b78
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon4.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon5.png b/src/assets/business_firekeynotearea/eqicon5.png
new file mode 100644
index 0000000..9f5c131
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon5.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon6.png b/src/assets/business_firekeynotearea/eqicon6.png
new file mode 100644
index 0000000..122d7ad
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon6.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon7.png b/src/assets/business_firekeynotearea/eqicon7.png
new file mode 100644
index 0000000..d178645
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon7.png differ
diff --git a/src/assets/business_firekeynotearea/eqicon8.png b/src/assets/business_firekeynotearea/eqicon8.png
new file mode 100644
index 0000000..68a2821
Binary files /dev/null and b/src/assets/business_firekeynotearea/eqicon8.png differ
diff --git a/src/assets/business_firekeynotearea/keyparts_bg.png b/src/assets/business_firekeynotearea/keyparts_bg.png
new file mode 100644
index 0000000..4e95bf2
Binary files /dev/null and b/src/assets/business_firekeynotearea/keyparts_bg.png differ
diff --git a/src/assets/business_firekeynotearea/map.png b/src/assets/business_firekeynotearea/map.png
new file mode 100644
index 0000000..cfdf182
Binary files /dev/null and b/src/assets/business_firekeynotearea/map.png differ
diff --git a/src/assets/business_firekeynotearea/tree-child-node-selected.svg b/src/assets/business_firekeynotearea/tree-child-node-selected.svg
new file mode 100644
index 0000000..9f3b982
--- /dev/null
+++ b/src/assets/business_firekeynotearea/tree-child-node-selected.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/assets/business_firekeynotearea/tree-child-node.svg b/src/assets/business_firekeynotearea/tree-child-node.svg
new file mode 100644
index 0000000..614d428
--- /dev/null
+++ b/src/assets/business_firekeynotearea/tree-child-node.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/assets/business_firekeynotearea/tree-parent-node.svg b/src/assets/business_firekeynotearea/tree-parent-node.svg
new file mode 100644
index 0000000..6b6f47c
--- /dev/null
+++ b/src/assets/business_firekeynotearea/tree-parent-node.svg
@@ -0,0 +1,15 @@
+
diff --git a/src/assets/img/fire_keynote_area.svg b/src/assets/img/fire_keynote_area.svg
new file mode 100644
index 0000000..d8b1c5c
--- /dev/null
+++ b/src/assets/img/fire_keynote_area.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/pages/business_firekeynotearea/FireKeynoteArea.js b/src/pages/business_firekeynotearea/FireKeynoteArea.js
new file mode 100644
index 0000000..e4ac73b
--- /dev/null
+++ b/src/pages/business_firekeynotearea/FireKeynoteArea.js
@@ -0,0 +1,56 @@
+import React, { useState } from 'react';
+import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
+import styles from './FireKeynoteArea.less';
+import KeypartsBasicInformation from './components/KeypartsBasicInformation'; //重点部位基础信息管理
+import EmergencyPlanAssociation from './components/EmergencyPlanAssociation'; //应急预案关联管理
+import EmergencyDrillRecordAssociation from './components/EmergencyDrillRecordAssociation'; //应急演练记录关联管理
+
+const FireKeynoteArea = () => {
+ const [activeModule, setActiveModule] = useState('1');
+
+ const handleModuleClick = (module) => {
+ setActiveModule(module)
+ }
+
+
+ const renderModule = () => {
+ switch (activeModule) {
+ case '1':
+ return ;
+ case '2':
+ return ;
+ case '3':
+ return ;
+ default:
+ return ;
+ }
+ };
+
+
+ return (
+
+
+
+
+
+
+
+ {renderModule()}
+
+
+ );
+};
+
+export default FireKeynoteArea;
diff --git a/src/pages/business_firekeynotearea/FireKeynoteArea.less b/src/pages/business_firekeynotearea/FireKeynoteArea.less
new file mode 100644
index 0000000..b479169
--- /dev/null
+++ b/src/pages/business_firekeynotearea/FireKeynoteArea.less
@@ -0,0 +1,66 @@
+.container {
+ background-color: transparent;
+ width: 100%;
+ height: 89vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+
+ .TopButton {
+ background-color: white;
+ width: 100%;
+ padding: 10px 30px;
+ display: flex;
+ gap: 24px;
+ margin-left: 6px;
+
+ .TopButtonItem {
+ background-color: transparent !important;
+ color: #333333 !important;
+ font-family: 'PingFang SC', sans-serif !important;
+ font-weight: 500 !important;
+ font-size: 14px !important;
+ line-height: 100% !important;
+ border-radius: 8px !important;
+ padding: 6px 10px !important;
+ height: auto !important;
+ border: none !important;
+ box-shadow: none !important;
+ position: relative !important;
+
+ &:hover {
+ color: #333333 !important;
+ border: none !important;
+ }
+
+ &:focus {
+ color: #2E4CD4 !important;
+ border: none !important;
+ }
+
+ &.active {
+ color: #2E4CD4 !important;
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: -10px;
+ left: 0;
+ right: 0;
+ width: 100%;
+ height: 4px;
+ background-color: #2E4CD4;
+ border-radius: 0;
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ .content {
+ // ======== 内容区域样式 ========
+ flex: 1; // ======== 占据剩余空间 ========
+ overflow-y: auto; // ======== 允许垂直滚动 ========
+ padding: 0; // ======== 无内边距 ========
+ }
+}
\ No newline at end of file
diff --git a/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.js b/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.js
new file mode 100644
index 0000000..e963cc2
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.js
@@ -0,0 +1,749 @@
+
+import React, { useEffect, useRef, useState } from 'react';
+import { Card, Result, Select, Button, Segmented, Input } from 'antd';
+import { PlusOutlined } from '@ant-design/icons';
+import * as echarts from 'echarts';
+import StandardTable from '@/components/StandardTable';
+import styles from './EmergencyDrillRecordAssociation.less';
+import eqicon1 from '@/assets/business_firekeynotearea/eqicon1.png';
+import eqicon6 from '@/assets/business_firekeynotearea/eqicon6.png';
+import eqicon7 from '@/assets/business_firekeynotearea/eqicon7.png';
+import eqicon8 from '@/assets/business_firekeynotearea/eqicon8.png';
+
+const EmergencyDrillRecordAssociation = () => {
+ const chartRef = useRef(null);
+ const pieChartRef = useRef(null);
+ const faultPieChartRef = 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,
+ });
+
+ // 饼图初始化
+ useEffect(() => {
+ if (pieChartRef.current) {
+ const pieChart = echarts.init(pieChartRef.current);
+
+ const pieOption = {
+ color: ['#44BB5F', '#F8C541', '#A493FB', '#4B69F1', '#949FD0'],
+ legend: {
+ orient: 'vertical',
+ right: '10%',
+ top: 'center',
+ itemWidth: 13,
+ itemHeight: 4,
+ textStyle: {
+ fontSize: 12,
+ color: '#333'
+ }
+ },
+ series: [{
+ name: '设备状态',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ center: ['35%', '50%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: 'center'
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '14',
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: false
+ },
+ data: [
+ { value: 480, name: '配电房' },
+ { value: 289, name: '消防控制室' },
+ { value: 200, name: '档案室' },
+ { value: 150, name: '服务器机房' },
+ { value: 161, name: '食堂厨房' }
+ ]
+ }]
+ };
+
+ pieChart.setOption(pieOption);
+
+ // 响应式调整
+ const handlePieResize = () => {
+ if (pieChart && !pieChart.isDisposed()) {
+ pieChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handlePieResize);
+
+ return () => {
+ window.removeEventListener('resize', handlePieResize);
+ if (pieChart && !pieChart.isDisposed()) {
+ pieChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ // 故障类型饼图初始化
+ useEffect(() => {
+ if (faultPieChartRef.current) {
+ const faultPieChart = echarts.init(faultPieChartRef.current);
+
+ const faultPieOption = {
+ color: ['#FF3E48', '#FF8800', '#FFC403'],
+ legend: {
+ orient: 'vertical',
+ right: '10%',
+ top: 'center',
+ itemWidth: 8,
+ itemHeight: 8,
+ textStyle: {
+ fontSize: 12,
+ color: '#333'
+ }
+ },
+ series: [{
+ name: '设备故障类型',
+ type: 'pie',
+ radius: '70%',
+ center: ['35%', '50%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: true,
+ position: 'outside',
+ formatter: '{b}: {c}',
+ fontSize: 12
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '14',
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: true
+ },
+ data: [
+ { value: 120, name: '紧急' },
+ { value: 80, name: '重要' },
+ { value: 60, name: '一般' }
+ ]
+ }]
+ };
+
+ faultPieChart.setOption(faultPieOption);
+
+ // 响应式调整
+ const handleFaultPieResize = () => {
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handleFaultPieResize);
+
+ return () => {
+ window.removeEventListener('resize', handleFaultPieResize);
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ useEffect(() => {
+ if (chartRef.current) {
+ const chart = echarts.init(chartRef.current);
+
+ // 强制初始化时调整大小
+ setTimeout(() => {
+ if (chart && !chart.isDisposed()) {
+ chart.resize();
+ }
+ }, 100);
+
+ const option = {
+ color: ['#8979FF', '#3CC3DF'],
+
+ legend: {
+ // data: ['消防水泵1', '消防水泵2'],
+ top: "-3px",
+ // left: "center",
+ // itemGap: 40,
+ itemWidth: 20,
+ itemHeight: 8,
+ // icon: 'path://M902 472.7H747.9c-19.1-113.3-117.7-200-236.4-200s-217.3 86.7-236.4 200H119.7c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h155.5c19.1 113.3 117.7 200 236.4 200S728.9 666 748 552.7h154c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z m-390.5 200c-88.2 0-160-71.8-160-160s71.8-160 160-160 160 71.8 160 160-71.8 160-160 160z',
+ textStyle: {
+ fontSize: 10
+ }
+ },
+ grid: {
+ left: '2%',
+ right: '4%',
+ bottom: '2%',
+ top: '12%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: ['9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00'],
+ axisLabel: {
+ fontSize: 10
+ }
+ },
+ yAxis: {
+ type: 'value',
+ min: 0,
+ max: 30,
+ axisLabel: {
+ formatter: '{value}',
+ fontSize: 10
+ }
+ },
+ series: [
+ {
+ name: '消防水泵1',
+ type: 'line',
+ smooth: false,
+ lineStyle: {
+ width: 2,
+ color: '#8979FF'
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(137, 121, 255, 0.3)' },
+ { offset: 1, color: 'rgba(137, 121, 255, 0.05)' }
+ ]
+ }
+ },
+ symbol: 'circle',
+ symbolSize: 4,
+ itemStyle: {
+ color: '#fff',
+ borderColor: '#8979FF',
+ borderWidth: 1
+ },
+ data: [12, 15, 18, 14, 16, 20, 22, 19, 17, 21, 23, 25]
+ },
+ {
+ name: '消防水泵2',
+ type: 'line',
+ smooth: false,
+ lineStyle: {
+ width: 2,
+ color: '#3CC3DF'
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(60, 195, 223, 0.3)' },
+ { offset: 1, color: 'rgba(60, 195, 223, 0.05)' }
+ ]
+ }
+ },
+ symbol: 'circle',
+ symbolSize: 4,
+ itemStyle: {
+ color: '#fff',
+ borderColor: '#3CC3DF',
+ borderWidth: 1
+ },
+ data: [8, 11, 14, 10, 13, 17, 19, 16, 14, 18, 20, 22]
+ }
+ ]
+ };
+
+ chart.setOption(option);
+
+ // 响应式调整 - 使用多种方式监听容器尺寸变化
+ 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 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);
+ }
+
+ // 使用MutationObserver监听DOM结构变化(菜单展开收起时)
+ const mutationObserver = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.type === 'attributes' &&
+ (mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
+ // 延迟执行,确保DOM更新完成
+ setTimeout(() => {
+ handleResize();
+ }, 200);
+ }
+ });
+ });
+
+ // 监听整个页面的class和style变化
+ mutationObserver.observe(document.body, {
+ attributes: true,
+ attributeFilter: ['class', 'style'],
+ subtree: true
+ });
+
+ 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: 'drillId',
+ key: 'drillId',
+ width: 140,
+ },
+ {
+ title: '演练时间',
+ dataIndex: 'drillTime',
+ key: 'drillTime',
+ width: 180,
+ },
+ {
+ title: '演练类型',
+ dataIndex: 'drillType',
+ key: 'drillType',
+ width: 120,
+ },
+ {
+ title: '关联部位',
+ dataIndex: 'relatedPart',
+ key: 'relatedPart',
+ width: 120,
+ },
+ {
+ title: '部位名称',
+ dataIndex: 'partName',
+ key: 'partName',
+ width: 160,
+ },
+ {
+ title: '演练次数',
+ dataIndex: 'drillCount',
+ key: 'drillCount',
+ width: 100,
+ },
+ {
+ title: '参与人数',
+ dataIndex: 'participantCount',
+ key: 'participantCount',
+ width: 100,
+ },
+ {
+ title: '效果评估',
+ dataIndex: 'effect',
+ key: 'effect',
+ width: 120,
+ render: (text) => {
+ let color = '#FFF3E9', fontColor = '#FF8800', label = text;
+ if (text === '优秀') {
+ color = '#D8F7DE';
+ fontColor = '#44BB5F';
+ }
+ return (
+ {label}
+ );
+ }
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 120,
+ render: (_, record) => (
+ <>
+ 编辑
+ 删除
+ >
+ ),
+ },
+ ];
+
+ // 表格数据(同步图片)
+ const mockData = [
+ {
+ key: '1',
+ drillId: 'YL202310001',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '实战演练',
+ relatedPart: '三楼东侧',
+ partName: '数据机房 A区',
+ drillCount: 5,
+ participantCount: 25,
+ effect: '良好',
+ },
+ {
+ key: '2',
+ drillId: 'YL202310002',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '桌面推演',
+ relatedPart: '二楼西侧',
+ partName: 'B区厨房',
+ drillCount: 6,
+ participantCount: 18,
+ effect: '良好',
+ },
+ {
+ key: '3',
+ drillId: 'YL202310003',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '模拟演练',
+ relatedPart: '地下一层',
+ partName: '数据中心机房',
+ drillCount: 3,
+ participantCount: 32,
+ effect: '优秀',
+ },
+ ];
+
+ // 初始化数据
+ 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 handleAddDevice = () => {
+ console.log('新增设备');
+ // TODO: 实现新增设备逻辑
+ };
+
+ // 导出数据按钮点击事件
+ const handleExportData = () => {
+ console.log('导出数据');
+ // TODO: 实现导出数据逻辑
+ };
+
+ // 分页变化处理
+ const handleTableChange = (pagination) => {
+ setPagination(prev => ({
+ ...prev,
+ current: pagination.current,
+ pageSize: pagination.pageSize,
+ }));
+ };
+
+ // 重点部位卡片数据和选中状态
+ const keypartsData = [
+ {
+ name: '配电房',
+ location: '1楼 - 东区',
+ risk: '高风险',
+ riskColor: '#FFE0E2',
+ riskTextColor: '#FF3E48',
+ },
+ {
+ name: '消防控制室',
+ location: '1楼 - 西区',
+ risk: '中风险',
+ riskColor: '#FFF8E2',
+ riskTextColor: '#FFC403',
+ },
+ {
+ name: '档案室',
+ location: '2楼 - 中区',
+ risk: '低风险',
+ riskColor: '#DAF3FF',
+ riskTextColor: '#00AAFA',
+ }
+ ];
+ const [selectedKeypartIdx, setSelectedKeypartIdx] = useState(0);
+
+ return (
+
+ {/* 第一个div - 高度20% */}
+
+
+
+ {/* 块1 */}
+
+
+
+

+
+
+
+ {/* 块2 */}
+
+
+
+

+
+
+
+ {/* 块3 */}
+
+
+
+

+
+
+
+ {/* 块4 */}
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* 地图图片 */}
+
})
+
+
+
+
+
+
{
+ console.log(value);
+ }}
+ />
+
+ {/* 设备状态饼图 */}
+
+
+
+
+
+
+
+ {/* 重点部位列表 */}
+
+ {keypartsData.map((item, idx) => (
+
setSelectedKeypartIdx(idx)}
+ style={{ cursor: 'pointer' }}
+ >
+
+
+ {item.name}
+
+
{item.location}
+
+
+ {item.risk}
+
+
+ ))}
+
+
+
+
+
+
+
+ {/* 第三个div - 占满剩余位置 */}
+
+
+
+
+ {/* 表格 */}
+
+
+
+
+
+ {/* 搜索输入框 */}
+
+
+
+ {/* 下拉选择 */}
+
+ {/* 新增按钮 */}
+
+
+
+
+
+ {/* 表格 */}
+
+
+ `共 ${total} 条`,
+ }}
+ // scroll={{ x: 1200 }}
+ />
+
+
+
+
+
+ );
+};
+
+export default EmergencyDrillRecordAssociation;
\ No newline at end of file
diff --git a/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.less b/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.less
new file mode 100644
index 0000000..053e850
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EmergencyDrillRecordAssociation.less
@@ -0,0 +1,500 @@
+// 重点部位列表样式
+.keypartsList {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 200px;
+ margin: 35px 0 0 0;
+ overflow: auto;
+}
+
+.keypartsCard {
+ background: #f9fbff;
+ border: 1px solid #ECEDFC;
+ border-radius: 4px;
+ padding: 8px 12px 6px 12px;
+ box-shadow: 0 1px 4px 0 rgba(46, 76, 212, 0.03);
+ transition: border-color 0.2s, box-shadow 0.2s;
+ position: relative;
+ // min-height: 44px;
+ max-width: 300px;
+ width: 100%;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.keypartsCardActive {
+ border-color: #75A7FF;
+ background: #F6F7FF;
+ box-shadow: 0 2px 8px 0 rgba(46, 76, 212, 0.10);
+}
+
+.keypartsCardHeader {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 3px;
+}
+
+.keypartsCardTitle {
+ font-size: 12px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 8px;
+}
+
+.keypartsRiskTag {
+ display: inline-block;
+ min-width: 40px;
+ height: 30px;
+ line-height: 30px;
+ text-align: center;
+ font-size: 13px;
+ font-weight: 500;
+ border-radius: 5px;
+ padding: 0 8px;
+ box-shadow: 0 1px 3px 0 rgba(46, 76, 212, 0.05);
+}
+
+.keypartsCardSub {
+ font-size: 12px;
+ color: #666;
+ font-weight: 400;
+ letter-spacing: 0.5px;
+}
+
+.Rcontainer {
+ padding: 8px 6px 0px 6px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ // 第一个div - 高度20%
+ .RcontainerTop {
+ height: 16%;
+ // background-color: #fff;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ // padding: 15px;
+
+ .blocksContainer {
+ flex: 1;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+ .blockItem {
+ flex: 1;
+ height: 100%;
+ display: flex;
+ background: linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ border-radius: 2px;
+ // border: 2px solid #FFFFFF;
+
+ &.bgBlock1 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock2 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock3 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock4 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock5 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ .blockLeft {
+ width: 60%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 15px;
+ padding-left: 20px;
+ gap: 15px;
+
+ .blockTitle {
+ font-family: PingFang SC;
+ font-weight: 400;
+ font-size: 12px;
+ color: #333333;
+ 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;
+
+ .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 {
+ // width: 80%;
+ height: 65%;
+ // height: 80%;
+ object-fit: contain;
+ margin-right: -5px;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 第二个div - 高度39%
+ .RcontainerMiddle {
+ height: 100%;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+
+
+ .middleBlock1 {
+ // flex: 3;
+ width: 28%;
+ height: 100%;
+ background: #fff;
+
+ 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;
+ height: 28px;
+ line-height: 28px;
+
+ .block1Title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 14px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ .block1Segmented {
+ padding: 0;
+ margin: 0;
+ border: 1px solid #E3E3E3;
+ border-radius: 4px;
+ height: 28px;
+
+ :global(.ant-segmented) {
+ padding: 0;
+ margin: 0;
+ height: 28px;
+ }
+
+ :global(.ant-segmented-item) {
+ font-size: 12px;
+ // padding: 2px 8px;
+ height: 26px;
+ line-height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ :global(.ant-segmented-item-selected) {
+ background-color: #2E4CD4;
+ color: #fff;
+ }
+ }
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 35px;
+ left: 10px;
+ right: 10px;
+ bottom: 10px;
+ z-index: 10;
+ }
+
+ // .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: 6;
+ 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 {
+ font-size: 12px;
+ width: 60px;
+ height: 20px;
+ line-height: 20px;
+ background-color: #E6E9FB;
+ color: #2E4CD4;
+ text-align: center;
+ border-radius: 2px;
+ }
+ }
+
+ .middleBlock2Chart {
+ width: 100%;
+ height: 100%;
+ padding: 5px;
+ // min-height: 200px;
+ }
+ }
+
+ }
+ }
+
+ // 第三个div - 高度不超过45%
+ .RcontainerBottom {
+ height: 45%; // 限制高度不超过45%
+ max-height: 45%; // 确保最大高度不超过45%
+ // display: flex;
+ // flex-direction: column;
+
+ .sectionContent {
+ // display: flex;
+ // flex-direction: row;
+ // gap: 10px;
+ padding: 0;
+
+ .tableBlock {
+ width: 100%;
+ 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;
+ }
+ }
+
+ .tableActions {
+ display: flex;
+ gap: 8px;
+ margin-top: 5px;
+
+ .searchInput {
+ // flex: 1;
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // padding: 0 16px;
+ // font-size: 14px;
+ // color: #333;
+ // background: #fff;
+ // outline: none;
+ // box-shadow: none;
+ // transition: border-color 0.2s;
+ }
+
+ .searchInput:focus {
+ border-color: #2E4CD4;
+ }
+
+ .selectAll {
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // background: #fff;
+ // font-size: 14px;
+ // color: #333;
+ // padding: 0 32px 0 16px;
+ // margin-left: 12px;
+ }
+
+ .selectAll:focus {
+ border-color: #2E4CD4;
+ }
+
+ .addBtn {
+ background: #2E4CD4;
+ margin-left: 15px;
+ }
+
+ .addBtn:hover {
+ background: #1d3bb3;
+ }
+ }
+ }
+
+ .tableContainer {
+ flex: 1;
+ overflow: hidden;
+ margin: 10px 15px 0 15px; // 上边距10px,左右边距15px
+
+ :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;
+ color: #666666;
+ }
+
+ :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_firekeynotearea/components/EmergencyPlanAssociation.js b/src/pages/business_firekeynotearea/components/EmergencyPlanAssociation.js
new file mode 100644
index 0000000..27d689f
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EmergencyPlanAssociation.js
@@ -0,0 +1,749 @@
+
+import React, { useEffect, useRef, useState } from 'react';
+import { Card, Result, Select, Button, Segmented, Input } from 'antd';
+import { PlusOutlined } from '@ant-design/icons';
+import * as echarts from 'echarts';
+import StandardTable from '@/components/StandardTable';
+import styles from './EmergencyPlanAssociation.less';
+import eqicon1 from '@/assets/business_firekeynotearea/eqicon1.png';
+import eqicon6 from '@/assets/business_firekeynotearea/eqicon6.png';
+import eqicon7 from '@/assets/business_firekeynotearea/eqicon7.png';
+import eqicon8 from '@/assets/business_firekeynotearea/eqicon8.png';
+
+const EmergencyPlanAssociation = () => {
+ const chartRef = useRef(null);
+ const pieChartRef = useRef(null);
+ const faultPieChartRef = 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,
+ });
+
+ // 饼图初始化
+ useEffect(() => {
+ if (pieChartRef.current) {
+ const pieChart = echarts.init(pieChartRef.current);
+
+ const pieOption = {
+ color: ['#44BB5F', '#F8C541', '#A493FB', '#4B69F1', '#949FD0'],
+ legend: {
+ orient: 'vertical',
+ right: '10%',
+ top: 'center',
+ itemWidth: 13,
+ itemHeight: 4,
+ textStyle: {
+ fontSize: 12,
+ color: '#333'
+ }
+ },
+ series: [{
+ name: '设备状态',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ center: ['35%', '50%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: 'center'
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '14',
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: false
+ },
+ data: [
+ { value: 480, name: '配电房' },
+ { value: 289, name: '消防控制室' },
+ { value: 200, name: '档案室' },
+ { value: 150, name: '服务器机房' },
+ { value: 161, name: '食堂厨房' }
+ ]
+ }]
+ };
+
+ pieChart.setOption(pieOption);
+
+ // 响应式调整
+ const handlePieResize = () => {
+ if (pieChart && !pieChart.isDisposed()) {
+ pieChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handlePieResize);
+
+ return () => {
+ window.removeEventListener('resize', handlePieResize);
+ if (pieChart && !pieChart.isDisposed()) {
+ pieChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ // 故障类型饼图初始化
+ useEffect(() => {
+ if (faultPieChartRef.current) {
+ const faultPieChart = echarts.init(faultPieChartRef.current);
+
+ const faultPieOption = {
+ color: ['#FF3E48', '#FF8800', '#FFC403'],
+ legend: {
+ orient: 'vertical',
+ right: '10%',
+ top: 'center',
+ itemWidth: 8,
+ itemHeight: 8,
+ textStyle: {
+ fontSize: 12,
+ color: '#333'
+ }
+ },
+ series: [{
+ name: '设备故障类型',
+ type: 'pie',
+ radius: '70%',
+ center: ['35%', '50%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: true,
+ position: 'outside',
+ formatter: '{b}: {c}',
+ fontSize: 12
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '14',
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: true
+ },
+ data: [
+ { value: 120, name: '紧急' },
+ { value: 80, name: '重要' },
+ { value: 60, name: '一般' }
+ ]
+ }]
+ };
+
+ faultPieChart.setOption(faultPieOption);
+
+ // 响应式调整
+ const handleFaultPieResize = () => {
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handleFaultPieResize);
+
+ return () => {
+ window.removeEventListener('resize', handleFaultPieResize);
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ useEffect(() => {
+ if (chartRef.current) {
+ const chart = echarts.init(chartRef.current);
+
+ // 强制初始化时调整大小
+ setTimeout(() => {
+ if (chart && !chart.isDisposed()) {
+ chart.resize();
+ }
+ }, 100);
+
+ const option = {
+ color: ['#8979FF', '#3CC3DF'],
+
+ legend: {
+ // data: ['消防水泵1', '消防水泵2'],
+ top: "-3px",
+ // left: "center",
+ // itemGap: 40,
+ itemWidth: 20,
+ itemHeight: 8,
+ // icon: 'path://M902 472.7H747.9c-19.1-113.3-117.7-200-236.4-200s-217.3 86.7-236.4 200H119.7c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h155.5c19.1 113.3 117.7 200 236.4 200S728.9 666 748 552.7h154c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z m-390.5 200c-88.2 0-160-71.8-160-160s71.8-160 160-160 160 71.8 160 160-71.8 160-160 160z',
+ textStyle: {
+ fontSize: 10
+ }
+ },
+ grid: {
+ left: '2%',
+ right: '4%',
+ bottom: '2%',
+ top: '12%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: ['9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00'],
+ axisLabel: {
+ fontSize: 10
+ }
+ },
+ yAxis: {
+ type: 'value',
+ min: 0,
+ max: 30,
+ axisLabel: {
+ formatter: '{value}',
+ fontSize: 10
+ }
+ },
+ series: [
+ {
+ name: '消防水泵1',
+ type: 'line',
+ smooth: false,
+ lineStyle: {
+ width: 2,
+ color: '#8979FF'
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(137, 121, 255, 0.3)' },
+ { offset: 1, color: 'rgba(137, 121, 255, 0.05)' }
+ ]
+ }
+ },
+ symbol: 'circle',
+ symbolSize: 4,
+ itemStyle: {
+ color: '#fff',
+ borderColor: '#8979FF',
+ borderWidth: 1
+ },
+ data: [12, 15, 18, 14, 16, 20, 22, 19, 17, 21, 23, 25]
+ },
+ {
+ name: '消防水泵2',
+ type: 'line',
+ smooth: false,
+ lineStyle: {
+ width: 2,
+ color: '#3CC3DF'
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(60, 195, 223, 0.3)' },
+ { offset: 1, color: 'rgba(60, 195, 223, 0.05)' }
+ ]
+ }
+ },
+ symbol: 'circle',
+ symbolSize: 4,
+ itemStyle: {
+ color: '#fff',
+ borderColor: '#3CC3DF',
+ borderWidth: 1
+ },
+ data: [8, 11, 14, 10, 13, 17, 19, 16, 14, 18, 20, 22]
+ }
+ ]
+ };
+
+ chart.setOption(option);
+
+ // 响应式调整 - 使用多种方式监听容器尺寸变化
+ 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 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);
+ }
+
+ // 使用MutationObserver监听DOM结构变化(菜单展开收起时)
+ const mutationObserver = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.type === 'attributes' &&
+ (mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
+ // 延迟执行,确保DOM更新完成
+ setTimeout(() => {
+ handleResize();
+ }, 200);
+ }
+ });
+ });
+
+ // 监听整个页面的class和style变化
+ mutationObserver.observe(document.body, {
+ attributes: true,
+ attributeFilter: ['class', 'style'],
+ subtree: true
+ });
+
+ 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: 'drillId',
+ key: 'drillId',
+ width: 140,
+ },
+ {
+ title: '演练时间',
+ dataIndex: 'drillTime',
+ key: 'drillTime',
+ width: 180,
+ },
+ {
+ title: '演练类型',
+ dataIndex: 'drillType',
+ key: 'drillType',
+ width: 120,
+ },
+ {
+ title: '关联部位',
+ dataIndex: 'relatedPart',
+ key: 'relatedPart',
+ width: 120,
+ },
+ {
+ title: '部位名称',
+ dataIndex: 'partName',
+ key: 'partName',
+ width: 160,
+ },
+ {
+ title: '演练次数',
+ dataIndex: 'drillCount',
+ key: 'drillCount',
+ width: 100,
+ },
+ {
+ title: '参与人数',
+ dataIndex: 'participantCount',
+ key: 'participantCount',
+ width: 100,
+ },
+ {
+ title: '效果评估',
+ dataIndex: 'effect',
+ key: 'effect',
+ width: 120,
+ render: (text) => {
+ let color = '#FFF3E9', fontColor = '#FF8800', label = text;
+ if (text === '优秀') {
+ color = '#D8F7DE';
+ fontColor = '#44BB5F';
+ }
+ return (
+ {label}
+ );
+ }
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 120,
+ render: (_, record) => (
+ <>
+ 编辑
+ 删除
+ >
+ ),
+ },
+ ];
+
+ // 表格数据(同步图片)
+ const mockData = [
+ {
+ key: '1',
+ drillId: 'YL202310001',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '实战演练',
+ relatedPart: '三楼东侧',
+ partName: '数据机房 A区',
+ drillCount: 5,
+ participantCount: 25,
+ effect: '良好',
+ },
+ {
+ key: '2',
+ drillId: 'YL202310002',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '桌面推演',
+ relatedPart: '二楼西侧',
+ partName: 'B区厨房',
+ drillCount: 6,
+ participantCount: 18,
+ effect: '良好',
+ },
+ {
+ key: '3',
+ drillId: 'YL202310003',
+ drillTime: '2025-09-10 14:23:45',
+ drillType: '模拟演练',
+ relatedPart: '地下一层',
+ partName: '数据中心机房',
+ drillCount: 3,
+ participantCount: 32,
+ effect: '优秀',
+ },
+ ];
+
+ // 初始化数据
+ 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 handleAddDevice = () => {
+ console.log('新增设备');
+ // TODO: 实现新增设备逻辑
+ };
+
+ // 导出数据按钮点击事件
+ const handleExportData = () => {
+ console.log('导出数据');
+ // TODO: 实现导出数据逻辑
+ };
+
+ // 分页变化处理
+ const handleTableChange = (pagination) => {
+ setPagination(prev => ({
+ ...prev,
+ current: pagination.current,
+ pageSize: pagination.pageSize,
+ }));
+ };
+
+ // 重点部位卡片数据和选中状态
+ const keypartsData = [
+ {
+ name: '配电房',
+ location: '1楼 - 东区',
+ risk: '高风险',
+ riskColor: '#FFE0E2',
+ riskTextColor: '#FF3E48',
+ },
+ {
+ name: '消防控制室',
+ location: '1楼 - 西区',
+ risk: '中风险',
+ riskColor: '#FFF8E2',
+ riskTextColor: '#FFC403',
+ },
+ {
+ name: '档案室',
+ location: '2楼 - 中区',
+ risk: '低风险',
+ riskColor: '#DAF3FF',
+ riskTextColor: '#00AAFA',
+ }
+ ];
+ const [selectedKeypartIdx, setSelectedKeypartIdx] = useState(0);
+
+ return (
+
+ {/* 第一个div - 高度20% */}
+
+
+
+ {/* 块1 */}
+
+
+
+

+
+
+
+ {/* 块2 */}
+
+
+
+

+
+
+
+ {/* 块3 */}
+
+
+
+

+
+
+
+ {/* 块4 */}
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* 地图图片 */}
+
})
+
+
+
+
+
+
{
+ console.log(value);
+ }}
+ />
+
+ {/* 设备状态饼图 */}
+
+
+
+
+
+
+
+ {/* 重点部位列表 */}
+
+ {keypartsData.map((item, idx) => (
+
setSelectedKeypartIdx(idx)}
+ style={{ cursor: 'pointer' }}
+ >
+
+
+ {item.name}
+
+
{item.location}
+
+
+ {item.risk}
+
+
+ ))}
+
+
+
+
+
+
+
+ {/* 第三个div - 占满剩余位置 */}
+
+
+
+
+ {/* 表格 */}
+
+
+
+
+
+ {/* 搜索输入框 */}
+
+
+
+ {/* 下拉选择 */}
+
+ {/* 新增按钮 */}
+
+
+
+
+
+ {/* 表格 */}
+
+
+ `共 ${total} 条`,
+ }}
+ // scroll={{ x: 1200 }}
+ />
+
+
+
+
+
+ );
+};
+
+export default EmergencyPlanAssociation;
\ No newline at end of file
diff --git a/src/pages/business_firekeynotearea/components/EmergencyPlanAssociation.less b/src/pages/business_firekeynotearea/components/EmergencyPlanAssociation.less
new file mode 100644
index 0000000..053e850
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EmergencyPlanAssociation.less
@@ -0,0 +1,500 @@
+// 重点部位列表样式
+.keypartsList {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 200px;
+ margin: 35px 0 0 0;
+ overflow: auto;
+}
+
+.keypartsCard {
+ background: #f9fbff;
+ border: 1px solid #ECEDFC;
+ border-radius: 4px;
+ padding: 8px 12px 6px 12px;
+ box-shadow: 0 1px 4px 0 rgba(46, 76, 212, 0.03);
+ transition: border-color 0.2s, box-shadow 0.2s;
+ position: relative;
+ // min-height: 44px;
+ max-width: 300px;
+ width: 100%;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.keypartsCardActive {
+ border-color: #75A7FF;
+ background: #F6F7FF;
+ box-shadow: 0 2px 8px 0 rgba(46, 76, 212, 0.10);
+}
+
+.keypartsCardHeader {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 3px;
+}
+
+.keypartsCardTitle {
+ font-size: 12px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 8px;
+}
+
+.keypartsRiskTag {
+ display: inline-block;
+ min-width: 40px;
+ height: 30px;
+ line-height: 30px;
+ text-align: center;
+ font-size: 13px;
+ font-weight: 500;
+ border-radius: 5px;
+ padding: 0 8px;
+ box-shadow: 0 1px 3px 0 rgba(46, 76, 212, 0.05);
+}
+
+.keypartsCardSub {
+ font-size: 12px;
+ color: #666;
+ font-weight: 400;
+ letter-spacing: 0.5px;
+}
+
+.Rcontainer {
+ padding: 8px 6px 0px 6px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ // 第一个div - 高度20%
+ .RcontainerTop {
+ height: 16%;
+ // background-color: #fff;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ // padding: 15px;
+
+ .blocksContainer {
+ flex: 1;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+ .blockItem {
+ flex: 1;
+ height: 100%;
+ display: flex;
+ background: linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ border-radius: 2px;
+ // border: 2px solid #FFFFFF;
+
+ &.bgBlock1 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock2 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock3 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock4 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock5 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ .blockLeft {
+ width: 60%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 15px;
+ padding-left: 20px;
+ gap: 15px;
+
+ .blockTitle {
+ font-family: PingFang SC;
+ font-weight: 400;
+ font-size: 12px;
+ color: #333333;
+ 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;
+
+ .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 {
+ // width: 80%;
+ height: 65%;
+ // height: 80%;
+ object-fit: contain;
+ margin-right: -5px;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 第二个div - 高度39%
+ .RcontainerMiddle {
+ height: 100%;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+
+
+ .middleBlock1 {
+ // flex: 3;
+ width: 28%;
+ height: 100%;
+ background: #fff;
+
+ 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;
+ height: 28px;
+ line-height: 28px;
+
+ .block1Title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 14px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ .block1Segmented {
+ padding: 0;
+ margin: 0;
+ border: 1px solid #E3E3E3;
+ border-radius: 4px;
+ height: 28px;
+
+ :global(.ant-segmented) {
+ padding: 0;
+ margin: 0;
+ height: 28px;
+ }
+
+ :global(.ant-segmented-item) {
+ font-size: 12px;
+ // padding: 2px 8px;
+ height: 26px;
+ line-height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ :global(.ant-segmented-item-selected) {
+ background-color: #2E4CD4;
+ color: #fff;
+ }
+ }
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 35px;
+ left: 10px;
+ right: 10px;
+ bottom: 10px;
+ z-index: 10;
+ }
+
+ // .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: 6;
+ 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 {
+ font-size: 12px;
+ width: 60px;
+ height: 20px;
+ line-height: 20px;
+ background-color: #E6E9FB;
+ color: #2E4CD4;
+ text-align: center;
+ border-radius: 2px;
+ }
+ }
+
+ .middleBlock2Chart {
+ width: 100%;
+ height: 100%;
+ padding: 5px;
+ // min-height: 200px;
+ }
+ }
+
+ }
+ }
+
+ // 第三个div - 高度不超过45%
+ .RcontainerBottom {
+ height: 45%; // 限制高度不超过45%
+ max-height: 45%; // 确保最大高度不超过45%
+ // display: flex;
+ // flex-direction: column;
+
+ .sectionContent {
+ // display: flex;
+ // flex-direction: row;
+ // gap: 10px;
+ padding: 0;
+
+ .tableBlock {
+ width: 100%;
+ 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;
+ }
+ }
+
+ .tableActions {
+ display: flex;
+ gap: 8px;
+ margin-top: 5px;
+
+ .searchInput {
+ // flex: 1;
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // padding: 0 16px;
+ // font-size: 14px;
+ // color: #333;
+ // background: #fff;
+ // outline: none;
+ // box-shadow: none;
+ // transition: border-color 0.2s;
+ }
+
+ .searchInput:focus {
+ border-color: #2E4CD4;
+ }
+
+ .selectAll {
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // background: #fff;
+ // font-size: 14px;
+ // color: #333;
+ // padding: 0 32px 0 16px;
+ // margin-left: 12px;
+ }
+
+ .selectAll:focus {
+ border-color: #2E4CD4;
+ }
+
+ .addBtn {
+ background: #2E4CD4;
+ margin-left: 15px;
+ }
+
+ .addBtn:hover {
+ background: #1d3bb3;
+ }
+ }
+ }
+
+ .tableContainer {
+ flex: 1;
+ overflow: hidden;
+ margin: 10px 15px 0 15px; // 上边距10px,左右边距15px
+
+ :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;
+ color: #666666;
+ }
+
+ :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_firekeynotearea/components/EvaluationReport.js b/src/pages/business_firekeynotearea/components/EvaluationReport.js
new file mode 100644
index 0000000..1d61812
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EvaluationReport.js
@@ -0,0 +1,922 @@
+import React, { useEffect, useRef, useState } from 'react';
+import { Card, Result, Select, Button, Segmented, Progress, Input } from 'antd';
+import { CheckCircleOutlined, ExportOutlined, HeartFilled, LineHeightOutlined, ExclamationCircleOutlined, SearchOutlined } from '@ant-design/icons';
+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';
+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';
+import eqicon1 from '@/assets/business_basic/eqicon1.png';
+import eqicon2 from '@/assets/business_basic/eqicon2.png';
+import eqicon3 from '@/assets/business_basic/eqicon3.png';
+import eqicon4 from '@/assets/business_basic/eqicon4.png';
+
+const EvaluationReport = () => {
+ const chartRef = useRef(null);
+ const pieChartRef = useRef(null);
+ const faultPieChartRef = 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: 8,
+ total: 0,
+ });
+ const [searchText, setSearchText] = useState('');
+
+ // 柱状图初始化
+ useEffect(() => {
+ if (pieChartRef.current) {
+ const barChart = echarts.init(pieChartRef.current);
+
+ const barOption = {
+ grid: {
+ left: '5%',
+ right: '5%',
+ bottom: '10%',
+ top: '20%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ data: ['灭火器', '消火栓', '报警器', '疏散灯', '排烟设备'],
+ axisLabel: {
+ fontSize: 12,
+ color: '#333',
+ interval: 0,
+ rotate: 0
+ },
+ axisLine: {
+ show: false
+ },
+ axisTick: {
+ show: false
+ }
+ },
+ yAxis: {
+ type: 'value',
+ min: 0,
+ max: 50,
+ interval: 10,
+ axisLabel: {
+ fontSize: 12,
+ color: '#666',
+ formatter: '{value}'
+ },
+ axisLine: {
+ show: false
+ },
+ axisTick: {
+ show: false
+ },
+ splitLine: {
+ lineStyle: {
+ color: '#00001A26',
+ type: 'dashed'
+ }
+ }
+ },
+ series: [{
+ name: '使用次数',
+ type: 'bar',
+ barWidth: 27,
+ data: [35, 28, 42, 31, 38],
+ itemStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: '#199BFB' },
+ { offset: 1, color: '#1373FA' }
+ ]
+ }
+ },
+ emphasis: {
+ itemStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: '#0D7AE8' },
+ { offset: 1, color: '#0F5BC7' }
+ ]
+ }
+ }
+ }
+ }],
+ legend: {
+ show: true,
+ top: '5%',
+ left: 'center',
+ itemWidth: 15,
+ itemHeight: 3,
+ textStyle: {
+ fontSize: 12,
+ color: '#333'
+ },
+ data: [{
+ name: '使用次数',
+ icon: 'rect',
+ itemStyle: {
+ color: '#4B69F1'
+ }
+ }]
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ },
+ formatter: function (params) {
+ return `${params[0].name}
使用次数: ${params[0].value}`;
+ }
+ }
+ };
+
+ barChart.setOption(barOption);
+
+ // 响应式调整
+ const handleBarResize = () => {
+ if (barChart && !barChart.isDisposed()) {
+ barChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handleBarResize);
+
+ return () => {
+ window.removeEventListener('resize', handleBarResize);
+ if (barChart && !barChart.isDisposed()) {
+ barChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ // 维护费用趋势折线图初始化
+ useEffect(() => {
+ if (faultPieChartRef.current) {
+ const faultPieChart = echarts.init(faultPieChartRef.current);
+
+ const faultPieOption = {
+
+ legend: {
+ show: true,
+ top: '5%',
+ left: 'center',
+ itemWidth: 20,
+ itemHeight: 8,
+ textStyle: {
+ color: '#333',
+ fontSize: 12
+ }
+ },
+ grid: {
+ left: '5%',
+ right: '5%',
+ bottom: '10%',
+ top: '20%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
+ axisLine: {
+ lineStyle: {
+ color: '#E5E5E5'
+ }
+ },
+ axisTick: {
+ show: false
+ },
+ axisLabel: {
+ color: '#666',
+ fontSize: 12,
+ interval: 0
+ }
+ },
+ yAxis: {
+ type: 'value',
+ min: 20000,
+ max: 30000,
+ interval: 2000,
+ axisLine: {
+ show: false
+ },
+ axisTick: {
+ show: false
+ },
+ axisLabel: {
+ color: '#666',
+ fontSize: 12,
+ formatter: '¥{value}'
+ },
+ splitLine: {
+ lineStyle: {
+ color: '#00001A26',
+ type: 'dashed'
+ }
+ }
+ },
+ series: [{
+ name: '费用',
+ type: 'line',
+ data: [29000, 21000, 27500, 21900, 26000, 25000, 27000, 24000, 22300, 28000, 29000, 27000],
+ smooth: false,
+ symbol: 'circle',
+ symbolSize: 6,
+ lineStyle: {
+ color: '#1269FF',
+ width: 1
+ },
+ itemStyle: {
+ color: '#FFFFFF',
+ borderColor: '#1269FF',
+ borderWidth: 1
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [{
+ offset: 0,
+ color: 'rgba(18, 105, 255, 0.3)'
+ }, {
+ offset: 1,
+ color: 'rgba(18, 105, 255, 0.05)'
+ }]
+ }
+ }
+ }]
+ };
+
+ faultPieChart.setOption(faultPieOption);
+
+ // 响应式调整
+ const handleFaultPieResize = () => {
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.resize();
+ }
+ };
+
+ window.addEventListener('resize', handleFaultPieResize);
+
+ return () => {
+ window.removeEventListener('resize', handleFaultPieResize);
+ if (faultPieChart && !faultPieChart.isDisposed()) {
+ faultPieChart.dispose();
+ }
+ };
+ }
+ }, []);
+
+ useEffect(() => {
+ if (chartRef.current) {
+ const chart = echarts.init(chartRef.current);
+
+ // 强制初始化时调整大小
+ setTimeout(() => {
+ if (chart && !chart.isDisposed()) {
+ chart.resize();
+ }
+ }, 100);
+
+ const option = {
+ color: ['#3C7EFF', '#FF8800', '#FFC403', '#31BCFF'],
+ legend: {
+ orient: 'vertical',
+ right: '2%',
+ top: 'middle',
+ itemWidth: 14,
+ itemHeight: 5,
+ textStyle: {
+ fontSize: 10,
+ color: '#666'
+ }
+ },
+ tooltip: {
+ trigger: 'item',
+ formatter: '{b}
{d}%'
+ },
+ series: [
+ {
+ name: '设备类型占比',
+ type: 'pie',
+ radius: '70%',
+ center: ['40%', '55%'],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderRadius: 0,
+ borderColor: '#fff',
+ borderWidth: 1
+ },
+ label: {
+ show: false,
+ position: 'center'
+ },
+ emphasis: {
+ label: {
+ show: false
+ }
+ },
+ labelLine: {
+ show: false
+ },
+ data: [
+ { value: 25, name: '灭火器' },
+ { value: 30, name: '消防栓' },
+ { value: 20, name: '报警器' },
+ { value: 25, name: '烟雾探测器' }
+ ]
+ }
+ ]
+ };
+
+ chart.setOption(option);
+
+ // 响应式调整 - 使用多种方式监听容器尺寸变化
+ 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 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);
+ }
+
+ // 使用MutationObserver监听DOM结构变化(菜单展开收起时)
+ const mutationObserver = new MutationObserver((mutations) => {
+ mutations.forEach((mutation) => {
+ if (mutation.type === 'attributes' &&
+ (mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
+ // 延迟执行,确保DOM更新完成
+ setTimeout(() => {
+ handleResize();
+ }, 200);
+ }
+ });
+ });
+
+ // 监听整个页面的class和style变化
+ mutationObserver.observe(document.body, {
+ attributes: true,
+ attributeFilter: ['class', 'style'],
+ subtree: true
+ });
+
+ 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: 'id',
+ key: 'id',
+ width: 60,
+ render: (text, record, index) => {
+ const page = pagination.current || 1;
+ const pageSize = pagination.pageSize || 8;
+ const number = (page - 1) * pageSize + index + 1;
+ return `0${number}`.slice(-2);
+ }
+ },
+ {
+ title: '设备编号',
+ dataIndex: 'deviceId',
+ key: 'deviceId',
+ width: 140,
+ },
+ {
+ title: '设备名称',
+ dataIndex: 'deviceName',
+ key: 'deviceName',
+ width: 110,
+ },
+ {
+ title: '类型',
+ dataIndex: 'modelSpec',
+ key: 'modelSpec',
+ width: 120,
+ },
+ {
+ title: '安装位置',
+ dataIndex: 'installLocation',
+ key: 'installLocation',
+ width: 100,
+ },
+ {
+ title: '状态',
+ dataIndex: 'status',
+ key: 'status',
+ width: 100,
+ render: (text) => {
+ const statusMap = {
+ '报废': { color: '#FF3E48', bg: '#FFE0E2' },
+ '待维修': { color: '#FF8800', bg: '#FFF3E9' },
+ '已使用': { color: '#00AAFA', bg: '#DAF3FF' },
+ '正常': { color: '#44BB5F', bg: '#D8F7DE' }
+ };
+ const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
+ return (
+
+ {text}
+
+ );
+ }
+ },
+ {
+ title: '最后维护时间',
+ dataIndex: 'lastMaintenance',
+ key: 'lastMaintenance',
+ width: 150,
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 140,
+ render: (_, record) => (
+
+
+
+
+ ),
+ },
+ ];
+
+ // 模拟数据
+ const mockData = [
+ {
+ key: '1',
+ id: '001',
+ deviceId: 'HQ-XF-01-001',
+ deviceName: '干粉灭火器',
+ modelSpec: '灭火设备',
+ installLocation: '1层大厅',
+ status: '报废',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '2',
+ id: '002',
+ deviceId: 'HQ-XF-02-015',
+ deviceName: '室内消火栓',
+ modelSpec: '灭火设备',
+ installLocation: '3层东区',
+ status: '已使用',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '3',
+ id: '003',
+ deviceId: 'HQ-XF-03-007',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '正常',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '4',
+ id: '004',
+ deviceId: 'HQ-XF-03-008',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '待维修',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '5',
+ id: '005',
+ deviceId: 'HQ-XF-01-009',
+ deviceName: '干粉灭火器',
+ modelSpec: '灭火设备',
+ installLocation: '地下一层',
+ status: '报废',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '6',
+ id: '006',
+ deviceId: 'HQ-XF-01-010',
+ deviceName: '室内消火栓',
+ modelSpec: '灭火设备',
+ installLocation: '地下一层',
+ status: '已使用',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '7',
+ id: '007',
+ deviceId: 'HQ-XF-01-011',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '待维修',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '8',
+ id: '008',
+ deviceId: 'HQ-XF-01-012',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '正常',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '9',
+ id: '009',
+ deviceId: 'HQ-XF-01-013',
+ deviceName: '干粉灭火器',
+ modelSpec: '灭火设备',
+ installLocation: '地下一层',
+ status: '已使用',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '10',
+ id: '010',
+ deviceId: 'HQ-XF-01-014',
+ deviceName: '室内消火栓',
+ modelSpec: '灭火设备',
+ installLocation: '地下一层',
+ status: '待维修',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '11',
+ id: '011',
+ deviceId: 'HQ-XF-01-015',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '正常',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '12',
+ id: '012',
+ deviceId: 'HQ-XF-01-016',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下一层',
+ status: '已使用',
+ lastMaintenance: '2025-09-10',
+ },
+ {
+ key: '13',
+ id: '013',
+ deviceId: 'HQ-XF-01-017',
+ deviceName: '干粉灭火器',
+ modelSpec: '灭火设备',
+ installLocation: '2层西区',
+ status: '报废',
+ lastMaintenance: '2024-08-15',
+ },
+ {
+ key: '14',
+ id: '014',
+ deviceId: 'HQ-XF-02-018',
+ deviceName: '室内消火栓',
+ modelSpec: '灭火设备',
+ installLocation: '4层南区',
+ status: '报废',
+ lastMaintenance: '2024-07-20',
+ },
+ {
+ key: '15',
+ id: '015',
+ deviceId: 'HQ-XF-03-019',
+ deviceName: '火警报警器',
+ modelSpec: '报警设备',
+ installLocation: '地下二层',
+ status: '报废',
+ lastMaintenance: '2024-06-10',
+ },
+ {
+ key: '16',
+ id: '016',
+ deviceId: 'HQ-XF-01-020',
+ deviceName: '干粉灭火器',
+ modelSpec: '灭火设备',
+ installLocation: '5层北区',
+ status: '报废',
+ lastMaintenance: '2024-05-05',
+ },
+ ];
+
+ // 初始化数据
+ 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 handleAddDevice = () => {
+ console.log('新增设备');
+ // TODO: 实现新增设备逻辑
+ };
+
+ // 导出数据按钮点击事件
+ const handleExportData = () => {
+ console.log('导出数据');
+ // TODO: 实现导出数据逻辑
+ };
+
+ // 分页变化处理
+ const handleTableChange = (pagination) => {
+ setPagination(prev => ({
+ ...prev,
+ current: pagination.current,
+ pageSize: pagination.pageSize,
+ }));
+ };
+
+ // 搜索处理
+ const handleSearchChange = (e) => {
+ setSearchText(e.target.value);
+ console.log('搜索:', e.target.value);
+ // TODO: 实现搜索逻辑,根据设备名称、编号等筛选数据
+ };
+
+ return (
+
+ {/* 第1个div - 高度39% */}
+
+
+
+
+
+
+
+ {/* 维护费用趋势折线图 */}
+
+
+
+
+
+
+
+
+ {/* 第2个div - 占满剩余位置 */}
+
+
+
+
+
+
+
+
+
+
SH-MHQ-023-C 干粉灭火器
+
位置: 4楼办公区丨维护类型: 季度检查
+
负责人: 张三
+
+
+
+
+
+
SH-XHS-045-D 室内消火栓
+
位置: 2楼东侧走廊丨维护类型: 水压测试
+
负责人: 李四
+
+
+
+
+
+
+
+
+ {/* 进度条区域 */}
+
+
+
月度维护计划
+
+
+
季度维护计划
+
+
+
+
年度维护计划
+
+
+
+ {/* 警告提示框 */}
+
+
+ 本月有5项维护任务即将到期
+
+
+
+
+
+
+
+
+
+ {/* 表格 */}
+
+
+
+ {/* 操作按钮 */}
+
+
+ }
+ />
+
+
+
+
+
+
+
+ {/* 表格 */}
+
+
+ `共 ${total} 条`,
+ }}
+ />
+
+
+
+
+
+ );
+};
+
+export default EvaluationReport;
diff --git a/src/pages/business_firekeynotearea/components/EvaluationReport.less b/src/pages/business_firekeynotearea/components/EvaluationReport.less
new file mode 100644
index 0000000..e62182a
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/EvaluationReport.less
@@ -0,0 +1,558 @@
+.Econtainer {
+ padding: 8px 6px 0px 6px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ // 第二个div - 高度35%
+ .EcontainerMiddle {
+ // height: 400px;
+ min-height: 35%;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+ .middleBlock1 {
+ width: 30%;
+ height: 100%;
+ background: #fff;
+ border: 2px solid #fff;
+ 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;
+ margin-top: 5px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 14px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ right: 10px;
+ z-index: 10;
+ min-height: 100%;
+ }
+ }
+
+ .middleBlock12 {
+ flex: 1;
+ height: 100%;
+ background-color: #fff;
+ display: flex;
+ flex-direction: column;
+ font-family: PingFang SC;
+ font-size: 14px;
+ color: #333333;
+ padding: 5px 10px 5px 10px;
+ position: relative;
+
+ .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;
+ margin-top: 5px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 14px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ right: 10px;
+ // bottom: 10px;
+ z-index: 10;
+ }
+ }
+
+ .middleBlock12 {
+ width: 45%;
+ height: 100%;
+ background-color: #fff;
+ display: flex;
+ flex-direction: column;
+ font-family: PingFang SC;
+ font-size: 14px;
+ color: #333333;
+ padding: 5px 10px 5px 10px;
+ position: relative;
+
+ .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;
+ }
+ }
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ right: 10px;
+ // bottom: 10px;
+ min-height: 100%;
+ z-index: 10;
+ }
+ }
+
+ .middleBlock2 {
+ // flex: 1;
+ width: calc(100% - 75% - 15px);
+ 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-top: 5px;
+
+ .titleLeft {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 14px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ }
+
+ .middleBlock2Chart {
+ width: 100%;
+ height: 100%;
+ }
+ }
+ }
+ }
+
+ // 第三个div - 占满剩余位置
+ .EcontainerBottom {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+
+ .sectionContent {
+ display: flex;
+ flex-direction: row;
+ flex: 1;
+ gap: 10px;
+ padding: 0;
+
+ .leftBlock {
+ width: 30%;
+ flex-shrink: 0;
+ height: 100%;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ .leftBlockTitle {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+ margin-bottom: 10px;
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ .maintenanceStack {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ .maintenanceSection {
+ width: 100%;
+ height: 50%;
+ background: #FFF;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+ padding: 12px 14px;
+
+ .maintenanceTitle {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+ margin-bottom: 8px;
+ }
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+
+ .maintenanceContent {
+ flex: 1;
+ width: 100%;
+ }
+
+ .maintenanceContent1 {
+ flex: 1;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ margin-top: 8px;
+ .maintenanceItem {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background-color: #F1F7FF;
+ border-radius: 4px;
+ padding: 16px 16px;
+
+ .maintenanceLeft {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+
+ .maintenanceText1 {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333333;
+ font-family: PingFang SC;
+ }
+
+ .maintenanceText2 {
+ font-size: 12px;
+ color: #666666;
+ font-family: PingFang SC;
+ }
+
+ .maintenanceText3 {
+ font-size: 12px;
+ color: #666666;
+ font-family: PingFang SC;
+ }
+ }
+
+ .maintenanceRight {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .maintenanceStatus {
+ font-size: 12px;
+ color: #FF3E48;
+ font-weight: 500;
+ font-family: PingFang SC;
+ background-color: #FFE0E2;
+ padding: 4px 8px;
+ border-radius: 4px;
+ // border: 1px solid #FFE0E2;
+ }
+ }
+
+ .maintenanceRight2 {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .maintenanceStatus {
+ font-size: 12px;
+ color: #FF8800;
+ font-weight: 500;
+ font-family: PingFang SC;
+ background-color: #FFF3E9;
+ padding: 4px 8px;
+ border-radius: 4px;
+ // padding-right: 2px;
+ }
+ }
+ }
+ }
+
+ .maintenanceContent2 {
+ flex: 1;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+ padding: 8px 0;
+
+ .warningBox {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ background-color: #FFF3CD;
+ border: 1px solid #F4E3AE;
+ border-radius: 4px;
+ padding: 8px 12px;
+ // margin-bottom: 8px;
+ // margin-top: 10px;
+
+ .warningIcon {
+ color: #8C6C0B;
+ font-size: 14px;
+ }
+
+ .warningText {
+ color: #8C6C0B;
+ font-size: 12px;
+ font-family: PingFang SC;
+ font-weight: 400;
+ }
+ }
+
+ .progressSection {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ // gap: 12px;
+ padding: 0px 12px 12px 12px;
+
+
+ .progressLabel {
+ font-size: 12px;
+ color: #666666;
+ font-family: PingFang SC;
+ font-weight: 400;
+
+ }
+
+ // 自定义进度条样式
+ :global(.ant-progress) {
+ .ant-progress-bg {
+ background: linear-gradient(90deg, #2E4CD4 0%, #4B69F1 100%);
+ }
+
+ .ant-progress-text {
+ color: #2E4CD4;
+ font-weight: 500;
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ .rightBlock {
+ width: calc(100% - 28% - 10px);
+ height: 100%;
+ background-color: #fff;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+
+ .tableHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 11px 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;
+ }
+ }
+ }
+
+ .tableActions {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 8px;
+ margin-top: 5px;
+ padding: 0px 15px;
+
+ .leftActions {
+ display: flex;
+ align-items: center;
+ }
+
+ .rightActions {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ }
+
+ .actionButton {
+ 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: 0px 8px;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background-color: #f0f2ff;
+ border-color: #2E4CD4;
+ }
+
+ &:active {
+ background-color: #e6ebff;
+ }
+
+ .buttonIcon {
+ font-size: 14px;
+ font-weight: bold;
+ }
+ }
+ }
+
+ .tableContainer {
+ flex: 1;
+ overflow: hidden;
+ margin: 10px 15px 0 15px; // 上边距10px,左右边距15px
+
+ :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;
+ color: #666666;
+ }
+
+ :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_firekeynotearea/components/KeypartsBasicInformation.js b/src/pages/business_firekeynotearea/components/KeypartsBasicInformation.js
new file mode 100644
index 0000000..07779ce
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/KeypartsBasicInformation.js
@@ -0,0 +1,429 @@
+
+import React, { useEffect, useRef, useState } from 'react';
+import { Button, Input, Select, Tree } from 'antd';
+import { ExportOutlined, PlusOutlined } from '@ant-design/icons';
+import StandardTable from '@/components/StandardTable';
+import styles from './KeypartsBasicInformation.less';
+import eqicon1 from '@/assets/business_firekeynotearea/eqicon1.png';
+import eqicon2 from '@/assets/business_firekeynotearea/eqicon2.png';
+import eqicon3 from '@/assets/business_firekeynotearea/eqicon3.png';
+import eqicon4 from '@/assets/business_firekeynotearea/eqicon4.png';
+import eqicon5 from '@/assets/business_firekeynotearea/eqicon5.png';
+
+const KeypartsBasicInformation = () => {
+ 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 columns = [
+ {
+ title: '编号',
+ dataIndex: 'id',
+ key: 'id',
+ width: 60,
+ fixed: 'left',
+ 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: 'name',
+ key: 'name',
+ width: 120,
+ },
+ {
+ title: '所属建筑',
+ dataIndex: 'building',
+ key: 'building',
+ width: 120,
+ },
+ {
+ title: '类型',
+ dataIndex: 'type',
+ key: 'type',
+ width: 100,
+ },
+ {
+ title: '标签',
+ dataIndex: 'tags',
+ key: 'tags',
+ width: 200,
+ render: (tags) => (
+ <>
+ {tags.map((tag, idx) => {
+ const tagColorMap = {
+ '电气风险': { color: '#F9EBBC', fontColor: '#333333' },
+ '重要设备': { color: '#CDDFFF', fontColor: '#333333' },
+ '易燃易爆': { color: '#F8C6C6', fontColor: '#333333' },
+ '人员密集': { color: '#B6E1F6', fontColor: '#333333' },
+ '关键设施': { color: '#FDDBB5', fontColor: '#333333' },
+ '高风险区': { color: '#F8C6C6', fontColor: '#333333' },
+ };
+ const style = tagColorMap[tag] || { color: '#eee', fontColor: '#666' };
+ return (
+ {tag}
+ );
+ })}
+ >
+ )
+ },
+ {
+ title: '状态',
+ dataIndex: 'status',
+ key: 'status',
+ width: 80,
+ render: (text) => {
+ const statusMap = {
+ '故障': { color: '#FF3E48', bg: '#FFE0E2' },
+ '预警': { color: '#FF8800', bg: '#FFF3E9' },
+ '正常': { color: '#44BB5F', bg: '#D8F7DE' }
+ };
+ const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
+ return (
+
+ {text}
+
+ );
+ }
+ },
+ {
+ title: '最后更新',
+ dataIndex: 'lastUpdate',
+ key: 'lastUpdate',
+ width: 120,
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 100,
+ align: 'center',
+ fixed: 'right',
+ render: (_, record) => (
+ <>
+
+
+ >
+ ),
+ },
+ ];
+
+ // 模拟数据
+ const mockData = [
+ {
+ key: '1',
+ id: '001',
+ name: '1号办公楼',
+ building: '1号办公楼',
+ type: '配电室',
+ tags: ['电气风险', '重要设备'],
+ status: '故障',
+ lastUpdate: '2025-09-10',
+ },
+ {
+ key: '2',
+ id: '002',
+ name: 'B区厨房',
+ building: '员工餐厅',
+ type: '厨房',
+ tags: ['易燃易爆', '人员密集'],
+ status: '预警',
+ lastUpdate: '2025-09-10',
+ },
+ {
+ key: '3',
+ id: '003',
+ name: '数据中心机房',
+ building: '信息中心',
+ type: '数据机房',
+ tags: ['关键设施', '重要设备'],
+ status: '正常',
+ lastUpdate: '2025-09-10',
+ },
+ {
+ key: '4',
+ id: '004',
+ name: '化学品仓库',
+ building: '实验楼',
+ type: '仓库',
+ tags: ['易燃易爆', '高风险区'],
+ status: '正常',
+ lastUpdate: '2025-09-10',
+ },
+ ];
+
+ // 初始化数据
+ 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 handleAddDevice = () => {
+ console.log('新增设备');
+ // TODO: 实现新增设备逻辑
+ };
+
+ // 导出数据按钮点击事件
+ const handleExportData = () => {
+ console.log('导出数据');
+ // TODO: 实现导出数据逻辑
+ };
+
+ // 分页变化处理
+ const handleTableChange = (pagination) => {
+ setPagination(prev => ({
+ ...prev,
+ current: pagination.current,
+ pageSize: pagination.pageSize,
+ }));
+ };
+
+ return (
+
+ {/* 第一个div - 高度20% */}
+
+
+
+ {/* 块1 */}
+
+
+
+

+
+
+
+ {/* 块2 */}
+
+
+
+

+
+
+
+ {/* 块3 */}
+
+
+
+

+
+
+
+ {/* 块4 */}
+
+
+
+

+
+
+
+ {/* 块5 */}
+
+
+
+

+
+
+
+
+
+
+
+ {/* 第二个div - 占满剩余位置 */}
+
+
+
+
+ {/* 表格头部 */}
+
+
+ {/* 搜索与操作栏 */}
+
+
+ {/* 搜索输入框 */}
+
+
+
+ {/* 下拉选择 */}
+
+ {/* 新增按钮 */}
+
+
+
+
+ {/* 表格内容 */}
+
+
+ `共 ${total} 条`,
+ }}
+ scroll={{ x: "max-content" }}
+ />
+
+
+
+
+ {/* 第一行块 - 蓝色方块加标题 */}
+
+ {/* 树形结构 */}
+
+
+ ,
+ children: [
+ {
+ title: 危险化学品储存区,
+ key: '0-0-0',
+ icon: ,
+ },
+ {
+ title: 危险化学品储存区,
+ key: '0-0-1',
+ icon: ,
+ },
+ {
+ title: 危险化学品储存区,
+ key: '0-0-2',
+ icon: ,
+ },
+ ],
+ },
+ {
+ title: '人员密集区域',
+ key: '0-1',
+ icon: ,
+ children: [],
+ },
+ {
+ title: '重要设备房',
+ key: '0-2',
+ icon: ,
+ children: [],
+ },
+ {
+ title: '物资储存区',
+ key: '0-3',
+ icon: ,
+ children: [],
+ },
+ ]}
+ />
+
+
+
+
+
+ );
+};
+
+export default KeypartsBasicInformation;
\ No newline at end of file
diff --git a/src/pages/business_firekeynotearea/components/KeypartsBasicInformation.less b/src/pages/business_firekeynotearea/components/KeypartsBasicInformation.less
new file mode 100644
index 0000000..76d5e91
--- /dev/null
+++ b/src/pages/business_firekeynotearea/components/KeypartsBasicInformation.less
@@ -0,0 +1,659 @@
+/* 树形结构区域样式 */
+.treeWrap {
+ background: #fff;
+ border-radius: 6px;
+ padding: 0 0 0 0;
+}
+
+.treeSearchInput {
+ width: 100%;
+ height: 36px;
+ // border-radius: 6px;
+ // border: 1px solid #E3E6EB;
+ // font-size: 14px;
+ // margin-bottom: 10px;
+ // background: #F7F8FA;
+}
+
+.customTree {
+ background: #fff;
+ border: none;
+
+ .ant-tree-switcher {
+ margin-right: 4px;
+ }
+
+ .ant-tree-node-content-wrapper {
+ font-size: 14px;
+ min-height: 32px;
+ padding: 2px 0 2px 0;
+ }
+
+ .ant-tree-treenode-selected {
+ background: #F0F5FF !important;
+ border-radius: 6px;
+ }
+}
+
+.folderIcon {
+ display: inline-block;
+ width: 18px;
+ height: 18px;
+ background: url('@/assets/business_firekeynotearea/tree-parent-node.svg') no-repeat center center;
+ background-size: contain;
+ margin-right: 6px;
+ vertical-align: text-bottom;
+}
+
+.childIconSelected {
+ display: inline-block;
+ width: 18px;
+ height: 18px;
+ background: url('@/assets/business_firekeynotearea/tree-child-node-selected.svg') no-repeat center center;
+ background-size: contain;
+ margin-right: 6px;
+ vertical-align: text-bottom;
+}
+
+.childIcon {
+ display: inline-block;
+ width: 18px;
+ height: 18px;
+ background: url('@/assets/business_firekeynotearea/tree-child-node.svg') no-repeat center center;
+ background-size: contain;
+ margin-right: 6px;
+ vertical-align: text-bottom;
+}
+
+/* 搜索与操作栏样式 */
+.searchWrap {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin: 10px 15px 0 15px;
+ height: 40px;
+}
+
+.searchInput {
+ // flex: 1;
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // padding: 0 16px;
+ // font-size: 14px;
+ // color: #333;
+ // background: #fff;
+ // outline: none;
+ // box-shadow: none;
+ // transition: border-color 0.2s;
+}
+
+.searchInput:focus {
+ border-color: #2E4CD4;
+}
+
+.selectAll {
+ // height: 40px;
+ // border: 1px solid #E3E6EB;
+ // border-radius: 6px;
+ // background: #fff;
+ // font-size: 14px;
+ // color: #333;
+ // padding: 0 32px 0 16px;
+ // margin-left: 12px;
+}
+
+.selectAll:focus {
+ border-color: #2E4CD4;
+}
+
+.addBtn {
+ background: #2E4CD4;
+ margin-left: 15px;
+}
+
+.addBtn:hover {
+ background: #1d3bb3;
+}
+
+.Rcontainer {
+ padding: 8px 0px 0px 6px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+
+ // 第一个div - 高度20%
+ .RcontainerTop {
+ height: 16%;
+ // background-color: #fff;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ // padding: 15px;
+
+ .blocksContainer {
+ flex: 1;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+ .blockItem {
+ flex: 1;
+ height: 100%;
+ display: flex;
+ background: linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ border-radius: 2px;
+ // border: 2px solid #FFFFFF;
+
+ &.bgBlock1 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock2 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock3 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock4 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ &.bgBlock5 {
+ background: url('@/assets/business_firekeynotearea/keyparts_bg.png') no-repeat center center, linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
+ background-size: cover;
+ }
+
+ .blockLeft {
+ width: 60%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 15px;
+ padding-left: 20px;
+ gap: 15px;
+
+ .blockTitle {
+ font-family: PingFang SC;
+ font-weight: 400;
+ font-size: 12px;
+ color: #333333;
+ 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;
+
+ .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 {
+ // width: 80%;
+ height: 65%;
+ // height: 80%;
+ object-fit: contain;
+ margin-right: -5px;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 第二个div - 高度39%
+ .RcontainerMiddle {
+ height: 33%;
+ border-radius: 4px;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ height: 100%;
+ display: flex;
+ display: flex;
+ gap: 10px;
+ height: 100%;
+
+
+
+ .middleBlock1 {
+ // flex: 1;
+ width: 28%;
+ height: 100%;
+ background: #fff;
+
+ 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;
+ }
+ }
+
+ .block1Segmented {
+ padding: 0;
+ margin: 0;
+ border: 1px solid #E3E3E3;
+ border-radius: 4px;
+ height: 28px;
+
+ :global(.ant-segmented) {
+ padding: 0;
+ margin: 0;
+ height: 28px;
+ }
+
+ :global(.ant-segmented-item) {
+ font-size: 12px;
+ padding: 2px 8px;
+ height: 26px;
+ line-height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ :global(.ant-segmented-item-selected) {
+ background-color: #1890ff;
+ color: #fff;
+ }
+ }
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 35px;
+ left: 10px;
+ right: 10px;
+ bottom: 10px;
+ z-index: 10;
+ }
+
+ // .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;
+ // }
+ // }
+ }
+
+ .middleBlock12 {
+ flex: 1;
+ height: 100%;
+ background-color: #fff;
+ display: flex;
+ flex-direction: column;
+ font-family: PingFang SC;
+ font-size: 14px;
+ color: #333333;
+ padding: 5px 10px 5px 10px;
+ position: relative;
+
+ .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;
+ }
+ }
+
+ .block1Segmented {
+ padding: 0;
+ margin: 0;
+ border: 1px solid #E3E3E3;
+ border-radius: 4px;
+ height: 28px;
+
+ :global(.ant-segmented) {
+ padding: 0;
+ margin: 0;
+ height: 28px;
+ }
+
+ :global(.ant-segmented-item) {
+ font-size: 12px;
+ padding: 2px 8px;
+ height: 26px;
+ line-height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ :global(.ant-segmented-item-selected) {
+ background-color: #1890ff;
+ color: #fff;
+ }
+ }
+
+ .customSelect {
+ :global(.ant-select-single:not(.ant-select-customize-input) .ant-select-selector) {
+ height: 26px !important;
+ display: flex !important;
+ align-items: center !important;
+ }
+
+ :global(.ant-select-selection-item) {
+ line-height: 24px !important;
+ // height: 24px !important;
+ display: flex !important;
+ align-items: center !important;
+ }
+ }
+ }
+
+ .deviceStatusChart {
+ position: absolute;
+ top: 35px;
+ left: 10px;
+ right: 10px;
+ bottom: 10px;
+ z-index: 10;
+ }
+ }
+
+ .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;
+ }
+ }
+
+ }
+ }
+
+ // 第三个div - 占满剩余空间
+ .RcontainerBottom {
+ flex: 1 1 0;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+
+ .sectionContent {
+ flex: 1 1 0;
+ min-height: 0;
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ padding: 0;
+
+ .leftBlock {
+ width: calc(100% - 28% - 10px);
+ height: 100%;
+ background-color: #fff;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 0;
+ min-width: 0;
+
+ .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;
+ }
+ }
+
+ .tableActions {
+ display: flex;
+ gap: 8px;
+ margin-top: 5px;
+
+ .actionButton {
+ 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: 0px 8px;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background-color: #f0f2ff;
+ border-color: #2E4CD4;
+ }
+
+ &:active {
+ background-color: #e6ebff;
+ }
+
+ .buttonIcon {
+ font-size: 14px;
+ font-weight: bold;
+ }
+ }
+ }
+ }
+
+ .tableContainer {
+ flex: 1;
+ overflow: hidden;
+ margin: 10px 15px 0 15px; // 上边距10px,左右边距15px
+
+ :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;
+ color: #666666;
+ }
+
+ :global(.ant-table-tbody > tr:hover > td) {
+ background-color: #f5f5f5;
+ }
+
+ :global(.ant-pagination) {
+ margin-top: 16px;
+ text-align: right;
+ }
+ }
+ }
+
+ .rightBlock {
+ width: 28%;
+ flex-shrink: 0;
+ height: 100%;
+ background: #fff;
+ padding: 0 15px 0 15px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ min-width: 260px;
+
+ .leftBlockTitle {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+ margin-bottom: 10px;
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/nav_system_content/SystemContentList.js b/src/pages/nav_system_content/SystemContentList.js
index 93c3a23..d77fab6 100644
--- a/src/pages/nav_system_content/SystemContentList.js
+++ b/src/pages/nav_system_content/SystemContentList.js
@@ -12,6 +12,7 @@ import menuTitle from '@/assets/img/智能管控平台.svg'
import menuTitle1 from '@/assets/img/智能管控平台-1.svg'
import fireHydrant from '@/assets/img/fireHydrant.svg'
import fireHydrant1 from '@/assets/img/fireHydrant1.svg'
+import fireKeynoteArea from '@/assets/img/fire_keynote_area.svg'
import trouble from '@/assets/img/trouble.svg'
import book from '@/assets/img/book.svg'
import danger from '@/assets/img/danger.svg'
@@ -104,6 +105,19 @@ const SystemContentList = (props) => {
key: "/topnavbar00/business/basic",
"label": "基础信息管理"
},
+ {
+ path: '/topnavbar00/business/firekeynotearea',
+ icon:
,
+ key: "/topnavbar00/business/firekeynotearea",
+ "label": "消防重点部位管理"
+ },
{
"path": "/topnavbar00/business/basicinformation",
icon:
,
diff --git a/src/pages/topnavbar/TopNavBar.js b/src/pages/topnavbar/TopNavBar.js
index 0579cf3..03c9867 100644
--- a/src/pages/topnavbar/TopNavBar.js
+++ b/src/pages/topnavbar/TopNavBar.js
@@ -12,6 +12,10 @@ const menuItem = [
label: '基础信息管理',
key: '/topnavbar00/business/basic',
},
+ {
+ label: '消防重点部位管理',
+ key: '/topnavbar00/business/firekeynotearea',
+ },
{
label: '安全管理基础信息',
key: '/topnavbar00/business/basicinformation',