浏览代码

feat: 增加设备地图页面

yanglzh 9 月之前
父节点
当前提交
72b8c76682

二进制
public/imgs/device.png


二进制
src/assets/map-title.png


二进制
src/assets/window.png


+ 2 - 0
src/utils/map.ts

@@ -1,7 +1,9 @@
+import styleJson from './mapStyle.json'
 import apiSystem from '/@/api/system';
 import { ElMessageBox } from 'element-plus';
 
 let centerPoint: any
+export const MapStyleJson = styleJson
 
 // 增加map配置
 export function initMap(): any {

+ 1113 - 0
src/utils/mapStyle.json

@@ -0,0 +1,1113 @@
+[{
+  "featureType": "land",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "on",
+      "color": "#183d6cff"
+  }
+}, {
+  "featureType": "water",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#183d6cff"
+  }
+}, {
+  "featureType": "building",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0d315dff"
+  }
+}, {
+  "featureType": "building",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#001f44ff"
+  }
+}, {
+  "featureType": "water",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "village",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "town",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "district",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "country",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "city",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "continent",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "poilabel",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "poilabel",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "scenicspotslabel",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "scenicspotslabel",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "transportationlabel",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "transportationlabel",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "airportlabel",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "airportlabel",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "green",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "on",
+      "color": "#419fb8ff"
+  }
+}, {
+  "featureType": "scenicspots",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "on",
+      "color": "#183d6cff"
+  }
+}, {
+  "featureType": "scenicspots",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "scenicspots",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "continent",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "country",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "city",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "city",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "scenicspotslabel",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "airportlabel",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "transportationlabel",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "railway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "subway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "highwaysign",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "nationalwaysign",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "nationalwaysign",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "provincialwaysign",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "provincialwaysign",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "tertiarywaysign",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "tertiarywaysign",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "subwaylabel",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "subwaylabel",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff",
+      "weight": "90"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "shopping",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "scenicspots",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "on"
+  }
+}, {
+  "featureType": "scenicspotslabel",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "manmade",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "manmade",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "highwaysign",
+  "elementType": "labels.icon",
+  "stylers": {
+      "visibility": "off"
+  }
+}, {
+  "featureType": "water",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#419fb800"
+  }
+}, {
+  "featureType": "road",
+  "stylers": {
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "stylers": {
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "stylers": {
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "road",
+  "elementType": "labels.text",
+  "stylers": {
+      "fontsize": "24"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "color": "#1c4f7eff"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "color": "#1c4f7eff"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "tertiaryway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "fourlevelway",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "local",
+  "elementType": "geometry.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#bdc291ff"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "tertiaryway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "fourlevelway",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "local",
+  "elementType": "geometry.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#9f9f69ff"
+  }
+}, {
+  "featureType": "local",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "local",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "fourlevelway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "tertiaryway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "labels.text.fill",
+  "stylers": {
+      "visibility": "on",
+      "color": "#1c76c5ff"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "tertiaryway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "fourlevelway",
+  "elementType": "labels.text.stroke",
+  "stylers": {
+      "visibility": "on",
+      "color": "#0c172bff",
+      "weight": "1"
+  }
+}, {
+  "featureType": "fourlevelway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "1"
+  }
+}, {
+  "featureType": "tertiaryway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "1"
+  }
+}, {
+  "featureType": "local",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "1"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "geometry",
+  "stylers": {
+      "weight": "3"
+  }
+}, {
+  "featureType": "highway",
+  "stylers": {
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "stylers": {
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "stylers": {
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "highway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "stylers": {
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "stylers": {
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "stylers": {
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "nationalway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "provincialway",
+  "stylers": {
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "provincialway",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "provincialway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "8-10"
+  }
+}, {
+  "featureType": "cityhighway",
+  "stylers": {
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "stylers": {
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "stylers": {
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "6",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "7",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "8",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "cityhighway",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "6-9"
+  }
+}, {
+  "featureType": "arterial",
+  "stylers": {
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "9-9"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "geometry",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "9-9"
+  }
+}, {
+  "featureType": "arterial",
+  "elementType": "labels",
+  "stylers": {
+      "visibility": "off",
+      "level": "9",
+      "curZoomRegionId": "0",
+      "curZoomRegion": "9-9"
+  }
+}]

+ 105 - 0
src/views/iot/property/deviceMap/edit.vue

@@ -0,0 +1,105 @@
+<template>
+  <el-dialog class="api-edit" v-model="showDialog" :title="`${formData.id ? '编辑资产关系' : '新增资产关系'}`" width="800px" :close-on-click-modal="false" :close-on-press-escape="false">
+    <div class="dialog-wrapper" v-if="showDialog">
+      <el-form class="inline-form" ref="formRef" :model="formData" :rules="ruleForm" label-width="auto">
+        <el-form-item label="选择角色" prop="roleId">
+          <el-cascader :options="roleData" :props="{
+            checkStrictly: true, multiple: false, emitPath: false, value: 'id', label: 'name'
+          }" placeholder="请选择角色" clearable class="w100" disabled v-model="formData.roleId">
+            <template #default="{ node, data }">
+              <span>{{ data.name }}</span>
+              <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+            </template>
+          </el-cascader>
+        </el-form-item>
+        <el-form-item label="已选设备" prop="assetIds">
+          <el-tag v-for="name in assetName" class="mr-2">{{ name }} </el-tag>
+        </el-form-item>
+      </el-form>
+      <el-table :data="tableData" style="width: 100%" row-key="id" @selection-change="handleSelectionChange" v-loading="loading">
+        <el-table-column type="selection" reserve-selection width="55" align="center" />
+        <el-table-column prop="deviceName" label="设备名称" min-width="100" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="deviceKey" label="设备KEY" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="deviceNumber" label="设备编码" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="deviceCategory" label="设备类型" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="installTime" label="安装时间" width="160" align="center"></el-table-column>
+      </el-table>
+      <pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
+    </div>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="showDialog = false">取消</el-button>
+        <el-button type="primary" @click="onSubmit">确定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, nextTick } from 'vue';
+import api from '/@/api/device'
+import system from '/@/api/system';
+import { useSearch } from '/@/hooks/useCommon'
+import { ruleRequired } from '/@/utils/validator';
+import { ElMessage } from 'element-plus';
+import { deepClone } from '/@/utils/other';
+
+const emit = defineEmits(['getList']);
+
+const showDialog = ref(false);
+const formRef = ref();
+const roleData = ref([]);
+const assetName = ref<string[]>([]);
+const baseForm = {
+  id: undefined,
+  roleId: '',
+  assetIds: [],
+};
+
+const formData = reactive<any>(deepClone(baseForm));
+
+const ruleForm = {
+  roleId: [ruleRequired('角色不能为空')],
+  assetIds: [ruleRequired('设备不能为空')],
+};
+
+const { params, tableData, getList, loading } = useSearch<any[]>(api.dev_asset.getList, 'Data', { pageSize: 10 })
+getList()
+
+const handleSelectionChange = (selection: any[]) => {
+  formData.assetIds = selection.map((item) => item.id);
+  assetName.value = selection.map((item) => item.deviceName);
+};
+
+const onSubmit = async () => {
+  await formRef.value.validate();
+  await api.assetRelationship.bind(formData);
+  ElMessage.success('操作成功');
+  resetForm();
+  showDialog.value = false;
+  emit('getList');
+};
+
+const resetForm = async () => {
+  Object.assign(formData, deepClone(baseForm));
+  assetName.value = []
+  formRef.value && formRef.value.resetFields();
+};
+
+const open = async (roleId: string) => {
+  resetForm();
+  showDialog.value = true;
+  formData.roleId = roleId;
+  //获取所有的角色
+  system.role.getList({ status: 1 }).then((resp: any) => {
+    roleData.value = resp;
+  })
+};
+
+defineExpose({ open });
+</script>
+<style scoped lang="scss">
+.demo-form-inline .el-input {
+  --el-input-width: 320px;
+}
+</style>

+ 118 - 0
src/views/iot/property/deviceMap/filter.vue

@@ -0,0 +1,118 @@
+<template>
+  <el-dialog class="api-edit" v-model="showDialog" title="设置筛选条件" width="800px" :close-on-click-modal="false" :close-on-press-escape="false">
+    <el-form class="inline-form" ref="formRef" label-width="auto">
+      <el-form-item v-for="(item, i) in ruleList" :key="item.id" :label="item.title" :prop="item.name">
+        <template #label>
+          <el-checkbox v-model="item.isCheck">{{ item.title }}</el-checkbox>
+        </template>
+        <el-input v-if="item.types === 'input'" v-model="item.value" :disabled="!item.isCheck" placeholder="请输入" />
+        <el-input v-else-if="item.types === 'textarea'" v-model="item.value" :disabled="!item.isCheck" type="textarea" placeholder="请输入" />
+        <el-date-picker v-else-if="item.types === 'date'" v-model="item.value" :disabled="!item.isCheck" type="date" value-format="YYYY-MM-DD" placeholder="请选择时间" class="w100" clearable />
+      </el-form-item>
+      <el-form-item v-if="ruleList.length % 2 === 1"> </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="showDialog = false">取消</el-button>
+        <el-button type="primary" @click="onSubmit">确定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, nextTick } from 'vue';
+import api from '/@/api/device'
+
+import { ElMessage } from 'element-plus';
+
+const emit = defineEmits(['getList']);
+const showDialog = ref(false);
+const formRef = ref();
+const ruleList = ref([]);
+const baseForm = {
+  id: undefined,
+};
+
+const formData = reactive({
+  ...baseForm,
+});
+
+const onSubmit = async () => {
+  const hasNull = ruleList.value.find((item: any) => {
+    const isNull = item.isCheck && !item.value
+    if (isNull) {
+      ElMessage.closeAll()
+      ElMessage.warning(`${item.title}不能为空`)
+    }
+    return isNull
+  })
+
+  if (hasNull) return
+
+  const ruleInfo = ruleList.value.map((item: any) => {
+    item.isCheck = item.isCheck ? 1 : 0
+    delete item.title
+    return item
+  })
+
+  await api.assetRelationship.editRuleInfo({ id: formData.id, ruleInfo });
+  ElMessage.success('操作成功');
+  resetForm();
+  showDialog.value = false;
+  emit('getList');
+};
+
+const resetForm = async () => {
+  Object.assign(formData, { ...baseForm });
+  ruleList.value = []
+  formRef.value && formRef.value.resetFields();
+};
+
+const open = async (row: any) => {
+  resetForm();
+  showDialog.value = true;
+  formData.id = row.id
+  const productKey = row.assetInfo.productKey
+
+  const ruleInfo = JSON.parse(row.ruleInfo || '[]')
+
+  //获取属性列表
+  api.dev_asset_metadata.detail({ productKey }).then((res: any) => {
+    const list = res.map((row: any) => {
+
+      const hasFindItem = ruleInfo.find((item2: any) => item2.id === row.id)
+      const item = {
+        id: row.id,
+        name: row.name,
+        title: row.title,
+        types: row.types,
+        value: hasFindItem ? hasFindItem.value : null,
+        isCheck: hasFindItem?.isCheck ? true : false,
+      }
+      return item
+    })
+    ruleList.value = list
+  })
+};
+
+defineExpose({ open });
+</script>
+<style scoped lang="scss">
+.demo-form-inline .el-input {
+  --el-input-width: 320px;
+}
+
+.el-form {
+  display: flex;
+  flex-flow: row wrap;
+  gap: 20px;
+  align-items: flex-start;
+
+  .el-form-item {
+    flex: 1;
+    min-width: 40%;
+    margin-bottom: 0;
+  }
+}
+</style>

+ 246 - 0
src/views/iot/property/deviceMap/index.vue

@@ -0,0 +1,246 @@
+<template>
+	<div class="page page-full">
+		<div class="map" id="device-map"></div>
+	</div>
+</template>
+
+<script lang="ts" setup>
+import { initMap, MapStyleJson } from '/@/utils/map'
+import { onMounted } from 'vue'
+import api from '/@/api/device'
+
+let BMapGL: any = null
+let map: any = null
+
+onMounted(async () => {
+	const { BMapGL: theBMapGL } = await initMap()
+
+	BMapGL = theBMapGL
+
+	map = new BMapGL.Map('device-map')
+
+	map.setMapStyleV2({
+		styleJson: MapStyleJson,
+	})
+
+	map.enableScrollWheelZoom(true)
+	map.centerAndZoom('四川', 5)
+	setTimeout(setMarker, 1200)
+
+	map.addEventListener('click', function () {
+		map.closeInfoWindow()
+	})
+})
+
+async function setMarker() {
+	const { device: list } = await api.device.allList({})
+
+	const points: any[] = []
+	const markers: any[] = []
+
+	list.map((row: any) => {
+		if (!row.lat || !row.lng) return
+
+		const point = new BMapGL.Point(row.lng, row.lat)
+		const marker = new BMapGL.Marker(point, {
+			icon: new BMapGL.Icon('/imgs/device.png', new BMapGL.Size(146, 85)),
+			// offset: new BMapGL.Size(-73, -42.5),
+		})
+		points.push(point)
+		markers.push(marker)
+		map.addOverlay(marker)
+
+		marker.addEventListener('click', function () {
+			const deviceType = row.product.deviceType === '网关' ? '网关' : '设备'
+			// api.screen.alarmCount(row.key).then(({ handled, number, unhandled }: any) => {
+			const number = 0
+			const unhandled = 0
+			const handled = 0
+			const infoWindow = new BMapGL.InfoWindow(
+				`
+      <div class="map-hover-box">
+        <div class="map-hover-title">${row.name}</div>
+				${
+					false
+						? `
+        <div class="map-hover-nums">
+          <div class="map-hover-nums-item">
+            <div class="map-hover-nums-label">今日报警总数</div>
+            <div class="map-hover-nums-value">${number}</div>
+          </div>
+          <div class="map-hover-nums-item">
+            <div class="map-hover-nums-label">今日未处理报警</div>
+            <div class="map-hover-nums-value">${unhandled}</div>
+          </div>
+          <div class="map-hover-nums-item">
+            <div class="map-hover-nums-label">今日已处理报警</div>
+            <div class="map-hover-nums-value">${handled}</div>
+          </div>
+        </div>`
+						: ''
+				}
+        <div class="map-hover-row-item">
+          <div class="map-hover-label">编号:</div>
+          <div class="map-hover-value">${row.key}</div>
+        </div>
+        <div class="map-hover-row-item">
+          <div class="map-hover-label">最后在线时间:</div>
+          <div class="map-hover-value">${row.lastOnlineTime || '-'}</div>
+        </div>
+        <div class="map-hover-row-item">
+          <div class="map-hover-label">${deviceType}地址:</div>
+          <div class="map-hover-value">${row.address || '-'}</div>
+        </div>
+      </div>
+        `,
+				{
+					width: 268 * 1.2, // 信息窗口宽度  268 * 193
+					// height: 120 * 1.2, // 信息窗口高度
+					title: '',
+				}
+			)
+			map.openInfoWindow(infoWindow, point) //开启信息窗口
+			// })
+		})
+	})
+
+	if (!markers.length) return
+
+	// 设置地图显示范围
+	map.setViewport(points, {
+		enableAnimation: true, // 启用动画过渡
+		margins: [30, 30, 30, 30], // 设置四个边界的边距
+	})
+}
+</script>
+<style scoped lang="scss">
+.map {
+	width: 100%;
+	height: 100%;
+	background-color: #ccc;
+}
+</style>
+
+<style lang="scss">
+.map-hover-station {
+	.view-div-head,
+	.view-div {
+		color: #fff;
+		background: #222;
+	}
+}
+
+.BMap_bubble_pop {
+	width: 220px;
+	padding: 0 !important;
+	border: none !important;
+	background: transparent !important;
+	color: #fff !important;
+	margin-top: 0;
+	margin-left: -20px;
+	// pointer-events: none;
+
+	& > img {
+		display: none !important;
+	}
+}
+
+.BMap_bubble_content {
+	color: #fff !important;
+}
+
+// .BMap_bubble_content,
+// .BMap_bubble_center {
+// 	height: 150px !important;
+// }
+
+.BMap_bubble_content {
+	width: 100% !important;
+	height: 100% !important;
+	// background: rgba(0, 29, 122, 0.6) !important;
+	background-image: url('/@/assets/window.png');
+	background-repeat: no-repeat;
+	background-size: 100% 100%;
+	border-radius: 3px;
+	backdrop-filter: blur(5px);
+}
+
+.BMap_bubble_top,
+.BMap_bubble_bottom {
+	display: none !important;
+}
+
+.map-hover-box {
+	color: #fff;
+	font-size: 14px;
+	padding: 15px 20px;
+
+	.map-hover-nums {
+		font-size: 13px;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		margin-top: 10px;
+		padding-bottom: 12px;
+		margin-bottom: 12px;
+		border-bottom: 1px solid #3ba4fc;
+
+		.map-hover-nums-item {
+			text-align: center;
+
+			.map-hover-nums-label {
+				font-weight: 500;
+			}
+
+			.map-hover-nums-value {
+				font-size: 18px;
+				font-weight: bold;
+				color: #fd1d1a;
+				margin-top: 5px;
+			}
+
+			&:last-child .map-hover-nums-value {
+				color: #4496df;
+			}
+		}
+	}
+
+	.map-hover-title {
+		line-height: 1.4;
+		font-size: 16px;
+		font-weight: 500;
+		background-image: url('/@/assets/map-title.png');
+		background-size: 14px 14px;
+		background-repeat: no-repeat;
+		background-position: left center;
+		text-indent: 20px;
+	}
+
+	.map-hover-label {
+		white-space: nowrap;
+	}
+
+	.map-hover-btn {
+		white-space: nowrap;
+		background: #67c23a;
+		padding: 6px 12px;
+		border-radius: 4px;
+		cursor: pointer;
+	}
+
+	.map-hover-row-item {
+		display: flex;
+		align-items: flex-start;
+		line-height: 1.4;
+		margin-top: 5px;
+
+		// gap: 20px;
+		.map-hover-value {
+			// font-size: 22px;
+			color: #4decff;
+			font-weight: 500;
+			word-break: break-all;
+		}
+	}
+}
+</style>