likang 3 years ago
parent
commit
f771dc0b7b

+ 0 - 1
src/views/device/storage_equipment/bmapModel.vue

@@ -66,7 +66,6 @@ export default {
      
     },
     getChangeValue(res){
-      console.log(res);
         this.formData.lat=res.location.lat
         this.formData.lng=res.location.lng
          this.formData.address = res.location.address

+ 467 - 0
src/views/work_box_map/gpsRouteDialog.vue

@@ -0,0 +1,467 @@
+<template>
+  <el-dialog
+    @closed="closedDialog"
+   :visible.sync="dialog" 
+   append-to-body
+   direction="rtl" 
+   :fullscreen=true
+  >
+    <baidu-map class="bm-view" :center="center" :zoom="zoom" @ready="init"
+      v-loading="loading"
+      element-loading-text="数据加载中"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="rgba(0, 0, 0, 0.8)"
+    >
+    <bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-map-type>
+    <bm-control :offset="searchControlOffset">
+      <div id="searchbox">
+        <div id="searchbox-container">
+          <div id="sole-searchbox-content" class="searchbox-content">
+            <el-date-picker
+              v-model="timeRange"
+              type="datetimerange"
+              :picker-options="pickerOptions"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              align="right">
+            </el-date-picker>
+          </div>
+        </div>
+        <el-button type="info" id="search-button" @click="queryStudentRoute" >搜索</el-button>
+      </div>
+    </bm-control>
+    <bm-control anchor="BMAP_ANCHOR_TOP_RIGHT" :offset="listControlOffset">
+     <div id="route-container">
+        <el-table
+          class="ontop-route-table"
+          ref="singleTable"
+          :data="Routedata"
+           height="480"
+          highlight-current-row
+           @row-click="clickStudentRow"
+
+          @current-change="handleCurrentChange"
+          style="width: 100%">
+          <el-table-column
+            type="index"
+            width="40"
+           
+            align="center">
+          </el-table-column>
+
+          <el-table-column label="定位列表" >
+            <template slot-scope="record">
+              <div>
+                {{record.row.PassTime}}&nbsp;&nbsp;<i v-if="record.row.WifiAddress" class="wifi_icon">W</i><i v-else class="gps_icon">G</i><br/> 
+               <div v-if="record.row.WifiAddress"> {{record.row.WifiAddress}}</div> 
+               <div v-else> {{record.row.Address}}</div> 
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+       
+
+      </div>
+    </bm-control>
+
+  </baidu-map>
+  </el-dialog>
+</template>
+<script>
+
+export default {
+  props: ["displayVisible","activeRfid"],
+
+  data() {
+    return {
+      loading: false,
+      dialog: false,
+      title:'轨迹地图',
+      Routedata:[
+        {
+          PassTime:'2022-05-25 15:11:11',
+          Address:'浙江省杭州市滨江区华城和瑞科技广场',
+          Latitude:30.192001,
+          Longitude:120.20121,
+        },
+        {
+          PassTime:'2022-05-25 15:11:11',
+          Address:'浙江省杭州市滨江区滨安路跟江虹路交叉口',
+          Latitude:30.192797,
+          Longitude:120.207067,
+        },
+        {
+          PassTime:'2022-05-24 15:11:11',
+          Address:'浙江省杭州市滨江区江虹小区东门',
+          Latitude:30.202219,
+          Longitude:120.208827,
+        },
+        
+      ],
+      map: null,
+      center: '杭州市滨江区',
+      zoom: 19,
+      searchControlOffset:{},
+      listControlOffset:{},
+      route_type:'All',
+      filterTrack:false,
+      markerIcons: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/smart_tool/beng.png',
+      pickerOptions: {
+          shortcuts: [
+           {
+            text: '3小时内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 3);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '6小时内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 6);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '12小时内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 12);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '24小时内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '2天内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 2);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '3天内',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 3);
+              picker.$emit('pick', [start, end]);
+            }
+          }]
+        },
+        timeRange: [new Date(new Date().toLocaleDateString()), new Date(new Date(new Date().toLocaleDateString()).getTime() + (24 * 60 * 60 * 1000)-1000)],
+
+        trackMarkers:[],
+        currentRow: null,
+     
+    };
+  },
+  mounted(){
+
+    this.dialog = this.displayVisible;
+    
+
+
+    this.$nextTick(() => {
+      
+      // const query = { device_number: this.activeRfid}
+      // this.$http.get('map/queryDeviceCurLocation',{ params: query }).then(res=>{
+      //     let pointInfo=res.data
+      //     var trackPoint = new BMap.Point(pointInfo.longitude, pointInfo.latitude);
+      //     let pointType = "terminus";
+      //     var pointIcon = new BMap.Icon(this.markerIcons[pointType], new BMap.Size(27, 32));
+      //     pointIcon.iconAnchor = new BMap.Point(5, 5);
+      //     pointIcon.shadow = "";
+      //     let trackMarker = new BMap.Marker(trackPoint, { icon: pointIcon });
+      //     this.map.addOverlay(trackMarker);
+      //     this.center=trackPoint
+      //     //this.map.centerAndZoom(trackPoint, 19);
+      //     this.queryStudentRoute();
+      // }).catch(e => {
+      //   // this.loading = false;
+      // });
+      let topTables = document.getElementsByClassName('ontop-route-table');
+      topTables.forEach(item => {
+        item.onwheel = function(e) {
+          e.stopPropagation();
+        }
+      })
+    })
+  },
+  methods: {
+    init({ BMap, map }) {
+      this.map = map;
+      // 初始化地图,设置中心点坐标
+      // map.centerAndZoom("杭州市滨江区", 15);
+      this.searchControlOffset=new BMap.Size(20, 20)
+      this.listControlOffset=new BMap.Size(20, 40)
+      // 添加鼠标滚动缩放
+      map.enableScrollWheelZoom();
+      //临时写的
+      this.queryStudentRoute()
+      
+    },
+    queryStudentRoute(){
+      let that=this
+      this.loading = true;
+      setTimeout(function(){ 
+        that.DrawMapLine(that.Routedata);
+       that.loading = false;
+      }, 2000);
+      
+      // const query = { active_rfid: this.activeRfid,time_range:this.timeRange,route_type:this.route_type,filter_track:this.filterTrack,}
+      // this.$http.get('map/queryStudentRouteGps',{ params: query,timeout:60000}).then(res=>{
+      //     this.map.clearOverlays()
+      //     let data=[]
+      //     let trackLength=res.data.length
+      //     if(trackLength>0){
+      //       for (var i = 0; i < trackLength; i++){
+      //           let item=res.data[i]
+      //           // var myGeo = new BMap.Geocoder();      
+      //           // // 根据坐标得到地址描述    
+      //           // myGeo.getLocation(new BMap.Point(item.Longitude,item.Latitude), function(result){          
+      //           //       item['Address']=result.address
+      //           // });
+      //           // data.push(item)
+      //           item['index']=i
+      //           data[i]=item
+      //       }
+      //       this.DrawMapLine(data)
+      //     }
+      //     this.Routedata=data
+           
+      //     this.loading = false;
+          
+      // })
+      // .catch(e => {
+      //   this.loading = false;
+      // });
+    },
+    DrawMapLine(data){
+        var pointType = "node";//点类型
+        var pointLogLat = new BMap.Point(data[0].Longitude, data[0].Latitude);//终点
+        var trackCount=data.length
+       // this.center=pointLogLat
+        this.map.centerAndZoom(pointLogLat, 19);
+        var onLineCoordinates = [];
+        for (var i = trackCount-1; i >= 0; i--)
+        {
+            //线上的点
+            pointLogLat = new BMap.Point(data[i].Longitude, data[i].Latitude);
+            onLineCoordinates.push(pointLogLat);
+
+            var pointMarker = this.CreatePointMarkers(data[i]);
+
+            this.trackMarkers.push(pointMarker);
+            
+        }
+        var sy = new BMap.Symbol(BMap_Symbol_SHAPE_BACKWARD_OPEN_ARROW, {
+            scale: 0.6,//图标缩放大小
+            strokeColor:'#fff',//设置矢量图标的线填充颜色
+            strokeWeight: '2',//设置线宽
+        });
+        var icons = new BMap.IconSequence(sy, '10', '30');
+        //画线
+        // var polyline = new BMap.Polyline(onLineCoordinates,{
+        //   enableEditing: false,//是否启用线编辑,默认为false
+        //   enableClicking: true,//是否响应点击事件,默认为true
+        //   icons:[icons],
+        //   strokeWeight:'4',//折线的宽度,以像素为单位
+        //   strokeOpacity: 0.8,//折线的透明度,取值范围0 - 1
+        //   strokeColor:"blue" //折线颜色
+        // });
+        // this.map.addOverlay(polyline);
+        //最佳视野
+        this.map.setViewport(onLineCoordinates);
+    },
+    CreatePointMarkers(pointInfo)
+    {
+        // console.log(pType)
+        var _this=this
+        var trackMarker;
+        var trackPoint = new BMap.Point(pointInfo.Longitude, pointInfo.Latitude);
+
+
+          var pointIcon = new BMap.Icon(this.markerIcons, new BMap.Size(32, 32));
+
+        pointIcon.setImageSize(new BMap.Size(32, 32));
+        // var pointIcon = new BMap.Icon(this.markerIcons[pType], new BMap.Size(27, 32));
+            //描点,创建标注 
+        pointIcon.iconAnchor = new BMap.Point(5, 5);
+        pointIcon.shadow = "";
+        trackMarker = new BMap.Marker(trackPoint, { icon: pointIcon });
+
+        
+        trackMarker.addEventListener("click", function ()
+        {
+            // if(pointInfo.SignalType=='WiFi'){
+              var content ='<p>经过时间:' + pointInfo.PassTime + '</p><p>地址:' + pointInfo.Address + '</p>'
+              var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+              _this.map.centerAndZoom(trackPoint, 19);
+              _this.map.openInfoWindow(infoWindow,trackPoint);
+            // }else{
+            //   var myGeo = new BMap.Geocoder();      
+            //     // 根据坐标得到地址描述    
+            //   myGeo.getLocation(new BMap.Point(pointInfo.Longitude,pointInfo.Latitude), function(result){     
+            //               let index=pointInfo['index']     
+            //               pointInfo['Address']=result.address
+            //               _this.Routedata[index]=pointInfo
+            //               var trackPoint = new BMap.Point(pointInfo.Longitude, pointInfo.Latitude);
+            //               var content ='<p>经过时间:' + pointInfo.PassTime + '</p><p>地址:' + pointInfo.Address + '</p>'
+            //               var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+            //               _this.map.centerAndZoom(trackPoint, 19);
+            //               _this.map.openInfoWindow(infoWindow,trackPoint);
+            //   });
+            //   // var content ='<p>经过时间:' + pointInfo.PassTime + '</p><p>地址:' + pointInfo.Address + '</p><p>定位类型:' + pointInfo.SignalType + '</p>'
+            // }
+            
+           
+        });
+        this.map.addOverlay(trackMarker);
+
+        return trackMarker;
+    },
+
+    clickStudentRow(row, column, event){
+        let that=this
+        let index=row['index']
+        let item=row
+        // if(row['WifiAddress']){
+            item['Address']=row['Address']
+            that.Routedata[index]=item
+            var trackPoint = new BMap.Point(row['Longitude'], row['Latitude']);
+            var content ='<p>经过时间:' + item.PassTime + '</p><p>地址:' + item.Address + '</p>'
+            var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+            that.map.centerAndZoom(trackPoint, 19);
+            // that.map.panTo(trackPoint)
+            that.map.openInfoWindow(infoWindow,trackPoint);
+        // }else{
+        //     var myGeo = new BMap.Geocoder();      
+        //         // 根据坐标得到地址描述    
+        //     myGeo.getLocation(new BMap.Point(item.Longitude,item.Latitude), function(result){          
+        //                 item['Address']=result.address
+        //                 that.Routedata[index]=item
+        //                 var trackPoint = new BMap.Point(item.Longitude, item.Latitude);
+        //                 var content ='<p>经过时间:' + item.PassTime + '</p><p>地址:' + item.Address + '</p>'
+        //                 var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+        //                 that.map.centerAndZoom(trackPoint, 19);
+        //                 // that.map.panTo(trackPoint)
+        //                 that.map.openInfoWindow(infoWindow,trackPoint);
+        //     });
+        // }
+
+    },
+    handleCurrentChange(val) {
+        this.currentRow = val;
+    },
+    closedDialog() {
+      // this.dialog = false;
+      this.$emit("formCancel");  
+    }
+  }
+};
+</script>
+<style>
+.el-select-dropdown{
+  z-index:9999 !important;
+}
+</style>
+<style lang="scss" scoped>
+
+.el-drawer span:focus {
+  outline: none;
+}
+.bm-view {
+  width: 100%;
+  height: calc(100vh - 40px);
+  margin-top:10px;
+}
+#route-container{
+  width:280px;
+  height: 500px;
+  background-color: #fafafa;
+}
+
+#searchbox {
+  border-radius: 2px;
+  width: 464px;
+  position: relative;
+  z-index: 5;
+  display: flex;
+}
+#searchbox #searchbox-container {
+  display: flex;
+  position: relative;
+  z-index: 2;
+  pointer-events: auto;
+  width: 400px;
+  float: left;
+  
+  box-sizing: border-box;
+  
+}
+
+#sole-searchbox-content {
+  position: relative;
+}
+.searchbox-content {
+  width: 400px;
+  border-bottom:none !important;
+  border-radius: 2px 0 0 2px;
+  background: #fff;
+}
+#sole-searchbox-content #sole-input,
+#searchType {
+  box-sizing: border-box;
+  border: 0;
+  padding: 9px 0;
+  border-left: 10px solid transparent;
+  border-right: 10px solid transparent;
+  line-height: 20px;
+  font-size: 14px;
+  height: 38px;
+  color: #333;
+  position: relative;
+  border-radius: 2px 0 0 2px;
+}
+#sole-input {
+  width: 250px;
+}
+#sole-input:focus {
+  outline: none;
+}
+#search-button{
+  border-top-left-radius:0px !important;
+  border-bottom-left-radius:0px !important;
+}
+.wifi_icon{
+  display:inline-block;
+  width:18px;
+  height:18px;
+  border-radius:9px;
+  background:#1296db;
+  color:#FFF;
+  text-align:center;
+  line-height:18px;
+}
+.gps_icon{
+  display:inline-block;
+  width:18px;
+  height:18px;
+  border-radius:9px;
+  background:#1afa29;
+  color:#FFF;
+  text-align:center;
+  line-height:18px;
+}
+</style>

