| | |
| | | :terrain="true" |
| | | :layer-mode="4" |
| | | :boundary="false" |
| | | /> |
| | | :list="list" |
| | | @point-change="handlePointChange" |
| | | > |
| | | <template #timeline-prefix> |
| | | <el-icon class="track-play-btn" :size="30" @click.stop="handlePlayClick"> |
| | | <VideoPause v-if="isPlaying" /> |
| | | <VideoPlay v-else /> |
| | | </el-icon> |
| | | </template> |
| | | </CommonCesiumMap> |
| | | </div> |
| | | <div class="right-container"> |
| | | <div class="header"> |
| | |
| | | <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 ref="pointTableRef" 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> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="footer"> |
| | | <el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button> |
| | | <el-button v-if="dialogMode != 'view'" color="#2B2B4C" @click="handleCancel"> |
| | | {{ dialogReadonly ? '关闭' : '取消' }} |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { Close } from '@element-plus/icons-vue' |
| | | import { Close, VideoPause, VideoPlay } from '@element-plus/icons-vue' |
| | | |
| | | import { computed, nextTick, ref } from 'vue' |
| | | import { computed, nextTick, onBeforeUnmount, ref } from 'vue' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import { fwDroneFlightRecordDetailApi } from '@/views/recordManage/historyTracks/fwDroneFlightRecord' |
| | | import { fwDroneFlightRecordDetailPageApi } from '@/views/recordManage/historyTracks/flyTrajectory' |
| | |
| | | |
| | | // 关闭后重置 |
| | | function handleClosed() { |
| | | stopTrackPlay() |
| | | formData.value = initForm() |
| | | list.value = [] |
| | | selectedPointIndex.value = 0 |
| | | viewer = null |
| | | geometricSource = null |
| | | droneLineEntity = null |
| | | startDroneEntity = null |
| | | } |
| | | |
| | | function getRowClassName({ row }) { |
| | | console.log(row.isAlarm, 11111111111) |
| | | // 当前选中的轨迹点索引(与地图时间轴联动) |
| | | const selectedPointIndex = ref(0) |
| | | const pointTableRef = ref(null) |
| | | const isPlaying = ref(false) |
| | | const PLAY_INTERVAL = 1000 |
| | | let playTimer = null |
| | | let playIndex = 0 |
| | | |
| | | return row?.isAlarm === 1 ? 'alarm-row' : '' |
| | | // 停止轨迹播放 |
| | | function stopTrackPlay() { |
| | | if (playTimer) { |
| | | clearTimeout(playTimer) |
| | | playTimer = null |
| | | } |
| | | isPlaying.value = false |
| | | } |
| | | |
| | | // 播放下一个轨迹点 |
| | | function playNextPoint() { |
| | | if (!list.value.length || playIndex >= list.value.length) { |
| | | stopTrackPlay() |
| | | return |
| | | } |
| | | mapRef.value?.clickWeekTime?.(list.value[playIndex], playIndex, { |
| | | animate: true, |
| | | duration: PLAY_INTERVAL, |
| | | }) |
| | | playIndex += 1 |
| | | playTimer = setTimeout(() => { |
| | | playTimer = null |
| | | if (playIndex >= list.value.length) { |
| | | stopTrackPlay() |
| | | return |
| | | } |
| | | playNextPoint() |
| | | }, PLAY_INTERVAL) |
| | | } |
| | | |
| | | // 切换轨迹播放状态 |
| | | function handlePlayClick() { |
| | | if (isPlaying.value) { |
| | | stopTrackPlay() |
| | | return |
| | | } |
| | | if (!list.value.length) return |
| | | mapRef.value?.clickWeekTime?.(list.value[0], 0) |
| | | if (list.value.length === 1) return |
| | | playIndex = 1 |
| | | isPlaying.value = true |
| | | playNextPoint() |
| | | } |
| | | |
| | | // 地图上点击轨迹点后,同步高亮表格对应行,并滚动到该行 |
| | | function handlePointChange({ index } = {}) { |
| | | if (typeof index !== 'number') return |
| | | selectedPointIndex.value = index |
| | | scrollToSelectedRow() |
| | | } |
| | | |
| | | // 表格行较多时自动滚动到选中行 |
| | | async function scrollToSelectedRow() { |
| | | await nextTick() |
| | | const rowEl = pointTableRef.value?.$el?.querySelector('.selected-row') |
| | | rowEl?.scrollIntoView({ block: 'nearest', behavior: 'smooth' }) |
| | | } |
| | | |
| | | function getRowClassName({ row, rowIndex }) { |
| | | const classNames = [] |
| | | if (row?.isAlarm === 1) classNames.push('alarm-row') |
| | | if (rowIndex === selectedPointIndex.value) classNames.push('selected-row') |
| | | return classNames.join(' ') |
| | | } |
| | | |
| | | let viewer, geometricSource, droneLineEntity, startDroneEntity |
| | |
| | | |
| | | // 打开弹框 |
| | | async function open({ mode, row } = {}) { |
| | | stopTrackPlay() |
| | | dialogMode.value = mode || 'add' |
| | | visible.value = true |
| | | await nextTick() |
| | |
| | | } |
| | | |
| | | defineExpose({ open }) |
| | | |
| | | // 卸载时清理播放定时器 |
| | | onBeforeUnmount(() => { |
| | | stopTrackPlay() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .left-container { |
| | | min-width: 0; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .right-container { |
| | | position: relative; |
| | | flex-shrink: 0; |
| | | z-index: 1; |
| | | background: #1a1a2a; |
| | | } |
| | | |
| | | :deep(.alarm-row) { |
| | | background: #2B2B4C !important; |
| | | background: #2b2b4c !important; |
| | | |
| | | td { |
| | | background-color: transparent !important; |
| | | } |
| | | } |
| | | |
| | | // 与地图时间轴联动的选中行高亮 |
| | | :deep(.selected-row) { |
| | | background: #14335f !important; |
| | | |
| | | td { |
| | | background-color: transparent !important; |
| | | color: #4faaff !important; |
| | | } |
| | | } |
| | | |
| | | .track-play-btn { |
| | | color: #ffffff; |
| | | cursor: pointer; |
| | | } |
| | | </style> |