处置救援

main
wangyunfei 2 months ago
parent 4a9b30d821
commit 186a92a581

@ -1,10 +1,10 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Input, Button, Select, message, Modal } from 'antd'; import { Input, Button, Select, message, Modal, DatePicker } from 'antd';
import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'; import { SearchOutlined, PlusOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable'; import StandardTable from '@/components/StandardTable';
import styles from './czjy.less'; import styles from './czjy.less';
import iconsc from '@/assets/yjzygl/iconsc.svg'; import iconDrill5 from '@/assets/business_Emergency/iconDrill5.svg';
const { Option } = Select; const { Option } = Select;
@ -12,6 +12,7 @@ const Czjy = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState(undefined); const [searchValue, setSearchValue] = useState(undefined);
const [dateRange, setDateRange] = useState([null, null]);
const [pagination, setPagination] = useState({ const [pagination, setPagination] = useState({
current: 1, current: 1,
pageSize: 10, pageSize: 10,
@ -25,177 +26,221 @@ const Czjy = () => {
const [dataSource, setDataSource] = useState([ const [dataSource, setDataSource] = useState([
{ {
key: '1', key: '1',
number: '01', type: '泄漏',
fireName: '消防点一', time: '2025-10-10 17:08:13',
waterPointName: '消防池 01', location: '一号仓库',
hydrantCount: 97, event: '储罐气体泄漏',
hydrantLocation: '一楼走廊', emergencyResource: '---',
range: 97, hazardSource: '储罐',
waterType: '企业消防水池', protectionTarget: '泄露区域人员',
personInCharge: '冯钰涛', shelterPlace: '应急路散点',
fireImage: '点击查看图片', commandPlan: '泄漏应急指挥方案',
remarks: '无', rescuePlan: '救援方案一',
guaranteePlan: '---',
emergencyPlan: '应急预案',
}, },
{ {
key: '2', key: '2',
number: '02', type: '火灾',
fireName: '消防点二', time: '2025-10-08 09:21:56',
waterPointName: '消防池 02', location: '三楼会议室',
hydrantCount: 96, event: '电路老化起火',
hydrantLocation: '二楼走廊', emergencyResource: '---',
range: 96, hazardSource: '挥源',
waterType: '企业消防水池', protectionTarget: '区域内人员及物资',
personInCharge: '周静', shelterPlace: '应急路散点',
fireImage: '点击查看图片', commandPlan: '火灾应急指挥方案',
remarks: '备注二二', rescuePlan: '救援方案二',
guaranteePlan: '---',
emergencyPlan: '应急预案',
}, },
]);
// 表格列配置
const columns = [
{ {
key: '3', title: '类型',
number: '03', dataIndex: 'type',
fireName: '消防点三', key: 'type',
waterPointName: '消防池 03', width: 80,
hydrantCount: 91, align: 'center',
hydrantLocation: '三楼图书馆门口',
range: 91,
waterType: '企业消防水池',
personInCharge: '何能',
fireImage: '点击查看图片',
remarks: '备注三三',
}, },
{ {
key: '4', title: '应急事件',
number: '04', key: 'emergencyEvent',
fireName: '消防点四', children: [
waterPointName: '消防池 04', {
hydrantCount: 59, title: '时间',
hydrantLocation: '三楼应急通道口', dataIndex: 'time',
range: 59, key: 'time',
waterType: '企业消防水池', width: 160,
personInCharge: '冯新', align: 'center',
fireImage: '点击查看图片', onHeaderCell: () => ({
remarks: '备注四四', style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
})
}, },
{ {
key: '5', title: '地点',
number: '05', dataIndex: 'location',
fireName: '消防点五', key: 'location',
waterPointName: '消防池 05', width: 100,
hydrantCount: 50, align: 'center',
hydrantLocation: '负一层东侧走廊', onHeaderCell: () => ({
range: 50, style: { borderWidth: '1px 0px 0px 1px' }
waterType: '企业消防水池', }),
personInCharge: '赵俊英', onCell: () => ({
fireImage: '点击查看图片', style: { borderWidth: '1px 0px 1px 1px' }
remarks: '备注五五', })
}, },
{ {
key: '6', title: '事件',
number: '06', dataIndex: 'event',
fireName: '消防点六', key: 'event',
waterPointName: '消防池 06', width: 120,
hydrantCount: 48, align: 'center',
hydrantLocation: '四楼c西侧走廊', onHeaderCell: () => ({
range: 48, style: { borderWidth: '1px 1px 0px 1px' }
waterType: '企业消防水池', }),
personInCharge: '赵中琏', onCell: () => ({
fireImage: '点击查看图片', style: { borderWidth: '1px 1px 1px 1px' }
remarks: '备注六六', })
}, },
]);
// 表格列配置 ],
const columns = [
{
title: '编号',
dataIndex: 'number',
key: 'number',
width: 80,
}, },
{ {
title: '消防点名称', title: '联动分析',
dataIndex: 'fireName', key: 'linkageAnalysis',
key: 'fireName', children: [
width: 120,
},
{ {
title: '消防取水点名称', title: '应急资源',
dataIndex: 'waterPointName', dataIndex: 'emergencyResource',
key: 'waterPointName', key: 'emergencyResource',
width: 140, width: 90,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
})
}, },
{ {
title: '消防栓数量', title: '危险源',
dataIndex: 'hydrantCount', dataIndex: 'hazardSource',
key: 'hydrantCount', key: 'hazardSource',
width: 110, width: 90,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
})
}, },
{ {
title: '消防栓位置', title: '防护目标',
dataIndex: 'hydrantLocation', dataIndex: 'protectionTarget',
key: 'hydrantLocation', key: 'protectionTarget',
width: 150, width: 160,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
})
}, },
{ {
title: '射程', title: '避难场所',
dataIndex: 'range', dataIndex: 'shelterPlace',
key: 'range', key: 'shelterPlace',
width: 80, width: 120,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 1px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 1px 1px 1px' }
})
}, },
{
title: '消防栓用水类型', ],
dataIndex: 'waterType',
key: 'waterType',
width: 140,
}, },
{ {
title: '负责人', title: '应急预案',
dataIndex: 'personInCharge', key: 'emergencyPlan',
key: 'personInCharge', children: [{
width: 100, title: '指挥方案',
dataIndex: 'commandPlan',
key: 'commandPlan',
width: 160,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
})
}, },
{ {
title: '消防点图片', title: '救援方案',
dataIndex: 'fireImage', dataIndex: 'rescuePlan',
key: 'fireImage', key: 'rescuePlan',
width: 120, width: 120,
render: (text) => ( align: 'center',
<Button onHeaderCell: () => ({
type="link" style: { borderWidth: '1px 0px 0px 1px' }
size="small" }),
onClick={() => message.info('查看图片功能待实现')} onCell: () => ({
> style: { borderWidth: '1px 0px 1px 1px' }
{text} })
</Button>
),
}, },
{ {
title: '备注', title: '保障方案',
dataIndex: 'remarks', dataIndex: 'guaranteePlan',
key: 'remarks', key: 'guaranteePlan',
width: 100, width: 100,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 1px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 1px 1px 1px' }
})
},
]
}, },
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
width: 120, width: 120,
align: 'center',
onHeaderCell: () => ({
style: { borderWidth: '1px 0px 0px 1px' }
}),
onCell: () => ({
style: { borderWidth: '1px 0px 1px 1px' }
}),
render: (text, record) => ( render: (text, record) => (
<div className={styles.actionButtons}> <div className={styles.actionButtons}>
<Button <Button
type="link" type="link"
size="small" size="small"
// icon={<EditOutlined />} onClick={() => handleUpload(record)}
onClick={() => handleEdit(record)}
> >
修改 上传
</Button> </Button>
<Button <Button
type="link" type="link"
size="small" size="small"
danger onClick={() => handleDistribute(record)}
// icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
> >
删除 分发
</Button> </Button>
</div> </div>
), ),
@ -234,21 +279,14 @@ const Czjy = () => {
}); });
}; };
// 编辑处理 // 上传处理
const handleEdit = (record) => { const handleUpload = (record) => {
message.info(`编辑 ${record.fireName} 的信息`); message.info(`上传 ${record.type} 事件的相关资料`);
}; };
// 删除处理 // 分发处理
const handleDelete = (record) => { const handleDistribute = (record) => {
Modal.confirm({ message.info(`分发 ${record.type} 事件的应急预案`);
title: '确认删除',
content: `确定要删除 ${record.fireName} 吗?`,
onOk() {
setDataSource(dataSource.filter(item => item.key !== record.key));
message.success('删除成功');
},
});
}; };
// 分页处理 // 分页处理
@ -257,37 +295,68 @@ const Czjy = () => {
}; };
return ( return (
<div className={styles.containerCZYJ}> <div className={styles.containerCzjy}>
{/* 页面标题 */} {/* 页面标题 */}
<div className={styles.header}> <div className={styles.header}>
<div className={styles.titleBar}></div> <div className={styles.titleBar}></div>
<h2 className={styles.title}>处置救援</h2> <h2 className={styles.title}>处置经验</h2>
</div> </div>
{/* 搜索和操作区域 */} {/* 搜索和操作区域 */}
<div className={styles.searchBar}> <div className={styles.searchBar}>
<div className={styles.searchLeft}> <div className={styles.searchLeft}>
<div className={styles.searchItem}>
<span className={styles.searchLabel}>事件时间:</span>
<div style={{ display: 'flex', alignItems: 'center', border: '1px solid #DDDEE6', borderRadius: '2px' }}>
<div className={styles.datePickerWithIcon}>
<img src={iconDrill5} alt="日期icon" className={styles.dateIcon} />
<DatePicker
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
value={dateRange ? dateRange[0] : null}
onChange={(value) => {
setDateRange([value, dateRange ? dateRange[1] : null]);
}}
placeholder="请输入日期"
className={styles.datePickerFirst}
suffixIcon={null}
/>
</div>
{/* 短线 */}
<div className={styles.dateSeparator}></div>
<div className={styles.datePickerWithIcon}>
<img src={iconDrill5} alt="日期icon" className={styles.dateIcon} />
<DatePicker
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
value={dateRange ? dateRange[1] : null}
onChange={(value) => {
setDateRange([dateRange ? dateRange[0] : null, value]);
}}
placeholder="请输入日期"
className={styles.datePickerFirst}
suffixIcon={null}
/>
</div>
</div>
</div>
<Select <Select
placeholder="事故类型" placeholder="事故地点"
value={searchValue} value={searchValue}
onChange={setSearchValue} onChange={setSearchValue}
style={{ width: 180 }} style={{ width: 180 }}
className={styles.customSelect} className={styles.customSelect}
allowClear allowClear
> >
<Option value="火灾事故">火灾事故</Option> <Option value="一号仓库">一号仓库</Option>
<Option value="爆炸事故">爆炸事故</Option> <Option value="二号仓库">二号仓库</Option>
<Option value="危化品泄漏">危化品泄漏</Option> <Option value="三号仓库">三号仓库</Option>
<Option value="触电事故">触电事故</Option> <Option value="三楼会议室">三楼会议室</Option>
<Option value="高处坠落">高处坠落</Option> <Option value="生产车间">生产车间</Option>
<Option value="其他事故">其他事故</Option> <Option value="其他">其他</Option>
</Select> </Select>
<Input
placeholder="输入报警人"
style={{width: 180}}
className={styles.customInput}
allowClear
/>
<Button <Button
type="primary" type="primary"
icon={<SearchOutlined />} icon={<SearchOutlined />}
@ -298,16 +367,6 @@ const Czjy = () => {
查询 查询
</Button> </Button>
</div> </div>
<div className={styles.searchRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={handleAdd}
className={styles.customButton}
>
新增
</Button>
</div>
</div> </div>
{/* 数据表格 */} {/* 数据表格 */}

@ -1,4 +1,4 @@
.containerCZYJ { .containerCzjy {
padding: 20px; padding: 20px;
background: #fff; background: #fff;
height:100vh; height:100vh;
@ -32,18 +32,132 @@
margin-bottom: 10px; margin-bottom: 10px;
padding: 5px; padding: 5px;
.searchItem {
display: flex;
align-items: center;
gap: 8px;
.searchLeft { .searchLabel {
font-size: 13px;
color: #333333;
white-space: nowrap;
}
.datePickerWithIcon {
display: inline-flex;
align-items: center;
height: 30px;
border: none;
.dateIcon {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; padding: 0 0px 0 14px;
border: none;
}
.datePickerFirst {
height: 28px;
width: 125px;
border: none;
:global {
.ant-picker-input>input::placeholder {
color: #666 !important;
font-size: 13px;
}
}
}
:global {
.ant-picker-focused {
box-shadow: none;
}
}
.datePicker {
flex: 1;
border: none;
background: transparent;
}
}
.dateSeparator {
width: 12px;
height: 1px;
background-color: #999;
flex-shrink: 0;
}
.dateInput {
width: 150px;
height: 32px;
padding: 0 12px;
border: none;
font-size: 13px;
outline: none;
transition: all 0.3s;
&:focus {
border-color: #2E4CD4;
}
&::placeholder {
color: #666;
}
}
.companyInput {
width: 150px;
height: 31px;
padding: 0 8px;
border: 1px solid #D9D9D9;
border-radius: 2px;
font-size: 13px;
outline: none;
transition: all 0.3s;
&:focus {
border-color: #2E4CD4;
}
&::placeholder {
color: #666;
}
}
.unitSelect {
color: #666;
width: 150px;
height: 31px;
padding: 0 6px;
border: 1px solid #D9D9D9;
border-radius: 2px;
font-size: 13px;
outline: none;
background-color: #FFFFFF;
cursor: pointer;
transition: all 0.3s;
&:focus {
border-color: #2E4CD4;
}
option {
padding: 8px;
}
}
} }
.searchRight { .searchLeft {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 12px;
} }
} }
// 自定义 Select 样式 // 自定义 Select 样式
@ -67,19 +181,11 @@
.ant-select-selection-placeholder { .ant-select-selection-placeholder {
color: #666 !important; color: #666 !important;
font-size: 13px !important;
} }
} }
} }
// 自定义 Input 样式
.customInput {
height: 30px !important;
border-radius: 2px !important;
&::placeholder {
color: #666 !important;
}
}
// 自定义按钮样式 // 自定义按钮样式
.customButton { .customButton {
@ -88,6 +194,7 @@
border-radius: 2px !important; border-radius: 2px !important;
height: 30px !important; height: 30px !important;
width: 75px; width: 75px;
font-size: 13px !important;
display: flex !important; display: flex !important;
align-items: center !important; align-items: center !important;
justify-content: center !important; justify-content: center !important;
@ -134,20 +241,38 @@
// 表格样式优化 // 表格样式优化
.tableContainer { .tableContainer {
:global { :global {
// 表格边框合并,避免重复叠加
.ant-table {
border: 1px solid #E2E2E2;
border-radius: 2px;
}
.ant-table-thead > tr > th { .ant-table-thead > tr > th {
background: #F5F5FA; background: #F5F5FA;
font-weight: 500; font-weight: 500;
color: #333333; color: #333333;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
border-right: 1px solid #E2E2E2;
border-bottom: 1px solid #E2E2E2;
}
// 覆盖 Ant Design 的默认样式,让有 colspan 的表头也显示下边框
.ant-table-thead > tr:not(:last-child) > th[colspan] {
border-bottom: 1px solid #E2E2E2 !important;
} }
.ant-table-tbody > tr > td { .ant-table-tbody > tr > td {
color: #666666; color: #666666;
font-size: 13px; font-size: 13px;
text-align: center; text-align: center;
border-right: 1px solid #E2E2E2;
border-bottom: 1px solid #E2E2E2;
} }
.ant-table-tbody > tr:hover > td { .ant-table-tbody > tr:hover > td {
background: #f5f5f5; background: #f5f5f5;
} }

Loading…
Cancel
Save