<template>
|
<div class="yzx-details">
|
<div class="det-title">
|
<div class="title">执行机巢详情</div>
|
<div class="contain">
|
<div class="img-title">
|
<img :src="flySvg" alt="" />
|
{{ details.device_names }}
|
</div>
|
<div class="img-status">
|
<img v-if="details.status === 5" :src="errorSvg" alt="" @click.stop="errorClick" />
|
<div class="status" :style="{ background: selectedColor }">{{ selectedStatus }}</div>
|
</div>
|
</div>
|
</div>
|
<TaskContent :taskDetails="details" />
|
<div class="task-line">
|
<div class="title">任务航线</div>
|
<div class="details-map" :class="{ 'fullscreen': isFullscreen }">
|
<div class="sf-img" @click.stop="handleMapClick"><img :src="isFullscreen ? suoSvg : fangSvg" alt="" /></div>
|
<div id="detailsMap"></div>
|
</div>
|
</div>
|
<van-dialog v-model:show="showDialog" :show-confirm-button="false" :show-cancel-button="false">
|
<template #title>
|
<div class="custom-header">
|
<div class="ts">提示</div>
|
<div class="close-icon">
|
<van-icon name="cross" @click="showDialog = false" />
|
</div>
|
</div>
|
</template>
|
<div class="dialog-content">
|
<p class="reason">{{ details.reason || '暂无原因' }}</p>
|
</div>
|
</van-dialog>
|
</div>
|
</template>
|
<script setup>
|
import { getJobDetails } from '@/api/home/task'
|
import { getFindAction } from '@/views/RoutePlan/PointAirLine/pointWayLineUtils'
|
import flySvg from '@/appDataSource/inspectionTask/fly.svg'
|
import errorSvg from '@/appDataSource/inspectionTask/error.svg'
|
import _ from 'lodash'
|
import L from 'leaflet'
|
import 'leaflet/dist/leaflet.css'
|
import sl from '@/appDataSource/leafletMapIcon/sl.svg'
|
import yx from '@/appDataSource/leafletMapIcon/yx.svg'
|
import suoSvg from '@/appDataSource/inspectionTask/suo-bg.svg'
|
import fangSvg from '@/appDataSource/inspectionTask/fang-bg.svg'
|
import { analysisPointLineKmz } from '@/views/RoutePlan/PointAirLine/pointWayLineUtils'
|
import startImg from '@/assets/images/signMachineNest/rwqfd.png'
|
import droneIconSvg from '@/appDataSource/leafletMapIcon/drone-icon.svg'
|
import endPointImg from '@/assets/images/EndPointicon.png'
|
import TaskContent from '@/appPages/inspectionTask/TaskInProgress/TaskContent.vue'
|
import { useIdentificationAreaForApp } from '@ztzf/hooks'
|
import 'leaflet-ant-path'
|
import {
|
basemapLayer0,
|
basemapLayer1,
|
basemapLayer2,
|
basemapLayer3,
|
polylineOptions0,
|
polylineOptions1,
|
polylineOptions2,
|
} from '@/const/leafletConst'
|
import { useAreaBoundary } from '@/hooks/useAreaBoundary'
|
import { useRoute } from 'vue-router'
|
const route = useRoute()
|
const basemap0 = L.layerGroup([basemapLayer0, basemapLayer1])
|
const basemap1 = L.layerGroup([basemapLayer2, basemapLayer3])
|
const layers = [
|
{
|
src: sl,
|
name: '天地图电子',
|
key: 1,
|
map: basemap0,
|
},
|
{
|
src: yx,
|
name: '天地图影像',
|
key: 2,
|
map: basemap1,
|
},
|
]
|
let map = null
|
|
const props = defineProps(['wayLineJobInfoId'])
|
const flightEvents = ref([])
|
const details = inject('detailsObj')
|
const taskWayLineDetails = inject('taskWayLineDetails')
|
|
async function getDetails() {
|
const params = {
|
wayLineJobInfoId: props.wayLineJobInfoId,
|
waylineJobId: route.query.waylineJobId,
|
batchNo: route.query.batch_no
|
}
|
|
// getJobDetails(params).then(async res => {
|
// details.value = res.data.data
|
// 飞行事件
|
try {
|
flightEvents.value = details?.value.action_modes.flatMap(item => getFindAction(item, 'app'))
|
// 状态
|
selectedColor.value = listStatus.value.find(item => item.status.includes(details.value.status)).color
|
selectedStatus.value = listStatus.value.find(item => item.status.includes(details.value.status)).name
|
// 显示航线
|
|
console.log(taskWayLineDetails, 111111111)
|
const { pointList } = await analysisPointLineKmz(taskWayLineDetails.value[0].url)
|
let points = pointList.map(item => {
|
return [item.latitude, item.longitude]
|
})
|
// 连接到机巢
|
points.unshift([details.value.latitude, details.value.longitude])
|
let currentPolyline = L.polyline.antPath(points, polylineOptions0).addTo(map)
|
// 创建起点图标
|
const startIcon = L.icon({
|
iconUrl: droneIconSvg, // 起点图片路径
|
iconSize: [28, 28], // 图标大小
|
})
|
|
// 创建终点图标
|
const endIcon = L.icon({
|
iconUrl: endPointImg, // 终点图片路径
|
iconSize: [28, 28],
|
iconAnchor: [16, 28],
|
popupAnchor: [0, -28],
|
})
|
// 添加起点标记
|
L.marker(points[0], { icon: startIcon }).addTo(map)
|
// 添加终点标记
|
L.marker(points[points.length - 1], { icon: endIcon }).addTo(map)
|
// 调整地图视图显示整个航线
|
map.fitBounds(currentPolyline.getBounds().pad(0.1))
|
// 自定义识别区渲染
|
const {setArea,removeArea } = useIdentificationAreaForApp()
|
setArea(details.value.ai_types.split(','),map)
|
// })
|
} catch (error) {
|
// 航线不存在 解析会报错
|
console.log(error,'error')
|
if (map) {
|
map.setView([details.value.latitude, details.value.longitude], 13);
|
}
|
}
|
}
|
const selectedColor = ref('')
|
const selectedStatus = ref('')
|
const listStatus = ref([
|
{ name: '执行中', color: '#FF8B42', status: [2] },
|
{ name: '待执行', color: '#F3B200', status: [1] },
|
{ name: '已执行', color: '#39B002', status: [3] },
|
{ name: '执行失败', color: '#FF381D', status: [5] },
|
{ name: '取消执行', color: '#ADADAD', status: [7] },
|
])
|
let boundaryInstance = useAreaBoundary()
|
let markersLayer = null
|
const initMap = () => {
|
if (map) return
|
map = L.map('detailsMap', {
|
preferCanvas: true,
|
crs: L.CRS.EPSG4326,
|
zoomControl: false,
|
attributionControl: false,
|
doubleClickZoom: false,
|
editable: true, //绘制控件
|
}).setView([25.992338, 114.823254], 13)
|
boundaryInstance.initBoundary(map)
|
markersLayer = L.layerGroup().addTo(map) // 创建一个标注层,便于管理和移除
|
}
|
const showDialog = ref(false)
|
function errorClick() {
|
showDialog.value = true
|
}
|
const isFullscreen = ref(false)
|
async function handleMapClick() {
|
if (isFullscreen.value) {
|
isFullscreen.value = false
|
} else {
|
isFullscreen.value = true
|
}
|
await nextTick()
|
setTimeout(() => {
|
map.invalidateSize()
|
}, 350)
|
}
|
|
let activeTab = inject('activeTab')
|
|
watch(activeTab, (newValue,oldValue) => {
|
isFullscreen.value = true
|
handleMapClick()
|
},{immediate:true})
|
|
watch(details, (newVal) => {
|
getDetails()
|
})
|
|
onMounted(async () => {
|
// getDetails()
|
await nextTick()
|
initMap()
|
map.addLayer(layers[0].map)
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.yzx-details {
|
.det-title {
|
height: 86px;
|
background: white;
|
margin: 12px;
|
padding: 8px;
|
border-radius: 6px 6px 6px 6px;
|
.title {
|
height: 30px;
|
font-weight: bold;
|
font-size: 16px;
|
color: #222324;
|
}
|
.contain {
|
height: 38px;
|
line-height: 38px;
|
background: #e6f0ff;
|
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.03);
|
border-radius: 6px 6px 6px 6px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 0 12px;
|
|
.img-title {
|
display: flex;
|
align-items: center;
|
font-weight: 500;
|
font-size: 14px;
|
color: #282828;
|
margin-right: 4px;
|
}
|
.img-status {
|
display: flex;
|
}
|
.status {
|
margin-left: 4px;
|
padding: 0 6px;
|
min-width: 54px;
|
height: 22px;
|
line-height: 22px;
|
text-align: center;
|
color: white;
|
//background: #39b002;
|
border-radius: 4px 4px 4px 4px;
|
}
|
}
|
}
|
.det-contain {
|
background: white;
|
margin: 12px;
|
padding: 8px 8px 23px 8px;
|
border-radius: 6px 6px 6px 6px;
|
.title {
|
font-weight: bold;
|
font-size: 16px;
|
color: #222324;
|
}
|
.item {
|
height: 40px;
|
line-height: 40px;
|
padding: 0 14px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
.left {
|
font-weight: 400;
|
font-size: 15px;
|
color: #222324;
|
}
|
.right {
|
text-align: right;
|
width: 60%;
|
font-weight: 400;
|
font-size: 15px;
|
color: #7b7b7b;
|
align-items: center;
|
white-space: nowrap; /* 不换行 */
|
overflow: hidden; /* 超出隐藏 */
|
text-overflow: ellipsis; /* 显示省略号 */
|
}
|
.flightEvents {
|
display: flex;
|
align-items: center;
|
justify-content: end;
|
> img {
|
width: 22px;
|
height: 22px;
|
margin-right: 2px;
|
}
|
}
|
border-bottom: 1px solid #f5f5f5;
|
}
|
}
|
.task-line {
|
height: 260px;
|
background: #ffffff;
|
border-radius: 6px 6px 6px 6px;
|
margin: 12px;
|
padding: 12px;
|
.title {
|
font-weight: bold;
|
font-size: 16px;
|
color: #222324;
|
margin-bottom: 7px;
|
}
|
.details-map {
|
width: 100%;
|
height: 206px;
|
position: relative;
|
.sf-img {
|
position: absolute;
|
top: 8px;
|
right: 11px;
|
z-index: 999;
|
}
|
}
|
#detailsMap {
|
width: 100%;
|
height: 100%;
|
border-radius: 6px 6px 6px 6px;
|
}
|
.fullscreen {
|
position: fixed;
|
top: 0;
|
left: 0;
|
width: 100vw;
|
margin-top: 44px;
|
height: calc(100vh - 44px);
|
z-index: 997;
|
}
|
}
|
:deep(.van-dialog) {
|
min-height: 70px;
|
width: 234px;
|
border-radius: 8px 8px 8px 8px;
|
.van-dialog__header {
|
padding-top: 4px;
|
}
|
.custom-header {
|
display: flex;
|
justify-items: center;
|
justify-content: space-between;
|
height: 24px;
|
line-height: 24px;
|
padding: 0 10px 0 11px;
|
.close-icon {
|
width: 11px;
|
height: 11px;
|
}
|
.ts {
|
font-family: Source Han Sans CN, Source Han Sans CN;
|
font-weight: bolder;
|
font-size: 14px;
|
color: #222222;
|
}
|
}
|
.dialog-content {
|
position: relative;
|
font-size: 14px;
|
height: 100%;
|
p {
|
//margin: 6px auto;
|
padding: 6px 17px 11px 17px;
|
width: 100%;
|
min-height: 30px;
|
text-align: justify
|
}
|
}
|
}
|
}
|
</style>
|