Merge remote-tracking branch 'origin/main' into main

main
jiangxucong 6 days ago
commit c328ead387

@ -0,0 +1,4 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.57031 8.06346C6.57031 8.02513 6.58554 7.98837 6.61264 7.96127C6.63974 7.93417 6.6765 7.91895 6.71483 7.91895H7.87096C7.90928 7.91895 7.94604 7.93417 7.97314 7.96127C8.00025 7.98837 8.01547 8.02513 8.01547 8.06346V12.3989C8.01547 12.4373 8.00025 12.474 7.97314 12.5011C7.94604 12.5282 7.90928 12.5435 7.87096 12.5435H6.71483C6.6765 12.5435 6.63974 12.5282 6.61264 12.5011C6.58554 12.474 6.57031 12.4373 6.57031 12.3989V8.06346ZM11.3393 8.06346C11.3393 8.02513 11.3241 7.98837 11.297 7.96127C11.2699 7.93417 11.2332 7.91895 11.1948 7.91895H10.0387C10.0004 7.91895 9.96361 7.93417 9.93651 7.96127C9.90941 7.98837 9.89418 8.02513 9.89418 8.06346V12.3989C9.89418 12.4373 9.90941 12.474 9.93651 12.5011C9.96361 12.5282 10.0004 12.5435 10.0387 12.5435H11.1948C11.2332 12.5435 11.2699 12.5282 11.297 12.5011C11.3241 12.474 11.3393 12.4373 11.3393 12.3989V8.06346Z" fill="#FF2526"/>
<path d="M5.50451 3.67355V1.57806C5.50451 1.25881 5.76332 1 6.08258 1H11.8632C12.1825 1 12.4413 1.25881 12.4413 1.57806V3.67355H15.7471C15.7854 3.67355 15.8222 3.68877 15.8493 3.71587C15.8764 3.74298 15.8916 3.77973 15.8916 3.81806V4.97419C15.8916 5.01252 15.8764 5.04928 15.8493 5.07638C15.8222 5.10348 15.7854 5.11871 15.7471 5.11871H14.7535V16.5897C14.7535 16.9089 14.4947 17.1677 14.1755 17.1677H3.77032C3.45107 17.1677 3.19226 16.9089 3.19226 16.5897V5.11871H2.14452C2.10619 5.11871 2.06943 5.10348 2.04233 5.07638C2.01523 5.04928 2 5.01252 2 4.97419V3.81806C2 3.77973 2.01523 3.74298 2.04233 3.71587C2.06943 3.68877 2.10619 3.67355 2.14452 3.67355H5.50451ZM6.94967 2.44516V3.67355H10.9961V2.44516H6.94967ZM4.63742 5.11871V15.7226H13.3084V5.11871H4.63742Z" fill="#FF2526"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -1,12 +1,6 @@
import React, { useState } from 'react';
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
import styles from './EmergencyResource.less';
import ComplianceManagement from './components/ComplianceManagement'; //合规性管理
import OnlineMonitoring from './components/OnlineMonitoring'; //在线监测预警
import EnvironmentalPersonnelManagement from './components/EnvironmentalPersonnelManagement'; //环保人员管理
import EvaluationReport from './components/EvaluationReport'; //评估报告
import EquipmentManagement from './components/EquipmentManagement'; //环保设备设施管理
import PollutionSourceManagement from './components/PollutionSourceManagement'; //污染源管理
import EmergencyMap from './components/EmergencyMap'; //应急一张图
import EmergencyResource from './components/EmergencyResource'; //应急资源
import EmergencyRescue from './components/EmergencyRescue'; //应急处置救援
@ -14,7 +8,7 @@ import EmergencyRescue from './components/EmergencyRescue'; //应急处置救援
const SafeMajorHazardList = () => {
const [activeModule, setActiveModule] = useState('organization');
const [activeModule, setActiveModule] = useState('emergencyMap');
const handleModuleClick = (module) => {
setActiveModule(module)
@ -23,18 +17,6 @@ const SafeMajorHazardList = () => {
const renderModule = () => {
switch (activeModule) {
case 'organization':
return <ComplianceManagement />;
case 'equipment':
return <OnlineMonitoring />;
case 'firefighting':
return <EnvironmentalPersonnelManagement />;
case 'other':
return <EvaluationReport />;
case 'equipmentManagement':
return <EquipmentManagement />;
case 'pollutionSource':
return <PollutionSourceManagement />;
case 'emergencyMap':
return <EmergencyMap />;
case 'emergencyResource':
@ -42,7 +24,7 @@ const SafeMajorHazardList = () => {
case 'emergencyRescue':
return <EmergencyRescue />;
default:
return <ComplianceManagement />;
return <EmergencyMap />;
}
};
@ -50,31 +32,6 @@ const SafeMajorHazardList = () => {
return (
<div className={styles.container}>
<div className={styles.TopButton}>
<Button
className={`${styles.TopButtonItem} ${activeModule === "organization" ? styles.active : ""}`}
onClick={() => handleModuleClick("organization")}
>合规性管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "firefighting" ? styles.active : ""}`}
onClick={() => handleModuleClick("firefighting")}
>环保人员管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "other" ? styles.active : ""}`}
onClick={() => handleModuleClick("other")}
>排污许可管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "equipmentManagement" ? styles.active : ""}`}
onClick={() => handleModuleClick("equipmentManagement")}
>环保设备设施管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "pollutionSource" ? styles.active : ""}`}
onClick={() => handleModuleClick("pollutionSource")}
>污染源管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "emergencyMap" ? styles.active : ""}`}
onClick={() => handleModuleClick("emergencyMap")}

@ -67,5 +67,6 @@
flex: 1; // ======== 占据剩余空间 ========
overflow-y: auto; // ======== 允许垂直滚动 ========
padding: 0; // ======== 无内边距 ========
}
}

@ -1,513 +0,0 @@
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 './AtmospherePollutantLibrary.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';
import icon_add from '@/assets/business_envinformation/icon_add.svg';
const AtmospherePollutantLibrary = () => {
const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false);
const [currentImage, setCurrentImage] = useState(null);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 19,
});
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [dataSource, setDataSource] = useState([
{
key: 1,
serialNumber: 1,
pollutantName: '对乙酰氨基酚栓',
category: 25,
mainFeatures: '在接受调查的19为华尔街分析师...',
monitoringPoint: 1.25,
emittingEnterprise: '每日协通(北京)咨询有限公司',
monthlyEmission: 4.6,
quarterlyEmission: 4.6,
yearlyEmission: 5.0,
},
{
key: 2,
serialNumber: 2,
pollutantName: '萘普生缓释胶囊(适洛特)',
category: 27,
mainFeatures: '热到融化的马路、无穷无尽的野火...',
monitoringPoint: 1.25,
emittingEnterprise: '赢王科技有限公司',
monthlyEmission: 1.1,
quarterlyEmission: 1.1,
yearlyEmission: 1.8,
},
{
key: 3,
serialNumber: 3,
pollutantName: '复方感冒灵片',
category: 44,
mainFeatures: '从病虫害探测、土壤墒情监测智能...',
monitoringPoint: 1.25,
emittingEnterprise: '北京福商商务服务有限公司',
monthlyEmission: 2.4,
quarterlyEmission: 2.4,
yearlyEmission: 5.0,
},
{
key: 4,
serialNumber: 4,
pollutantName: '红药片',
category: 21,
mainFeatures: '近日,有科普博主发帖称,某社交...',
monitoringPoint: 1.25,
emittingEnterprise: '实华国际租赁有限公司',
monthlyEmission: 3.6,
quarterlyEmission: 3.6,
yearlyEmission: 4.7,
},
{
key: 5,
serialNumber: 5,
pollutantName: '布洛芬混悬液(翔宇赛可)',
category: 56,
mainFeatures: '在七八十年代,这种面料做成的服...',
monitoringPoint: 1.25,
emittingEnterprise: '北京冠钧财经策划有限公司',
monthlyEmission: 3.0,
quarterlyEmission: 3.0,
yearlyEmission: 4.7,
},
{
key: 6,
serialNumber: 6,
pollutantName: '阿莫西林胶囊',
category: 32,
mainFeatures: '抗生素类药物,用于治疗细菌感染...',
monitoringPoint: 1.15,
emittingEnterprise: '华北制药集团有限责任公司',
monthlyEmission: 2.8,
quarterlyEmission: 2.8,
yearlyEmission: 3.5,
},
{
key: 7,
serialNumber: 7,
pollutantName: '头孢拉定胶囊',
category: 28,
mainFeatures: '头孢类抗生素,广谱抗菌药物...',
monitoringPoint: 1.30,
emittingEnterprise: '石药集团欧意药业有限公司',
monthlyEmission: 1.9,
quarterlyEmission: 1.9,
yearlyEmission: 2.3,
},
{
key: 8,
serialNumber: 8,
pollutantName: '复方甘草片',
category: 35,
mainFeatures: '镇咳祛痰药物,含有甘草提取物...',
monitoringPoint: 1.20,
emittingEnterprise: '太极集团重庆桐君阁药厂有限公司',
monthlyEmission: 3.2,
quarterlyEmission: 3.2,
yearlyEmission: 4.1,
},
{
key: 9,
serialNumber: 9,
pollutantName: '板蓝根颗粒',
category: 41,
mainFeatures: '清热解毒,凉血利咽的中成药...',
monitoringPoint: 1.10,
emittingEnterprise: '广州白云山和记黄埔中药有限公司',
monthlyEmission: 4.5,
quarterlyEmission: 4.5,
yearlyEmission: 5.8,
},
{
key: 10,
serialNumber: 10,
pollutantName: '维生素C片',
category: 22,
mainFeatures: '补充维生素C增强免疫力...',
monitoringPoint: 1.35,
emittingEnterprise: '华润三九医药股份有限公司',
monthlyEmission: 2.1,
quarterlyEmission: 2.1,
yearlyEmission: 2.7,
},
{
key: 11,
serialNumber: 11,
pollutantName: '感冒清热颗粒',
category: 38,
mainFeatures: '疏风散寒,解表清热的中成药...',
monitoringPoint: 1.25,
emittingEnterprise: '北京同仁堂股份有限公司',
monthlyEmission: 3.7,
quarterlyEmission: 3.7,
yearlyEmission: 4.9,
},
{
key: 12,
serialNumber: 12,
pollutantName: '双氯芬酸钠缓释片',
category: 29,
mainFeatures: '非甾体抗炎药,用于缓解疼痛...',
monitoringPoint: 1.18,
emittingEnterprise: '扬子江药业集团有限公司',
monthlyEmission: 1.6,
quarterlyEmission: 1.6,
yearlyEmission: 2.0,
},
{
key: 13,
serialNumber: 13,
pollutantName: '藿香正气水',
category: 43,
mainFeatures: '解表化湿,理气和中的中成药...',
monitoringPoint: 1.22,
emittingEnterprise: '云南白药集团股份有限公司',
monthlyEmission: 2.9,
quarterlyEmission: 2.9,
yearlyEmission: 3.8,
},
{
key: 14,
serialNumber: 14,
pollutantName: '蒙脱石散',
category: 26,
mainFeatures: '止泻药物,保护胃肠黏膜...',
monitoringPoint: 1.28,
emittingEnterprise: '博福-益普生制药有限公司',
monthlyEmission: 1.4,
quarterlyEmission: 1.4,
yearlyEmission: 1.9,
},
{
key: 15,
serialNumber: 15,
pollutantName: '复方丹参片',
category: 37,
mainFeatures: '活血化瘀,理气止痛的中成药...',
monitoringPoint: 1.16,
emittingEnterprise: '天津中新药业集团股份有限公司',
monthlyEmission: 3.3,
quarterlyEmission: 3.3,
yearlyEmission: 4.2,
},
{
key: 16,
serialNumber: 16,
pollutantName: '奥美拉唑肠溶胶囊',
category: 31,
mainFeatures: '质子泵抑制剂,治疗胃溃疡...',
monitoringPoint: 1.33,
emittingEnterprise: '阿斯利康制药有限公司',
monthlyEmission: 2.2,
quarterlyEmission: 2.2,
yearlyEmission: 2.8,
},
{
key: 17,
serialNumber: 17,
pollutantName: '六味地黄丸',
category: 45,
mainFeatures: '滋阴补肾的经典中成药...',
monitoringPoint: 1.12,
emittingEnterprise: '仲景宛西制药股份有限公司',
monthlyEmission: 4.1,
quarterlyEmission: 4.1,
yearlyEmission: 5.3,
},
{
key: 18,
serialNumber: 18,
pollutantName: '阿司匹林肠溶片',
category: 24,
mainFeatures: '解热镇痛抗炎药,预防血栓...',
monitoringPoint: 1.27,
emittingEnterprise: '拜耳医药保健有限公司',
monthlyEmission: 1.8,
quarterlyEmission: 1.8,
yearlyEmission: 2.4,
},
{
key: 19,
serialNumber: 19,
pollutantName: '复方黄连素片',
category: 39,
mainFeatures: '清热燥湿,行气止痛的中成药...',
monitoringPoint: 1.21,
emittingEnterprise: '哈药集团三精制药有限公司',
monthlyEmission: 2.6,
quarterlyEmission: 2.6,
yearlyEmission: 3.4,
},
]);
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: 'serialNumber',
key: 'serialNumber',
width: 80,
align: 'center',
},
{
title: '特征污染物名称',
dataIndex: 'pollutantName',
key: 'pollutantName',
width: 200,
align: 'center',
},
{
title: '种类',
dataIndex: 'category',
key: 'category',
width: 100,
align: 'center',
},
{
title: '主要特征',
dataIndex: 'mainFeatures',
key: 'mainFeatures',
width: 300,
},
{
title: '环境监测点',
dataIndex: 'monitoringPoint',
key: 'monitoringPoint',
width: 120,
align: 'center',
},
{
title: '排放企业',
dataIndex: 'emittingEnterprise',
key: 'emittingEnterprise',
width: 200,
},
{
title: '本月排放量',
dataIndex: 'monthlyEmission',
key: 'monthlyEmission',
width: 120,
align: 'center',
},
{
title: '本季度排放量',
dataIndex: 'quarterlyEmission',
key: 'quarterlyEmission',
width: 130,
align: 'center',
},
{
title: '本年度排放量',
dataIndex: 'yearlyEmission',
key: 'yearlyEmission',
width: 130,
align: 'center',
},
{
title: '操作',
key: 'action',
width: 140,
align: 'center',
fixed: 'right',
render: (_, record) => (
<Space size={18}>
{/* <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.atmospherePollutantLibrary}>
{/* 页面头部 */}
<div className={styles.pageHeader}>
大气污染特征污染物名录库
</div>
{/* 第一块:操作按钮和筛选条件 */}
<div className={styles.searchSection}>
<div className={styles.leftButtons}>
<Button
type="primary"
onClick={handleAdd}
className={styles.addButton}
>
<img
src={icon_add}
alt="新增"
style={{ width: 16, height: 16, marginRight: 0 }}
/>
新增
</Button>
<Button
onClick={handleImport}
className={styles.importButton}
>
批量导出
</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 AtmospherePollutantLibrary;

@ -1,218 +0,0 @@
.atmospherePollutantLibrary {
width: 100%;
height: 100%;
// padding: 20px;
// background-color: #fff;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
.pageHeader {
margin-bottom: 15px;
background: #fff;
padding: 15px 15px 15px 20px;
border-radius: 2px;
color: #333333;
font-size: 16px;
font-weight: 500;
}
.searchSection {
background: #fff;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
.leftButtons {
display: flex;
gap: 12px;
.addButton {
background-color: #00D48A;
color: #fff;
height: 28px;
border-radius: 4px;
display: flex;
align-items: center;
gap: 4px;
&:hover {
background-color: #00D48A;
border-color: #00D48A;
}
}
.importButton {
display: flex;
align-items: center;
background-color: #fff;
border-color: #D7D7D7;
color: #333;
height: 28px;
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 25px 0;
background-color: #fff;
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: 70px !important;
}
}
}
}

@ -1,62 +0,0 @@
import React, { useState } from 'react';
import styles from './ComplianceManagement.less';
import PermitManagement from './secondary_menu/PermitManagement'; // 排污许可
import RegulationCompliance from './secondary_menu/RegulationCompliance'; // 法规符合性
import SupervisionInspection from './secondary_menu/SupervisionInspection'; // 监督检查
import InformationDisclosure from './secondary_menu/InformationDisclosure'; // 信息公开及绿色通道
const ComplianceManagement = () => {
const [activeMenu, setActiveMenu] = useState('permit');
const menuItems = [
{ key: 'permit', label: '排污许可' },
{ key: 'regulation', label: '法规符合性' },
{ key: 'inspection', label: '监督检查' },
{ key: 'disclosure', label: '信息公开及绿色通道' }
];
const handleMenuClick = (key) => {
setActiveMenu(key);
};
const renderContent = () => {
switch (activeMenu) {
case 'permit':
return <PermitManagement />;
case 'regulation':
return <RegulationCompliance />;
case 'inspection':
return <SupervisionInspection />;
case 'disclosure':
return <InformationDisclosure />;
default:
return <PermitManagement />;
}
};
return (
<div className={styles.container}>
{/* 左侧菜单 */}
<div className={styles.leftMenu}>
{menuItems.map(item => (
<div
key={item.key}
className={`${styles.menuItem} ${activeMenu === item.key ? styles.active : ''}`}
onClick={() => handleMenuClick(item.key)}
>
{activeMenu === item.key && <div className={styles.activeIndicator}></div>}
<span className={styles.menuText}>{item.label}</span>
</div>
))}
</div>
{/* 右侧内容区 */}
<div className={styles.rightContent}>
{renderContent()}
</div>
</div>
);
};
export default ComplianceManagement;

@ -1,85 +0,0 @@
.container {
width: 100%;
height: 100%;
display: flex;
gap: 10px;
padding-left: 5px;
// padding-right: 5px;
padding-top: 10px;
padding-bottom: 10px;
background-color: #f5f5f5;
// 左侧菜单
.leftMenu {
display: flex;
flex-direction: column;
// gap: 1px;
flex-shrink: 0;
background-color: #fff;
.menuItem {
width: 180px;
height: 50px;
background-color: #FFFFFF;
border-radius: 4px;
display: flex;
align-items: center;
position: relative;
cursor: pointer;
transition: all 0.3s ease;
padding-left: 20px;
.menuText {
font-size: 14px;
color: #999999;
font-weight: 400;
transition: color 0.3s ease;
}
// 激活状态的指示器(左侧长条)
.activeIndicator {
position: absolute;
left: 3px;
width: 17.34765625px;
height: 1.97802734375px;
border-radius: 6px;
background-color: #009D6F;
transform: rotate(-90deg);
}
// 激活状态样式
&.active {
background-color: #D4FFEC;
.menuText {
color: #009D6F;
}
}
// 鼠标悬停效果
&:hover:not(.active) {
background-color: #f9f9f9;
}
}
}
// 右侧内容区
.rightContent {
flex: 1;
// background-color: #FFFFFF;
border-radius: 4px;
// padding: 20px;
overflow: auto;
.contentPlaceholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: #666666;
}
}
}

@ -39,4 +39,6 @@
.contentArea {
flex: 1;
background-color: #EBF0FE;
margin-left: 5px;
// margin-top: 10px;
}

@ -1,536 +0,0 @@
// 表单输入框样式
.formInput {
:global(.ant-input) {
color: #333333 !important;
font-size: 12px !important;
}
:global(.ant-select-selector) {
color: #333333 !important;
font-size: 12px !important;
}
:global(.ant-picker-input input) {
color: #333333 !important;
font-size: 12px !important;
}
}
.Rcontainer {
padding: 8px 6px 0px 6px;
height: 100%;
display: flex;
flex-direction: column;
gap: 10px;
// 第一个div - 高度20%
.RcontainerTop {
height: 18%;
// background-color: #fff;
border-radius: 4px;
display: flex;
flex-direction: column;
.sectionContent {
height: 100%;
display: flex;
flex-direction: column;
// padding: 15px;
.blocksContainer {
flex: 1;
display: flex;
gap: 10px;
height: 100%;
.blockItem {
flex: 1;
height: 100%;
display: flex;
// background: linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
border-radius: 4px;
// border: 2px solid #FFFFFF;
// 块1 - 蓝色渐变 + SVG背景
&.block1 {
background:
url('@/assets/business_envinformation/background1.svg'),
linear-gradient(180deg, #DBEBFF 0%, #DBEBFF 12.5%, rgba(255, 255, 255, 0.700824) 56%, rgba(255, 255, 255, 0.01) 100%),
linear-gradient(0deg, #FFFFFF, #FFFFFF);
// linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2));
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
// 块2 - 黄色渐变
&.block2 {
background:
url('@/assets/business_envinformation/background2.svg'),
linear-gradient(180deg, #FFFEDB 0%, #F5FFDB 19.23%, #FFFFFF 55.77%, #FFFFFF 100%);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
// 块3 - 绿色渐变
&.block3 {
background:
url('@/assets/business_envinformation/background3.svg'),
linear-gradient(180deg, #8CFFCD 0%, #C0FFE4 12.5%, #FFFFFF 56%, #FFFFFF 100%);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
// 块4 - 青色渐变
&.block4 {
background:
url('@/assets/business_envinformation/background4.svg'),
linear-gradient(180deg, #C5FFFC 0%, #C0FFFC 12.5%, #FFFFFF 56%, #FFFFFF 100%);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
// 块5 - 红色渐变
&.block5 {
background:
url('@/assets/business_envinformation/background5.svg'),
linear-gradient(180deg, #FFD2D2 0%, #FFD9D9 12.5%, #FFFFFF 56%, #FFFFFF 100%);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
// 块6 - 紫色渐变
&.block6 {
background:
url('@/assets/business_envinformation/background6.svg'),
linear-gradient(180deg, #F2D7FF 0%, #F4DDFF 12.5%, #FFFFFF 56%, #FFFFFF 100%);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
}
.blockLeft {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding: 15px;
padding-left: 20px;
gap: 8px;
.blockTitle {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #333333;
line-height: 1.2;
}
.blockNumber {
font-family: PingFang SC;
font-weight: 700;
font-size: 24px;
color: #333333;
line-height: 1.2;
// 特定数字颜色
&.number258 {
color: #0080FF;
}
&.number58 {
color: #EFB700;
}
&.number51 {
color: #00DA86;
}
&.number28 {
color: #00DA86;
}
&.number50 {
color: #FD0404;
}
&.number58Second {
color: #A318E4;
}
}
.blockTime {
font-family: PingFang SC;
font-weight: 400;
font-size: 10px;
color: #999999;
line-height: 1.2;
}
.blockChange {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #1269FF;
line-height: 1.2;
display: flex;
align-items: center;
gap: 4px;
.arrow {
font-size: 14px;
font-weight: bold;
}
.checkIcon {
font-size: 16px;
color: #1269FF;
}
}
}
.blockRight {
flex: 1;
height: 100%;
background-color: transparent;
border-radius: 0 4px 4px 0;
display: flex;
align-items: center;
justify-content: center;
.blockImage {
// width: 80%;
height: 65%;
// height: 80%;
object-fit: contain;
margin-right: -5px;
}
}
}
}
}
}
// 第三个div - 占满剩余位置
.RcontainerBottom {
flex: 1; // 占满剩余空间
display: flex;
flex-direction: column;
background-color: #fff;
padding: 15px;
.sectionContent {
height: 100%;
display: flex;
flex-direction: column;
gap: 15px;
// 第一行 - 表单控件
.formRow {
display: flex;
align-items: center;
gap: 15px;
flex-shrink: 0;
.addButton {
display: flex;
align-items: center;
gap: 4px;
height: 28px;
border: 1px solid #00D48A;
border-radius: 2px;
color: #fff;
font-weight: 400;
font-size: 12px;
padding: 0 10px;
background: #00D48A;
cursor: pointer;
transition: all 0.2s ease;
&:hover {
background-color: #00B875;
border-color: #00B875;
}
.buttonIcon {
font-size: 16px;
font-weight: bold;
}
}
.rightControls {
display: flex;
align-items: center;
gap: 15px;
margin-left: auto;
.filterLabel {
font-size: 13px;
color: #333333;
white-space: nowrap;
}
// Select组件样式
:global(.ant-select) {
font-size: 12px;
height: 28px !important;
}
:global(.ant-select .ant-select-selector) {
height: 28px !important;
font-size: 12px;
border-radius: 2px !important;
display: flex !important;
align-items: center !important;
padding: 0 11px !important;
}
:global(.ant-select .ant-select-selection-item) {
line-height: 1.5714285714285714;
font-size: 12px;
}
:global(.ant-select .ant-select-selection-placeholder) {
line-height: 1.5714285714285714;
font-size: 12px;
color: #00000040 !important;
}
.searchInput {
width: 150px;
height: 28px;
border: 1px solid #d9d9d9;
border-radius: 2px;
padding: 0 12px;
font-size: 12px;
&:focus {
border-color: #2E4CD4;
outline: none;
}
&::placeholder {
color: #00000040;
}
}
.queryButton, .resetButton {
height: 28px;
border: 1px solid #d9d9d9;
border-radius: 4px;
padding: 0 16px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s ease;
&:hover {
border-color: #2E4CD4;
color: #2E4CD4;
}
}
.queryButton {
background-color: #00D48A;
color: #fff;
border-color: #00D48A;
&:hover {
background-color: #00B875;
border-color: #00B875;
color: #fff;
}
}
.resetButton {
background-color: #fff;
color: #666;
&:hover {
background-color: #f5f5f5;
}
}
}
}
// 第二行 - 表格
.tableSection {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
:global {
.ant-spin-nested-loading {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.ant-spin-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.ant-table-wrapper {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.ant-table {
flex: 1;
overflow: auto;
}
.ant-table-pagination {
flex-shrink: 0;
margin: 16px 0 0 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;
}
.ant-table-tbody > tr > td {
border-right: none;
color: #000000D9;
font-weight: 400;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background-color: #f5f5f5;
}
a {
color: #1890ff;
text-decoration: none;
&:hover {
color: #40a9ff;
}
}
}
.ant-pagination {
text-align: right;
}
}
}
}
}
}
// 操作按钮图标样式
.eye-icon {
width: 20px;
height: 12.5px;
position: relative;
display: inline-block;
&::before {
content: '';
position: absolute;
width: 20px;
height: 12.5px;
border: 2px solid #86F278;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
top: 0;
left: 0;
transform: rotate(-180deg);
opacity: 1;
}
&::after {
content: '';
position: absolute;
width: 6px;
height: 6px;
background-color: #86F278;
border-radius: 50%;
top: 3.5px;
left: 7px;
transform: rotate(-180deg);
}
}
.edit-icon {
width: 16px;
height: 16px;
position: relative;
display: inline-block;
&::before {
content: '';
position: absolute;
width: 12px;
height: 2px;
background-color: #1890ff;
top: 3px;
left: 2px;
transform: rotate(45deg);
}
&::after {
content: '';
position: absolute;
width: 2px;
height: 12px;
background-color: #1890ff;
top: 2px;
left: 7px;
transform: rotate(45deg);
}
}
.delete-icon {
width: 16px;
height: 16px;
position: relative;
display: inline-block;
&::before {
content: '';
position: absolute;
width: 12px;
height: 2px;
background-color: #ff4d4f;
top: 7px;
left: 2px;
transform: rotate(45deg);
}
&::after {
content: '';
position: absolute;
width: 12px;
height: 2px;
background-color: #ff4d4f;
top: 7px;
left: 2px;
transform: rotate(-45deg);
}
}

@ -1,58 +0,0 @@
import React, { useState } from 'react';
import { Tabs } from 'antd';
import styles from './EquipmentManagement.less';
// 导入子页面组件
import WasteGasPollutionControl from './secondary_menu/WasteGasPollutionControl';
import WastewaterFacilityManagement from './secondary_menu/WastewaterFacilityManagement';
import ProtectionFacilityMaintenance from './secondary_menu/ProtectionFacilityMaintenance';
const EquipmentManagement = () => {
const [activeTab, setActiveTab] = useState('waste-gas-control');
// 标签页配置
const tabItems = [
{
key: 'waste-gas-control',
label: '废气污染防治信息',
children: <WasteGasPollutionControl />
},
{
key: 'wastewater-facility',
label: '废水设置运行管理',
children: <WastewaterFacilityManagement />
},
{
key: 'protection-facility',
label: '防护设施检维修管理',
children: <ProtectionFacilityMaintenance />
}
];
// 标签页切换处理
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'
}}
/>
</div>
);
};
export default EquipmentManagement;

@ -1,119 +0,0 @@
.container {
width: 100%;
height: 100%;
padding: 16px;
// 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;
}
}
// 额外的全局样式覆盖,确保优先级足够高
: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%;
}
}
}
}
}

@ -1,57 +0,0 @@
import React, { useState } from 'react';
import { Tabs } from 'antd';
import styles from './EvaluationReport.less';
// 导入子页面组件
import PermitStatistics from './secondary_menu/PermitStatistics';
import EnvironmentalTaskList from './secondary_menu/EnvironmentalTaskList';
import DischargePermitManagement from './secondary_menu/DischargePermitManagement';
const EvaluationReport = () => {
const [activeTab, setActiveTab] = useState('permit-statistics');
// 标签页配置
const tabItems = [
{
key: 'permit-statistics',
label: '许可证信息统计表',
children: <PermitStatistics />
},
{
key: 'environmental-task-list',
label: '环保管理任务清单',
children: <EnvironmentalTaskList />
},
{
key: 'discharge-permit-management',
label: '排污许可执行管理',
children: <DischargePermitManagement />
}
];
// 标签页切换处理
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'
}}
/>
</div>
);
};
export default EvaluationReport;

@ -1,119 +0,0 @@
.container {
width: 100%;
height: 100%;
padding: 16px;
// 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;
}
}
// 额外的全局样式覆盖,确保优先级足够高
: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%;
}
}
}
}
}

@ -1,716 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, Result, Select, Button } from 'antd';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
import styles from './OnlineMonitoring.less';
import alarm0 from '@/assets/safe_majorHazard/online_monitoring/alarm0.png';
import alarm1 from '@/assets/safe_majorHazard/online_monitoring/alarm1.png';
import alarm2 from '@/assets/safe_majorHazard/online_monitoring/alarm2.png';
import alarm3 from '@/assets/safe_majorHazard/online_monitoring/alarm3.png';
import exportIcon from '@/assets/safe_majorHazard/online_monitoring/export.png';
import deleteIcon from '@/assets/safe_majorHazard/online_monitoring/delete.png';
const OnlineMonitoring = () => {
const chartRef = useRef(null);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [selectedRows, setSelectedRows] = useState([]);
const [loading, setLoading] = useState(false);
const [dataSource, setDataSource] = useState([]);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 5,
total: 0,
});
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
const option = {
color: ['#04A7F3', '#E7C42C', '#EC6941'],
legend: {
data: ['液位', '温度', '压力'],
top: "-3px",
left: "center",
itemGap: 40, // 图例间距
textStyle: {
fontSize: 10
}
},
grid: {
left: '2%',
right: '4%',
bottom: '2%',
top: '12%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['0:00', '2:00', '4:00', '6:00', '8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'],
axisLabel: {
fontSize: 10
}
},
yAxis: {
type: 'value',
min: 0,
max: 500,
axisLabel: {
formatter: '{value}',
fontSize: 10
}
},
series: [
{
name: '液位',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#04A7F3'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(4, 167, 243, 0.3)' },
{ offset: 1, color: 'rgba(4, 167, 243, 0)' }
]
}
},
symbol: 'none', // 不显示数据点
data: [120, 200, 150, 300, 250, 400, 350, 280, 320, 180, 220, 160, 140]
},
{
name: '温度',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#E7C42C'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(231, 196, 44, 0.3)' },
{ offset: 1, color: 'rgba(231, 196, 44, 0)' }
]
}
},
symbol: 'none',
data: [80, 120, 100, 180, 160, 220, 200, 150, 170, 90, 110, 85, 75]
},
{
name: '压力',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#EC6941'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 1,
x2: 0,
y2: 0,
colorStops: [
{ offset: 0, color: 'rgba(236, 105, 65, 0)' },
{ offset: 1, color: 'rgba(236, 105, 65, 0.3)' }
]
}
},
symbol: 'none',
data: [200, 300, 250, 450, 400, 430, 480, 420, 480, 280, 320, 260, 240]
}
]
};
chart.setOption(option);
// 响应式调整 - 使用ResizeObserver监听容器尺寸变化
let resizeTimer = null;
const handleResize = () => {
// 防抖处理避免频繁调用resize
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(() => {
chart.resize();
}, 100);
};
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
// 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题)
let resizeObserver = null;
if (window.ResizeObserver) {
resizeObserver = new ResizeObserver(() => {
// 使用setTimeout确保DOM更新完成后再调整图表
setTimeout(() => {
handleResize();
}, 0);
});
resizeObserver.observe(chartRef.current);
}
return () => {
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
}
if (resizeTimer) {
clearTimeout(resizeTimer);
}
chart.dispose();
};
}
}, []);
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 80,
render: (text, record, index) => {
const page = pagination.current || 1;
const pageSize = pagination.pageSize || 5;
const number = (page - 1) * pageSize + index + 1;
return `0${number}`.slice(-2);
}
},
{
title: '报警时间',
dataIndex: 'alarmTime',
key: 'alarmTime',
width: 150,
},
{
title: '报警传感器名称',
dataIndex: 'sensorName',
key: 'sensorName',
width: 150,
},
{
title: '报警类型',
dataIndex: 'alarmType',
key: 'alarmType',
width: 120,
},
{
title: '报警内容',
dataIndex: 'alarmContent',
key: 'alarmContent',
width: 200,
},
{
title: '优先级',
dataIndex: 'priority',
key: 'priority',
width: 80,
render: (text) => {
const colorMap = {
'高': '#FF4D4F',
'中': '#FAAD14',
'低': '#52C41A'
};
return <span style={{ color: colorMap[text] || '#333' }}>{text}</span>;
}
},
{
title: '处理状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (text) => {
const statusMap = {
'未处理': { color: '#FF4D4F', bg: '#FFF2F0' },
'处理中': { color: '#FAAD14', bg: '#FFFBE6' },
'已处理': { color: '#52C41A', bg: '#F6FFED' }
};
const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
return (
<span style={{
color: status.color,
backgroundColor: status.bg,
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px'
}}>
{text}
</span>
);
}
},
{
title: '处理时间',
dataIndex: 'processTime',
key: 'processTime',
width: 150,
},
{
title: '处理人',
dataIndex: 'processor',
key: 'processor',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (_, record) => (
<div>
<Button type="link" size="small" style={{ padding: 0, marginRight: 8 }}>
查看
</Button>
</div>
),
},
];
// 模拟数据
const mockData = [
{
key: '1',
id: '001',
alarmTime: '2024-01-15 08:30:25',
sensorName: 'LNG储罐',
alarmType: '温度超限',
alarmContent: '储罐温度超过安全阈值',
priority: '高',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '2',
id: '002',
alarmTime: '2024-01-15 09:15:10',
sensorName: 'LNG储罐',
alarmType: '压力异常',
alarmContent: '管道压力异常波动',
priority: '中',
status: '处理中',
processTime: '2024-01-15 09:20:00',
processor: '张三',
},
{
key: '3',
id: '003',
alarmTime: '2024-01-15 10:45:30',
sensorName: 'LNG储罐',
alarmType: '液位异常',
alarmContent: '储罐液位低于警戒线',
priority: '高',
status: '已处理',
processTime: '2024-01-15 11:00:15',
processor: '李四',
},
{
key: '4',
id: '004',
alarmTime: '2024-01-15 11:20:45',
sensorName: 'LNG储罐',
alarmType: '气体泄漏',
alarmContent: '检测到可燃气体泄漏',
priority: '高',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '5',
id: '005',
alarmTime: '2024-01-15 12:10:20',
sensorName: 'LNG储罐',
alarmType: '设备振动',
alarmContent: '设备异常振动',
priority: '低',
status: '已处理',
processTime: '2024-01-15 12:30:00',
processor: '王五',
},
{
key: '6',
id: '006',
alarmTime: '2024-01-15 13:25:15',
sensorName: 'LNG管道',
alarmType: '流量异常',
alarmContent: '管道流量异常波动',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '7',
id: '007',
alarmTime: '2024-01-15 14:10:30',
sensorName: 'LNG储罐',
alarmType: '温度异常',
alarmContent: '储罐温度异常升高',
priority: '高',
status: '处理中',
processTime: '2024-01-15 14:15:00',
processor: '赵六',
},
{
key: '8',
id: '008',
alarmTime: '2024-01-15 15:45:20',
sensorName: 'LNG管道',
alarmType: '压力超限',
alarmContent: '管道压力超过安全阈值',
priority: '高',
status: '已处理',
processTime: '2024-01-15 16:00:00',
processor: '孙七',
},
{
key: '9',
id: '009',
alarmTime: '2024-01-15 16:30:45',
sensorName: 'LNG储罐',
alarmType: '液位超限',
alarmContent: '储罐液位超过警戒线',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '10',
id: '010',
alarmTime: '2024-01-15 17:15:10',
sensorName: 'LNG管道',
alarmType: '泄漏检测',
alarmContent: '检测到轻微气体泄漏',
priority: '低',
status: '已处理',
processTime: '2024-01-15 17:30:00',
processor: '周八',
},
{
key: '11',
id: '011',
alarmTime: '2024-01-15 18:20:35',
sensorName: 'LNG储罐',
alarmType: '设备故障',
alarmContent: '储罐阀门异常关闭',
priority: '高',
status: '处理中',
processTime: '2024-01-15 18:25:00',
processor: '吴九',
},
{
key: '12',
id: '012',
alarmTime: '2024-01-15 19:05:50',
sensorName: 'LNG管道',
alarmType: '温度异常',
alarmContent: '管道温度异常下降',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
];
// 初始化数据
useEffect(() => {
setPagination(prev => ({ ...prev, total: mockData.length }));
}, []);
// 根据分页获取当前页数据
const getCurrentPageData = () => {
const { current, pageSize } = pagination;
const startIndex = (current - 1) * pageSize;
const endIndex = startIndex + pageSize;
return mockData.slice(startIndex, endIndex);
};
// 表格选择变化
const onSelectChange = (newSelectedRowKeys, newSelectedRows) => {
setSelectedRowKeys(newSelectedRowKeys);
setSelectedRows(newSelectedRows);
};
// 分页变化处理
const handleTableChange = (pagination) => {
setPagination(prev => ({
...prev,
current: pagination.current,
pageSize: pagination.pageSize,
}));
};
// 导出功能
const handleExport = () => {
console.log('导出数据');
// 这里可以添加导出逻辑
};
// 批量删除功能
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
console.log('没有选中任何行');
// 可以在这里添加提示用户选择行的逻辑
return;
}
console.log('批量删除', selectedRowKeys);
// 这里可以添加批量删除逻辑
};
return (
<div className={styles.Ocontainer}>
<div className={styles.OcontainerTop}>
<div className={styles.OcontainerTopLeft}>
<div className={styles.OcontainerTopLeftTop}>
<div className={styles.alarmO}>
<div className={styles.alarmOLeft}>
<img style={{ width: 58, height: 47 }} src={alarm0} alt='alarm0' />
</div>
<div className={styles.alarmORight}>
<div className={styles.alarmORightText1}>总报警</div>
<div className={styles.alarmORightText2}>1456</div>
<div className={styles.alarmORightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmTw}>
<div className={styles.alarmTwLeft}>
<img style={{ width: 58, height: 47 }} src={alarm1} alt='alarm1' />
</div>
<div className={styles.alarmTwRight}>
<div className={styles.alarmTwRightText1}>一级报警</div>
<div className={styles.alarmTwRightText2}>357</div>
<div className={styles.alarmTwRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmTh}>
<div className={styles.alarmThLeft}>
<img style={{ width: 58, height: 47 }} src={alarm2} alt='alarm2' />
</div>
<div className={styles.alarmThRight}>
<div className={styles.alarmThRightText1}>二级报警</div>
<div className={styles.alarmThRightText2}>401</div>
<div className={styles.alarmThRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmF}>
<div className={styles.alarmFLeft}>
<img style={{ width: 58, height: 47 }} src={alarm3} alt='alarm3' />
</div>
<div className={styles.alarmFRight}>
<div className={styles.alarmFRightText1}>三级报警</div>
<div className={styles.alarmFRightText2}>556</div>
<div className={styles.alarmFRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
</div>
<div className={styles.OcontainerTopLeftBottom}>
<div className={styles.OcontainerTopLeftBottomTitle}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>预警看板</div>
</div>
<div className={styles.titleRight}>
<div>检测对象</div>
<Select
style={{ width: 80 }}
defaultValue="储罐"
options={[
{ value: '储罐', label: '储罐' },
{ value: '管道', label: '管道' },
{ value: '设备', label: '设备' }
]}
/>
</div>
</div>
<div className={styles.OcontainerTopLeftBottomChart} ref={chartRef}>
</div>
</div>
</div>
<div className={styles.OcontainerTopRight}>
<div className={styles.realTimeDataHeader}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>实时数据采集</div>
</div>
<div className={styles.totalCount}>
总数 <text style={{ color: '#2e4cd4' }}>1378</text>
</div>
</div>
<div className={styles.dataItem1}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>三级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem2}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>一级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem3}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>二级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem4}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>三级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* 表格 */}
<div className={styles.OcontainerBottom}>
{/* 首行 左侧标题左对齐 右侧按钮右对齐 */}
<div className={styles.tableHeader}>
<div className={styles.tableTitle}>
<div className={styles.titleIcon}></div>
<div>报警信息列表</div>
</div>
<div className={styles.tableActions}>
<Button
type="primary"
onClick={handleExport}
style={{ marginRight: 8 }}
>
<img src={exportIcon} alt="导出" style={{ width: 16, height: 16, margin: '-2px 6px 0 0px'}} />
导出word 报告
</Button>
<Button
type="primary"
onClick={handleBatchDelete}
>
<img src={deleteIcon} alt="删除" style={{ width: 16, height: 16, margin: '-2px 6px 0 0px' }} />
批量删除
</Button>
</div>
</div>
{/* 表格 5行10列 带页码 每页5条数据 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: getCurrentPageData(),
pagination: pagination
}}
loading={loading}
selectionType="checkbox"
onSelectRow={onSelectChange}
onChange={handleTableChange}
pagination={{
...pagination,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
}}
scroll={{ x: 1200 }}
/>
</div>
</div>
</div>
);
};
export default OnlineMonitoring;

@ -1,919 +0,0 @@
.Ocontainer {
padding: 8px 6px 0px 6px;
height: 100%;
display: flex;
flex-direction: column;
.OcontainerTop {
display: flex;
height: 50%;
margin-bottom: 5px;
.OcontainerTopLeft {
width: 72%;
height: 100%;
// background-color: pink;
margin-right: 10px;
// display: flex;
.OcontainerTopLeftTop {
width: 100%;
height: 35%;
display: flex;
gap: 12px;
.alarmO {
flex: 1;
height: 100%;
background-color: #F4F7FF;
border: 1px solid #AED3FF;
border-bottom: 0px solid #AED3FF;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #5382FE33 inset;
display: flex;
.alarmOLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmORight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmORightText1 {
margin-top: 15px;
}
.alarmORightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmORightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmTw {
flex: 1;
height: 100%;
background-color: #FFF5f4;
border: 1px solid #FFC5BC;
border-bottom: 0px solid #FFC5BC;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #FE5F4C33 inset;
display: flex;
.alarmTwLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmTwRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmTwRightText1 {
margin-top: 15px;
}
.alarmTwRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmTwRightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmTh {
flex: 1;
height: 100%;
background-color: #FFF7F2;
border: 1px solid #FFD9B2;
border-bottom: 0px solid #FFD9B2;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #FD883C33 inset;
display: flex;
.alarmThLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmThRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmThRightText1 {
margin-top: 15px;
}
.alarmThRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmThRightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmF {
flex: 1;
height: 100%;
background-color: #EFF9FF;
border: 1px solid #89E1FF;
border-bottom: 0px solid #89E1FF;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #22A4FD33 inset;
display: flex;
.alarmFLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmFRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmFRightText1 {
margin-top: 15px;
}
.alarmFRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmFRightText3 {
display: flex;
gap: 22px;
}
}
}
}
.OcontainerTopLeftBottom {
margin-top: 12px;
background-color: #fff;
width: 100%;
height: 60%;
.OcontainerTopLeftBottomTitle {
display: flex;
justify-content: space-between;
align-items: center;
// padding: 8px 15px;
padding: 8px 15px 0px 15px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-style: Medium;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.titleRight {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-style: Medium;
font-size: 13px;
line-height: 100%;
letter-spacing: 0%;
.selectBox {
padding: 4px 8px;
border: 1px solid #d9d9d9;
border-radius: 4px;
background-color: #fff;
font-size: 12px;
color: #333;
outline: none;
&:focus {
border-color: #2E4CD4;
}
}
}
}
.OcontainerTopLeftBottomChart {
flex: 1;
width: 100%;
height: 75%;
}
}
}
.OcontainerTopRight {
flex: 1;
height: calc(100% - 3.3px);
background-color: #fff;
background-image: url('@/assets/safe_majorHazard/online_monitoring/backTopRight.png');
background-size: 100% auto;
display: flex;
flex-direction: column;
overflow-y: auto;
.realTimeDataHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 15px;
margin-bottom: 10px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-style: Medium;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.totalCount {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
}
}
.dataItem {
height: 23%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 2px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFang SC;
font-size: 14px;
// color: #666;
background-color: #EFF9FF;
&:last-child {
// margin-bottom: 1px;
}
}
.dataItem1 {
height: 25%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #EFF9FF;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1; // 强制宽高比1:1
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(51, 176, 253, 0.3);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(4, 128, 251, 0.8);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem2 {
height: 25%;
flex-shrink: 0;
border: 1px solid rgba(255, 197, 188, 1);
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #fff5f4;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(254, 214, 209, 1);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(253, 41, 14, 1);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem3 {
height: 25%;
flex-shrink: 0;
border: 1px solid rgba(255, 217, 178, 1);
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #fef6f1;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(255, 234, 218, 1);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(252, 103, 18, 1);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem4 {
height: 25%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #EFF9FF;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(51, 176, 253, 0.3);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(4, 128, 251, 0.8);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
}
}
.OcontainerBottom {
background-color: #fff;
flex: 1;
padding: 8px 15px 5px 15px;
display: flex;
flex-direction: column;
.tableHeader {
display: flex;
justify-content: space-between;
align-items: center;
// margin-bottom: 15px;
padding-bottom: 5px;
// border-bottom: 1px solid #f0f0f0;
.tableTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.tableActions {
display: flex;
gap: 8px;
// 自定义按钮样式
:global(.ant-btn) {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
// 主要按钮样式
&.ant-btn-primary {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
}
// 危险按钮样式
&.ant-btn-dangerous {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
}
// 禁用状态
&:disabled {
background-color: #f5f5f5 !important;
border-color: #d9d9d9 !important;
color: #bfbfbf !important;
box-shadow: none !important;
}
}
}
}
.tableContainer {
flex: 1;
overflow: hidden;
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
}
:global(.ant-table-tbody > tr:hover > td) {
background-color: #f5f5f5;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}
}

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

@ -1,590 +0,0 @@
.pollutionDashboard {
width: 100%;
min-height: 75vh;
// background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 15px;
box-sizing: border-box;
// 顶部统计区域
.statsSection {
display: flex;
gap: 15px;
margin-bottom: 15px;
height: 35vh;
align-items: stretch;
// 污染物排放统计卡片
.pollutantStatsCard {
width: 37%;
height: 100%;
background: url('@/assets/business_envinformation/background7.svg'),
linear-gradient(180deg, #E2FFF5 0%, rgba(255, 255, 255, 0.6) 51.44%),
linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2));
background-repeat: no-repeat;
border-radius: 2px;
padding: 10px 20px;
display: flex;
flex-direction: column;
.cardTitle {
background: transparent;
color: #000000;
font-weight: 500;
font-size: 16px;
padding: 0;
margin: 0 0 15px 0;
border: none;
display: flex;
align-items: center;
justify-content: space-between;
}
}
// 超标排放统计卡片
.exceedanceStatsCard {
width: 40%;
height: 100%;
background: url('@/assets/business_envinformation/background8.svg'),
linear-gradient(180.21deg, rgba(255, 227, 227, 0.58) 0.18%, #FFFFFF 53.1%),
linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2));
background-repeat: no-repeat;
border-radius: 2px;
padding: 10px 20px;
display: flex;
flex-direction: column;
.cardTitle {
background: transparent;
color: #000000;
font-weight: 500;
font-size: 16px;
padding: 0;
margin: 0 0 15px 0;
border: none;
display: flex;
align-items: center;
justify-content: space-between;
}
.filterGroup {
display: flex;
gap: 10px;
}
.exceedanceTimeFilter,
.exceedanceCategoryFilter {
width: 100px;
flex-shrink: 0;
:global(.ant-select-selector) {
border-radius: 2px;
border: 1px solid #FFC3C3;
background: #FFDEDEB2;
transition: all 0.3s ease;
}
}
}
// 卡片头部筛选器
.cardHeader {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
margin-bottom: 0;
.cardTitle {
background: transparent;
color: #000000;
font-weight: 500;
font-size: 16px;
padding: 0;
margin: 0;
border: none;
flex-shrink: 0;
}
.filterGroup {
display: flex;
gap: 10px;
}
.timeFilter,
.categoryFilter {
width: 100px;
flex-shrink: 0;
:global(.ant-select-selector) {
border-radius: 2px;
border: 1px solid #73E9C6;
background: #C0FFE9AB;
transition: all 0.3s ease;
}
}
}
// 图表容器
.chartsContainer {
display: flex;
gap: 20px;
justify-content: space-between;
background: transparent;
flex: 1;
.pieChartContainer {
flex: 1;
text-align: center;
position: relative;
background: transparent;
height: 100%;
min-height: 200px;
.chartTitle {
font-size: 14px;
color: #666;
margin-bottom: 10px;
font-weight: 500;
background: transparent;
}
.chartCenterContent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
background: transparent;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.chartValue {
font-size: 18px;
font-weight: bold;
color: #FF2F2F;
background: transparent;
margin: 0;
line-height: 1;
}
.chartLabel {
font-size: 12px;
font-weight: 500;
color: #000000;
background: transparent;
margin: 0;
margin-top: 2px;
line-height: 1;
}
}
}
// 条形图容器
.barChartContainer {
flex: 1;
margin-top: 10px;
}
// 环境分类卡片区域
.environmentalCategories {
flex: 1; // 撑满剩余宽度
height: 100%;
display: flex;
flex-direction: column;
gap: 15px;
// background-color: pink;
.categoryCard1 {
flex: 1;
background: linear-gradient(90deg, rgba(27, 201, 181, 0.2) 0%, rgba(58, 255, 216, 0) 100%);
position: relative;
padding: 5px 15px;
.airPollutionText {
position: absolute;
top: 2px;
left: 12px;
background: linear-gradient(183.17deg, rgba(0, 255, 217, 0.1) 2.62%, rgba(0, 153, 131, 0.1) 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 600;
font-style: normal;
font-size: 22px;
line-height: 22px;
letter-spacing: 0%;
z-index: 1;
pointer-events: none;
}
}
.categoryCard2 {
flex: 1;
background: linear-gradient(90deg, rgba(36, 149, 255, 0.2) 0%, rgba(85, 164, 255, 0) 100%);
position: relative;
padding: 5px 15px;
.waterPollutionText {
position: absolute;
top: 2px;
left: 12px;
background: linear-gradient(183.17deg, rgba(0, 170, 255, 0.1) 2.62%, rgba(89, 186, 255, 0.1) 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 600;
font-style: normal;
font-size: 22px;
line-height: 22px;
letter-spacing: 0%;
z-index: 1;
pointer-events: none;
}
}
.categoryCard3 {
flex: 1;
background: linear-gradient(90deg, rgba(25, 60, 234, 0.2) 0%, rgba(139, 193, 255, 0) 100%);
position: relative;
cursor: pointer;
padding: 5px 15px;
.soilPollutionText {
position: absolute;
top: 2px;
left: 12px;
background: linear-gradient(183.17deg, rgba(0, 89, 255, 0.1) 2.62%, rgba(89, 117, 255, 0.1) 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 600;
font-style: normal;
font-size: 22px;
line-height: 22px;
letter-spacing: 0%;
z-index: 1;
pointer-events: none;
}
}
.categoryContent {
display: flex;
justify-content: space-between;
align-items: center;
.categoryInfo {
flex: 1;
.titleContainer {
display: flex;
flex-direction: column;
margin-bottom: 5px;
}
.categoryTitle {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 0px;
&.atmosphereGradient {
background: linear-gradient(183.17deg, #0EE5C5 2.62%, #08C2C2 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 10px;
}
&.atmosphereMirror {
background: linear-gradient(183.17deg, rgba(168, 255, 242, 0) 2.62%, rgba(86, 237, 214, 0) 65.7%, #00D9B9 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 0px;
transform: scaleY(-1);
}
&.waterGradient {
background: linear-gradient(183.17deg, #40AFFF 2.62%, #00B3FF 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 10px;
}
&.waterMirror {
background: linear-gradient(183.17deg, rgba(64, 175, 255, 0) 2.62%, rgba(0, 179, 255, 0) 65.7%, #00B3FF 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 0px;
transform: scaleY(-1);
}
&.soilGradient {
background: linear-gradient(183.17deg, #6E90FF 2.62%, #3D90EF 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 10px;
}
&.soilMirror {
background: linear-gradient(183.17deg, rgba(110, 144, 255, 0) 2.62%, rgba(61, 144, 239, 0) 65.7%, #3D90EF 132.53%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-family: 'Alimama ShuHeiTi', sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 22px;
letter-spacing: 0%;
margin-top: 0px;
transform: scaleY(-1);
}
}
.categorySubtitle {
font-size: 12px;
color: #666;
&.pollutantSubtitle {
color: rgba(51, 51, 51, 1);
font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 500;
font-size: 14px;
line-height: 22px;
letter-spacing: 4%;
margin-top: -20px;
}
}
}
.categoryIcon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
// border-radius: 50%;
// background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
.factoryIcon,
.waterIcon,
.soilIcon {
font-size: 20px;
filter: grayscale(0);
}
}
}
}
}
// 表格卡片
.tableCard {
background: #fff;
border-radius: 2px;
// box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
// border: 1px solid rgba(255, 255, 255, 0.2);
// backdrop-filter: blur(10px);
padding: 20px;
.cardTitle {
// background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
color: rgba(0, 0, 0, 1);
font-weight: 500;
font-size: 16px;
padding: 12px 16px;
margin: -20px -20px 10px -20px;
// border-radius: 12px 12px 0 0;
// border-bottom: 2px solid #e8f4fd;
display: flex;
justify-content: space-between;
align-items: center;
.titleButtons {
display: flex;
gap: 10px;
align-items: center;
.titleAddButton {
background: rgba(0, 212, 138, 1);
border: none;
border-radius: 4px;
color: #fff;
font-weight: 500;
transition: all 0.3s ease;
height: 32px;
padding: 4px 15px;
font-size: 14px;
&:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
}
.titleReportButton {
border-radius: 4px;
border: 1px solid #d9d9d9;
background: #fff;
color: #666;
transition: all 0.3s ease;
height: 32px;
padding: 4px 15px;
font-size: 14px;
&:hover {
border-color: #40a9ff;
color: #40a9ff;
transform: translateY(-1px);
}
}
}
}
}
// 自定义Tooltip样式
.customTooltip {
background: rgba(0, 0, 0, 0.8);
border-radius: 8px;
padding: 10px;
color: white;
font-size: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
.tooltipLabel {
font-weight: 600;
margin-bottom: 5px;
color: #fff;
}
.tooltipStatus {
color: #ff6b6b;
margin-bottom: 3px;
}
.tooltipExceedance {
color: #ffd93d;
margin-bottom: 3px;
}
.tooltipType {
color: #a8e6cf;
font-size: 11px;
}
}
// 响应式设计
@media (max-width: 1200px) {
.statsSection {
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto;
.environmentalCategories {
grid-column: 1 / -1;
flex-direction: row;
gap: 15px;
.categoryCard {
flex: 1;
}
}
}
}
@media (max-width: 768px) {
padding: 10px;
.statsSection {
grid-template-columns: 1fr;
gap: 15px;
.environmentalCategories {
flex-direction: column;
}
}
}
// 表格样式优化
:global(.ant-table) {
// border-radius: 8px;
overflow: hidden;
// box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
font-size: 12px;
color: rgba(0, 0, 0, 0.85);
:global(.ant-table-thead > tr > th) {
// background: linear-gradient(90deg, #f8f9fa 0%, #e9ecef 100%);
// border-bottom: 2px solid #dee2e6;
font-weight: 400;
}
:global(.ant-table-tbody > tr) {
// transition: all 0.3s ease;
}
:global(.ant-table-tbody > tr > td) {
// border-bottom: 1px solid #f0f0f0;
}
}
// 分页器样式
// :global(.ant-pagination) {
// margin-top: 20px;
// text-align: center;
// :global(.ant-pagination-item) {
// border-radius: 6px;
// border: 1px solid #d9d9d9;
// transition: all 0.3s ease;
// &.ant-pagination-item-active {
// background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
// border-color: #667eea;
// color: white;
// }
// }
// :global(.ant-pagination-prev),
// :global(.ant-pagination-next) {
// border-radius: 6px;
// border: 1px solid #d9d9d9;
// transition: all 0.3s ease;
// }
// }
}

@ -1,345 +0,0 @@
import React, { useState } from 'react';
import { Button, Input, Select } from 'antd';
import { SearchOutlined, RedoOutlined, UploadOutlined, DownloadOutlined, DeleteOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './DischargePermitManagement.less';
// import attachment from '@/assets/business_envinformation/attachment.svg';
import downloadicon from '@/assets/business_envinformation/downloadicon.svg';
import deleteicon from '@/assets/business_envinformation/deleteicon.svg';
const DischargePermitManagement = () => {
const [activeTab, setActiveTab] = useState('actual');
// 实际排放数据
const actualEmissionData = [
{ key: 1, emissionType: '前林市', pollutant: '51669811', outletType: '信用风险管理与法律防', outletName: '北京那蓝国际贸易有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 2, emissionType: '拉萨市', pollutant: '34887875', outletType: '涉外警务', outletName: '中瀚石林企业咨询(上海)有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 3, emissionType: '长家界市', pollutant: '12345678', outletType: '环境设计', outletName: '上海环境科技有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 4, emissionType: '北京市', pollutant: '87654321', outletType: '污染治理', outletName: '北京环保科技有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 5, emissionType: '上海市', pollutant: '11223344', outletType: '排放监测', outletName: '上海监测技术有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 6, emissionType: '广州市', pollutant: '55667788', outletType: '工业废水', outletName: '广州环保科技股份有限公司', permittedEmission: '3年', annualTotal: '2025-09-10' },
{ key: 7, emissionType: '深圳市', pollutant: '99887766', outletType: '生活污水', outletName: '深圳水务集团有限公司', permittedEmission: '4年', annualTotal: '2025-07-20' },
{ key: 8, emissionType: '杭州市', pollutant: '33445566', outletType: '农业面源', outletName: '杭州农业科技有限公司', permittedEmission: '2年', annualTotal: '2025-10-05' },
{ key: 9, emissionType: '南京市', pollutant: '77889900', outletType: '工业废气', outletName: '南京工业集团股份有限公司', permittedEmission: '6年', annualTotal: '2025-06-15' },
{ key: 10, emissionType: '武汉市', pollutant: '11223355', outletType: '交通污染', outletName: '武汉交通发展有限公司', permittedEmission: '3年', annualTotal: '2025-11-20' },
{ key: 11, emissionType: '成都市', pollutant: '66778899', outletType: '建筑扬尘', outletName: '成都建筑工程有限公司', permittedEmission: '5年', annualTotal: '2025-05-30' },
{ key: 12, emissionType: '西安市', pollutant: '44556677', outletType: '餐饮油烟', outletName: '西安餐饮管理有限公司', permittedEmission: '4年', annualTotal: '2025-12-10' }
];
// 超标排放数据
const excessiveEmissionData = [
{ key: 1, emissionType: '俞林市', pollutant: '51669811', outletType: '信用风险管理与法律防', outletName: '北京那蓝国际贸易有限公司', permittedEmission: '5年', annualTotal: '2025-08-15' },
{ key: 2, emissionType: '拉萨市', pollutant: '34887875', outletType: '涉外警务', outletName: '中瀚石林企业咨询(上海)有限公司', permittedEmission: '5年', annualTotal: '2025-08-09' },
{ key: 3, emissionType: '长家界市', pollutant: '1716652546', outletType: '环境设计', outletName: '水木晨曦(北京)科技有限公司', permittedEmission: '5年', annualTotal: '2025-08-17' },
{ key: 4, emissionType: '潭市', pollutant: '384654762', outletType: '电子竞技运动与管理', outletName: '亚商桥(北京)咨询有限公司', permittedEmission: '5年', annualTotal: '2025-08-18' },
{ key: 5, emissionType: '次州市', pollutant: '34669295254', outletType: '精算学', outletName: '中讯通讯科技有限公司', permittedEmission: '5年', annualTotal: '2025-08-13' },
{ key: 6, emissionType: '驻马店市', pollutant: '4347052411', outletType: '数字媒体艺术', outletName: '嘉实瑞沃德(北京)商贸有限公司', permittedEmission: '5年', annualTotal: '2025-08-21' },
{ key: 7, emissionType: '三亚市', pollutant: '388946891', outletType: '技术侦察学', outletName: '中大国际文化有限公司', permittedEmission: '5年', annualTotal: '2025-08-17' },
{ key: 8, emissionType: '巢湖市', pollutant: '7190228566', outletType: '财政学', outletName: '嘉实瑞沃德(北京)商贸有限公司', permittedEmission: '5年', annualTotal: '2025-08-20' },
{ key: 9, emissionType: '东营市', pollutant: '6656363924', outletType: '保险学', outletName: '北京济丰国际医院管理有限公司', permittedEmission: '5年', annualTotal: '2025-08-27' },
{ key: 10, emissionType: '九龙', pollutant: '622145211', outletType: '英语', outletName: '北京庆奔科贸有限公司', permittedEmission: '5年', annualTotal: '2025-08-28' },
{ key: 11, emissionType: '深圳市', pollutant: '99887766', outletType: '生活污水', outletName: '深圳水务集团有限公司', permittedEmission: '4年', annualTotal: '2025-07-20' },
{ key: 12, emissionType: '杭州市', pollutant: '33445566', outletType: '农业面源', outletName: '杭州农业科技有限公司', permittedEmission: '2年', annualTotal: '2025-10-05' }
];
// 污染治理设备异常情况数据
const equipmentAbnormalData = [
{ key: 1, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 2, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 3, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 4, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 5, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 6, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 7, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 8, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 9, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 10, emissionType: '类型1', pollutant: '10:15:10—10:50:10', outletType: '管道', outletName: '老化', permittedEmission: '因子名称', annualTotal: '管口5m内' },
{ key: 11, emissionType: '类型2', pollutant: '11:20:15—11:45:30', outletType: '风机', outletName: '磨损', permittedEmission: '因子名称2', annualTotal: '风机10m内' },
{ key: 12, emissionType: '类型3', pollutant: '14:30:20—15:10:40', outletType: '泵站', outletName: '堵塞', permittedEmission: '因子名称3', annualTotal: '泵站15m内' }
];
// 实际排放和超标排放的表格列定义
const normalColumns = [
{
title: '序号',
dataIndex: 'key',
key: 'key',
width: 80,
align: 'center',
},
{
title: '排放物类型',
dataIndex: 'emissionType',
key: 'emissionType',
width: 100,
},
{
title: '污染物',
dataIndex: 'pollutant',
key: 'pollutant',
width: 100,
},
{
title: '排放口类型',
dataIndex: 'outletType',
key: 'outletType',
width: 160,
},
{
title: '排放口编号/排放口名称',
dataIndex: 'outletName',
key: 'outletName',
width: 220,
},
{
title: '许可排放量(吨)',
dataIndex: 'permittedEmission',
key: 'permittedEmission',
width: 120,
},
{
title: '年度合计',
dataIndex: 'annualTotal',
key: 'annualTotal',
width: 120,
},
{
title: '第一季度',
key: 'q1',
width: 80,
render: () => <a href="#" className={styles.attachmentLink}>附件</a>,
},
{
title: '二季度',
key: 'q2',
width: 80,
render: () => <a href="#" className={styles.attachmentLink}>附件</a>,
},
{
title: '三季度',
key: 'q3',
width: 80,
render: () => <a href="#" className={styles.attachmentLink}>附件</a>,
},
{
title: '四季度',
key: 'q4',
width: 80,
render: () => <a href="#" className={styles.attachmentLink}>附件</a>,
},
{
title: '操作',
key: 'action',
width: 100,
render: (_, record) => (
<div className={styles.actionButtons}>
<img
src={downloadicon}
alt="下载"
className={styles.downloadIcon}
title="下载"
/>
<img
src={deleteicon}
alt="删除"
className={styles.deleteIcon}
title="删除"
/>
</div>
),
},
];
// 污染治理设备异常情况的表格列定义
const equipmentColumns = [
{
title: '序号',
dataIndex: 'key',
key: 'key',
width: 80,
align: 'center',
},
{
title: '故障类型',
dataIndex: 'emissionType',
key: 'emissionType',
width: 100,
},
{
title: '超标时段(开始时段—结束时段)',
dataIndex: 'pollutant',
key: 'pollutant',
width: 200,
},
{
title: '故障设施',
dataIndex: 'outletType',
key: 'outletType',
width: 100,
},
{
title: '故障原因',
dataIndex: 'outletName',
key: 'outletName',
width: 100,
},
{
title: '排放因子',
dataIndex: 'permittedEmission',
key: 'permittedEmission',
width: 100,
},
{
title: '排放范围',
dataIndex: 'annualTotal',
key: 'annualTotal',
width: 120,
},
{
title: '排放因子浓度(mg/m³或dB(A))',
key: 'concentration',
width: 200,
render: () => '2025-08-15',
},
{
title: '应对',
key: 'response',
width: 80,
render: () => '—',
},
{
title: '操作',
key: 'action',
width: 120,
render: (_, record) => (
<div className={styles.actionButtons}>
<img
src={downloadicon}
alt="下载"
className={styles.downloadIcon}
title="下载"
/>
<img
src={deleteicon}
alt="删除"
className={styles.deleteIcon}
title="删除"
/>
</div>
),
},
];
// 获取当前标签页的数据
const getCurrentData = () => {
switch (activeTab) {
case 'actual':
return actualEmissionData;
case 'excessive':
return excessiveEmissionData;
case 'equipment':
return equipmentAbnormalData;
default:
return actualEmissionData;
}
};
// 获取当前标签页的列定义
const getCurrentColumns = () => {
switch (activeTab) {
case 'actual':
case 'excessive':
return normalColumns;
case 'equipment':
return equipmentColumns;
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}>
<span className={styles.filterLabel}>筛选条件</span>
<Select
className={styles.filterSelect}
placeholder="请选择"
style={{ width: 120 }}
/>
<Input
className={styles.filterInput}
placeholder="请输入"
style={{ width: 200 }}
/>
<Button
type="primary"
// icon={<SearchOutlined />}
className={styles.queryBtn}
>
查询
</Button>
<Button
// icon={<RedoOutlined />}
className={styles.resetBtn}
>
重置
</Button>
<Button
// icon={<UploadOutlined />}
className={styles.uploadBtn}
>
上传
</Button>
</div>
</div>
<div className={styles.tableContent}>
<StandardTable
columns={getCurrentColumns()}
data={{
list: getCurrentData(),
pagination: pagination
}}
rowKey="key"
/>
</div>
</div>
);
};
export default DischargePermitManagement;

@ -1,160 +0,0 @@
.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);
}
}
}
}
}

@ -1,42 +0,0 @@
import React from 'react';
import styles from './EnvironmentalTaskList.less';
const EnvironmentalTaskList = () => {
return (
<div className={styles.environmentalTaskListContainer}>
<div className={styles.environmentalTaskListContent}>
<div className={styles.environmentalTaskListText}>
<h2>2) 环保管理任务清单</h2>
<p>依据排污许可证副本中的环保要求,提供生成环保管理要求任务清单;</p>
<p>环保任务清单包括:大气排放口信息,大气污染物有组织排放许可年限值,大气污染物无组织排放年限制企业大气排放总许可量;废水排放口废水污染物排放许可限制;固体废物排放信息自行贮存和自行利用/处置设施信息;工业噪声排放信息;</p>
<p>环境管理要求包括:自行检测及记录表环境管理台账记录</p>
</div>
</div>
<div className={styles.environmentalTaskListPagination}>
<div className={styles.paginationInfo}>
<span>共85条</span>
</div>
<div className={styles.paginationControls}>
<select className={styles.pageSizeSelect}>
<option value="5">5/page</option>
</select>
<div className={styles.pageNumbers}>
<button className={styles.pageButton}>&lt;</button>
<button className={styles.pageNumber}>1</button>
<span className={styles.pageEllipsis}>...</span>
<button className={styles.pageNumber}>4</button>
<button className={styles.pageNumber}>5</button>
<button className={`${styles.pageNumber} ${styles.active}`}>6</button>
<button className={styles.pageNumber}>7</button>
<button className={styles.pageNumber}>8</button>
<span className={styles.pageEllipsis}>...</span>
<button className={styles.pageNumber}>50</button>
<button className={styles.pageButton}>&gt;</button>
</div>
</div>
</div>
</div>
);
};
export default EnvironmentalTaskList;

@ -1,105 +0,0 @@
.environmentalTaskListContainer {
width: 100%;
height: 72vh;
display: flex;
flex-direction: column;
background-color: #fff;
position: relative;
}
.environmentalTaskListContent {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 0px 20px;
}
.environmentalTaskListText {
max-width: 800px;
text-align: left;
line-height: 1.6;
h2 {
font-size: 20px;
color: #333;
margin-bottom: 20px;
font-weight: 600;
}
p {
font-size: 16px;
color: #333;
margin-bottom: 15px;
text-indent: 2em;
}
}
.environmentalTaskListPagination {
position: absolute;
bottom: 20px;
right: 20px;
display: flex;
align-items: center;
gap: 20px;
background: #fff;
padding: 10px 20px;
border-radius: 4px;
// box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.paginationInfo {
font-size: 14px;
color: #666;
}
.paginationControls {
display: flex;
align-items: center;
gap: 10px;
}
.pageSizeSelect {
padding: 4px 8px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 12px;
background: #fff;
}
.pageNumbers {
display: flex;
align-items: center;
gap: 4px;
}
.pageButton, .pageNumber {
padding: 4px 8px;
border: 1px solid #d9d9d9;
background: #fff;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
min-width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
&:hover {
border-color: #1890ff;
color: #1890ff;
}
}
.pageNumber.active {
background: #1890ff;
color: #fff;
border-color: #1890ff;
}
.pageEllipsis {
padding: 4px 8px;
font-size: 12px;
color: #666;
}

@ -1,13 +0,0 @@
import React from 'react';
import styles from './InformationDisclosure.less';
const InformationDisclosure = () => {
return (
<div className={styles.container}>
<div className={styles.content}>待开发</div>
</div>
);
};
export default InformationDisclosure;

@ -1,15 +0,0 @@
.container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
.content {
font-size: 24px;
color: #999999;
font-weight: 400;
}
}

@ -1,286 +0,0 @@
import React, { useState } from 'react';
import { Form, Input, Button, DatePicker, Space, Modal } from 'antd';
import { SearchOutlined, RedoOutlined, CloseOutlined, EyeOutlined, DeleteOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './PermitManagement.less';
import licence1 from '@/assets/business_envinformation/licence1.svg';
import licence2 from '@/assets/business_envinformation/licence2.svg';
const PermitManagement = () => {
const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false);
const [currentImage, setCurrentImage] = useState(null);
const [dataSource, setDataSource] = useState([
{
key: 1,
companyName: '北京某某环保有限公司',
permitNumber: 'PWX-BJ-2023-001',
issueOrg: '北京市生态环境局',
expireDate: '2025-12-31',
original: '已上传',
duplicate: '已上传',
},
{
key: 2,
companyName: '上海某某化工有限公司',
permitNumber: 'PWX-SH-2023-002',
issueOrg: '上海市生态环境局',
expireDate: '2025-10-15',
original: '已上传',
duplicate: '已上传',
},
{
key: 3,
companyName: '广州某某制造有限公司',
permitNumber: 'PWX-GZ-2023-003',
issueOrg: '广州市生态环境局',
expireDate: '2026-03-20',
original: '未上传',
duplicate: '已上传',
},
{
key: 4,
companyName: '深圳某某电子有限公司',
permitNumber: 'PWX-SZ-2023-004',
issueOrg: '深圳市生态环境局',
expireDate: '2025-08-10',
original: '已上传',
duplicate: '未上传',
},
{
key: 5,
companyName: '成都某某科技有限公司',
permitNumber: 'PWX-CD-2023-005',
issueOrg: '成都市生态环境局',
expireDate: '2026-01-25',
original: '已上传',
duplicate: '已上传',
},
{
key: 6,
companyName: '武汉某某工业有限公司',
permitNumber: 'PWX-WH-2023-006',
issueOrg: '武汉市生态环境局',
expireDate: '2025-11-30',
original: '已上传',
duplicate: '已上传',
},
{
key: 7,
companyName: '杭州某某环保有限公司',
permitNumber: 'PWX-HZ-2023-007',
issueOrg: '杭州市生态环境局',
expireDate: '2026-05-15',
original: '未上传',
duplicate: '已上传',
},
{
key: 8,
companyName: '南京某某化学有限公司',
permitNumber: 'PWX-NJ-2023-008',
issueOrg: '南京市生态环境局',
expireDate: '2025-09-20',
original: '已上传',
duplicate: '已上传',
},
{
key: 9,
companyName: '重庆某某重工有限公司',
permitNumber: 'PWX-CQ-2023-009',
issueOrg: '重庆市生态环境局',
expireDate: '2026-02-28',
original: '已上传',
duplicate: '未上传',
},
{
key: 10,
companyName: '天津某某制药有限公司',
permitNumber: 'PWX-TJ-2023-010',
issueOrg: '天津市生态环境局',
expireDate: '2025-07-10',
original: '已上传',
duplicate: '已上传',
},
{
key: 11,
companyName: '西安某某材料有限公司',
permitNumber: 'PWX-XA-2023-011',
issueOrg: '西安市生态环境局',
expireDate: '2026-04-05',
original: '未上传',
duplicate: '已上传',
},
{
key: 12,
companyName: '青岛某某机械有限公司',
permitNumber: 'PWX-QD-2023-012',
issueOrg: '青岛市生态环境局',
expireDate: '2025-12-15',
original: '已上传',
duplicate: '已上传',
},
]);
const columns = [
{
title: '序号',
dataIndex: 'key',
key: 'key',
width: 80,
align: 'center',
},
{
title: '企业名称',
dataIndex: 'companyName',
key: 'companyName',
width: 200,
},
{
title: '排污许可证号',
dataIndex: 'permitNumber',
key: 'permitNumber',
width: 180,
},
{
title: '颁发机构',
dataIndex: 'issueOrg',
key: 'issueOrg',
width: 180,
},
{
title: '到期时间',
dataIndex: 'expireDate',
key: 'expireDate',
width: 120,
sorter: (a, b) => new Date(a.expireDate) - new Date(b.expireDate),
showSorterTooltip: false,
},
{
title: '正本',
dataIndex: 'original',
key: 'original',
width: 100,
align: 'center',
render: () => <a style={{ color: '#0080FF' }} onClick={() => { setCurrentImage(licence1); setIsModalVisible(true); }}>附件</a>
},
{
title: '副本',
dataIndex: 'duplicate',
key: 'duplicate',
width: 100,
align: 'center',
render: () => <a style={{ color: '#0080FF' }} onClick={() => { setCurrentImage(licence2); setIsModalVisible(true); }}>附件</a>
},
{
title: '操作',
key: 'action',
width: 150,
align: 'center',
render: (_, record) => (
<Space size="middle">
<EyeOutlined
style={{ color: '#7ee370', fontSize: 16, cursor: 'pointer' }}
onClick={() => handleView(record)}
/>
<DeleteOutlined
style={{ color: '#ff7e72', fontSize: 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 handleDelete = (record) => {
console.log('删除:', record);
// TODO: 实现删除功能
};
return (
<div className={styles.permitContainer}>
{/* 第一块:搜索表单 */}
<div className={styles.searchSection}>
<Form form={form} layout="inline" onFinish={handleSearch}>
<Form.Item label="企业名称" name="companyName">
<Input placeholder="请输入" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item label="许可证号" name="permitNumber">
<Input placeholder="请输入" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item label="到期时间" name="expireDate">
<DatePicker placeholder="请选择" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
style={{ backgroundColor: '#00D48A', borderColor: '#00D48A', color: '#fff', borderRadius: '4px' }}
>
查询
</Button>
</Form.Item>
<Form.Item>
<Button onClick={handleReset} style={{ borderRadius: '4px' }}>
重置
</Button>
</Form.Item>
</Form>
</div>
{/* 第二块:表格 */}
<div className={styles.tableSection}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: {
total: dataSource.length,
pageSize: 10,
currentPage: 1,
showTotal: (total) => `${total}`,
}
}}
/>
</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 PermitManagement;

@ -1,137 +0,0 @@
.permitContainer {
width: 100%;
height: 100%;
// padding: 20px;
background-color: #fff;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
.searchSection {
// margin-bottom: 20px;
padding: 20px;
// background-color: #fafafa;
// border-radius: 2px;
:global {
.ant-form-inline {
display: flex;
.ant-form-item {
margin-right: 16px;
margin-bottom: 0;
}
.ant-form-item:nth-last-child(2) {
margin-left: auto;
}
.ant-form-item:last-child {
margin-right: 0;
}
}
.ant-form-item-label {
font-weight: 500;
label {
color: #666666;
font-size: 13px;
}
}
.ant-input::placeholder,
.ant-picker-input input::placeholder {
color: #00000040;
font-size: 13px;
}
}
}
.tableSection {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 0 20px 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 {
flex: 1;
overflow: auto;
margin: 0;
}
.ant-table-pagination {
flex-shrink: 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;
}
.ant-table-tbody > tr > td {
border-right: none;
color: #000000D9;
font-weight: 400;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background-color: #f5f5f5;
}
a {
color: #1890ff;
text-decoration: none;
&:hover {
color: #40a9ff;
}
}
}
.ant-pagination {
text-align: right;
margin-top: 70px !important;
}
}
}
}

@ -1,421 +0,0 @@
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 './PermitStatistics.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 PermitStatistics = () => {
const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false);
const [currentImage, setCurrentImage] = useState(null);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 14,
});
const [dataSource, setDataSource] = useState([
{
key: 1,
administrativeRegion: '榆林市',
permitNumber: '51669811',
industryCategory: '信用风险管理与法律防',
companyName: '北京那蓝国际贸易有限公司',
validityPeriod: '5年',
issueDate: '2025-08-15',
original: '附件',
duplicate: '附件',
},
{
key: 2,
administrativeRegion: '拉萨市',
permitNumber: '34887875',
industryCategory: '涉外警务',
companyName: '中潮石林企业咨询(上海)有限公司北京分公司',
validityPeriod: '5年',
issueDate: '2025-08-09',
original: '附件',
duplicate: '附件',
},
{
key: 3,
administrativeRegion: '长家界市',
permitNumber: '1716652546',
industryCategory: '环境设计',
companyName: '水木晨曦(北京)科技有限公司',
validityPeriod: '5年',
issueDate: '2025-08-17',
original: '附件',
duplicate: '附件',
},
{
key: 4,
administrativeRegion: '马潭市',
permitNumber: '384654762',
industryCategory: '电子竞技运动与管理',
companyName: '亚商桥(北京)咨询有限公司',
validityPeriod: '5年',
issueDate: '2025-08-17',
original: '附件',
duplicate: '附件',
},
{
key: 5,
administrativeRegion: '交州市',
permitNumber: '34669295254',
industryCategory: '精算学',
companyName: '中讯通讯科技有限公司',
validityPeriod: '5年',
issueDate: '2025-08-13',
original: '附件',
duplicate: '附件',
},
{
key: 6,
administrativeRegion: '驻马店市',
permitNumber: '4347052411',
industryCategory: '数字媒体艺术',
companyName: '嘉实瑞沃德(北京)商贸有限公司',
validityPeriod: '5年',
issueDate: '2025-08-21',
original: '附件',
duplicate: '附件',
},
{
key: 7,
administrativeRegion: '三亚市',
permitNumber: '388946691',
industryCategory: '技术侦察学',
companyName: '中大国际文化有限公司',
validityPeriod: '5年',
issueDate: '2025-08-17',
original: '附件',
duplicate: '附件',
},
{
key: 8,
administrativeRegion: '美湖市',
permitNumber: '7190228566',
industryCategory: '财政学',
companyName: '嘉实瑞沃德(北京)商贸有限公司',
validityPeriod: '5年',
issueDate: '2025-08-20',
original: '附件',
duplicate: '附件',
},
{
key: 9,
administrativeRegion: '东营市',
permitNumber: '6656363924',
industryCategory: '保险学',
companyName: '北京清丰国际医院管理有限公司',
validityPeriod: '5年',
issueDate: '2025-06-27',
original: '附件',
duplicate: '附件',
},
{
key: 10,
administrativeRegion: '九龙',
permitNumber: '622145211',
industryCategory: '英语',
companyName: '北京庆奔科贸有限公司',
validityPeriod: '5年',
issueDate: '2025-08-28',
original: '附件',
duplicate: '附件',
},
{
key: 11,
administrativeRegion: '深圳市',
permitNumber: '755123456',
industryCategory: '计算机科学与技术',
companyName: '深圳创新科技有限公司',
validityPeriod: '3年',
issueDate: '2025-09-01',
original: '附件',
duplicate: '附件',
},
{
key: 12,
administrativeRegion: '杭州市',
permitNumber: '571789012',
industryCategory: '电子商务',
companyName: '杭州数字贸易有限公司',
validityPeriod: '4年',
issueDate: '2025-09-05',
original: '附件',
duplicate: '附件',
},
{
key: 13,
administrativeRegion: '成都市',
permitNumber: '028345678',
industryCategory: '生物技术',
companyName: '成都生物科技股份有限公司',
validityPeriod: '5年',
issueDate: '2025-09-10',
original: '附件',
duplicate: '附件',
},
{
key: 14,
administrativeRegion: '武汉市',
permitNumber: '027456789',
industryCategory: '机械工程',
companyName: '武汉智能制造有限公司',
validityPeriod: '3年',
issueDate: '2025-09-15',
original: '附件',
duplicate: '附件',
},
]);
const columns = [
{
title: '序号',
dataIndex: 'key',
key: 'key',
width: 80,
align: 'center',
},
{
title: '行政区',
dataIndex: 'administrativeRegion',
key: 'administrativeRegion',
width: 120,
},
{
title: '许可证编号',
dataIndex: 'permitNumber',
key: 'permitNumber',
width: 130,
},
{
title: '行业类别',
dataIndex: 'industryCategory',
key: 'industryCategory',
width: 200,
},
{
title: '企业名称',
dataIndex: 'companyName',
key: 'companyName',
width: 230,
},
{
title: '有效期限',
dataIndex: 'validityPeriod',
key: 'validityPeriod',
width: 80,
align: 'center',
},
{
title: '发证日期',
dataIndex: 'issueDate',
key: 'issueDate',
width: 120,
align: 'center',
},
{
title: '正本',
dataIndex: 'original',
key: 'original',
width: 80,
align: 'center',
render: () => <a style={{ color: '#0080FF' }} onClick={() => { setCurrentImage(licence1); setIsModalVisible(true); }}>附件</a>
},
{
title: '副本',
dataIndex: 'duplicate',
key: 'duplicate',
width: 120,
align: 'center',
render: () => <a style={{ color: '#0080FF' }} onClick={() => { setCurrentImage(licence2); setIsModalVisible(true); }}>附件</a>
},
{
title: '操作',
key: 'action',
width: 140,
align: 'center',
render: (_, record) => (
<Space size={13}>
<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 getCurrentPageData = () => {
const { current, pageSize } = pagination;
const start = (current - 1) * pageSize;
const end = start + pageSize;
return dataSource.slice(start, end);
};
return (
<div className={styles.permitContainer}>
{/* 第一块:操作按钮和筛选条件 */}
<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>
</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}
/>
</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 PermitStatistics;

@ -1,187 +0,0 @@
.permitContainer {
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;
overflow: hidden;
padding: 0 20px 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 {
flex: 1;
overflow: auto;
margin: 0;
}
.ant-table-pagination {
flex-shrink: 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;
}
.ant-table-tbody > tr > td {
border-right: none;
color: #000000D9;
font-weight: 400;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background-color: #f5f5f5;
}
a {
color: #1890ff;
text-decoration: none;
&:hover {
color: #40a9ff;
}
}
}
.ant-pagination {
text-align: right;
margin-top: 70px !important;
}
}
}
}

@ -1,578 +0,0 @@
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 './ProtectionFacilityMaintenance.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 ProtectionFacilityMaintenance = () => {
const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false);
const [currentImage, setCurrentImage] = useState(null);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 13,
});
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [dataSource, setDataSource] = useState([
{
key: 1,
recordTime: '2025-08-29',
recorder: '赵吾行',
reviewer: '郑叶飞',
facilityName: '塞隆风湿酒(同仁堂)',
facilityCode: '35.236.217.212',
startTime: '2025-08-23 06:18',
endTime: '2025-08-23 06:18',
pollutantType: '123',
concentration: '39',
unit: 'm³/d',
dischargeDestination: '大气',
eventReason: '从病虫害探测、土壤墒情监测智能...',
isReported: '已报告',
responseMeasures: '2025-08-23 06:18',
},
{
key: 2,
recordTime: '2025-09-02',
recorder: '王嘉骐',
reviewer: '赵子峰',
facilityName: '复方水杨酸甲酯乳膏(曼秀雷敦)',
facilityCode: '65.177.48.116',
startTime: '2025-09-07 17:48',
endTime: '2025-09-07 17:48',
pollutantType: '大气污染物',
concentration: '52',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '从病虫害探测、土壤墒情监测智能...',
isReported: '已报告',
responseMeasures: '2025-09-07 17:48',
},
{
key: 3,
recordTime: '2025-09-06',
recorder: '王嘉琪',
reviewer: '郑清予',
facilityName: '口炎清颗粒(大神)',
facilityCode: '111.161.135.125',
startTime: '2025-09-04 13:08',
endTime: '2025-09-04 13:08',
pollutantType: '污水',
concentration: '28',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '从病虫害探测、土壤墒情监测智能...',
isReported: '已报告',
responseMeasures: '2025-09-04 13:08',
},
{
key: 4,
recordTime: '2025-08-22',
recorder: '王佛瑶',
reviewer: '赵玉',
facilityName: '烧烫伤膏(茂祥)',
facilityCode: '162.208.135.147',
startTime: '2025-08-28 22:40',
endTime: '2025-08-28 22:40',
pollutantType: '污水',
concentration: '46',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '近期,高铁"熊孩子"事件频出,...',
isReported: '已报告',
responseMeasures: '2025-08-28 22:40',
},
{
key: 5,
recordTime: '2025-08-31',
recorder: '吴子萱',
reviewer: '钱品妍',
facilityName: '云南白药(云南白药)',
facilityCode: '138.6.246.181',
startTime: '2025-09-17 19:48',
endTime: '2025-09-17 19:48',
pollutantType: '污水',
concentration: '37',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '刘某及同伴三人前往该射击俱乐部...',
isReported: '已报告',
responseMeasures: '2025-09-17 19:48',
},
{
key: 6,
recordTime: '2025-08-29',
recorder: '何风景',
reviewer: '赵海洲',
facilityName: '麝香壮骨膏(修正)',
facilityCode: '134.80.173.128',
startTime: '2025-09-02 22:21',
endTime: '2025-09-02 22:21',
pollutantType: '污水',
concentration: '53',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '一位网友在社交平台发布的视频显...',
isReported: '未报告',
responseMeasures: '2025-09-02 22:21',
},
{
key: 7,
recordTime: '2025-08-28',
recorder: '李琳颖',
reviewer: '李建刚',
facilityName: '复方醋酸甲羟孕酮胶囊(妇复春)',
facilityCode: '218.169.25.43',
startTime: '2025-09-06 16:27',
endTime: '2025-09-06 16:27',
pollutantType: '污水',
concentration: '24',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '盛夏时节,四川绵竹市汉旺镇一株...',
isReported: '未报告',
responseMeasures: '2025-09-06 16:27',
},
{
key: 8,
recordTime: '2025-08-22',
recorder: '赵午光',
reviewer: '钱泽西',
facilityName: '桂龙药膏',
facilityCode: '54.218.80.84',
startTime: '2025-09-12 22:50',
endTime: '2025-09-12 22:50',
pollutantType: '污水',
concentration: '47',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '随着"热射病"这一高温疾病快速...',
isReported: '未报告',
responseMeasures: '2025-09-12 22:50',
},
{
key: 9,
recordTime: '2025-08-21',
recorder: '王凤娇',
reviewer: '李金泽',
facilityName: '和兴白花油(和兴白花油)',
facilityCode: '222.1.18.173',
startTime: '2025-09-10 04:28',
endTime: '2025-09-10 04:28',
pollutantType: '污水',
concentration: '33',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '夏粮丰,全年稳。国家粮食和物资...',
isReported: '未报告',
responseMeasures: '2025-09-10 04:28',
},
{
key: 10,
recordTime: '2025-09-09',
recorder: '赵涛',
reviewer: '何能',
facilityName: '茶苯海明含片(贻晗柠)',
facilityCode: '136.200.182.22',
startTime: '2025-08-30 07:15',
endTime: '2025-08-30 07:15',
pollutantType: '污水',
concentration: '34',
unit: 'm³/d',
dischargeDestination: '河流',
eventReason: '近日,一则"携程推出火车卧铺女...',
isReported: '未报告',
responseMeasures: '2025-08-30 07:15',
},
{
key: 11,
recordTime: '2025-09-15',
recorder: '李小明',
reviewer: '王建国',
facilityName: '阿莫西林胶囊(华北制药)',
facilityCode: '192.168.1.100',
startTime: '2025-09-15 14:30',
endTime: '2025-09-15 16:45',
pollutantType: '大气污染物',
concentration: '68',
unit: 'mg/m³',
dischargeDestination: '大气',
eventReason: '设备故障导致废气处理系统异常运行...',
isReported: '已报告',
responseMeasures: '2025-09-15 16:45',
},
{
key: 12,
recordTime: '2025-09-18',
recorder: '张美丽',
reviewer: '刘德华',
facilityName: '布洛芬缓释胶囊(中美史克)',
facilityCode: '10.0.0.25',
startTime: '2025-09-18 09:20',
endTime: '2025-09-18 11:30',
pollutantType: '污水',
concentration: '42',
unit: 'mg/L',
dischargeDestination: '污水处理厂',
eventReason: '管道泄漏导致废水直接排放...',
isReported: '未报告',
responseMeasures: '2025-09-18 11:30',
},
{
key: 13,
recordTime: '2025-09-20',
recorder: '陈志强',
reviewer: '周杰伦',
facilityName: '头孢拉定胶囊(石药集团)',
facilityCode: '172.16.0.88',
startTime: '2025-09-20 20:15',
endTime: '2025-09-20 22:00',
pollutantType: '噪声',
concentration: '85',
unit: 'dB',
dischargeDestination: '环境',
eventReason: '夜间施工未采取降噪措施...',
isReported: '已报告',
responseMeasures: '2025-09-20 22:00',
},
]);
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: 'facilityCode',
key: 'facilityCode',
width: 150,
align: 'center',
},
{
title: '异常情况起始时刻',
dataIndex: 'startTime',
key: 'startTime',
width: 160,
align: 'center',
},
{
title: '异常情况终止时刻',
dataIndex: 'endTime',
key: 'endTime',
width: 160,
align: 'center',
},
{
title: '污染物种类',
dataIndex: 'pollutantType',
key: 'pollutantType',
width: 120,
align: 'center',
},
{
title: '污染物排放浓度',
dataIndex: 'concentration',
key: 'concentration',
width: 140,
align: 'center',
},
{
title: '浓度单位',
dataIndex: 'unit',
key: 'unit',
width: 100,
align: 'center',
},
{
title: '排放去向',
dataIndex: 'dischargeDestination',
key: 'dischargeDestination',
width: 100,
align: 'center',
},
{
title: '事件原因',
dataIndex: 'eventReason',
key: 'eventReason',
width: 180,
},
{
title: '是否报告',
dataIndex: 'isReported',
key: 'isReported',
width: 100,
align: 'center',
render: (text) => (
<span style={{
color: text === '未报告' ? '#722ed1' : '#52c41a',
backgroundColor: text === '未报告' ? '#F9F0FF' : '#F6FFED',
border: text === '未报告' ? '1px solid #D3ADF7' : '1px solid #B7EB8F',
padding: '2px 8px',
borderRadius: '4px',
display: 'inline-block'
}}>
{text}
</span>
),
},
{
title: '应对措施',
dataIndex: 'responseMeasures',
key: 'responseMeasures',
width: 150,
align: 'center',
},
{
title: '操作',
key: 'action',
width: 100,
align: 'center',
fixed: 'right',
render: (_, record) => (
<Space size={18}>
<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.protectionFacilityContainer}>
{/* 第一块:操作按钮和筛选条件 */}
<div className={styles.searchSection}>
<div className={styles.leftButtons}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.addButton}
>
新增
</Button>
<Button
onClick={handleImport}
className={styles.importButton}
>
上传
</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 ProtectionFacilityMaintenance;

@ -1,205 +0,0 @@
.protectionFacilityContainer {
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;
}
}
}
}

@ -1,592 +0,0 @@
import React, { useState } from 'react';
import { Form, Input, Button, DatePicker, Select, Drawer, Descriptions, Tag } from 'antd';
import styles from './RegulationCompliance.less';
import stipulation1 from '@/assets/business_envinformation/stipulation1.svg';
const RegulationCompliance = () => {
const [form] = Form.useForm();
const [drawerVisible, setDrawerVisible] = useState(false);
const [selectedRegulation, setSelectedRegulation] = useState(null);
const handleSearch = (values) => {
console.log('搜索参数:', values);
// TODO: 实现搜索功能
};
const handleReset = () => {
form.resetFields();
// TODO: 重置搜索
};
// 显示抽屉详情
const showDrawer = (regulation) => {
setSelectedRegulation(regulation);
setDrawerVisible(true);
};
// 关闭抽屉
const onCloseDrawer = () => {
setDrawerVisible(false);
setSelectedRegulation(null);
};
// 模拟法规数据(实际应该从后端获取)
const mockRegulationDetail = {
name: '2025排污许可条例',
publishDate: '2025-08-24',
department: '环保部门名称',
content: '在此输入具体的法规内容...',
status: '有效',
category: '排污许可',
version: '1.0',
updateTime: '2025-08-24'
};
return (
<div className={styles.regulationContainer}>
{/* 第一块:搜索表单 */}
<div className={styles.searchSection}>
<Form form={form} layout="inline" onFinish={handleSearch}>
<Form.Item label="法规名称" name="regulationName">
<Input placeholder="请输入" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item label="发布部门" name="regulationNumber">
<Input placeholder="请输入" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item label="发布日期" name="publishDate">
<DatePicker placeholder="请选择" style={{ width: 160, borderRadius: '2px' }} />
</Form.Item>
<Form.Item>
<Button
type="primary"
htmlType="submit"
style={{ backgroundColor: '#00D48A', borderColor: '#00D48A', color: '#fff', borderRadius: '4px' }}
>
查询
</Button>
</Form.Item>
<Form.Item>
<Button onClick={handleReset} style={{ borderRadius: '4px' }}>
重置
</Button>
</Form.Item>
</Form>
</div>
{/* 第二块:表格区域 */}
<div className={styles.tableSection}>
<div className={styles.blocksContainer}>
{/* 法规合规管理块1 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-24
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块2 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-25
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块3 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-26
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块4 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-27
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块5 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-28
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块6 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-29
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块7 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-30
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块8 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-08-31
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块9 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-09-01
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称9
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块10 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-09-02
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块11 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-09-03
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
{/* 法规合规管理块12 */}
<div className={styles.regulationBlock}>
{/* 第一行:法规名称 */}
<div className={styles.regulationTitle}>
<img src={stipulation1} alt="法规图标" style={{ width: '20px', height: '20px', marginRight: '4px' }} />
2025排污许可条例
</div>
{/* 第二行:发布时间和发布部门 */}
<div className={styles.regulationInfo}>
<div className={styles.publishDate}>
发布时间&nbsp;&nbsp;&nbsp;&nbsp;2025-09-04
</div>
<div className={styles.publishDepartment}>
发布部门&nbsp;&nbsp;&nbsp;&nbsp;环保部门名称
</div>
</div>
{/* 第三行:操作按钮 */}
<div className={styles.actionButtons}>
<div
className={styles.actionButton}
onClick={() => showDrawer(mockRegulationDetail)}
style={{ cursor: 'pointer' }}
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" fill="#D8D8D8"/>
</svg>
</div>
<div className={styles.actionButton}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="#D8D8D8"/>
</svg>
</div>
</div>
</div>
</div>
</div>
{/* 静态分页组件 */}
<div className={styles.paginationContainer}>
<div className={styles.pagination}>
<span className={styles.totalItems}>共85条</span>
{/* <select className={styles.pageSizeSelect}>
<option value="10">10 / page</option>
</select> */}
<button className={styles.pageButton}>&lt;</button>
<button className={styles.pageButton}>1</button>
<span className={styles.ellipsis}>...</span>
<button className={styles.pageButton}>4</button>
<button className={styles.pageButton}>5</button>
<button className={`${styles.pageButton} ${styles.active}`}>6</button>
<button className={styles.pageButton}>7</button>
<button className={styles.pageButton}>8</button>
<span className={styles.ellipsis}>...</span>
<button className={styles.pageButton}>50</button>
<button className={styles.pageButton}>&gt;</button>
</div>
</div>
{/* 抽屉详情 */}
<Drawer
title="法规详情"
width={600}
placement="right"
onClose={onCloseDrawer}
visible={drawerVisible}
maskClosable={true}
>
{selectedRegulation && (
<Descriptions bordered column={1} size="middle">
<Descriptions.Item label="法规名称">
{selectedRegulation.name}
</Descriptions.Item>
<Descriptions.Item label="发布日期">
{selectedRegulation.publishDate}
</Descriptions.Item>
<Descriptions.Item label="发布部门">
{selectedRegulation.department}
</Descriptions.Item>
<Descriptions.Item label="法规状态">
<Tag color="green">{selectedRegulation.status}</Tag>
</Descriptions.Item>
<Descriptions.Item label="法规类别">
{selectedRegulation.category}
</Descriptions.Item>
<Descriptions.Item label="版本号">
{selectedRegulation.version}
</Descriptions.Item>
<Descriptions.Item label="更新时间">
{selectedRegulation.updateTime}
</Descriptions.Item>
<Descriptions.Item label="法规内容">
<div style={{ whiteSpace: 'pre-wrap', maxHeight: '300px', overflow: 'auto' }}>
{selectedRegulation.content}
</div>
</Descriptions.Item>
</Descriptions>
)}
</Drawer>
</div>
);
};
export default RegulationCompliance;

@ -1,204 +0,0 @@
.regulationContainer {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.searchSection {
padding: 20px;
background-color: #fff;
:global {
.ant-form-inline {
display: flex;
.ant-form-item {
margin-right: 16px;
margin-bottom: 0;
}
.ant-form-item:nth-last-child(2) {
margin-left: auto;
}
.ant-form-item:last-child {
margin-right: 0;
}
}
.ant-form-item-label {
font-weight: 500;
label {
color: #666666;
font-size: 13px;
}
}
.ant-input::placeholder,
.ant-picker-input input::placeholder {
color: #00000040;
font-size: 13px;
}
}
}
.tableSection {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 20px;
.blocksContainer {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 20px;
margin-bottom: 20px;
}
.regulationBlock {
background-color: #fff;
// border: 1px solid #EEEEEE;
border-radius: 2px;
// padding: 8px 16px;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 120px;
}
.regulationTitle {
font-size: 14px;
font-weight: 500;
color: #333333;
padding: 8px 16px;
border: 1px solid #EEEEEE;
border-bottom: none;
margin-bottom: 0;
display: flex;
align-items: center;
}
.regulationInfo {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 15px;
border: 1px solid #EEEEEE;
border-bottom: none;
margin-bottom: 0;
}
.publishDate {
font-size: 12px;
color: #666666;
font-weight: 400;
margin-bottom: 6px;
}
.publishDepartment {
font-size: 12px;
color: #666666;
font-weight: 400;
}
.actionButtons {
display: flex;
justify-content: center;
gap: 8px;
width: 100%;
// margin-bottom: 0;
border: 1px solid #EEEEEE;
border-bottom: none;
// padding-top: 4px;
}
.actionButton {
width: calc(50% - 4px);
height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border-radius: 2px;
transition: background-color 0.2s;
&:hover {
background-color: #f5f5f5;
}
}
}
.paginationContainer {
position: fixed;
bottom: 10px;
right: 10px;
z-index: 1000;
}
.pagination {
display: flex;
align-items: center;
gap: 8px;
// background: #fff;
padding: 8px 30px;
border-radius: 4px;
// box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.totalItems {
font-size: 12px;
color: #666;
margin-right: 8px;
}
.pageSizeSelect {
font-size: 12px;
border: 1px solid #d9d9d9;
border-radius: 2px;
padding: 2px 6px;
margin-right: 8px;
background: #fff;
}
.pageButton {
width: 28px;
height: 28px;
border: 1px solid #d9d9d9;
background: #fff;
color: #333;
font-size: 12px;
border-radius: 2px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
&:hover {
border-color: #00D48A;
color: #00D48A;
}
&.active {
background: #00D48A;
border-color: #00D48A;
color: #fff;
}
}
.ellipsis {
font-size: 12px;
color: #999;
padding: 0 4px;
}
}

@ -1,13 +0,0 @@
import React from 'react';
import styles from './SupervisionInspection.less';
const SupervisionInspection = () => {
return (
<div className={styles.container}>
<div className={styles.content}>待开发</div>
</div>
);
};
export default SupervisionInspection;

@ -1,15 +0,0 @@
.container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
.content {
font-size: 24px;
color: #999999;
font-weight: 400;
}
}

@ -1,803 +0,0 @@
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 './WasteGasPollutionControl.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 WasteGasPollutionControl = () => {
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',
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: 2,
recordTime: '2025-09-02',
recorder: '王嘉琪',
reviewer: '赵子能',
facilityName: '复方水杨酸甲酯乳膏(曼秀雷敦)',
code: '65.177.48.116',
equipmentModel: '3D8d4ffa-bD7e-AffF-ED68-839DAFe74c27',
parameterName: '重量',
designValue: '2',
unit: 't',
startRunTime: '14:10',
endRunTime: '03:06',
isNormal: '异常',
pollutantFlueGasVolume: '2',
pollutantFactor: '烟尘2',
treatmentEfficiency: '93.81',
dataSource: '实时采集',
exhaustStackHeight: '2',
exhaustTemperature: '59.12',
pressure: '95',
emissionTime: '100',
powerConsumption: '34',
byproductName: '二氧化碳',
byproductProduction: '2',
reagentName: '乳酸钠葡萄糖',
reagentAdditionTime: '2025-08-24 05:16',
reagentAdditionAmount: '2',
},
{
key: 3,
recordTime: '2025-09-06',
recorder: '王嘉琪',
reviewer: '郑清予',
facilityName: '口炎清颗粒(大神)',
code: '111.161.135.125',
equipmentModel: '19b89E82-ae94-6bF7-2355-8DBC2d6a6009',
parameterName: '重量',
designValue: '2',
unit: 't',
startRunTime: '12:26',
endRunTime: '03:26',
isNormal: '异常',
pollutantFlueGasVolume: '2',
pollutantFactor: '烟尘',
treatmentEfficiency: '91.40',
dataSource: '实时采集',
exhaustStackHeight: '2',
exhaustTemperature: '59.95',
pressure: '90',
emissionTime: '95',
powerConsumption: '55',
byproductName: '二氧化碳',
byproductProduction: '2',
reagentName: '乳酸钠葡萄糖',
reagentAdditionTime: '2025-08-30 18:34',
reagentAdditionAmount: '2',
},
{
key: 4,
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: 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: '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: 'equipmentModel',
key: 'equipmentModel',
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: 'pollutantFlueGasVolume',
key: 'pollutantFlueGasVolume',
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: '排气筒高度(m)',
dataIndex: 'exhaustStackHeight',
key: 'exhaustStackHeight',
width: 130,
align: 'center',
},
{
title: '排气温度(℃)',
dataIndex: 'exhaustTemperature',
key: 'exhaustTemperature',
width: 130,
align: 'center',
},
{
title: '压力(kpa)',
dataIndex: 'pressure',
key: 'pressure',
width: 100,
align: 'center',
},
{
title: '排放时间(h)',
dataIndex: 'emissionTime',
key: 'emissionTime',
width: 120,
align: 'center',
},
{
title: '耗电量(kWh)',
dataIndex: 'powerConsumption',
key: 'powerConsumption',
width: 120,
align: 'center',
},
{
title: '副产物名称',
dataIndex: 'byproductName',
key: 'byproductName',
width: 120,
align: 'center',
},
{
title: '副产物产生量(t)',
dataIndex: 'byproductProduction',
key: 'byproductProduction',
width: 140,
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.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>
{/* <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 WasteGasPollutionControl;

@ -1,205 +0,0 @@
.wasteGasContainer {
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;
}
}
}
}

@ -1,746 +0,0 @@
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;

@ -1,206 +0,0 @@
.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;
}
}
}
}

@ -1,11 +1,283 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjdw.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjdw = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
应急队伍内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急队伍</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

@ -1,11 +1,283 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjssd.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjssd = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
应急疏散点内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急疏散点</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

@ -1,11 +1,283 @@
import React from 'react';
import styles from './yjwz.less';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjdw.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjwz = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
应急物资内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急队伍</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

@ -1,11 +1,283 @@
import React from 'react';
import styles from './yjxf.less';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjzbry.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjxf = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
应急消防点内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急值班人员</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

@ -0,0 +1,286 @@
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjxfd.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjxfd = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急消防电</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);
};
export default Yjxfd;

@ -0,0 +1,122 @@
.container {
padding: 20px;
background: #f5f5f5;
min-height: 100vh;
}
.header {
margin-bottom: 20px;
display: flex;
align-items: center;
}
.titleBar {
width: 4px;
height: 20px;
background: #1890ff;
margin-right: 10px;
}
.title {
margin: 0;
font-size: 18px;
font-weight: 500;
color: #333;
}
.searchBar {
background: #fff;
padding: 20px;
border-radius: 6px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
.customButton {
height: 30px !important;
border-radius: 2px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.tableContainer {
background: #fff;
border-radius: 6px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.actionButtons {
display: flex;
gap: 8px;
}
.actionButtons .ant-btn-link {
padding: 0;
height: auto;
line-height: 1;
}
.actionButtons .ant-btn-link:hover {
background: transparent;
}
// 覆盖全局按钮样式
:global(.ant-btn) {
height: 28px !important;
border-radius: 2px !important;
}
:global(.ant-select) {
.ant-select-selector {
height: 30px !important;
border-radius: 2px !important;
}
}
:global(.ant-input) {
height: 30px !important;
border-radius: 2px !important;
}
:global(.ant-table) {
.ant-table-thead > tr > th {
background: #fafafa;
font-weight: 500;
color: #333;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
:global(.ant-pagination-item) {
border-radius: 2px;
}
:global(.ant-pagination-prev),
:global(.ant-pagination-next) {
border-radius: 2px;
}

@ -4,6 +4,8 @@ import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant
import StandardTable from '@/components/StandardTable';
import styles from './yjzbry.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjzbry = () => {
@ -222,9 +224,9 @@ const Yjzbry = () => {
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
style={{ width: 180 }}
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
@ -237,6 +239,7 @@ const Yjzbry = () => {
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
@ -246,12 +249,14 @@ const Yjzbry = () => {
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
icon={<DeleteOutlined />}
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除

@ -7,6 +7,7 @@
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
@ -45,6 +46,37 @@
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;

@ -1,11 +1,283 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjzj.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Yjzj = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
应急专家内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急专家</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

@ -1,11 +1,283 @@
import React from 'react';
import styles from './zbhy.less';
import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './yjzbry.less';
import iconsc from '@/assets/yjzygl/iconsc.svg';
const { Option } = Select;
const Zbhy = () => {
const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState('');
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 48,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) => `${total}`,
});
// 模拟数据
const [dataSource, setDataSource] = useState([
{
key: '1',
number: '01',
unitName: '文登市兴文新材料有限公司',
name: '国云海',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '2',
number: '02',
unitName: '文登市兴文新材料有限公司',
name: '陈志强',
position: '生产班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '3',
number: '03',
unitName: '合湾新材科技有限公司',
name: '侯文涛',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '白班',
},
{
key: '4',
number: '04',
unitName: '山东万图高分子材料股份有限公司',
name: '宋东',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '5',
number: '05',
unitName: '合鸿新材科技有限公司',
name: '王一声',
position: '班长',
mobile: '17898786567',
email: '1878967633@qq.com',
dutyTime: '夜班',
},
{
key: '6',
number: '06',
unitName: '山东万图高分子材料股份有限公司',
name: '赵小敏',
position: '班长',
mobile: '17898786567',
email: '1878987633@qq.com',
dutyTime: '夜班',
},
]);
// 表格列配置
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
},
{
title: '单位名称',
dataIndex: 'unitName',
key: 'unitName',
width: 200,
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: '职务',
dataIndex: 'position',
key: 'position',
width: 120,
},
{
title: '手机号',
dataIndex: 'mobile',
key: 'mobile',
width: 130,
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email',
width: 180,
},
{
title: '值班时间',
dataIndex: 'dutyTime',
key: 'dutyTime',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (text, record) => (
<div className={styles.actionButtons}>
<Button
type="link"
size="small"
// icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
修改
</Button>
<Button
type="link"
size="small"
danger
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</div>
),
},
];
// 搜索处理
const handleSearch = () => {
setLoading(true);
// 模拟搜索请求
setTimeout(() => {
setLoading(false);
message.success('查询完成');
}, 1000);
};
// 新增处理
const handleAdd = () => {
message.info('新增功能待实现');
};
// 批量删除处理
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
message.warning('请选择要删除的数据');
return;
}
Modal.confirm({
title: '确认删除',
content: `确定要删除选中的 ${selectedRowKeys.length} 条数据吗?`,
onOk() {
setDataSource(dataSource.filter(item => !selectedRowKeys.includes(item.key)));
setSelectedRowKeys([]);
message.success('删除成功');
},
});
};
// 编辑处理
const handleEdit = (record) => {
message.info(`编辑 ${record.name} 的信息`);
};
// 删除处理
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除 ${record.name} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
};
// 分页处理
const handleTableChange = (pagination) => {
setPagination(pagination);
};
return (
<div className={styles.container}>
<div className={styles.content}>
周边医院内容
{/* 页面标题 */}
<div className={styles.header}>
<div className={styles.titleBar}></div>
<h2 className={styles.title}>应急值班人员</h2>
</div>
{/* 搜索和操作区域 */}
<div className={styles.searchBar}>
<div className={styles.searchLeft}>
<Select
placeholder="请选择单位名称"
value={searchValue}
onChange={setSearchValue}
style={{width: 180, height: 30, borderRadius: 2}}
allowClear
>
<Option value="文登市兴文新材料有限公司">文登市兴文新材料有限公司</Option>
<Option value="合湾新材科技有限公司">合湾新材科技有限公司</Option>
<Option value="山东万图高分子材料股份有限公司">山东万图高分子材料股份有限公司</Option>
<Option value="合鸿新材科技有限公司">合鸿新材科技有限公司</Option>
</Select>
<Button
type="primary"
icon={<SearchOutlined />}
onClick={handleSearch}
loading={loading}
className={styles.customButton}
>
查询
</Button>
</div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
<Button
danger
style={{width: 70, height: 30, borderRadius: 2, display: 'flex', alignItems: 'center', justifyContent: 'center'}}
icon={<img src={iconsc} alt="delete" style={{width: 14, height: 14, marginTop: -2}}/>}
onClick={handleBatchDelete}
>
删除
</Button>
</div>
</div>
{/* 数据表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: dataSource,
pagination: pagination
}}
rowKey="key"
selectedRows={selectedRowKeys}
onSelectRow={setSelectedRowKeys}
onChange={handleTableChange}
loading={loading}
/>
</div>
</div>
);

@ -1,10 +1,138 @@
.container {
padding: 20px;
background-color: #EBF0FE;
min-height: 100vh;
background: #fff;
height:100vh;
}
.content {
.header {
display: flex;
align-items: center;
// background-color: pink;
margin-bottom: 15px;
.titleBar {
width: 3px;
height: 16px;
background: #2E4CD4;
margin-right: 12px;
}
.title {
margin: 0;
font-size: 14px;
font-weight: 500;
color: #333;
}
}
.searchBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding: 5px;
.searchLeft {
display: flex;
align-items: center;
gap: 12px;
}
.searchRight {
display: flex;
align-items: center;
gap: 12px;
}
}
// 自定义按钮样式
.customButton {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
border-radius: 2px !important;
height: 30px !important;
width: 75px;
display: flex !important;
align-items: center !important;
justify-content: center !important;
&:hover {
background-color: #1e3bb8 !important;
border-color: #1e3bb8 !important;
}
&:focus {
background-color: #2E4CD4 !important;
border-color: #2E4CD4 !important;
}
}
// // 所有按钮统一样式
// .ant-btn {
// border-radius: 4px !important;
// height: 28px !important;
// display: flex !important;
// align-items: center !important;
// justify-content: center !important;
// }
.tableContainer {
background: #fff;
border-radius: 0px;
overflow: hidden;
.actionButtons {
display: flex;
gap: 8px;
font-size: 10px;
justify-content: center;
.ant-btn-link {
padding: 0;
height: auto;
font-size: 10px;
}
}
}
// 表格样式优化
.tableContainer {
:global {
.ant-table-thead > tr > th {
background: #F5F5FA;
font-weight: 500;
color: #333333;
font-size: 14px;
text-align: center;
}
.ant-table-tbody > tr > td {
color: #666666;
font-size: 13px;
text-align: center;
}
.ant-table-tbody > tr:hover > td {
background: #f5f5f5;
}
.ant-pagination {
margin-top: 10px;
text-align: right;
}
// 覆盖操作列按钮样式
.ant-btn.ant-btn-sm {
font-size: 13px !important;
height: 20px !important;
padding: 0px 4px !important;
}
.ant-btn-link.ant-btn-sm {
font-size: 13px !important;
height: auto !important;
padding: 0 !important;
}
}
}

Loading…
Cancel
Save