huangmp il y a 4 ans
Parent
commit
a31b43827d

BIN
public/img/icon/menjin1.png


BIN
public/img/icon/video-device.png


BIN
public/img/icon/video-device1.png


BIN
public/img/icon/video-device2.png


BIN
public/img/icon/video-device3.png


BIN
public/img/icon/video-device4.png


+ 27 - 0
src/api/device/gb/gbdevicechannel.js

@@ -32,6 +32,14 @@ export const remove = (ids) => {
   })
 }
 
+export const edit = (row) => {
+  return request({
+    url: '/api/cyzh-smart-device/gbdevicechannel/edit',
+    method: 'post',
+    data: row
+  })
+}
+
 export const add = (row) => {
   return request({
     url: '/api/cyzh-smart-device/gbdevicechannel/submit',
@@ -48,6 +56,15 @@ export const update = (row) => {
   })
 }
 
+
+export const updateBatch = (row) => {
+  return request({
+    url: '/api/cyzh-smart-device/gbdevicechannel/updateBatch',
+    method: 'post',
+    data: row
+  })
+}
+
 //设备点播
 export const startPlay = (deviceId, channelId) => {
   return request({
@@ -97,3 +114,13 @@ export const channelBindLocal = (deviceId, channelId, residentialId, buildingId,
     }
   })
 }
+
+export const getVideoDeviceCoordinates = (params) => {
+  return request({
+    url: '/api/cyzh-smart-device/gbdevicechannel/getVideoDeviceCoordinates',
+    method: 'get',
+    params: {
+      ...params,
+    }
+  })
+}

+ 90 - 26
src/components/map/comps/device-list.vue

@@ -4,38 +4,37 @@
       <more title='设备列表' nomore></more>
     </div>
     <div style="margin:0px 0px 15px">
-      <tab :list="tabList" width="4.4rem"></tab>
+      <tab @click="select" :list="tabList" width="4.4rem"></tab>
     </div>
 
-    <div class="device" v-loading="loading" style="height:100%">
+    <div v-if="$isNotEmpty(list)" class="device" v-loading="loading" style="height:100%">
       <div class="card" style="padding:13px 20px;" @click.stop="clickDevice(item)" v-for="(item,index) in list"
         :key="index">
         <div class="left">
           <div class="name text-cut">
-            {{item.name}}
+            {{handelData(item).name}}
           </div>
 
           <div class="address text-cut" style="display:flex">
-            <span v-if="$isEmpty(item.latitude)||$isEmpty(item.longitude)" style="color:#fa3534;margin-right:4px">
+            <span v-if="$isEmpty(handelData(item).latitude)||$isEmpty(handelData(item).longitude)"
+              style="color:#fa3534;margin-right:4px">
               [未设置坐标]</span>
-            <img v-else src="../../../../public/img/icon/location2.png"
+            <img v-else src="/img/icon/location2.png"
               style="width:16px;height:16px;margin-right:2px;margin-top:2px"></img>
-            {{item.address}}
+            {{handelData(item).address}}
           </div>
         </div>
+
         <!-- 中间菜单 -->
         <div class="right">
           <div class="status">
-            <span style="color:#fa3534" v-if="item.deviceStatus==0">离线</span>
-            <span style="color:#19be6b" v-else-if="item.deviceStatus==1">在线</span>
-            <span style="color:#82848a" v-else>未知</span>
-
+            <span :style="{color:handelData(item).statusColor}">{{handelData(item).statusName}}</span>
 
             <el-dropdown>
               <i class="el-icon-s-operation" style="color:#3b8ff4;margin-left:10px"></i>
               <el-dropdown-menu slot="dropdown">
-                <el-dropdown-item @click.native="dropdownClick(item)"
-                  v-for="(item1,index1) in operationList" :key="index1" :icon="item1.icon">
+                <el-dropdown-item @click.native="dropdownClick(item,item1)" v-for="(item1,index1) in operationList"
+                  :key="index1" :icon="item1.icon">
                   {{item1.name}}
                 </el-dropdown-item>
               </el-dropdown-menu>
@@ -47,13 +46,15 @@
           </div>
         </div>
       </div>
-      <div class="pagination" style="display:flex;justify-content: flex-end">
+      <div class="pagination" v-if="page.pages!=1&&page.pages!=0" style="display:flex;justify-content: flex-end">
         <el-pagination @current-change="currentChange" small background :page-count="page.pages"
           layout="prev, pager, next">
         </el-pagination>
       </div>
     </div>
 
+    <avue-empty v-else style="margin-top: 150px;"></avue-empty>
+
 
   </div>
 </template>
@@ -63,8 +64,12 @@
   import tab from "@/components/tab.vue"
   import more from "@/components/more.vue"
   import {
-    getList
+    getList as getDoorDeviceList
   } from "@/api/device/doordevice.js"
+
+  import {
+    getList as getVideoDeviceList
+  } from "@/api/device/gb/gbdevicechannel.js"
   export default {
     components: {
       tab,
@@ -90,23 +95,74 @@
           }
         ],
         operationList: [{
-          index:0,
+            index: 0,
             icon: 'el-icon-view',
             name: '详情',
           },
           {
-            index:1,
+            index: 1,
             icon: 'el-icon-edit',
             name: '编辑'
           },
           {
-            index:2,
+            index: 2,
             icon: 'el-icon-delete',
             name: '删除'
           }
         ]
       }
     },
+    computed: {
+      handelData() {
+        return item => {
+          let obj = {
+            name: '',
+            statusName: '',
+            statusColor: '',
+            latitude: '',
+            longitude: '',
+            address: '',
+          }
+          if (this.activeIndex == 0) {
+            obj.name = item.name
+            obj.longitude = item.longitude
+            obj.latitude = item.latitude
+            obj.address = item.address
+
+
+            if (item.deviceStatus == 0) {
+              obj.statusName = '离线'
+              obj.statusColor = '#fa3534'
+            } else if (item.deviceStatus == 1) {
+              obj.statusName = '在线'
+              obj.statusColor = '#19be6b'
+            } else {
+              obj.statusName = '未知'
+              obj.statusColor = '#82848a'
+            }
+          } else if (this.activeIndex == 1) {
+            obj.name = item.name
+            obj.longitude = item.longitude
+            obj.latitude = item.latitude
+            obj.address = item.address
+            obj.statusColor = '#82848a'
+
+            if (item.ptzType == 0) {
+              obj.statusName = '未知'
+            } else if (item.deviceStatus == 1) {
+              obj.statusName = '球机'
+            } else if (item.deviceStatus == 2) {
+              obj.statusName = '半球'
+            } else if (item.deviceStatus == 3) {
+              obj.statusName = '固定枪机'
+            } else if (item.deviceStatus == 4) {
+              obj.statusName = '遥控枪机'
+            }
+          }
+          return obj
+        }
+      }
+    },
     created() {
       this.fetchDeviceList()
     },
