269 lines
9.4 KiB
Vue
269 lines
9.4 KiB
Vue
|
|
<template>
|
|||
|
|
<el-dialog title="查看运动轨迹" v-model="data.dialogVisible" :before-close="handleClose" style="width: 700px; padding-bottom: 20px">
|
|||
|
|
<el-form ref="formDataRef" :inline="true" :model="formData" class="demo-form-inline">
|
|||
|
|
<el-form-item label="日期">
|
|||
|
|
<!-- <el-date-picker
|
|||
|
|
v-model="formData.time"
|
|||
|
|
type="date"
|
|||
|
|
format="YYYY-MM-DD"
|
|||
|
|
value-format="YYYY-MM-DD"
|
|||
|
|
placeholder="请选择日期"
|
|||
|
|
:disabled-date="disabledDate"
|
|||
|
|
></el-date-picker> -->
|
|||
|
|
<el-date-picker
|
|||
|
|
v-model="formData.time"
|
|||
|
|
type="datetimerange"
|
|||
|
|
format="YYYY-MM-DD HH:mm:ss"
|
|||
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|||
|
|
placeholder="请选择日期"
|
|||
|
|
:disabled-date="disabledDate"
|
|||
|
|
@change="dateChange"
|
|||
|
|
></el-date-picker>
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-form-item>
|
|||
|
|
<el-button type="primary" @click="getPath">查询</el-button>
|
|||
|
|
<el-button type="warning" @click="playPoints" :disabled="!data.mapShow">{{ data.play ? '暂停' : '播放' }}</el-button>
|
|||
|
|
</el-form-item>
|
|||
|
|
</el-form>
|
|||
|
|
<div
|
|||
|
|
v-loading="data.trackLoading"
|
|||
|
|
element-loading-text="正在加载中..."
|
|||
|
|
style="height: 500px"
|
|||
|
|
element-loading-background="rgba(255, 255, 255,1)"
|
|||
|
|
>
|
|||
|
|
<div class="empty-box" v-if="data.noTrack">
|
|||
|
|
<img style="width: 50%" src="../../assets/images/wuguiji.png" />
|
|||
|
|
</div>
|
|||
|
|
<baidu-map
|
|||
|
|
class="map"
|
|||
|
|
@ready="handler"
|
|||
|
|
:center="data.centerPoint"
|
|||
|
|
:zoom="data.zoom"
|
|||
|
|
:dragging="true"
|
|||
|
|
:auto-resize="true"
|
|||
|
|
:scroll-wheel-zoom="true"
|
|||
|
|
style="height: 500px"
|
|||
|
|
v-if="data.mapShow"
|
|||
|
|
>
|
|||
|
|
<!-- 运行轨迹的路线 stroke-weight边线的宽度stroke-opacity边线透明度-->
|
|||
|
|
<bm-polyline stroke-color="blue" :path="data.path" :stroke-opacity="0.5" :stroke-weight="3" :editing="false"></bm-polyline>
|
|||
|
|
<!-- marker 可以展示的图标 起点、终点 -->
|
|||
|
|
<bm-marker :icon="startMarkIcon" :position="{ lng: data.startMark.lng, lat: data.startMark.lat }"></bm-marker>
|
|||
|
|
<bm-marker :icon="endMarkIcon" :position="{ lng: data.endMark.lng, lat: data.endMark.lat }"></bm-marker>
|
|||
|
|
<bm-marker
|
|||
|
|
v-for="(item, index) in data.path"
|
|||
|
|
:key="index"
|
|||
|
|
:icon="biaoMarkIcon"
|
|||
|
|
:position="{ lng: item.lng, lat: item.lat }"
|
|||
|
|
></bm-marker>
|
|||
|
|
<!-- 暂停是根据你提供的坐标,如果还没过第一个,就会返回,如果过了,在第一个到第二个之间暂停,他会跑掉第二个后面 -->
|
|||
|
|
<bml-lushu @stop="reset" :path="data.path" :icon="iconss" :play="data.play" :rotation="true" :speed="900"></bml-lushu>
|
|||
|
|
</baidu-map>
|
|||
|
|
</div>
|
|||
|
|
<template #footer>
|
|||
|
|
<div class="dialog-footer">
|
|||
|
|
<el-button @click="handleClose">取消</el-button>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
</el-dialog>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, reactive, onMounted } from 'vue';
|
|||
|
|
import { BmlLushu } from 'vue-baidu-map-3x';
|
|||
|
|
import { collarTrack, collarTrackOrder } from '~/api/hardware.js';
|
|||
|
|
import startIcon from '../../assets/images/qi.png';
|
|||
|
|
import endIcon from '../../assets/images/zhong.png';
|
|||
|
|
import biaoIcon from '../../assets/images/biaozhu.png';
|
|||
|
|
import goIcon from '../../assets/images/yuan.png';
|
|||
|
|
|
|||
|
|
const formDataRef = ref(null);
|
|||
|
|
const data = reactive({
|
|||
|
|
dialogVisible: false,
|
|||
|
|
play: false, // 是否自动播放轨迹动画
|
|||
|
|
zoom: 15,
|
|||
|
|
path: [],
|
|||
|
|
centerPoint: { lng: 116.404, lat: 39.915 },
|
|||
|
|
startMark: { lng: 116.404, lat: 39.915 },
|
|||
|
|
endMark: { lng: 116.404, lat: 116.404 },
|
|||
|
|
trackLoading: false,
|
|||
|
|
noTrack: false,
|
|||
|
|
mapShow: false,
|
|||
|
|
type: '',
|
|||
|
|
});
|
|||
|
|
const formData = reactive({
|
|||
|
|
time: '',
|
|||
|
|
});
|
|||
|
|
const handleClose = () => {
|
|||
|
|
data.dialogVisible = false;
|
|||
|
|
};
|
|||
|
|
// 查询当前时间
|
|||
|
|
const getNowDate = () => {
|
|||
|
|
const year = new Date().getFullYear();
|
|||
|
|
let month = new Date().getMonth() + 1;
|
|||
|
|
let day = new Date().getDate();
|
|||
|
|
let hours = new Date().getHours();
|
|||
|
|
let minutes = new Date().getMinutes();
|
|||
|
|
let seconds = new Date().getSeconds();
|
|||
|
|
month = month < 10 ? `0${month}` : month;
|
|||
|
|
day = day < 10 ? `0${day}` : day;
|
|||
|
|
hours = hours < 10 ? `0${hours}` : hours;
|
|||
|
|
minutes = minutes < 10 ? `0${minutes}` : minutes;
|
|||
|
|
seconds = seconds < 10 ? `0${seconds}` : seconds;
|
|||
|
|
// formData.time = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
|
|||
|
|
formData.time = [`${year}-${month}-${day} ` + `00` + `:` + `00` + `:` + `00`, `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`];
|
|||
|
|
};
|
|||
|
|
// 禁用今天之后的日期
|
|||
|
|
const disabledDate = (time) => {
|
|||
|
|
return time.getTime() > Date.now();
|
|||
|
|
};
|
|||
|
|
const dateChange = () => {
|
|||
|
|
if (!formData.time) {
|
|||
|
|
formData.time = '';
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
// 起点图标
|
|||
|
|
const startMarkIcon = reactive({
|
|||
|
|
url: startIcon,
|
|||
|
|
size: { width: 32, height: 32 },
|
|||
|
|
opts: { anchor: { width: 16, height: 16 } },
|
|||
|
|
});
|
|||
|
|
// 终点图标
|
|||
|
|
const endMarkIcon = reactive({
|
|||
|
|
url: endIcon,
|
|||
|
|
size: { width: 32, height: 32 },
|
|||
|
|
opts: { anchor: { width: 16, height: 16 } },
|
|||
|
|
});
|
|||
|
|
// 运动图标
|
|||
|
|
const iconss = reactive({
|
|||
|
|
url: goIcon,
|
|||
|
|
size: { width: 18, height: 18 },
|
|||
|
|
opts: { anchor: { width: 9, height: 9 } },
|
|||
|
|
});
|
|||
|
|
const biaoMarkIcon = reactive({
|
|||
|
|
url: biaoIcon,
|
|||
|
|
size: { width: 32, height: 32 },
|
|||
|
|
opts: { anchor: { width: 15, height: 32 } },
|
|||
|
|
});
|
|||
|
|
const handler = ({ BMap, map }) => {
|
|||
|
|
// 自动获取展示的比例
|
|||
|
|
const view = map.getViewport(eval(data.path));
|
|||
|
|
data.zoom = view.zoom;
|
|||
|
|
data.centerPoint = view.center;
|
|||
|
|
};
|
|||
|
|
// 查询
|
|||
|
|
const getPath = () => {
|
|||
|
|
data.mapShow = false;
|
|||
|
|
data.noTrack = false;
|
|||
|
|
getTrack();
|
|||
|
|
};
|
|||
|
|
// 播放/暂停 运行轨迹
|
|||
|
|
const playPoints = () => {
|
|||
|
|
if (data.noTrack) {
|
|||
|
|
ElMessage.warning('暂无定位轨迹');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
data.play = !data.play;
|
|||
|
|
};
|
|||
|
|
// 停止播放运行轨迹
|
|||
|
|
const reset = () => {
|
|||
|
|
data.play = false;
|
|||
|
|
};
|
|||
|
|
// 查询定位
|
|||
|
|
const getTrack = () => {
|
|||
|
|
data.trackLoading = true;
|
|||
|
|
if (data.type == 'order') {
|
|||
|
|
collarTrack({
|
|||
|
|
deliveryId: data.deliveryId,
|
|||
|
|
xqDeviceId: data.xqDeviceId,
|
|||
|
|
trackTime: formData.time[0] ? formData.time[0] : '',
|
|||
|
|
trackEndTime: formData.time[1] ? formData.time[1] : '',
|
|||
|
|
})
|
|||
|
|
.then((res) => {
|
|||
|
|
data.trackLoading = false;
|
|||
|
|
if (res.code === 200) {
|
|||
|
|
data.mapShow = true;
|
|||
|
|
if (res.data.length > 0) {
|
|||
|
|
data.path = [];
|
|||
|
|
res.data.forEach((item) => {
|
|||
|
|
data.path.push({
|
|||
|
|
lng: item.longitude,
|
|||
|
|
lat: item.latitude,
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
data.startMark = data.path[0]; // 起点
|
|||
|
|
data.endMark = data.path[data.path.length - 1]; // 终点
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
ElMessage.error(res.msg);
|
|||
|
|
data.noTrack = true;
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(() => {
|
|||
|
|
data.trackLoading = false;
|
|||
|
|
data.noTrack = true;
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
collarTrackOrder({
|
|||
|
|
deliveryId: data.deliveryId,
|
|||
|
|
xqDeviceId: data.xqDeviceId,
|
|||
|
|
trackTime: formData.time[0] ? formData.time[0] : '',
|
|||
|
|
trackEndTime: formData.time[1] ? formData.time[1] : '',
|
|||
|
|
})
|
|||
|
|
.then((res) => {
|
|||
|
|
data.trackLoading = false;
|
|||
|
|
if (res.code === 200) {
|
|||
|
|
data.mapShow = true;
|
|||
|
|
if (res.data.length > 0) {
|
|||
|
|
data.path = [];
|
|||
|
|
res.data.forEach((item) => {
|
|||
|
|
data.path.push({
|
|||
|
|
lng: item.longitude,
|
|||
|
|
lat: item.latitude,
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
data.startMark = data.path[0]; // 起点
|
|||
|
|
data.endMark = data.path[data.path.length - 1]; // 终点
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
ElMessage.error(res.msg);
|
|||
|
|
data.noTrack = true;
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(() => {
|
|||
|
|
data.trackLoading = false;
|
|||
|
|
data.noTrack = true;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
const onShowTrackDialog = (row) => {
|
|||
|
|
data.dialogVisible = true;
|
|||
|
|
getNowDate();
|
|||
|
|
if (row) {
|
|||
|
|
data.deliveryId = row.deliveryId;
|
|||
|
|
data.xqDeviceId = row.deviceId;
|
|||
|
|
data.type = row.type ? row.type : '';
|
|||
|
|
data.mapShow = false;
|
|||
|
|
data.noTrack = false;
|
|||
|
|
data.formData = '';
|
|||
|
|
getTrack();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
defineExpose({
|
|||
|
|
onShowTrackDialog,
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="less" scoped>
|
|||
|
|
::v-deep .anchorBL {
|
|||
|
|
display: none;
|
|||
|
|
visibility: hidden;
|
|||
|
|
}
|
|||
|
|
.empty-box {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
height: 500px;
|
|||
|
|
}
|
|||
|
|
</style>
|