devicesmgt/sgzb-ui/src/views/warehouseManage/machinery/coding/component/MapDIalog.vue

662 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- 地图弹框 展示设备轨迹 -->
<el-dialog
title="装备定位信息"
:visible.sync="dialogVisible"
width="90%"
@close="handelCloseDialog()"
>
<el-card shadow="hover">
<div class="device-title">
<h2>{{ deviceName }}</h2>
<span>({{ deviceType }})</span>
</div>
<div class="equipment"> 定位设备编号: {{ iotCode }} </div>
<div class="equipment" v-if="false">{{ engineering }}工程</div>
<el-row :gutter="24">
<el-col :span="16">
<el-date-picker
v-model="queryForm.date"
type="datetimerange"
range-separator="至"
start-placeholder="请选择开始日期"
end-placeholder="请选择结束日期"
value-format="yyyy-MM-dd HH:mm:ss"
@change="onChangeTime"
/>
<el-button
type="primary"
style="padding: 8px 16px; margin-left: 5px"
@click="handleQuery()"
>查询</el-button
>
</el-col>
</el-row>
</el-card>
<el-row :gutter="24" class="map-container">
<el-col :span="6" v-loading="loadingData">
<el-tabs type="border-card" class="map-left">
<el-tab-pane label="行程">
<template v-if="tripInfoListNew.length > 0">
<div
class="trip-container"
@click="handlePreviewTrip(item, index)"
v-for="(item, index) in tripInfoListNew"
:key="index"
>
<div class="left-num">{{ index + 1 }}</div>
<div
class="right-info"
:class="{
active: activeIndex === index,
}"
>
<!-- <ul>
<li>{{ item.tripdistance }}KM</li>
<li>{{ item.drivingDuration }}秒</li>
<li>{{ item.maxspeed }}KM/h</li>
<li>{{ item.averagespeed }}KM/h</li>
</ul>
<ul>
<li>里程</li>
<li>行驶时长</li>
<li>最大速度</li>
<li>平均速度</li>
</ul> -->
<div style="margin-top: 10px">
<div class="time-container">
<span class="radius-span"
>始</span
>
<span>{{
item.startTime
}}</span>
</div>
<h3>{{ item.startAddress }}</h3>
</div>
<div style="margin-top: 10px">
<div class="time-container">
<span
class="radius-span"
style="
background-color: #e6a23c;
"
>终</span
>
<span>{{ item.endTime }}</span>
</div>
<h3>{{ item.endAddress }}</h3>
</div>
</div>
</div>
</template>
<template v-else>
{{ loadingData ? '数据加载中...' : '暂无数据' }}
</template>
</el-tab-pane>
<el-tab-pane label="停留点">
<template v-if="parkList.length > 0">
<div
class="point-container"
v-for="(item, index) in parkList"
:key="index"
>
<div class="time-container">
<span class="radius-span">{{
index + 1
}}</span>
<span>{{ item.startTime }}</span>
<span
>{{ item.hours }}时{{
item.mints
}}分</span
>
</div>
<h3>{{ item.address }}</h3>
</div>
</template>
<template v-else> 暂无数据 </template>
</el-tab-pane>
<el-tab-pane label="报警">
<template v-if="warningList.length > 0">
<div
class="point-container"
v-for="(item, index) in warningList"
:key="index"
>
<div class="time-container">
<span class="radius-span">{{
index + 1
}}</span>
<span>{{ item.warnTime }}</span>
</div>
<h3>{{ item.startAlarm }}</h3>
</div>
</template>
<template v-else> 暂无数据 </template>
</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="18">
<!-- 地图 -->
<div
id="container"
style="height: 550px; background-color: #bfc"
></div>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import moment from 'moment'
import {
getIotDeviceLocationApi,
getIotDeviceTripApi,
getIotDeviceParkDetailApi,
getIotDeviceAlarmApi,
} from '@/api/iotDevice/index.js'
export default {
name: 'MapDialog',
props: {
// 设备名称
deviceName: {
type: String,
default: () => '',
},
// 设备状态
deviceType: {
type: String,
default: () => '',
},
// iot设备id
iotCode: {
type: String,
default: () => '',
},
},
data() {
return {
dialogVisible: true,
openMap: false, // 是否打开地图弹框
queryForm: {
date: [
moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss'),
moment().format('YYYY-MM-DD HH:mm:ss'),
],
},
equipment: '', // 设备名称
equipmentNumber: 'H906L', // 设备编号
engineering: '大禹治水', // 工程
map: null,
// 轨迹点
linePointList: [
{
lng: '',
lat: '',
},
{
lng: '',
lat: '',
},
],
count: 0,
trackAni: null, // 轨迹实例
calLon: '',
calLat: '',
// 查询设备行程信息的参数
tripParams: {
beginTime: moment()
.subtract(1, 'days')
.format('YYYY-MM-DD HH:mm:ss'),
endTime: moment().format('YYYY-MM-DD HH:mm:ss'),
iotId: '',
},
// 行程信息
tripList: [],
activeIndex: '',
// 停留点信息
parkList: [],
warningList: [],
loadingData: true,
tripInfoListNew: [], // 新行程信息
}
},
created() {},
mounted() {
Promise.all([this.getIotDeviceLocation(), this.handleQuery()])
.then((res) => {
this.loadingData = false
this.initMap()
})
.catch((err) => {
console.log(err)
this.loadingData = false
})
// this.getIotDeviceLocation()
},
beforeDestroy() {
/** 组件销毁之前 先清除地图实例 */
// 1. 判断轨迹实例是否存在 如果存在 先强制关闭动画,否则页面报错
if (this.trackAni) {
this.trackAni.cancel()
}
// 2. 清除地图上面的标点覆盖物 并清除地图实例
if (this.map) {
this.map.clearOverlays()
this.map.destroy()
this.map = null
}
},
methods: {
/** 获取当前设备的信息 */
async getIotDeviceLocation() {
if (this.iotCode) {
const { data: res } = await getIotDeviceLocationApi({
iotId: this.iotCode,
})
// 获取经纬度并赋值
this.calLon = res.callon || 116.404
this.calLat = res.callat || 39.915
}
},
/** 查询按钮 */
async handleQuery() {
if (!this.queryForm.date) {
this.$message.error('请选择时间范围!')
return
}
this.loadingData = true
this.tripParams.iotId = this.iotCode
// const res = await getIotDeviceTripApi({ ...this.tripParams })
// console.log(res, '行程信息--')
const resS = await getIotDeviceParkDetailApi({ ...this.tripParams })
const params = { ...this.tripParams }
params.beginTime = params.beginTime.slice(0, 10)
params.endTime = params.endTime.slice(0, 10)
const resSs = await getIotDeviceAlarmApi(params)
this.loadingData = false
this.warningList = resSs.data
this.warningList.forEach((e) => {
e.warnTime = moment(parseInt(e.startAlarmTime)).format(
'YYYY-MM-DD HH:mm:ss',
)
})
this.parkList = resS.data
this.parkList.forEach((e) => {
console.log(e, '----')
e.startTime = moment(parseInt(e.beginTime)).format(
'YYYY-MM-DD HH:mm:ss',
)
e.hours = parseInt(
(parseInt(e.endTime) - parseInt(e.beginTime)) /
1000 /
60 /
60,
)
e.mints = parseInt(
((parseInt(e.endTime) - parseInt(e.beginTime)) /
1000 /
60) %
60,
)
})
// 处理行程信息
this.tripInfoListNew = []
let tripInfoList = []
if (this.parkList.length > 1) {
this.parkList.forEach((e, index) => {
if (index < this.parkList.length - 1) {
let obj = {
startTime: e.startTime,
startAddress: e.address,
startLng: e.callon,
startLat: e.callat,
endLng: '',
endLat: '',
endTime: '',
endAddress: '',
}
tripInfoList.push(obj)
}
})
this.parkList.forEach((e, index) => {
if (index > 0) {
tripInfoList[index - 1].endTime = e.startTime
tripInfoList[index - 1].endAddress = e.address
tripInfoList[index - 1].endLng = e.callon
tripInfoList[index - 1].endLat = e.callat
}
})
}
this.tripInfoListNew = tripInfoList
// console.log(tripInfoList, '处理后的行程---')
// let tripInfo = JSON.parse(res.msg)
// console.log(tripInfo, '反序列化之后', this.parkList)
// let addressList = []
// if (tripInfo.addressmap) {
// addressList = Object.keys(tripInfo.addressmap)
// }
// tripInfo.totaltrips.forEach((e) => {
// e.startTime = moment(e.trackstarttime).format(
// 'YYYY-MM-DD HH:mm:ss',
// )
// e.endTime = moment(e.trackendtime).format('YYYY-MM-DD HH:mm:ss')
// e.drivingDuration = parseInt(
// (e.trackendtime - e.trackstarttime) / 1000,
// )
// addressList.forEach((v) => {
// if (v.indexOf(e.slat.toString().slice(0, 7)) > -1) {
// e.startAddress = tripInfo.addressmap[v]
// }
// if (v.indexOf(e.elat.toString().slice(0, 7)) > -1) {
// e.endAddress = tripInfo.addressmap[v]
// }
// })
// })
// this.tripList = tripInfo.totaltrips
// console.log(tripInfo, '处理之后-----')
},
/** 查看行程 */
handlePreviewTrip(item, index) {
this.activeIndex = index
if (this.trackAni) {
this.trackAni.cancel()
}
this.map.clearOverlays()
let pointList = []
this.linePointList[0].lng = item.startLng
this.linePointList[0].lat = item.startLat
this.linePointList[1].lng = item.endLng
this.linePointList[1].lat = item.endLat
if (this.linePointList.length === 0) return
for (var i = 0; i < this.linePointList.length; i++) {
pointList.push(
new BMapGL.Point(
this.linePointList[i].lng,
this.linePointList[i].lat,
),
)
}
// pointList.push(new BMapGL.Point(item.slon, item.slat))
// pointList.push(new BMapGL.Point(item.elon, item.elat))
let polyline = new BMapGL.Polyline(pointList)
// 修改线的样式
polyline.setStrokeColor('#EA3323') // 线颜色 #EA3323
// polyline.setStrokeWeight(2) // 线宽
this.trackAni = new BMapGLLib.TrackAnimation(this.map, polyline, {
overallView: true, // 动画完成后自动调整视野到总览
tilt: 55, // 轨迹播放的角度默认为55
duration: 1500, // 动画持续时长默认为10000单位ms
delay: 100, // 动画开始的延迟默认0单位ms
})
this.trackAni.start()
// 设置起点终点图标
this.triggerMovement()
},
// async handleQuery() {
// console.log('🚀 ~ handleQuery ~ 查询:', this.queryForm.date)
// const params = {
// date: this.queryForm.date,
// }
// this.getEquipmentInfo(params)
// // 先销毁地图 再重新初始化
// this.map.clearOverlays()
// this.map = null
// await this.initMap()
// },
openMapDialog(val) {
this.openMap = val
this.initMap()
},
// 获取装备信息
getEquipmentInfo(params = {}) {
console.log('🚀 ~ getEquipmentInfo ~ 获取装备信息', params)
// 接口(params).then(res => {
// this.equipment = res.equipment
// this.equipmentNumber = res.equipmentNumber
// this.engineering = res.engineering
// this.linePointList = res.linePointList
// })
},
// 初始化地图和轨迹
initMap() {
console.log('地图初始化--')
this.$nextTick(() => {
this.map = new BMapGL.Map('container') // 创建地图实例
// let point = new BMapGL.Point(117.13805, 31.8734) // 创建点坐标
let point = new BMapGL.Point(this.calLon, this.calLat) // 创建点坐标
this.map.centerAndZoom(point, 15) // 初始化地图,设置中心点坐标和地图级别
this.map.enableScrollWheelZoom(true) // 启用滚轮放大缩小
this.map.setHeading(64.5) //设置地图旋转角度
this.map.setTilt(73) //设置地图的倾斜角度
let marker = new BMapGL.Marker(point) // 创建标点
this.map.addOverlay(marker)
var myGeo = new BMapGL.Geocoder()
// 根据坐标得到地址描述
// myGeo.getLocation(new BMapGL.Point(this.calLon, this.calLat))
// this.map.getLocation(point, (res) => {
// console.log(res, '所在位置--')
// })
})
},
// 添加起点和终点的标记
addStartEndMarkers(startLatLng, endLatLng) {
let startIcon = new BMapGL.Icon(
require('/src/assets/images/startIcon.png'),
new BMapGL.Size(32, 32),
)
let startMarker = new BMapGL.Marker(startLatLng, {
icon: startIcon,
})
this.map.addOverlay(startMarker)
let endIcon = new BMapGL.Icon(
require('/src/assets/images/endIcon.png'),
new BMapGL.Size(32, 32),
)
let endMarker = new BMapGL.Marker(endLatLng, { icon: endIcon })
this.map.addOverlay(endMarker)
},
// 轨迹运动结束后的回调
triggerMovement() {
// 轨迹运动结束后获取起点和终点的经纬度坐标
let startLatLng = new BMapGL.Point(
this.linePointList[0].lng,
this.linePointList[0].lat,
)
let endLatLng = new BMapGL.Point(
this.linePointList[this.linePointList.length - 1].lng,
this.linePointList[this.linePointList.length - 1].lat,
)
// 添加起点和终点的图标
this.addStartEndMarkers(startLatLng, endLatLng)
},
/** 关闭地图弹框 */
handelCloseDialog() {
this.$emit('handelCloseDialog')
},
/** 时间选择器 */
onChangeTime(val) {
if (val) {
this.tripParams.beginTime = val[0]
this.tripParams.endTime = val[1]
}
},
},
}
</script>
<style lang="scss" scoped>
.device-title {
display: flex;
h2 {
padding: 0;
margin: 0;
font-weight: bold;
}
span {
padding: 4px 0 0 6px;
color: rgb(9, 193, 9);
}
}
.equipment {
margin: 8px 0;
font-weight: 600;
font-size: 15px;
}
.map-container {
margin-top: 8px;
.map-left {
height: 550px;
}
}
::v-deep .el-tabs__nav {
width: 100%;
display: flex;
.el-tabs__item {
flex: 1;
text-align: center;
}
}
::v-deep .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
color: #fff;
background-color: #1890ff;
}
::v-deep .el-tabs--border-card > .el-tabs__content {
padding: 0;
height: 510px;
overflow: auto;
}
::v-deep .el-dialog__body {
padding: 5px 20px;
}
.trip-container {
display: flex;
margin-bottom: 3px;
cursor: pointer;
border-bottom: 1px solid #ccc;
.left-num {
width: 16px;
display: flex;
align-items: center;
justify-content: center;
background-color: #e7f3ff;
}
.right-info {
flex: 1;
padding: 8px;
ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
align-items: center;
li {
flex: 1;
text-align: center;
}
&:first-child li {
color: #409eff;
}
}
.time-container {
padding-left: 15px;
span {
display: inline-block;
height: 20px;
line-height: 20px;
}
}
}
.active {
background-color: #e8eaed;
}
}
h3 {
padding: 0 0 0 15px;
margin: 5px 0 0 0;
font-size: 16px;
color: #000;
}
.radius-span {
margin-right: 3px;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
border-radius: 15px;
background-color: #409eff;
color: #fff;
}
.point-container {
margin: 2px;
padding: 8px;
border: 1px solid #ccc;
border-radius: 3px;
.time-container {
display: flex;
justify-content: space-between;
align-items: center;
}
.time-container span:nth-child(2) {
flex: 1;
margin-left: 5px;
}
h3 {
padding-left: 0;
}
}
</style>