@@ -119,14 +175,17 @@
       }
     },
     methods: {
-      dropdownClick(item){
-        let index=item.index
-        switch (index){
-          case 0:
-            break;
-          default:
-            break;
+      select(item) {
+        this.activeIndex = item.value
+        this.fetchDeviceList()
+        this.$emit('select', this.activeIndex)
+      },
+      dropdownClick(item,item1) {
+        let obj={
+          name:item1.name,
+          data:item
         }
+        this.$emit('dropdownClick',obj)
       },
       clickDevice(data) {
         this.list.forEach(item => {
@@ -136,8 +195,12 @@
       },
       async fetchDeviceList() {
         this.loading = true
-        let res = await getList(this.page.current, this.page.size)
-        let data = res.data.data
+        let data = {}
+        if (this.activeIndex == 0) {
+          data = (await getDoorDeviceList(this.page.current, this.page.size)).data.data
+        } else if (this.activeIndex == 1) {
+          data = (await getVideoDeviceList(this.page.current, this.page.size)).data.data
+        }
         this.initData(data)
         this.loading = false
       },
@@ -161,6 +224,7 @@
   * {
     box-sizing: border-box;
   }
+
   /* 设备列表 */
   .container {
     border-top: 1px solid #f2f1ed;

+ 315 - 0
src/components/map/comps/video-device-form.vue

@@ -0,0 +1,315 @@
+<template>
+  <div>
+    <el-dialog :modal-append-to-body="true" :append-to-body="true" :title="title" :before-close="beforeClose"
+      :center="true" :visible.sync="dialogShow" width="45%" :close-on-click-modal="false" top="4%">
+      <avue-form ref="avueForm" :option="option" v-model="model" @submit="submit"></avue-form>
+    </el-dialog>
+  </div>
+</template>
+<script>
+  import {
+    update
+  } from "@/api/device/gb/gbdevicechannel.js"
+  import {
+    deepClone
+  } from '@/util/util.js'
+  export default {
+    data() {
+      return {
+        isAdd: false,
+
+        dialogShow: false,
+        model: {},
+        option: {
+          detail: true,
+          labelWidth: 110,
+          group: [{
+            label: '基本信息',
+            prop: 'group1',
+            column: [{
+                label: "设备编号",
+                prop: "deviceId",
+                overHidden: true,
+                disabled: true,
+                rules: [{
+                  required: false,
+                  message: "请输入设备编号",
+                  trigger: "blur"
+                }]
+              }, {
+                label: "设备名称",
+                prop: "name",
+                labelWidth: 100,
+                width: 150,
+                rules: [{
+                  required: true,
+                  message: "请输入设备名称",
+                  trigger: "blur"
+                }],
+              },
+              {
+                label: "厂商名称",
+                prop: "manufacture",
+              },
+              {
+                label: "型号",
+                prop: "model",
+                hide: true,
+                disabled: true,
+              },
+              {
+                label: "ip地址",
+                prop: "ipAddress",
+                hide: true,
+                disabled: true,
+              },
+              {
+                label: "端口号",
+                prop: "port",
+                hide: true,
+                disabled: true,
+              },
+              {
+                label: "云台类型",
+                prop: "ptzType",
+                slot: true,
+                search: true,
+                type: "select",
+                width: 100,
+                align: "center",
+                disabled: true,
+                dicData: [{
+                    label: "未知",
+                    value: 0
+                  },
+                  {
+                    label: "球机",
+                    value: 1
+                  },
+                  {
+                    label: "半球",
+                    value: 2
+                  },
+                  {
+                    label: "固定枪机",
+                    value: 3
+                  },
+                  {
+                    label: "遥控枪机",
+                    value: 4
+                  }
+                ]
+              },
+              {
+                label: "是否有音频",
+                prop: "hasAudio",
+                slot: true,
+                search: true,
+                type: "select",
+                width: 100,
+                align: "center",
+                dicData: [{
+                    label: "有",
+                    value: true
+                  },
+                  {
+                    label: "无",
+                    value: false
+                  }
+                ]
+              },
+            ]
+          }, {
+            label: '所属信息',
+            prop: 'group2',
+            column: [{
+                label: "所属园区",
+                prop: "agencyId",
+                type: "select",
+                search: true,
+                remote: true,
+                searchSpan: 4,
+                searchFilterable: true,
+                hide: true,
+                dataType: "string",
+                cascaderItem: ['residentialId'],
+                dicUrl: "/api/cyzh-community/agency/list?size=500&id={{key}}",
+                dicFormatter: (res) => {
+                  return res.data.records; //返回字典的层级结构
+                },
+                props: {
+                  label: "name",
+                  value: "id"
+                },
+                rules: [{
+                  required: false,
+                  message: "请选择所属区域",
+                  trigger: "change"
+                }],
+              },
+              {
+                label: "所属区域",
+                prop: "residentialId",
+                type: "select",
+                search: true,
+                searchSpan: 4,
+                searchFilterable: true,
+                hide: true,
+                cascaderItem: ['buildingId'],
+                dicUrl: "/api/cyzh-community/residential/list?size=500&agencyId={{key}}",
+                dicFormatter: (res) => {
+                  return res.data.records; //返回字典的层级结构
+                },
+                dateType: "string",
+                props: {
+                  label: "name",
+                  value: "id"
+                },
+                rules: [{
+                  required: true,
+                  message: "请选择所属区域",
+                  trigger: "change"
+                }],
+              },
+              {
+                label: "所属楼栋",
+                prop: "buildingId",
+                type: "select",
+                search: true,
+                searchSpan: 4,
+                searchFilterable: true,
+                hide: true,
+                cascaderItem: ['unitId'],
+                dicUrl: "/api/cyzh-community/building/list?size=500&residentialId={{key}}",
+                dicFormatter: (res) => {
+                  return res.data.records; //返回字典的层级结构
+                },
+                props: {
+                  label: "name",
+                  value: "id"
+                },
+                rules: [{
+                  required: false,
+                  message: "请选择所属楼栋",
+                  trigger: "change"
+                }],
+              },
+              {
+                label: "所属楼层",
+                prop: "floorId",
+                type: "select",
+                search: true,
+                searchFilterable: true,
+                hide: true,
+                searchSpan: 4,
+                dateType: "string",
+                dicUrl: "/api/cyzh-community/floor/list?size=500",
+                dicFormatter: (res) => {
+                  return res.data.records; //返回字典的层级结构
+                },
+                props: {
+                  label: "name",
+                  value: "id"
+                },
+                rules: [{
+                  required: false,
+                  message: "请选择所属楼层",
+                  trigger: "change"
+                }],
+              },
+            ]
+          }, {
+            label: '位置信息',
+            prop: 'group3',
+            column: [{
+                label: "经度",
+                prop: "longitude",
+                width: 100,
+                overHidden: true,
+                disabled: true,
+                hide: true,
+                rules: [{
+                  required: false,
+                  message: "请输入经度",
+                  trigger: "blur"
+                }]
+              },
+              {
+                label: "纬度",
+                prop: "latitude",
+                width: 100,
+                overHidden: true,
+                disabled: true,
+                hide: true,
+                rules: [{
+                  required: false,
+                  message: "请输入纬度",
+                  trigger: "blur"
+                }]
+              },
+              {
+                label: "安装地址",
+                prop: "address",
+                hide: true,
+                overHidden: true,
+                rules: [{
+                  required: false,
+                  message: "请输入具体地址",
+                  trigger: "blur"
+                }]
+              },
+            ]
+          }],
+
+        }
+      }
+    },
+    computed: {
+      title() {
+        if (this.isAdd) {
+          return '添加监控设备'
+        }
+        if (this.option.detail) {
+          return '监控设备详情'
+        } else {
+          return '编辑监控设备'
+        }
+      }
+    },
+    methods: {
+      showDialog(model, detail = true) {
+        this.isAdd = false
+        this.model = model
+        this.option.detail = detail
+        this.dialogShow = true
+      },
+      showAddForm(model) {
+        this.isAdd = true
+        this.dialogShow = true
+        this.option.detail = false
+        this.model = model
+      },
+      beforeClose(done) {
+        console.log("close");
+        this.$refs.avueForm.resetForm()
+        done()
+        this.$emit('closed')
+      },
+      async submit(form, done) {
+        let data = deepClone(form)
+        let res = await update(data)
+        done()
+        if (res.data.success) {
+          this.dialogShow = false;
+          this.$refs.avueForm.resetForm()
+          this.$message.success('操作成功')
+          this.$emit('reloadData', res.data.data)
+        } else {
+          this.$message.success('操作失败')
+        }
+
+      },
+    }
+  }
+</script>
+x

+ 0 - 9
src/components/map/demo.html

@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title></title>
-	</head>
-	<body>
-	</body>
-</html>

+ 0 - 572
src/components/map/divide - 副本.vue

@@ -1,572 +0,0 @@
-<template>
-  <div class="device-body" style="height:100%;">
-    <!-- 地图 -->
-    <div id="container" style="height:100%"></div>
-    <!-- 搜索框 -->
-    <div id="panel" style="display:flex;justify-content: center;align-items: center">
-      <div class="search">
-        <el-select @change="setSuggestion" :clearable="true" @clear="clear" v-model="value" style="width:100%"
-          filterable remote reserve-keyword placeholder="请输入地址关键词" :remote-method="getSuggestions" :loading="loading">
-          <el-option v-for="(item,index) in suggestionList" :key="index" :label="item.name" :value="item">
-            <span style="float: left">{{ item.name }}</span>
-            <el-tooltip class="item" effect="dark" :content="item.address" placement="top-start">
-              <span style="float: right; color: #8492a6; font-size: 13px;">{{textCut(item.address)}}</span>
-            </el-tooltip>
-          </el-option>
-        </el-select>
-      </div>
-
-      <div style="margin-left: 10px" v-if="!ismove">
-        <el-button @click="addDevice" icon="el-icon-plus" :type="isAdd?'primary':''" circle></el-button>
-      </div>
-
-
-      <div style="margin-left: 10px">
-        <el-button @click="operaMarkers" size="small" v-text="ismove?'保存':'移动设备位置'" :type="ismove?'primary':''"
-          :style="ismove?'border-radius:4px 0 0 4px':''"></el-button>
-        <el-button @click="cancelMove" size="small" v-if="ismove"
-          style="margin:0;border-radius:0 4px 4px 0;border:1px solid #62a5f6">取消</el-button>
-      </div>
-    </div>
-    <!-- 设备列表 -->
-    <device-list @click="clickDevice" ref="deviceList"></device-list>
-
-    <door-device-form ref="doorDeviceForm" @reloadData="reloadData"></door-device-form>
-  </div>
-</template>
-
-<script>
-
-</script>
-
-<script>
-  import {
-    deepClone
-  } from '@/util/util.js'
-  import doorDeviceForm from "./comps/door-device-form.vue"
-  import {
-    getDoorDeviceCoordinates
-  } from "@/api/device/doordevice.js"
-  import * as mapUtil from "./js/mapUtil.js"
-  import deviceList from "./comps/device-list.vue"
-  import {
-    updateBatch,
-    getList,
-    remove
-  } from "@/api/device/doordevice.js"
-  let _this = this
-  let TMap, map, markers, editor, geocoder;
-  let infoWindow; //窗口
-  export default {
-    components: {
-      deviceList,
-      doorDeviceForm
-    },
-    data() {
-      return {
-        markerGeometries: [],
-
-        ismove: false,
-        isAdd: false,
-        isEdit:false,
-
-
-        dialogVisible: false,
-        //标记坐标集合
-        coordinates: [],
-
-        //搜索
-        value: '',
-        suggestionList: [],
-        loading: false,
-      };
-    },
-    computed: {
-      textCut() {
-        return data => {
-          let len = 7
-          if (data.length >= len) {
-            data = data.substring(0, len) + "..."
-          }
-          return data
-        }
-      }
-    },
-    created() {
-      this.init()
-    },
-    methods: {
-      reloadData(data) {
-        //关闭添加
-        this.isAdd = false
-        //更新设备列表
-        this.$refs.deviceList.fetchDeviceList()
-        let position = markers.getGeometryById("add").position
-        //删除添加标记
-        markers.remove(["add"])
-        //添加新的标记
-        markers.add([{
-          id: data.id,
-          styleId: 'marker',
-          position,
-          content: data.name
-        }])
-      },
-      async init() {
-        _this = this
-        await this.getDoorDeviceCoordinates()
-        this.initMap()
-      },
-      addDevice() {
-        infoWindow.close();
-        this.ismove = false
-        this.isAdd = !this.isAdd
-        if (this.isAdd) {
-          let center = map.getCenter()
-          this.addMarkers('add', center)
-
-          this.$notify({
-            title: '提示',
-            type: 'success',
-            message: '已激活添加设备操作,请点击地图选点再添加设备',
-            duration: 6000
-          });
-
-        } else {
-          markers.remove(["add"])
-        }
-      },
-      async getSuggestions(name) {
-        let params = {
-          name
-        }
-        let res = await getList(1, 10, params)
-        let data = res.data.data
-        this.suggestionList = data.records
-        this.$refs.deviceList.initData(data)
-      },
-      clear() {
-        this.getSuggestions()
-      },
-      setSuggestion(item) {
-        //先关闭窗口
-        infoWindow.close();
-        //再打开窗口
-        this.openInfoWindow(item)
-      },
-      // animation:qq.maps.MarkerAnimation.DROP,
-      clickDevice(item) {
-        let flag = this.coordinates.some(line => line.id == item.id)
-        if (flag) {
-          map.setCenter(new TMap.LatLng(item.latitude, item.longitude))
-          //先关闭窗口
-          infoWindow.close();
-          //再打开窗口
-          this.openInfoWindow(item)
-          return
-        } else {
-          this.isEdit=true
-          //选取设备坐标
-          let id = item.id + 'add'
-          let position = map.getCenter()
-          let content = '选取设备坐标'
-          this.addMarkers(id, position, content)
-
-          this.$notify({
-            title: '提示',
-            type: 'success',
-            message: '请点击地图选取设备坐标',
-            duration: 6000
-          });
-        }
-      },
-      //获取设备坐标集合
-      async getDoorDeviceCoordinates() {
-        let res = await getDoorDeviceCoordinates()
-        this.coordinates = res.data.data
-      },
-      async initMap() {
-        let scripts = ['https://map.qq.com/api/gljs?libraries=service&v=1.exp',
-          'https://map.qq.com/api/js?v=2.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77',
-          'https://map.qq.com/api/gljs?libraries=tools&v=1.exp'
-        ]
-        TMap = await mapUtil.loadMap(scripts)
-        //创建地图
-        this.createMap()
-        //新建逆地址服务类
-        geocoder = new TMap.service.Geocoder();
-
-        //创建标点集合类
-        this.createMarkers()
-        //创建标点拖动类
-        this.markersDrag()
-        //设置中心位置
-        this.setCenter()
-
-
-      },
-      //逆地址
-      async getAddress(location) {
-        let address = (await geocoder.getAddress({
-          location
-        })).result.address
-        return address
-      },
-
-      /**
-       * 创建地图
-       */
-      createMap() {
-        let _this = this
-        //获取中心点
-        map = new TMap.Map('container', {
-          zoom: 19,
-          baseMap: {
-            type: 'vector',
-            features: ['base', 'building3d'], // 隐藏矢量文字
-          },
-        });
-        map.on("click", async (evt) => {
-          let lat = evt.latLng.getLat().toFixed(6);
-          let lng = evt.latLng.getLng().toFixed(6);
-          let model = {
-            latitude: lat,
-            longitude: lng,
-            address: ''
-          }
-          let position = new TMap.LatLng(lat, lng)
-
-          if (!this.isAdd && !this.isEdit) {
-            return
-          }
-          //逆地址解释
-          model.address = await this.getAddress(position)
-          if (_this.isAdd) {
-            this.showAddForm(model,position)
-            return
-          }
-          if (_this.isEdit) {
-            console.log("修改");
-          }
-
-        })
-      },
-      async showAddForm(model,position){
-        let id = 'add'
-        let geometries = deepClone(markers.geometries) || null
-        if (!geometries) {
-          _this.addMarkers(id, position)
-          _this.$refs.doorDeviceForm.showAddForm(model)
-          return
-        }
-        let flag = geometries.find(item => item.id == "add")
-        if (!flag) {
-          _this.addMarkers(id, position)
-          _this.$refs.doorDeviceForm.showAddForm(model)
-          return
-        }
-        markers.updateGeometries([{
-          id,
-          position,
-          styleId: 'addStyle',
-          content: '点击地图选点',
-        }])
-        _this.$refs.doorDeviceForm.showAddForm(model)
-      },
-      addMarkers(id, position, content = '点击地图选点') {
-        markers.add([{
-          id,
-          styleId: 'addStyle',
-          position,
-          content,
-        }])
-      },
-      //设置中心位置
-      setCenter() {
-        let arr = mapUtil.getPointsCenter(this.coordinates, "latitude", "longitude")
-        if (this.$isNotEmpty(arr) && this.$isNotEmpty(arr[0]) && this.$isNotEmpty(arr[1])) {
-          map.setCenter(new TMap.LatLng(arr[0], arr[1]));
-        } else {
-          //ip定位获取中心点
-          mapUtil.ipLocate(TMap, markers, map)
-        }
-      },
-      /**
-       * 创建区域
-       */
-      crearePolygon() {
-        let polygon = new TMap.MultiPolygon({
-          map,
-          geometries: [{
-            paths,
-          }]
-        });
-      },
-      /**
-       * 新建一个标点集合
-       */
-      createMarkers() {
-        //创建标点集合对象
-        markers = new TMap.MultiMarker({
-          id: 'marker-layer',
-          enableCollision: false,
-          map,
-          styles: {
-            'label': new TMap.LabelStyle({
-              'color': '#3777FF', //颜色属性
-              'size': 20, //文字大小属性
-              'offset': {
-                x: 0,
-                y: 0
-              }, //文字偏移属性单位为像素
-              'angle': 90, //文字旋转属性
-              'alignment': 'center', //文字水平对齐属性
-              'verticalAlignment': 'middle' //文字垂直对齐属性
-            })
-          },
-          styles: {
-            "marker": new TMap.MarkerStyle({
-              "width": 30,
-              "height": 30,
-              "anchor": {
-                x: 16,
-                y: 32
-              },
-              "src": '/img/device/door-device.png',
-              "color": '#333', // 标注点文本颜色
-              "size": 14, // 标注点文本文字大小
-              "direction": 'bottom', // 标注点文本文字相对于标注点图片的方位
-              "offset": {
-                x: 0,
-                y: 8
-              }, // 标注点文本文字基于direction方位的偏移属性
-              "strokeColor": '#fff', // 标注点文本描边颜色
-              "strokeWidth": 2, // 标注点文本描边宽度
-            }),
-            "addStyle": new TMap.MarkerStyle({
-              "width": 30,
-              "height": 30,
-              "anchor": {
-                x: 20,
-                y: 30
-              },
-              "src": '/img/icon/add_location.png',
-              "color": '#e54d42', // 标注点文本颜色
-              "size": 14, // 标注点文本文字大小
-              "direction": 'bottom', // 标注点文本文字相对于标注点图片的方位
-              "offset": {
-                x: 0,
-                y: 8
-              }, // 标注点文本文字基于direction方位的偏移属性
-              "strokeColor": '#fff', // 标注点文本描边颜色
-              "strokeWidth": 2, // 标注点文本描边宽度
-            }),
-          },
-          geometries: []
-        });
-        //更新标点坐标
-        if (this.$isEmpty(this.coordinates)) {
-          return
-        }
-        let geometries = []
-        this.coordinates.forEach((item) => {
-          let obj = {
-            "id": item.id,
-            "styleId": 'marker',
-            "content": item.name,
-            "position": new TMap.LatLng(item.latitude, item.longitude),
-            "properties": item,
-          }
-          geometries.push(obj)
-        })
-        markers.updateGeometries(geometries);
-        //点击标记弹出信息窗口
-        let position = new TMap.LatLng(this.coordinates[0].latitude, this.coordinates[0].longitude)
-        //初始化infoWindow
-        infoWindow = new TMap.InfoWindow({
-          map,
-          position,
-          offset: {
-            x: 0,
-            y: -32
-          } //设置信息窗相对position偏移像素
-        });
-        infoWindow.close(); //初始关闭信息窗关闭
-        //监听标注点击事件
-        markers.on("click", (evt) => {
-          let item = evt.geometry.properties
-          if (!this.ismove) {
-            this.openInfoWindow(item)
-          }
-        })
-      },
-      //开启标记拖动
-      markersDrag() {
-        // 初始化几何图形及编辑器
-        editor = new TMap.tools.GeometryEditor({
-          map, // 编辑器绑定的地图对象
-          overlayList: [{
-            overlay: markers, // 可编辑图层
-            id: "marker",
-            selectedStyleId: "addStyle" // 被选中的marker会变为高亮样式
-          }],
-          actionMode: TMap.tools.constants.EDITOR_ACTION.INTERACT, // 编辑器的工作模式
-          activeOverlayId: "marker", // 激活图层
-          selectable: false
-        });
-      },
-      openInfoWindow(data) {
-        //设置infoWindow
-        infoWindow.open(); //打开信息窗
-        infoWindow.setPosition(new TMap.LatLng(data.latitude, data.longitude)); //设置信息窗位置
-        let content = `<div>
-          <div style="color: #272727;font-size: 15px;font-weight: 500;display:flex;justify-content: flex-start">名称:${data.name}</div>
-          <div style="margin-top:6px;font-size: 13px;font-weight: 300;display:flex;justify-content: flex-start">地址:${data.address}</div>
-          <div style="display: flex;justify-content: flex-end;padding-top:8px;font-size:12px;cursor: pointer">
-            <span id="detail" style="color: #2979ff;margin-right: 6px;text-decoration: underline">详情</span>
-            <span id="edit" style="color: #2979ff;margin-right: 6px;text-decoration: underline">编辑</span>
-            <span id="del" style="color: #fa3534;text-decoration: underline" >删除</span>
-          </div>
-        </div>`
-        infoWindow.setContent(content); //设置信息窗内容
-        //详情
-        document.getElementById("detail").addEventListener("click", function() {
-          _this.detail(data)
-        });
-        document.getElementById("edit").addEventListener("click", function() {
-          _this.edit(data)
-        });
-        document.getElementById("del").addEventListener("click", function() {
-          _this.delDevice(data)
-        });
-      },
-      operaMarkers() {
-        if (this.ismove) {
-          this.save()
-        } else {
-          this.move()
-        }
-      },
-      cancelMove() {
-        markers.updateGeometries(this.markerGeometries)
-        this.ismove = false
-        editor.setSelectable(false)
-      },
-      move() {
-        //移动前先把旧的数据保存起来
-        this.markerGeometries = deepClone(markers.getGeometries())
-        console.log(this.markerGeometries, "oldMarkerGeometries");
-
-        this.$notify({
-          title: '提示',
-          type: 'success',
-          message: '已激活拖动操作,请点击所要移动的标记再拖动',
-          duration: 6000
-        });
-        infoWindow.close()
-        markers.remove(["add"])
-        this.isAdd = false
-        this.ismove = true
-        editor.setSelectable(true)
-      },
-      async save() {
-        this.ismove = false
-        editor.setSelectable(false)
-        let oldMarkers = this.markerGeometries
-        let newMarkers = markers.getGeometries()
-
-        let updateObj = []
-        oldMarkers.forEach((oldItem) => {
-          let id = oldItem.id
-          let newItem = newMarkers.find(line => line.id == id)
-
-          let oldLat = oldItem.position.lat.toFixed(6)
-          let newLat = newItem.position.lat.toFixed(6)
-
-          let oldLng = oldItem.position.lng.toFixed(6)
-          let newLng = newItem.position.lng.toFixed(6)
-
-          if (oldLat != newLat || oldLng != newLng) {
-            let model = newItem.properties
-            model.latitude = newLat
-            model.longitude = newLng
-            updateObj.push(model)
-          }
-        })
-        console.log(updateObj, "updateObj");
-        if (this.$isNotEmpty(updateObj)) {
-          let res = await updateBatch(updateObj)
-          if (res.data.success) {
-            this.$message.success('操作成功')
-          }
-        }
-      },
-      detail(data) {
-        infoWindow.close();
-        _this.$refs.doorDeviceForm.showDialog(data)
-      },
-      edit(data) {
-        infoWindow.close();
-        _this.$refs.doorDeviceForm.showDialog(data, false)
-      },
-      delDevice(data) {
-        //先关闭窗口
-        infoWindow.close();
-        this.$confirm("确定删除该设备?", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
-            type: "warning"
-          })
-          .then(() => {
-            return remove(data.id);
-          })
-          .then(() => {
-            //更新设备列表
-            this.$refs.deviceList.fetchDeviceList()
-            //删除标记
-            markers.remove([data.id])
-            this.message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-
-    }
-  };
-</script>
-
-
-<style scoped lang="scss">
-  .device-body {
-    height: 100%;
-    margin: 0px;
-    padding: 0px;
-  }
-
-  #container {
-    width: 78%;
-    height: 100%;
-  }
-
-  /* 搜索框 */
-  #panel {
-    display: flex;
-    position: absolute;
-    z-index: 9999;
-    top: 30px;
-    left: 30px;
-  }
-
-
-
-  .search {
-    display: flex;
-    width: 280px;
-  }
-
-  /* 编辑器 */
-  #toolControl {
-    display: flex
-  }
-</style>

+ 214 - 69
src/components/map/divide.vue

@@ -3,10 +3,11 @@
     <!-- 地图 -->
     <div id="container" style="height:100%"></div>
     <!-- 搜索框 -->
-    <div id="panel" style="display:flex;justify-content: center;align-items: center">
+    <div id="panel" style="display:flex;justify-content: center;align-items: center;">
+
       <div class="search">
         <el-select @change="setSuggestion" :clearable="true" @clear="clear" v-model="value" style="width:100%"
-          filterable remote reserve-keyword placeholder="请输入地址关键词" :remote-method="getSuggestions" :loading="loading">
+          filterable remote reserve-keyword placeholder="请输入设备名称关键词" :remote-method="getSuggestions" :loading="loading">
           <el-option v-for="(item,index) in suggestionList" :key="index" :label="item.name" :value="item">
             <span style="float: left">{{ item.name }}</span>
             <el-tooltip class="item" effect="dark" :content="item.address" placement="top-start">
@@ -16,22 +17,31 @@
         </el-select>
       </div>
 
-      <div style="margin-left: 10px" v-if="operaType!=3">
-        <el-button @click="addDevice" icon="el-icon-plus" :type="operaType==1?'primary':''" circle></el-button>
+      <div style="margin-left: 10px;display:flex" v-show="operaType!=3">
+        <el-button @click="addDevice" size="small" type="primary" v-text="operaType==1?'取消添加':'添加设备'"
+          style="border-radius:4px 0 0 4px;margin-right:-2px;height:36px;padding:10px"></el-button>
+        <el-button @click="move" size="small"
+          style="margin:0;border-radius:0 4px 4px 0;margin-left:-2px;height:36px;padding:10px;border:1px solid #3b8ff4;color:#3b8ff4">
+          移动设备
+        </el-button>
       </div>
 
-
-      <div style="margin-left: 10px">
-        <el-button @click="operaMarkers" size="small" v-text="operaType==3?'保存':'移动设备位置'"
-          :type="operaType==3?'primary':''" :style="operaType==3?'border-radius:4px 0 0 4px':''"></el-button>
-        <el-button @click="cancelMove" size="small" v-if="operaType==3"
-          style="margin:0;border-radius:0 4px 4px 0;border:1px solid #62a5f6">取消</el-button>
+      <div style="margin-left: 10px;display:flex" v-show="operaType==3">
+        <el-button @click="save" size="small" type="primary" style="border-radius:4px 0 0 4px;height:34px">保存
+        </el-button>
+        <el-button @click="cancelMove" size="small"
+          style="margin:0;border-radius:0 4px 4px 0;height:34px;border:1px solid #3b8ff4;color:#3b8ff4">取消
+        </el-button>
       </div>
+
+
     </div>
     <!-- 设备列表 -->
-    <device-list @click="clickDevice" ref="deviceList"></device-list>
+    <device-list @select="selectDevice" @dropdownClick="dropdownClick" @click="clickDevice" ref="deviceList">
+    </device-list>
 
     <door-device-form ref="doorDeviceForm" @reloadData="reloadData"></door-device-form>
+    <video-device-form ref="videoDeviceForm" @reloadData="reloadData"></video-device-form>
   </div>
 </template>
 
@@ -40,35 +50,53 @@
 </script>
 
 <script>
+  //设备列表
+  import deviceList from "./comps/device-list.vue"
+  // 门禁
   import {
-    deepClone
-  } from '@/util/util.js'
+    getDoorDeviceCoordinates,
+    edit as editDoordevice,
+    updateBatch as updateDoordeviceBatch,
+    getList as getDoordeviceList,
+    remove as removeDoordevice
+  } from "@/api/device/doordevice.js"
   import doorDeviceForm from "./comps/door-device-form.vue"
+  //监控
   import {
-    getDoorDeviceCoordinates
-  } from "@/api/device/doordevice.js"
-  import * as mapUtil from "./js/mapUtil.js"
-  import deviceList from "./comps/device-list.vue"
+    getVideoDeviceCoordinates,
+    edit as editGbdevicechannel,
+    updateBatch as updateGbdevicechannelBatch,
+    getList as getGbdevicechannelList,
+    remove as removeGbdevicechannel
+  } from "@/api/device/gb/gbdevicechannel.js"
+  import videoDeviceForm from "./comps/video-device-form.vue"
+  //地图
   import {
-    edit,
-    updateBatch,
-    getList,
-    remove
-  } from "@/api/device/doordevice.js"
+    deepClone
+  } from '@/util/util.js'
+  import * as mapUtil from "./js/mapUtil.js"
+
   let _this = this
   let TMap, map, markers, editor, geocoder;
   let infoWindow; //窗口
   export default {
     components: {
       deviceList,
-      doorDeviceForm
+      doorDeviceForm,
+      videoDeviceForm
     },
     data() {
       return {
+        //0:门禁设备 1:监控设备
+        refName: 'doorDeviceForm',
+        activeIndex: 0,
+
         markerGeometries: [],
 
         //0无操作,1添加操作,2修改操作,3移动操作
         operaType: 0,
+        //监控设备不需要添加操作
+        needAdd: true,
         operaEditItem: '',
 
         dialogVisible: false,
@@ -114,11 +142,12 @@
       },
       async init() {
         _this = this
-        await this.getDoorDeviceCoordinates()
+        await this.getDeviceCoordinates()
         this.initMap()
       },
       addDevice() {
         infoWindow.close();
+        this.removeEditRemark()
         if (this.operaType == 1) {
           this.operaType = 0
         } else {
@@ -157,28 +186,60 @@
         //再打开窗口
         this.openInfoWindow(item)
       },
-      // animation:qq.maps.MarkerAnimation.DROP,
+      //组件事件
+      async selectDevice(index) {
+        this.needAdd = true
+        this.activeIndex = index
+        //重新获取坐标集合
+        await this.getDeviceCoordinates()
+        //重新更新坐标集合
+        if (index == 0) {
+          this.refName = 'doorDeviceForm'
+          this.updateGeometries()
+        } else if (index == 1) {
+          this.needAdd = false
+          this.refName = 'videoDeviceForm'
+          this.updateGeometries('videoDevice')
+        }
+      },
+      /**
+       * 移除编辑中的点
+       */
+      removeEditRemark() {
+        let geometries = deepClone(markers.geometries) || null
+        if (geometries) {
+          let editItem = geometries.find(item => item.id.indexOf('edit') >= 0)
+          if (editItem) {
+            markers.remove([editItem.id])
+          }
+        }
+      },
       clickDevice(item) {
+        //先关闭窗口
+        infoWindow.close();
         let flag = this.coordinates.some(line => line.id == item.id)
         if (flag) {
+          this.operaType = 0
+          //移除编辑中的点
+          this.removeEditRemark()
           map.setCenter(new TMap.LatLng(item.latitude, item.longitude))
-          //先关闭窗口
-          infoWindow.close();
           //再打开窗口
           this.openInfoWindow(item)
           return
         }
         this.operaType = 2
-        //选取设备坐标
+        //点击的id
         let id = item.id + 'edit'
-        //获取所有的标记点,如果存在编辑中的标记,先移除再添加
-        let geometries = deepClone(markers.geometries) || null
-        if (geometries) {
-          let editItem = geometries.find(item => item.id.indexOf('edit') >= 0)
-          if (editItem) {
-            markers.remove([editItem.id])
-          }
+
+        //重复点击相同的设备,则取消操作
+        let activeMarkers = markers.getGeometryById(id)
+        if (this.$isNotEmpty(activeMarkers)) {
+          this.operaType = 0
+          this.removeEditRemark()
+          return
         }
+        //获取所有的标记点,如果存在编辑中的标记,先移除再添加
+        this.removeEditRemark()
         this.operaEditItem = item
         let position = map.getCenter()
         this.addMarkers(id, position, this.operaEditItem.name)
@@ -189,12 +250,16 @@
           message: '请点击地图选取设备坐标',
           duration: 6000
         });
-
       },
       //获取设备坐标集合
-      async getDoorDeviceCoordinates() {
-        let res = await getDoorDeviceCoordinates()
-        this.coordinates = res.data.data
+      async getDeviceCoordinates() {
+        console.log("123");
+        this.coordinates = []
+        if (this.activeIndex == 0) {
+          this.coordinates = (await getDoorDeviceCoordinates()).data.data
+        } else if (this.activeIndex == 1) {
+          this.coordinates = (await getVideoDeviceCoordinates()).data.data
+        }
       },
       async initMap() {
         let scripts = ['https://map.qq.com/api/gljs?libraries=service&v=1.exp',
@@ -262,22 +327,31 @@
 
         })
       },
-      confirmEdit() {
+      async confirmEdit() {
         //旧的标记会带有edit字符,保存成功后需要移除edit字符
         let id = this.operaEditItem.id + 'edit'
         let old = markers.getGeometryById(id)
         let model = {
           id: this.operaEditItem.id,
           latitude: old.position.lat,
-          longitude: old.position.lng
+          longitude: old.position.lng,
         }
-        this.$confirm(`确定选取该坐标作为设备【${this.operaEditItem.name}】的坐标?`, {
+        let position = new TMap.LatLng(old.position.lat, old.position.lng)
+        model.address = await this.getAddress(position)
+
+        this.$confirm(`确定选取【${model.address}】作为设备【${this.operaEditItem.name}】的坐标?`, {
             confirmButtonText: "确定",
             cancelButtonText: "取消",
             type: "success"
           })
           .then(() => {
-            return edit(model);
+            let flag = false
+            if (this.activeIndex == 0) {
+              flag = editDoordevice(model)
+            } else if (this.activeIndex == 1) {
+              flag = editGbdevicechannel(model)
+            }
+            return flag;
           })
           .then(() => {
             this.$refs.deviceList.fetchDeviceList()
@@ -315,14 +389,14 @@
         let id = 'add'
         let geometries = deepClone(markers.geometries) || null
         if (!geometries) {
-          _this.addMarkers(id, position)
-          _this.$refs.doorDeviceForm.showAddForm(model)
+          this.addMarkers(id, position)
+          this.$refs[this.refName].showAddForm(model)
           return
         }
         let flag = geometries.find(item => item.id == "add")
         if (!flag) {
           _this.addMarkers(id, position)
-          _this.$refs.doorDeviceForm.showAddForm(model)
+          this.$refs[this.refName].showAddForm(model)
           return
         }
         markers.updateGeometries([{
@@ -331,7 +405,7 @@
           styleId: 'addStyle',
           content: '点击地图选点',
         }])
-        _this.$refs.doorDeviceForm.showAddForm(model)
+        this.$refs[this.refName].showAddForm(model)
       },
       addMarkers(id, position, content = '点击地图选点', styleId = 'addStyle') {
         markers.add([{
@@ -403,6 +477,24 @@
               "strokeColor": '#fff', // 标注点文本描边颜色
               "strokeWidth": 2, // 标注点文本描边宽度
             }),
+            "videoDevice": new TMap.MarkerStyle({
+              "width": 30,
+              "height": 30,
+              "anchor": {
+                x: 16,
+                y: 36
+              },
+              "src": '/img/icon/video-device4.png',
+              "color": '#333', // 标注点文本颜色
+              "size": 14, // 标注点文本文字大小
+              "direction": 'bottom', // 标注点文本文字相对于标注点图片的方位
+              "offset": {
+                x: 0,
+                y: 2
+              }, // 标注点文本文字基于direction方位的偏移属性
+              "strokeColor": '#fff', // 标注点文本描边颜色
+              "strokeWidth": 2, // 标注点文本描边宽度
+            }),
             "addStyle": new TMap.MarkerStyle({
               "width": 30,
               "height": 30,
@@ -424,22 +516,29 @@
           },
           geometries: []
         });
+        this.updateGeometries()
+      },
+      /**
+       * 更新标记集合
+       */
+      updateGeometries(styleId = 'marker') {
         //更新标点坐标
         if (this.$isEmpty(this.coordinates)) {
+          markers.setGeometries([])
           return
         }
         let geometries = []
         this.coordinates.forEach((item) => {
           let obj = {
-            "id": item.id,
-            "styleId": 'marker',
-            "content": item.name,
-            "position": new TMap.LatLng(item.latitude, item.longitude),
-            "properties": item,
+            id: item.id,
+            styleId,
+            content: item.name,
+            position: new TMap.LatLng(item.latitude, item.longitude),
+            properties: item,
           }
           geometries.push(obj)
         })
-        markers.updateGeometries(geometries);
+        markers.setGeometries(geometries);
         //点击标记弹出信息窗口
         let position = new TMap.LatLng(this.coordinates[0].latitude, this.coordinates[0].longitude)
         //初始化infoWindow
@@ -461,6 +560,7 @@
           }
         })
       },
+
       //开启标记拖动
       markersDrag() {
         // 初始化几何图形及编辑器
@@ -501,19 +601,13 @@
           _this.delDevice(data)
         });
       },
-      operaMarkers() {
-        if (this.operaType == 3) {
-          this.save()
-        } else {
-          this.move()
-        }
-      },
       cancelMove() {
         markers.updateGeometries(this.markerGeometries)
         this.operaType = 0
         editor.setSelectable(false)
       },
       move() {
+        this.removeEditRemark()
         //移动前先把旧的数据保存起来
         this.markerGeometries = deepClone(markers.getGeometries())
         console.log(this.markerGeometries, "oldMarkerGeometries");
@@ -527,9 +621,11 @@
         infoWindow.close()
         markers.remove(["add"])
         this.operaType = 3
+        console.log(this.operaType);
         editor.setSelectable(true)
       },
       async save() {
+        this.removeEditRemark()
         this.operaType = 0
         editor.setSelectable(false)
         let oldMarkers = this.markerGeometries
@@ -553,21 +649,28 @@
             updateObj.push(model)
           }
         })
-        console.log(updateObj, "updateObj");
-        if (this.$isNotEmpty(updateObj)) {
-          let res = await updateBatch(updateObj)
-          if (res.data.success) {
-            this.$message.success('操作成功')
-          }
+        if (this.$isEmpty(updateObj)) {
+          return
+        }
+        let flag = false
+        if (this.activeIndex == 0) {
+          flag = (await updateDoordeviceBatch(updateObj)).data.success
+        } else if (this.activeIndex == 1) {
+          flag = (await updateGbdevicechannelBatch(updateObj)).data.success
+        }
+        if (flag) {
+          this.$message.success('操作成功')
+        } else {
+          this.$message.error('操作失败')
         }
       },
       detail(data) {
         infoWindow.close();
-        _this.$refs.doorDeviceForm.showDialog(data)
+        _this.$refs[this.refName].showDialog(data)
       },
       edit(data) {
         infoWindow.close();
-        _this.$refs.doorDeviceForm.showDialog(data, false)
+        _this.$refs[this.refName].showDialog(data, false)
       },
       delDevice(data) {
         //先关闭窗口
@@ -578,7 +681,13 @@
             type: "warning"
           })
           .then(() => {
-            return remove(data.id);
+            let flag = false
+            if (this.activeIndex == 0) {
+              flag = removeDoordevice(data.id)
+            } else if (this.activeIndex == 1) {
+              flag = removeGbdevicechannel(data.id)
+            }
+            return flag;
           })
           .then(() => {
             //更新设备列表
@@ -592,12 +701,48 @@
           });
       },
 
+      dropdownClick(evt) {
+        let name = evt.name
+        let data = evt.data
+        switch (name) {
+          case '详情':
+            this.detail(data)
+            break;
+          case '编辑':
+            this.edit(data)
+            break;
+          case '删除':
+            this.delDevice(data)
+            break;
+          default:
+            break;
+        }
+      }
+
     }
   };
 </script>
 
 
 <style scoped lang="scss">
+  /deep/ .el-input__inner {
+    -webkit-appearance: none;
+    background-color: #fff;
+    background-image: none;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    color: #606266;
+    display: inline-block;
+    font-size: inherit;
+    height: 38px;
+    line-height: 38px;
+    outline: 0;
+    padding: 0 15px;
+    -webkit-transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+    transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+    width: 100%;
+  }
+
   .device-body {
     height: 100%;
     margin: 0px;