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.
657 lines
24 KiB
JavaScript
657 lines
24 KiB
JavaScript
import React, { useState, useEffect, useRef } from 'react';
|
|
import { Select, Button, Table, Input, Space, Tooltip, message } from 'antd';
|
|
import { SearchOutlined, PlusOutlined, FileTextOutlined, DeleteOutlined, EditOutlined, MoreOutlined, RobotOutlined } from '@ant-design/icons';
|
|
import ReactECharts from 'echarts-for-react';
|
|
import { history } from 'umi';
|
|
import StandardTable from '@/components/StandardTable';
|
|
import styles from './PollutionSourceManagement.less';
|
|
import icon_water from '@/assets/business_envinformation/icon_water.svg';
|
|
import icon_soil from '@/assets/business_envinformation/icon_soil.svg';
|
|
import icon_factory from '@/assets/business_envinformation/icon_atmosphere.svg';
|
|
|
|
|
|
|
|
const { Option } = Select;
|
|
|
|
const PollutionSourceManagement = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [chartReady, setChartReady] = useState(false);
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
const [tableData, setTableData] = useState({
|
|
list: [],
|
|
pagination: {
|
|
current: 1,
|
|
pageSize: 5,
|
|
total: 85
|
|
}
|
|
});
|
|
|
|
// 确保DOM准备好后再渲染图表
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
setChartReady(true);
|
|
}, 100);
|
|
return () => clearTimeout(timer);
|
|
}, []);
|
|
|
|
// 污染物排放统计图表配置 - 闭合环图+进度饼图
|
|
const pollutantEmissionOption = {
|
|
tooltip: {
|
|
show: false
|
|
},
|
|
series: [
|
|
// 外层闭合环图
|
|
{
|
|
name: '外层环',
|
|
type: 'pie',
|
|
radius: ['58%', '80%'],
|
|
center: ['50%', '50%'],
|
|
data: [{ value: 100, name: '外层环' }],
|
|
itemStyle: {
|
|
color: '#F6F1E8',
|
|
shadowBlur: 4,
|
|
shadowColor: '#FFF5F0',
|
|
shadowOffsetY: 4,
|
|
borderRadius: 10,
|
|
borderColor: 'rgba(255, 227, 208, 0.6)', // 外边框颜色
|
|
borderWidth: 2
|
|
},
|
|
label: { show: false },
|
|
labelLine: { show: false },
|
|
silent: true
|
|
},
|
|
// 内层进度饼图
|
|
{
|
|
name: '进度饼图',
|
|
type: 'pie',
|
|
radius: ['61%', '77%'],
|
|
center: ['50%', '50%'],
|
|
data: [
|
|
{
|
|
value: 62,
|
|
name: '超标污染物数量',
|
|
itemStyle: {
|
|
color: {
|
|
type: 'linear',
|
|
x: 0, y: 0, x2: 1, y2: 1,
|
|
colorStops: [
|
|
{ offset: 0, color: '#FFF4B3' },
|
|
{ offset: 0.5, color: '#FF8351' },
|
|
{ offset: 1, color: '#FF7125' }
|
|
]
|
|
},
|
|
borderRadius: 10
|
|
}
|
|
},
|
|
{
|
|
value: 38,
|
|
name: '剩余',
|
|
itemStyle: { color: 'transparent' }
|
|
}
|
|
],
|
|
label: { show: false },
|
|
labelLine: { show: false },
|
|
silent: true
|
|
}
|
|
]
|
|
};
|
|
|
|
// 超标污染物种类统计图表配置 - 闭合环图+进度饼图
|
|
const pollutantTypeOption = {
|
|
tooltip: {
|
|
show: false
|
|
},
|
|
series: [
|
|
// 外层闭合环图
|
|
{
|
|
name: '外层环',
|
|
type: 'pie',
|
|
radius: ['58%', '80%'],
|
|
center: ['50%', '50%'],
|
|
data: [{ value: 100, name: '外层环' }],
|
|
itemStyle: {
|
|
color: '#F2F0FF',
|
|
shadowBlur: 4,
|
|
shadowColor: '#F2F0FF',
|
|
shadowOffsetY: 4,
|
|
borderRadius: 10,
|
|
borderColor: '#E4E1FB', // 外边框颜色
|
|
borderWidth: 2
|
|
},
|
|
label: { show: false },
|
|
labelLine: { show: false },
|
|
silent: true
|
|
},
|
|
// 内层进度饼图
|
|
{
|
|
name: '进度饼图',
|
|
type: 'pie',
|
|
radius: ['61%', '77%'],
|
|
center: ['50%', '50%'],
|
|
data: [
|
|
{
|
|
value: 25,
|
|
name: '超标污染物种类',
|
|
itemStyle: {
|
|
color: {
|
|
type: 'linear',
|
|
x: 0, y: 0, x2: 0, y2: 1,
|
|
colorStops: [
|
|
{ offset: 0, color: '#B3D6FF' },
|
|
{ offset: 0.476, color: '#9E7DFF' },
|
|
{ offset: 1, color: '#2549FF' }
|
|
]
|
|
},
|
|
borderRadius: 10
|
|
}
|
|
},
|
|
{
|
|
value: 75,
|
|
name: '剩余',
|
|
itemStyle: { color: 'transparent' }
|
|
}
|
|
],
|
|
label: { show: false },
|
|
labelLine: { show: false },
|
|
silent: true
|
|
}
|
|
]
|
|
};
|
|
|
|
// 超标排放统计图表配置
|
|
const exceedanceOption = {
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
axisPointer: {
|
|
type: 'shadow'
|
|
},
|
|
formatter: function (params) {
|
|
const data = params[0];
|
|
const exceedanceData = [
|
|
{ name: '污染物1', status: '轻微超标', exceedance: '15%' },
|
|
{ name: '污染物2', status: '严重超标', exceedance: '66%' },
|
|
{ name: '污染物3', status: '轻微超标', exceedance: '8%' },
|
|
{ name: '污染物4', status: '正常', exceedance: '0%' },
|
|
{ name: '污染物5', status: '轻微超标', exceedance: '12%' }
|
|
];
|
|
const item = exceedanceData[data.dataIndex];
|
|
return `
|
|
<div style=" background: #fff; color: #000000; border-radius: 8px;">
|
|
<div style="font-weight: 600; display: inline-block; margin-right: 10px;">${data.name}</div>
|
|
<div style="color: #ff6b6b; display: inline-block; margin-bottom: 5px;">${item.status}</div>
|
|
<div style="color: #000000; margin-bottom: 5px;">超标 ${item.exceedance}</div>
|
|
<div style="color: #000000; font-size: 12px;">大气环境特征污染物</div>
|
|
</div>
|
|
`;
|
|
}
|
|
},
|
|
grid: {
|
|
left: '12%',
|
|
right: '5%',
|
|
top: '5%',
|
|
bottom: '12%'
|
|
},
|
|
xAxis: {
|
|
type: 'value',
|
|
max: 100,
|
|
min: 0,
|
|
interval: 10,
|
|
splitNumber: 10,
|
|
axisLine: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: '#D7D6D6',
|
|
width: 1
|
|
}
|
|
},
|
|
axisTick: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: '#D7D6D6'
|
|
}
|
|
},
|
|
axisLabel: {
|
|
color: '#666',
|
|
formatter: function (value) {
|
|
return value;
|
|
}
|
|
},
|
|
splitLine: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: '#f0f0f0',
|
|
type: 'dashed'
|
|
}
|
|
}
|
|
},
|
|
yAxis: {
|
|
type: 'category',
|
|
data: ['污染物1', '污染物2', '污染物3', '污染物4', '污染物5'],
|
|
axisLine: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: '#D7D6D6'
|
|
}
|
|
},
|
|
axisTick: {
|
|
show: false
|
|
},
|
|
axisLabel: {
|
|
color: '#666',
|
|
fontSize: 12
|
|
}
|
|
},
|
|
series: [{
|
|
type: 'bar',
|
|
data: [45, 66, 32, 28, 38],
|
|
itemStyle: {
|
|
color: {
|
|
type: 'linear',
|
|
x: 0,
|
|
y: 0,
|
|
x2: 1,
|
|
y2: 0,
|
|
colorStops: [{
|
|
offset: 0, color: '#FFEBD9'
|
|
}, {
|
|
offset: 1, color: '#FF0000'
|
|
}]
|
|
},
|
|
// borderRadius: [0, 4, 0, 0]
|
|
},
|
|
barWidth: '60%',
|
|
barCategoryGap: '20px'
|
|
}]
|
|
};
|
|
|
|
// 表格列定义
|
|
const columns = [
|
|
{
|
|
title: '生产工艺设备',
|
|
dataIndex: 'equipment',
|
|
key: 'equipment',
|
|
width: 120,
|
|
},
|
|
{
|
|
title: '原材料产品',
|
|
dataIndex: 'material',
|
|
key: 'material',
|
|
width: 150,
|
|
},
|
|
{
|
|
title: '污染物排放处理设施',
|
|
dataIndex: 'facility',
|
|
key: 'facility',
|
|
width: 180,
|
|
},
|
|
{
|
|
title: '污染物排放种类',
|
|
dataIndex: 'type',
|
|
key: 'type',
|
|
width: 150,
|
|
render: (text) => (
|
|
<Space>
|
|
{text}
|
|
{/* <SearchOutlined style={{ color: '#1890ff', cursor: 'pointer' }} /> */}
|
|
</Space>
|
|
),
|
|
},
|
|
{
|
|
title: '排放数量',
|
|
dataIndex: 'quantity',
|
|
key: 'quantity',
|
|
width: 100,
|
|
},
|
|
{
|
|
title: '数量单位',
|
|
dataIndex: 'unit',
|
|
key: 'unit',
|
|
width: 100,
|
|
},
|
|
{
|
|
title: '排放方式',
|
|
dataIndex: 'method',
|
|
key: 'method',
|
|
width: 100,
|
|
},
|
|
{
|
|
title: '趋向',
|
|
dataIndex: 'trend',
|
|
key: 'trend',
|
|
width: 200,
|
|
ellipsis: true,
|
|
},
|
|
{
|
|
title: '操作',
|
|
key: 'action',
|
|
width: 80,
|
|
render: (_, record) => (
|
|
<Space size="middle">
|
|
<Tooltip title="删除">
|
|
<DeleteOutlined
|
|
style={{ color: '#ff4d4f', cursor: 'pointer' }}
|
|
onClick={() => handleDelete(record)}
|
|
/>
|
|
</Tooltip>
|
|
</Space>
|
|
),
|
|
},
|
|
];
|
|
|
|
// 模拟表格数据
|
|
const mockTableData = [
|
|
{
|
|
key: '1',
|
|
equipment: '比亚迪',
|
|
material: '丁硼乳膏(雅皓)',
|
|
facility: '净水设备234',
|
|
type: '种类1',
|
|
quantity: 47,
|
|
unit: 'm³',
|
|
method: '方式1',
|
|
trend: '近3年下达中央预算内投'
|
|
},
|
|
{
|
|
key: '2',
|
|
equipment: '荣威',
|
|
material: '东方活血膏(明仁)',
|
|
facility: '净水设备234',
|
|
type: '种类1',
|
|
quantity: 34,
|
|
unit: 'm³',
|
|
method: '方式1',
|
|
trend: '近3年下达中央预算内投'
|
|
},
|
|
{
|
|
key: '3',
|
|
equipment: '现代',
|
|
material: '骨友灵搽剂(太极)',
|
|
facility: '净水设备234',
|
|
type: '种类1',
|
|
quantity: 45,
|
|
unit: 'm³',
|
|
method: '方式1',
|
|
trend: '刘某及同伴三人前往该射'
|
|
},
|
|
{
|
|
key: '4',
|
|
equipment: '日产',
|
|
material: '对乙酰氨基酚栓',
|
|
facility: '净水设备234',
|
|
type: '种类1',
|
|
quantity: 55,
|
|
unit: 'm³',
|
|
method: '方式1',
|
|
trend: '一到假期,大量"xx暑假'
|
|
},
|
|
{
|
|
key: '5',
|
|
equipment: '北汽',
|
|
material: '对乙酰氨基酚片(必理通)',
|
|
facility: '净水设备234',
|
|
type: '种类1',
|
|
quantity: 22,
|
|
unit: 'm³',
|
|
method: '方式1',
|
|
trend: '近日,陕西延安培文实验'
|
|
},
|
|
{
|
|
key: '6',
|
|
equipment: '吉利',
|
|
material: '阿莫西林胶囊(联邦)',
|
|
facility: '污水处理设备001',
|
|
type: '种类2',
|
|
quantity: 38,
|
|
unit: 'kg',
|
|
method: '方式2',
|
|
trend: '环保部门加强监管力度,排放标准逐步提高'
|
|
},
|
|
{
|
|
key: '7',
|
|
equipment: '长城',
|
|
material: '布洛芬缓释胶囊(芬必得)',
|
|
facility: '废气处理设备002',
|
|
type: '种类3',
|
|
quantity: 29,
|
|
unit: 't',
|
|
method: '方式3',
|
|
trend: '企业积极响应绿色生产号召,投入环保设施'
|
|
},
|
|
{
|
|
key: '8',
|
|
equipment: '奇瑞',
|
|
material: '复方甘草片(太极)',
|
|
facility: '固废处理设备003',
|
|
type: '种类4',
|
|
quantity: 15,
|
|
unit: 'm³',
|
|
method: '方式4',
|
|
trend: '定期进行环境监测,确保排放达标'
|
|
}
|
|
];
|
|
|
|
useEffect(() => {
|
|
setTableData({
|
|
list: mockTableData,
|
|
pagination: {
|
|
current: 6,
|
|
pageSize: 5,
|
|
total: 85
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
// 处理删除操作
|
|
const handleDelete = (record) => {
|
|
message.success(`删除 ${record.equipment} 成功`);
|
|
};
|
|
|
|
// 处理新增操作
|
|
const handleAdd = () => {
|
|
message.info('新增功能开发中');
|
|
};
|
|
|
|
// 处理生成报表操作
|
|
const handleGenerateReport = () => {
|
|
message.info('生成报表功能开发中');
|
|
};
|
|
|
|
// 处理表格变化
|
|
const handleTableChange = (pagination) => {
|
|
setTableData(prev => ({
|
|
...prev,
|
|
pagination: {
|
|
...prev.pagination,
|
|
current: pagination.current,
|
|
pageSize: pagination.pageSize
|
|
}
|
|
}));
|
|
};
|
|
|
|
// 处理大气环境点击
|
|
const handleAtmosphereCardClick = () => {
|
|
history.push('/topnavbar00/business/atmospherePollutantLibrary');
|
|
};
|
|
|
|
|
|
return (
|
|
<div className={styles.pollutionDashboard}>
|
|
{/* 顶部统计区域 */}
|
|
<div className={styles.statsSection}>
|
|
{/* 污染物排放统计 */}
|
|
<div className={styles.pollutantStatsCard}>
|
|
<div className={styles.cardTitle}>
|
|
<span>污染物排放统计</span>
|
|
<div className={styles.cardHeader}>
|
|
<Select defaultValue="今日" className={styles.timeFilter}>
|
|
<Option value="今日">今日</Option>
|
|
<Option value="本周">本周</Option>
|
|
<Option value="本月">本月</Option>
|
|
</Select>
|
|
<Select defaultValue="所有名录" className={styles.categoryFilter}>
|
|
<Option value="所有名录">所有名录</Option>
|
|
<Option value="大气环境">大气环境</Option>
|
|
<Option value="水环境">水环境</Option>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
<div className={styles.chartsContainer}>
|
|
<div className={styles.pieChartContainer}>
|
|
{/* <div className={styles.chartTitle}>超标污染物数量</div> */}
|
|
{chartReady && (
|
|
<ReactECharts
|
|
option={pollutantEmissionOption}
|
|
style={{ height: '100%', width: '100%' }}
|
|
opts={{ renderer: 'canvas' }}
|
|
/>
|
|
)}
|
|
<div className={styles.chartCenterContent}>
|
|
<div className={styles.chartValue}>62%</div>
|
|
<div className={styles.chartLabel}>超标污染物数量</div>
|
|
</div>
|
|
</div>
|
|
<div className={styles.pieChartContainer}>
|
|
{/* <div className={styles.chartTitle}>超标污染物种类</div> */}
|
|
{chartReady && (
|
|
<ReactECharts
|
|
option={pollutantTypeOption}
|
|
style={{ height: '100%', width: '100%' }}
|
|
opts={{ renderer: 'canvas' }}
|
|
/>
|
|
)}
|
|
<div className={styles.chartCenterContent}>
|
|
<div className={styles.chartValue}>25%</div>
|
|
<div className={styles.chartLabel}>超标污染物种类</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 超标排放统计 */}
|
|
<div className={styles.exceedanceStatsCard}>
|
|
<div className={styles.cardHeader}>
|
|
<div className={styles.cardTitle}>超标排放统计</div>
|
|
<div className={styles.filterGroup}>
|
|
<Select defaultValue="今日" className={styles.exceedanceTimeFilter}>
|
|
<Option value="今日">今日</Option>
|
|
<Option value="本周">本周</Option>
|
|
<Option value="本月">本月</Option>
|
|
</Select>
|
|
<Select defaultValue="所有名录" className={styles.exceedanceCategoryFilter}>
|
|
<Option value="所有名录">所有名录</Option>
|
|
<Option value="大气环境">大气环境</Option>
|
|
<Option value="水环境">水环境</Option>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
<div className={styles.barChartContainer}>
|
|
{chartReady && (
|
|
<ReactECharts
|
|
option={exceedanceOption}
|
|
style={{ height: '200px', width: '100%' }}
|
|
opts={{ renderer: 'canvas' }}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* 环境分类卡片 */}
|
|
<div className={styles.environmentalCategories}>
|
|
|
|
<div className={styles.categoryCard1} onClick={handleAtmosphereCardClick}>
|
|
<div className={styles.airPollutionText}>AIR POLLUSION</div>
|
|
<div className={styles.categoryContent}>
|
|
<div className={styles.categoryInfo}>
|
|
<div className={styles.titleContainer}>
|
|
<div className={`${styles.categoryTitle} ${styles.atmosphereGradient}`}>大气环境</div>
|
|
<div className={`${styles.categoryTitle} ${styles.atmosphereMirror}`}>大气环境</div>
|
|
</div>
|
|
<div className={`${styles.categorySubtitle} ${styles.pollutantSubtitle}`}>特征污染物名录库</div>
|
|
</div>
|
|
<img className={styles.categoryIcon} src={icon_factory} alt="icon_factory" />
|
|
</div>
|
|
</div>
|
|
<div className={styles.categoryCard2}>
|
|
<div className={styles.waterPollutionText}>WATER POLLUSION</div>
|
|
<div className={styles.categoryContent}>
|
|
<div className={styles.categoryInfo}>
|
|
<div className={styles.titleContainer}>
|
|
<div className={`${styles.categoryTitle} ${styles.waterGradient}`}>水环境</div>
|
|
<div className={`${styles.categoryTitle} ${styles.waterMirror}`}>水环境</div>
|
|
</div>
|
|
<div className={`${styles.categorySubtitle} ${styles.pollutantSubtitle}`}>特征污染物名录库</div>
|
|
</div>
|
|
<img src={icon_water} alt="icon_water" className={styles.categoryIcon} />
|
|
</div>
|
|
</div>
|
|
<div className={styles.categoryCard3}>
|
|
<div className={styles.soilPollutionText}>SOILPOLLUSION</div>
|
|
<div className={styles.categoryContent}>
|
|
<div className={styles.categoryInfo}>
|
|
<div className={styles.titleContainer}>
|
|
<div className={`${styles.categoryTitle} ${styles.soilGradient}`}>土壤及地下水</div>
|
|
<div className={`${styles.categoryTitle} ${styles.soilMirror}`}>土壤及地下水</div>
|
|
</div>
|
|
<div className={`${styles.categorySubtitle} ${styles.pollutantSubtitle}`}>特征污染物名录库</div>
|
|
</div>
|
|
<img className={styles.categoryIcon} src={icon_soil} alt="icon_soil" />
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 污染源管理表格区域 */}
|
|
<div className={styles.tableCard}>
|
|
<div className={styles.cardTitle}>
|
|
<span>污染源管理</span>
|
|
<div className={styles.titleButtons}>
|
|
<Button
|
|
type="primary"
|
|
// icon={<PlusOutlined />}
|
|
onClick={handleAdd}
|
|
className={styles.titleAddButton}
|
|
>
|
|
新增
|
|
</Button>
|
|
<Button
|
|
// icon={<FileTextOutlined />}
|
|
onClick={handleGenerateReport}
|
|
className={styles.titleReportButton}
|
|
>
|
|
生成报表
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<StandardTable
|
|
columns={columns}
|
|
data={tableData}
|
|
onChange={handleTableChange}
|
|
rowKey="key"
|
|
size="small"
|
|
// scroll={{ x: 1200 }}
|
|
rowSelection={{
|
|
selectedRowKeys,
|
|
onChange: setSelectedRowKeys,
|
|
getCheckboxProps: (record) => ({
|
|
name: record.name,
|
|
}),
|
|
}}
|
|
pagination={{
|
|
showTotal: (total, range) => `共 ${total} 条`,
|
|
showSizeChanger: true,
|
|
showQuickJumper: true,
|
|
pageSizeOptions: ['5', '10', '20', '50', '100'],
|
|
defaultPageSize: 5,
|
|
size: 'small',
|
|
}}
|
|
/>
|
|
</div>
|
|
</div >
|
|
);
|
|
};
|
|
|
|
export default PollutionSourceManagement;
|
|
|