From 1e09a7a01a6c1888e1a2a832eb007fb8c2b653a0 Mon Sep 17 00:00:00 2001
From: ZZJ <zzjdsg2300@163.com>
Date: 星期三, 26 一月 2022 11:06:27 +0800
Subject: [PATCH] Merge branch 'bhomebus' of http://192.168.5.5:10010/r/web/vue-smart-ai into bhomebus

---
 src/pages/internetEquipment/module/mapIndex.vue | 1124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,116 insertions(+), 8 deletions(-)

diff --git a/src/pages/internetEquipment/module/mapIndex.vue b/src/pages/internetEquipment/module/mapIndex.vue
index c00944a..18305c4 100644
--- a/src/pages/internetEquipment/module/mapIndex.vue
+++ b/src/pages/internetEquipment/module/mapIndex.vue
@@ -1,21 +1,1129 @@
 <template>
-  <div class="map-index">
+  <div id="map-index">
+    <div class="control">
+      <a href="#" title="瀹氫綅" @click="aClick()">
+        <div class="location icon iconfont" @click="location">&#xe74e;</div>
+      </a>
+      <a href="#" title="鏀惧ぇ" @click="aClick()">
+        <div class="zoom-in icon iconfont" @click="zoomIn">&#xeb89;</div>
+      </a>
 
+      <a href="#" title="缂╁皬" @click="aClick()">
+        <div class="zoom-out icon iconfont" @click="zoomOut">&#xe758;</div>
+      </a>
+    </div>
+    <a href="#" title="鏂板/缂栬緫" @click="aClick()">
+      <div class="range icon iconfont" @click="drawPolygon">&#xe773;</div>
+    </a>
+    <el-input v-model="nodeId" placeholder="璇疯緭鍏ュ唴瀹�"></el-input>
+    <div class="save" v-if="showBtn" @click="savePoly">淇濆瓨</div>
+    <div class="del" v-if="polygonInfo" @click="delPoly">鍒犻櫎</div>
+    <div class="cancel" v-if="showBtn" @click="resetMap">鍙栨秷</div>
+
+    <span id="polygonInfo" v-show="polygonInfo">{{ polygonInfo }}</span>
+
+    <img
+      v-if="myNode && !isHidden"
+      src="/images/map/Group 594.png"
+      alt=""
+      class="video_icon"
+      @click="hiddenVideo()"
+    />
+    <a v-if="myNode && isHidden" href="#" title="瀹炴椂鐩戞帶" @click="aClick()">
+      <img
+        src="/images/map/鐩戞帶.png"
+        alt=""
+        class="video_icon"
+        @click="showVideo()"
+      />
+    </a>
+
+    <div class="video_box" v-show="myNode" :class="{ hidden: isHidden }">
+      <div class="title">
+        <div class="left">
+          <span class="ball"></span>
+          <span class="left_info">瀹炴椂鐩戞帶</span>
+        </div>
+
+        <div class="right">
+          璁惧缂栫爜: {{ myNode && myNode.values && myNode.values_.id }}
+        </div>
+      </div>
+
+      <video controls="controls" loop="loop">
+        <source src="/images/map/video_20210924_101628.mp4" type="video/mp4" />
+      </video>
+    </div>
+
+    <div class="helmet_box" v-show="myNodeHover">
+      <div class="icon_close iconfont" @click="close">&#xe729;</div>
+      <div class="sn" v-if="myNodeHover">{{ myNodeHover.values_.lat.id }}</div>
+      <div class="location" v-if="myNodeHover">
+        缁忓害: {{ myNodeHover.values_.lat }}
+      </div>
+      <div class="location" v-if="myNodeHover">
+        绾害: {{ myNodeHover.values_.lng }}
+      </div>
+      <div class="info" v-if="myNodeHover">
+        鐢甸噺: {{ myNodeHover.values_.battery }}
+      </div>
+      <div class="button">
+        <img
+          src="/images/InternetData/瑙嗛.png"
+          alt=""
+          v-if="!isSending"
+          @click="sendVoice()"
+        />
+        <img src="/images/InternetData/瑙嗛_鐐瑰嚮.png" alt="" v-if="isSending" />
+        <img
+          src="/images/InternetData/璇煶.png"
+          alt=""
+          v-if="isTele == false"
+          @click="isTele = true"
+        />
+        <img
+          src="/images/InternetData/璇煶_鐐瑰嚮.png"
+          alt=""
+          v-if="isTele == true"
+          @click="isTele = false"
+        />
+      </div>
+    </div>
+
+    <telephoneBox :tele="myNode" v-if="isTele" @close="isTele = false" />
+
+    <div class="mask" v-if="isTele"></div>
   </div>
 </template>
 
 <script>
