From 8739df8c235b3c36df0b47ddc20a691dadc7bb4f Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 09 Feb 2026 15:58:05 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/dataCockpit/index.vue | 336 ++++++++++++++++++++++++++++---------------------------
1 files changed, 169 insertions(+), 167 deletions(-)
diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index 1224bd5..d9399c1 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/applications/drone-command/src/views/dataCockpit/index.vue
@@ -2,7 +2,7 @@
* @Author : yuan
* @Date : 2026-01-06 16:35:50
* @LastEditors : yuan
- * @LastEditTime : 2026-01-31 15:40:15
+ * @LastEditTime : 2026-02-09 15:40:07
* @FilePath : \applications\drone-command\src\views\dataCockpit\index.vue
* @Description :
* Copyright 2026 OBKoro1, All Rights Reserved.
@@ -10,201 +10,203 @@
-->
<template>
<div class="page-container">
- <DeviceMapContainer
- :all-devices="allDevices"
- :alarm-drones="realWarningData"
- :left-collapsed="leftCollapsed"
- 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"
+ <DeviceMapContainer ref="deviceMapRef" :all-devices="allDevices" :alarm-drones="realWarningData"
+ :left-collapsed="leftCollapsed" 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" />
- <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />
+ @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 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';
+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 allDevices = ref([]);
- const realWarningData = ref([]);
- const realWarningLoading = ref(true);
- const minLoadingMs = 400;
+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 actionTextMap = {
- signal: '信号干扰',
- counter: '诱导驱离'
- };
+const handleSceneClick = (item) => {
+ if (item?.longitude && item?.latitude) {
+ deviceMapRef.value?.flyTo({
+ position: {
+ longitude: Number(item.longitude),
+ latitude: Number(item.latitude),
+ height: 18000
+ },
+ })
+ }
+}
- const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id;
- const getFavoriteId = (item) =>
- item?.favoriteId ??
- item?.alarmFavoriteId ??
- item?.fwAlarmFavoriteId ??
- item?.favoriteRecordId ??
- getAlarmRecordId(item);
+const actionTextMap = {
+ signal: '信号干扰',
+ counter: '诱导驱离'
+}
- const isFavorited = (item) => {
- const value = item?.favorited ?? item?.isFavorite;
- return value === 1 || value === '1' || value === true;
- };
+const getAlarmRecordId = (item) => item?.alarmRecordId ?? item?.id
+const getFavoriteId = (item) =>
+ item?.favoriteId ??
+ item?.alarmFavoriteId ??
+ item?.fwAlarmFavoriteId ??
+ item?.favoriteRecordId ??
+ getAlarmRecordId(item)
- const buildPayload = (type, item) => ({
- counterWay: type === 'signal' ? 1 : type === 'counter' ? 2 : '',
- alarmRecordId: getAlarmRecordId(item)
- });
+const isFavorited = (item) => {
+ const value = item?.favorited ?? item?.isFavorite
+ return value === 1 || value === '1' || value === true
+}
- 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 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 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 + '失败' })
}
- 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 + '失败' });
- }
- };
+ } catch (error) {
+ ElMessage({ type: 'error', message: actionText + '失败' })
+ }
+}
- const fetchRealWarning = async () => {
- const startAt = Date.now();
- realWarningLoading.value = true;
- 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 {
- const elapsed = Date.now() - startAt;
- if (elapsed < minLoadingMs) {
- await new Promise((resolve) => setTimeout(resolve, minLoadingMs - elapsed));
- }
- realWarningLoading.value = false;
- }
- };
+const fetchRealWarning = async () => {
+ // 只有超过200ms才显示loading,避免闪烁
+ loadingTimer.value = setTimeout(() => {
+ realWarningLoading.value = true
+ }, 200)
- onMounted(() => {
- fetchRealWarning();
- });
+ 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;
- bottom: 20px;
+ top: 0;
+ bottom: 0;
+ padding: 20px;
width: 300px;
- z-index: 9;
- backdrop-filter: blur(2px);
+ background: rgba(0, 0, 0, 0.3);
+ backdrop-filter: blur(16px);
border-radius: 10px 10px 10px 10px;
-
- ::v-deep(.wrapper) {
- display: flex;
- flex-direction: column;
- position: absolute;
- top: 0;
- bottom: 0;
- 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;
- }
+ box-sizing: border-box;
}
+}
- .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%);
- }
+.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%);
+}
- .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: 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%);
+}
- .legend-container {
- position: absolute;
- left: 50%;
- bottom: 22px;
- transform: translateX(-50%);
- z-index: 9;
- }
+.legend-container {
+ position: absolute;
+ left: 50%;
+ bottom: 22px;
+ transform: translateX(-50%);
+ z-index: 9;
+}
</style>
--
Gitblit v1.9.3