Newer
Older
smartcity_video / src / views / overview / listoverview.vue
dutingting on 7 Dec 20 KB 历史视频层级问题
<template>
  <div id="overview" class="app-container">
    <!--筛选条件-->
    <div class="search-div">
      <el-form ref="selectForm" :inline="true" :model="listQuery" class="form-container">
        <el-form-item class="selectForm-container-item" prop="remarks">
          <el-input v-model.trim="listQuery.remarks" placeholder="设备描述" clearable/>
        </el-form-item>
        <el-form-item class="selectForm-container-item" prop="ip">
          <el-input v-model="listQuery.ip" placeholder="ip" clearable/>
        </el-form-item>
        <el-form-item class="selectForm-container-item" prop="devType">
          <el-select v-model="listQuery.devType" filterable placeholder="设备类型" clearable value="" @change="fetchData()">
            <el-option
              v-for="item in cartypelist"
              :key="item.value"
              :label="item.name"
              :value="item.value"/>
          </el-select>
        </el-form-item>
        <!-- <el-form-item class="selectForm-container-item" prop="keywords">
          <dept-select v-model="listQuery.deptId" :dept-show="deptShow" placeholder="使用单位" clearable value=""/>
        </el-form-item> -->

        <el-button class="filter-item" type="primary" icon="el-icon-search" @click="search">查 询</el-button>
      </el-form>
    </div>
    <div id="map" style="height: calc(100vh - 120px)">
      <video-com v-if="showVideo" :device-info="deviceInfo" ref="videoRef" style="position: absolute;top: 0px;z-index: 9999999; right: 0px;background-color: rgba(238, 238, 238, 0.93);"/>
      <!--查询结果Table显示-->
      <!-- <div slot="header" class="rightcard" >
        <el-row>
          <el-col :span="4">
            <div style="font-size: 14px;padding-top: 10px;padding-left: 20px">在线:{{ online }}</div>
          </el-col>
          <el-col :span="3">
            <div style="font-size: 14px;padding-top: 10px">离线:{{ offline }}</div>
          </el-col>
          <el-col :span="2">
            <div style="font-size: 14px;padding-top: 10px;padding-left: 5px">刷新时间</div>
          </el-col>
          <el-col :span="8" style="padding-top: 12px;padding-left: 10px">
            <el-radio-group v-model="refresh" @change="clicktime">
              <el-radio label="10">10秒</el-radio>
              <el-radio label="30">30秒</el-radio>
              <el-radio label="60">60秒</el-radio>
            </el-radio-group>
          </el-col>
          <el-col :span="3" style="padding-top: 4px;padding-left: 8px">
            <el-button type="primary" size="small" @click="fetchData">立即刷新</el-button>
          </el-col>
          <el-col :span="3" style="padding-top: 10px">
            <label style="font-size: 14px;padding-left: 10px;color: red">{{ sec }}</label>
            <label style="font-size: 14px">秒后刷新</label>
          </el-col>
        </el-row>

      </div> -->
      <div style="position: absolute;bottom: 10px;z-index: 9999999; left: 20px;background-color: rgba(238, 238, 238, 0.93);width: 300px;">
        <el-row>
          <el-col :span="12">
            <div style="font-size: 14px;padding-top: 10px;padding-left: 20px;display: flex;align-items: center;">
              <img src="../../assets/global_images/on.png" style="width: 30px;height: 30px;;">
              <span>在线:{{ online }}</span>
            </div>
          </el-col>
          <el-col :span="12">
            <div style="font-size: 14px;padding-top: 10px;display: flex;align-items: center;">
              <img src="../../assets/global_images/off.png" style="width: 30px;height: 30px;;">
              <span>离线:{{ offline }}</span>
            </div>
          </el-col>
          </el-row>
      </div>
      <div slot="header" class="table-title" @click="tableclick">
        <div class="table-name" style="color: white">
          设备列表
        </div>
        <i v-if="showtable==true" class="el-icon-arrow-down" style="position:absolute; left:20px;top:20px;margin-top:-8px;color: white"/>
        <i v-if="showtable==false" class="el-icon-arrow-right" style="position:absolute; left:20px;top:20px;margin-top:-8px;color: white"/>
      </div>
      <div style="position: relative;display: block;">
        <el-table v-if="showtable==true" :row-style="{height: '25px'}" :cell-style="{padding: '0px'}" :data="list" class="table" border @row-dblclick="dbSelected" >
        <el-table-column :index="indexMethod" align="center" type="index" label="序号" width="55"/>
        <el-table-column v-for="column in columns" :key="column.value" :label="column.text" :width="column.width" :align="column.align" show-overflow-tooltip>
          <template slot-scope="scope">
            <span :class="column.class">{{ scope.row[column.value] }}</span>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
            v-show="total && showtable"
            :current-page="listQuery.offset"
            :page-sizes="[15,20,30]"
            :page-size="listQuery.limit"
            :total="total"
            class="pagination-container"
            align="center"
            layout="total, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"/>
      </div>
    </div>