+ 326 - 0
src/views/work_box_map/rfidRouteDialog.vue

@@ -0,0 +1,326 @@
+<template>
+  <el-dialog
+  
+   :visible.sync="dialog"   
+   direction="rtl" 
+   :fullscreen=true
+  >
+    <baidu-map class="bm-view" :center="center" :zoom="zoom" @ready="init">
+    <bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-map-type>
+    <bm-control :offset="searchControlOffset">
+      <div id="searchbox">
+        <div id="searchbox-container">
+          <div id="sole-searchbox-content" class="searchbox-content">
+            <el-date-picker
+              v-model="timeRange"
+              type="datetimerange"
+              :picker-options="pickerOptions"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              align="right">
+            </el-date-picker>
+          </div>
+        </div>
+        <el-button type="info" id="search-button" @click="queryStudentRoute" >搜索</el-button>
+      </div>
+    </bm-control>
+    <bm-control anchor="BMAP_ANCHOR_TOP_RIGHT" :offset="listControlOffset">
+     <div id="route-container">
+        <el-table
+          ref="singleTable"
+          class="ontop-route-table"
+          :data="Routedata"
+           height="480"
+          highlight-current-row
+           @row-click="clickStudentRow"
+
+          @current-change="handleCurrentChange"
+          style="width: 100%">
+          <el-table-column
+            type="index"
+            width="40"
+           
+            align="center">
+          </el-table-column>
+
+          <el-table-column label="RFID轨迹列表" >
+            <template slot-scope="record">
+              <div>{{record.row.PassTime}}<br/>{{record.row.Address}}
+
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+       
+
+      </div>
+    </bm-control>
+
+  </baidu-map>
+  </el-dialog>
+</template>
+<script>
+
+export default {
+  props: ["displayVisible","activeRfid"],
+
+  components: {
+
+  },
+  created() {
+    // 初始化统计数据
+    // this.getChartData()
+  },
+  data() {
+    return {
+      title:'轨迹地图',
+      Routedata:[],
+      map: null,
+      center: '',
+      zoom: 13,
+      searchControlOffset:{},
+      listControlOffset:{},
+      pickerOptions: {
+          shortcuts: [{
+            text: '最近一周',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '最近一个月',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+              picker.$emit('pick', [start, end]);
+            }
+          }, {
+            text: '最近三个月',
+            onClick(picker) {
+              const end = new Date();
+              const start = new Date();
+              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+              picker.$emit('pick', [start, end]);
+            }
+          }]
+        },
+        timeRange: [new Date(new Date().toLocaleDateString()), new Date(new Date(new Date().toLocaleDateString()).getTime() + (24 * 60 * 60 * 1000)-1000)],
+        markerIcons: { // 覆盖物图标
+                origin: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/wxt_school/origin_icon.png', 
+                terminus: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/wxt_school/terminus_icon.png', 
+                alarm: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/wxt_school/alarm_icon.png', 
+        },
+        trackMarkers:[],
+        currentRow: null,
+     
+    };
+  },
+  computed: {
+    dialog: {
+      set(val) {
+        this.$emit("formCancel", val); // 表示将子组件改变的值传递给父组件
+      },
+      get() {
+        if (this.displayVisible) {
+          this.loading = true
+          this.queryStudentRoute()
+        }
+        // console.log(this.activeRfid)
+        
+        return this.displayVisible; // 表示获取父组件的值
+      }
+    }
+  },
+  mounted(){
+    this.$nextTick(() => {
+      let topTables = document.getElementsByClassName('ontop-route-table');
+      topTables.forEach(item => {
+        item.onwheel = function(e) {
+          e.stopPropagation();
+        }
+      })
+    })
+  },
+
+  methods: {
+    init({ BMap, map }) {
+      this.map = map;
+      // 初始化地图,设置中心点坐标
+      map.centerAndZoom("杭州市滨江区", 14);
+      this.searchControlOffset=new BMap.Size(20, 20)
+      this.listControlOffset=new BMap.Size(20, 40)
+      // 添加鼠标滚动缩放
+      map.enableScrollWheelZoom();
+    },
+    queryStudentRoute(){
+      const query = { active_rfid: this.activeRfid,time_range:this.timeRange}
+      this.$http.get('map/queryStudentRouteRfid',{ params: query }).then(res=>{
+          this.map.clearOverlays()
+          this.Routedata=res.data
+          if(res.data.length>0){
+            this.DrawMapLine(res.data)
+          }
+          
+      });
+    },
+    DrawMapLine(data){
+      
+        var pointType = "node";//点类型
+        var pointLogLat = new BMap.Point(data[0].Longitude, data[0].Latitude);//起点 
+        this.center=pointLogLat
+        var trackCount=data.length
+        // this.map.centerAndZoom(pointLogLat, 13);
+        var onLineCoordinates = [];
+        for (var i = trackCount-1; i >= 0; i--)
+        {
+            //线上的点
+            pointLogLat = new BMap.Point(data[i].Longitude, data[i].Latitude);
+            onLineCoordinates.push(pointLogLat);
+            //描点
+            if (i == 0)
+                pointType = "terminus";
+            else if (i==(trackCount - 1))
+                pointType = "origin";
+            else if (data[i].AlarmType >0 )
+                pointType = "alarm";
+            else
+                pointType = "node";
+            if (pointType != "node"){
+                var pointMarker = this.CreatePointMarkers(data[i], pointType);
+
+                this.trackMarkers.push(pointMarker);
+            }
+        }
+        var sy = new BMap.Symbol(BMap_Symbol_SHAPE_BACKWARD_OPEN_ARROW, {
+            scale: 0.6,//图标缩放大小
+            strokeColor:'#fff',//设置矢量图标的线填充颜色
+            strokeWeight: '2',//设置线宽
+        });
+        var icons = new BMap.IconSequence(sy, '10', '30');
+        //画线
+        var polyline = new BMap.Polyline(onLineCoordinates,{
+          enableEditing: false,//是否启用线编辑,默认为false
+          enableClicking: true,//是否响应点击事件,默认为true
+          icons:[icons],
+          strokeWeight:'4',//折线的宽度,以像素为单位
+          strokeOpacity: 0.8,//折线的透明度,取值范围0 - 1
+          strokeColor:"blue" //折线颜色
+        });
+        this.map.addOverlay(polyline);
+        //最佳视野
+        this.map.setViewport(onLineCoordinates);
+    },
+    CreatePointMarkers(pointInfo, pType)
+    {
+        var _this=this
+        var trackMarker;
+        var trackPoint = new BMap.Point(pointInfo.Longitude, pointInfo.Latitude);
+
+  
+        var pointIcon = new BMap.Icon(this.markerIcons[pType], new BMap.Size(27, 32));
+            //描点,创建标注 
+        pointIcon.iconAnchor = new BMap.Point(5, 5);
+        pointIcon.shadow = "";
+        trackMarker = new BMap.Marker(trackPoint, { icon: pointIcon });
+
+        trackMarker.setOffset(new BMap.Size(-1, -15));//大图标,偏移确定图片在点正上方
+        
+        trackMarker.addEventListener("click", function ()
+        {
+            var content ='<p>经过时间:' + pointInfo.PassTime + '</p><p>地址:' + pointInfo.Address + '</p><p>基站MAC:' + pointInfo.StationCode + '</p>'
+            var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+            _this.map.centerAndZoom(trackPoint, 17);
+            _this.map.openInfoWindow(infoWindow,trackPoint);
+        });
+        this.map.addOverlay(trackMarker);
+
+        return trackMarker;
+    },
+
+    clickStudentRow(row, column, event){
+        var trackPoint = new BMap.Point(row.Longitude, row.Latitude);
+        var content ='<p>经过时间:' + row.PassTime + '</p><p>地址:' + row.Address + '</p><p>基站MAC:' + row.StationCode + '</p>'
+        var infoWindow = new BMap.InfoWindow(content);  // 创建信息窗口对象  
+        this.map.centerAndZoom(trackPoint, 17);
+        this.map.openInfoWindow(infoWindow,trackPoint);
+
+    },
+    handleCurrentChange(val) {
+        this.currentRow = val;
+    },
+    
+  }
+};
+</script>
+<style lang="scss" scoped>
+
+.el-drawer span:focus {
+  outline: none;
+}
+.bm-view {
+  width: 100%;
+  height: calc(100vh - 40px);
+  margin-top:10px;
+}
+#route-container{
+  width:280px;
+  height: 500px;
+  background-color: #fafafa;
+}
+
+#searchbox {
+  border-radius: 2px;
+  width: 464px;
+  position: relative;
+  z-index: 5;
+  display: flex;
+}
+#searchbox #searchbox-container {
+  display: flex;
+  position: relative;
+  z-index: 2;
+  pointer-events: auto;
+  width: 400px;
+  float: left;
+  
+  box-sizing: border-box;
+  
+}
+#sole-searchbox-content {
+  position: relative;
+}
+.searchbox-content {
+  width: 400px;
+  border-bottom:none !important;
+  border-radius: 2px 0 0 2px;
+  background: #fff;
+}
+#sole-searchbox-content #sole-input,
+#searchType {
+  box-sizing: border-box;
+  border: 0;
+  padding: 9px 0;
+  border-left: 10px solid transparent;
+  border-right: 10px solid transparent;
+  line-height: 20px;
+  font-size: 14px;
+  height: 38px;
+  color: #333;
+  position: relative;
+  border-radius: 2px 0 0 2px;
+}
+#sole-input {
+  width: 250px;
+}
+#sole-input:focus {
+  outline: none;
+}
+#search-button{
+  border-top-left-radius:0px !important;
+  border-bottom-left-radius:0px !important;
+}
+</style>

