吉安感知网项目-前端
shuishen
2026-01-14 052d0e8bd9c1d8e0d243a166bedf761fc5a7a891
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<template>
    <el-dialog v-model="visible" :title="dialogTitle" @closed="handleClosed" destroy-on-close>
        <div class="bodyBox">
            <div class="leftMap ztzf-cesium" id="leftMapContainer"></div>
            <div class="rightInfo">
                <div>
                    <div>无人机名称:{{ formData.droneName }}</div>
                    <div>序列号: {{ formData.serialNo }}</div>
                    <div>告警时间: {{ formData.alarmTime }}</div>
                    <div>触发原因: {{ formData.triggerType }}</div>
                    <div>停留时长: {{ formData.stayDuration }}</div>
                </div>
                <el-table :data="list">
                    <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>
        <template #footer>
            <el-button @click="handleCancel">{{ dialogReadonly ? '关闭' : '取消' }}</el-button>
        </template>
    </el-dialog>
</template>
 
<script setup>
import { computed, 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 '@/utils/cesium/mapUtil'
 
const initForm = () => ({
    droneName: '',
    serialNo: '',
    alarmTime: '',
    triggerType: '',
    stayDuration: '',
})
let list = ref([])
const emit = defineEmits(['success'])
const formData = ref(initForm()) // 表单数据
const visible = ref(false) // 弹框显隐
const dialogMode = ref('add') // 弹框模式
const dialogReadonly = computed(() => dialogMode.value === 'view')
const dialogTitle = computed(() => {
    if (dialogMode.value === 'edit') {
        return '编辑'
    } else if (dialogMode.value === 'view') {
        return '查看'
    } else {
        return '新增'
    }
})
 
// 关闭弹框
function handleCancel() {
    visible.value = false
}
 
// 加载详情
async function loadDetail() {
    if (!formData.value.id) return
    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 ?? {}
}
 
// 角度转c3
function degreesToC3({ longitude, latitude, height = 0 }) {
    return Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
}
// 渲染航线
function drawFlightPath() {
    const positions = list.value.map(p => degreesToC3(p))
    droneLineEntity && geometricSource.entities.remove(droneLineEntity)
    const color = Cesium.Color.fromCssColorString('#00D690')
    droneLineEntity = geometricSource.entities.add({
        polyline: {
            positions: positions,
            width: 3,
            material: new Cesium.PolylineOutlineMaterialProperty({ color }),
            clampToGround: false,
        },
    })
    viewer.flyTo(droneLineEntity)
}
 
// 关闭后重置
function handleClosed() {
    formData.value = initForm()
}
 
let viewer, geometricSource, droneLineEntity
function initMap() {
    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 {
        formData.value = row
        await loadDetail()
    }
}
 
defineExpose({ open })
</script>
<style scoped lang="scss">
.bodyBox {
    display: flex;
    .rightInfo {
        width: 50%;
        height: 500px;
    }
    .leftMap {
        width: 50%;
        height: 500px;
    }
}
</style>