Resolve merge conflict and keep atmosphere pollutant library and env monitoring menu items
commit
d45da29ee4
@ -0,0 +1,3 @@
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.04453 3.0682C8.33094 3.0682 8.56312 2.83602 8.56312 2.54961V1.51273C8.56312 1.22633 8.33094 0.994141 8.04453 0.994141C7.75813 0.994141 7.52594 1.22633 7.52594 1.51273V2.54977C7.52609 2.83617 7.75813 3.0682 8.04453 3.0682ZM4.88203 3.57086C5.02516 3.81883 5.34234 3.90383 5.59031 3.7607C5.83828 3.61758 5.92328 3.30039 5.78016 3.05242L5.26156 2.1543C5.11844 1.90633 4.80125 1.82133 4.55328 1.96445C4.30531 2.10758 4.22031 2.42477 4.36344 2.67273L4.88203 3.57086ZM2.20453 5.25867L3.10266 5.77727C3.35063 5.92039 3.66781 5.83555 3.81094 5.58742C3.95406 5.33945 3.86922 5.02227 3.62109 4.87914L2.72297 4.36055C2.475 4.21742 2.15781 4.30227 2.01469 4.55039C1.87156 4.79836 1.95656 5.11539 2.20453 5.25867ZM3.18344 8.05898C3.18344 7.77258 2.95125 7.54039 2.66484 7.54039H1.62797C1.34156 7.54039 1.10938 7.77258 1.10938 8.05898C1.10938 8.34539 1.34156 8.57758 1.62797 8.57758H2.665C2.95125 8.57758 3.18344 8.34539 3.18344 8.05898ZM13.0513 5.66492L13.9494 5.14633C14.1973 5.0032 14.2823 4.68602 14.1392 4.43805C13.9961 4.19008 13.6789 4.10508 13.4309 4.2482L12.5328 4.7668C12.2848 4.90992 12.1998 5.22711 12.343 5.47508C12.4861 5.72305 12.8033 5.80805 13.0513 5.66492ZM10.5162 3.69586C10.7642 3.83898 11.0814 3.75414 11.2245 3.50602L11.7431 2.60789C11.8862 2.35992 11.8014 2.04273 11.5533 1.89961C11.3053 1.75648 10.9881 1.84133 10.845 2.08945L10.3264 2.98758C10.1833 3.23555 10.2681 3.55258 10.5162 3.69586ZM10.8281 11.4888C10.8281 11.696 10.9104 11.8947 11.0569 12.0413C11.2035 12.1878 11.4022 12.2701 11.6094 12.2701C11.8166 12.2701 12.0153 12.1878 12.1618 12.0413C12.3083 11.8947 12.3906 11.696 12.3906 11.4888C12.3906 11.2816 12.3083 11.0829 12.1618 10.9364C12.0153 10.7899 11.8166 10.7076 11.6094 10.7076C11.4022 10.7076 11.2035 10.7899 11.0569 10.9364C10.9104 11.0829 10.8281 11.2816 10.8281 11.4888ZM11.6094 7.98883C9.67641 7.98883 8.10938 9.55586 8.10938 11.4888C8.10938 13.4218 9.67641 14.9888 11.6094 14.9888C13.5423 14.9888 15.1094 13.4218 15.1094 11.4888C15.1094 9.55586 13.5423 7.98883 11.6094 7.98883ZM11.6094 12.8013C10.2286 12.8013 9.10938 11.4888 9.10938 11.4888C9.10938 11.4888 10.2286 10.1763 11.6094 10.1763C12.9902 10.1763 14.1094 11.4888 14.1094 11.4888C14.1094 11.4888 12.9902 12.8013 11.6094 12.8013ZM7.45922 12.542C7.42891 12.3815 7.38125 12.0577 7.36891 11.8949C7.30984 11.1123 7.44781 10.6059 7.60969 10.1488L7.63953 9.93305H6.42422L8.85469 6.3882L8.63375 8.52336C9.42609 7.72758 10.5227 7.23492 11.7344 7.23492C11.8472 7.23492 11.9589 7.23914 12.0697 7.24758C11.62 5.44273 9.98859 4.10523 8.04453 4.10523C5.75359 4.10523 3.89641 5.96242 3.89641 8.25336V13.9385H2.34078C2.05437 13.9385 1.82219 14.1707 1.82219 14.4571C1.82219 14.7435 2.05437 14.9757 2.34078 14.9757H8.93937C8.20219 14.3629 7.64359 13.5177 7.45922 12.542Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,63 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
|
||||
import styles from './EnvMonitoring.less';
|
||||
import EnvMonitoringOneMap from './components/EnvMonitoringOneMap'; //环保监测一张图
|
||||
import WastewaterMonitoring from './components/WastewaterMonitoring'; //废水监测管理
|
||||
import ExhaustMonitoring from './components/ExhaustMonitoring'; //废气监测管理
|
||||
import WasteMonitoring from './components/WasteMonitoring'; //废物监测管理
|
||||
const EnvMonitoring = () => {
|
||||
const [activeModule, setActiveModule] = useState('1');
|
||||
|
||||
const handleModuleClick = (module) => {
|
||||
setActiveModule(module)
|
||||
}
|
||||
|
||||
|
||||
const renderModule = () => {
|
||||
switch (activeModule) {
|
||||
case '1':
|
||||
return <EnvMonitoringOneMap />;
|
||||
case '2':
|
||||
return <WastewaterMonitoring />;
|
||||
case '3':
|
||||
return <ExhaustMonitoring />;
|
||||
case '4':
|
||||
return <WasteMonitoring />;
|
||||
default:
|
||||
return <EnvMonitoringOneMap />;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.TopButton}>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "1" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("1")}
|
||||
>环保检测一张图
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "2" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("2")}
|
||||
>废水监测管理
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "3" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("3")}
|
||||
>废气监测管理
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "4" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("4")}
|
||||
>废物监测管理
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{renderModule()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnvMonitoring;
|
||||
@ -0,0 +1,69 @@
|
||||
.container {
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 89vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.TopButton {
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: 8px 15px 5px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
// margin-left: 6px;
|
||||
|
||||
.TopButtonItem {
|
||||
background-color: #FFFFFF !important;
|
||||
color: #999999 !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: 4px 16px !important;
|
||||
height: auto !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
position: relative !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
gap: 5px !important;
|
||||
transition: all 0.3s ease !important;
|
||||
|
||||
&:hover {
|
||||
color: #999999 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: #999999 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(98.03deg, #00E49C 0.68%, #00D2D2 98.3%) !important;
|
||||
box-shadow: 0px 2px 2px 0px #AEEDDE !important;
|
||||
color: #FFFFFF !important;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: 28px;
|
||||
height: 5px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
// ======== 内容区域样式 ========
|
||||
flex: 1; // ======== 占据剩余空间 ========
|
||||
overflow-y: auto; // ======== 允许垂直滚动 ========
|
||||
padding: 0; // ======== 无内边距 ========
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import styles from './EnvMonitoringOneMap.less';
|
||||
|
||||
const EnvMonitoringOneMap = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
开发中
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EnvMonitoringOneMap;
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
|
||||
.developingBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 80px;
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(240, 147, 251, 0.3);
|
||||
|
||||
.developingText {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Tabs, Button } from 'antd';
|
||||
import styles from './ExhaustMonitoring.less';
|
||||
import { SettingOutlined } from '@ant-design/icons';
|
||||
// 导入子页面组件
|
||||
import ExhaustEmissionStandard from './secondary_menu/ExhaustEmissionStandard';
|
||||
import AlarmInformation from './secondary_menu/AlarmInformation';
|
||||
import AbnormalAlarmInformation from './secondary_menu/AbnormalAlarmInformation';
|
||||
|
||||
const ExhaustMonitoring = () => {
|
||||
const [activeTab, setActiveTab] = useState('exhaust-emission-standard');
|
||||
|
||||
// 标签页配置
|
||||
const tabItems = [
|
||||
{
|
||||
key: 'exhaust-emission-standard',
|
||||
label: '废气排放达标情况管理',
|
||||
children: <ExhaustEmissionStandard />
|
||||
},
|
||||
{
|
||||
key: 'abnormal-alarm-information',
|
||||
label: '异常报警信息管理',
|
||||
children: <AbnormalAlarmInformation />
|
||||
},
|
||||
{
|
||||
key: 'alarm-information',
|
||||
label: '告警信息管理',
|
||||
children: <AlarmInformation />
|
||||
}
|
||||
];
|
||||
|
||||
// 标签页切换处理
|
||||
const handleTabChange = (key) => {
|
||||
setActiveTab(key);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={handleTabChange}
|
||||
items={tabItems}
|
||||
className={styles.tabs}
|
||||
style={{
|
||||
'--ant-tabs-tab-color': '#AFAFAF',
|
||||
'--ant-tabs-tab-active-color': '#009D6F',
|
||||
'--ant-tabs-tab-active-bg': '#fff'
|
||||
}}
|
||||
tabBarStyle={{
|
||||
'--ant-tabs-tab-active-color': '#009D6F'
|
||||
}}
|
||||
tabBarExtraContent={
|
||||
<Button
|
||||
icon={<SettingOutlined />}
|
||||
className={styles.settingButton}
|
||||
onClick={() => {/* 你的操作 */ }}>
|
||||
自动报警设置
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExhaustMonitoring;
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px 0;
|
||||
// background-color: #f5f5f5;
|
||||
|
||||
.tabs {
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
border-radius: 8px;
|
||||
// box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
:global(.ant-tabs-nav) {
|
||||
margin: 0;
|
||||
padding: 0 0px;
|
||||
background-color: transparent;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
:global(.ant-tabs-tab) {
|
||||
padding: 16px 24px !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 400 !important;
|
||||
color: #AFAFAF !important;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
color: #AFAFAF !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
&.ant-tabs-tab-active {
|
||||
color: #009D6F !important;
|
||||
background-color: #fff !important;
|
||||
border-bottom: none !important;
|
||||
font-weight: 700;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 额外的全局样式覆盖,确保优先级足够高
|
||||
:global(.ant-tabs-tab.ant-tabs-tab-active) {
|
||||
color: #009D6F !important;
|
||||
background-color: #fff !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
// 更强的选择器优先级
|
||||
:global(.ant-tabs .ant-tabs-tab.ant-tabs-tab-active) {
|
||||
color: #009D6F !important;
|
||||
background-color: #fff !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
// 针对可能的嵌套结构
|
||||
:global(.ant-tabs-nav .ant-tabs-tab.ant-tabs-tab-active) {
|
||||
color: #009D6F !important;
|
||||
background-color: #fff !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
// // 覆盖 Ant Design 5.x 的高优先级样式
|
||||
// :global(.ant-tabs .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
||||
// color: #009D6F !important;
|
||||
// text-shadow: none !important;
|
||||
// }
|
||||
|
||||
// 使用更高优先级的选择器
|
||||
:global(.ant-tabs.ant-tabs-top .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
||||
color: #009D6F !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
// 针对 CSS 模块的覆盖
|
||||
:global(.ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
||||
color: #009D6F !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
// 最高优先级覆盖
|
||||
:global(.ant-tabs .ant-tabs-tab.ant-tabs-tab-active .ant-tabs-tab-btn) {
|
||||
color: #009D6F !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
// 覆盖Ant Design的默认下划线
|
||||
:global(.ant-tabs-ink-bar) {
|
||||
background: none !important;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) rotate(180deg);
|
||||
width: 38.36132812500014px;
|
||||
height: 3.3613271713256965px;
|
||||
background-color: #009D6F;
|
||||
opacity: 1;
|
||||
border-radius: 2px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.ant-tabs-content-holder) {
|
||||
height: calc(100% - 60px);
|
||||
// padding: 20px;
|
||||
|
||||
.ant-tabs-content {
|
||||
height: 100%;
|
||||
|
||||
.ant-tabs-tabpane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settingButton {
|
||||
border-color: #d9d9d9;
|
||||
color: #333;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import styles from './WasteMonitoring.less';
|
||||
|
||||
const WasteMonitoring = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
开发中
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WasteMonitoring;
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
|
||||
.developingBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 60px 80px;
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(240, 147, 251, 0.3);
|
||||
|
||||
.developingText {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
letter-spacing: 4px;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
||||
animation: pulse 2s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,349 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Card, Select, Button, Table, Tag, Input, Form, Row, Col, Pagination, Space } from 'antd';
|
||||
import { EyeOutlined, SettingOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import * as echarts from 'echarts';
|
||||
import styles from './WastewaterMonitoring.less';
|
||||
import viewIcon from '@/assets/business_envinformation/viewicon.svg';
|
||||
const pollutantOptions = [
|
||||
{ value: '全部', label: '全部污染物' },
|
||||
{ value: 'COD', label: 'COD' },
|
||||
{ value: '氨氮', label: '氨氮' },
|
||||
];
|
||||
const monitorPointOptions = [
|
||||
{ value: '全部', label: '全部监测点' },
|
||||
{ value: '点1', label: '点1' },
|
||||
{ value: '点2', label: '点2' },
|
||||
];
|
||||
const dateOptions = [
|
||||
{ value: '本月', label: '本月' },
|
||||
{ value: '本周', label: '本周' },
|
||||
{ value: '今日', label: '今日' },
|
||||
];
|
||||
const statData = [
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '超标' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '报警' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '正常' },
|
||||
{ w: 'COD', s: '山顶点', v: '490mg/L', d: '2025-09-11', st: '超标' },
|
||||
];
|
||||
const alarmTableColumns = [
|
||||
{ title: '序号', dataIndex: 'index', width: 60, render: (_, __, i) => i + 1 },
|
||||
{ title: '报警时间', dataIndex: 'time' },
|
||||
{ title: '监测站点', dataIndex: 'point' },
|
||||
{ title: '污染物名称', dataIndex: 'name' },
|
||||
{ title: '超标情况(%)', dataIndex: 'percent' },
|
||||
{ title: '负责人', dataIndex: 'person' },
|
||||
{ title: '报警短信', dataIndex: 'sms', render: v => v === '已发送' ? <span style={{ background: '#FAFAFA', color: '#333333', border: '1px solid #D9D9D9', borderRadius: 4, padding: '2px 12px', fontSize: 13 }}>已发送</span> : <span style={{ background: '#FFEAE9', color: '#FF0000', border: '1px solid #FFBEBE', borderRadius: 4, padding: '2px 12px', fontSize: 13 }}>未发送</span> },
|
||||
{ title: '处理情况', dataIndex: 'status', render: v => v === '已处理' ? <span style={{ background: '#F6FFED', color: '#52C41A', border: '1px solid #B7EB8F', borderRadius: 4, padding: '2px 12px', fontSize: 13 }}>已处理</span> : v === '未处理' ? <span style={{ background: '#FFF2E8', color: '#FA541C', border: '1px solid #FFBB96', borderRadius: 4, padding: '2px 12px', fontSize: 13 }}>未处理</span> : <span style={{ background: '#FFFBE6', color: '#FAAD14', border: '1px solid #FFE58F', borderRadius: 4, padding: '2px 12px', fontSize: 13 }}>处理中</span> },
|
||||
{
|
||||
title: '操作', dataIndex: 'action', align: 'center', render: (_, record) => (
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '14px' }}>
|
||||
<img
|
||||
src={viewIcon}
|
||||
alt="查看"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
const alarmTableData = [
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'hto', percent: 26, person: '负责人', sms: '已发送', status: '已处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 58, person: '负责人', sms: '未发送', status: '未处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 52, person: '王华俊', sms: '已发送', status: '已处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 43, person: '赵荣堂', sms: '已发送', status: '已处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 43, person: '赵荣堂', sms: '已发送', status: '已处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 43, person: '赵荣堂', sms: '已发送', status: '已处理' },
|
||||
{ time: '2025-08-27 07:12', point: 'xxxxx', name: 'dfadf', percent: 43, person: '赵荣堂', sms: '已发送', status: '已处理' },
|
||||
];
|
||||
|
||||
const OnlineMonitoring = () => {
|
||||
const chartRef = useRef(null);
|
||||
const [monitorPoint, setMonitorPoint] = useState('全部');
|
||||
const [pollutant, setPollutant] = useState('全部');
|
||||
const [dateRange, setDateRange] = useState('本月');
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
});
|
||||
const [alarmPage, setAlarmPage] = useState(1);
|
||||
const ALARM_PAGE_SIZE = 7;
|
||||
const ALARM_TOTAL = 85; // 真实总数
|
||||
|
||||
useEffect(() => {
|
||||
if (chartRef.current) {
|
||||
const chart = echarts.init(chartRef.current);
|
||||
chart.setOption({
|
||||
grid: { left: 40, right: 20, top: 20, bottom: 40 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['05-01', '05-05', '05-09', '05-13', '05-17', '05-21', '05-25', '05-29', '05-31'],
|
||||
boundaryGap: false,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { color: '#A3ACB7', fontSize: 13, margin: 16 },
|
||||
splitLine: { show: false }, // 竖线不显示
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 900,
|
||||
splitNumber: 9,
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { color: '#A3ACB7', fontSize: 13, margin: 16 },
|
||||
splitLine: { show: true, lineStyle: { color: '#E9F0F5', type: 'dashed' } }, // 横线为虚线
|
||||
},
|
||||
series: [{
|
||||
data: [400, 500, 700, 800, 600, 700, 500, 400, 450],
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
lineStyle: { color: '#00C48F', width: 2 },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0, y: 0, x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(0,196,143,0.15)' },
|
||||
{ offset: 1, color: 'rgba(0,196,143,0.00)' }
|
||||
]
|
||||
}
|
||||
},
|
||||
}],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: '#fff',
|
||||
borderColor: '#E9F0F5',
|
||||
borderWidth: 1,
|
||||
textStyle: { color: '#222', fontSize: 13 },
|
||||
axisPointer: { type: 'line', lineStyle: { color: '#00C48F', width: 1 } },
|
||||
},
|
||||
markLine: {
|
||||
symbol: 'none',
|
||||
data: [
|
||||
{
|
||||
yAxis: 700,
|
||||
lineStyle: { color: '#FF8A00', type: 'dashed', width: 2 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'start',
|
||||
color: '#fff',
|
||||
backgroundColor: '#FF8A00',
|
||||
borderRadius: 4,
|
||||
padding: [2, 8],
|
||||
fontSize: 13,
|
||||
fontWeight: 500,
|
||||
formatter: '700',
|
||||
distance: 10
|
||||
}
|
||||
},
|
||||
{
|
||||
yAxis: 700,
|
||||
lineStyle: { color: 'transparent' },
|
||||
label: {
|
||||
show: true,
|
||||
position: [0, 18],
|
||||
color: '#FF8A00',
|
||||
backgroundColor: 'transparent',
|
||||
fontSize: 12,
|
||||
formatter: '严重超标',
|
||||
distance: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
yAxis: 500,
|
||||
lineStyle: { color: '#FFB800', type: 'dashed', width: 2 },
|
||||
label: {
|
||||
show: true,
|
||||
position: 'start',
|
||||
color: '#fff',
|
||||
backgroundColor: '#FFB800',
|
||||
borderRadius: 4,
|
||||
padding: [2, 8],
|
||||
fontSize: 13,
|
||||
fontWeight: 500,
|
||||
formatter: '500',
|
||||
distance: 10
|
||||
}
|
||||
},
|
||||
{
|
||||
yAxis: 500,
|
||||
lineStyle: { color: 'transparent' },
|
||||
label: {
|
||||
show: true,
|
||||
position: [0, 18],
|
||||
color: '#FFB800',
|
||||
backgroundColor: 'transparent',
|
||||
fontSize: 12,
|
||||
formatter: '报警线',
|
||||
distance: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [monitorPoint, pollutant, dateRange]);
|
||||
|
||||
return (
|
||||
<div className={styles.Ocontainer}>
|
||||
<div className={styles.pageMainRow}>
|
||||
{/* 左侧主区 */}
|
||||
<div className={styles.pageMainColLeft}>
|
||||
<div className={styles.trendCard}>
|
||||
<div className={styles.trendHeader}>
|
||||
<div className={styles.trendTitle}>
|
||||
<div className={styles.trendTitleBar}></div>
|
||||
污染物排放趋势
|
||||
</div>
|
||||
<div className={styles.trendSelects}>
|
||||
<Select value={monitorPoint} onChange={setMonitorPoint} options={monitorPointOptions} className={styles.trendSelect} />
|
||||
<Select value={pollutant} onChange={setPollutant} options={pollutantOptions} className={styles.trendSelect} />
|
||||
<Select value={dateRange} onChange={setDateRange} options={dateOptions} className={styles.trendSelect} />
|
||||
</div>
|
||||
</div>
|
||||
<div ref={chartRef} className={styles.trendChart} />
|
||||
</div>
|
||||
<div className={styles.alarmTableCard}>
|
||||
<div className={styles.alarmTableHeader}>
|
||||
<div className={styles.alarmTableTitle}>
|
||||
<div className={styles.alarmTableTitleBar}></div>
|
||||
报警信息
|
||||
</div>
|
||||
<div className={styles.alarmTableSelects}>
|
||||
<Select defaultValue="全部" options={monitorPointOptions} className={styles.alarmTableSelect} dropdownStyle={{ minWidth: 100 }} />
|
||||
<Select defaultValue="全部" options={pollutantOptions} className={styles.alarmTableSelect} dropdownStyle={{ minWidth: 100 }} />
|
||||
<Select defaultValue="本月" options={dateOptions} className={styles.alarmTableSelect} dropdownStyle={{ minWidth: 100 }} />
|
||||
<Button className={styles.alarmTableAddBtn}><PlusOutlined /></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.alarmTableWrap}>
|
||||
<Table
|
||||
columns={alarmTableColumns}
|
||||
dataSource={alarmTableData.slice((alarmPage - 1) * ALARM_PAGE_SIZE, alarmPage * ALARM_PAGE_SIZE)}
|
||||
size="small"
|
||||
pagination={{
|
||||
pageSize: ALARM_PAGE_SIZE,
|
||||
total: ALARM_TOTAL,
|
||||
current: alarmPage,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
onChange: (page) => setAlarmPage(page),
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: true,
|
||||
position: ['bottomRight'],
|
||||
}}
|
||||
rowKey={(_, i) => i + (alarmPage - 1) * ALARM_PAGE_SIZE}
|
||||
scroll={{ x: 'max-content' }}
|
||||
bordered={false}
|
||||
className={styles.alarmTable}
|
||||
tableLayout="fixed"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: 420, display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||
<div className={styles.statCard}>
|
||||
<div className={styles.statHeader}>
|
||||
<div className={styles.trendTitle}>
|
||||
<div className={styles.trendTitleBar}></div>
|
||||
污染物排放统计
|
||||
</div>
|
||||
<Button className={styles.statAddBtn}>手动添加</Button>
|
||||
</div>
|
||||
<div className={styles.statTableWrap}>
|
||||
<Table
|
||||
className={styles.statTable}
|
||||
columns={[
|
||||
{
|
||||
title: '污染物',
|
||||
dataIndex: 'w',
|
||||
width: 100,
|
||||
},
|
||||
{ title: '站点', dataIndex: 's', width: 120 },
|
||||
{ title: '排放量', dataIndex: 'v', width: 120 },
|
||||
{ title: '日期', dataIndex: 'd', width: 140 },
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'st',
|
||||
width: 120,
|
||||
},
|
||||
]}
|
||||
dataSource={statData.slice((alarmPage - 1) * ALARM_PAGE_SIZE, alarmPage * ALARM_PAGE_SIZE)}
|
||||
size="small"
|
||||
pagination={{
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
current: 1,
|
||||
showTotal: () => `共 10 条`,
|
||||
onChange: (page) => setAlarmPage(page),
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: true,
|
||||
position: ['bottomRight'],
|
||||
}}
|
||||
rowKey={(r, i) => i + (alarmPage - 1) * ALARM_PAGE_SIZE}
|
||||
scroll={{ x: 'max-content' }}
|
||||
bordered={false}
|
||||
tableLayout="fixed"
|
||||
rowClassName={(_, idx) => idx % 2 === 0 ? '' : 'table-row-alt'}
|
||||
onRow={() => ({ style: { height: 20 } })}
|
||||
components={{
|
||||
body: {
|
||||
wrapper: (props) => {
|
||||
// 过滤掉第一个tr
|
||||
const { children, ...rest } = props;
|
||||
return (
|
||||
<tbody {...rest}>
|
||||
{React.Children.toArray(children).slice(1)}
|
||||
</tbody>
|
||||
);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* 短信区块 */}
|
||||
<div style={{ background: '#fff', boxShadow: 'none', padding: 0 }}>
|
||||
<div className={styles.smsCard}>
|
||||
<div className={styles.smsHeader}>
|
||||
<div className={styles.trendTitle}>
|
||||
<div className={styles.trendTitleBar}></div>
|
||||
报警短信
|
||||
</div>
|
||||
<div className={styles.smsHeaderBtns}>
|
||||
<Button className={styles.smsTplBtn}>设置模板</Button>
|
||||
<Button type="primary" className={styles.smsSendBtn}>发送</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Form layout="vertical" className={styles.smsForm}>
|
||||
<div className={styles.smsFormRow} style={{ display: 'flex', alignItems: 'center', marginTop: 20 }}>
|
||||
<span className={styles.smsFormLabel} style={{ minWidth: 70 }}>收 件 人</span>
|
||||
<Select className={styles.smsFormInput} value="xxx" options={[{ value: 'xxx', label: 'xxx' }]} style={{ width: 320 }} />
|
||||
</div>
|
||||
<div className={styles.smsFormRow} style={{ display: 'flex', alignItems: 'center', marginTop: 20 }}>
|
||||
<span className={styles.smsFormLabel} style={{ minWidth: 70 }}>手机号码</span>
|
||||
<Input className={styles.smsFormInput} placeholder="请输入" style={{ width: 320 }} />
|
||||
</div>
|
||||
<div className={styles.smsFormRow} style={{ display: 'flex', alignItems: 'flex-start', marginTop: 20 }}>
|
||||
<span className={styles.smsFormLabel} style={{ minWidth: 70, marginTop: 8 }}>短信内容</span>
|
||||
<div style={{ width: 320 }}>
|
||||
<Input.TextArea className={styles.smsFormTextarea} value="xxx" rows={5} style={{ resize: 'none' }} />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OnlineMonitoring;
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,196 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Button, Input, Select, Switch } from 'antd';
|
||||
import { SearchOutlined, RedoOutlined, UploadOutlined, DownloadOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
import styles from './AbnormalAlarmInformation.less';
|
||||
|
||||
const AbnormalAlarmInformation = () => {
|
||||
const [activeTab, setActiveTab] = useState('actual');
|
||||
|
||||
// 表格数据与图片一致
|
||||
const [tableData, setTableData] = useState([
|
||||
{ key: 1, siteName: '2025-08-29', monitorFactor: '赵若行', alarmCount: '郑祥飞', autoHandle: false },
|
||||
{ key: 2, siteName: '2025-09-02', monitorFactor: '王翠琪', alarmCount: '赵广峰', autoHandle: true },
|
||||
{ key: 3, siteName: '2025-09-06', monitorFactor: '王翠琪', alarmCount: '郑嘉亨', autoHandle: true },
|
||||
{ key: 4, siteName: '2025-08-22', monitorFactor: '王锦瑞', alarmCount: '赵玉', autoHandle: true },
|
||||
{ key: 5, siteName: '2025-08-31', monitorFactor: '吴子鑫', alarmCount: '钱如珩', autoHandle: true },
|
||||
{ key: 6, siteName: '2025-08-29', monitorFactor: '何凤彬', alarmCount: '赵润琪', autoHandle: false },
|
||||
{ key: 7, siteName: '2025-08-28', monitorFactor: '李树烈', alarmCount: '李建刚', autoHandle: false },
|
||||
{ key: 8, siteName: '2025-08-22', monitorFactor: '赵午光', alarmCount: '钱瑞西', autoHandle: false },
|
||||
{ key: 9, siteName: '2025-08-21', monitorFactor: '王凤妍', alarmCount: '李金涛', autoHandle: false },
|
||||
{ key: 10, siteName: '2025-09-09', monitorFactor: '赵涛', alarmCount: '何倩', autoHandle: false },
|
||||
]);
|
||||
|
||||
// 表格列定义
|
||||
const handleSwitchChange = (checked, record) => {
|
||||
setTableData(prevData => prevData.map(item =>
|
||||
item.key === record.key ? { ...item, autoHandle: checked } : item
|
||||
));
|
||||
};
|
||||
|
||||
const normalColumns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'key',
|
||||
key: 'key',
|
||||
align: 'center',
|
||||
width: 60,
|
||||
},
|
||||
{
|
||||
title: '站点名称',
|
||||
dataIndex: 'siteName',
|
||||
key: 'siteName',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: '监测因子',
|
||||
dataIndex: 'monitorFactor',
|
||||
key: 'monitorFactor',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: '报警次数',
|
||||
dataIndex: 'alarmCount',
|
||||
key: 'alarmCount',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
title: '异常自动报警',
|
||||
dataIndex: 'autoHandle',
|
||||
key: 'autoHandle',
|
||||
align: 'left',
|
||||
render: (text, record) => (
|
||||
<Switch checked={!!text} size="small" onChange={checked => handleSwitchChange(checked, record)} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '详情',
|
||||
key: 'detail',
|
||||
align: 'left',
|
||||
render: () => <a href="#">查看</a>,
|
||||
},
|
||||
];
|
||||
|
||||
// 获取当前标签页的数据
|
||||
const getCurrentData = () => {
|
||||
switch (activeTab) {
|
||||
case 'actual':
|
||||
case 'excessive':
|
||||
case 'equipment':
|
||||
return tableData;
|
||||
default:
|
||||
return tableData;
|
||||
}
|
||||
};
|
||||
|
||||
// 获取当前标签页的列定义
|
||||
const getCurrentColumns = () => {
|
||||
switch (activeTab) {
|
||||
case 'actual':
|
||||
case 'excessive':
|
||||
case 'equipment':
|
||||
return normalColumns;
|
||||
default:
|
||||
return normalColumns;
|
||||
}
|
||||
};
|
||||
|
||||
// 分页配置
|
||||
const pagination = {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 12,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.dischargePermitManagement}>
|
||||
<div className={styles.tabContainer}>
|
||||
<div className={styles.tabButtons}>
|
||||
<Button
|
||||
className={`${styles.tabButton} ${activeTab === 'actual' ? styles.active : ''}`}
|
||||
onClick={() => setActiveTab('actual')}
|
||||
>
|
||||
异常报警
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.tabButton} ${activeTab === 'excessive' ? styles.active : ''}`}
|
||||
onClick={() => setActiveTab('excessive')}
|
||||
>
|
||||
超标报警
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.tabButton} ${activeTab === 'equipment' ? styles.active : ''}`}
|
||||
onClick={() => setActiveTab('equipment')}
|
||||
>
|
||||
离线报警
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={styles.filterSection}>
|
||||
<Select
|
||||
defaultValue={"1"}
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
style={{ width: 120 }}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: '全部站点类型' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={"1"}
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
style={{ width: 120 }}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: '全部站点' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={"1"}
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
style={{ width: 120 }}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: '全部监测因子' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
// icon={<SearchOutlined />}
|
||||
className={styles.queryBtn}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button
|
||||
// icon={<RedoOutlined />}
|
||||
className={styles.resetBtn}
|
||||
>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.tableContent}>
|
||||
<StandardTable
|
||||
columns={getCurrentColumns()}
|
||||
data={{
|
||||
list: getCurrentData(),
|
||||
pagination: pagination
|
||||
}}
|
||||
rowKey="key"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AbnormalAlarmInformation;
|
||||
@ -0,0 +1,160 @@
|
||||
.dischargePermitManagement {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
|
||||
.tabContainer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding: 0 ;
|
||||
// border-bottom: 1px solid #e8e8e8;
|
||||
|
||||
.tabButtons {
|
||||
display: flex;
|
||||
gap: 0;
|
||||
background-color: #F4F4F4;
|
||||
border-radius: 4px;
|
||||
padding: 4px 8px;
|
||||
align-items: center;
|
||||
|
||||
.tabButton {
|
||||
padding: 8px 20px;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
height: auto;
|
||||
line-height: 1.4;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #03C598;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filterSection {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
border-radius: 4px;
|
||||
|
||||
.filterLabel {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.filterInput {
|
||||
min-width: 200px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: #389e0d;
|
||||
border-color: #389e0d;
|
||||
}
|
||||
}
|
||||
|
||||
.resetBtn, .uploadBtn {
|
||||
background-color: #fff;
|
||||
color: #666;
|
||||
border-color: #d9d9d9;
|
||||
border-radius: 4px;
|
||||
|
||||
|
||||
&:hover {
|
||||
border-color: #1890ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableContent {
|
||||
width: 100%;
|
||||
|
||||
// 覆盖表头样式
|
||||
:global {
|
||||
.ant-table-thead > tr > th {
|
||||
font-weight: 400 !important;
|
||||
font-size: 12px !important;
|
||||
color: #333 !important;
|
||||
// text-align: center !important;
|
||||
background-color: #FAFAFA !important;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ant-table-wrapper {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.attachmentLink {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.actionButtons {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.downloadIcon, .deleteIcon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.downloadIcon {
|
||||
&:hover {
|
||||
filter: brightness(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.deleteIcon {
|
||||
&:hover {
|
||||
filter: brightness(1.2) saturate(1.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,235 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker, Space, Modal, Select } from 'antd';
|
||||
import { SearchOutlined, RedoOutlined, CloseOutlined, EyeOutlined, DeleteOutlined, PlusOutlined, UploadOutlined, EditOutlined, DownloadOutlined } from '@ant-design/icons';
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
import styles from './AlarmInformation.less';
|
||||
import viewIcon from '@/assets/business_envinformation/viewicon.svg';
|
||||
import deleteIcon from '@/assets/business_envinformation/deleteicon.svg';
|
||||
const AlarmInformation = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [currentImage, setCurrentImage] = useState(null);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 12,
|
||||
});
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [dataSource, setDataSource] = useState([
|
||||
{ key: 1, type: 'xxxx', level: '二级', company: '北京市-聚能和京东有限公司', site: 'xxxx站点', time: '2025-08-31', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 2, type: 'xxxx', level: '二级', company: '万和化企业服务有限公司北京分公司', site: 'xxxx站点', time: '2025-08-29', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 3, type: 'xxxx', level: '二级', company: '佳园国际集团有限公司', site: 'xxxx站点', time: '2025-09-14', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 4, type: 'xxxx', level: '二级', company: '飞骑摩车(中国)有限公司北京分公司', site: 'xxxx站点', time: '2025-09-13', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 5, type: 'xxxx', level: '二级', company: '深圳亿和企业管理有限公司', site: 'xxxx站点', time: '2025-08-20', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 6, type: 'xxxx', level: '二级', company: '深圳亿和企业管理有限公司', site: 'xxxx站点', time: '2025-08-20', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 7, type: 'xxxx', level: '二级', company: '深圳亿和企业管理有限公司', site: 'xxxx站点', time: '2025-08-20', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 8, type: 'xxxx', level: '二级', company: '深圳亿和企业管理有限公司', site: 'xxxx站点', time: '2025-08-20', method: 'xxxx', content: 'xxxx' },
|
||||
{ key: 9, type: 'xxxx', level: '二级', company: '深圳亿和企业管理有限公司', site: 'xxxx站点', time: '2025-08-20', method: 'xxxx', content: 'xxxx' },
|
||||
]);
|
||||
|
||||
const getCurrentPageData = () => {
|
||||
const { current, pageSize } = pagination;
|
||||
const start = (current - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
return dataSource.slice(start, end);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: '序号', dataIndex: 'key', key: 'key', align: 'left' },
|
||||
{ title: '告警类型', dataIndex: 'type', key: 'type', align: 'left' },
|
||||
{ title: '告警等级', dataIndex: 'level', key: 'level', align: 'left' },
|
||||
{ title: '所属企业', dataIndex: 'company', key: 'company', align: 'left' },
|
||||
{ title: '告警站点', dataIndex: 'site', key: 'site', align: 'left' },
|
||||
{ title: '告警时间', dataIndex: 'time', key: 'time', align: 'left' },
|
||||
{ title: '通知方式', dataIndex: 'method', key: 'method', align: 'left' },
|
||||
{ title: '告警内容', dataIndex: 'content', key: 'content', align: 'left' },
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
render: (_, record) => (
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '14px' }}>
|
||||
<img
|
||||
src={viewIcon}
|
||||
alt="查看"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
onClick={() => handleView(record)}
|
||||
/>
|
||||
<img src={deleteIcon} alt="删除" style={{ width: 16, height: 16, cursor: 'pointer' }} />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handleSearch = (values) => {
|
||||
console.log('搜索参数:', values);
|
||||
// TODO: 实现搜索功能
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
form.resetFields();
|
||||
// TODO: 重置搜索
|
||||
};
|
||||
|
||||
const handleView = (record) => {
|
||||
console.log('查看:', record);
|
||||
// TODO: 实现查看功能
|
||||
};
|
||||
|
||||
const handleEdit = (record) => {
|
||||
console.log('编辑:', record);
|
||||
// TODO: 实现编辑功能
|
||||
};
|
||||
|
||||
const handleDownload = (record) => {
|
||||
console.log('下载:', record);
|
||||
// TODO: 实现下载功能
|
||||
};
|
||||
|
||||
const handleDelete = (record) => {
|
||||
console.log('删除:', record);
|
||||
// TODO: 实现删除功能
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
console.log('新增');
|
||||
// TODO: 实现新增功能
|
||||
};
|
||||
|
||||
const handleImport = () => {
|
||||
console.log('导入');
|
||||
// TODO: 实现导入功能
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
console.log('查询');
|
||||
// TODO: 实现查询功能
|
||||
};
|
||||
|
||||
const handleTableChange = (pagination) => {
|
||||
setPagination(pagination);
|
||||
};
|
||||
|
||||
// 全选功能
|
||||
const handleSelectAll = (checked) => {
|
||||
if (checked) {
|
||||
const allKeys = getCurrentPageData().map(item => item.key);
|
||||
setSelectedRowKeys(allKeys);
|
||||
} else {
|
||||
setSelectedRowKeys([]);
|
||||
}
|
||||
};
|
||||
|
||||
// 批量操作
|
||||
const handleBatchOperation = (operation) => {
|
||||
console.log(`批量${operation}:`, selectedRowKeys);
|
||||
// TODO: 实现批量操作功能
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.wasteGasContainer}>
|
||||
{/* 第一块:操作按钮和筛选条件 */}
|
||||
<div className={styles.searchSection}>
|
||||
<Form
|
||||
form={form}
|
||||
layout="inline"
|
||||
className={styles.rightControls}
|
||||
onFinish={handleQuery}
|
||||
>
|
||||
<Form.Item label="告警类型" name="type" style={{ marginRight: 12 }}>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={[
|
||||
{ value: '1', label: '类型1' },
|
||||
{ value: '2', label: '类型2' },
|
||||
{ value: '3', label: '类型3' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="告警等级" name="level" style={{ marginRight: 12 }}>
|
||||
<Select
|
||||
placeholder="全部监测因子"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={[
|
||||
{ value: '1', label: '一级' },
|
||||
{ value: '2', label: '二级' },
|
||||
{ value: '3', label: '三级' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="告警站点" name="site" style={{ marginRight: 12 }}>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={[
|
||||
{ value: '1', label: '站点1' },
|
||||
{ value: '2', label: '站点2' },
|
||||
{ value: '3', label: '站点3' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item style={{ marginInlineEnd: 0 }}>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
className={styles.queryButton}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
onClick={handleReset}
|
||||
className={styles.resetButton}
|
||||
>
|
||||
重置
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
{/* 第二块:表格 */}
|
||||
<div className={styles.tableSection}>
|
||||
<StandardTable
|
||||
columns={columns}
|
||||
data={{
|
||||
list: getCurrentPageData(),
|
||||
pagination: {
|
||||
...pagination,
|
||||
total: dataSource.length,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
showSizeChanger: false,
|
||||
}
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
scroll={{ x: 'max-content' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 图片弹窗 */}
|
||||
<Modal
|
||||
open={isModalVisible}
|
||||
onCancel={() => setIsModalVisible(false)}
|
||||
footer={null}
|
||||
closeIcon={<CloseOutlined style={{ color: '#fff', fontSize: 20 }} />}
|
||||
width="auto"
|
||||
centered
|
||||
styles={{
|
||||
mask: { backgroundColor: '#10101080' },
|
||||
content: { padding: 0, background: 'transparent', boxShadow: 'none' }
|
||||
}}
|
||||
>
|
||||
{currentImage && <img src={currentImage} alt="许可证" style={{ width: '100%', display: 'block' }} />}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AlarmInformation;
|
||||
@ -0,0 +1,213 @@
|
||||
.wasteGasContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding: 20px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
.switchContainer {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background-color: #F4F4F4;
|
||||
border-radius: 6px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.searchSection {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.leftButtons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.addButton {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
color: white;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
}
|
||||
}
|
||||
|
||||
.importButton {
|
||||
background-color: white;
|
||||
border-color: #d9d9d9;
|
||||
color: #333;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rightControls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.filterLabel {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.queryButton {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
color: white;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
}
|
||||
}
|
||||
|
||||
.selectInput {
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 28px !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableSection {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 20px 0;
|
||||
overflow: hidden; // 只设置垂直隐藏
|
||||
min-width: 0; // 确保可以收缩
|
||||
|
||||
:global {
|
||||
.ant-spin-nested-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-spin-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-table-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table {
|
||||
font-size: 12px;
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background-color: #FAFAFA;
|
||||
font-weight: 400;
|
||||
color: #000000D9;
|
||||
border-right: none;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
border-right: none;
|
||||
color: #000000D9;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
// 固定列样式
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-left,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-left {
|
||||
// background-color: #FAFAFA;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-right,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-right {
|
||||
// background-color: #FAFAFA;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// 固定列阴影效果
|
||||
.ant-table-cell-fix-left {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
.ant-table-cell-fix-right {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
text-align: right;
|
||||
margin-top: 25px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,617 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker, Space, Modal, Select, Switch } from 'antd';
|
||||
import { SearchOutlined, RedoOutlined, CloseOutlined, EyeOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
import styles from './ExhaustEmissionStandard.less';
|
||||
|
||||
const ExhaustEmissionStandard = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [currentImage, setCurrentImage] = useState(null);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 12,
|
||||
});
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [dataSource, setDataSource] = useState([
|
||||
// 图片表格数据
|
||||
{
|
||||
key: 1,
|
||||
region: '2025-08-29',
|
||||
source: '赵喜行',
|
||||
outletName: '郑叶飞',
|
||||
outletNumber: '塞隆风湿酒(同仁堂)',
|
||||
monitorTime: '35.236.217.212',
|
||||
smokeHumidity: '6Dd888D-3d',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
region: '2025-09-02',
|
||||
source: '王嘉琪',
|
||||
outletName: '赵子峰',
|
||||
outletNumber: '复方水杨酸甲酯乳膏(曼秀雷敦)',
|
||||
monitorTime: '65.177.48.116',
|
||||
smokeHumidity: '3D8d4ffa-bD',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
region: '2025-09-06',
|
||||
source: '王嘉琪',
|
||||
outletName: '郑清予',
|
||||
outletNumber: '口炎清颗粒(大神)',
|
||||
monitorTime: '111.161.135.125',
|
||||
smokeHumidity: 'f9b89EB2-ae9',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
region: '2025-09-06',
|
||||
source: '王思琪',
|
||||
outletName: '赵玉',
|
||||
outletNumber: '烧结砖(茂祥)',
|
||||
monitorTime: '162.208.135.147',
|
||||
smokeHumidity: '0ca9DB56-DA',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
region: '2025-08-31',
|
||||
source: '吴子富',
|
||||
outletName: '钱茂莉',
|
||||
outletNumber: '云南白药(云南白药)',
|
||||
monitorTime: '138.6.246.181',
|
||||
smokeHumidity: 'bf0173D6-3cf',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
region: '2025-08-30',
|
||||
source: '何凤景',
|
||||
outletName: '赵海洲',
|
||||
outletNumber: '鹏程书局(修正)',
|
||||
monitorTime: '134.80.173.128',
|
||||
smokeHumidity: '55aACD54-69',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
region: '2025-08-29',
|
||||
source: '李计颖',
|
||||
outletName: '李海洲',
|
||||
outletNumber: '复方醋酸甲羟孕酮颗粒(妇复春)',
|
||||
monitorTime: '218.169.25.43',
|
||||
smokeHumidity: 'b0a849eD-9e',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
region: '2025-08-26',
|
||||
source: '赵年光',
|
||||
outletName: '钱海莉',
|
||||
outletNumber: '杜龙药酒',
|
||||
monitorTime: '54.218.80.84',
|
||||
smokeHumidity: 'b1D5cFbD-EA',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
region: '2025-08-21',
|
||||
source: '王凤妍',
|
||||
outletName: '李金泽',
|
||||
outletNumber: '和兴白花油(和兴白花油)',
|
||||
monitorTime: '222.1.18.173',
|
||||
smokeHumidity: 'fbc9cb69-F8B',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 10,
|
||||
region: '2025-09-09',
|
||||
source: '赵芳',
|
||||
outletName: '何能',
|
||||
outletNumber: '柔来期明含片(哈喽舒)',
|
||||
monitorTime: '136.200.182.22',
|
||||
smokeHumidity: 'e4b6adE6-8C1',
|
||||
smokeFlow: '重量',
|
||||
smokePressure: '2',
|
||||
o2Content: 't',
|
||||
o2Content2: 't',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 10,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 11,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 12,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵喜行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
equipmentModel: '6Ddb888D-3d7A-305E-3372-109F7154Ad3A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantFlueGasVolume: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
exhaustStackHeight: '2',
|
||||
exhaustTemperature: '50.48',
|
||||
pressure: '100',
|
||||
emissionTime: '115',
|
||||
powerConsumption: '39',
|
||||
byproductName: '氮气',
|
||||
byproductProduction: '2',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
]);
|
||||
|
||||
const getCurrentPageData = () => {
|
||||
const { current, pageSize } = pagination;
|
||||
const start = (current - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
return dataSource.slice(start, end);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedRowKeys.length === getCurrentPageData().length && getCurrentPageData().length > 0}
|
||||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
/>
|
||||
),
|
||||
key: 'selection',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
render: (_, record) => (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedRowKeys.includes(record.key)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedRowKeys([...selectedRowKeys, record.key]);
|
||||
} else {
|
||||
setSelectedRowKeys(selectedRowKeys.filter(key => key !== record.key));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{ title: '所属区县', dataIndex: 'region', key: 'region', align: 'left' },
|
||||
{ title: '污染源', dataIndex: 'source', key: 'source', align: 'left' },
|
||||
{ title: '排口名称', dataIndex: 'outletName', key: 'outletName', align: 'left' },
|
||||
{ title: '排口编号', dataIndex: 'outletNumber', key: 'outletNumber', align: 'left' },
|
||||
{ title: '监测时间', dataIndex: 'monitorTime', key: 'monitorTime', align: 'left' },
|
||||
{ title: '烟气湿度', dataIndex: 'smokeHumidity', key: 'smokeHumidity', align: 'left' },
|
||||
{ title: '烟气流速', dataIndex: 'smokeFlow', key: 'smokeFlow', align: 'left' },
|
||||
{ title: '烟气压力', dataIndex: 'smokePressure', key: 'smokePressure', align: 'left' },
|
||||
{ title: 'O₂含量', dataIndex: 'o2Content', key: 'o2Content', align: 'left' },
|
||||
{ title: 'O₂含量', dataIndex: 'o2Content2', key: 'o2Content2', align: 'left' },
|
||||
];
|
||||
|
||||
const handleSearch = (values) => {
|
||||
console.log('搜索参数:', values);
|
||||
// TODO: 实现搜索功能
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
form.resetFields();
|
||||
// TODO: 重置搜索
|
||||
};
|
||||
|
||||
const handleView = (record) => {
|
||||
console.log('查看:', record);
|
||||
// TODO: 实现查看功能
|
||||
};
|
||||
|
||||
const handleEdit = (record) => {
|
||||
console.log('编辑:', record);
|
||||
// TODO: 实现编辑功能
|
||||
};
|
||||
|
||||
const handleDownload = (record) => {
|
||||
console.log('下载:', record);
|
||||
// TODO: 实现下载功能
|
||||
};
|
||||
|
||||
const handleDelete = (record) => {
|
||||
console.log('删除:', record);
|
||||
// TODO: 实现删除功能
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
console.log('新增');
|
||||
// TODO: 实现新增功能
|
||||
};
|
||||
|
||||
const handleImport = () => {
|
||||
console.log('导入');
|
||||
// TODO: 实现导入功能
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
console.log('查询');
|
||||
// TODO: 实现查询功能
|
||||
};
|
||||
|
||||
const handleTableChange = (pagination) => {
|
||||
setPagination(pagination);
|
||||
};
|
||||
|
||||
// 全选功能
|
||||
const handleSelectAll = (checked) => {
|
||||
if (checked) {
|
||||
const allKeys = getCurrentPageData().map(item => item.key);
|
||||
setSelectedRowKeys(allKeys);
|
||||
} else {
|
||||
setSelectedRowKeys([]);
|
||||
}
|
||||
};
|
||||
|
||||
// 批量操作
|
||||
const handleBatchOperation = (operation) => {
|
||||
console.log(`批量${operation}:`, selectedRowKeys);
|
||||
// TODO: 实现批量操作功能
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.wasteGasContainer}>
|
||||
{/* 第一块:操作按钮和筛选条件 */}
|
||||
<div className={styles.searchSection}>
|
||||
<div className={styles.leftButtons}>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={handleAdd}
|
||||
className={styles.addButton}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
<Button
|
||||
// icon={<UploadOutlined />}
|
||||
onClick={handleImport}
|
||||
className={styles.importButton}
|
||||
>
|
||||
上传
|
||||
</Button>
|
||||
<Button
|
||||
// icon={<UploadOutlined />}
|
||||
onClick={() => handleBatchOperation('下载')}
|
||||
className={styles.importButton}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
>
|
||||
批量下载
|
||||
</Button>
|
||||
<div className={styles.switchContainer}>
|
||||
<span>仅显示异常信息</span>
|
||||
<Switch />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.rightControls}>
|
||||
<Select
|
||||
defaultValue={'1'}
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: 'xx监测点' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={'1'}
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: 'xx污染物' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={'1'}
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
options={
|
||||
[
|
||||
{ value: '1', label: '本月' },
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
onClick={handleQuery}
|
||||
className={styles.queryButton}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleReset}
|
||||
className={styles.resetButton}
|
||||
>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第二块:表格 */}
|
||||
<div className={styles.tableSection}>
|
||||
<StandardTable
|
||||
columns={columns}
|
||||
data={{
|
||||
list: getCurrentPageData(),
|
||||
pagination: {
|
||||
...pagination,
|
||||
total: dataSource.length,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
showSizeChanger: false,
|
||||
}
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
scroll={{ x: 'max-content' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 图片弹窗 */}
|
||||
<Modal
|
||||
open={isModalVisible}
|
||||
onCancel={() => setIsModalVisible(false)}
|
||||
footer={null}
|
||||
closeIcon={<CloseOutlined style={{ color: '#fff', fontSize: 20 }} />}
|
||||
width="auto"
|
||||
centered
|
||||
styles={{
|
||||
mask: { backgroundColor: '#10101080' },
|
||||
content: { padding: 0, background: 'transparent', boxShadow: 'none' }
|
||||
}}
|
||||
>
|
||||
{currentImage && <img src={currentImage} alt="许可证" style={{ width: '100%', display: 'block' }} />}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExhaustEmissionStandard;
|
||||
@ -0,0 +1,213 @@
|
||||
.wasteGasContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding: 20px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
.switchContainer {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background-color: #F4F4F4;
|
||||
border-radius: 6px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.searchSection {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.leftButtons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.addButton {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
color: white;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
}
|
||||
}
|
||||
|
||||
.importButton {
|
||||
background-color: white;
|
||||
border-color: #d9d9d9;
|
||||
color: #333;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rightControls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.filterLabel {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.queryButton {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
color: white;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #00D48A;
|
||||
border-color: #00D48A;
|
||||
}
|
||||
}
|
||||
|
||||
.selectInput {
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 28px !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableSection {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 20px 0;
|
||||
overflow: hidden; // 只设置垂直隐藏
|
||||
min-width: 0; // 确保可以收缩
|
||||
|
||||
:global {
|
||||
.ant-spin-nested-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-spin-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-table-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table {
|
||||
font-size: 12px;
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background-color: #FAFAFA;
|
||||
font-weight: 400;
|
||||
color: #000000D9;
|
||||
border-right: none;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
border-right: none;
|
||||
color: #000000D9;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
// 固定列样式
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-left,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-left {
|
||||
// background-color: #FAFAFA;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-right,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-right {
|
||||
// background-color: #FAFAFA;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// 固定列阴影效果
|
||||
.ant-table-cell-fix-left {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
.ant-table-cell-fix-right {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
text-align: right;
|
||||
margin-top: 25px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,746 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker, Space, Modal, Select } from 'antd';
|
||||
import { SearchOutlined, RedoOutlined, CloseOutlined, EyeOutlined, DeleteOutlined, PlusOutlined, UploadOutlined, EditOutlined, DownloadOutlined } from '@ant-design/icons';
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
import styles from './WastewaterFacilityManagement.less';
|
||||
import licence1 from '@/assets/business_envinformation/image1.svg';
|
||||
import licence2 from '@/assets/business_envinformation/image2.svg';
|
||||
import viewicon from '@/assets/business_envinformation/viewicon.svg';
|
||||
import editicon from '@/assets/business_envinformation/editicon.svg';
|
||||
import downloadicon from '@/assets/business_envinformation/downloadicon.svg';
|
||||
import deleteicon from '@/assets/business_envinformation/deleteicon.svg';
|
||||
|
||||
const WastewaterFacilityManagement = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [currentImage, setCurrentImage] = useState(null);
|
||||
const [pagination, setPagination] = useState({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 12,
|
||||
});
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [dataSource, setDataSource] = useState([
|
||||
{
|
||||
key: 1,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
recordTime: '2025-09-02',
|
||||
recorder: '王嘉祺',
|
||||
reviewer: '赵子峰',
|
||||
facilityName: '复方水杨酸甲酯乳膏(曼秀雷敦)',
|
||||
code: '65.177.48.116',
|
||||
facilityModel: '3D8d4ffa-bD7e-AffF-ED68-839DAFe74c27',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '14:10',
|
||||
endRunTime: '03:06',
|
||||
isNormal: '异常',
|
||||
pollutantOutletFlow: '2',
|
||||
pollutantFactor: '烟尘2',
|
||||
treatmentEfficiency: '93.81',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '59.12',
|
||||
treatmentMethod: '95',
|
||||
powerConsumption: '34',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-08-24 05:16',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
recordTime: '2025-09-06',
|
||||
recorder: '王嘉琪',
|
||||
reviewer: '郑清予',
|
||||
facilityName: '口炎清颗粒(大神)',
|
||||
code: '111.161.135.125',
|
||||
facilityModel: '19b89EB2-ae94-6bF7-2355-6DBC2d6a6009',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '12:26',
|
||||
endRunTime: '03:26',
|
||||
isNormal: '异常',
|
||||
pollutantOutletFlow: '2',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '91.40',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '59.95',
|
||||
treatmentMethod: '90',
|
||||
powerConsumption: '56',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-08-30 18:34',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 10,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 11,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
{
|
||||
key: 12,
|
||||
recordTime: '2025-08-29',
|
||||
recorder: '赵吾行',
|
||||
reviewer: '郑叶飞',
|
||||
facilityName: '塞隆风湿酒(同仁堂)',
|
||||
code: '35.236.217.212',
|
||||
facilityModel: '6Ddb888D-3d7A-3e5E-3372-109F7154A03A',
|
||||
parameterName: '重量',
|
||||
designValue: '2',
|
||||
unit: 't',
|
||||
startRunTime: '00:46',
|
||||
endRunTime: '03:55',
|
||||
isNormal: '正常',
|
||||
pollutantOutletFlow: '1',
|
||||
pollutantFactor: '烟尘',
|
||||
treatmentEfficiency: '95.32',
|
||||
dataSource: '实时采集',
|
||||
dischargeDestination: '2',
|
||||
sludgeProduction: '50.48',
|
||||
treatmentMethod: '100',
|
||||
powerConsumption: '39',
|
||||
reagentName: '乳酸钠葡萄糖',
|
||||
reagentAdditionTime: '2025-09-01 07:53',
|
||||
reagentAdditionAmount: '2',
|
||||
},
|
||||
]);
|
||||
|
||||
const getCurrentPageData = () => {
|
||||
const { current, pageSize } = pagination;
|
||||
const start = (current - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
return dataSource.slice(start, end);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedRowKeys.length === getCurrentPageData().length && getCurrentPageData().length > 0}
|
||||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
/>
|
||||
),
|
||||
key: 'selection',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
fixed: 'left',
|
||||
render: (_, record) => (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedRowKeys.includes(record.key)}
|
||||
onChange={(e) => {
|
||||
if (e.target.checked) {
|
||||
setSelectedRowKeys([...selectedRowKeys, record.key]);
|
||||
} else {
|
||||
setSelectedRowKeys(selectedRowKeys.filter(key => key !== record.key));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '记录时间',
|
||||
dataIndex: 'recordTime',
|
||||
key: 'recordTime',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '记录人',
|
||||
dataIndex: 'recorder',
|
||||
key: 'recorder',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '审核人',
|
||||
dataIndex: 'reviewer',
|
||||
key: 'reviewer',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '设施名称',
|
||||
dataIndex: 'facilityName',
|
||||
key: 'facilityName',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '编码',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '设施型号',
|
||||
dataIndex: 'facilityModel',
|
||||
key: 'facilityModel',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '参数名称',
|
||||
dataIndex: 'parameterName',
|
||||
key: 'parameterName',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '设计值',
|
||||
dataIndex: 'designValue',
|
||||
key: 'designValue',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '开始运行时间',
|
||||
dataIndex: 'startRunTime',
|
||||
key: 'startRunTime',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '结束运行时间',
|
||||
dataIndex: 'endRunTime',
|
||||
key: 'endRunTime',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '是否正常',
|
||||
dataIndex: 'isNormal',
|
||||
key: 'isNormal',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (text) => (
|
||||
<span style={{
|
||||
color: text === '异常' ? '#ff4d4f' : '#52c41a',
|
||||
backgroundColor: text === '异常' ? '#FFF1F0' : '#F6FFED',
|
||||
border: text === '异常' ? '1px solid #FFA39E' : '1px solid #B7EB8F',
|
||||
padding: '2px 8px',
|
||||
borderRadius: '4px',
|
||||
display: 'inline-block'
|
||||
}}>
|
||||
{text}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '污染物出口流量(m³/h)',
|
||||
dataIndex: 'pollutantOutletFlow',
|
||||
key: 'pollutantOutletFlow',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '污染因子',
|
||||
dataIndex: 'pollutantFactor',
|
||||
key: 'pollutantFactor',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '治理效率(%)',
|
||||
dataIndex: 'treatmentEfficiency',
|
||||
key: 'treatmentEfficiency',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '数据来源',
|
||||
dataIndex: 'dataSource',
|
||||
key: 'dataSource',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '排放去向',
|
||||
dataIndex: 'dischargeDestination',
|
||||
key: 'dischargeDestination',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '污泥产生量(t)',
|
||||
dataIndex: 'sludgeProduction',
|
||||
key: 'sludgeProduction',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '处理方式',
|
||||
dataIndex: 'treatmentMethod',
|
||||
key: 'treatmentMethod',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '耗电量(kWh)',
|
||||
dataIndex: 'powerConsumption',
|
||||
key: 'powerConsumption',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '药剂名称',
|
||||
dataIndex: 'reagentName',
|
||||
key: 'reagentName',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '药剂添加时间',
|
||||
dataIndex: 'reagentAdditionTime',
|
||||
key: 'reagentAdditionTime',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '药剂添加量(t)',
|
||||
dataIndex: 'reagentAdditionAmount',
|
||||
key: 'reagentAdditionAmount',
|
||||
width: 140,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 140,
|
||||
align: 'center',
|
||||
fixed: 'right',
|
||||
render: (_, record) => (
|
||||
<Space size={18}>
|
||||
{/* <img
|
||||
src={viewicon}
|
||||
alt="查看"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
onClick={() => handleView(record)}
|
||||
/> */}
|
||||
<img
|
||||
src={editicon}
|
||||
alt="编辑"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
onClick={() => handleEdit(record)}
|
||||
/>
|
||||
<img
|
||||
src={downloadicon}
|
||||
alt="下载"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
onClick={() => handleDownload(record)}
|
||||
/>
|
||||
<img
|
||||
src={deleteicon}
|
||||
alt="删除"
|
||||
style={{ width: 16, height: 16, cursor: 'pointer' }}
|
||||
onClick={() => handleDelete(record)}
|
||||
/>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handleSearch = (values) => {
|
||||
console.log('搜索参数:', values);
|
||||
// TODO: 实现搜索功能
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
form.resetFields();
|
||||
// TODO: 重置搜索
|
||||
};
|
||||
|
||||
const handleView = (record) => {
|
||||
console.log('查看:', record);
|
||||
// TODO: 实现查看功能
|
||||
};
|
||||
|
||||
const handleEdit = (record) => {
|
||||
console.log('编辑:', record);
|
||||
// TODO: 实现编辑功能
|
||||
};
|
||||
|
||||
const handleDownload = (record) => {
|
||||
console.log('下载:', record);
|
||||
// TODO: 实现下载功能
|
||||
};
|
||||
|
||||
const handleDelete = (record) => {
|
||||
console.log('删除:', record);
|
||||
// TODO: 实现删除功能
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
console.log('新增');
|
||||
// TODO: 实现新增功能
|
||||
};
|
||||
|
||||
const handleImport = () => {
|
||||
console.log('导入');
|
||||
// TODO: 实现导入功能
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
console.log('查询');
|
||||
// TODO: 实现查询功能
|
||||
};
|
||||
|
||||
const handleTableChange = (pagination) => {
|
||||
setPagination(pagination);
|
||||
};
|
||||
|
||||
// 全选功能
|
||||
const handleSelectAll = (checked) => {
|
||||
if (checked) {
|
||||
const allKeys = getCurrentPageData().map(item => item.key);
|
||||
setSelectedRowKeys(allKeys);
|
||||
} else {
|
||||
setSelectedRowKeys([]);
|
||||
}
|
||||
};
|
||||
|
||||
// 批量操作
|
||||
const handleBatchOperation = (operation) => {
|
||||
console.log(`批量${operation}:`, selectedRowKeys);
|
||||
// TODO: 实现批量操作功能
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.wastewaterFacilityContainer}>
|
||||
{/* 第一块:操作按钮和筛选条件 */}
|
||||
<div className={styles.searchSection}>
|
||||
<div className={styles.leftButtons}>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={handleAdd}
|
||||
className={styles.addButton}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
<Button
|
||||
// icon={<UploadOutlined />}
|
||||
onClick={handleImport}
|
||||
className={styles.importButton}
|
||||
>
|
||||
上传
|
||||
</Button>
|
||||
<Button
|
||||
// icon={<UploadOutlined />}
|
||||
onClick={() => handleBatchOperation('下载')}
|
||||
className={styles.importButton}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
>
|
||||
批量下载
|
||||
</Button>
|
||||
{/* <Button
|
||||
onClick={() => handleBatchOperation('删除')}
|
||||
className={styles.importButton}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
>
|
||||
批量删除
|
||||
</Button> */}
|
||||
</div>
|
||||
|
||||
<div className={styles.rightControls}>
|
||||
<span className={styles.filterLabel}>筛选条件</span>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
style={{ width: 140, height: 28 }}
|
||||
allowClear
|
||||
className={styles.selectInput}
|
||||
/>
|
||||
|
||||
<Input
|
||||
placeholder="请输入"
|
||||
style={{ width: 160, height: 28 }}
|
||||
/>
|
||||
<Button
|
||||
onClick={handleQuery}
|
||||
className={styles.queryButton}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleReset}
|
||||
className={styles.resetButton}
|
||||
>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第二块:表格 */}
|
||||
<div className={styles.tableSection}>
|
||||
<StandardTable
|
||||
columns={columns}
|
||||
data={{
|
||||
list: getCurrentPageData(),
|
||||
pagination: {
|
||||
...pagination,
|
||||
total: dataSource.length,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
showSizeChanger: false,
|
||||
}
|
||||
}}
|
||||
onChange={handleTableChange}
|
||||
scroll={{ x: 3000 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 图片弹窗 */}
|
||||
<Modal
|
||||
open={isModalVisible}
|
||||
onCancel={() => setIsModalVisible(false)}
|
||||
footer={null}
|
||||
closeIcon={<CloseOutlined style={{ color: '#fff', fontSize: 20 }} />}
|
||||
width="auto"
|
||||
centered
|
||||
styles={{
|
||||
mask: { backgroundColor: '#10101080' },
|
||||
content: { padding: 0, background: 'transparent', boxShadow: 'none' }
|
||||
}}
|
||||
>
|
||||
{currentImage && <img src={currentImage} alt="许可证" style={{ width: '100%', display: 'block' }} />}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WastewaterFacilityManagement;
|
||||
@ -0,0 +1,206 @@
|
||||
.wastewaterFacilityContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding: 20px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.searchSection {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.leftButtons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.addButton {
|
||||
background-color: #52c41a;
|
||||
border-color: #52c41a;
|
||||
color: white;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: #73d13d;
|
||||
border-color: #73d13d;
|
||||
}
|
||||
}
|
||||
|
||||
.importButton {
|
||||
background-color: white;
|
||||
border-color: #d9d9d9;
|
||||
color: #333;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rightControls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.filterLabel {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.queryButton {
|
||||
background-color: #52c41a;
|
||||
border-color: #52c41a;
|
||||
color: white;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
background-color: #73d13d;
|
||||
border-color: #73d13d;
|
||||
}
|
||||
}
|
||||
|
||||
.selectInput {
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 28px !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableSection {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 20px 0;
|
||||
overflow: hidden; // 只设置垂直隐藏
|
||||
min-width: 0; // 确保可以收缩
|
||||
|
||||
|
||||
:global {
|
||||
.ant-spin-nested-loading {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-spin-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.ant-table-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table {
|
||||
font-size: 12px;
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background-color: #fafafa;
|
||||
font-weight: 400;
|
||||
color: #000000D9;
|
||||
border-right: none;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
border-right: none;
|
||||
color: #000000D9;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
white-space: nowrap; // 防止换行
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
// 固定列样式
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-left,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-left {
|
||||
background-color: #fafafa;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th.ant-table-cell-fix-right,
|
||||
.ant-table-tbody > tr > td.ant-table-cell-fix-right {
|
||||
background-color: #fafafa;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// 固定列阴影效果
|
||||
.ant-table-cell-fix-left {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
.ant-table-cell-fix-right {
|
||||
// box-shadow: 0px 0 4px 0px #00000040;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
text-align: right;
|
||||
margin-top: 25px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue