Jelajahi Sumber

feat(app): 新增预警事项和原因管理功能

- 实现了预警事项管理和原因库管理的前端界面
- 添加了事项和原因的新增、修改、禁用和作废功能
- 优化了表单布局和数据展示
nahida 9 bulan lalu
induk
melakukan
f5d7f4fe95
1 mengubah file dengan 263 tambahan dan 0 penghapusan
  1. 263 0
      app/(other)/test6/components/matter-management.tsx

+ 263 - 0
app/(other)/test6/components/matter-management.tsx

@@ -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>
+  )
+}