|
@@ -0,0 +1,431 @@
|
|
|
|
|
+"use client"
|
|
|
|
|
+
|
|
|
|
|
+import {useState} from "react"
|
|
|
|
|
+import {Button, Card, Col, DatePicker, Form, Input, Modal, Popconfirm, Row, Select, Space, Table, Tag,} from "antd"
|
|
|
|
|
+import {DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined} from "@ant-design/icons"
|
|
|
|
|
+import dayjs from "dayjs"
|
|
|
|
|
+import globalMessage from "@/app/_modules/globalMessage";
|
|
|
|
|
+
|
|
|
|
|
+const { Option } = Select
|
|
|
|
|
+const { TextArea } = Input
|
|
|
|
|
+
|
|
|
|
|
+// 模拟隐患数据
|
|
|
|
|
+const mockHazardData = [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: "H001",
|
|
|
|
|
+ title: "解放路段管线压力异常",
|
|
|
|
|
+ type: "压力异常",
|
|
|
|
|
+ level: "高",
|
|
|
|
|
+ location: "解放路与建设路交叉口",
|
|
|
|
|
+ description: "管线压力超出正常范围,存在安全隐患",
|
|
|
|
|
+ reportDate: "2024-01-15",
|
|
|
|
|
+ reportPerson: "张三",
|
|
|
|
|
+ status: "处理中",
|
|
|
|
|
+ assignedTo: "李四",
|
|
|
|
|
+ expectedDate: "2024-02-15",
|
|
|
|
|
+ actualDate: null,
|
|
|
|
|
+ treatmentPlan: "更换老化管段,加强压力监测",
|
|
|
|
|
+ progress: 60,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ id: "H002",
|
|
|
|
|
+ name: "人民路窨井盖损坏",
|
|
|
|
|
+ type: "设施损坏",
|
|
|
|
|
+ level: "中",
|
|
|
|
|
+ location: "人民路中段",
|
|
|
|
|
+ description: "窨井盖出现裂纹,影响安全",
|
|
|
|
|
+ reportDate: "2024-01-20",
|
|
|
|
|
+ reportPerson: "王五",
|
|
|
|
|
+ status: "已完成",
|
|
|
|
|
+ assignedTo: "赵六",
|
|
|
|
|
+ expectedDate: "2024-01-25",
|
|
|
|
|
+ actualDate: "2024-01-24",
|
|
|
|
|
+ treatmentPlan: "更换新井盖",
|
|
|
|
|
+ progress: 100,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ id: "H003",
|
|
|
|
|
+ name: "建设路段泄漏检测",
|
|
|
|
|
+ type: "泄漏隐患",
|
|
|
|
|
+ level: "高",
|
|
|
|
|
+ location: "建设路北段",
|
|
|
|
|
+ description: "检测到微量燃气泄漏",
|
|
|
|
|
+ reportDate: "2024-01-25",
|
|
|
|
|
+ reportPerson: "孙七",
|
|
|
|
|
+ status: "待处理",
|
|
|
|
|
+ assignedTo: null,
|
|
|
|
|
+ expectedDate: "2024-02-10",
|
|
|
|
|
+ actualDate: null,
|
|
|
|
|
+ treatmentPlan: "待制定",
|
|
|
|
|
+ progress: 0,
|
|
|
|
|
+ },
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+export default function HazardArchive() {
|
|
|
|
|
+ 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,
|
|
|
|
|
+ reportDate: record.reportDate ? dayjs(record.reportDate) : null,
|
|
|
|
|
+ expectedDate: record.expectedDate ? dayjs(record.expectedDate) : null,
|
|
|
|
|
+ actualDate: record.actualDate ? dayjs(record.actualDate) : 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 columns = [
|
|
|
|
|
+ { title: "隐患编号", dataIndex: "id", key: "id", width: 100 },
|
|
|
|
|
+ { title: "隐患标题", dataIndex: "title", key: "title", width: 200 },
|
|
|
|
|
+ { title: "隐患类型", dataIndex: "type", key: "type", width: 120 },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: "风险等级",
|
|
|
|
|
+ dataIndex: "level",
|
|
|
|
|
+ key: "level",
|
|
|
|
|
+ width: 100,
|
|
|
|
|
+ render: (level: string) => {
|
|
|
|
|
+ const colorMap = { 高: "red", 中: "orange", 低: "green" }
|
|
|
|
|
+ return <Tag color={colorMap[level as keyof typeof colorMap]}>{level}</Tag>
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ { title: "位置", dataIndex: "location", key: "location", width: 150 },
|
|
|
|
|
+ { title: "上报日期", dataIndex: "reportDate", key: "reportDate", width: 120 },
|
|
|
|
|
+ { title: "上报人", dataIndex: "reportPerson", key: "reportPerson", width: 100 },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: "处理状态",
|
|
|
|
|
+ dataIndex: "status",
|
|
|
|
|
+ key: "status",
|
|
|
|
|
+ width: 100,
|
|
|
|
|
+ render: (status: string) => {
|
|
|
|
|
+ const colorMap = {
|
|
|
|
|
+ 待处理: "default",
|
|
|
|
|
+ 处理中: "processing",
|
|
|
|
|
+ 已完成: "success",
|
|
|
|
|
+ 已关闭: "error",
|
|
|
|
|
+ }
|
|
|
|
|
+ return <Tag color={colorMap[status as keyof typeof colorMap]}>{status}</Tag>
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ { title: "负责人", dataIndex: "assignedTo", key: "assignedTo", width: 100 },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: "进度",
|
|
|
|
|
+ dataIndex: "progress",
|
|
|
|
|
+ key: "progress",
|
|
|
|
|
+ width: 80,
|
|
|
|
|
+ render: (progress: number) => `${progress}%`,
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ 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>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="p-6">
|
|
|
|
|
+ <Card title="隐患台账管理">
|
|
|
|
|
+ <Row gutter={16} className="mb-4">
|
|
|
|
|
+ <Col span={6}>
|
|
|
|
|
+ <Card size="small">
|
|
|
|
|
+ <div className="text-center">
|
|
|
|
|
+ <div className="text-2xl font-bold text-blue-600">156</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-red-600">23</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">45</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-green-600">88</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="pressure">压力异常</Option>
|
|
|
|
|
+ <Option value="leak">泄漏隐患</Option>
|
|
|
|
|
+ <Option value="damage">设施损坏</Option>
|
|
|
|
|
+ <Option value="other">其他</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ <Select placeholder="处理状态" style={{ width: 120 }}>
|
|
|
|
|
+ <Option value="pending">待处理</Option>
|
|
|
|
|
+ <Option value="processing">处理中</Option>
|
|
|
|
|
+ <Option value="completed">已完成</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <Table
|
|
|
|
|
+ columns={columns}
|
|
|
|
|
+ dataSource={mockHazardData}
|
|
|
|
|
+ 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="type" label="隐患类型" rules={[{ required: true }]}>
|
|
|
|
|
+ <Select>
|
|
|
|
|
+ <Option value="压力异常">压力异常</Option>
|
|
|
|
|
+ <Option value="泄漏隐患">泄漏隐患</Option>
|
|
|
|
|
+ <Option value="设施损坏">设施损坏</Option>
|
|
|
|
|
+ <Option value="其他">其他</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <Form.Item name="level" label="风险等级" rules={[{ required: true }]}>
|
|
|
|
|
+ <Select>
|
|
|
|
|
+ <Option value="高">高</Option>
|
|
|
|
|
+ <Option value="中">中</Option>
|
|
|
|
|
+ <Option value="低">低</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <Form.Item name="location" label="位置" rules={[{ required: true }]}>
|
|
|
|
|
+ <Input />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Form.Item name="description" label="隐患描述" rules={[{ required: true }]}>
|
|
|
|
|
+ <TextArea rows={3} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={8}>
|
|
|
|
|
+ <Form.Item name="reportDate" label="上报日期" rules={[{ required: true }]}>
|
|
|
|
|
+ <DatePicker style={{ width: "100%" }} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={8}>
|
|
|
|
|
+ <Form.Item name="reportPerson" label="上报人" rules={[{ required: true }]}>
|
|
|
|
|
+ <Input />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={8}>
|
|
|
|
|
+ <Form.Item name="assignedTo" label="负责人">
|
|
|
|
|
+ <Input />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <Form.Item name="expectedDate" label="预期完成日期">
|
|
|
|
|
+ <DatePicker style={{ width: "100%" }} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <Form.Item name="status" label="处理状态" rules={[{ required: true }]}>
|
|
|
|
|
+ <Select>
|
|
|
|
|
+ <Option value="待处理">待处理</Option>
|
|
|
|
|
+ <Option value="处理中">处理中</Option>
|
|
|
|
|
+ <Option value="已完成">已完成</Option>
|
|
|
|
|
+ <Option value="已关闭">已关闭</Option>
|
|
|
|
|
+ </Select>
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Form.Item name="treatmentPlan" label="治理方案">
|
|
|
|
|
+ <TextArea rows={3} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Form>
|
|
|
|
|
+ </Modal>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 详情查看模态框 */}
|
|
|
|
|
+ <Modal
|
|
|
|
|
+ title="隐患详情"
|
|
|
|
|
+ open={isDetailModalVisible}
|
|
|
|
|
+ onCancel={() => setIsDetailModalVisible(false)}
|
|
|
|
|
+ footer={[
|
|
|
|
|
+ <Button key="close" onClick={() => setIsDetailModalVisible(false)}>
|
|
|
|
|
+ 关闭
|
|
|
|
|
+ </Button>,
|
|
|
|
|
+ ]}
|
|
|
|
|
+ width={800}
|
|
|
|
|
+ >
|
|
|
|
|
+ {viewingRecord && (
|
|
|
|
|
+ <div className="space-y-4">
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>隐患编号:</strong>
|
|
|
|
|
+ {viewingRecord.id}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>隐患标题:</strong>
|
|
|
|
|
+ {viewingRecord.title}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>隐患类型:</strong>
|
|
|
|
|
+ {viewingRecord.type}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>风险等级:</strong>
|
|
|
|
|
+ <Tag
|
|
|
|
|
+ color={viewingRecord.level === "高" ? "red" : viewingRecord.level === "中" ? "orange" : "green"}
|
|
|
|
|
+ >
|
|
|
|
|
+ {viewingRecord.level}
|
|
|
|
|
+ </Tag>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>位置:</strong>
|
|
|
|
|
+ {viewingRecord.location}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>隐患描述:</strong>
|
|
|
|
|
+ <div className="mt-2 p-3 bg-gray-50 rounded">{viewingRecord.description}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>上报日期:</strong>
|
|
|
|
|
+ {viewingRecord.reportDate}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>上报人:</strong>
|
|
|
|
|
+ {viewingRecord.reportPerson}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <Row gutter={16}>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>处理状态:</strong>
|
|
|
|
|
+ <Tag
|
|
|
|
|
+ color={
|
|
|
|
|
+ viewingRecord.status === "待处理"
|
|
|
|
|
+ ? "default"
|
|
|
|
|
+ : viewingRecord.status === "处理中"
|
|
|
|
|
+ ? "processing"
|
|
|
|
|
+ : viewingRecord.status === "已完成"
|
|
|
|
|
+ ? "success"
|
|
|
|
|
+ : "error"
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ {viewingRecord.status}
|
|
|
|
|
+ </Tag>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col span={12}>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>负责人:</strong>
|
|
|
|
|
+ {viewingRecord.assignedTo || "未分配"}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>治理方案:</strong>
|
|
|
|
|
+ <div className="mt-2 p-3 bg-gray-50 rounded">{viewingRecord.treatmentPlan}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <strong>处理进度:</strong>
|
|
|
|
|
+ <span className="ml-2">{viewingRecord.progress}%</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </Modal>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|