|
@@ -0,0 +1,263 @@
|
|
|
|
|
+"use client"
|
|
|
|
|
+
|
|
|
|
|
+import type React from "react"
|
|
|
|
|
+import {useMemo, useState} from "react"
|
|
|
|
|
+import dayjs from "dayjs"
|
|
|
|
|
+import {Button, Card, Col, Flex, Form, Input, Popconfirm, Row, Select, Space, Table, Tag} from "antd"
|
|
|
|
|
+import {BadgeAlertIcon as Alert, FileText} from "lucide-react"
|
|
|
|
|
+import globalMessage from "@/app/_modules/globalMessage";
|
|
|
|
|
+
|
|
|
|
|
+type Level = "红色" | "橙色" | "黄色" | "蓝色"
|
|
|
|
|
+type WarnType = "燃气" | "供水" | "电力" | "交通" | "综合"
|
|
|
|
|
+type MatterItemStatus = "启用" | "禁用" | "作废"
|
|
|
|
|
+
|
|
|
|
|
+export type MatterItem = {
|
|
|
|
|
+ id: string
|
|
|
|
|
+ code: string
|
|
|
|
|
+ name: string
|
|
|
|
|
+ type: WarnType
|
|
|
|
|
+ level: Level
|
|
|
|
|
+ status: MatterItemStatus
|
|
|
|
|
+ createdAt: string
|
|
|
|
|
+ updatedAt: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export type ReasonEntry = {
|
|
|
|
|
+ id: string
|
|
|
|
|
+ type: WarnType
|
|
|
|
|
+ level: Level
|
|
|
|
|
+ reason: string
|
|
|
|
|
+ createdAt: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export type MatterManagementProps = {
|
|
|
|
|
+ matters: MatterItem[]
|
|
|
|
|
+ setMatters: React.Dispatch<React.SetStateAction<MatterItem[]>>
|
|
|
|
|
+ reasons: ReasonEntry[]
|
|
|
|
|
+ setReasons: React.Dispatch<React.SetStateAction<ReasonEntry[]>>
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const LEVELS: Level[] = ["红色", "橙色", "黄色", "蓝色"]
|
|
|
|
|
+const TYPES: WarnType[] = ["燃气", "供水", "电力", "交通", "综合"]
|
|
|
|
|
+
|
|
|
|
|
+function levelColor(lvl: Level) {
|
|
|
|
|
+ switch (lvl) {
|
|
|
|
|
+ case "红色":
|
|
|
|
|
+ return "red"
|
|
|
|
|
+ case "橙色":
|
|
|
|
|
+ return "orange"
|
|
|
|
|
+ case "黄色":
|
|
|
|
|
+ return "gold"
|
|
|
|
|
+ case "蓝色":
|
|
|
|
|
+ return "blue"
|
|
|
|
|
+ default:
|
|
|
|
|
+ return "default"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function genId(prefix = "id") {
|
|
|
|
|
+ return `${prefix}_${Math.random().toString(36).slice(2, 10)}`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function autoCode(type: WarnType, level: Level, seq: number) {
|
|
|
|
|
+ const date = dayjs().format("YYYYMMDD")
|
|
|
|
|
+ const t = { 燃气: "GAS", 供水: "WTR", 电力: "ELE", 交通: "TRF", 综合: "COM" }[type]
|
|
|
|
|
+ const l = { 红色: "R", 橙色: "O", 黄色: "Y", 蓝色: "B" }[level]
|
|
|
|
|
+ return `YW-${t}-${l}-${date}-${seq.toString().padStart(3, "0")}`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default function MatterManagement({ matters, setMatters, reasons, setReasons }: MatterManagementProps) {
|
|
|
|
|
+ const [form] = Form.useForm<{ name: string; type: WarnType; level: Level }>()
|
|
|
|
|
+ const [seq, setSeq] = useState(matters.length + 1)
|
|
|
|
|
+ const type = Form.useWatch("type", form)
|
|
|
|
|
+ const level = Form.useWatch("level", form)
|
|
|
|
|
+
|
|
|
|
|
+ const computedCode = useMemo(() => {
|
|
|
|
|
+ if (!type || !level) return ""
|
|
|
|
|
+ return autoCode(type, level, seq)
|
|
|
|
|
+ }, [type, level, seq])
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <Space direction="vertical" size={16} className="w-full">
|
|
|
|
|
+ <Card
|
|
|
|
|
+ title={
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <FileText />
|
|
|
|
|
+ <span>预警清单管理</span>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ <Row gutter={12}>
|
|
|
|
|
+ <Col xs={24} md={10}>
|
|
|
|
|
+ <Card size="small" title="新增/修改事项">
|
|
|
|
|
+ <Form
|
|
|
|
|
+ form={form}
|
|
|
|
|
+ layout="vertical"
|
|
|
|
|
+ initialValues={{ type: "综合", level: "黄色" }}
|
|
|
|
|
+ onFinish={(vals) => {
|
|
|
|
|
+ const item: MatterItem = {
|
|
|
|
|
+ id: genId("matter"),
|
|
|
|
|
+ code: computedCode || autoCode(vals.type, vals.level, seq),
|
|
|
|
|
+ name: vals.name,
|
|
|
|
|
+ type: vals.type,
|
|
|
|
|
+ level: vals.level,
|
|
|
|
|
+ status: "启用",
|
|
|
|
|
+ createdAt: new Date().toISOString(),
|
|
|
|
|
+ updatedAt: new Date().toISOString(),
|
|
|
|
|
+ }
|
|
|
|
|
+ setMatters((prev) => [item, ...prev])
|
|
|
|
|
+ setSeq((s) => s + 1)
|
|
|
|
|
+ form.resetFields()
|
|
|
|
|
+ globalMessage.success("已新增事项")
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Form.Item label="事项名称" name="name" rules={[{ required: true }]}>
|
|
|
|
|
+ <Input placeholder="事项名称" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Flex gap={12} wrap="wrap">
|
|
|
|
|
+ <Form.Item label="专项类型" name="type" rules={[{ required: true }]} style={{ flex: 1 }}>
|
|
|
|
|
+ <Select options={TYPES.map((t) => ({ label: t, value: t }))} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Form.Item label="预警等级" name="level" rules={[{ required: true }]} style={{ width: 180 }}>
|
|
|
|
|
+ <Select options={LEVELS.map((l) => ({ label: l, value: l }))} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ </Flex>
|
|
|
|
|
+ <Form.Item label="事项编码(自动生成)">
|
|
|
|
|
+ <Input value={computedCode} readOnly />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
|
|
+ 保存
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button onClick={() => form.resetFields()}>重置</Button>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ </Form>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col xs={24} md={14}>
|
|
|
|
|
+ <Card size="small" title="事项信息列表">
|
|
|
|
|
+ <Table<MatterItem>
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ rowKey="id"
|
|
|
|
|
+ dataSource={matters}
|
|
|
|
|
+ pagination={{ pageSize: 6 }}
|
|
|
|
|
+ columns={[
|
|
|
|
|
+ { title: "名称", dataIndex: "name" },
|
|
|
|
|
+ { title: "编码", dataIndex: "code" },
|
|
|
|
|
+ { title: "类型", dataIndex: "type" },
|
|
|
|
|
+ { title: "等级", dataIndex: "level" },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: "状态",
|
|
|
|
|
+ dataIndex: "status",
|
|
|
|
|
+ render: (s: MatterItemStatus) => (
|
|
|
|
|
+ <Tag color={s === "启用" ? "success" : s === "禁用" ? "default" : "error"}>{s}</Tag>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: "操作",
|
|
|
|
|
+ render: (_, r) => (
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ onClick={() =>
|
|
|
|
|
+ setMatters((prev) =>
|
|
|
|
|
+ prev.map((m) =>
|
|
|
|
|
+ m.id === r.id
|
|
|
|
|
+ ? {
|
|
|
|
|
+ ...m,
|
|
|
|
|
+ status: m.status === "启用" ? ("禁用" as const) : ("启用" as const),
|
|
|
|
|
+ updatedAt: new Date().toISOString(),
|
|
|
|
|
+ }
|
|
|
|
|
+ : m,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ {r.status === "启用" ? "禁用" : "启用"}
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Popconfirm
|
|
|
|
|
+ title="确定作废该事项?"
|
|
|
|
|
+ onConfirm={() =>
|
|
|
|
|
+ setMatters((prev) =>
|
|
|
|
|
+ prev.map((m) =>
|
|
|
|
|
+ m.id === r.id ? { ...m, status: "作废", updatedAt: new Date().toISOString() } : m,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ <Button size="small" danger>
|
|
|
|
|
+ 作废
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Popconfirm>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ ]}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+
|
|
|
|
|
+ <Card
|
|
|
|
|
+ title={
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Alert />
|
|
|
|
|
+ <span>预警原因库管理</span>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ <Row gutter={12}>
|
|
|
|
|
+ <Col xs={24} md={10}>
|
|
|
|
|
+ <Card size="small" title="新增原因">
|
|
|
|
|
+ <Form
|
|
|
|
|
+ layout="vertical"
|
|
|
|
|
+ onFinish={(vals: any) => {
|
|
|
|
|
+ const item: ReasonEntry = {
|
|
|
|
|
+ id: genId("reason"),
|
|
|
|
|
+ type: vals.type,
|
|
|
|
|
+ level: vals.level,
|
|
|
|
|
+ reason: vals.reason,
|
|
|
|
|
+ createdAt: new Date().toISOString(),
|
|
|
|
|
+ }
|
|
|
|
|
+ setReasons((prev) => [item, ...prev])
|
|
|
|
|
+ globalMessage.success("已添加原因")
|
|
|
|
|
+ }}
|
|
|
|
|
+ initialValues={{ type: "综合", level: "黄色" }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Form.Item label="类型" name="type" rules={[{ required: true }]}>
|
|
|
|
|
+ <Select options={TYPES.map((t) => ({ label: t, value: t }))} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Form.Item label="等级" name="level" rules={[{ required: true }]}>
|
|
|
|
|
+ <Select options={LEVELS.map((l) => ({ label: l, value: l }))} />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Form.Item label="原因描述" name="reason" rules={[{ required: true }]}>
|
|
|
|
|
+ <Input.TextArea rows={3} placeholder="维护原因项,供处置人员选择" />
|
|
|
|
|
+ </Form.Item>
|
|
|
|
|
+ <Button type="primary" htmlType="submit">
|
|
|
|
|
+ 添加
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </Form>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ <Col xs={24} md={14}>
|
|
|
|
|
+ <Card size="small" title="原因库">
|
|
|
|
|
+ <Table<ReasonEntry>
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ rowKey="id"
|
|
|
|
|
+ dataSource={reasons}
|
|
|
|
|
+ pagination={{ pageSize: 6 }}
|
|
|
|
|
+ columns={[
|
|
|
|
|
+ { title: "类型", dataIndex: "type" },
|
|
|
|
|
+ { title: "等级", dataIndex: "level" },
|
|
|
|
|
+ { title: "原因", dataIndex: "reason" },
|
|
|
|
|
+ { title: "创建时间", dataIndex: "createdAt", render: (t) => dayjs(t).format("YYYY-MM-DD") },
|
|
|
|
|
+ ]}
|
|
|
|
|
+ />
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Col>
|
|
|
|
|
+ </Row>
|
|
|
|
|
+ </Card>
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|