Sfoglia il codice sorgente

feat(test8): 新增运行监测可视化组件

- 添加 MonitoringVisualization组件,实现燃气管网运行监测的可视化展示
- 包含图层控制、时间范围选择、刷新间隔设置等功能
- 集成地图组件显示管网分布和监测点信息
- 展示监测点详情和实时统计信息
nahida 9 mesi fa
parent
commit
7666970335
1 ha cambiato i file con 297 aggiunte e 0 eliminazioni
  1. 297 0
      app/(other)/test8/components/monitoring-visualization.tsx

+ 297 - 0
app/(other)/test8/components/monitoring-visualization.tsx

@@ -0,0 +1,297 @@
+"use client"
+
+import {useState} from "react"
+import {Button, Card, Col, Row, Select, Slider, Space, Switch, Tag} from "antd"
+import {FullscreenOutlined, ReloadOutlined} from "@ant-design/icons"
+import dynamic from "next/dynamic"
+
+const GasNetworkMap = dynamic(() => import("./gas-network-map"), {
+  ssr: false,
+  loading: () => <div className="flex items-center justify-center h-96">加载地图中...</div>,
+})
+
+const { Option } = Select
+
+// 模拟实时监测数据点
+const mockMonitoringPoints = [
+  {
+    id: "MP001",
+    name: "解放路监���点",
+    position: [39.9042, 116.4074],
+    type: "pressure",
+    value: 0.42,
+    unit: "MPa",
+    status: "normal",
+    lastUpdate: "2024-01-15 14:30:25",
+  },
+  {
+    id: "MP002",
+    name: "人民路监测点",
+    position: [39.9052, 116.4084],
+    type: "flow",
+    value: 2850,
+    unit: "m³/h",
+    status: "normal",
+    lastUpdate: "2024-01-15 14:30:20",
+  },
+  {
+    id: "MP003",
+    name: "建设路监测点",
+    position: [39.9032, 116.4064],
+    type: "temperature",
+    value: 18.5,
+    unit: "°C",
+    status: "normal",
+    lastUpdate: "2024-01-15 14:30:15",
+  },
+  {
+    id: "MP004",
+    name: "泄漏检测点",
+    position: [39.9062, 116.4094],
+    type: "leakage",
+    value: 0.02,
+    unit: "ppm",
+    status: "warning",
+    lastUpdate: "2024-01-15 14:30:30",
+  },
+]
+
+export default function MonitoringVisualization() {
+  const [layerVisibility, setLayerVisibility] = useState({
+    pipeline: true,
+    pressure: true,
+    flow: true,
+    temperature: true,
+    leakage: true,
+    devices: true,
+  })
+  const [selectedTimeRange, setSelectedTimeRange] = useState("realtime")
+  const [dataRefreshInterval, setDataRefreshInterval] = useState(5)
+  const [isFullscreen, setIsFullscreen] = useState(false)
+
+  const handleLayerToggle = (layer: string, visible: boolean) => {
+    setLayerVisibility((prev) => ({
+      ...prev,
+      [layer]: visible,
+    }))
+  }
+
+  const handleRefresh = () => {
+    // 刷新数据逻辑
+    console.log("刷新监测数据")
+  }
+
+  const getStatusColor = (status: string) => {
+    switch (status) {
+      case "normal":
+        return "#52c41a"
+      case "warning":
+        return "#faad14"
+      case "danger":
+        return "#f5222d"
+      default:
+        return "#1890ff"
+    }
+  }
+
+  const getTypeLabel = (type: string) => {
+    const typeMap = {
+      pressure: "压力",
+      flow: "流量",
+      temperature: "温度",
+      leakage: "泄漏",
+    }
+    return typeMap[type as keyof typeof typeMap] || type
+  }
+
+  return (
+    <div className="p-6">
+      <Card title="运行监测可视化" className="mb-4">
+        {/* 控制面板 */}
+        <Row gutter={16} className="mb-4">
+          <Col span={24}>
+            <Card size="small" title="图层控制">
+              <Row gutter={16}>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.pipeline}
+                      onChange={(checked) => handleLayerToggle("pipeline", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">管网管线</span>
+                  </div>
+                </Col>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.pressure}
+                      onChange={(checked) => handleLayerToggle("pressure", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">压力监测</span>
+                  </div>
+                </Col>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.flow}
+                      onChange={(checked) => handleLayerToggle("flow", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">流量监测</span>
+                  </div>
+                </Col>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.temperature}
+                      onChange={(checked) => handleLayerToggle("temperature", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">温度监测</span>
+                  </div>
+                </Col>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.leakage}
+                      onChange={(checked) => handleLayerToggle("leakage", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">泄漏检测</span>
+                  </div>
+                </Col>
+                <Col span={4}>
+                  <div className="mb-2">
+                    <Switch
+                      checked={layerVisibility.devices}
+                      onChange={(checked) => handleLayerToggle("devices", checked)}
+                      size="small"
+                    />
+                    <span className="ml-2">监测设备</span>
+                  </div>
+                </Col>
+              </Row>
+            </Card>
+          </Col>
+        </Row>
+
+        <Row gutter={16} className="mb-4">
+          <Col span={6}>
+            <Card size="small" title="时间范围">
+              <Select value={selectedTimeRange} onChange={setSelectedTimeRange} style={{ width: "100%" }}>
+                <Option value="realtime">实时数据</Option>
+                <Option value="1hour">近1小时</Option>
+                <Option value="6hours">近6小时</Option>
+                <Option value="24hours">近24小时</Option>
+                <Option value="7days">近7天</Option>
+              </Select>
+            </Card>
+          </Col>
+          <Col span={6}>
+            <Card size="small" title="刷新间隔">
+              <div>
+                <Slider
+                  min={1}
+                  max={60}
+                  value={dataRefreshInterval}
+                  onChange={setDataRefreshInterval}
+                  marks={{ 1: "1s", 30: "30s", 60: "60s" }}
+                />
+                <div className="text-center text-sm text-gray-500">{dataRefreshInterval}秒</div>
+              </div>
+            </Card>
+          </Col>
+          <Col span={6}>
+            <Card size="small" title="操作控制">
+              <Space>
+                <Button icon={<ReloadOutlined />} onClick={handleRefresh} size="small">
+                  刷新
+                </Button>
+                <Button icon={<FullscreenOutlined />} onClick={() => setIsFullscreen(!isFullscreen)} size="small">
+                  全屏
+                </Button>
+              </Space>
+            </Card>
+          </Col>
+          <Col span={6}>
+            <Card size="small" title="监测状态">
+              <div className="space-y-1">
+                <div className="flex justify-between">
+                  <span>正常:</span>
+                  <Tag color="green">3</Tag>
+                </div>
+                <div className="flex justify-between">
+                  <span>预警:</span>
+                  <Tag color="orange">1</Tag>
+                </div>
+                <div className="flex justify-between">
+                  <span>异常:</span>
+                  <Tag color="red">0</Tag>
+                </div>
+              </div>
+            </Card>
+          </Col>
+        </Row>
+
+        {/* 地图展示 */}
+        <Row gutter={16}>
+          <Col span={18}>
+            <Card title="实时监测一张图" size="small" className={isFullscreen ? "fixed inset-0 z-50" : ""}>
+              <GasNetworkMap height={isFullscreen ? "calc(100vh - 120px)" : "700px"} />
+            </Card>
+          </Col>
+          <Col span={6}>
+            <Card title="监测点详情" size="small">
+              <div className="space-y-3 max-h-96 overflow-y-auto">
+                {mockMonitoringPoints.map((point) => (
+                  <div key={point.id} className="p-3 border rounded-lg">
+                    <div className="flex justify-between items-center mb-2">
+                      <span className="font-medium">{point.name}</span>
+                      <Tag color={getStatusColor(point.status)}>
+                        {point.status === "normal" ? "正常" : point.status === "warning" ? "预警" : "异常"}
+                      </Tag>
+                    </div>
+                    <div className="text-sm text-gray-600 space-y-1">
+                      <div>类型: {getTypeLabel(point.type)}</div>
+                      <div>
+                        当前值: {point.value} {point.unit}
+                      </div>
+                      <div>更新时间: {point.lastUpdate}</div>
+                    </div>
+                  </div>
+                ))}
+              </div>
+            </Card>
+
+            <Card title="实时统计" size="small" className="mt-4">
+              <div className="space-y-3">
+                <div className="flex justify-between">
+                  <span>监测点总数:</span>
+                  <span className="font-bold text-blue-600">342</span>
+                </div>
+                <div className="flex justify-between">
+                  <span>在线设备:</span>
+                  <span className="font-bold text-green-600">298</span>
+                </div>
+                <div className="flex justify-between">
+                  <span>离线设备:</span>
+                  <span className="font-bold text-red-600">12</span>
+                </div>
+                <div className="flex justify-between">
+                  <span>维护中:</span>
+                  <span className="font-bold text-orange-600">32</span>
+                </div>
+                <div className="flex justify-between">
+                  <span>数据更新率:</span>
+                  <span className="font-bold text-blue-600">98.5%</span>
+                </div>
+              </div>
+            </Card>
+          </Col>
+        </Row>
+      </Card>
+    </div>
+  )
+}