|
|
@@ -0,0 +1,49 @@
|
|
|
+"use client"
|
|
|
+
|
|
|
+import "leaflet/dist/leaflet.css"
|
|
|
+import {CircleMarker, MapContainer, Popup, TileLayer} from "react-leaflet"
|
|
|
+import type {FC} from "react"
|
|
|
+
|
|
|
+type Device = {
|
|
|
+ id: string
|
|
|
+ name: string
|
|
|
+ status: "online" | "offline"
|
|
|
+ lat: number
|
|
|
+ lng: number
|
|
|
+}
|
|
|
+
|
|
|
+const DeviceMap: FC<{ devices: Device[] }> = ({ devices = [] }) => {
|
|
|
+ const center = devices.length ? [devices[0].lat, devices[0].lng] : [31.231706, 121.472644]
|
|
|
+
|
|
|
+ return (
|
|
|
+ <MapContainer
|
|
|
+ center={[Number(center[0]), Number(center[1])]}
|
|
|
+ zoom={12}
|
|
|
+ style={{ height: "100%", width: "100%", borderRadius: 8 }}
|
|
|
+ scrollWheelZoom
|
|
|
+ >
|
|
|
+ <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© OpenStreetMap contributors" />
|
|
|
+ {devices.map((d) => (
|
|
|
+ <CircleMarker
|
|
|
+ key={d.id}
|
|
|
+ center={[d.lat, d.lng]}
|
|
|
+ radius={10}
|
|
|
+ pathOptions={{ color: d.status === "online" ? "#22c55e" : "#64748b", fillOpacity: 0.8 }}
|
|
|
+ >
|
|
|
+ <Popup>
|
|
|
+ <div style={{ minWidth: 180 }}>
|
|
|
+ <div style={{ fontWeight: 600 }}>{d.name}</div>
|
|
|
+ <div>设备ID:{d.id}</div>
|
|
|
+ <div>状态:{d.status === "online" ? "在线" : "离线"}</div>
|
|
|
+ <div>
|
|
|
+ 坐标:{d.lat.toFixed(4)}, {d.lng.toFixed(4)}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Popup>
|
|
|
+ </CircleMarker>
|
|
|
+ ))}
|
|
|
+ </MapContainer>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default DeviceMap
|