-export default {
+import {
+  getHelemtData,
+  getZones,
+  createZones,
+  delZones,
+  sendAudio,
+} from "@/api/helemt";
+import telephoneBox from "../components/telephoneBox.vue";
 
-}
+import "ol/ol.css";
+import Feature from "ol/Feature";
+import Point from "ol/geom/Point";
+import VectorSource from "ol/source/Vector";
+import { Icon, Style, Fill, Stroke } from "ol/style";
+import { transform } from "ol/proj";
+import { Map, View } from "ol";
+import TileLayer from "ol/layer/Tile";
+import { Vector as VectorLayer } from "ol/layer";
+import OSM from "ol/source/OSM";
+import Draw from "ol/interaction/Draw";
+import { Modify, Snap } from "ol/interaction";
+import Polygon from "ol/geom/Polygon";
+import Select from "ol/interaction/Select";
+import Overlay from "ol/Overlay";
+import { pointerMove } from "ol/events/condition";
+
+let myMap = {};
+let myVectorSource = {};
+let baseLayer = new TileLayer({
+  source: new OSM({
+    // url:'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=8',
+    url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
+    crossOrigin: "anonymous",
+    // url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
+  }),
+});
+let myDraw = {};
+let myModify = {};
+let myPolygon = {};
+let mySelect = {};
+let mySelect2 = {};
+let overlay = {};
+let overlay2 = {};
+let voiceText = "";
+let drawFeature = [];
+export default {
+  data() {
+    return {
+      isSending: false,
+      isTele: false,
+      isHidden: false,
+      showBtn: false,
+      nodeArr: [],
+      nodeId: "",
+      iconArr: [],
+      rangeArr: [],
+      zoom: 15,
+      center: [116.06667, 39.66667],
+      polygonArr: [],
+      polyFeature: [],
+      drawStore: [],
+      modifyStore: [],
+      polygonInfo: "",
+      nodeFeature: [],
+      myNode: null,
+      myNodeHover: null,
+      commentContent: "",
+    };
+  },
+  mounted() {
+    this.initMap();
+  },
+  components: {
+    telephoneBox,
+  },
+  methods: {
+    async initMap() {
+      const that = this;
+      // 鑾峰彇鑺傜偣
+      const res = await getHelemtData();
+      this.nodeArr = [];
+      res.data.items.forEach((item) => {
+        this.nodeArr.push({
+          data: [item.lng, item.lat],
+          id: item.device_sn,
+          color: item.is_out_bound == 0 ? "缁�" : "绾�",
+          battery: item.battery,
+        });
+      });
+
+      // 鑾峰彇鍖哄煙
+      const res2 = await getZones();
+      if (res2.data && res2.data.items && res2.data.items.length > 0) {
+        this.polygonArr = res2.data.items.map((obj) => {
+          obj.data = obj.dots.map((item) => {
+            return transform([item[0], item[1]], "EPSG:4326", "EPSG:3857");
+          });
+          return obj;
+        });
+      }
+
+      // 璁剧疆鍦板浘涓績
+      this.center = this.nodeArr[0].data;
+
+      if (this.polygonArr.length > 0) {
+        this.initPolygonArr();
+      }
+
+      const vectorSource = new VectorSource({
+        features: this.polyFeature,
+      });
+      /* if(this.polygonArr.length>0){
+      this.initPolygonArr()
+      console.log(this.polyFeature);
+      vectorSource.addFeature(this.polyFeature[0])
+      } */
+      myVectorSource = vectorSource;
+      this.initAllNode();
+
+      const vectorLayer = this.initLayer(vectorSource);
+
+      const map = this.initBottomMap(vectorLayer);
+
+      myMap = map;
+      /* map.getView().on('change:resolution', ()=> {
+      this.iconArr.forEach(item=>{
+        let style = item.getStyle()
+        console.log(this.zoom);
+        style.getImage().setScale(this.zoom/15)
+        item.setStyle(style)
+        console.log(item);
+      })
+    }) */
+
+      window.addEventListener("resize", function () {
+        map.updateSize();
+      });
+
+      const select = new Select({
+        filter: (feature, layer) => {
+          if (feature.values_ && feature.values_.type == "node") {
+            this.myNode = feature;
+            return true;
+          } else if (feature.type && feature.type == "polygon") {
+            myPolygon = feature;
+            this.myNode = null;
+            this.nodeId = "";
+            return true;
+          }
+        },
+        style: (feature) => {
+          if (feature.values_ && feature.values_.type == "node") {
+            return new Style({
+              image: new Icon({
+                size: [32, 32],
+                src: `/images/map/瀹夊叏甯�-${feature.values_.color}.png`,
+              }),
+              zIndex: 1,
+            });
+          } else if (feature.type && feature.type == "polygon") {
+            return new Style({
+              fill: new Fill({
+                color: "rgba(0, 0, 255, 0.1)",
+              }),
+              stroke: new Stroke({
+                color: "skyblue",
+                width: 3,
+              }),
+            });
+          }
+        },
+      });
+
+      const select2 = new Select({
+        condition: pointerMove,
+        filter: (feature, layer) => {
+          if (feature.values_ && feature.values_.type == "node") {
+            this.myNodeHover = feature;
+            return true;
+          } else {
+            return false;
+          }
+        },
+        style: (feature) => {
+          if (feature.values_ && feature.values_.type == "node") {
+            return new Style({
+              image: new Icon({
+                size: [32, 32],
+                src: `/images/map/瀹夊叏甯�-${feature.values_.color}.png`,
+              }),
+              zIndex: 1,
+            });
+          }
+        },
+      });
+
+      const info = document.querySelector("#polygonInfo");
+
+      map.addInteraction(select);
+      map.addInteraction(select2);
+      mySelect = select;
+      mySelect2 = select2;
+
+      select.on("select", function (e) {
+        //   e.stopPropagation();
+        console.log("--------------");
+        overlay.setPosition(undefined);
+
+        if (e.selected.length == 0) {
+          console.log("999999");
+
+          that.polygonInfo = "";
+          that.nodeId = "";
+          that.myNode = null;
+          return false;
+        }
+
+        if (e.selected[0].values_.type == "node") {
+          that.isHidden = false;
+          that.nodeId = e.selected[0].values_.id;
+          return false;
+        }
+
+        if (myPolygon.polygonName) {
+          that.polygonInfo = myPolygon.polygonName;
+        } else {
+          that.polygonInfo = "鏂板尯鍩�";
+        }
+        if (e.mapBrowserEvent) {
+          console.log(e.mapBrowserEvent.coordinate);
+          overlay.setPosition(e.mapBrowserEvent.coordinate);
+        }
+
+        return false;
+      });
+
+      select2.on("select", function (e) {
+        if (
+          e.selected.length &&
+          e.selected[0].values_.type == "node" &&
+          that.myNodeHover &&
+          that.myNodeHover.values_.id == e.selected[0].values_.id
+        ) {
+          overlay2.setPosition(e.mapBrowserEvent.coordinate);
+        } else {
+        }
+      });
+    },
+    initNode([x, y], color) {
+      const iconFeature = new Feature({
+        geometry: new Point(transform([x, y], "EPSG:4326", "EPSG:3857")),
+      });
+
+      const iconStyle = new Style({
+        image: new Icon({
+          size: [32, 32],
+          src: `/images/map/瀹夊叏甯�-${color}.png`,
+        }),
+        zIndex: 1,
+      });
+
+      iconFeature.setStyle(iconStyle);
+      this.iconArr.push(iconFeature);
+      iconFeature.set("color", `${color}`);
+      iconFeature.set("lat", `${x}`);
+      iconFeature.set("lng", `${y}`);
+
+      return iconFeature;
+    },
+    initAllNode() {
+      this.nodeArr.forEach((item) => {
+        const node = this.initNode(item.data, item.color);
+        node.set("id", item.id);
+        node.set("type", "node");
+        node.set("battery", item.battery);
+        this.nodeFeature.push(node);
+        myVectorSource.addFeature(node);
+      });
+    },
+    initPolygonArr() {
+      this.polyFeature = [];
+      this.polygonArr.forEach((item) => {
+        const feature = new Feature({ geometry: new Polygon([item.data]) });
+        feature.id = item.id;
+        feature.type = "polygon";
+        feature.polygonName = item.name;
+        feature.data1 = item.data[1];
+        this.polyFeature.push(feature);
+      });
+    },
+    initLayer(source) {
+      return new VectorLayer({
+        source: source,
+        style: new Style({
+          fill: new Fill({
+            color: "rgba(255, 255, 255, 0.4)",
+          }),
+          stroke: new Stroke({
+            color: "#F54336",
+            width: 2,
+          }),
+        }),
+      });
+    },
+    initBottomMap(vectorLayer) {
+      const info = document.querySelector("#polygonInfo");
+      const helmet_box = document.querySelector(".helmet_box");
+      overlay2 = new Overlay({
+        element: helmet_box,
+        autoPan: true,
+        autoPanAnimation: {
+          duration: 250,
+        },
+      });
+
+      overlay = new Overlay({
+        element: info,
+      });
+      return new Map({
+        target: "map-index",
+        layers: [baseLayer, vectorLayer],
+        view: new View({
+          center: transform(this.center, "EPSG:4326", "EPSG:3857"),
+          zoom: this.zoom,
+        }),
+        overlays: [overlay, overlay2],
+      });
+    },
+    zoomIn() {
+      const view = myMap.getView();
+      this.zoom++;
+      view.setZoom(this.zoom);
+    },
+    zoomOut() {
+      const view = myMap.getView();
+      this.zoom--;
+      view.setZoom(this.zoom);
+    },
+    location() {
+      const view = myMap.getView();
+      view.setZoom(this.zoom);
+      view.setCenter(transform(this.center, "EPSG:4326", "EPSG:3857"));
+    },
+    drawPolygon() {
+      this.rangeArr = [];
+      this.myNodeHover = null;
+      //   this.myNode = null;
+      //   this.nodeId = "";
+      mySelect2.getFeatures().clear();
+
+      mySelect.dispatchEvent({
+        type: "select",
+        selected: [],
+      });
+
+      this.resetMap();
+      mySelect.setActive(false);
+      mySelect2.setActive(false);
+      this.showBtn = true;
+      const draw = new Draw({
+        source: myVectorSource,
+        type: "Polygon",
+      });
+      myDraw = draw;
+      draw.on("drawend", (event) => {
+        let id;
+
+        /* if (this.polygonArr.length > 0) {
+          id =
+            this.drawStore.length > 0
+              ? +this.drawStore[this.drawStore.length - 1].id + 1
+              : +this.polygonArr[this.polygonArr.length - 1].id + 1;
+        } else {
+          id = 1;
+        } */
+
+        if (this.drawStore.length > 0) {
+          id = +this.drawStore[this.drawStore.length - 1].id + 1;
+        } else {
+          id =
+            this.polygonArr.length > 0
+              ? +this.polygonArr[this.polygonArr.length - 1].id + 1
+              : "1";
+        }
+
+        event.feature.id = id;
+        event.feature.type = "polygon";
+        this.drawStore.push({
+          id,
+          data: event.feature.getGeometry().getCoordinates()[0],
+        });
+        drawFeature.push(event.feature);
+      });
+
+      const modify = new Modify({ source: myVectorSource });
+      modify.addEventListener("modifyend", (event) => {
+        const id = event.features.array_[0].id;
+        const data = event.features.array_[0].getGeometry().getCoordinates()[0];
+        this.modifyStore.push({ id, data });
+      });
+      myModify = modify;
+      myMap.addInteraction(modify);
+      myMap.addInteraction(draw);
+    },
+    resetMap() {
+      drawFeature = [];
+      this.polygonInfo = "";
+      mySelect.setActive(true);
+      mySelect2.setActive(true);
+      this.initPolygonArr();
+      const vectorSource = new VectorSource({
+        features: this.polyFeature,
+      });
+      /* if(this.polygonArr.length>0){
+      this.initPolygonArr()
+      vectorSource.addFeature(this.polyFeature[0])
+      } */
+      myVectorSource = vectorSource;
+      this.initAllNode();
+
+      const vectorLayer = this.initLayer(vectorSource);
+      myMap.setLayers([baseLayer, vectorLayer]);
+      myMap.removeInteraction(myDraw);
+      myMap.removeInteraction(myModify);
+      this.showBtn = false;
+      this.drawStore = [];
+      this.modifyStore = [];
+    },
+    async savePoly() {
+      mySelect.setActive(true);
+      mySelect2.setActive(true);
+      myMap.removeInteraction(myDraw);
+      myMap.removeInteraction(myModify);
+      this.showBtn = false;
+      if (this.drawStore.length) {
+        this.polygonArr = [...this.polygonArr, ...this.drawStore];
+        this.drawStore = [];
+      }
+      if (this.modifyStore.length) {
+        this.modifyStore.forEach((item) => {
+          this.polygonArr.forEach((item2) => {
+            if (item.id == item2.id) {
+              item2.data = item.data;
+            }
+          });
+        });
+        this.modifyStore = [];
+      }
+      const arrData = this.polygonArr.map((item) => {
+        let name = item.name ? item.name : "";
+        let data = item.data.map((arr) => {
+          arr = transform([arr[0], arr[1]], "EPSG:3857", "EPSG:4326");
+          return arr.join(",");
+        });
+        data = data.join("&");
+        return {
+          name,
+          dots: data,
+          id: +item.id,
+        };
+      });
+      const res = await createZones({ dots_arr: arrData });
+      if (res.status == 200) {
+        this.$message({
+          type: "success",
+          message: "淇濆瓨鎴愬姛!",
+        });
+      } else {
+        this.$message({
+          type: "info",
+          message: "淇濆瓨澶辫触",
+        });
+      }
+
+      const res2 = await getZones();
+      if (res2.data && res2.data.items && res2.data.items.length > 0) {
+        this.polygonArr = res2.data.items.map((obj) => {
+          obj.data = obj.dots.map((item) => {
+            return transform([item[0], item[1]], "EPSG:4326", "EPSG:3857");
+          });
+          return obj;
+        });
+      }
+
+      if (drawFeature.length > 0) {
+        this.polyFeature.forEach((item) => {
+          myVectorSource.removeFeature(item);
+        });
+        this.initPolygonArr();
+
+        this.polyFeature.forEach((item) => {
+          myVectorSource.addFeature(item);
+        });
+      }
+
+      //   ;
+
+      /*  const res = await getHelemtData();
+      this.nodeArr = [];
+      res.data.items.forEach((item) => {
+        this.nodeArr.push({
+          data: [item.lng, item.lat],
+          id: item.device_sn,
+          color: item.is_out_bound == 0 ? "缁�" : "绾�",
+        });
+      });
+      this.nodeFeature.forEach((item) => {
+        myVectorSource.removeFeature(item);
+      });
+      this.initNode();
+      this.initAllNode(); */
+    },
+    delPoly() {
+      this.$confirm("姝ゆ搷浣滃皢鍒犻櫎璇ュ尯鍩�, 鏄惁缁х画?", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning",
+      })
+        .then(async () => {
+          myVectorSource.removeFeature(myPolygon);
+          const res = await delZones({ id: myPolygon.id });
+          if (res.status == 200) {
+            this.$message({
+              type: "success",
+              message: "鍒犻櫎鎴愬姛!",
+            });
+            this.polygonInfo = "";
+            const res2 = await getZones();
+            if (res2.data && res2.data.items && res2.data.items.length > 0) {
+              this.polygonArr = res2.data.items.map((obj) => {
+                obj.data = obj.dots.map((item) => {
+                  return transform(
+                    [item[0], item[1]],
+                    "EPSG:4326",
+                    "EPSG:3857"
+                  );
+                });
+                return obj;
+              });
+            }
+          } else {
+            this.$message({
+              type: "info",
+              message: "鍒犻櫎澶辫触",
+            });
+          }
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "宸插彇娑堝垹闄�",
+          });
+        });
+    },
+    showVideo() {
+      if (!this.myNode) {
+        return false;
+      }
+
+      this.isHidden = false;
+    },
+    hiddenVideo() {
+      document.querySelector("video").pause();
+      this.isHidden = true;
+    },
+    close() {
+      overlay2.setPosition(undefined);
+    },
+    onCommentInputChange() {
+      let value = document.querySelector("#commentContent").value;
+      voiceText = value;
+      let cont = 20 - value.length;
+      document.querySelector(
+        "#comment_info"
+      ).innerHTML = `杩樺彲杈撳叆${cont}涓瓧绗;
+    },
+    sendVoice() {
+      const _this = this;
+      this.isSending = true;
+
+      const h = this.$createElement;
+      this.$msgbox({
+        message: h(
+          "div",
+          {
+            attrs: {
+              class: "el-textarea",
+            },
+          },
+          [
+            h(
+              "div",
+              {
+                attrs: {
+                  class: "el-title",
+                },
+              },
+              [
+                h(
+                  "span",
+                  {
+                    attrs: {
+                      class: "icon iconfont",
+                    },
+                  },
+                  "\ue7cc"
+                ),
+                h("span", null, "鍙戦�佽闊�"),
+              ]
+            ),
+            h("textarea", {
+              attrs: {
+                placeholder: "璇疯緭鍏ヨ闊冲懡浠�",
+                maxlength: "20",
+                class: "el-textarea__inner",
+                autocomplete: "off",
+                rows: 3,
+                id: "commentContent",
+              },
+              value: this.commentContent,
+              on: { input: this.onCommentInputChange },
+            }),
+            h(
+              "div",
+              { attrs: { class: "info", id: "comment_info" } },
+              "杩樺彲杈撳叆20涓瓧绗�"
+            ),
+          ]
+        ),
+        showCancelButton: true,
+        confirmButtonText: "纭畾",
+        confirmButtonClass: "hele_btn_save",
+        cancelButtonClass: "hele_btn_cancel",
+        cancelButtonText: "鍙栨秷",
+        beforeClose: (action, instance, done) => {
+          document.querySelector("#commentContent").value = "";
+          document.querySelector(
+            "#comment_info"
+          ).innerHTML = `杩樺彲杈撳叆20涓瓧绗;
+          _this.isSending = false;
+          done();
+        },
+      })
+        .then((action) => {
+          if (action == "confirm") {
+            if (!voiceText) {
+              this.$message({
+                message: "鎸囦护涓嶈兘涓虹┖",
+                type: "warning",
+              });
+              _this.isSending = false;
+              return;
+            }
+            sendAudio(_this.myNode.values_.id, voiceText).then((res) => {
+              this.$message({
+                message: "鎸囦护鍙戦�佹垚鍔�",
+                type: "success",
+              });
+              _this.isSending = false;
+            });
+            _this.isSending = false;
+          } else {
+            _this.isSending = false;
+          }
+        })
+        .catch(() => {
+          _this.isSending = false;
+        });
+    },
+    aClick() {
+      return false;
+    },
+  },
+  watch: {
+    nodeId: {
+      async handler(val) {
+        if (!val) {
+          if (this.rangeArr.length > 0) {
+            this.rangeArr.forEach((item) => {
+              myVectorSource.removeFeature(item);
+            });
+            this.rangeArr = [];
+          }
+
+          return false;
+        }
+
+        const res = await getHelemtData({ sn: val });
+
+        if (res.msg == "zone") {
+          mySelect.getFeatures().clear();
+          const polyArr = this.polyFeature.filter((item) => {
+            return item.id == res.data.ID;
+          });
+
+          myPolygon = polyArr[0];
+          mySelect.getFeatures().push(polyArr[0]);
+          mySelect.dispatchEvent({
+            type: "select",
+            selected: [polyArr[0]],
+            mapBrowserEvent: {
+              coordinate: polyArr[0].data1,
+            },
+          });
+
+          return;
+        }
+
+        const arr = [];
+        if (res.data.items && res.data.items.length > 0) {
+          res.data.items.forEach((obj) => {
+            this.nodeArr.forEach((item) => {
+              if (item.id == obj.device_sn) {
+                arr.push(item);
+              }
+            });
+          });
+        }
+
+        if (this.rangeArr.length > 0) {
+          this.rangeArr.forEach((item) => {
+            myVectorSource.removeFeature(item);
+          });
+          this.rangeArr = [];
+        }
+
+        if (arr.length > 0) {
+          arr.forEach((item) => {
+            const rangeFeature = new Feature({
+              geometry: new Point(
+                transform(item.data, "EPSG:4326", "EPSG:3857")
+              ),
+              name: "Null Island",
+              population: 4000,
+              rainfall: 500,
+            });
+
+            const iconStyle = new Style({
+              image: new Icon({
+                size: [64, 64],
+                src: `/images/map/鑼冨洿-${item.color}.png`,
+              }),
+            });
+
+            rangeFeature.setStyle(iconStyle);
+            myVectorSource.addFeature(rangeFeature);
+            rangeFeature.set("type", "range");
+            this.rangeArr.push(rangeFeature);
+          });
+        }
+      },
+    },
+  },
+};
 </script>
 
 <style scoped lang="scss">
