| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- "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>
- )
- }
|