|  |  | 
 |  |  | <template> | 
 |  |  |     <div id="devicePosition" style="height: 100%"> | 
 |  |  |         <el-container style="height: 100%"> | 
 |  |  |             <el-header> | 
 |  |  |                 <uiHeader></uiHeader> | 
 |  |  |             </el-header> | 
 |  |  |             <el-main> | 
 |  |  |                 <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | 
 |  |  |                     <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | 
 |  |  |                 </div> | 
 |  |  |                 <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> | 
 |  |  |                     <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> | 
 |  |  |                     <!-- <span class="demonstration">从</span> --> | 
 |  |  |                     <el-date-picker v-model="searchFrom" type="datetime" placeholder="选择开始日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | 
 |  |  |                     <el-date-picker v-model="searchTo" type="datetime" placeholder="选择结束日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | 
 |  |  |                     <el-button-group> | 
 |  |  |                         <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> | 
 |  |  |                         <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> | 
 |  |  |                     </el-button-group> | 
 |  |  |                     <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> | 
 |  |  |                     <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> | 
 |  |  |                     <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> | 
 |  |  |                     <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> | 
 |  |  |                     <el-button-group> | 
 |  |  |                         <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> | 
 |  |  |                         <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> | 
 |  |  |                     </el-button-group> | 
 |  |  |                     <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> | 
 |  |  |                 </div> | 
 |  |  |                 <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> | 
 |  |  |                     <div class="baidumap" id="allmap"></div> | 
 |  |  |                 </div> | 
 |  |  |             </el-main> | 
 |  |  |         </el-container> | 
 |  |  |     <div id="devicePosition" style="width: 100vw; height: 91vh;"> | 
 |  |  |       <el-container v-if="onOff" style="height: 91vh;" v-loading="isLoging"> | 
 |  |  |         <el-aside width="auto" style="background-color: #ffffff"> | 
 |  |  |           <DeviceTree ref="deviceTree" :clickEvent="clickEvent" :contextMenuEvent="contextmenuEventHandler" ></DeviceTree> | 
 |  |  |         </el-aside> | 
 |  |  |         <el-main style="height: 91vh; padding: 0"> | 
 |  |  |           <MapComponent ref="map"></MapComponent> | 
 |  |  |         </el-main> | 
 |  |  |       </el-container> | 
 |  |  |       <div v-if="!onOff" style="width: 100%; height:100%; text-align: center; line-height: 5rem"> | 
 |  |  |         <p>地图功能已关闭</p> | 
 |  |  |       </div> | 
 |  |  |       <div ref="infobox" v-if="channel != null " > | 
 |  |  |         <div v-if="channel != null" class="infobox-content"> | 
 |  |  |           <el-descriptions class="margin-top" :title="channel.name" :column="1" :colon="true" size="mini" :labelStyle="labelStyle" > | 
 |  |  |             <el-descriptions-item label="生产厂商">{{channel.manufacture}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="型号">{{channel.model}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="设备归属" >{{channel.owner}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="行政区域" >{{channel.civilCode}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="安装地址" >{{channel.address == null?'未知': channel.address}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="云台类型" >{{channel.ptztypeText}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="经纬度" >{{channel.longitude}},{{channel.latitude}}</el-descriptions-item> | 
 |  |  |             <el-descriptions-item label="状态"> | 
 |  |  |               <el-tag size="small" v-if="channel.status === 1">在线</el-tag> | 
 |  |  |               <el-tag size="small" type="info" v-if="channel.status === 0">离线</el-tag> | 
 |  |  |             </el-descriptions-item> | 
 |  |  |           </el-descriptions> | 
 |  |  |           <div style="padding-top: 10px"> | 
 |  |  |             <el-button type="primary" size="small" title="播放" icon="el-icon-video-play" @click="play(channel)"></el-button> | 
 |  |  |             <el-button type="primary" size="small" title="编辑位置" icon="el-icon-edit" @click="edit(channel)"></el-button> | 
 |  |  |             <el-button type="primary" size="small" title="轨迹查询" icon="el-icon-map-location" @click="getTrace(channel)"></el-button> | 
 |  |  |           </div> | 
 |  |  |           <span class="infobox-close el-icon-close" @click="closeInfoBox()"></span> | 
 |  |  |         </div> | 
 |  |  |       </div> | 
 |  |  |       <devicePlayer ref="devicePlayer" ></devicePlayer> | 
 |  |  |       <queryTrace ref="queryTrace" ></queryTrace> | 
 |  |  |     </div> | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | <script> | 
 |  |  | import uiHeader from "./UiHeader.vue"; | 
 |  |  | import moment from "moment"; | 
 |  |  | import geoTools from "./GeoConvertTools.js"; | 
 |  |  | import MapComponent from "./common/MapComponent.vue"; | 
 |  |  | import DeviceService from "./service/DeviceService"; | 
 |  |  | import DeviceTree from "./common/DeviceTree"; | 
 |  |  | import channelMapInfobox from "./dialog/channelMapInfobox"; | 
 |  |  | import devicePlayer from './dialog/devicePlayer.vue' | 
 |  |  | import queryTrace from './dialog/queryTrace.vue' | 
 |  |  |  | 
 |  |  | export default { | 
 |  |  |     name: "devicePosition", | 
 |  |  |     components: { | 
 |  |  |         uiHeader, | 
 |  |  |     }, | 
 |  |  |     data() { | 
 |  |  |         return { | 
 |  |  |             pickerOptions: { | 
 |  |  |                 shortcuts: [{ | 
 |  |  |                     text: '今天', | 
 |  |  |                     onClick(picker) { | 
 |  |  |                         picker.$emit('pick', new Date()); | 
 |  |  |                     } | 
 |  |  |                 }, { | 
 |  |  |                     text: '昨天', | 
 |  |  |                     onClick(picker) { | 
 |  |  |                         const date = new Date(); | 
 |  |  |                         date.setTime(date.getTime() - 3600 * 1000 * 24); | 
 |  |  |                         picker.$emit('pick', date); | 
 |  |  |                     } | 
 |  |  |                 }, { | 
 |  |  |                     text: '一周前', | 
 |  |  |                     onClick(picker) { | 
 |  |  |                         const date = new Date(); | 
 |  |  |                         date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); | 
 |  |  |                         picker.$emit('pick', date); | 
 |  |  |                     } | 
 |  |  |                 }] | 
 |  |  |   name: "devicePosition", | 
 |  |  |   components: { | 
 |  |  |     MapComponent, | 
 |  |  |     DeviceTree, | 
 |  |  |     channelMapInfobox, | 
 |  |  |     devicePlayer, | 
 |  |  |     queryTrace, | 
 |  |  |   }, | 
 |  |  |   data() { | 
 |  |  |     return { | 
 |  |  |       onOff: typeof window.mapParam !== "undefined", | 
 |  |  |       deviceService: new DeviceService(), | 
 |  |  |       layer: null, | 
 |  |  |       lineLayer: null, | 
 |  |  |       channel: null, | 
 |  |  |       infoBoxId: null, | 
 |  |  |       labelStyle: { | 
 |  |  |         width: "56px" | 
 |  |  |       }, | 
 |  |  |       isLoging: false, | 
 |  |  |     }; | 
 |  |  |   }, | 
 |  |  |   created() { | 
 |  |  |     if (this.$route.query.deviceId) { | 
 |  |  |       console.log(this.$route.query.deviceId) | 
 |  |  |       // this.$refs.deviceTree.openByDeivceId(this.$route.query.deivceId) | 
 |  |  |       setTimeout(()=>{ // 延迟以等待地图加载完成 TODO 后续修改为通过是实际这;状态加回调完成 | 
 |  |  |         this.deviceService.getAllChannel(false, this.$route.query.deviceId, this.channelsHandler) | 
 |  |  |       }, 1000) | 
 |  |  |  | 
 |  |  |     } | 
 |  |  |   }, | 
 |  |  |   destroyed() { | 
 |  |  |  | 
 |  |  |   }, | 
 |  |  |   methods: { | 
 |  |  |     clickEvent: function (data) { | 
 |  |  |       if (data.channelId && data.subCount == 0) { | 
 |  |  |         // 点击通道 | 
 |  |  |         if (data.longitude * data.latitude === 0) { | 
 |  |  |           this.$message.error('未获取到位置信息'); | 
 |  |  |         } else { | 
 |  |  |           if (this.layer != null) { | 
 |  |  |             this.$refs.map.removeLayer(this.layer); | 
 |  |  |           } | 
 |  |  |           this.closeInfoBox() | 
 |  |  |           this.layer = this.$refs.map.addLayer([{ | 
 |  |  |             position: [data.longitude, data.latitude], | 
 |  |  |             image: { | 
 |  |  |               src: this.getImageByChannel(data), | 
 |  |  |               anchor: [0.5, 1] | 
 |  |  |             }, | 
 |  |  |             deviceId: this.$route.params.deviceId, | 
 |  |  |             showHistoryPosition: false, //显示历史轨迹 | 
 |  |  |             startTime: null, | 
 |  |  |             endTime: null, | 
 |  |  |             searchFrom: null, | 
 |  |  |             searchTo: null, | 
 |  |  |             expired: 600, | 
 |  |  |             interval: 5, | 
 |  |  |             mobilePositionList: [], | 
 |  |  |             mapPointList: [], | 
 |  |  |             parentChannelId: this.$route.params.parentChannelId, | 
 |  |  |             updateLooper: 0, //数据刷新轮训标志 | 
 |  |  |             total: 0, | 
 |  |  |             beforeUrl: "/deviceList", | 
 |  |  |             isLoging: false, | 
 |  |  |             autoList: false, | 
 |  |  |         }; | 
 |  |  |     }, | 
 |  |  |     mounted() { | 
 |  |  |         this.initData(); | 
 |  |  |         this.initBaiduMap(); | 
 |  |  |         if (this.autoList) { | 
 |  |  |             this.updateLooper = setInterval(this.initData, 5000); | 
 |  |  |             data: data | 
 |  |  |           }], this.featureClickEvent) | 
 |  |  |           this.$refs.map.panTo([data.longitude, data.latitude], mapParam.maxZoom) | 
 |  |  |         } | 
 |  |  |       } | 
 |  |  |     }, | 
 |  |  |     destroyed() { | 
 |  |  |         // this.$destroy("videojs"); | 
 |  |  |         clearTimeout(this.updateLooper); | 
 |  |  |     contextmenuEventHandler: function (event, data) { | 
 |  |  |       if (data.channelId && data.subCount == 0) { | 
 |  |  |         // 点击通道 | 
 |  |  |         this.$contextmenu({ | 
 |  |  |           items: [ | 
 |  |  |             { | 
 |  |  |               label: "播放", | 
 |  |  |               icon: "el-icon-video-play", | 
 |  |  |               disabled: false, | 
 |  |  |               onClick: () => { | 
 |  |  |                 this.play(data); | 
 |  |  |               } | 
 |  |  |             }, | 
 |  |  |             { | 
 |  |  |               label: "编辑位置", | 
 |  |  |               icon: "el-icon-edit", | 
 |  |  |               disabled: false, | 
 |  |  |               onClick: () => { | 
 |  |  |                 this.edit(data) | 
 |  |  |               } | 
 |  |  |             }, | 
 |  |  |             { | 
 |  |  |               label: "轨迹查询", | 
 |  |  |               icon: "el-icon-map-location", | 
 |  |  |               disabled: false, | 
 |  |  |               onClick: () => { | 
 |  |  |                 this.getTrace(data) | 
 |  |  |               } | 
 |  |  |             } | 
 |  |  |           ], | 
 |  |  |           event, // 鼠标事件信息 | 
 |  |  |           customClass: "custom-class", // 自定义菜单 class | 
 |  |  |           zIndex: 3000, // 菜单样式 z-index | 
 |  |  |         }); | 
 |  |  |       } else { | 
 |  |  |         this.deviceOrSubChannelMenu(event, data) | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |     }, | 
 |  |  |     methods: { | 
 |  |  |         initData: function () { | 
 |  |  |             // if (this.parentChannelId == "" || this.parentChannelId == 0) { | 
 |  |  |             //     this.getDeviceChannelList(); | 
 |  |  |             // } else { | 
 |  |  |             //     this.showSubchannels(); | 
 |  |  |             // } | 
 |  |  |         }, | 
 |  |  |         initParam: function () { | 
 |  |  |             // this.deviceId = this.$route.params.deviceId; | 
 |  |  |             // this.parentChannelId = this.$route.params.parentChannelId; | 
 |  |  |             // this.currentPage = parseInt(this.$route.params.page); | 
 |  |  |             // this.count = parseInt(this.$route.params.count); | 
 |  |  |             // if (this.parentChannelId == "" || this.parentChannelId == 0) { | 
 |  |  |             //     this.beforeUrl = "/deviceList"; | 
 |  |  |             // } | 
 |  |  |         }, | 
 |  |  |         initBaiduMap() { | 
 |  |  |             this.map = new BMap.Map("allmap"); // 创建地图实例 | 
 |  |  |             let points = []; | 
 |  |  |             let point = new BMap.Point(116.231398, 39.567445); // 创建点坐标 | 
 |  |  |             this.map.centerAndZoom(point, 5); // 初始化地图,设置中心点坐标和地图级别 | 
 |  |  |             this.map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 | 
 |  |  |             this.map.addControl(new BMap.NavigationControl()); | 
 |  |  |             this.map.addControl(new BMap.ScaleControl()); | 
 |  |  |             this.map.addControl(new BMap.OverviewMapControl()); | 
 |  |  |             this.map.addControl(new BMap.MapTypeControl()); | 
 |  |  |             //map.setMapStyle({ style: 'midnight' }) //地图风格 | 
 |  |  |         }, | 
 |  |  |         currentChange: function (val) { | 
 |  |  |             // var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`; | 
 |  |  |             // console.log(url); | 
 |  |  |             // this.$router.push(url).then(() => { | 
 |  |  |             //     this.initParam(); | 
 |  |  |             //     this.initData(); | 
 |  |  |             // }); | 
 |  |  |         }, | 
 |  |  |         handleSizeChange: function (val) { | 
 |  |  |             // var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`; | 
 |  |  |             // this.$router.push(url).then(() => { | 
 |  |  |             //     this.initParam(); | 
 |  |  |             //     this.initData(); | 
 |  |  |             // }); | 
 |  |  |         }, | 
 |  |  |         showDevice: function () { | 
 |  |  |             this.$router.push(this.beforeUrl).then(() => { | 
 |  |  |                 this.initParam(); | 
 |  |  |                 this.initData(); | 
 |  |  |             }); | 
 |  |  |         }, | 
 |  |  |         autoListChange: function () { | 
 |  |  |             if (this.autoList) { | 
 |  |  |                 this.updateLooper = setInterval(this.initData, 1500); | 
 |  |  |             } else { | 
 |  |  |                 window.clearInterval(this.updateLooper); | 
 |  |  |     deviceOrSubChannelMenu: function (event, data) { | 
 |  |  |       // 点击设备 | 
 |  |  |       this.$contextmenu({ | 
 |  |  |         items: [ | 
 |  |  |           { | 
 |  |  |             label: "定位", | 
 |  |  |             icon: "el-icon-s-promotion", | 
 |  |  |             disabled: false, | 
 |  |  |             onClick: () => { | 
 |  |  |               if (!data.channelId) { | 
 |  |  |                 this.deviceService.getAllChannel(false, data.deviceId, this.channelsHandler) | 
 |  |  |               } | 
 |  |  |               if (data.channelId && data.subCount > 0) { | 
 |  |  |                 // 点击子目录 | 
 |  |  |                 this.deviceService.getAllSubChannel(false, data.deviceId, data.channelId, this.channelsHandler) | 
 |  |  |               } | 
 |  |  |             } | 
 |  |  |         }, | 
 |  |  |         showHistoryPath: function () { | 
 |  |  |             this.map.clearOverlays(); | 
 |  |  |             this.mapPointList = []; | 
 |  |  |             this.mobilePositionList = []; | 
 |  |  |             if (!!this.searchFrom) { | 
 |  |  |                 this.startTime = this.toGBString(this.searchFrom); | 
 |  |  |                 console.log(this.startTime); | 
 |  |  |             } else{ | 
 |  |  |                 this.startTime = null; | 
 |  |  |             } | 
 |  |  |             if (!!this.searchTo) { | 
 |  |  |                 this.endTime = this.toGBString(this.searchTo); | 
 |  |  |                 console.log(this.endTime); | 
 |  |  |             } else { | 
 |  |  |                 this.endTime = null; | 
 |  |  |             } | 
 |  |  |             let self = this; | 
 |  |  |             this.$axios.get(`/api/positions/${this.deviceId}/history`, { | 
 |  |  |                 params: { | 
 |  |  |                     start: self.startTime, | 
 |  |  |                     end: self.endTime, | 
 |  |  |                 }, | 
 |  |  |             }) | 
 |  |  |             .then(function (res) { | 
 |  |  |                 self.total = res.data.length; | 
 |  |  |                 self.mobilePositionList = res.data; | 
 |  |  |                 console.log(self.mobilePositionList); | 
 |  |  |                 if (self.total == 0) { | 
 |  |  |                     self.$message({ | 
 |  |  |                         showClose: true, | 
 |  |  |                   message: '未找到符合条件的移动位置信息', | 
 |  |  |                   type: 'error' | 
 |  |  |                }); | 
 |  |  |                 } else { | 
 |  |  |                     self.$nextTick(() => { | 
 |  |  |                         self.showMarkPoints(self); | 
 |  |  |                     }); | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |             .catch(function (error) { | 
 |  |  |                 console.log(error); | 
 |  |  |             }); | 
 |  |  |         }, | 
 |  |  |         showLatestPosition: function() { | 
 |  |  |             this.map.clearOverlays(); | 
 |  |  |             this.mapPointList = []; | 
 |  |  |             this.mobilePositionList = []; | 
 |  |  |             let self = this; | 
 |  |  |             this.$axios.get(`/api/positions/${this.deviceId}/latest`) | 
 |  |  |             .then(function (res) { | 
 |  |  |                 console.log(res.data); | 
 |  |  |                 self.total = res.data.length; | 
 |  |  |                 self.mobilePositionList.push(res.data); | 
 |  |  |                 console.log(self.mobilePositionList); | 
 |  |  |                 if (self.total == 0) { | 
 |  |  |                     self.$message({ | 
 |  |  |                         showClose: true, | 
 |  |  |                   message: '未找到符合条件的移动位置信息', | 
 |  |  |                   type: 'error' | 
 |  |  |                }); | 
 |  |  |                 } else { | 
 |  |  |                     self.$nextTick(() => { | 
 |  |  |                         self.showMarkPoints(self); | 
 |  |  |                     }); | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |             .catch(function (error) { | 
 |  |  |                 console.log(error); | 
 |  |  |             }); | 
 |  |  |         }, | 
 |  |  |         subscribeMobilePosition: function() { | 
 |  |  |             let self = this; | 
 |  |  |             this.$axios.get(`/api/positions/${this.deviceId}/subscribe`, { | 
 |  |  |                 params: { | 
 |  |  |                     expires: self.expired, | 
 |  |  |                     interval: self.interval, | 
 |  |  |                 }, | 
 |  |  |             }) | 
 |  |  |             .then(function (res) { | 
 |  |  |                 console.log(res.data); | 
 |  |  |             }) | 
 |  |  |             .catch(function (error) { | 
 |  |  |                 console.log(error); | 
 |  |  |             }); | 
 |  |  |         }, | 
 |  |  |         unSubscribeMobilePosition: function() { | 
 |  |  |             let self = this; | 
 |  |  |             this.$axios.get(`/api/positions/${this.deviceId}/subscribe`, { | 
 |  |  |                 params: { | 
 |  |  |                     expires: 0, | 
 |  |  |                     interval: self.interval, | 
 |  |  |                 }, | 
 |  |  |             }) | 
 |  |  |             .then(function (res) { | 
 |  |  |                 console.log(res.data); | 
 |  |  |             }) | 
 |  |  |             .catch(function (error) { | 
 |  |  |                 console.log(error); | 
 |  |  |             }); | 
 |  |  |         }, | 
 |  |  |         toGBString: function (dateTime) { | 
 |  |  |             return ( | 
 |  |  |                 dateTime.getFullYear() +  | 
 |  |  |                 "-" + this.twoDigits(dateTime.getMonth() + 1) + | 
 |  |  |                 "-" + this.twoDigits(dateTime.getDate()) + | 
 |  |  |                 "T" + this.twoDigits(dateTime.getHours()) + | 
 |  |  |                 ":" + this.twoDigits(dateTime.getMinutes()) + | 
 |  |  |                 ":" + this.twoDigits(dateTime.getSeconds()) | 
 |  |  |             ); | 
 |  |  |         }, | 
 |  |  |         twoDigits: function (num) { | 
 |  |  |             if (num < 10) { | 
 |  |  |                 return "0" + num; | 
 |  |  |             } else { | 
 |  |  |                 return "" + num; | 
 |  |  |             } | 
 |  |  |         }, | 
 |  |  |         showMarkPoints: function(self) { | 
 |  |  |             let that = self; | 
 |  |  |             let npointJ = null; | 
 |  |  |             let npointW = null; | 
 |  |  |             let point = null; | 
 |  |  |             for (let i = 0; i < self.mobilePositionList.length; i++) { | 
 |  |  |                 if (self.mobilePositionList[i].geodeticSystem == "BD-09") { | 
 |  |  |                     npointJ = self.mobilePositionList[i].cnLng; | 
 |  |  |                     npointW = self.mobilePositionList[i].cnLat; | 
 |  |  |                     point = new BMap.Point(npointJ, npointW); | 
 |  |  |                 } else { | 
 |  |  |                     npointJ = self.mobilePositionList[i].longitude; | 
 |  |  |                     npointW = self.mobilePositionList[i].latitude; | 
 |  |  |                     let bd2 = geoTools.GPSToBaidu(npointJ, npointW); | 
 |  |  |                     point = new BMap.Point(bd2.lat, bd2.lng); | 
 |  |  |                 } | 
 |  |  |                 self.mapPointList.push(point); | 
 |  |  |                 let marker = new BMap.Marker(point); // 创建标注 | 
 |  |  |                 self.map.addOverlay(marker); // 将标注添加到地图中 | 
 |  |  |                 //提示信息  可以解析 HTML标签以及CSS | 
 |  |  |                 let infoWindow = new BMap.InfoWindow(`<p style='text-align:left;font-weight:800'>设备: ${self.mobilePositionList[i].deviceId}</p> | 
 |  |  |                             <p style='text-align:left;font-weight:0'>时间: ${self.mobilePositionList[i].time}</p>`); | 
 |  |  |                 // 鼠标移上标注点要发生的事 | 
 |  |  |                 marker.addEventListener("mouseover", function () { | 
 |  |  |                     this.openInfoWindow(infoWindow); | 
 |  |  |                 }); | 
 |  |  |                 // 鼠标移开标注点要发生的事 | 
 |  |  |                 marker.addEventListener("mouseout", function () { | 
 |  |  |                     this.closeInfoWindow(infoWindow); | 
 |  |  |                 }); | 
 |  |  |                 // 鼠标点击标注点要发生的事情 | 
 |  |  |                 marker.addEventListener("click", function () { | 
 |  |  |                     alert("点击"); | 
 |  |  |                 }); | 
 |  |  |             } | 
 |  |  |             let view = that.map.getViewport(eval(self.mapPointList)); | 
 |  |  |             that.map.centerAndZoom(view.center, view.zoom); | 
 |  |  |         }, | 
 |  |  |           } | 
 |  |  |         ], | 
 |  |  |         event, // 鼠标事件信息 | 
 |  |  |         customClass: "custom-class", // 自定义菜单 class | 
 |  |  |         zIndex: 3000, // 菜单样式 z-index | 
 |  |  |       }); | 
 |  |  |  | 
 |  |  |     }, | 
 |  |  |     channelsHandler: function (channels) { | 
 |  |  |       console.log(2) | 
 |  |  |       if (channels.length > 0) { | 
 |  |  |         this.clean() | 
 |  |  |         this.closeInfoBox() | 
 |  |  |         let params = []; | 
 |  |  |         for (let i = 0; i < channels.length; i++) { | 
 |  |  |           if (channels[i].longitude * channels[i].latitude === 0) { | 
 |  |  |             continue; | 
 |  |  |           } | 
 |  |  |           let item = { | 
 |  |  |             position: [channels[i].longitude, channels[i].latitude], | 
 |  |  |             image: { | 
 |  |  |               src: this.getImageByChannel(channels[i]), | 
 |  |  |               anchor: [0.5, 1] | 
 |  |  |             }, | 
 |  |  |             data: channels[i] | 
 |  |  |           } | 
 |  |  |           params.push(item); | 
 |  |  |         } | 
 |  |  |         console.log(3) | 
 |  |  |  | 
 |  |  |         this.layer = this.$refs.map.addLayer(params, this.featureClickEvent) | 
 |  |  |         console.log(4) | 
 |  |  |         if (params.length === 1) { | 
 |  |  |           this.$refs.map.panTo([channels[0].longitude, channels[0].latitude], mapParam.maxZoom) | 
 |  |  |         } else if (params.length > 1) { | 
 |  |  |           this.$refs.map.fit(this.layer) | 
 |  |  |         } else { | 
 |  |  |           this.$message.error('未获取到位置信息'); | 
 |  |  |         } | 
 |  |  |       } else { | 
 |  |  |         this.$message.error('未获取到位置信息'); | 
 |  |  |       } | 
 |  |  |     }, | 
 |  |  |     getImageByChannel: function (channel) { | 
 |  |  |       let src = "static/images/gis/camera.png" | 
 |  |  |       switch (channel.ptztype) { | 
 |  |  |         case 1: | 
 |  |  |           if (channel.status === 1) { | 
 |  |  |             src = "static/images/gis/camera1.png" | 
 |  |  |           } else { | 
 |  |  |             src = "static/images/gis/camera1-offline.png" | 
 |  |  |           } | 
 |  |  |           break; | 
 |  |  |         case 2: | 
 |  |  |           if (channel.status === 1) { | 
 |  |  |             src = "static/images/gis/camera2.png" | 
 |  |  |           } else { | 
 |  |  |             src = "static/images/gis/camera2-offline.png" | 
 |  |  |           } | 
 |  |  |           break; | 
 |  |  |         case 3: | 
 |  |  |           if (channel.status === 1) { | 
 |  |  |             src = "static/images/gis/camera3.png" | 
 |  |  |           } else { | 
 |  |  |             src = "static/images/gis/camera3-offline.png" | 
 |  |  |           } | 
 |  |  |           break; | 
 |  |  |         default: | 
 |  |  |           if (channel.status === 1) { | 
 |  |  |             src = "static/images/gis/camera.png" | 
 |  |  |           } else { | 
 |  |  |             src = "static/images/gis/camera-offline.png" | 
 |  |  |           } | 
 |  |  |       } | 
 |  |  |       return src; | 
 |  |  |     }, | 
 |  |  |     featureClickEvent: function (channels) { | 
 |  |  |       this.closeInfoBox() | 
 |  |  |       if (channels.length > 0) { | 
 |  |  |         this.channel = channels[0] | 
 |  |  |       } | 
 |  |  |       this.$nextTick(() => { | 
 |  |  |         this.infoBoxId = this.$refs.map.openInfoBox([this.channel.longitude, this.channel.latitude], this.$refs.infobox, [0, -50]) | 
 |  |  |       }) | 
 |  |  |     }, | 
 |  |  |     closeInfoBox: function () { | 
 |  |  |       if (this.infoBoxId != null) { | 
 |  |  |         this.$refs.map.closeInfoBox(this.infoBoxId) | 
 |  |  |       } | 
 |  |  |     }, | 
 |  |  |     play: function (channel) { | 
 |  |  |  | 
 |  |  |       let deviceId = channel.deviceId; | 
 |  |  |       this.isLoging = true; | 
 |  |  |       let channelId = channel.channelId; | 
 |  |  |       console.log("通知设备推流1:" + deviceId + " : " + channelId); | 
 |  |  |       let that = this; | 
 |  |  |       this.$axios({ | 
 |  |  |         method: 'get', | 
 |  |  |         url: '/api/play/start/' + deviceId + '/' + channelId | 
 |  |  |       }).then(function (res) { | 
 |  |  |         that.isLoging = false; | 
 |  |  |         if (res.data.code === 0) { | 
 |  |  |  | 
 |  |  |           that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { | 
 |  |  |             streamInfo: res.data.data, | 
 |  |  |             hasAudio: channel.hasAudio | 
 |  |  |           }); | 
 |  |  |  | 
 |  |  |         } else { | 
 |  |  |           that.$message.error(res.data.msg); | 
 |  |  |         } | 
 |  |  |       }).catch(function (e) { | 
 |  |  |       }); | 
 |  |  |     }, | 
 |  |  |     edit: function (data) { | 
 |  |  |       this.$message.warning('暂不支持'); | 
 |  |  |     }, | 
 |  |  |     getTrace: function (data) { | 
 |  |  |       // this.$message.warning('暂不支持'); | 
 |  |  |       this.clean() | 
 |  |  |       this.$refs.queryTrace.openDialog(data, (channelPositions) => { | 
 |  |  |         console.log("getTrace") | 
 |  |  |         console.log(channelPositions) | 
 |  |  |         if (channelPositions.length === 0) { | 
 |  |  |           this.$message.success('未查询到轨迹信息'); | 
 |  |  |         } else { | 
 |  |  |           let positions = []; | 
 |  |  |           for (let i = 0; i < channelPositions.length; i++) { | 
 |  |  |             if (channelPositions[i].cnLng * channelPositions[i].cnLat > 0) { | 
 |  |  |               positions.push([channelPositions[i].cnLng, channelPositions[i].cnLat]) | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |           } | 
 |  |  |           if (positions.length === 0) { | 
 |  |  |             this.$message.success('未查询到轨迹信息'); | 
 |  |  |             return; | 
 |  |  |           } | 
 |  |  |           this.lineLayer = this.$refs.map.addLineLayer(positions) | 
 |  |  |           this.$refs.map.fit(this.lineLayer) | 
 |  |  |         } | 
 |  |  |       }) | 
 |  |  |     }, | 
 |  |  |     clean: function (){ | 
 |  |  |       if (this.lineLayer != null) { | 
 |  |  |         this.$refs.map.removeLayer(this.lineLayer) | 
 |  |  |       } | 
 |  |  |       if (this.infoBoxId != null) { | 
 |  |  |         this.$refs.map.closeInfoBox(this.infoBoxId) | 
 |  |  |       } | 
 |  |  |       if (this.layer != null) { | 
 |  |  |         this.$refs.map.removeLayer(this.layer) | 
 |  |  |       } | 
 |  |  |     } | 
 |  |  |   }, | 
 |  |  |  | 
 |  |  | }; | 
 |  |  | </script> | 
 |  |  |  | 
 |  |  | <style> | 
 |  |  | .videoList { | 
 |  |  |   display: flex; | 
 |  |  |   flex-wrap: wrap; | 
 |  |  |   align-content: flex-start; | 
 |  |  | .infobox-content{ | 
 |  |  |   width: 260px; | 
 |  |  |   background-color: #FFFFFF; | 
 |  |  |   padding: 10px; | 
 |  |  |   border-radius: 10px; | 
 |  |  |   border: 1px solid #e2e2e2; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | .video-item { | 
 |  |  |   position: relative; | 
 |  |  |   width: 15rem; | 
 |  |  |   height: 10rem; | 
 |  |  |   margin-right: 1rem; | 
 |  |  |   background-color: #000000; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | .video-item-img { | 
 |  |  | .infobox-content::after { | 
 |  |  |   position: absolute; | 
 |  |  |   top: 0; | 
 |  |  |   bottom: 0; | 
 |  |  |   left: 0; | 
 |  |  |   right: 0; | 
 |  |  |   margin: auto; | 
 |  |  |   width: 100%; | 
 |  |  |   height: 100%; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | .video-item-img:after { | 
 |  |  |   bottom: -11px; | 
 |  |  |   left: 130px; | 
 |  |  |   display: block; | 
 |  |  |   content: ""; | 
 |  |  |   display: inline-block; | 
 |  |  |   position: absolute; | 
 |  |  |   z-index: 2; | 
 |  |  |   top: 0; | 
 |  |  |   bottom: 0; | 
 |  |  |   left: 0; | 
 |  |  |   right: 0; | 
 |  |  |   margin: auto; | 
 |  |  |   width: 3rem; | 
 |  |  |   height: 3rem; | 
 |  |  |   background-image: url("../assets/loading.png"); | 
 |  |  |   background-size: cover; | 
 |  |  |   background-color: #000000; | 
 |  |  |   width: 16px; | 
 |  |  |   height: 16px; | 
 |  |  |   background: url('~@static/images/arrow.png') no-repeat center; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | .video-item-title { | 
 |  |  | .infobox-close { | 
 |  |  |   position: absolute; | 
 |  |  |   bottom: 0; | 
 |  |  |   right: 1rem; | 
 |  |  |   top: 1rem; | 
 |  |  |   color: #000000; | 
 |  |  |   background-color: #ffffff; | 
 |  |  |   line-height: 1.5rem; | 
 |  |  |   padding: 0.3rem; | 
 |  |  |   width: 14.4rem; | 
 |  |  |   cursor:pointer | 
 |  |  | } | 
 |  |  |  | 
 |  |  | .baidumap { | 
 |  |  | .el-descriptions__title { | 
 |  |  |   font-size: 1rem; | 
 |  |  |   font-weight: 700; | 
 |  |  |   padding: 20px 20px 0px 23px; | 
 |  |  |   text-align: center; | 
 |  |  |   width: 100%; | 
 |  |  |   height: 100%; | 
 |  |  |   border: none; | 
 |  |  |   position: absolute; | 
 |  |  |   left: 0; | 
 |  |  |   top: 0; | 
 |  |  |   right: 0; | 
 |  |  |   bottom: 0; | 
 |  |  |   margin: auto; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | /* 去除百度地图版权那行字 和 百度logo */ | 
 |  |  | .baidumap > .BMap_cpyCtrl { | 
 |  |  |   display: none !important; | 
 |  |  | } | 
 |  |  | .baidumap > .anchorBL { | 
 |  |  |   display: none !important; | 
 |  |  | } | 
 |  |  | </style> |