环保设备

main
wangyunfei 2 weeks ago
parent e5cbd53d42
commit 4e9c67ed3e

@ -1,16 +1,576 @@
import React from 'react'; import React, { useState } from 'react';
import { Button } from 'antd'; 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 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 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: 200,
},
{
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: 160,
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 ( return (
<div className={styles.protectionFacilityMaintenance}> <div className={styles.protectionFacilityContainer}>
<div className={styles.content}> {/* 第一块:操作按钮和筛选条件 */}
<Button type="primary" className={styles.button}>防护设施检维修管理</Button> <div className={styles.searchSection}>
<div className={styles.status}> <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>
<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> </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> </div>
); );
}; };

@ -1,49 +1,205 @@
.protectionFacilityMaintenance { .protectionFacilityContainer {
width: 100%; width: 100%;
height: 100%; height: 100%;
// padding: 20px;
background-color: #fff; background-color: #fff;
padding: 20px; display: flex;
flex-direction: column;
margin: 0;
padding: 0;
.header { .searchSection {
padding: 20px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 20px; margin-bottom: 16px;
padding-bottom: 15px;
border-bottom: 1px solid #e8e8e8;
.title {
font-size: 18px;
font-weight: 600;
color: #333;
}
.actions { .leftButtons {
display: flex; display: flex;
gap: 12px; gap: 12px;
align-items: center;
.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;
}
}
} }
}
.content { .rightControls {
.placeholder {
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
justify-content: center; gap: 12px;
height: 300px;
color: #666; .filterLabel {
font-size: 16px; 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;
.button { &:hover {
margin-bottom: 20px; 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;
}
}
}
.status { .ant-pagination {
font-size: 16px; text-align: right;
color: #666; margin-top: 25px !important;
text-align: center; }
} }
} }
} }

Loading…
Cancel
Save