You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

426 lines
12 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React, { useState, useEffect } from 'react';
import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag, Rate, Progress } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import './RiskAssessment.less';
const { Option } = Select;
const RiskAssessment = () => {
const [form] = Form.useForm();
const [dataSource, setDataSource] = useState([]);
const [loading, setLoading] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [editingRecord, setEditingRecord] = useState(null);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 10,
total: 0,
});
// 模拟数据
const mockData = [
{
id: 1,
riskName: '化学品泄漏风险',
riskType: '环境风险',
riskLevel: '高',
probability: 4,
impact: 5,
riskScore: 20,
assessor: '张三',
assessDate: '2024-01-15',
status: '待处理',
description: '生产过程中化学品可能发生泄漏,造成环境污染',
controlMeasures: '加强设备维护,安装泄漏检测装置',
},
{
id: 2,
riskName: '设备故障风险',
riskType: '设备风险',
riskLevel: '中',
probability: 3,
impact: 3,
riskScore: 9,
assessor: '李四',
assessDate: '2024-01-10',
status: '已处理',
description: '关键设备可能发生故障,影响生产安全',
controlMeasures: '定期维护保养,建立备件库存',
},
{
id: 3,
riskName: '人员操作风险',
riskType: '人员风险',
riskLevel: '低',
probability: 2,
impact: 2,
riskScore: 4,
assessor: '王五',
assessDate: '2024-01-08',
status: '监控中',
description: '操作人员误操作可能导致安全事故',
controlMeasures: '加强培训,完善操作规程',
},
];
useEffect(() => {
fetchData();
}, [pagination.current, pagination.pageSize]);
const fetchData = async () => {
setLoading(true);
try {
// 模拟API调用
setTimeout(() => {
setDataSource(mockData);
setPagination(prev => ({ ...prev, total: mockData.length }));
setLoading(false);
}, 500);
} catch (error) {
message.error('获取数据失败');
setLoading(false);
}
};
const handleAdd = () => {
setEditingRecord(null);
form.resetFields();
setModalVisible(true);
};
const handleEdit = (record) => {
setEditingRecord(record);
form.setFieldsValue(record);
setModalVisible(true);
};
const handleDelete = (record) => {
Modal.confirm({
title: '确认删除',
content: `确定要删除风险评估"${record.riskName}"吗?`,
onOk: () => {
setDataSource(dataSource.filter(item => item.id !== record.id));
message.success('删除成功');
},
});
};
const handleView = (record) => {
Modal.info({
title: '查看风险评估详情',
content: (
<div>
<p><strong>风险名称</strong>{record.riskName}</p>
<p><strong>风险类型</strong>{record.riskType}</p>
<p><strong>风险等级</strong>
<Tag color={record.riskLevel === '高' ? 'red' : record.riskLevel === '中' ? 'orange' : 'green'}>
{record.riskLevel}
</Tag>
</p>
<p><strong>发生概率</strong>
<Rate disabled value={record.probability} />
<span style={{ marginLeft: 8 }}>({record.probability}/5)</span>
</p>
<p><strong>影响程度</strong>
<Rate disabled value={record.impact} />
<span style={{ marginLeft: 8 }}>({record.impact}/5)</span>
</p>
<p><strong>风险评分</strong>{record.riskScore}</p>
<p><strong>评估人</strong>{record.assessor}</p>
<p><strong>评估日期</strong>{record.assessDate}</p>
<p><strong>处理状态</strong>
<Tag color={record.status === '已处理' ? 'green' : record.status === '待处理' ? 'red' : 'blue'}>
{record.status}
</Tag>
</p>
<p><strong>风险描述</strong>{record.description}</p>
<p><strong>控制措施</strong>{record.controlMeasures}</p>
</div>
),
width: 700,
});
};
const handleSubmit = async (values) => {
try {
const riskScore = values.probability * values.impact;
const riskLevel = riskScore >= 16 ? '高' : riskScore >= 9 ? '中' : '低';
const formData = {
...values,
riskScore,
riskLevel,
};
if (editingRecord) {
// 编辑
setDataSource(dataSource.map(item =>
item.id === editingRecord.id ? { ...item, ...formData } : item
));
message.success('编辑成功');
} else {
// 新增
const newRecord = {
id: Date.now(),
...formData,
assessor: '当前用户',
assessDate: new Date().toISOString().split('T')[0],
status: '待处理',
};
setDataSource([...dataSource, newRecord]);
message.success('添加成功');
}
setModalVisible(false);
form.resetFields();
} catch (error) {
message.error('操作失败');
}
};
const getRiskLevelColor = (level) => {
switch (level) {
case '高': return 'red';
case '中': return 'orange';
case '低': return 'green';
default: return 'default';
}
};
const getStatusColor = (status) => {
switch (status) {
case '已处理': return 'green';
case '待处理': return 'red';
case '监控中': return 'blue';
default: return 'default';
}
};
const columns = [
{
title: '风险名称',
dataIndex: 'riskName',
key: 'riskName',
width: 150,
},
{
title: '风险类型',
dataIndex: 'riskType',
key: 'riskType',
width: 120,
},
{
title: '风险等级',
dataIndex: 'riskLevel',
key: 'riskLevel',
width: 100,
render: (level) => (
<Tag color={getRiskLevelColor(level)}>
{level}
</Tag>
),
},
{
title: '风险评分',
dataIndex: 'riskScore',
key: 'riskScore',
width: 100,
render: (score) => (
<div>
<Progress
percent={(score / 25) * 100}
size="small"
status={score >= 16 ? 'exception' : score >= 9 ? 'active' : 'success'}
showInfo={false}
/>
<span style={{ fontSize: '12px' }}>{score}</span>
</div>
),
},
{
title: '发生概率',
dataIndex: 'probability',
key: 'probability',
width: 120,
render: (probability) => (
<div>
<Rate disabled value={probability} style={{ fontSize: '12px' }} />
<span style={{ marginLeft: 4, fontSize: '12px' }}>({probability}/5)</span>
</div>
),
},
{
title: '影响程度',
dataIndex: 'impact',
key: 'impact',
width: 120,
render: (impact) => (
<div>
<Rate disabled value={impact} style={{ fontSize: '12px' }} />
<span style={{ marginLeft: 4, fontSize: '12px' }}>({impact}/5)</span>
</div>
),
},
{
title: '处理状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (status) => (
<Tag color={getStatusColor(status)}>
{status}
</Tag>
),
},
{
title: '评估人',
dataIndex: 'assessor',
key: 'assessor',
width: 100,
},
{
title: '评估日期',
dataIndex: 'assessDate',
key: 'assessDate',
width: 120,
},
{
title: '操作',
key: 'action',
width: 200,
render: (_, record) => (
<Space size="small">
<Button
type="link"
icon={<EyeOutlined />}
onClick={() => handleView(record)}
>
查看
</Button>
<Button
type="link"
icon={<EditOutlined />}
onClick={() => handleEdit(record)}
>
编辑
</Button>
<Button
type="link"
danger
icon={<DeleteOutlined />}
onClick={() => handleDelete(record)}
>
删除
</Button>
</Space>
),
},
];
return (
<div className="risk-assessment">
<Card
title="风险评估管理"
extra={
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
新增评估
</Button>
}
>
<Table
columns={columns}
dataSource={dataSource}
loading={loading}
rowKey="id"
pagination={{
...pagination,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total, range) =>
`${range[0]}-${range[1]} 条/共 ${total}`,
onChange: (page, pageSize) => {
setPagination(prev => ({
...prev,
current: page,
pageSize: pageSize || prev.pageSize,
}));
},
}}
/>
</Card>
<Modal
title={editingRecord ? '编辑风险评估' : '新增风险评估'}
open={modalVisible}
onCancel={() => {
setModalVisible(false);
form.resetFields();
}}
onOk={() => form.submit()}
width={700}
>
<Form
form={form}
layout="vertical"
onFinish={handleSubmit}
>
<Form.Item
name="riskName"
label="风险名称"
rules={[{ required: true, message: '请输入风险名称' }]}
>
<Input placeholder="请输入风险名称" />
</Form.Item>
<Form.Item
name="riskType"
label="风险类型"
rules={[{ required: true, message: '请选择风险类型' }]}
>
<Select placeholder="请选择风险类型">
<Option value="环境风险">环境风险</Option>
<Option value="设备风险">设备风险</Option>
<Option value="人员风险">人员风险</Option>
<Option value="管理风险">管理风险</Option>
<Option value="技术风险">技术风险</Option>
</Select>
</Form.Item>
<Form.Item
name="probability"
label="发生概率 (1-5分)"
rules={[{ required: true, message: '请选择发生概率' }]}
>
<Rate />
</Form.Item>
<Form.Item
name="impact"
label="影响程度 (1-5分)"
rules={[{ required: true, message: '请选择影响程度' }]}
>
<Rate />
</Form.Item>
<Form.Item
name="description"
label="风险描述"
rules={[{ required: true, message: '请输入风险描述' }]}
>
<Input.TextArea rows={3} placeholder="请输入风险描述" />
</Form.Item>
<Form.Item
name="controlMeasures"
label="控制措施"
rules={[{ required: true, message: '请输入控制措施' }]}
>
<Input.TextArea rows={3} placeholder="请输入控制措施" />
</Form.Item>
</Form>
</Modal>
</div>
);
};
export default RiskAssessment;