Newer
Older
rescue_front / src / views / car / listoverview.vue
[wangxitong] on 26 Mar 2022 22 KB first commit
<template>
  <app-container id="overview">
    <div id="map">
      <div v-if="bottombtn==='消防车'" slot="header" class="rightcard">
        <el-row>
          <el-col :span="3">
            <div style="font-size: 14px;padding-top: 10px;">在线:{{ online }}</div>
          </el-col>
          <el-col :span="3">
            <div style="font-size: 14px;padding-top: 10px">离线:{{ offline }}</div>
          </el-col>
          <el-col :span="3">
            <div style="font-size: 14px;padding-top: 10px;padding-left: 5px">刷新时间</div>
          </el-col>
          <el-col :span="9" 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="4" style="padding-top: 10px">
            <label style="font-size: 14px;padding-left: 5px;color: red">{{ sec }}</label>
            <label style="font-size: 14px">秒后刷新</label>
          </el-col>
          <el-col :span="2" style="padding-top: 4px;padding-left: 5px">
            <el-button type="primary" size="small" @click="fetchData(false)">立即刷新</el-button>
          </el-col>
        </el-row>
      </div>
      <div slot="header" class="table-title" @click="showtable=!showtable">
        <div class="table-name">
          {{ bottombtn }}列表
        </div>
        <i v-if="showtable==true" class="el-icon-arrow-down" style="position:absolute; right:20px;top:20px;margin-top:-8px;"/>
        <i v-if="showtable==false" class="el-icon-arrow-right" style="position:absolute; right:20px;top:20px;margin-top:-8px;"/>
      </div>
      <div v-if="showtable==true">
        <div v-if="bottombtn==='消防车'" class="search-bar">
          <el-input v-model.trim="listQuery.description" style="width: 180px;margin-right: 10px" placeholder="车辆描述" size="small" clearable/>
          <el-input v-model="listQuery.carCode" style="width: 180px;margin-right: 10px" placeholder="车牌号" size="small" clearable/>
          <el-button type="primary" size="small" style="height:32px" @click="search">搜索</el-button>
        </div>
        <el-table
          v-loading="listLoading"
          :row-style="{height: '35px'}"
          :cell-style="{padding: '0px'}"
          :header-cell-style="{background: '#ffffff'}"
          :data="list"
          max-height="300"
          class="table"
          border
          @row-dblclick="dbSelected"
          @selection-change="handleSelectionChange">
          <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-column v-if="bottombtn==='消防车'" label="更多" width="110" align="center">
            <template slot-scope="scope">
              <el-button type="text" size="mini" @click="track(scope.row.carId)">跟踪</el-button>
              <el-button type="text" size="mini" @click="trail(scope.row.carId,scope.row)">轨迹</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div class="pagination-container" style="width: 460px">
          <el-pagination
            v-show="total>listQuery.limit"
            :current-page="listQuery.offset"
            :page-sizes="[10,15,20,30]"
            :page-size="listQuery.limit"
            :total="total"
            class="table-bottom"
            page-count="5"
            small="true"
            align="center"
            layout="total, sizes, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"/>
        </div>
      </div>
      <div class="btn_bottom" style="margin-bottom: 10px">
        <div style="width: 252px;position: relative;margin: 0px auto;text-align: center">
          <el-radio-group v-model="bottombtn" @change="fetchData(false)">
            <el-radio-button label="消防车">
              <el-image :src="require('../../assets/global_images/car1.png')" fit="contain" style="width: 35px;height: 35px"/>
              <div>消防车</div>
            </el-radio-button>
            <el-radio-button label="井盖">
              <el-image :src="require('../../assets/global_images/wall.png')" fit="contain" style="width: 35px;height: 35px;" />
              <div>井盖</div>
            </el-radio-button>
            <el-radio-button label="消防栓">
              <el-image :src="require('../../assets/global_images/hydrant.png')" fit="contain" style="width: 35px;height: 35px;"/>
              <div>消防栓</div>
            </el-radio-button>
          </el-radio-group>
        </div>
      </div>
    </div>
  </app-container>
