You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

555 lines
19 KiB
JavaScript

import React, { useState, useEffect, useRef } from 'react';
import { Button, Segmented, Tag } from 'antd';
1 month ago
import {
ExclamationCircleOutlined,
FolderOutlined,
FileTextOutlined,
PlusOutlined,
EditOutlined,
EyeOutlined
} from '@ant-design/icons';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
1 month ago
import styles from './EventWarningManagement.less';
1 month ago
// import bgMan1 from '@/assets/business_Emergency/bgMan1.svg';
import bgMan2 from '@/assets/business_Emergency/bgMan2.svg';
import bgMan3 from '@/assets/business_Emergency/bgMan3.svg';
import bgMan4 from '@/assets/business_Emergency/bgMan4.svg';
import bgMan5 from '@/assets/business_Emergency/bgMan5.svg';
1 month ago
const EventWarningManagement = () => {
const [timeType, setTimeType] = useState('month');
const lineChartRef = useRef(null);
const lineChartInstanceRef = useRef(null);
const donutChartRef = useRef(null);
const donutChartInstanceRef = useRef(null);
const [tableData, setTableData] = useState({
list: [
{
key: '1',
alertId: '#ALRT-20230512-001',
alertType: '气象预警',
alertLevel: '高级',
sourceChannel: '气象监测数据',
affectedArea: '东城区、西城区',
alertLevelColor: '红色预警',
alertTime: '2025-10-20 01:32:25',
status: '处理中',
statusType: 'processing'
},
{
key: '2',
alertId: '#ALRT-20230512-002',
alertType: '火灾隐患',
alertLevel: '中级',
sourceChannel: '安全监测设备',
affectedArea: '南山区工业园区',
alertLevelColor: '橙色预警',
alertTime: '2025-10-18 21:15:07',
status: '处理中',
statusType: 'processing'
},
{
key: '3',
alertId: '#ALRT-20230512-003',
alertType: '疫情传播',
alertLevel: '中级',
sourceChannel: '社会舆情信息',
affectedArea: '全市范围',
alertLevelColor: '蓝色预警',
alertTime: '2025-10-15 12:24:25',
status: '待处理',
statusType: 'pending'
},
{
key: '4',
alertId: '#ALRT-20230512-004',
alertType: '化工泄漏',
alertLevel: '低级',
sourceChannel: '安全监测设备',
affectedArea: '化工园区A区',
alertLevelColor: '蓝色预警',
alertTime: '2025-10-17 06:49:59',
status: '已处理',
statusType: 'processed'
}
],
pagination: {
current: 3,
currentPage: 3,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => `${total}`
}
});
// 折线图配置
useEffect(() => {
if (!lineChartRef.current) return;
if (!lineChartInstanceRef.current) {
lineChartInstanceRef.current = echarts.init(lineChartRef.current);
}
const option = {
grid: {
left: '3%',
right: '4%',
1 month ago
top: '15%',
bottom: '3%',
containLabel: true
},
legend: {
1 month ago
data: ['气象灾害', '安全事故', '公共卫生'],
top: '0%',
left: 'center',
itemGap: 30,
1 month ago
itemWidth: 18, // 图例图标宽度
itemHeight: 8, // 图例图标高度
textStyle: {
color: '#666666',
fontSize: 12
}
},
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisLabel: {
color: '#666666',
fontSize: 12
},
axisLine: {
lineStyle: {
color: '#E5E5E5'
}
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
color: '#E5E5E5',
type: 'dashed'
}
}
},
yAxis: {
type: 'value',
min: 0,
max: 12,
interval: 2,
axisLabel: {
color: '#666666',
fontSize: 12
},
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
lineStyle: {
color: '#E5E5E5',
type: 'dashed'
}
}
},
series: [
{
name: '气象灾害',
type: 'line',
smooth: true,
data: [4, 5, 6, 7, 10, 8, 6, 7, 8, 9, 10, 12],
itemStyle: {
color: '#ffffff',
borderColor: '#8979FF',
1 month ago
borderWidth: 1
},
lineStyle: {
color: '#8979FF',
1 month ago
width: 1
},
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: 8,
symbolKeepAspect: true,
emphasis: {
itemStyle: {
1 month ago
color: '#fff',
borderColor: '#8979FF',
1 month ago
borderWidth: 1
}
}
},
{
name: '安全事故',
type: 'line',
smooth: true,
data: [2, 3, 5, 4, 3, 4, 5, 4, 3, 6, 5, 7],
itemStyle: {
color: '#ffffff',
borderColor: '#FF928A',
1 month ago
borderWidth: 1
},
lineStyle: {
color: '#FF928A',
1 month ago
width: 1
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(255, 146, 138, 0.3)' },
{ offset: 1, color: 'rgba(255, 146, 138, 0.05)' }
]
}
},
symbol: 'circle',
symbolSize: 8,
symbolKeepAspect: true,
emphasis: {
itemStyle: {
1 month ago
color: '#fff',
borderColor: '#FF928A',
1 month ago
borderWidth: 1
}
}
},
{
name: '公共卫生',
type: 'line',
smooth: true,
data: [3, 5, 2, 1, 2, 3, 4, 2, 1, 2, 3, 2],
itemStyle: {
color: '#ffffff',
borderColor: '#3CC3DF',
1 month ago
borderWidth: 1
},
lineStyle: {
color: '#3CC3DF',
1 month ago
width: 1
},
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: 8,
symbolKeepAspect: true,
emphasis: {
itemStyle: {
1 month ago
color: '#fff',
borderColor: '#3CC3DF',
1 month ago
borderWidth: 1
}
}
}
]
};
lineChartInstanceRef.current.setOption(option);
const resizeObserver = new ResizeObserver(() => {
lineChartInstanceRef.current?.resize();
});
if (lineChartRef.current) {
resizeObserver.observe(lineChartRef.current);
}
const handleResize = () => {
lineChartInstanceRef.current?.resize();
};
window.addEventListener('resize', handleResize);
return () => {
resizeObserver.disconnect();
window.removeEventListener('resize', handleResize);
};
}, [timeType]);
// 环形图配置
useEffect(() => {
if (!donutChartRef.current) return;
if (!donutChartInstanceRef.current) {
donutChartInstanceRef.current = echarts.init(donutChartRef.current);
}
const option = {
legend: {
orient: 'vertical',
1 month ago
right: 30,
top: 'center',
itemGap: 15,
1 month ago
itemWidth: 14,
itemHeight: 3,
textStyle: {
color: '#666666',
fontSize: 12
},
1 month ago
formatter: function (name) {
return name;
}
},
series: [
{
type: 'pie',
1 month ago
radius: ['45%', '75%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
label: {
show: false
},
labelLine: {
show: false
},
data: [
1 month ago
{ value: 65, name: '气象灾害', itemStyle: { color: '#4B69F1' } },
{ value: 10, name: '社会安全', itemStyle: { color: '#44BB5F' } },
{ value: 20, name: '公共卫生', itemStyle: { color: '#A493FB' } },
1 month ago
{ value: 5, name: '安全事故', itemStyle: { color: '#FFD85A' } }
]
}
]
};
donutChartInstanceRef.current.setOption(option);
const resizeObserver = new ResizeObserver(() => {
donutChartInstanceRef.current?.resize();
});
if (donutChartRef.current) {
resizeObserver.observe(donutChartRef.current);
}
const handleResize = () => {
donutChartInstanceRef.current?.resize();
};
window.addEventListener('resize', handleResize);
return () => {
resizeObserver.disconnect();
window.removeEventListener('resize', handleResize);
};
}, []);
// 组件卸载时销毁图表
useEffect(() => {
return () => {
lineChartInstanceRef.current?.dispose();
donutChartInstanceRef.current?.dispose();
};
}, []);
// 表格列定义
const columns = [
{
title: '预警编号',
dataIndex: 'alertId',
key: 'alertId',
1 month ago
width: 180,
align: 'center'
},
{
title: '预警类型',
dataIndex: 'alertType',
key: 'alertType',
1 month ago
width: 120,
align: 'center'
},
{
title: '来源渠道',
dataIndex: 'sourceChannel',
key: 'sourceChannel',
1 month ago
width: 150,
align: 'center'
},
{
title: '影响区域',
dataIndex: 'affectedArea',
key: 'affectedArea',
1 month ago
width: 180,
align: 'center'
},
{
title: '预警级别',
dataIndex: 'alertLevelColor',
key: 'alertLevelColor',
width: 120,
1 month ago
align: 'center',
render: (text) => {
1 month ago
let color = '#FF3E48';
let backgroundColor = '#FFE0E2';
if (text === '橙色预警') {
color = '#FF8800';
backgroundColor = '#FFF3E9';
} else if (text === '蓝色预警') {
color = '#00AAFA';
backgroundColor = '#DAF3FF';
}
return (
<Tag style={{ color, backgroundColor, border: 'none'}}>
{text}
</Tag>
);
}
},
{
title: '预警时间',
dataIndex: 'alertTime',
key: 'alertTime',
1 month ago
width: 180,
align: 'center'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
1 month ago
align: 'center',
1 month ago
render: (text) => {
let color =""
},
{
title: '操作',
key: 'action',
width: 120,
1 month ago
align: 'center',
render: (_, record) => (
<div className={styles.actionButtons}>
<Button type="link" size="small" icon={<EditOutlined />}>编辑</Button>
<Button type="link" size="small" icon={<EyeOutlined />}>查看</Button>
</div>
)
}
];
1 month ago
return (
<div className={styles.container}>
{/* A块顶部统计区域 */}
<div className={styles.blockA}>
{/* a块左侧70% */}
<div className={styles.blockA_a}>
<div className={styles.sectionHeader}>
<div className={styles.titleBar}></div>
<div className={styles.titleText}>今日预警统计</div>
</div>
<div className={styles.threeCards}>
1 month ago
<img src={bgMan3} alt="" style={{ width: '140px', height: '75px' }} />
<img src={bgMan2} alt="" style={{ width: '140px', height: '75px' }} />
<img src={bgMan3} alt="" style={{ width: '140px', height: '75px' }} />
</div>
</div>
{/* b块右侧30% */}
<div className={styles.blockA_b}>
<div className={styles.imageTextCard}>
<div className={styles.cardIcon}>
1 month ago
<img src={bgMan4} alt="待处理指令" />
</div>
<div className={styles.cardContent}>
<div className={styles.cardNumber}>12</div>
<div className={styles.cardText}>待处理指令</div>
</div>
</div>
<div className={styles.imageTextCard}>
<div className={styles.cardIcon}>
1 month ago
<img src={bgMan5} alt="待审核上报" />
</div>
<div className={styles.cardContent}>
<div className={styles.cardNumber}>10</div>
<div className={styles.cardText}>待审核上报</div>
</div>
</div>
</div>
</div>
{/* B块中间图表区域 */}
<div className={styles.blockB}>
{/* c块左侧70% */}
<div className={styles.blockB_c}>
<div className={styles.chartHeader}>
<div className={styles.sectionHeader}>
<div className={styles.titleBar}></div>
<div className={styles.titleText}>演练数据统计</div>
</div>
<Segmented
options={['年', '月', '周']}
value={timeType}
onChange={setTimeType}
className={styles.timeFilter}
/>
</div>
<div className={styles.chartContent}>
<div ref={lineChartRef} className={styles.lineChart}></div>
</div>
</div>
{/* d块右侧30% */}
<div className={styles.blockB_d}>
<div className={styles.sectionHeader}>
<div className={styles.titleBar}></div>
<div className={styles.titleText}>预警类型分布</div>
</div>
<div className={styles.chartContent}>
<div ref={donutChartRef} className={styles.donutChart}></div>
</div>
</div>
</div>
{/* C块底部表格区域 */}
<div className={styles.blockC}>
<div className={styles.tableHeader}>
<div className={styles.sectionHeader}>
<div className={styles.titleBar}></div>
<div className={styles.titleText}>事件预警信息</div>
</div>
<Button type="primary" icon={<PlusOutlined />} className={styles.addButton}>
添加预警
</Button>
</div>
<div className={styles.tableContent}>
<StandardTable
data={tableData}
columns={columns}
rowKey="key"
/>
</div>
1 month ago
</div>
</div>
);
};
export default EventWarningManagement;