Files
cattleTransportation/pc-cattle-transportation/src/views/hardware/trackDialog.vue

269 lines
9.4 KiB
Vue
Raw Normal View History

2025-10-20 17:32:09 +08:00
<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>