<!-- 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() mapRef.value.map.setZoom(19) } 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() mapRef.value.map.setZoom(19) } 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 = [] if(row.createTime) { datetimerange.value = [`${dayjs(row.createTime).format('YYYY-MM-DD')} 00:00:00`, dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss')] } else { 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)" style="display: none;opacity: 0;"> <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 disabled /> </search-item> </search-area> <div v-loading="loading" style="width: 100%;height: 300px;"> <a-map v-if="dialogFormVisible" ref="mapRef" :show-pieple-layer="false" :zoom="19" @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>