Переглянути джерело

fix:质量大屏组件添加定时刷新

luoxiao 6 днів тому
батько
коміт
93bfaf09bc

+ 77 - 39
src/views/screens/screen-components/QualityConsistencyInspection.vue

@@ -1,7 +1,12 @@
 <template>
   <div class="multi-product-ring-container">
     <ScreenComHeader :module-id="moduleId" title="质量一致性检验" />
-    <div ref="chartRef" style="width: 100%; height: 100%"></div>
+    <div
+      ref="chartRef"
+      style="width: 100%; height: 100%"
+      @mouseenter="pauseAllTimers"
+      @mouseleave="resumeAllTimers"
+    ></div>
   </div>
 </template>
 
@@ -20,7 +25,8 @@ const props = defineProps({
 const chartRef = ref(null);
 const chartData = ref([]);
 let chartInstance = null;
-let timer = null;
+let dataRefreshTimer = null; // 数据刷新定时器
+let chartRotateTimer = null; // 图表轮播定时器
 const currentProductIndex = ref(0);
 
 // 初始化图表
@@ -30,37 +36,53 @@ const initChart = () => {
   chartInstance = echarts.init(chartRef.value);
   updateChart();
   window.addEventListener("resize", handleResize);
+  startChartRotation();
+};
 
-  // 添加鼠标事件监听
-  chartInstance.on("mouseover", () => {
-    if (timer) {
-      clearInterval(timer);
-      timer = null;
-    }
-  });
-
-  chartInstance.on("mouseout", () => {
-    if (!timer) {
-      timer = setInterval(() => {
-        if (chartData.value.length > 0) {
-          currentProductIndex.value =
-            (currentProductIndex.value + 1) % chartData.value.length;
-          updateChart();
-        }
-      }, 5000);
-    }
-  });
-
-  // 5秒切换产品批次
-  timer = setInterval(() => {
-    if (chartData.value.length > 0) {
-      currentProductIndex.value =
-        (currentProductIndex.value + 1) % chartData.value.length;
-      updateChart();
-    }
+// 启动数据刷新定时器
+const startDataRefresh = () => {
+  // 先清除现有定时器
+  if (dataRefreshTimer) {
+    clearInterval(dataRefreshTimer);
+    dataRefreshTimer = null;
+  }
+
+  dataRefreshTimer = setInterval(() => {
+    loadData();
+  }, 300000);
+};
+
+// 启动图表轮播定时器
+const startChartRotation = () => {
+  // 只有数据多于1条时才需要轮播
+  if (chartData.value.length <= 1) return;
+
+  // 先清除现有定时器
+  if (chartRotateTimer) {
+    clearInterval(chartRotateTimer);
+    chartRotateTimer = null;
+  }
+
+  // 设置新的定时器,5秒切换一次图表
+  chartRotateTimer = setInterval(() => {
+    currentProductIndex.value =
+      (currentProductIndex.value + 1) % chartData.value.length;
+    updateChart();
   }, 5000);
 };
 
+// 暂停所有定时器
+const pauseAllTimers = () => {
+  if (dataRefreshTimer) clearInterval(dataRefreshTimer);
+  if (chartRotateTimer) clearInterval(chartRotateTimer);
+};
+
+// 恢复所有定时器
+const resumeAllTimers = () => {
+  startDataRefresh();
+  startChartRotation();
+};
+
 // 更新图表
 const updateChart = () => {
   if (!chartInstance || chartData.value.length === 0) return;
@@ -102,7 +124,7 @@ const updateChart = () => {
           <div style="font-weight:bold;margin-bottom:5px">${params.name}</div>
           <div style="margin:3px 0">检验时长: ${item.duration}小时</div>
           <div style="margin:3px 0">占比: ${percentage}%</div>
-          <div style="margin:3px 0">状态: ${item.status === 1 ? "通过" : "未通过"}</div>
+          <div style="margin:3px 0">状态: ${item.status === 1 ? "完成" : "未完成"}</div>
         `;
       },
       backgroundColor: "rgba(0,0,0,0.8)",
@@ -119,7 +141,7 @@ const updateChart = () => {
         radius: ["40%", "60%"],
         center: ["50%", "50%"],
         avoidLabelOverlap: false,
-        selectedMode: "multiple", // 允许选中单个扇区
+        selectedMode: "multiple", // 允许多个扇区同时选中
         selectedOffset: 20, // 选中扇区的偏移量
         itemStyle: {
           borderRadius: 4,
@@ -188,26 +210,42 @@ const handleResize = () => {
 const loadData = async () => {
   try {
     const res = await qualityConsistentInspection(2);
-    chartData.value = res.data;
-    if (chartData.value.length > 0) {
-      updateChart();
+    const newData = res.data;
+
+    // 只有当数据确实发生变化时才更新
+    if (JSON.stringify(newData) !== JSON.stringify(chartData.value)) {
+      chartData.value = newData;
+
+      // 重置当前索引
+      currentProductIndex.value = 0;
+
+      // 如果图表已经初始化,则更新图表
+      if (chartInstance) {
+        updateChart();
+      } else {
+        initChart();
+      }
     }
   } catch (error) {
     console.error("加载数据失败:", error);
+  } finally {
+    // 确保定时器重新启动
+    if (!dataRefreshTimer) {
+      startDataRefresh();
+    }
   }
 };
 
 onMounted(() => {
-  initChart();
   loadData();
 });
 
 onBeforeUnmount(() => {
-  if (timer) clearInterval(timer);
+  // 清除所有定时器
+  pauseAllTimers();
+
+  // 销毁图表实例
   if (chartInstance) {
-    // 移除事件监听
-    chartInstance.off("mouseover");
-    chartInstance.off("mouseout");
     chartInstance.dispose();
     window.removeEventListener("resize", handleResize);
   }

+ 68 - 47
src/views/screens/screen-components/QualityGoal.vue

@@ -1,7 +1,12 @@
 <template>
   <div class="sliding-chart-container">
     <ScreenComHeader :module-id="moduleId" title="质量目标" />
-    <div ref="chartRef" style="width: 100%; height: 100%"></div>
+    <div
+      ref="chartRef"
+      style="width: 100%; height: 100%"
+      @mouseenter="pauseAllTimers"
+      @mouseleave="resumeAllTimers"
+    ></div>
   </div>
 </template>
 
@@ -20,9 +25,9 @@ const props = defineProps({
 const chartRef = ref(null);
 const chartData = ref([]);
 let chartInstance = null;
-let timer = null;
+let dataRefreshTimer = null; // 数据刷新定时器
+let chartRotateTimer = null; // 图表轮播定时器
 const currentIndex = ref(0);
-const isHovering = ref(false);
 
 // 初始化图表
 const initChart = () => {
@@ -31,38 +36,50 @@ const initChart = () => {
   chartInstance = echarts.init(chartRef.value);
   updateChart();
   window.addEventListener("resize", handleResize);
+  startChartRotation();
+};
 
-  // 获取图表DOM元素
-  const chartDom = chartRef.value;
+// 启动数据刷新定时器
+const startDataRefresh = () => {
+  // 先清除现有定时器
+  if (dataRefreshTimer) {
+    clearInterval(dataRefreshTimer);
+    dataRefreshTimer = null;
+  }
 
-  // 直接在DOM元素上添加事件监听
-  chartDom.addEventListener("mouseenter", () => {
-    isHovering.value = true;
-    pauseAutoPlay();
-  });
+  dataRefreshTimer = setInterval(() => {
+    loadData();
+  }, 300000);
+};
 
-  chartDom.addEventListener("mouseleave", () => {
-    isHovering.value = false;
-    startAutoPlay();
-  });
+// 启动图表轮播定时器
+const startChartRotation = () => {
+  // 只有数据多于1条时才需要轮播
+  if (chartData.value.length <= 1) return;
+
+  // 先清除现有定时器
+  if (chartRotateTimer) {
+    clearInterval(chartRotateTimer);
+    chartRotateTimer = null;
+  }
 
-  // 初始定时器
-  startAutoPlay();
+  // 设置新的定时器,5秒切换一次图表
+  chartRotateTimer = setInterval(() => {
+    currentIndex.value = (currentIndex.value + 1) % chartData.value.length;
+    updateChart();
+  }, 5000);
 };
 
-// 暂停自动播放
-const pauseAutoPlay = () => {
-  if (timer) {
-    clearInterval(timer);
-    timer = null;
-  }
+// 暂停所有定时器
+const pauseAllTimers = () => {
+  if (dataRefreshTimer) clearInterval(dataRefreshTimer);
+  if (chartRotateTimer) clearInterval(chartRotateTimer);
 };
 
-// 开始自动播放
-const startAutoPlay = () => {
-  if (!isHovering.value && !timer && chartData.value.length > 1) {
-    timer = setInterval(nextChart, 5000);
-  }
+// 恢复所有定时器
+const resumeAllTimers = () => {
+  startDataRefresh();
+  startChartRotation();
 };
 
 // 数据转换函数
@@ -349,13 +366,6 @@ const updateChart = () => {
   chartInstance.setOption(option, true);
 };
 
-const nextChart = () => {
-  if (chartData.value.length > 0) {
-    currentIndex.value = (currentIndex.value + 1) % chartData.value.length;
-    updateChart();
-  }
-};
-
 const handleResize = () => {
   chartInstance?.resize();
 };
@@ -363,34 +373,45 @@ const handleResize = () => {
 const loadData = async () => {
   try {
     const rowData = await qualityReport();
-    chartData.value = transformData(rowData.data);
-    if (chartData.value.length > 0) {
-      updateChart();
-      startAutoPlay();
+    const newData = transformData(rowData.data);
+
+    // 只有当数据确实发生变化时才更新
+    if (JSON.stringify(newData) !== JSON.stringify(chartData.value)) {
+      chartData.value = newData;
+
+      // 重置当前索引
+      currentIndex.value = 0;
+
+      // 如果图表已经初始化,则更新图表
+      if (chartInstance) {
+        updateChart();
+      } else {
+        initChart();
+      }
     }
   } catch (error) {
     console.error("加载数据失败:", error);
+  } finally {
+    // 确保定时器重新启动
+    if (!dataRefreshTimer) {
+      startDataRefresh();
+    }
   }
 };
 
 onMounted(() => {
-  initChart();
   loadData();
 });
 
 onBeforeUnmount(() => {
-  if (chartInstance) {
-    // 移除DOM事件监听
-    const chartDom = chartRef.value;
-    if (chartDom) {
-      chartDom.removeEventListener("mouseenter");
-      chartDom.removeEventListener("mouseleave");
-    }
+  // 清除所有定时器
+  pauseAllTimers();
 
+  // 销毁图表实例
+  if (chartInstance) {
     chartInstance.dispose();
     window.removeEventListener("resize", handleResize);
   }
-  pauseAutoPlay();
 });
 </script>
 

+ 63 - 19
src/views/screens/screen-components/SingleProductionQuantityCompletion.vue

@@ -4,8 +4,8 @@
     <div
       ref="chartRef"
       style="width: 100%; height: 100%"
-      @mouseenter="pauseAutoPlay"
-      @mouseleave="startAutoPlay"
+      @mouseenter="pauseAllTimers"
+      @mouseleave="resumeAllTimers"
     ></div>
   </div>
 </template>
@@ -25,7 +25,8 @@ const props = defineProps({
 const chartRef = ref(null);
 const chartData = ref([]);
 let chartInstance = null;
-let timer = null;
+let dataRefreshTimer = null; // 数据刷新定时器
+let chartRotateTimer = null; // 图表轮播定时器
 const currentIndex = ref(0);
 
 // 初始化图表
@@ -35,27 +36,50 @@ const initChart = () => {
   chartInstance = echarts.init(chartRef.value);
   updateChart();
   window.addEventListener("resize", handleResize);
-  startAutoPlay();
+  startChartRotation();
 };
 
-// 启动自动轮播
-const startAutoPlay = () => {
+// 启动数据刷新定时器
+const startDataRefresh = () => {
+  // 先清除现有定时器
+  if (dataRefreshTimer) {
+    clearInterval(dataRefreshTimer);
+    dataRefreshTimer = null;
+  }
+
+  dataRefreshTimer = setInterval(() => {
+    loadData();
+  }, 300000);
+};
+
+// 启动图表轮播定时器
+const startChartRotation = () => {
   // 只有数据多于1条时才需要轮播
   if (chartData.value.length <= 1) return;
 
-  pauseAutoPlay(); // 先清除现有定时器
-  timer = setInterval(() => {
+  // 先清除现有定时器
+  if (chartRotateTimer) {
+    clearInterval(chartRotateTimer);
+    chartRotateTimer = null;
+  }
+
+  // 设置新的定时器,5秒切换一次图表
+  chartRotateTimer = setInterval(() => {
     currentIndex.value = (currentIndex.value + 1) % chartData.value.length;
     updateChart();
-  }, 5000); // 5秒切换一次
+  }, 5000);
 };
 
-// 暂停自动轮播
-const pauseAutoPlay = () => {
-  if (timer) {
-    clearInterval(timer);
-    timer = null;
-  }
+// 暂停所有定时器
+const pauseAllTimers = () => {
+  if (dataRefreshTimer) clearInterval(dataRefreshTimer);
+  if (chartRotateTimer) clearInterval(chartRotateTimer);
+};
+
+// 恢复所有定时器
+const resumeAllTimers = () => {
+  startDataRefresh();
+  startChartRotation();
 };
 
 // 数据转换函数 - 只提取成品率数据
@@ -243,12 +267,29 @@ const handleResize = () => {
 const loadData = async () => {
   try {
     const rowData = await qualityReport();
-    chartData.value = transformData(rowData.data);
-    if (chartData.value.length > 0) {
-      initChart();
+    const newData = transformData(rowData.data);
+
+    // 只有当数据确实发生变化时才更新
+    if (JSON.stringify(newData) !== JSON.stringify(chartData.value)) {
+      chartData.value = newData;
+
+      // 重置当前索引
+      currentIndex.value = 0;
+
+      // 如果图表已经初始化,则更新图表
+      if (chartInstance) {
+        updateChart();
+      } else {
+        initChart();
+      }
     }
   } catch (error) {
     console.error("加载数据失败:", error);
+  } finally {
+    // 确保定时器重新启动
+    if (!dataRefreshTimer) {
+      startDataRefresh();
+    }
   }
 };
 
@@ -257,11 +298,14 @@ onMounted(() => {
 });
 
 onBeforeUnmount(() => {
+  // 清除所有定时器
+  pauseAllTimers();
+
+  // 销毁图表实例
   if (chartInstance) {
     chartInstance.dispose();
     window.removeEventListener("resize", handleResize);
   }
-  pauseAutoPlay();
 });
 </script>