| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- "use client"
- import {useState} from "react"
- import {
- Button,
- Card,
- Col,
- DatePicker,
- Descriptions,
- Form,
- Input,
- Modal,
- Popconfirm,
- Progress,
- Row,
- Select,
- Space,
- Table,
- Tag,
- } from "antd"
- import {DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined} from "@ant-design/icons"
- import {Radar} from "@ant-design/plots"
- import dayjs from "dayjs"
- import globalMessage from "@/app/_modules/globalMessage";
- const { Option } = Select
- const { TextArea } = Input
- // 模拟风险档案数据
- const mockRiskData = [
- {
- id: "R001",
- title: "解放路段高压管线风险",
- location: "解放路与建设路交叉口",
- riskType: "管线老化",
- riskLevel: "高",
- riskScore: 85,
- assessmentDate: "2024-01-15",
- assessor: "张三",
- status: "待处理",
- description: "高压管线使用年限超过20年,存在老化风险",
- impactArea: "500m范围内",
- affectedPopulation: 2000,
- economicLoss: 500000,
- mitigationMeasures: "定期检测,制定更换计划",
- monitoringFrequency: "每月",
- lastUpdate: "2024-01-15",
- factors: {
- 管线状态: 80,
- 环境因素: 70,
- 人员密度: 90,
- 设备完好性: 75,
- 管理水平: 85,
- },
- },
- {
- id: "R002",
- title: "人民路段泄漏风险",
- location: "人民路中段",
- riskType: "泄漏隐患",
- riskLevel: "中",
- riskScore: 65,
- assessmentDate: "2024-01-10",
- assessor: "李四",
- status: "监控中",
- description: "管道接头处存在微量泄漏风险",
- impactArea: "200m范围内",
- affectedPopulation: 800,
- economicLoss: 200000,
- mitigationMeasures: "加强巡检,安装泄漏检测设备",
- monitoringFrequency: "每周",
- lastUpdate: "2024-01-12",
- factors: {
- 管线状态: 60,
- 环境因素: 65,
- 人员密度: 70,
- 设备完好性: 80,
- 管理水平: 75,
- },
- },
- {
- id: "R003",
- title: "建设路段压力风险",
- location: "建设路北段",
- riskType: "压力异常",
- riskLevel: "低",
- riskScore: 35,
- assessmentDate: "2024-01-08",
- assessor: "王五",
- status: "已控制",
- description: "调压设备运行正常,风险可控",
- impactArea: "100m范围内",
- affectedPopulation: 300,
- economicLoss: 50000,
- mitigationMeasures: "定期维护调压设备",
- monitoringFrequency: "每季度",
- lastUpdate: "2024-01-10",
- factors: {
- 管线状态: 40,
- 环境因素: 35,
- 人员密度: 30,
- 设备完好性: 45,
- 管理水平: 40,
- },
- },
- ]
- export default function RiskArchive() {
- const [isModalVisible, setIsModalVisible] = useState(false)
- const [isDetailModalVisible, setIsDetailModalVisible] = useState(false)
- const [editingRecord, setEditingRecord] = useState(null)
- const [viewingRecord, setViewingRecord] = useState(null)
- const [form] = Form.useForm()
- const handleAdd = () => {
- setEditingRecord(null)
- form.resetFields()
- setIsModalVisible(true)
- }
- const handleEdit = (record: any) => {
- setEditingRecord(record)
- form.setFieldsValue({
- ...record,
- assessmentDate: record.assessmentDate ? dayjs(record.assessmentDate) : null,
- })
- setIsModalVisible(true)
- }
- const handleView = (record: any) => {
- setViewingRecord(record)
- setIsDetailModalVisible(true)
- }
- const handleDelete = (id: string) => {
- globalMessage.success("删除成功")
- }
- const handleModalOk = () => {
- form.validateFields().then((values) => {
- if (editingRecord) {
- globalMessage.success("更新成功")
- } else {
- globalMessage.success("添加成功")
- }
- setIsModalVisible(false)
- form.resetFields()
- })
- }
- const getRiskLevelColor = (level: string) => {
- switch (level) {
- case "高":
- return "red"
- case "中":
- return "orange"
- case "低":
- return "blue"
- default:
- return "default"
- }
- }
- const getStatusColor = (status: string) => {
- switch (status) {
- case "待处理":
- return "red"
- case "监控中":
- return "orange"
- case "已控制":
- return "green"
- default:
- return "default"
- }
- }
- const getRiskScoreColor = (score: number) => {
- if (score >= 80) return "#f5222d"
- if (score >= 60) return "#faad14"
- if (score >= 40) return "#52c41a"
- return "#1890ff"
- }
- const columns = [
- { title: "风险编号", dataIndex: "id", key: "id", width: 100 },
- { title: "风险标题", dataIndex: "title", key: "title", width: 200 },
- { title: "位置", dataIndex: "location", key: "location", width: 150 },
- { title: "风险类型", dataIndex: "riskType", key: "riskType", width: 120 },
- {
- title: "风险等级",
- dataIndex: "riskLevel",
- key: "riskLevel",
- width: 100,
- render: (level: string) => <Tag color={getRiskLevelColor(level)}>{level}</Tag>,
- },
- {
- title: "风险评分",
- dataIndex: "riskScore",
- key: "riskScore",
- width: 120,
- render: (score: number) => (
- <div>
- <Progress
- percent={score}
- size="small"
- strokeColor={getRiskScoreColor(score)}
- format={(percent) => `${percent}`}
- />
- </div>
- ),
- },
- { title: "评估日期", dataIndex: "assessmentDate", key: "assessmentDate", width: 120 },
- { title: "评估人", dataIndex: "assessor", key: "assessor", width: 100 },
- {
- title: "状态",
- dataIndex: "status",
- key: "status",
- width: 100,
- render: (status: string) => <Tag color={getStatusColor(status)}>{status}</Tag>,
- },
- { title: "影响人口", dataIndex: "affectedPopulation", key: "affectedPopulation", width: 100 },
- {
- title: "操作",
- key: "action",
- width: 200,
- fixed: "right",
- render: (_, record) => (
- <Space>
- <Button type="link" icon={<EyeOutlined />} onClick={() => handleView(record)}>
- 查看
- </Button>
- <Button type="link" icon={<EditOutlined />} onClick={() => handleEdit(record)}>
- 编辑
- </Button>
- <Popconfirm title="确定删除吗?" onConfirm={() => handleDelete(record.id)}>
- <Button type="link" danger icon={<DeleteOutlined />}>
- 删除
- </Button>
- </Popconfirm>
- </Space>
- ),
- },
- ]
- const radarConfig = viewingRecord
- ? {
- data: Object.entries(viewingRecord.factors).map(([key, value]) => ({
- factor: key,
- value: value,
- })),
- xField: "factor",
- yField: "value",
- area: {
- style: {
- fill: getRiskScoreColor(viewingRecord.riskScore),
- fillOpacity: 0.3,
- },
- },
- point: {
- size: 3,
- },
- line: {
- style: {
- stroke: getRiskScoreColor(viewingRecord.riskScore),
- lineWidth: 2,
- },
- },
- }
- : null
- const highRiskCount = mockRiskData.filter((item) => item.riskLevel === "高").length
- const mediumRiskCount = mockRiskData.filter((item) => item.riskLevel === "中").length
- const lowRiskCount = mockRiskData.filter((item) => item.riskLevel === "低").length
- return (
- <div className="p-6">
- <Card title="风险档案管理">
- {/* 风险概览 */}
- <Row gutter={16} className="mb-6">
- <Col span={6}>
- <Card size="small">
- <div className="text-center">
- <div className="text-2xl font-bold text-red-600">{highRiskCount}</div>
- <div className="text-gray-600">高风险</div>
- </div>
- </Card>
- </Col>
- <Col span={6}>
- <Card size="small">
- <div className="text-center">
- <div className="text-2xl font-bold text-orange-600">{mediumRiskCount}</div>
- <div className="text-gray-600">中风险</div>
- </div>
- </Card>
- </Col>
- <Col span={6}>
- <Card size="small">
- <div className="text-center">
- <div className="text-2xl font-bold text-blue-600">{lowRiskCount}</div>
- <div className="text-gray-600">低风险</div>
- </div>
- </Card>
- </Col>
- <Col span={6}>
- <Card size="small">
- <div className="text-center">
- <div className="text-2xl font-bold text-gray-600">{mockRiskData.length}</div>
- <div className="text-gray-600">风险总数</div>
- </div>
- </Card>
- </Col>
- </Row>
- {/* 筛选控件 */}
- <div className="mb-4">
- <Space>
- <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
- 新增风险
- </Button>
- <Input.Search placeholder="搜索风险..." style={{ width: 300 }} />
- <Select placeholder="风险类型" style={{ width: 120 }}>
- <Option value="aging">管线老化</Option>
- <Option value="leak">泄漏隐患</Option>
- <Option value="pressure">压力异常</Option>
- <Option value="other">其他</Option>
- </Select>
- <Select placeholder="风险等级" style={{ width: 120 }}>
- <Option value="high">高</Option>
- <Option value="medium">中</Option>
- <Option value="low">低</Option>
- </Select>
- <Select placeholder="状态" style={{ width: 120 }}>
- <Option value="pending">待处理</Option>
- <Option value="monitoring">监控中</Option>
- <Option value="controlled">已控制</Option>
- </Select>
- </Space>
- </div>
- {/* 风险列表 */}
- <Table
- columns={columns}
- dataSource={mockRiskData}
- rowKey="id"
- pagination={{ pageSize: 10 }}
- scroll={{ x: 1400 }}
- />
- {/* 编辑/新增模态框 */}
- <Modal
- title={editingRecord ? "编辑风险" : "新增风险"}
- open={isModalVisible}
- onOk={handleModalOk}
- onCancel={() => setIsModalVisible(false)}
- width={800}
- >
- <Form form={form} layout="vertical">
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="title" label="风险标题" rules={[{ required: true }]}>
- <Input />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="location" label="位置" rules={[{ required: true }]}>
- <Input />
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="riskType" label="风险类型" rules={[{ required: true }]}>
- <Select>
- <Option value="管线老化">管线老化</Option>
- <Option value="泄漏隐患">泄漏隐患</Option>
- <Option value="压力异常">压力异常</Option>
- <Option value="其他">其他</Option>
- </Select>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="riskLevel" label="风险等级" rules={[{ required: true }]}>
- <Select>
- <Option value="高">高</Option>
- <Option value="中">中</Option>
- <Option value="低">低</Option>
- </Select>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="riskScore" label="风险评分" rules={[{ required: true }]}>
- <Input type="number" min={0} max={100} />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="assessmentDate" label="评估日期" rules={[{ required: true }]}>
- <DatePicker style={{ width: "100%" }} />
- </Form.Item>
- </Col>
- </Row>
- <Form.Item name="description" label="风险描述" rules={[{ required: true }]}>
- <TextArea rows={3} />
- </Form.Item>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="affectedPopulation" label="影响人口" rules={[{ required: true }]}>
- <Input type="number" />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="economicLoss" label="潜在经济损失" rules={[{ required: true }]}>
- <Input type="number" />
- </Form.Item>
- </Col>
- </Row>
- <Form.Item name="mitigationMeasures" label="缓解措施">
- <TextArea rows={3} />
- </Form.Item>
- </Form>
- </Modal>
- {/* 详情查看模态框 */}
- <Modal
- title="风险详情"
- open={isDetailModalVisible}
- onCancel={() => setIsDetailModalVisible(false)}
- footer={[
- <Button key="close" onClick={() => setIsDetailModalVisible(false)}>
- 关闭
- </Button>,
- ]}
- width={1000}
- >
- {viewingRecord && (
- <Row gutter={16}>
- <Col span={14}>
- <Descriptions column={2} bordered>
- <Descriptions.Item label="风险编号">{viewingRecord.id}</Descriptions.Item>
- <Descriptions.Item label="风险标题">{viewingRecord.title}</Descriptions.Item>
- <Descriptions.Item label="位置">{viewingRecord.location}</Descriptions.Item>
- <Descriptions.Item label="风险类型">{viewingRecord.riskType}</Descriptions.Item>
- <Descriptions.Item label="风险等级">
- <Tag color={getRiskLevelColor(viewingRecord.riskLevel)}>{viewingRecord.riskLevel}</Tag>
- </Descriptions.Item>
- <Descriptions.Item label="风险评分">
- <Progress
- percent={viewingRecord.riskScore}
- size="small"
- strokeColor={getRiskScoreColor(viewingRecord.riskScore)}
- />
- </Descriptions.Item>
- <Descriptions.Item label="评估日期">{viewingRecord.assessmentDate}</Descriptions.Item>
- <Descriptions.Item label="评估人">{viewingRecord.assessor}</Descriptions.Item>
- <Descriptions.Item label="影响范围">{viewingRecord.impactArea}</Descriptions.Item>
- <Descriptions.Item label="影响人口">{viewingRecord.affectedPopulation}人</Descriptions.Item>
- <Descriptions.Item label="潜在损失">¥{viewingRecord.economicLoss.toLocaleString()}</Descriptions.Item>
- <Descriptions.Item label="监测频率">{viewingRecord.monitoringFrequency}</Descriptions.Item>
- </Descriptions>
- <div className="mt-4">
- <h4 className="font-medium mb-2">风险描述</h4>
- <div className="p-3 bg-gray-50 rounded">{viewingRecord.description}</div>
- </div>
- <div className="mt-4">
- <h4 className="font-medium mb-2">缓解措施</h4>
- <div className="p-3 bg-blue-50 rounded">{viewingRecord.mitigationMeasures}</div>
- </div>
- </Col>
- <Col span={10}>
- <Card title="风险因子分析" size="small">
- {radarConfig && <Radar {...radarConfig} height={300} />}
- </Card>
- </Col>
- </Row>
- )}
- </Modal>
- </Card>
- </div>
- )
- }
|