|
@@ -1,67 +1,28 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="goaf-popup-container">
|
|
<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>
|
|
|
-
|
|
|
|
|
- <!-- 爆炸三角形图表 -->
|
|
|
|
|
- <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>
|
|
</div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 无预警空态 -->
|
|
|
|
|
+ <div v-else class="no-alarm">暂无预警</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<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 {
|
|
interface Props {
|
|
|
data: Record<string, any>;
|
|
data: Record<string, any>;
|
|
@@ -69,182 +30,78 @@ interface Props {
|
|
|
|
|
|
|
|
const props = defineProps<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>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
.goaf-popup-container {
|
|
.goaf-popup-container {
|
|
|
font-family: sans-serif;
|
|
font-family: sans-serif;
|
|
|
- width: 500px;
|
|
|
|
|
|
|
+ min-width: 380px;
|
|
|
max-height: 600px;
|
|
max-height: 600px;
|
|
|
border-radius: 8px;
|
|
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;
|
|
color: #000;
|
|
|
- font-size: 14px;
|
|
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
- padding: 20px 0;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.record-list {
|
|
|
|
|
|
|
+.alarm-table {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- display: grid;
|
|
|
|
|
- grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
- gap: 10px;
|
|
|
|
|
- background-color: #dceefb;
|
|
|
|
|
- padding: 10px;
|
|
|
|
|
border-radius: 4px;
|
|
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;
|
|
display: flex;
|
|
|
align-items: center;
|
|
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;
|
|
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;
|
|
color: #999;
|
|
|
- font-size: 12px;
|
|
|
|
|
|
|
+ font-size: 14px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
- padding: 10px 0;
|
|
|
|
|
- grid-column: 1 / 4;
|
|
|
|
|
|
|
+ padding: 20px 0;
|
|
|
|
|
+ background: #dceefb;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|