+ 422 - 0
src/views/work_box_map/routeMap.vue

@@ -0,0 +1,422 @@
+<template>
+  <baidu-map class="bm-view" :center="center" :zoom="zoom" @ready="init">
+    <bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']" anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-map-type>
+    <bm-control :offset="searchControlOffset">
+      <div id="searchbox">
+        <div id="searchbox-container">
+          <div id="sole-searchbox-content" class="searchbox-content">
+            <input
+              id="sole-input"
+              class="searchbox-content-common"
+              v-model="queryParam.number"
+              type="text"
+              name="word"
+              autocomplete="off"
+              maxlength="256"
+              placeholder="请输入设备号"
+              @change="startSearch"
+              value
+            />
+          </div>
+        </div>
+        <el-button type="info" id="search-button" @click="startSearch" >搜索</el-button>
+        <el-button type="info" id="search-button" @click="startSearch" >刷新</el-button>
+      </div>
+    </bm-control>
+    <bm-control anchor="BMAP_ANCHOR_TOP_RIGHT" :offset="listControlOffset">
+      <el-tabs type="border-card" @tab-click="clickTab" v-model="activeName">
+        <el-tab-pane label="设备列表" name="deviceList">
+            <div id="student-container">
+              <el-table
+                class="ontop-table"
+                ref="singleTable"
+                :data="data"
+                @row-click="clickStudentRow"
+                v-loading="loading"
+                highlight-current-row
+                height="440px"
+                style="width: 100%">
+                <el-table-column
+                  type="index"
+                  width="40"
+                  align="center">
+                </el-table-column>
+               
+                <el-table-column
+                  property="number"
+                  align="center"
+                  label="设备号">
+                  <template slot-scope="scope">
+                     {{ scope.row.number}}
+                  </template>
+                </el-table-column>
+              </el-table>
+              <el-pagination
+              small
+              background
+              class="pagination-container"
+              hide-on-single-page
+              @size-change="handleSizeChange"
+              @current-change="handleCurrentChange"
+              :current-page="paginate.current"
+              :page-sizes="paginate.sizes"
+              :page-size="paginate.limit"
+              :pager-count="5"
+              layout="slot, prev, pager, next, total"
+              :total="paginate.total"/>
+            </div>
+        </el-tab-pane>
+    
+      </el-tabs>
+     
+    </bm-control>
+    <!-- <bm-marker :position="{lng: 120.197113, lat: 30.196912}"  @click="infoWindowOpen" :icon="{url: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/wxt_school/student.png',imageSize:{width:36, height: 36}, size: {width:150, height: 150}}"></bm-marker> -->
+    <!-- <bm-info-window :position="{lng: 120.197113, lat: 30.196912}" :show="show" @close="infoWindowClose" @open="infoWindowOpen">我爱北京天安门</bm-info-window> -->
+      
+      <gps-dialog
+        v-if="gpsFormVisible"
+        :displayVisible="gpsFormVisible"
+        @formCancel="closeGpsDialog"
+        :activeRfid="currentActiveRfid"
+      />
+       <user-info-dialog
+        v-if="userFormVisible"
+        :displayVisible="userFormVisible"
+        @formCancel="closeUserDialog"
+        :userId="currentUserId"
+      />
+     
+  </baidu-map>
+    
+    
+</template>
+
+<script>
+import rlListOperate from "@/layout/rl-list-operate/rlListOperate";
+import rfidDialog from "./rfidRouteDialog";
+import gpsDialog from "./gpsRouteDialog";
+import userInfoDialog from "./userInfoDialog";
+
+import $ from "jquery";
+export default {
+  mixins: [rlListOperate],
+  components:{rfidDialog,gpsDialog,userInfoDialog},
+  data() {
+    return {
+      activeName: 'deviceList',
+      loading: false,
+      center: '杭州市滨江区',
+      url:'map/queryDeviceList',
+      pointObj:[],
+      currentUserId:'',
+      currentActiveRfid:'',
+      formVisible: false,
+      searchControlOffset:{},
+      listControlOffset:{},
+      zoom: 13,
+      mapData: [],
+      show: false,
+      map: null,
+      infoBox: null,
+      content: "",
+      opts: null,
+      queryParam:{
+        number:'',
+        type:0,
+      },
+  
+ 
+      gpsFormVisible:false,
+      userFormVisible:false,
+      markerIcons: 'https://rlfd.oss-cn-hangzhou.aliyuncs.com/smart_tool/beng.png',
+
+    };
+  },
+  mounted(){
+    let topTables = document.getElementsByClassName('ontop-table');
+    
+    topTables.forEach((item,index) => {
+      item.onwheel = function(e) {
+        e.stopPropagation();
+      }
+    })
+
+    let params = this.$router.currentRoute.query 
+    this.queryParam.number=params.number
+  },
+  created(){
+    window.showGpsRoute=this.showGpsRoute;
+    window.showUserInfo=this.showUserInfo;
+     
+  },
+  methods: {
+    init({ BMap, map }) {
+      this.map = map;
+      // 初始化地图,设置中心点坐标
+      
+      this.searchControlOffset=new BMap.Size(20, 20)
+      this.listControlOffset=new BMap.Size(0, 40)
+      // 添加鼠标滚动缩放
+      map.enableScrollWheelZoom();
+      
+      // this.queryLocationStationList()
+      this.queryLocationList()
+      // 获取风场数据
+      this.getwindData()
+    },
+    // 获取风场数据
+    getwindData() {
+      this.$http.get('wind/getWindList').then(resp => {
+          if (resp.code === 10000) {
+              resp.data.forEach(wind => {
+                this.addShapeWind(wind)
+              })
+
+          }
+      }).catch(() => {})
+    },
+     // 添加风场图形
+    addShapeWind(info) {
+            let side_color = info.side_color;
+            let inside_color=info.inside_color
+
+            var windOption = {
+                strokeColor: side_color,
+                strokeWeight: 2,
+                strokeOpacity: 0.3,
+            };
+            var windObj;
+            var that = this;
+            
+            if (info.wind_shape == 'circle') {
+                windObj = new BMap.Circle(info.wind_info.center, info.wind_info.radius, windOption)
+            } else if (info.wind_shape == 'polygon') {
+                windObj = new BMap.Polygon(info.wind_info, windOption)
+            }
+            windObj.setFillColor(inside_color);
+            windObj._infoData = info;
+
+            this.map.addOverlay(windObj)
+            // if(!this.isSetCenter){
+            //     if (info.wind_shape == 'circle') {
+            //         this.map.setViewport(windObj.getBounds(), {zoomFactor: -1});
+            //     } else if (info.wind_shape == 'polygon') {
+            //         this.map.setViewport(windObj._infoData.wind_info, {zoomFactor: -1})
+            //     }
+            //     this.isSetCenter=true
+            // }
+            // // 加入群组
+            // this.windGroup.push(windObj);
+
+            
+            
+        },
+    infoWindowClose () {
+      this.show = false
+    },
+    infoWindowOpen () {
+      this.show = true
+    },
+    addMarkerPoint(data) {
+      var myIcon;
+      this.pointObj=[]
+      Object.keys(data).forEach((k)=>{
+
+        let item=data[k]
+        var pt = new BMap.Point(item.longitude, item.latitude);
+        this.pointObj.push(pt)
+        myIcon = new BMap.Icon(this.markerIcons, new BMap.Size(32, 32));
+        myIcon.setImageSize(new BMap.Size(32, 32));
+        
+        var marker = new BMap.Marker(pt, {
+          icon: myIcon
+        }); // 创建标注
+      
+        let that=this
+        marker.addEventListener("click", function(){     
+          let content=that.createMarkerContent(item);
+          var opts = {
+            width : 320,     // 信息窗口宽度
+            enableAutoPan:false
+          }
+          var infoWindow = new BMap.InfoWindow(content,opts);  // 创建信息窗口对象      
+          this.map.openInfoWindow(infoWindow, pt); //开启信息窗口
+        });
+        this.map.addOverlay(marker);
+      })
+    },
+
+ 
+    showGpsRoute(val){
+      this.currentActiveRfid=val
+      this.gpsFormVisible=true
+    },
+    closeGpsDialog(){
+      this.gpsFormVisible=false
+    },
+    showUserInfo(val){
+      this.currentUserId=val
+      this.userFormVisible=true
+    },
+    closeUserDialog(){
+      this.userFormVisible=false
+    },
+   
+    addSingleMarker(data){
+        // 如果没有经纬度
+        if (!data.latitude || !data.longitude) {
+          this.$message.warning('暂无定位数据');
+          // return false;
+        }
+
+        var pt = new BMap.Point(data.longitude, data.latitude);
+        var opts = {
+            width : 320,     // 信息窗口宽度
+            enableAutoPan:false
+        }
+        let studentWindowContent=this.createMarkerContent(data)
+        var infoWindow = new BMap.InfoWindow(studentWindowContent,opts);  // 创建信息窗口对象 
+        this.map.openInfoWindow(infoWindow, pt); //开启信息窗口
+        this.map.centerAndZoom(pt,19);
+    },
+    createMarkerContent(data){
+      let address
+     
+        var myGeo = new BMap.Geocoder();      
+        // 根据坐标得到地址描述    
+        myGeo.getLocation(new BMap.Point(data.longitude,data.latitude), function(result){          
+            address=result.address
+            $('#marker_address').text(address);
+        });
+      
+        var content ='<div class="info_label">设备名称:测试设备</div>'
+        content +='<div class="info_label">设备编号:' + (data.number) + '</div>'
+        content += '<div class="info_label">定位地址:<a id="marker_address">' + address + '</a></div>' 
+
+        // content += '<div class="info_label">在线时间:'+data.online_time+'</div>'
+
+        content+='<div class="handle_btn info_label">'
+
+        content+='<button onclick="showGpsRoute(\''+data.number+'\')" class="el-button el-button--info el-button--small">历史定位</button>';
+
+        // content+='<button onclick="showUserInfo(\''+data.user_id+'\')" class="el-button el-button--info el-button--small">用户信息</button>'
+          
+        content+='</div>'
+          
+      return content
+    },
+    queryLocationList(){
+      const query = this.queryParam
+      this.$http.get("map/queryLocationList", { params: query }).then(response => {
+        if(response.data.length>0){
+          this.addMarkerPoint(response.data);
+          // this.map.setViewport(this.pointObj)
+          let center=response.data[0]
+          // 第一个学生没有轨迹则不设置中心点
+          if (!center.longitude || !center.latitude) {
+            return false;
+          }
+          this.center = new BMap.Point(center.longitude, center.latitude);
+        }
+      })
+    },
+   
+
+    startSearch(){
+      this.map.clearOverlays()
+      this.getList()
+      this.queryLocationList()
+    },
+    clickStudentRow(row, column, event){
+      this.addSingleMarker(row)
+    },
+    clickTab(tab) {
+      let name = tab.name;
+      // if (name == 'alarmList') {
+      //   this.url = 'map/queryAlarmList';
+      // } else 
+      if (name == 'deviceList') {
+        this.url = 'map/queryDeviceList';
+      }
+      this.handleRefresh();
+    },
+    
+},
+  
+};
+</script>
+
+<style lang="scss" scoped>
+.bm-view {
+  width: 100%;
+  // height: 100vh;
+  height: calc(100vh - 100px);
+}
+#searchbox {
+  border-radius: 2px;
+  width: 464px;
+  position: relative;
+  z-index: 5;
+  display: flex;
+}
+#searchbox #searchbox-container {
+  display: flex;
+  position: relative;
+  z-index: 2;
+  pointer-events: auto;
+  width: 250px;
+  float: left;
+  box-sizing: border-box;
+  
+}
+#sole-searchbox-content {
+  position: relative;
+}
+.searchbox-content {
+  width: 250px;
+  border-radius: 2px 0 0 2px;
+  background: #fff;
+}
+#sole-searchbox-content #sole-input,
+#searchType {
+  box-sizing: border-box;
+  border: 0;
+  padding: 9px 0;
+  border-left: 10px solid transparent;
+  border-right: 10px solid transparent;
+  line-height: 20px;
+  font-size: 14px;
+  height: 38px;
+  color: #333;
+  position: relative;
+  border-radius: 2px 0 0 2px;
+}
+#sole-input {
+  width: 250px;
+}
+#sole-input:focus {
+  outline: none;
+}
+#student-container{
+  width:240px;
+  height: 500px;
+  background-color: #fff;
+}
+
+.app-container {
+    height: calc(100vh - 102px);
+}
+::v-deep .el-dialog__body {
+        padding: 0;
+    }
+::v-deep .info_label{
+  padding-top:5px;
+  font-size: 14px;
+}
+::v-deep .handle_btn{
+  margin-top: 10px;
+}
+#search-button{
+  margin-left:1px;
+}
+</style>

