Newer
Older
smartwell_front / src / views / home / operation / trajectory / detail.vue
liyaguang on 22 Jan 6 KB 临时提交
<!--
  Description: 设备轨迹展示详情
  Author: 李亚光
  Date: 2024-09-13
 -->
<script lang="ts" setup name="showDeviceTrajectory">
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import AMap from '@/components/map/index.vue'
import { shortcuts } from '@/utils/common'
import { getTrajectoryDetail } from '@/api/home/operation/trajectory'
const dialogFormVisible = ref(false) // 对话框是否显示
const locationArr = ref<string[]>([])
const mapRef = ref()
const info = ref<any>({})
// 地图是否加载完成
const completeMapFlag = ref(false)
const listQuery = ref({
  begTime: '',
  endTime: '',
})
// 开始结束时间
const datetimerange = ref()
watch(() => datetimerange.value, (newVal) => {
  listQuery.value.begTime = ''
  listQuery.value.endTime = ''
  if (Array.isArray(newVal)) {
    if (newVal.length) {
      listQuery.value.begTime = `${newVal[0]}`
      listQuery.value.endTime = `${newVal[1]}`
    }
  }
})
const loading = ref(true)
const fetchData = (row: any) => {
  if (!completeMapFlag.value) {
    return
  }
  loading.value = true
  getTrajectoryDetail({
    begTime: listQuery.value.begTime,
    endTime: listQuery.value.endTime,
    devCode: row.devcode,
  }).then((res) => {
    console.log(res.data)
    loading.value = false
    if (res.data.length === 1) {
      if (res.data[0].LONGITUDE_LATITUDE) {
        mapRef.value.addMarker({
          position: (row.startPosition || '').split(','),
          // position: [116.307719, 39.979882],
          // content: '<div class="icon-marker-dir icon-start"></div>',
          label: '',
          data: res.data[0] || {},
          // type: 'start',
          // offsetX: -14,
          // offsetY: -14,
        })
        mapRef.value.map.setFitView()
      }
      else {
        mapRef.value.removeMarker()
        ElMessage.warning('轨迹信息无效')
      }
      return
    }
    if (res.data.length >= 2) {
      res.data.unshift({
        ...res.data[0],
        ALARM_TIME: res.data[0]?.ALARM_TIME || '',
        LONGITUDE_LATITUDE: row.startPosition || '',
      })
      res.data.push({
        ...res.data[0],
        ALARM_TIME: res.data[res.data.length - 1]?.ALARM_TIME || '',
        LONGITUDE_LATITUDE: row.currentPosition || '',
      })
      // 绘制轨迹
      const trajectory = res.data.filter((item: any) => item.LONGITUDE_LATITUDE).map((item: any) => (item.LONGITUDE_LATITUDE || '').split(','))
      console.log(trajectory, 'trajectory')
      mapRef.value.addPolyline({
        // path: [[116.307719, 39.979882], [116.295562, 39.978876]],
        path: trajectory,
        style: {
          strokeColor: '#0D81F2',
          strokeOpacity: 1,
          strokeWeight: 3,
        },
      })
      mapRef.value.map.setFitView()
    }
    else {
      mapRef.value.removeMarker()
      mapRef.value.removePolyline()
      ElMessage.warning('轨迹信息无效')
      return
    }
    // 绘制起点终点,标记点
    mapRef.value.addMarker({
      position: (row.startPosition || '').split(','),
      // position: [116.307719, 39.979882],
      content: '<div class="icon-marker-dir icon-start">起</div>',
      label: '',
      data: res.data[0] || {},
      type: 'start',
      offsetX: -14,
      offsetY: -14,
    })
    mapRef.value.addMarker({
      position: (row.currentPosition || '').split(','),
      // position: [116.295562, 39.978876],
      content: '<div class="icon-marker-dir icon-end">终</div>',
      label: '',
      data: res.data[res.data.length - 1] || {},
      type: 'end',
      offsetX: -14,
      offsetY: -14,
    })
  }).catch(() => {
    loading.value = false
  })
}
// 初始化对话框
const initDialog = (row: any) => {
  locationArr.value = []
  datetimerange.value = datetimerange.value = [dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]
  info.value = row
  dialogFormVisible.value = true
  setTimeout(() => {
    fetchData(info.value)
  })
}
// 点击标记点
const markerClick = (data: any) => {
  var content = [
    `<div><b>${data.data.type === 'start' ? '起点' : data.data.type === 'end' ? '终点' : ''}</b>`,
    `<div>设备编号: ${data.data.data.DEVCODE}`,
    `位置: ${data.data.data.LONGITUDE_LATITUDE}`,
    `上传时间: ${data.data.data.ALARM_TIME} </div>`,
  ]
  const infoWindow = new mapRef.value.AMap.InfoWindow({
    content: content.join('<br>'), // 传入字符串拼接的 DOM 元素
  })
  setTimeout(() => {
    console.log(data.data, '1')
    console.log(data.data.data?.LONGITUDE_LATITUDE.split(','))
    infoWindow.open(data.map, data.data.data?.LONGITUDE_LATITUDE.split(',') || data.map.getCenter())
  })
}
const completeMap = () => {
  completeMapFlag.value = true
  if (!locationArr.value.length && info.value.devcode) {
    fetchData(info.value)
  }
}
defineExpose({
  initDialog,
})
const cancel = () => {
  dialogFormVisible.value = false
}
</script>

<template>
  <el-dialog v-model="dialogFormVisible" title="轨迹查看" append-to-body>
    <search-area @search="fetchData(info)">
      <search-item>
        <el-date-picker v-model="datetimerange" type="datetimerange" format="YYYY-MM-DD HH:mm:ss" :shortcuts="shortcuts"
          value-format="YYYY-MM-DD HH:mm:ss" range-separator="至" start-placeholder="上报开始时间" end-placeholder="上报结束时间"
          clearable />
      </search-item>
    </search-area>
    <div v-loading="loading" style="width: 100%;height: 300px;">
      <a-map v-if="dialogFormVisible" ref="mapRef" :show-pieple-layer="true" :zoom="14" @complete="completeMap"
        @markerClick="markerClick" />
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="cancel">
          确认
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.el-dialog {
  width: 700px;
}

.el-select {
  width: 100%;
}
</style>

<style lang="scss">
.icon-marker-dir {
  width: 28px;
  height: 28px;
  text-align: center;
  line-height: 28px;
  border-radius: 50%;
  color: #fff;
  transform: translate(-9.5px, -14px) scale(1) rotate(0deg);
  vertical-align: middle;
}

.icon-start {
  background-color: #3d93fd;
  border: 2px solid #0670f1;
}

.icon-end {
  background-color: #f34234;
  border: 2px solid #ff1303;
}
</style>