| | |
| | | <template> |
| | | <el-dialog v-model="visible" :title="dialogTitle" @closed="handleClosed" destroy-on-close> |
| | | <div> |
| | | <div>无人机名称:{{ formData.droneName }}</div> |
| | | <div>序列号: {{ formData.serialNo }}</div> |
| | | <div>告警时间: {{ formData.alarmTime }}</div> |
| | | <div>触发原因: {{ formData.triggerType }}</div> |
| | | <div>停留时长: {{ formData.stayDuration }}</div> |
| | | <template> |
| | | <el-dialog |
| | | class="command-page-map-view-dialog" |
| | | v-model="visible" |
| | | :show-close="false" |
| | | :close-on-click-modal="false" |
| | | @closed="handleClosed" |
| | | destroy-on-close |
| | | > |
| | | <div class="dialog-container"> |
| | | <div class="left-container"> |
| | | <div class="leftMap command-cesium" id="leftMapContainer"></div> |
| | | </div> |
| | | <div class="right-container"> |
| | | <div class="header"> |
| | | <span>{{ dialogTitle }}</span> |
| | | |
| | | <el-icon class="close-btn" @click.stop="visible = false"><Close /></el-icon> |
| | | </div> |
| | | |
| | | <div class="content"> |
| | | <div class="detail-title">轨迹信息</div> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <div class="label">无人机名称</div> |
| | | <div class="val">{{ formData.droneName }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div class="label">无人机序列号</div> |
| | | <div class="val">{{ formData.serialNo }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div class="label">告警时间</div> |
| | | <div class="val">{{ formData.alarmTime }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div class="label">触发原因</div> |
| | | <div class="val">{{ formData.triggerType }}</div> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <div class="label">停留时长</div> |
| | | <div class="val">{{ formData.stayDuration }}</div> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="detail-title">轨迹点</div> |
| | | <div class="command-table-container"> |
| | | <div class="command-table-content"> |
| | | <el-table class="command-table" :data="list" :row-class-name="getRowClassName"> |
| | | <el-table-column type="index" width="60" label="序号" /> |
| | | <el-table-column label="经纬度"> |
| | | <template #default="{ row }">{{ row.longitude }},{{ row.latitude }}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="时间" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="footer"> |
| | | <el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <el-table :data="list"> |
| | | <el-table-column type="index" width="60" label="序号" /> |
| | | <el-table-column prop="areaCode" label="areaCode" /> |
| | | <el-table-column prop="createTime" label="createTime" /> |
| | | <el-table-column prop="latitude" label="latitude" /> |
| | | <el-table-column prop="longitude" label="longitude" /> |
| | | </el-table> |
| | | <template #footer> |
| | | <el-button @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref } from 'vue' |
| | | import { Close } from '@element-plus/icons-vue' |
| | | |
| | | import { computed, nextTick, ref } from 'vue' |
| | | import { fwDroneFlightRecordDetailApi } from '@/views/recordManage/historyTracks/fwDroneFlightRecord' |
| | | import { fwDroneFlightRecordDetailPageApi } from '@/views/recordManage/historyTracks/flyTrajectory' |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium' |
| | | import * as Cesium from 'cesium' |
| | | import { flyVisual } from '@ztzf/utils' |
| | | import { ArrowLineMaterialProperty } from '@/utils/cesium/Material' |
| | | import droneIcon from '@/assets/images/dataCockpit/map/drone.png' |
| | | |
| | | const initForm = () => ({ |
| | | droneName: '', |
| | |
| | | const res = await fwDroneFlightRecordDetailApi({ id: formData.value.id }) |
| | | const res1 = await fwDroneFlightRecordDetailPageApi({ flightRecordId: formData.value.id }) |
| | | list.value = res1.data.data.records ?? [] |
| | | drawFlightPath() |
| | | formData.value = res?.data?.data ?? {} |
| | | } |
| | | |
| | | let arrowLineMaterialProperty = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5, |
| | | }) |
| | | |
| | | // 角度转c3 |
| | | function degreesToC3({ longitude, latitude, height = 0 }) { |
| | | return Cesium.Cartesian3.fromDegrees(longitude, latitude, height) |
| | | } |
| | | // 渲染航线 |
| | | function drawFlightPath() { |
| | | const positions = list.value.map(p => degreesToC3(p)) |
| | | if (!positions.length) return |
| | | droneLineEntity && geometricSource.entities.remove(droneLineEntity) |
| | | droneLineEntity = geometricSource.entities.add({ |
| | | polyline: { |
| | | width: 4, |
| | | positions: positions, |
| | | material: arrowLineMaterialProperty, |
| | | clampToGround: false, |
| | | }, |
| | | }) |
| | | startDroneEntity && geometricSource.entities.remove(startDroneEntity) |
| | | startDroneEntity = geometricSource.entities.add({ |
| | | position: positions[0], |
| | | billboard: { |
| | | image: droneIcon, |
| | | width: 40, |
| | | height: 40, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | }, |
| | | }) |
| | | viewer.flyTo(droneLineEntity, { duration: 0 }) |
| | | } |
| | | |
| | | // 关闭后重置 |
| | | function handleClosed() { |
| | | formData.value = initForm() |
| | | list.value = [] |
| | | viewer = null |
| | | geometricSource = null |
| | | droneLineEntity = null |
| | | startDroneEntity = null |
| | | } |
| | | |
| | | function getRowClassName({ row }) { |
| | | console.log(row.isAlarm, 11111111111) |
| | | |
| | | return row?.isAlarm === 1 ? 'alarm-row' : '' |
| | | } |
| | | |
| | | let viewer, geometricSource, droneLineEntity, startDroneEntity |
| | | function initMap() { |
| | | if (viewer) return |
| | | const publicCesiumInstance = new PublicCesium({ |
| | | dom: 'leftMapContainer', |
| | | flatMode: false, |
| | | terrain: true, |
| | | layerMode: 4, |
| | | boundary: false, |
| | | }) |
| | | viewer = publicCesiumInstance.getViewer() |
| | | geometricSource = new Cesium.CustomDataSource('geometricSource') |
| | | viewer.dataSources.add(geometricSource) |
| | | } |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode, row } = {}) { |
| | | dialogMode.value = mode || 'add' |
| | | visible.value = true |
| | | await nextTick() |
| | | initMap() |
| | | if (dialogMode.value === 'add') { |
| | | formData.value = initForm() |
| | | } else { |
| | |
| | | |
| | | defineExpose({ open }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | :deep(.alarm-row) { |
| | | background: #2B2B4C !important; |
| | | |
| | | td { |
| | | background-color: transparent !important; |
| | | } |
| | | } |
| | | </style> |