ソースを参照

[0924] 测点数据自动刷新

taosj 1 ヶ月 前
親
コミット
c3789d163a

+ 58 - 6
forecast-backend-vue/src/views/ufo/electricity/realtime/PointMonitor.vue

@@ -29,6 +29,7 @@
               <a-space>
                 <a-button type="primary" :loading="loading" @click="handleQuery"><BearJiaIcon icon="SearchOutlined"/>查询</a-button>
                 <a-button @click="resetQuery"><BearJiaIcon icon="ReloadOutlined"/>重置</a-button>
+                <a-button v-if="countdown > 0" disabled>{{ countdown }}s后刷新数据</a-button>
               </a-space>
             </a-form-item>
           </a-form>
@@ -57,7 +58,7 @@
 </template>
 
 <script setup name="PointMonitor">
-import { computed, reactive, ref } from 'vue';
+import { computed, onBeforeUnmount, reactive, ref } from 'vue';
 import dayjs from 'dayjs';
 import { cascadeMonitorChannel } from '@/api/config/channel';
 import { pointMonitor } from '@/api/config/point';
@@ -65,11 +66,11 @@ import { BearJiaIcon } from '@/utils/BearJiaIcon.js';
 
 const CATEGORY_FIRST = 'YX';
 const categoryOptions = [
-  { label: '遥信', value: 'YX' },
-  { label: '遥测', value: 'YC' },
-  { label: '遥脉', value: 'YM' },
-  { label: '遥控', value: 'YK' },
-  { label: '遥调', value: 'YT' }
+  { label: '遥信', value: 'YX', interval: 5 },
+  { label: '遥测', value: 'YC', interval: 15 }
+  // { label: '遥脉', value: 'YM' },
+  // { label: '遥控', value: 'YK' },
+  // { label: '遥调', value: 'YT' }
 ];
 
 const loading = ref(false);
@@ -89,6 +90,28 @@ const queryParams = reactive({
 });
 const pagination = reactive({ current: 1, pageSize: 10, total: 0, showSizeChanger: true });
 
+// 自动刷新定时器: 按`分类`选中option的interval定时调用getList
+let dataRefreshInterval = null;
+// 倒计时秒表, 每1s递减
+let countdownInterval = null;
+// 距下次刷新的秒数, >0时显示倒计时按钮
+const countdown = ref(0);
+
+const currentCategoryOption = computed(() => categoryOptions.find((item) => item.value === queryParams.category));
+
+// 清空定时器和倒计时(x<=0时按钮隐藏)
+const clearDataRefresh = () => {
+  if (dataRefreshInterval) {
+    clearInterval(dataRefreshInterval);
+    dataRefreshInterval = null;
+  }
+  if (countdownInterval) {
+    clearInterval(countdownInterval);
+    countdownInterval = null;
+  }
+  countdown.value = 0;
+};
+
 const columns = [
   { title: '名称', dataIndex: 'name', width: 180, ellipsis: true },
   { title: '编码', dataIndex: 'code', width: 140, ellipsis: true },
@@ -105,6 +128,8 @@ const tableScroll = computed(() => ({ x: columns.reduce((sum, col) => sum + (col
 const formatTime = (timestamp) => (timestamp && Number(timestamp) > 0 ? dayjs(Number(timestamp)).format('YYYY-MM-DD HH:mm:ss') : '');
 
 const getList = async () => {
+  // pointMonitor执行前, 若定时器已存在先清空, 避免重复叠加
+  clearDataRefresh();
   if (currentDeviceId.value === undefined) {
     rows.value = [];
     pagination.total = 0;
@@ -117,6 +142,17 @@ const getList = async () => {
     pagination.total = res?.total || 0;
     pagination.current = queryParams.pageNum;
     pagination.pageSize = queryParams.pageSize;
+    // 加载成功后, 按`分类`选中option的interval创建定时器并初始化倒计时; 失败即停不重建
+    const interval = currentCategoryOption.value?.interval;
+    if (interval) {
+      countdown.value = interval;
+      countdownInterval = setInterval(() => {
+        if (countdown.value > 0) countdown.value -= 1;
+      }, 1000);
+      dataRefreshInterval = setInterval(getList, interval * 1000);
+    }
+  } catch {
+    // 请求异常由axios拦截器统一提示, 此处失败即停
   } finally {
     loading.value = false;
   }
@@ -198,6 +234,22 @@ const loadCascades = async () => {
   }
 };
 
+// 浏览器tab隐藏时清空定时器, 恢复可见时立即刷新并重启倒计时
+const handleVisibilityChange = () => {
+  if (document.hidden) {
+    clearDataRefresh();
+  } else {
+    getList();
+  }
+};
+document.addEventListener('visibilitychange', handleVisibilityChange);
+
+// 页面销毁时清空定时器
+onBeforeUnmount(() => {
+  clearDataRefresh();
+  document.removeEventListener('visibilitychange', handleVisibilityChange);
+});
+
 loadCascades();
 </script>