-.map-index  {
-    width: 1170px;
-    height: 396px;
-    border-radius: 15px;
-    background-color: skyblue
+a {
+  background-color: transparent;
+  color: #337ab7;
+  text-decoration: none;
+}
+a:active a:hover {
+  outline: 0;
 }
 
+#map-index {
+  position: relative;
+  margin: 20px 0;
+  width: 100%;
+  height: 396px;
+  border-radius: 15px;
+
+  .helmet_box {
+    width: 205px;
+    height: 172px;
+    padding: 10px 10px 20px 15px;
+    font-size: 12px;
+    background: rgba(255, 255, 255, 0.7);
+    backdrop-filter: blur(4px);
+    border-radius: 15px;
+    text-align: left;
+
+    .icon_close {
+      text-align: right;
+      cursor: pointer;
+    }
+
+    .sn {
+      color: #f54336;
+    }
+    .location {
+      margin: 10px 0;
+    }
+    .button {
+      margin-top: 10px;
+      text-align: center;
+      img {
+        cursor: pointer;
+        width: 22px;
+        &:first-child {
+          margin-right: 48px;
+        }
+      }
+    }
+  }
+
+  .video_box {
+    box-sizing: border-box;
+    overflow: hidden;
+    position: absolute;
+    z-index: 2;
+    top: 45px;
+    right: 25px;
+    width: 483px;
+    height: 306px;
+    background: rgba(241, 250, 246, 0.6);
+    backdrop-filter: blur(4px);
+    /* Note: backdrop-filter has minimal browser support */
+    border-radius: 15px;
+    border: 1px solid rgb(17, 170, 102);
+    transition: all linear 0.5s;
+
+    &.hidden {
+      width: 0;
+      border: none;
+    }
+
+    .title {
+      margin: 15px 40px 0 20px;
+      width: 420px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      color: #4f4f4f;
+      font-size: 12px;
+
+      .left {
+        .ball {
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border: 4px solid #f54336;
+          border-radius: 2px;
+          margin-right: 10px;
+        }
+      }
+    }
+
+    video {
+      margin: 8px 40px 0 20px;
+      width: 424px;
+      height: 246px;
+      object-fit: fill;
+    }
+  }
+
+  .control {
+    position: absolute;
+    display: flex;
+    flex-direction: column;
+    z-index: 1;
+    left: 25px;
+    bottom: 25px;
+    width: 30px;
+    height: 91px;
+    background: #ffffff;
+    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.25);
+    border-radius: 8px;
+    .location,
+    .zoom-in,
+    .zoom-out {
+      line-height: 30px;
+      font-size: 18px;
+      flex: 1;
+      cursor: pointer;
+    }
+    .location {
+      background: #11aa66;
+      border-radius: 8px 8px 0 0;
+      color: #fff;
+    }
+  }
+  .el-input {
+    position: absolute;
+    z-index: 1;
+    top: 15px;
+    left: 15px;
+    width: 205px;
+    height: 35px;
+    ::v-deep input {
+      width: 100%;
+      height: 100%;
+
+      &:focus {
+        border-color: #11aa66 !important;
+      }
+    }
+  }
+  .range {
+    position: absolute;
+    left: 25px;
+    bottom: 126px;
+    width: 30px;
+    height: 30px;
+    background: #11aa66;
+    color: #fff;
+    border-radius: 8px;
+    cursor: pointer;
+    z-index: 1;
+    line-height: 30px;
+  }
+  .save {
+    position: absolute;
+    z-index: 3;
+    top: 15px;
+    right: 113px;
+    width: 87px;
+    height: 35px;
+    background: #11aa66;
+    border: 1px solid #11aa66;
+    border-radius: 8px;
+    color: #fff;
+    font-size: 12px;
+    line-height: 36px;
+    cursor: pointer;
+  }
+
+  .cancel {
+    position: absolute;
+    z-index: 3;
+    top: 15px;
+    right: 20px;
+    width: 87px;
+    height: 35px;
+    background: #fff;
+    border: 1px solid #11aa66;
+    border-radius: 8px;
+    color: #4f4f4f;
+    font-size: 12px;
+    line-height: 36px;
+    cursor: pointer;
+  }
+
+  .del {
+    position: absolute;
+    z-index: 3;
+    top: 15px;
+    right: 113px;
+    width: 87px;
+    height: 35px;
+    background: rgb(245, 108, 108);
+    border: 1px solid rgb(245, 108, 108);
+    border-radius: 8px;
+    color: #fff;
+    font-size: 12px;
+    line-height: 36px;
+    cursor: pointer;
+  }
+
+  .video_icon {
+    position: absolute;
+    z-index: 3;
+    top: 179px;
+    right: 10px;
+    width: 37px;
+  }
+
+  #polygonInfo {
+    position: absolute;
+    padding: 10px;
+    border: 1px solid;
+    color: black;
+    background-color: #fff;
+    z-index: 3;
+    width: 100px;
+  }
+
+  .mask {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    text-align: center;
+    z-index: 4;
+    background-color: black;
+    opacity: 0.5;
+  }
+}
+
+.el-textarea {
+  height: 150px;
+  padding: 0 15px;
+
+  .el-title {
+    margin-top: 20px;
+    margin-bottom: 15px;
+    color: #4f4f4f;
+    font-size: 16px;
+    font-weight: 700;
+
+    .icon {
+      font-weight: normal;
+      font-size: 19px;
+    }
+  }
+
+  .el-textarea__inner {
+    width: 357px;
+
+    &:focus {
+      border: 1px solid #11aa66;
+    }
+  }
+
+  .info {
+    font-size: 12px;
+    color: #828282;
+    text-align: right;
+    padding-right: 38px;
+  }
+}
+</style>
+
+<style>
+.ol-zoom {
+  display: none !important;
+}
 </style>
\ No newline at end of file

--
Gitblit v1.8.0