</template>
<script>
// import editCarInfo from '@/views/carinfo/editCarInfo'
import { getOverviewList, offlineCount, getOverviewAllList } from '@/api/overview'
import DeptSelect from '@/components/DeptSelect'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import 'leaflet-rotatedmarker/leaflet.rotatedMarker.js'
import { getWellList, watchDataByWell } from '@/api/well'
export default {
  name: 'ListOverview',
  components: { DeptSelect },
  data() {
    return {
      bottombtn: '消防车',
      dialogFormVisible: false, // 是否显示编辑框
      refresh: '30',
      showBase: false,
      online: 0,
      offline: 0,
      showtable: true,
      deptShow: true,
      listQuery: {
        description: '',
        wellType: '',
        carCode: '',
        carType: '',
        deptId: '',
        offset: 1,
        limit: 15
      }, // 查询条件
      listLoading: true, // 加载动画
      columns: [
        {
          text: '车辆描述',
          value: 'description',
          align: 'center'
        },
        {
          text: '车牌号',
          value: 'carCode',
          align: 'center',
          width: 90
        },
        {
          text: '状态',
          value: 'status',
          align: 'center',
          width: 70
        }
      ], // 动态加载的表头
      pointlayer: null,
      featurelayer: null,
      baselayer: [],
      baseUrl: '',
      mapUrl: '',
      list: [], // 列表数据
      alllist: [], // 列表数据
      map: null,
      initlocation: false,
      total: 0, // 数据总数
      sec: 10, // 数据总数
      // listLoading: true, // 加载动画
      fullscreenLoading: false, // 全屏加载动画
      deptlist: [] // 类型列表
    }
  },
  watch: {
    showBase(val) {
      if (val) this.map.addLayer(this.featurelayer)
      else this.map.removeLayer(this.featurelayer)
    },
    sec(val) {
      if (val === 0) {
        this.sec = Number(this.refresh)
        if (this.bottombtn === '消防车') {
          this.fetchData(true)
        }
      }
    }
  },
  mounted() {
    this.initMap()
    setInterval(() => {
      this.sec--
    }, 1000)
  },
  methods: {
    dbSelected(row) {
      this.map.setView({ lat: Number(row.lat), lng: Number(row.lng) }, 18)
    },
    // 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
        }
      })
    },
    async initMap() {
      const map = L.map('map', {
        minZoom: 3,
        maxZoom: 18,
        center: [27.75962, 116.06021],
        zoom: 16,
        zoomControl: false,
        attributionControl: false,
        crs: L.CRS.EPSG3857
      })
      map.doubleClickZoom.disable()
      this.map = map // data上需要挂载
      window.map = map
      var url = 'http://webrd0{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'
      this.baselayer.push(
        L.tileLayer(url, {
          subdomains: '1234'
        }).addTo(map))
      this.fetchData(false)
    },
    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。
        }
      }
    },
    fetchData(isNowPage = true) {
      this.listLoading = true
      this.list = []
      if (this.bottombtn === '消防车') {
        this.columns = [
          {
            text: '车辆描述',
            value: 'description',
            align: 'center'
          },
          {
            text: '车牌号',
            value: 'carCode',
            align: 'center',
            width: 90
          },
          {
            text: '状态',
            value: 'status',
            align: 'center',
            width: 70
          }
        ]
        offlineCount(this.listQuery).then(response => {
          this.online = response.data.online
          this.offline = response.data.offline
        })
        this.sec = Number(this.refresh)
        if (!isNowPage) {
          this.listQuery.offset = 1
        }
        getOverviewList(this.listQuery).then(response => {
          this.list = response.data.rows
          this.total = parseInt(response.data.total)
          this.listLoading = false
        })
        getOverviewAllList(this.listQuery).then(response => {
          this.alllist = response.data
          if (this.pointlayer !== null) this.map.removeLayer(this.pointlayer)
          this.pointlayer = new L.layerGroup().addTo(this.map)
          var list = []
          for (i = 0; i < this.alllist.length; i++) {
            if (Number(this.alllist[i].lat) === 0 && Number(this.alllist[i].lng) === 0) {
              continue
            }
            var item = [Number(this.alllist[i].lat), Number(this.alllist[i].lng)]
            list.push(item)
          }
          // if (list.length !== 0) {
          //   this.setZoom(list)
          // }
          var Icon
          for (var i = 0; i < this.alllist.length; i++) {
            if (i === 0 && !this.initlocation) {
              this.map.setView({ lat: this.alllist[0].lat, lng: this.alllist[0].lng }, 16)
              this.initlocation = true
            }
            if (this.alllist[i].status === '离线') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/car-offline.png'), // 灰
                iconSize: [40, 40]
              })
            } else if (this.alllist[i].status === '超时') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/car-timeout.png'), // 橙
                iconSize: [40, 40]
              })
            } else if (this.alllist[i].status === '停车') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/car-stop.png'), // 黄
                iconSize: [40, 40]
              })
            } else if (this.alllist[i].status === '行驶') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/car-online.png'), // 绿
                iconSize: [40, 40]
              })
            } else if (this.alllist[i].status === '报警') {
              Icon = L.icon({
                iconUrl: require('../../assets/global_images/car-alarm.png'), // 红
                iconSize: [40, 40]
              })
            }
            var myIcon = L.divIcon({
              html: '<div style="font-size: 13px;font-weight: bold;padding-top: 17px;text-align:center;"> ' + this.alllist[i].description + '</div>',
              className: '',
              iconSize: [100, 15]
            })
            L.marker([this.alllist[i].lat, this.alllist[i].lng], { icon: myIcon }).addTo(this.pointlayer)
            const { carId, description, carTypeName, deptName, status, lng, lat, upTime, speed, liquidValue } = this.alllist[i]
            var btndetail = 'btndetail' + carId
            var btntrack = 'btntrack' + carId
            var btntrail = 'btntrail' + carId
            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> ${description}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">类型</label> ${carTypeName}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">单位</label> ${deptName}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">状态</label> ${status}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">定位</label> ${lng} , ${lat}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">时间</label> ${upTime}</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">速度</label> ${speed} (km/h)</div>
            <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">液位值</label> ${liquidValue} </div>
            <!--<div style="padding-top: 8px"><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>-->
            <button style="padding-top: 8px;margin-right: 5px;margin-left: 5px;background-color: #409eff;border-color: #409eff;
            color: white;padding: 5px 8px;font-size: 12px;border-radius: 4px" id=${btntrack}>跟踪</button>
            <button style="background-color: #e6a23c;border-color: #e6a23c;color: white;padding: 5px 8px;font-size: 12px;border-radius: 4px" id=${btntrail}>轨迹</button></div></div>`
            var popup = L.popup().setContent(str)
            var marker = L.marker([this.alllist[i].lat, this.alllist[i].lng], {
              icon: Icon,
              slug: this.alllist[i],
              rotationAngle: this.alllist[i].direction,
              zIndexOffset: 100000
            }).addTo(this.pointlayer).bindPopup(popup)

            var that = this
            marker.on('click', function(e) {
              var carId = e.sourceTarget.options.slug.carId
              var btndetail = 'btndetail' + carId
              var btntrack = 'btntrack' + carId
              var btntrail = 'btntrail' + carId
              console.log('按钮:', document.getElementById(btndetail))
              // document.getElementById(btndetail).onclick = function() {
              //   console.log('carId:', e.sourceTarget.options.slug.carId)
              //   that.detail(e.sourceTarget.options.slug.carId)
              // }
              document.getElementById(btntrack).onclick = function() {
                that.track(e.sourceTarget.options.slug.carId)
              }
              document.getElementById(btntrail).onclick = function() {
                that.trail(e.sourceTarget.options.slug.carId, e.sourceTarget.options.slug)
              }
            })
          }
        })
      } else {
        this.inittable(this.bottombtn)
      }
    },
    inittable(type) {
      const that = this
      if (type === '井盖') {
        this.columns = [
          {
            text: '井盖编号',
            value: 'wellCode',
            align: 'center'
          }, {
            text: '井盖名称',
            value: 'wellName',
            align: 'center'
          },
          {
            text: '类型',
            value: 'wellTypeName',
            align: 'center',
            width: 90
          }
        ]
      } else if (type === '消防栓') {
        this.columns = [
          {
            text: '消防栓编号',
            value: 'wellCode',
            align: 'center'
          }, {
            text: '消防栓名称',
            value: 'wellName',
            align: 'center'
          },
          {
            text: '类型',
            value: 'wellTypeName',
            align: 'center',
            width: 70
          }
        ]
      }
      this.listQuery.wellType = type === '井盖' ? '1' : '2'
      getWellList(this.listQuery).then(response => {
        this.list = response.data.rows
        this.total = response.data.total
        this.listLoading = false
        if (this.pointlayer !== null) this.map.removeLayer(this.pointlayer)
        this.pointlayer = new L.layerGroup().addTo(this.map)
        var list = []
        for (i = 0; i < this.list.length; i++) {
          if (Number(this.list[i].latGaode) === 0 && Number(this.list[i].lngGaode) === 0) {
            continue
          }
          var item = [Number(this.list[i].latGaode), Number(this.list[i].lngGaode)]
          list.push(item)
        }
        if (list.length !== 0) {
          this.setZoom(list)
        }
        var Icon = L.icon({
          iconUrl: require('../../assets/global_images/' + type + '.png'),
          iconSize: [40, 40]
        })
        for (var i = 0; i < this.list.length; i++) {
          // if (i === 0 && !this.initlocation) {
          //   this.map.setView({ lat: this.list[0].lat, lng: this.list[0].lng }, 16)
          //   this.initlocation = true
          // }
          const { wellCode, wellName, position, bfztName, lngGaode, latGaode } = this.list[i]
          const str = `<div style="font-size: 15px;padding: 6px;width: 300px"> <div style="font-weight: bold;padding-bottom: 10px">${type}概要信息</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">编号</label> ${wellCode}</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">名称</label> ${wellName}</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">详细地址</label> ${position}</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">布防状态</label> ${bfztName}</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">定位</label> ${Number(lngGaode).toFixed(6)} , ${Number(latGaode).toFixed(6)}</div>
                <div style="padding-bottom: 6px"><label style="font-weight: bold;padding-right: 15px">设备监测值</label></div></div>`
          // const popup = L.popup().setContent(str)
          L.marker([this.list[i].latGaode, this.list[i].lngGaode], {
            id: this.list[i].id,
            icon: Icon,
            slug: str,
            rotationAngle: this.list[i].direction,
            zIndexOffset: 100000
          }).addTo(this.pointlayer)// .bindPopup(popup)
            .on('click', function(e) {
              console.log(e)
              watchDataByWell(e.target.options.id).then(response => {
                let content = e.sourceTarget.options.slug
                if (response.data.length !== 0) {
                  content = content.slice(0, content.length - 12) + response.data[0].data + content.slice(content.length - 12)
                }
                L.popup().setLatLng(e.latlng).setContent(content).openOn(that.map)// 通过popup添加点击弹出框
              })
            })
        }
      })
    },
    indexMethod(index) {
      return this.listQuery.limit * (this.listQuery.offset - 1) + index + 1
    },
    // 改变页容量
    handleSizeChange(val) {
      this.listQuery.limit = val
      this.fetchData(true)
    },
    // 改变当前页
    handleCurrentChange(val) {
      this.listQuery.offset = val
      this.fetchData(true)
    },
    // 多选触发方法
    handleSelectionChange(val) {
      this.multipleSelection = val
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  .rightcard{
    /*width: 750px;*/
    height: 40px;
    z-index: 10000;
    position: absolute;
    /*left:500px;*/
    top:10px;
    right: 0;
    background-color: #ffffff;
    padding-left: 20px;
    padding-right: 50px;
  }
  .table-bottom{
    position: relative;
    left: 11px;
    /*top: 20px;*/
    z-index: 10001;
    float: left;
    width: 458px;
    background-color: #ffffff;
    /* margin-top: 20px; */
    margin-top: 25px;
    padding-bottom: 10px;
  }
  .table-name{
    position:relative;
    width: 100px;
    color:#666666;
    top:20px;
    margin:-10px auto; //外面的div高度的一半
    z-index: 100001;
  }
  .table-title{
    font-size: 15px;
    text-align:center;
    width: 460px;
    height: 40px;
    background-color: #ffffff;
    z-index: 10000;
    position: absolute;
    left:10px;
    top:0px;
    font-weight: bold;
  }
  #map {
    width:100%;
    height: 90vh;
    /*border-top: 12px solid #ebebeb;*/
  }
  /deep/ .el-table--scrollable-y .el-table__body-wrapper{
    padding-bottom: 11px !important;
  }
  /deep/ .el-radio{
    margin-right: 5px;
  }
  /deep/ .el-radio__label{
    padding-left: 5px;
  }

  .table{
    width: 460px;
    z-index: 10000;
    position: relative;
    left:10px;
    top:40px;
  }
  .search-bar{
    width: 460px;
    z-index: 10000;
    position: relative;
    left:10px;
    top:40px;
    padding: 0px 10px;
    display: flex;
    height: 40px;
    background-color: white;
    z-index: 1000;
  }
  .btn_bottom{
    text-align:center;
    width: 100%;
    height:70px;
    z-index: 1000;
    position: fixed; bottom: 0; left: 0;right:0;
  }
</style>