From 7319ec49da9f1490ad35f47e0da62546d1cc7ff4 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Tue, 27 Jan 2026 18:05:34 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 applications/drone-command/src/views/dataCockpit/index.vue |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 112 insertions(+), 1 deletions(-)

diff --git a/applications/drone-command/src/views/dataCockpit/index.vue b/applications/drone-command/src/views/dataCockpit/index.vue
index 7f44448..aafe0df 100644
--- a/applications/drone-command/src/views/dataCockpit/index.vue
+++ b/applications/drone-command/src/views/dataCockpit/index.vue
@@ -12,10 +12,23 @@
   <div class="page-container">
     <DeviceMapContainer
       :online-devices="onlineDevices"
+      :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" />  
+    <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:onlineDevices="onlineDevices" />  
     <CenterContainer @select-warning="onSelectWarning" @select-equipment="onSelectEquipment" />  
     <LegendBar class="legend-container" />
@@ -28,12 +41,23 @@
   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 rightCollapsed = ref(false);
   const onlineDevices = ref([]);
+  const realWarningData = ref([]);
+  const realWarningLoading = ref(true);
+  const minLoadingMs = 400;
 
   const onSelectWarning = (type) => {
     leftActiveId.value = type;
@@ -43,6 +67,93 @@
   const onSelectEquipment = () => {
     rightCollapsed.value = false;
   };
+
+  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 () => {
+    const startAt = Date.now();
+    realWarningLoading.value = true;
+    try {
+      const params = { current: 1, size: 20, 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;
+    }
+  };
+
+  onMounted(() => {
+    fetchRealWarning();
+  });
 </script>
 
 <style scoped lang="scss">

--
Gitblit v1.9.3