<!--    <edit-car-info v-show="dialogFormVisible" ref="editCarInfo" @watchChild="fetchData"/>-->
  </div>
</template>
<script>
// import editCarInfo from '@/views/carinfo/editCarInfo'
import { getOverviewList, getOverviewAllList } from '@/api/overview'
import { offlineCount } from '@/api/device'
import { getDictByCode } from '@/api/system/dict'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import 'leaflet-rotatedmarker/leaflet.rotatedMarker.js'
import { getDeviceListPage, getDeviceList } from '@/api/device'
import VideoCom from './video.vue'
export default {
  name: 'ListOverview',
  components: { VideoCom },
  data() {
    return {
      deviceInfo: {},
      dialogFormVisible: false, // 是否显示编辑框
      refresh: '30',
      online: 0,
      offline: 0,
      showtable: true,
      deptShow: true,
      listQuery: {
        remarks: '',
        ip: '',
        devType: '',
        // deptId: '',
        offset: 1,
        limit: 15
      }, // 查询条件
      columns: [
        {
          text: '设备名称',
          value: 'devName' || 'description',
          align: 'center'
        },
        {
          text: '设备ip',
          value: 'ip' || 'carCode',
          align: 'center'
        },
        {
          text: '状态',
          value: 'statusName' || 'status',
          align: 'center',
          width: 70
        }
      ], // 动态加载的表头
      TianDiTu: {
        Normal: {
          Map: 'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
          Annotion: 'https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8'
        },
        Satellite: {
          Map: 'https://t{s}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
          Annotion: 'https://t{s}.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8'
        },
        Terrain: {
          Map: 'https://t{s}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
          Annotion: 'https://t{s}.tianditu.gov.cn/cta_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cta&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8'
        },
        Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      },
      baselayer: [],
      list: [], // 列表数据
      alllist: [], // 列表数据
      map: null,
      total: 0, // 数据总数
      sec: 10, // 数据总数
      // listLoading: true, // 加载动画
      fullscreenLoading: false, // 全屏加载动画
      cartypelist: [], // 类型列表
      deptlist: [], // 类型列表
      showVideo: false // 是否显示视频组件
    }
  },
  watch: {
    sec(val) {
      if (val === 0) {
        this.sec = Number(this.refresh)
        // 隐藏自动刷新
        // this.fetchData()
      }
    }
  },
  mounted() {
    getDictByCode('deviceType').then(response => {
      this.cartypelist = response.data
    })
    this.initMap()
    this.fetchData()
    setInterval(() => {
      this.sec--
    }, 1000)
  },
  methods: {
    dbSelected(row) {
      this.map.setView({ lat: Number(row.latitude), lng: Number(row.longitude) }, 18)
    },
    tableclick() {
      this.showtable = !this.showtable
    },
    detail(id) {
      this.dialogFormVisible = true
      var item = { id: id }
      this.$refs.editCarInfo.initDialog('detail', this.dialogFormVisible, item)
    },
    track(id) {
      this.$router.push({
        name: 'Track',
        query: {
          id: id
        }
      })
    },
    trail(id, row) {
      this.$router.push({
        name: 'Trail',
        query: {
          id: id,
          name: row.carCode + '-' + row.carTypeName
        }
      })
    },
    initMap() {
      const map = L.map('map', {
        minZoom: 3,
        maxZoom: 16,
        center: [27.75962, 116.06021],
        zoom: 18,
        zoomControl: false,
        attributionControl: false,
        crs: L.CRS.EPSG3857
      })
      map.doubleClickZoom.disable()
      this.map = map // data上需要挂载
      window.map = map
      this.baselayer.push(L.tileLayer(
        'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
        { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] }
      ).addTo(map))
      this.baselayer.push(L.tileLayer(
        'https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=216ee92889e17ab1b083fae665d522b8',
        { subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'] }
      ).addTo(map))
    },
    search() {
      this.fetchData(false)
    },
    clicktime() {
      this.sec = Number(this.refresh)
    },
    setZoom(points) {
      // console.log(points)
      if (points.length > 0) {
        var maxLng = points[0][1]
        var minLng = points[0][1]
        var maxLat = points[0][0]
        var minLat = points[0][0]
        var res
        for (var i = points.length - 1; i >= 0; i--) {
          res = points[i]
          if (res[1] > maxLng) maxLng = res[1]
          if (res[1] < minLng) minLng = res[1]
          if (res[0] > maxLat) maxLat = res[0]
          if (res[0] < minLat) minLat = res[0]
        }
        var cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2
        var cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2
        var zoom = this.getZoom(maxLng, minLng, maxLat, minLat)
        this.map.setView({ lat: cenLat, lng: cenLng }, zoom)
      } else {
        // 没有坐标,显示全中国
        this.map.setView({ lat: 103.388611, lng: 35.563611 }, 5)
      }
    },
    getZoom(maxLng, minLng, maxLat, minLat) {
      var zoom = ['50', '100', '200', '500', '1000', '2000', '5000', '10000', '20000', '25000', '50000', '100000', '200000', '500000', '1000000', '2000000']// 级别18到3。
      var latlng = L.latLng(maxLat, maxLng)
      var distance = latlng.distanceTo(L.latLng(minLat, minLng))
      // var distance = pointA.distanceTo(pointB)// 获取两点距离,保留小数点后两位
      for (var i = 0, zoomLen = zoom.length; i < zoomLen; i++) {
        if (zoom[i] - distance > 0) {
          return 18 - i + 2 // 之所以会多2,是因为地图范围常常是比例尺距离的10倍以上。所以级别会增加3。
        }
      }
    },
    setCenter(points) {
      // 获取折线中心点坐标
      if (points.length > 0) {
        let maxLng = points[0][1]
        let minLng = points[0][1]
        let maxLat = points[0][0]
        let minLat = points[0][0]
        let res
        for (let i = points.length - 1; i >= 0; i--) {
          res = points[i]
          if (res[1] > maxLng) maxLng = res[1]
          if (res[1] < minLng) minLng = res[1]
          if (res[0] > maxLat) maxLat = res[0]
          if (res[0] < minLat) minLat = res[0]
        }
        const cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2
        const cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2

        this.map.setView({ lat: cenLat, lng: cenLng })
      }
    },
    fetchData(isNowPage = true) {
      this.listLoading = true
      if (!isNowPage) { // 是否显示当前页,否则跳转第一页
        this.listQuery.offset = 1
      }

      offlineCount(this.listQuery).then(response => {
        this.online = response.data.online
        this.offline = response.data.offline
      })

      getDeviceListPage(this.listQuery).then(response => {
        if (response.code === 200) {
          this.list = response.data.rows
          this.total = parseInt(response.data.total)
          this.listLoading = false
        }
      })

      const { remarks, ip, devType } = this.listQuery;
      getDeviceList({ remarks, ip, devType }).then(response =>{
        if (response.code === 200) {
          this.alllist = response.data
          console.log(this.alllist)
          var base = this.baselayer
          this.map.eachLayer(function(layer) {
            if (layer !== base[0] && layer !== base[1]) {
              layer.remove()
            }
          })
          var list = []
          for (i = 0; i < this.alllist.length; i++) {
            if (Number(this.alllist[i].latitude) === 0 && Number(this.alllist[i].longitude) === 0) {
              continue
            }
            var item = [Number(this.alllist[i].latitude), Number(this.alllist[i].longitude)]
            list.push(item)
          }
          // if (list.length !== 0) {
          //   this.setZoom(list)
          // }

          var Icon
          for (var i = 0; i < this.alllist.length; i++) {
            if (this.alllist[i].statusName === '在线') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/on.png'),
                iconSize: [30, 30]
              })
            } else if (this.alllist[i].statusName === '离线') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/off.png'),
                iconSize: [30, 30]
              })
            }
            var myIcon = L.divIcon({
              // html: '<div style="font-size: 13px;font-weight: bold;padding-top: 17px;text-align:center;"> ' + this.alllist[i].devCode + '_' + this.alllist[i].remarks + '</div>',
              html: '<div style="font-size: 13px;font-weight: bold;padding-top: 17px;text-align:center;"> ' + this.alllist[i].remarks + '</div>',
              className: '',
              iconSize: [100, 15]
            })
            L.marker([this.alllist[i].latitude, this.alllist[i].longitude], { icon: myIcon }).addTo(this.map)
            var str = '<div style="font-size: 15px;padding: 6px"> <div style="font-weight: bold;padding-bottom: 10px">设备位置概要信息</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备号</label>' + this.alllist[i].devCode + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备名称</label>' + this.alllist[i].devName + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备ip</label>' + this.alllist[i].ip + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备类型</label>' + this.alllist[i].devTypeName + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备状态</label>' + this.alllist[i].statusName + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备经纬度</label>' + this.alllist[i].longitude + ' , ' + this.alllist[i].latitude + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">安装时间</label>' + this.alllist[i].installTime + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">详细位置</label>' + this.alllist[i].detailLocation + '</div>' +
              '<div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">备注</label>' + this.alllist[i].remarks + '</div>' +
              '<div style="padding-top: 8px"></div></div>' +
            '<button style="cursor:pointer;margin-left: 50px;background-color: #409eff;border-color: #409eff;color: white;padding: 5px 8px;font-size: 12px;border-radius: 4px" id="buttonVideo">播放视频</button>' +
            '<button style="cursor:pointer;margin-left: 80px;background-color: #909399;border-color: #909399;color: white;padding: 5px 8px;font-size: 12px;border-radius: 4px" id="buttonCancle">关闭视频</button>'
            // '<button style="margin-left: 80px;background-color: #42b983;border-color: #42b983;color: white;padding: 5px 8px;font-size: 12px;border-radius: 4px" id="btndetail">详情</button>'
            var popup = L.popup().setContent(str)
            var marker = L.marker([this.alllist[i].latitude, this.alllist[i].longitude], {
              icon: Icon,
              slug: this.alllist[i],
              // rotationAngle: this.alllist[i].direction,
              zIndexOffset: 100000
            }).addTo(this.map).bindPopup(popup)
            var that = this
            marker.on('click', function(e) {
              // document.getElementById('btndetail').onclick = function() {
              //   console.log('详情', e.sourceTarget.options);
              //   // that.detail(e.sourceTarget.options.slug.carId)
              // }
              console.log('marker click', e.sourceTarget.options.slug)
              document.getElementById('buttonVideo').onclick = function() {
                // that.detail(e.sourceTarget.options.slug.carId)
                that.showVideo = true
                that.deviceInfo = e.sourceTarget.options.slug
                console.log('父组件设备信息', that.deviceInfo)
              }

              document.getElementById('buttonCancle').onclick = function() {
                console.log('关闭')
                that.showVideo = false
              }
            })
          }
        }
      })
    },
    indexMethod(index) {
      return this.listQuery.limit * (this.listQuery.offset - 1) + index + 1
    },
    // 改变页容量
    handleSizeChange(val) {
      this.listQuery.limit = val
      this.fetchData()
    },
    // 改变当前页
    handleCurrentChange(val) {
      this.listQuery.offset = val
      this.fetchData()
    },
    // 多选触发方法
    handleSelectionChange(val) {
      this.multipleSelection = val
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" >
  .el-table__header tr,
  .el-table__header th {
    padding: 0;
    height: 40px;
    background-color: #f8f8f8;
  }
  .table{
    margin-bottom: 20px;
  }

</style>
<style rel="stylesheet/scss" lang="scss" scoped>
  .pagination-container{
    width: 460px;
    position: absolute;
    top: 579px;
    left: 20px;
    z-index: 100001;
  }
  .table{
    width: 460px;
    height: 560px;
    z-index: 10000;
    margin-top: 40px;
    position: absolute;
    left:20px;
    top:10px;
    overflow: auto
  }
  .rightcard{
    width: 750px;
    height: 40px;
    z-index: 10000;
    position: absolute;
    left:500px;
    top:10px;
    background-color: rgba(238, 238, 238, 0.93);
  }
  .table-bottom{
    position: absolute;
    left: 120px;
    top:700px;
    z-index: 10001;
  }
  .table-name{
    position:relative;
    width: 100px;
    top:20px;
    margin:-10px auto; //外面的div高度的一半
    z-index: 100001;
  }
  .table-title{
    font-size: 15px;
    text-align:center;
    width: 460px;
    height: 40px;
    background-color: #409eff;
    z-index: 10000;
    position: absolute;
    left:20px;
    top:10px;
  }
  #map {
    width:100%;
    height:82vh;
  }
  .el-form-item {
    margin-bottom:5px;
  }
</style>