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

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;