From 4c390d209b45d516fbe2f7552d26048687c83972 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Wed, 05 Aug 2026 14:29:25 +0800
Subject: [PATCH] feat:tab切换太快的时候内容不对应
---
applications/drone-command/src/views/dataCockpit/index.vue | 248 ++++++++++++++++++++++++++++++++++++------------
1 files changed, 184 insertions(+), 64 deletions(-)
diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index 5226ea0..5a0de73 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/applications/drone-command/src/views/dataCockpit/index.vue
@@ -2,91 +2,211 @@
* @Author : yuan
* @Date : 2026-01-06 16:35:50
* @LastEditors : yuan
- * @LastEditTime : 2026-01-09 16:34:39
+ * @LastEditTime : 2026-02-09 15:40:07
* @FilePath : \applications\drone-command\src\views\dataCockpit\index.vue
- * @Description :
- * Copyright 2026 OBKoro1, All Rights Reserved.
+ * @Description :
+ * Copyright 2026 OBKoro1, All Rights Reserved.
* 2026-01-06 16:35:50
-->
<template>
<div class="page-container">
- <MapContainer :online-devices="onlineDevices" :left-collapsed="leftCollapsed" />
- <LeftContainer class="left-container" v-model:activeId="leftActiveId" v-model:collapsed="leftCollapsed" />
- <RightContainer class="right-container" v-model:collapsed="rightCollapsed" v-model:onlineDevices="onlineDevices" />
- <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />
+ <DeviceMapContainer ref="deviceMapRef" :all-devices="allDevices" :alarm-drones="realWarningData"
+ :right-collapsed="rightCollapsed" container-id="data-cockpit-map"
+ @drone-signal="handleAlarmAction('signal', $event)" @drone-counter="handleAlarmAction('counter', $event)"
+ @drone-favorite="handleAlarmFavorite" />
+ <LeftContainer class="left-container" v-model:activeId="leftActiveId" v-model:collapsed="leftCollapsed"
+ :real-warning-data="realWarningData" :real-warning-loading="realWarningLoading"
+ @real-warning-signal="handleAlarmAction('signal', $event)"
+ @real-warning-counter="handleAlarmAction('counter', $event)" @real-warning-favorite="handleAlarmFavorite" />
+ <RightContainer class="right-container" v-model:collapsed="rightCollapsed" v-model:allDevices="allDevices"
+ @scene-click="handleSceneClick" />
+ <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />
+ <LegendBar class="legend-container" />
</div>
</template>
<script setup>
- import MapContainer from './components/MapContainer.vue';
- import LeftContainer from './components/LeftContainer.vue';
- import RightContainer from './components/RightContainer.vue';
- import CenterContainer from './components/CenterContainer.vue';
+import DeviceMapContainer from '@/components/map-container/device-map-container.vue'
+import LeftContainer from './components/LeftContainer.vue'
+import RightContainer from './components/RightContainer.vue'
+import CenterContainer from './components/CenterContainer.vue'
+import LegendBar from './components/LegendBar.vue'
+import {
+ alarmLogApi,
+ alarmFavoriteRemoveApi,
+ alarmFavoriteSaveApi,
+ interferenceAndExpulsionApi
+} from '@/api/dataCockpit'
+import { ElMessage } from 'element-plus'
+import { onMounted, ref } from 'vue'
- const leftActiveId = ref(1);
- const leftCollapsed = ref(false);
+const leftActiveId = ref(1)
+const leftCollapsed = ref(false)
- const rightCollapsed = ref(false);
- const onlineDevices = ref([]);
+const rightCollapsed = ref(false)
+const allDevices = ref([])
+const realWarningData = ref([])
+const realWarningLoading = ref(false)
+const loadingTimer = ref(null)
+const deviceMapRef = ref(null)
- const onSelectWarning = (type) => {
- leftActiveId.value = type;
- leftCollapsed.value = false;
- };
+const onSelectWarning = (type) => {
+ leftActiveId.value = type
+ leftCollapsed.value = false
+}
- const onSelectEquipment = () => {
- rightCollapsed.value = false;
- };
+const onSelectEquipment = () => {
+ rightCollapsed.value = false
+}
+
+const handleSceneClick = (item) => {
+ if (item?.longitude && item?.latitude) {
+ deviceMapRef.value?.flyTo({
+ position: {
+ longitude: Number(item.longitude),
+ latitude: Number(item.latitude),
+ height: 18000
+ },
+ })
+ }
+}
+
+const actionTextMap = {
+ signal: '信号干扰',
+ counter: '诱导驱离'
+}
+
+const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id
+const getFavoriteId = (item) =>
+ item?.favoriteId ??
+ item?.alarmFavoriteId ??
+ item?.fwAlarmFavoriteId ??
+ item?.favoriteRecordId ??
+ getAlarmRecordId(item)
+
+const isFavorited = (item) => {
+ const value = item?.favorited ?? item?.isFavorite
+ return value === 1 || value === '1' || value === true
+}
+
+const buildPayload = (type, item) => ({
+ counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '',
+ alarmRecordId: getAlarmRecordId(item)
+})
+
+const handleAlarmAction = async (type, item) => {
+ const actionText = actionTextMap[type] || '操作'
+ try {
+ const res = await interferenceAndExpulsionApi(buildPayload(type, item))
+ if (res?.data?.success) {
+ ElMessage({ type: 'success', message: actionText + '成功' })
+ await fetchRealWarning()
+ } else {
+ ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' })
+ }
+ } catch (error) {
+ ElMessage({ type: 'error', message: actionText + '失败' })
+ }
+}
+
+const handleAlarmFavorite = async (item) => {
+ const alarmRecordId = getAlarmRecordId(item)
+ if (!alarmRecordId) {
+ ElMessage({ type: 'warning', message: '缺少告警记录ID' })
+ return
+ }
+ const favorite = isFavorited(item)
+ const actionText = favorite ? '取消关注' : '关注'
+ try {
+ const res = favorite
+ ? await alarmFavoriteRemoveApi(getFavoriteId(item))
+ : await alarmFavoriteSaveApi({ alarmRecordId })
+ if (res?.data?.success) {
+ ElMessage({ type: 'success', message: actionText + '成功' })
+ await fetchRealWarning()
+ } else {
+ ElMessage({ type: 'error', message: res?.data?.msg || actionText + '失败' })
+ }
+ } catch (error) {
+ ElMessage({ type: 'error', message: actionText + '失败' })
+ }
+}
+
+const fetchRealWarning = async () => {
+ // 只有超过200ms才显示loading,避免闪烁
+ loadingTimer.value = setTimeout(() => {
+ realWarningLoading.value = true
+ }, 200)
+
+ try {
+ const params = { current: 1, size: 9999, alarmType: '1' }
+ const res = await alarmLogApi(params)
+ const records = res?.data?.data?.records ?? []
+ realWarningData.value = records.map((record) => ({
+ ...record,
+ isFavorite:
+ record?.isFavorite ??
+ (record?.favorited === 1 || record?.favorited === '1')
+ }))
+ } finally {
+ if (loadingTimer.value) clearTimeout(loadingTimer.value)
+ realWarningLoading.value = false
+ }
+}
+
+onMounted(() => {
+ fetchRealWarning()
+})
</script>
<style scoped lang="scss">
- .page-container {
- position: relative;
- width: 100%;
- height: 100%;
- }
+.page-container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
- .left-container,
- .right-container {
+.left-container,
+.right-container {
+ position: absolute;
+ bottom: 20px;
+ width: 300px;
+ z-index: 9;
+ backdrop-filter: blur(2px);
+ border-radius: 10px 10px 10px 10px;
+
+ ::v-deep(.wrapper) {
+ display: flex;
+ flex-direction: column;
position: absolute;
- top: 96px;
+ top: 0;
bottom: 0;
- width: 401px;
- z-index: 9;
- backdrop-filter: blur(2px);
-
- ::v-deep(.wrapper) {
- display: flex;
- flex-direction: column;
- position: absolute;
- top: 17px;
- bottom: 20px;
- padding: 20px;
- width: 300px;
- background: rgba(0,0,0,0.3);
- backdrop-filter: blur(16px);
- border-radius: 10px 10px 10px 10px;
- }
+ padding: 20px;
+ width: 300px;
+ background: rgba(0, 0, 0, 0.3);
+ backdrop-filter: blur(16px);
+ border-radius: 10px 10px 10px 10px;
+ box-sizing: border-box;
}
+}
- .left-container {
- top: 96px;
- left: 0;
- background: linear-gradient( 270deg, rgba(17,23,34,0) 0%, rgba(17,23,34,0.56) 50%, rgba(17,23,34,0.96) 100%);
+.left-container {
+ top: 113px;
+ left: 17px;
+ background: linear-gradient(270deg, rgba(17, 23, 34, 0) 0%, rgba(17, 23, 34, 0.56) 50%, rgba(17, 23, 34, 0.96) 100%);
+}
- ::v-deep(.wrapper) {
- left: 17px;
- }
- }
+.right-container {
+ top: 75px;
+ right: 17px;
+ background: linear-gradient(270deg, rgba(17, 23, 34, 0.96) 0.16%, rgba(17, 23, 34, 0.56) 57.57%, rgba(4, 30, 37, 0) 100%);
+}
- .right-container {
- top: 54px;
- right: 0;
- background: linear-gradient( 270deg, rgba(17,23,34,0.96) 0.16%, rgba(17,23,34,0.56) 57.57%, rgba(4,30,37,0) 100%);
-
- ::v-deep(.wrapper) {
- top: 21px;
- right: 17px;
- }
- }
+.legend-container {
+ position: absolute;
+ left: 50%;
+ bottom: 22px;
+ transform: translateX(-50%);
+ z-index: 9;
+}
</style>
--
Gitblit v1.9.3