+ 149 - 0
src/views/work_box_map/userInfoDialog.vue

@@ -0,0 +1,149 @@
+<template>
+  <el-dialog
+   :visible.sync="dialog"   
+    width="460px"
+   direction="rtl" 
+  >
+       <el-divider class="dialog-divider"></el-divider>
+      <div class="dialog-content">
+        <el-row class="dialog-row">
+          <div class="dialog-row-title">
+            用户信息
+          </div>
+          <div class="dialog-row-content">
+            <span class="content-row"> <span class="name-item"> 用户姓名: </span> <span>{{userInfo.realname}}</span> </span>
+            <span class="content-row"> <span class="name-item"> 用户角色: </span> <span>{{role_text}}</span> </span>
+            <span class="content-row"> <span class="name-item"> 手 机 号 : </span> <span>{{userInfo.phone}}</span> </span>
+            <span class="content-row"> <span class="name-item"> 身份证号: </span> <span>{{userInfo.idcard}}</span> </span>
+            <span class="content-row"> <span class="name-item"> 用户编号: </span> <span>{{userInfo.user_no}}</span> </span>
+          </div>
+        </el-row>
+
+      </div>
+    <el-divider class="dialog-divider"></el-divider>
+    <span slot="footer" class="dialog-footer">
+      <!-- <el-button @click="dialogVisible = false">取 消</el-button> -->
+      <el-button style="margin-left:20px" type="primary" @click="dialog = false">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+export default {
+  props: ["displayVisible","userId"],
+
+  components: {
+
+  },
+  created() {
+    // 初始化统计数据
+    // this.getChartData()
+  },
+  data() {
+    return {
+        title:'用户信息',
+        userInfo:{
+          realname:'',
+          phone:'',
+          idcard:'',
+          user_no:'',
+        },
+        role_text:'',
+     
+    };
+  },
+  computed: {
+    dialog: {
+      set(val) {
+        this.$emit("formCancel", val); // 表示将子组件改变的值传递给父组件
+      },
+      get() {
+        if (this.displayVisible) {
+        //   this.loading = true
+            if(this.userId && this.userId!=0){
+              this.$http.get("users/"+this.userId).then(response => {
+                this.role_text=response.data.roles[0].role_name
+                this.userInfo=response.data
+                // console.log(this.userInfo)
+              })
+            }
+            
+        }
+        // console.log(this.activeRfid)
+        
+        return this.displayVisible; // 表示获取父组件的值
+      }
+    }
+  },
+  mounted(){
+    
+  },
+
+  methods: {
+   
+    
+  }
+};
+</script>
+<style lang="scss" scoped>
+
+.el-drawer span:focus {
+  outline: none;
+}
+
+::v-deep .el-dialog{
+  min-width: 360px;
+}
+ .el-dialog__body{
+  padding: 0px!important;
+  /* padding-bottom: 0px!important; */
+}
+
+
+.dialog-divider{
+  margin:0px;
+  margin-top:10px;
+}
+.dialog-content{
+  padding: 5px;
+}
+
+.dialog-row{
+  display: flex;
+  flex-direction: column;
+  padding: 10px;
+  font-size: 12px;
+}
+.dialog-row-title{
+  margin-left: 20px;
+  margin-bottom: 10px;
+  font-size: 15px;
+  color: black;
+}
+.dialog-row-content{
+  margin-left: 50px;
+  display: flex;
+  flex-direction: column; 
+}
+.content-row{
+  margin-top: 5px;
+}
+.name-item{
+  width: 60px;
+  white-space:pre;
+  word-wrap: break-word;
+}
+.el-drawer__body{
+  max-height:100vh;
+  overflow: hidden;
+   overflow-y: auto;
+   width:100%;
+
+}
+.primary-btn{
+  color: #fff;
+  background-color: #409eff;
+  border-color: #98a9b9;
+  margin-left:5px;
+}
+</style>