Просмотр исходного кода

[Mod 0000] 表面监测-CAD图纸采空区弹窗改造为预警列表展示

houzekong 2 недель назад
Родитель
Сommit
e66a53b740
2 измененных файлов с 68 добавлено и 220 удалено
  1. 12 21
      src/views/system/cadFile/app.ts
  2. 56 199
      src/views/system/cadFile/components/GoafPopup.vue

+ 12 - 21
src/views/system/cadFile/app.ts

@@ -211,14 +211,6 @@ export function useMap2D(): UseMap2DReturn {
   }
 
   function createMarkerElement(goafItem: any, showInfo: boolean = false): HTMLDivElement {
-    const riskMap = {
-      '1': '低风险',
-      '2': '一般风险',
-      '3': '较高风险',
-      '4': '高风险',
-    };
-
-    const alarmLevelColor = [StatusColorEnum.blue, StatusColorEnum.yellow, StatusColorEnum.gold, StatusColorEnum.red];
     const el = document.createElement('div');
     el.className = 'marker';
     el.style.cssText = `
@@ -228,12 +220,12 @@ export function useMap2D(): UseMap2DReturn {
       cursor: move;
     `;
 
-    const level = parseInt(goafItem.alarmLevel, 10);
-    const color = level >= 1 && level <= 4 ? alarmLevelColor[level - 1] : '#333';
+    const hasAlarm = Array.isArray(goafItem.alarmList) && goafItem.alarmList.length > 0;
+    const alarmColor = hasAlarm ? StatusColorEnum.red : StatusColorEnum.green;
 
     if (showInfo) {
-      const alarmLevelDiv = document.createElement('div');
-      alarmLevelDiv.style.cssText = `
+      const alarmStatusDiv = document.createElement('div');
+      alarmStatusDiv.style.cssText = `
         font-size: 14px;
         white-space: nowrap;
         font-weight: bold;
@@ -242,17 +234,16 @@ export function useMap2D(): UseMap2DReturn {
       `;
 
       const labelSpan = document.createElement('span');
-      labelSpan.textContent = '风险等级:';
+      labelSpan.textContent = '是否预警:';
       labelSpan.style.color = '#333';
 
       const valueSpan = document.createElement('span');
-      const riskText = riskMap[String(goafItem.alarmLevel)] || '正常';
-      valueSpan.textContent = goafItem.alarmLevel ? riskText : '正常';
-      valueSpan.style.color = color;
+      valueSpan.textContent = hasAlarm ? '预警' : '正常';
+      valueSpan.style.color = alarmColor;
 
-      alarmLevelDiv.appendChild(labelSpan);
-      alarmLevelDiv.appendChild(valueSpan);
-      el.appendChild(alarmLevelDiv);
+      alarmStatusDiv.appendChild(labelSpan);
+      alarmStatusDiv.appendChild(valueSpan);
+      el.appendChild(alarmStatusDiv);
     }
 
     const iconDiv = document.createElement('div');
@@ -328,7 +319,7 @@ export function useMap2D(): UseMap2DReturn {
 
     const el = createMarkerElement(
       {
-        alarmLevel: props?.alarmLevel,
+        alarmList: props?.alarmList,
         devicePos: props?.name || props?.devicePos,
       },
       false
@@ -388,7 +379,7 @@ export function useMap2D(): UseMap2DReturn {
 
       const finalEl = createMarkerElement(
         {
-          alarmLevel: props?.alarmLevel,
+          alarmList: props?.alarmList,
           devicePos: props?.name || props?.devicePos,
         },
         true

+ 56 - 199
src/views/system/cadFile/components/GoafPopup.vue

@@ -1,67 +1,28 @@
 <template>
   <div class="goaf-popup-container">
-    <!-- 加载状态 -->
-    <div v-if="loading" class="loading">加载中...</div>
-
-    <!-- 内容区域 -->
-    <div v-else class="content-wrapper">
-      <!-- 固定监测数据展示 -->
-      <div class="record-list">
-        <div class="record-item">
-          <div class="label">CO(ppm)</div>
-          <div class="value">{{ monitorData.coVal || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">CO₂(%)</div>
-          <div class="value">{{ monitorData.co2Val || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">CH₄(%)</div>
-          <div class="value">{{ monitorData.ch4Val || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">C₂H₂(ppm)</div>
-          <div class="value">{{ monitorData.c2h2Val || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">C₂H₄(ppm)</div>
-          <div class="value">{{ monitorData.c2h4Val || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">O₂(%)</div>
-          <div class="value">{{ monitorData.o2Val || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">温度(℃)</div>
-          <div class="value">{{ monitorData.temperature || '--' }}</div>
-        </div>
-        <div class="record-item">
-          <div class="label">压差(Pa)</div>
-          <div class="value">{{ monitorData.sourcePressure || '--' }}</div>
-        </div>
+    <div class="popup-title">{{ props.data.name || '测风地点' }}</div>
+
+    <!-- 预警信息列表 -->
+    <div v-if="alarmList.length > 0" class="alarm-table">
+      <div class="alarm-table-row alarm-table-head">
+        <span class="col-type">预警类型</span>
+        <span class="col-val">真实值</span>
+        <span class="col-val">预期值</span>
       </div>
-
-      <!-- 爆炸三角形图表 -->
-      <div class="chart-section">
-        <div class="chart-title">爆炸三角形</div>
-        <div class="chart-box">
-          <BlastDelta
-            :posMonitor="monitorData"
-            :canvas-size="{ width: 420, height: 149 }"
-            :legendStyle="{ left: '50%', top: '10px' }"
-            text-color="#000"
-          />
-        </div>
+      <div v-for="item in alarmList" :key="item.id" class="alarm-table-row">
+        <span class="col-type">{{ alarmTypeMap[item.alarmType] || item.alarmType }}</span>
+        <span class="col-val">{{ item.realVal ?? '--' }}</span>
+        <span class="col-val">{{ item.expectVal ?? '--' }}</span>
       </div>
     </div>
+
+    <!-- 无预警空态 -->
+    <div v-else class="no-alarm">暂无预警</div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, onUnmounted } from 'vue';
-import { getGoafData } from '../cad.api';
-import { message } from 'ant-design-vue';
-import BlastDelta from '/@/components/Configurable/preset/BlastDelta.vue';
+import { computed } from 'vue';
 
 interface Props {
   data: Record<string, any>;
@@ -69,182 +30,78 @@ interface Props {
 
 const props = defineProps<Props>();
 
-// 加载状态
-const loading = ref(true);
-// 定时器 ID(用于关闭清除)
-let timer: ReturnType<typeof setInterval> | null = null;
-
-// 固定监测数据对象
-const monitorData = ref({
-  coVal: '',
-  ch4Val: '',
-  c2h4Val: '',
-  c2h2Val: '',
-  co2Val: '',
-  o2Val: '',
-  sourcePressure: '',
-  temperature: '',
-  btTriBlast: '',
-});
-
-// 获取数据方法(抽取出来复用)
-const fetchData = async () => {
-  try {
-    if (!props.data.id || !props.data.mineCode) {
-      throw new Error('缺少 goafId 或 deptId');
-    }
-
-    // 调用接口
-    const res = await getGoafData({
-      goafId: props.data.id,
-      deptId: props.data.mineCode,
-    });
-
-    // 从 res[0] 中取数据
-    const data = res?.records[0] || {};
-    
-    // 赋值到页面
-    monitorData.value = {
-      coVal: data.coVal,
-      ch4Val: data.ch4Val,
-      c2h4Val: data.c2h4Val,
-      c2h2Val: data.c2h2Val,
-      co2Val: data.co2Val,
-      o2Val: data.o2Val,
-      sourcePressure: data.sourcePressure,
-      temperature: data.temperature,
-      btTriBlast: data.btTriBlast,
-    };
-  } catch (err) {
-    message.error(`获取监测数据失败:${(err as Error).message}`);
-    console.error('getGoafData error:', err);
-  } finally {
-    loading.value = false;
-  }
+/** 预警类型中文映射(AlarmController alarmType 枚举),未知类型回退显示原始值 */
+const alarmTypeMap: Record<string, string> = {
+  vaOverLimit: '风速超限',
+  m3Lack: '风量不足',
+  // m3NotClosed: '风量不闭合',
+  disconnect: '断线',
+  vaChange: '风速波动',
 };
 
-// 页面打开时请求数据 + 开启定时
-onMounted(async () => {
-  // 首次立即加载
-  await fetchData();
-  
-  // 每 10 秒刷新一次 10000ms = 10s
-  timer = setInterval(() => {
-    fetchData();
-  }, 10000);
-});
-
-// 页面关闭时清除定时器(防止内存泄漏)
-onUnmounted(() => {
-  if (timer) {
-    clearInterval(timer);
-    timer = null;
-  }
-});
+const alarmList = computed(() => (Array.isArray(props.data.alarmList) ? props.data.alarmList : []));
 </script>
 
 <style scoped>
 .goaf-popup-container {
   font-family: sans-serif;
-  width: 500px;
+  min-width: 380px;
   max-height: 600px;
   border-radius: 8px;
-  padding-top: 10px;
-  /* background: #fff; */
+  padding: 10px 0;
 }
 
-/* .content-wrapper {
-  display: flex;
-  flex-direction: column;
-  gap: 15px;
-} */
-
-.loading {
+.popup-title {
+  font-size: 16px;
+  font-weight: bold;
   color: #000;
-  font-size: 14px;
+  margin-bottom: 10px;
   text-align: center;
-  padding: 20px 0;
 }
 
-.record-list {
+.alarm-table {
   width: 100%;
-  display: grid;
-  grid-template-columns: repeat(4, 1fr);
-  gap: 10px;
-  background-color: #dceefb;
-  padding: 10px;
   border-radius: 4px;
+  overflow: hidden;
+  background: #dceefb;
 }
 
-.record-item {
-  height: 80px;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  align-items: center;
-  padding: 0;
-  box-sizing: border-box;
-  min-height: 60px;
-  background-image: url(/src/assets/images/sealedGoaf/board-bg-details.png);
-  background-repeat: no-repeat;
-  background-size: 100% 100%;
-}
-
-
-.label {
-  height: 30px;
-  width: 100%;
-  flex-shrink: 0;
-  font-size: 14px;
-  color: #000;
-  text-align: center;
+.alarm-table-row {
   display: flex;
   align-items: center;
-  justify-content: center;
+  padding: 8px 10px;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
 }
 
-.value {
-  width: 100%;
-  height: 50px;
-  font-size: 16px;
-  color: #2b6ff0;
-  word-break: break-all;
-  border-left: none;
-  display: flex;
-  align-items: center;
-  justify-content: center;
+.alarm-table-row:last-child {
+  border-bottom: none;
 }
 
-/* 图表区域样式 */
-.chart-section {
-  margin-top: 10px;
-  border-radius: 4px;
-  padding: 4px 10px;
-  background: #dceefb;
+.alarm-table-head {
+  font-weight: bold;
+  color: #000;
+  background: rgba(0, 0, 0, 0.04);
 }
 
-.chart-title {
-  font-size: 14px;
+.col-type {
+  flex: 1.4;
   color: #000;
-  text-align: left;
+  font-size: 14px;
 }
 
-.chart-box {
-  width: 100%;
-  height: 200px;
-  border-radius: 4px;
-  overflow: hidden;
-}
-:deep(.legend-label) {
-  font-size: 15px;
-  color: #000;
+.col-val {
+  flex: 1;
+  color: #2b6ff0;
+  font-size: 14px;
+  text-align: center;
 }
 
-.no-data {
+.no-alarm {
   color: #999;
-  font-size: 12px;
+  font-size: 14px;
   text-align: center;
-  padding: 10px 0;
-  grid-column: 1 / 4;
+  padding: 20px 0;
+  background: #dceefb;
+  border-radius: 4px;
 }
-</style>
+</style>