From a4a795a986b009779f09e9a825c0099aa0bacbb8 Mon Sep 17 00:00:00 2001
From: zhoushihao <zsh19950802@163.com>
Date: 星期一, 18 八月 2025 16:41:34 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 UI-Project/src/views/largescreendisplay/screendisplay.vue | 1357 +++++++++++++++++++++++++++++++---------------------------
 1 files changed, 727 insertions(+), 630 deletions(-)

diff --git a/UI-Project/src/views/largescreendisplay/screendisplay.vue b/UI-Project/src/views/largescreendisplay/screendisplay.vue
index c462d41..f1127b4 100644
--- a/UI-Project/src/views/largescreendisplay/screendisplay.vue
+++ b/UI-Project/src/views/largescreendisplay/screendisplay.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onBeforeUnmount, onMounted, onUnmounted, ref, computed, nextTick } from "vue";
+import { onBeforeUnmount, onMounted, onUnmounted, ref, computed, nextTick, watch } from "vue";
 import { useRouter } from "vue-router"
 import { host, WebSocketHost } from '@/utils/constants'
 import request from "@/utils/request"
@@ -8,7 +8,11 @@
 import { ElMessage } from 'element-plus'
 import { useI18n } from 'vue-i18n'
 import * as echarts from 'echarts';
-
+import { debounce } from 'lodash-es';// 浣跨敤闃叉姈澶勭悊楂橀鏁版嵁鏇存柊
+// 浣跨敤娴呮瘮杈冨噺灏戜笉蹇呰鐨勫搷搴斿紡鏇存柊
+import { shallowRef } from 'vue';
+const rawGlassStorageDetailList = shallowRef([]);
+const orderDTOS = shallowRef([]);
 const load = ref(true)
 const edg = ref(true)
 const temp = ref(true)
@@ -20,10 +24,17 @@
 const { t } = useI18n()
 let language = ref(localStorage.getItem('lang') || 'zh')
 let socket = null;
-const rawGlassStorageDetailList = ref([])
-const orderDTOS = ref([])
+// const rawGlassStorageDetailList = ref([])
+// const orderDTOS = ref([])
 const socketUrl = `ws://${WebSocketHost}:${host}/api/glassStorage/api/talk/largenScreen`;
-const handleMessage = (data) => {
+const debouncedUpdate = debounce((data, handler) => {
+  handler(data);
+}, 300);
+let handleMessage = (data) => {
+  debouncedUpdate(data, (cleanData) => {
+    rawGlassStorageDetailList.value = cleanData.rawGlassStorageDetailList[0];
+    orderDTOS.value = cleanData.orderDTOS[0];
+  });
   rawGlassStorageDetailList.value = data.rawGlassStorageDetailList[0]
   orderDTOS.value = data.orderDTOS[0]
 };
@@ -32,407 +43,267 @@
 const edgTwoTasks = ref([])
 const engineeringOne = ref([])
 const engineeringTwo = ref([])
-
+// 鍚堝苟WebSocket杩炴帴锛屽噺灏戣繛鎺ユ暟
+const socketManager = {
+  sockets: {},
+  init(url, handler) {
+    if (!this.sockets[url]) {
+      this.sockets[url] = initializeWebSocket(url, handler);
+    }
+    return this.sockets[url];
+  },
+  closeAll() {
+    Object.values(this.sockets).forEach(socket => closeWebSocket(socket));
+    this.sockets = {};
+  }
+};
+let myChartLoad = null;
+let myChartEdg = null;
+let myChartTemp = null;
+let myChartHollow = null;
 const socketUrl1 = `ws://${WebSocketHost}:${host}/api/cacheGlass/api/talk/largenScreen`;
-const handleMessage1 = (data) => {
-  edgOneTasks.value = data.edgOneTasks[0];
-  edgTwoTasks.value = data.edgTwoTasks[0];
+let handleMessage1 = (data) => {
+  edgOneTasks.value = data.edgOneCount[0];
+  edgTwoTasks.value = data.edgOneCount[0];
   engineeringOne.value = data.engineeringOne[0];
   engineeringTwo.value = data.engineeringTwo[0];
-  if (numBoxes.value != edgOneTasks.value.length) {
-    numBoxes.value = edgOneTasks.value.length;
-    boxStart();
+  if (numBoxes.value != edgOneTasks.value) {
+    numBoxes.value = edgOneTasks.value;
+    initBoxes(boxes, numBoxes, 'firstup');
   }
-  if (numBoxes2.value != edgTwoTasks.value.length) {
-    numBoxes2.value = edgTwoTasks.value.length;
-    boxStart2();
+  if (numBoxes2.value != edgTwoTasks.value) {
+    numBoxes2.value = edgTwoTasks.value;
+    initBoxes(boxes2, numBoxes2, 'firstup');
   }
-  const pieChartVOS = ref([]);
-  pieChartVOS.value = data.pieChartVOS[0];
-
-  let oneFinish = ref();
-  let twoFinish = ref();
-  let oneunFinish = ref();
-  let twounFinish = ref();
-  if (pieChartVOS.length > 0) {
-    if (load.value) {
-      oneFinish = pieChartVOS.value[0].oneCompletedQuantity;
-      twoFinish = pieChartVOS.value[0].twoCompletedQuantity;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedQuantity;
-      twounFinish = pieChartVOS.value[0].twoUncompletedQuantity;
-    } else {
-      oneFinish = pieChartVOS.value[0].oneCompletedArea;
-      twoFinish = pieChartVOS.value[0].twoCompletedArea;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedArea;
-      twounFinish = pieChartVOS.value[0].twoUncompletedArea;
-    }
-  } else {
-    oneFinish = 0;
-    twoFinish = 0;
-    oneunFinish = 0;
-    twounFinish = 0;
-  }
-
-
-  const chartDomOne = chartOne.value;
-  if (!chartDomOne) {
-    console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
-    return;
-  }
-  const myChartOne = echarts.init(chartDomOne);
-  const optionOne = {
-    title: {
-      text: t('large.load'),
-      subtext: '',
-      left: 'right'
-    },
-    tooltip: {
-      trigger: 'item'
-    },
-    legend: {
-      orient: 'vertical',
-      left: 'left'
-    },
-    series: [
-      {
-        name: '',
-        type: 'pie',
-        radius: '50%',
-        data: [
-          { value: oneFinish, name: t('large.oneFinish') },
-          { value: twoFinish, name: t('large.twoFinish') },
-          { value: oneunFinish, name: t('large.oneunFinish') },
-          { value: twounFinish, name: t('large.twounFinish') },
-        ],
-        emphasis: {
-          itemStyle: {
-            shadowBlur: 10,
-            shadowOffsetX: 0,
-            shadowColor: 'rgba(0, 0, 0, 0.5)'
-          }
-        }
-      }
-    ],
-    graphic: [
-      {
-        type: 'rect',
-        left: 'center',
-        top: 0,
-        shape: {
-          width: 80,
-          height: 30
-        },
-        style: {
-          text: load.value == true ? t('large.quantity') : t('large.are'),
-          fill: '#5470C6',
-          stroke: '#000',
-          lineWidth: 1
-        },
-        onclick: function () {
-          load.value = !load.value;
-        }
-      }
-    ]
-  };
-
-  myChartOne.setOption(optionOne);
+  timeAxisCreate(t('large.cuttingState'), chartLoad.value, myChartLoad, tableDataTime(false, data.loadRunTimes[0]));
+  timeAxisCreate(t('large.edgingState'), chartEdg.value, myChartEdg, tableDataTime(false, data.loadRunTimes[0]));
 };
 let socket2 = null;
 const temperingTaskType = ref([])
 const temperingGlassInfoList = ref([])
 const temperingGlassInfoInList = ref([])
 const socketUrl2 = `ws://${WebSocketHost}:${host}/api/temperingGlass/api/talk/largenScreen`;
-const handleMessage2 = (data) => {
+let handleMessage2 = (data) => {
   temperingTaskType.value = data.temperingTaskType[0];
   temperingGlassInfoList.value = data.temperingGlassInfoList[0];
   if (numBoxes3.value != temperingTaskType.value) {
     numBoxes3.value = temperingTaskType.value;
-    boxStart3();
+    initBoxes(boxes3, numBoxes3, 'secondleft');
   }
-  if (temperingGlassInfoList.value > 1) {
-    numBoxes4.value = 1;
-  } else {
-    numBoxes4.value = 0;
-  }
-  temperingGlassInfoInList.value = data.temperingGlassInfoInList[0];
-  const pieChartVOS = ref([]);
-  pieChartVOS.value = data.pieChartVOS[0];
-  let oneFinish = ref();
-  let ondDamage = ref();
-  let oneunFinish = ref();
-  if (pieChartVOS.length > 0) {
-    if (temp.value) {
-      oneFinish = pieChartVOS.value[0].oneCompletedQuantity;
-      ondDamage = pieChartVOS.value[0].oneDamageQuantity;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedQuantity;
-    } else {
-      oneFinish = pieChartVOS.value[0].oneCompletedArea;
-      ondDamage = pieChartVOS.value[0].oneDamageArea;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedArea;
+  if (temperingGlassInfoList.value >= 1) {
+    if (numBoxes4.value != 1) {
+      numBoxes4.value = 1;
+      initBoxes(boxes4, numBoxes4, 'right');
     }
   } else {
-    oneFinish = 0;
-    ondDamage = 0;
-    oneunFinish = 0;
+    if (numBoxes4.value != 0) {
+      numBoxes4.value = 0;
+      initBoxes(boxes4, numBoxes4, 'right');
+    }
   }
-
-
-  const chartDomOne = chartThree.value;
-  if (!chartDomOne) {
-    console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
-    return;
-  }
-  const myChartOne = echarts.init(chartDomOne);
-  const optionOne = {
-    title: {
-      text: t('large.temp'),
-      subtext: '',
-      left: 'right'
-    },
-    tooltip: {
-      trigger: 'item'
-    },
-    legend: {
-      orient: 'vertical',
-      left: 'left'
-    },
-    series: [
-      {
-        name: '',
-        type: 'pie',
-        radius: '50%',
-        data: [
-          { value: oneFinish, name: t('large.oneFinish') },
-          { value: ondDamage, name: t('large.ondDamage') },
-          { value: oneunFinish, name: t('large.oneunFinish') },
-        ],
-        emphasis: {
-          itemStyle: {
-            shadowBlur: 10,
-            shadowOffsetX: 0,
-            shadowColor: 'rgba(0, 0, 0, 0.5)'
-          }
-        }
-      }
-    ],
-    graphic: [
-      {
-        type: 'rect',
-        left: 'center',
-        top: 0,
-        shape: {
-          width: 80,
-          height: 30
-        },
-        style: {
-          text: temp.value == true ? t('large.quantity') : t('large.are'),
-          fill: '#5470C6',
-          stroke: '#000',
-          lineWidth: 1
-        },
-        onclick: function () {
-          temp.value = !temp.value;
-        }
-      }
-    ]
-  };
-
-  myChartOne.setOption(optionOne);
+  temperingGlassInfoInList.value = data.temperingGlassInfoInList[0];
 };
 let socket3 = null;
 const bigStorageCageUsage = ref([])
 const socketUrl3 = `ws://${WebSocketHost}:${host}/api/cacheVerticalGlass/api/talk/largenScreen`;
-const handleMessage3 = (data) => {
+let handleMessage3 = (data) => {
   bigStorageCageUsage.value = data.bigStorageCageUsage[0];
-  const pieChartVOS = ref([]);
-  pieChartVOS.value = data.pieChartVOS[0];
-  let oneFinish = ref();
-  let twoFinish = ref();
-  let oneunFinish = ref();
-  let twounFinish = ref();
-  if (pieChartVOS.length > 0) {
-    if (edg.value) {
-      oneFinish = pieChartVOS.value[0].oneCompletedQuantity;
-      twoFinish = pieChartVOS.value[0].twoCompletedQuantity;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedQuantity;
-      twounFinish = pieChartVOS.value[0].twoUncompletedQuantity;
-    } else {
-      oneFinish = pieChartVOS.value[0].oneCompletedArea;
-      twoFinish = pieChartVOS.value[0].twoCompletedArea;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedArea;
-      twounFinish = pieChartVOS.value[0].twoUncompletedArea;
-    }
-  } else {
-    oneFinish = 0;
-    twoFinish = 0;
-    oneunFinish = 0;
-    twounFinish = 0;
+  timeAxisCreate(t('large.temperingState'), chartTemp.value, myChartTemp, tableDataTime(false, data.tempRunTimes[0]));
+};
+// let mychart = null; // 寤鸿璁句负澶栭儴鍙橀噺閬垮厤閲嶅鍒濆鍖�
+// const formatToTimeString(datetime)  => {
+const formatToTimeString = (datetime) => {
+  const date = new Date(datetime);
+  const hours = date.getHours().toString().padStart(2, '0');
+  const minutes = date.getMinutes().toString().padStart(2, '0');
+  const seconds = date.getSeconds().toString().padStart(2, '0');
+  return `${hours}:${minutes}:${seconds}`;
+}
+const tableDataTime = (result, tableDatax) => {
+  const tableData = [];
+  if (tableDatax.length > 0) {
+    tableDatax.forEach((item, index) => {
+      tableData.push({
+        firstTimestamp: index == 0 ? item.startTimestamp : tableDatax[index - 1].secondTimestamp,
+        secondTimestamp: index == tableDatax.length - 1 ? item.endTimestamp : item.firstTimestamp,
+        diffMinutes: item.diffMinutes,
+        startTimestamp: item.startTimestamp,
+        endTimestamp: item.endTimestamp,
+        state: 1
+      });
+      if (result) {
+        tableData.push({
+          firstTimestamp: item.firstTimestamp,
+          secondTimestamp: item.secondTimestamp,
+          diffMinutes: item.diffMinutes,
+          startTimestamp: item.startTimestamp,
+          endTimestamp: item.endTimestamp,
+          state: 2
+        });
+      }
+    });
   }
-
-
-  const chartDomOne = chartTwo.value;
-  if (!chartDomOne) {
+  return tableData;
+};
+const timeAxisCreate = (title, chartDom, mychart, RunTimes) => {
+  if (!chartDom) {
     console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
     return;
   }
-  const myChartOne = echarts.init(chartDomOne);
-  const optionOne = {
-    title: {
-      text: t('large.edg'),
-      subtext: '',
-      left: 'right'
-    },
-    tooltip: {
-      trigger: 'item'
-    },
-    legend: {
-      orient: 'vertical',
-      left: 'left'
-    },
-    series: [
+  if (!mychart) {
+    mychart = echarts.init(chartDom);
+  }
+  let firstTime = null;
+  let secondTime = null;
+  if (RunTimes.length == 0) {
+    firstTime = "00-00-00 00:00:00";
+    secondTime = "00-00-00 00:00:00";
+  } else {
+    firstTime = RunTimes[0].startTimestamp;
+    secondTime = RunTimes[0].endTimestamp;
+  }
+  // 鏋勫缓绾挎鏁扮粍
+  const segments = RunTimes.map(item => ({
+    type: 'line',
+    symbol: 'none',
+    data: [
       {
-        name: '',
-        type: 'pie',
-        radius: '50%',
-        data: [
-          { value: oneFinish, name: t('large.oneFinish') },
-          { value: twoFinish, name: t('large.twoFinish') },
-          { value: oneunFinish, name: t('large.oneunFinish') },
-          { value: twounFinish, name: t('large.twounFinish') },
-        ],
-        emphasis: {
-          itemStyle: {
-            shadowBlur: 10,
-            shadowOffsetX: 0,
-            shadowColor: 'rgba(0, 0, 0, 0.5)'
-          }
+        value: [item.firstTimestamp, 0],
+        extra: {
+          start: item.firstTimestamp,
+          end: item.secondTimestamp
+        }
+      },
+      {
+        value: [item.secondTimestamp, 0],
+        extra: {
+          start: item.firstTimestamp,
+          end: item.secondTimestamp
         }
       }
     ],
-    graphic: [
-      {
-        type: 'rect',
-        left: 'center',
-        top: 0,
-        shape: {
-          width: 80,
-          height: 30
-        },
-        style: {
-          text: edg.value == true ? t('large.quantity') : t('large.are'),
-          fill: '#5470C6',
-          stroke: '#000',
-          lineWidth: 1
-        },
-        onclick: function () {
-          edg.value = !edg.value;
-        }
+    lineStyle: {
+      color: 'red', // 鏀寔涓嶅悓棰滆壊
+      width: 4
+    },
+    z: 1
+  }));
+  const optionOne = {
+    title: {
+      text: title,
+      left: 'center',
+      top: '5%',
+      textStyle: {
+        fontSize: 16,
+        fontWeight: 'bold',
+        color: '#333'
       }
+    },
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: { type: 'line' },
+      backgroundColor: 'rgba(50,50,50,0.7)',
+      textStyle: { color: '#fff' },
+      formatter: (params) => {
+        const seen = new Set();
+        const items = params
+          .filter(p => {
+            const key = p.data?.extra?.start + '|' + p.data?.extra?.end;
+            if (seen.has(key)) return false;
+            seen.add(key);
+            return true;
+          })
+          .map(p => {
+            const start = p.data?.extra?.start;
+            const end = p.data?.extra?.end;
+            const timeStr = p.axisValueLabel;
+            if (start && end) {
+              return `寮�濮嬫椂闂达細${start}<br/>缁撴潫鏃堕棿锛�${end}`;
+            }
+            return `鏃堕棿锛�${timeStr}`;
+          })
+          .filter(Boolean);
+        return items.join('<br/>');
+      }
+    },
+    grid: {
+      top: '20%',
+      left: '5%',
+      right: '5%',
+      bottom: '15%'
+    },
+    xAxis: {
+      type: 'time',
+      axisLabel: {
+        formatter: function (value) {
+          const date = new Date(value);
+          return (
+            date.getHours().toString().padStart(2, '0') + ':' +
+            date.getMinutes().toString().padStart(2, '0') + ':' +
+            date.getSeconds().toString().padStart(2, '0')
+          );
+        },
+        fontSize: 10,
+        color: '#666'
+      },
+      splitLine: { show: false },
+      axisLine: { lineStyle: { color: '#aaa' } }
+    },
+    yAxis: {
+      type: 'value',
+      min: -1,
+      max: 1,
+      show: false
+    },
+    series: [
+      // 涓绘椂闂寸嚎锛堣摑鑹叉笎鍙橈紝绋嶅井鍔犵矖锛�
+      {
+        type: 'line',
+        symbol: 'none',
+        data: [
+          [firstTime, 0],
+          [secondTime, 0]
+        ],
+        lineStyle: {
+          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+            { offset: 0, color: 'red' },
+            { offset: 1, color: 'red' }
+          ]),
+          width: 5,
+          shadowColor: 'rgba(0,0,0,0.2)',
+          shadowBlur: 8
+        },
+        z: 0
+      },
+      // 灏忔鏃堕棿绾匡紙缁熶竴鏌斿拰鐨勯粍鑹诧級
+      ...segments.map(seg => ({
+        ...seg,
+        lineStyle: {
+          color: '#4facfe',
+          width: 3,
+          shadowColor: 'rgba(255,204,0,0.5)',
+          shadowBlur: 5
+        }
+      })),
     ]
   };
-
-  myChartOne.setOption(optionOne);
+  mychart.setOption(optionOne, true);
 };
 let socket4 = null;
 const hollowBigStorageCageUsage = ref([])
 const socketUrl4 = `ws://${WebSocketHost}:${host}/api/hollowGlass/api/talk/largenScreen`;
-const handleMessage4 = (data) => {
+let handleMessage4 = (data) => {
   hollowBigStorageCageUsage.value = data.hollowBigStorageCageUsage[0];
-  const pieChartVOS = ref([]);
-  pieChartVOS.value = data.pieChartVOS[0];
-  let oneFinish = ref();
-  let twoFinish = ref();
-  let oneunFinish = ref();
-  let twounFinish = ref();
-  if (pieChartVOS.length > 0) {
-    if (hollow.value) {
-      oneFinish = pieChartVOS.value[0].oneCompletedQuantity;
-      twoFinish = pieChartVOS.value[0].twoCompletedQuantity;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedQuantity;
-      twounFinish = pieChartVOS.value[0].twoUncompletedQuantity;
-    } else {
-      oneFinish = pieChartVOS.value[0].oneCompletedArea;
-      twoFinish = pieChartVOS.value[0].twoCompletedArea;
-      oneunFinish = pieChartVOS.value[0].oneUncompletedArea;
-      twounFinish = pieChartVOS.value[0].twoUncompletedArea;
-    }
-  } else {
-    oneFinish = 0;
-    twoFinish = 0;
-    oneunFinish = 0;
-    twounFinish = 0;
-  }
-
-
-  const chartDomOne = chartFour.value;
-  if (!chartDomOne) {
-    console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
-    return;
-  }
-  const myChartOne = echarts.init(chartDomOne);
-  const optionOne = {
-    title: {
-      text: t('large.hollow'),
-      subtext: '',
-      left: 'right'
-    },
-    tooltip: {
-      trigger: 'item'
-    },
-    legend: {
-      orient: 'vertical',
-      left: 'left'
-    },
-    series: [
-      {
-        name: '',
-        type: 'pie',
-        radius: '50%',
-        data: [
-          { value: oneFinish, name: t('large.oneFinish') },
-          { value: twoFinish, name: t('large.twoFinish') },
-          { value: oneunFinish, name: t('large.oneunFinish') },
-          { value: twounFinish, name: t('large.twounFinish') },
-        ],
-        emphasis: {
-          itemStyle: {
-            shadowBlur: 10,
-            shadowOffsetX: 0,
-            shadowColor: 'rgba(0, 0, 0, 0.5)'
-          }
-        }
-      }
-    ],
-    graphic: [
-      {
-        type: 'rect',
-        left: 'center',
-        top: 0,
-        shape: {
-          width: 80,
-          height: 30
-        },
-        style: {
-          text: hollow.value == true ? t('large.quantity') : t('large.are'),
-          fill: '#5470C6',
-          stroke: '#000',
-          lineWidth: 1
-        },
-        onclick: function () {
-          hollow.value = !hollow.value;
-        }
-      }
-    ]
-  };
-
-  myChartOne.setOption(optionOne);
+  timeAxisCreate(t('large.hollowState'), chartHollow.value, myChartHollow, tableDataTime(false, data.hollowRunTimes[0]));
 };
 let socket5 = null;
+let myChart = null;
+let myChart2 = null;
+const switchNoorAreaLeft = ref(true)
+const switchNoorAreaRight = ref(true)
 const productionVO = ref([])
 const socketUrl5 = `ws://${WebSocketHost}:${host}/api/cacheGlass/api/talk/largenScreenProduction`;
-const handleMessage5 = (data) => {
-  productionVO.value = data.productionVO[0];
-  // 灏嗗師濮嬫暟鎹浆鎹负 ECharts 鍥捐〃鎵�闇�鏍煎紡
+const createchart = (productionVO) => {
   categories = productionVO.value.map(item => item.date); // 鑾峰彇鏃ユ湡浣滀负 x 杞�
   totalAreaOutOne = productionVO.value.map(item => item.totalAreaOutOne);
   countIn = productionVO.value.map(item => item.countIn);
@@ -453,81 +324,151 @@
     console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
     return;
   }
-
-  const myChart = echarts.init(chartDom);
-
-
+  if (!myChart) {
+    myChart = echarts.init(chartDom);
+  }
+  let loadOneData;
+  let loadTwoData;
+  let tempfontData;
+  if (switchNoorAreaLeft.value) {
+    loadOneData = countOutOne;
+    loadTwoData = countOutTwo;
+    tempfontData = countIn;
+  } else {
+    loadOneData = totalAreaOutOne;
+    loadTwoData = totalAreaOutTwo;
+    tempfontData = totalAreaIn;
+  }
   const option = {
     title: { text: '' },
     tooltip: { trigger: 'axis' },
     legend: {
       data: [
         t('large.countOutOne'),
-        t('large.totalAreaOutOne'),
+        // t('large.totalAreaOutOne'),
         t('large.countOutTwo'),
-        t('large.totalAreaOutTwo'),
+        // t('large.totalAreaOutTwo'),
         t('large.countIn'),
-        t('large.totalAreaIn')
+        // t('large.totalAreaIn')
       ]
     },
-    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
-    toolbox: { feature: { saveAsImage: {} } },
+    grid: { top: '20%', left: '3%', right: '4%', bottom: '3%', containLabel: true },
+    toolbox: {
+      feature: {
+        saveAsImage: {},
+        myTool1: {
+          show: true,
+          title: t('large.switch'),
+          icon: 'path://M512 0C229.234 0 0 229.234 0 512s229.234 512 512 512 512-229.234 512-512S794.766 0 512 0z m0 960C264.602 960 64 759.398 64 512S264.602 64 512 64s448 200.602 448 448-200.602 448-448 448z m0-768c-176.448 0-320 143.552-320 320s143.552 320 320 320 320-143.552 320-320-143.552-320-320-320z', // 鍦嗗舰鎸夐挳鍥炬爣锛堝彲鎹級
+          onclick: function () {
+            switchNoorAreaLeft.value = !switchNoorAreaLeft.value;
+            createchart(productionVO);
+            // customButtonClick(); // 璋冪敤浣犺嚜瀹氫箟鐨勬柟娉�
+          }
+        }
+      }
+    },
     xAxis: {
       type: 'category',
-      boundaryGap: false,
+      boundaryGap: true,
       data: categories // 杩欐槸鏃ユ湡鏁版嵁
     },
-    yAxis: { type: 'value' },
+    yAxis: {
+      type: 'value',
+      name: switchNoorAreaLeft.value==true?t('large.quantity'):t('large.are'), // 鍧愭爣杞村悕绉�
+      axisLabel: {
+        formatter: '{value}'
+      }
+    },
     series: [
-      { name: t('large.countOutOne'), type: 'bar', data: countOutOne },
-      { name: t('large.totalAreaOutOne'), type: 'bar', data: totalAreaOutOne },
-      { name: t('large.countOutTwo'), type: 'bar', data: countOutTwo },
-      { name: t('large.totalAreaOutTwo'), type: 'bar', data: totalAreaOutTwo },
-      { name: t('large.countIn'), type: 'bar', data: countIn },
-      { name: t('large.totalAreaIn'), type: 'bar', data: totalAreaIn }
+      { name: t('large.countOutOne'), type: 'bar', data: loadOneData },
+      // { name: t('large.totalAreaOutOne'), type: 'bar', data: totalAreaOutOne },
+      { name: t('large.countOutTwo'), type: 'bar', data: loadTwoData },
+      // { name: t('large.totalAreaOutTwo'), type: 'bar', data: totalAreaOutTwo },
+      { name: t('large.countIn'), type: 'bar', data: tempfontData },
+      // { name: t('large.totalAreaIn'), type: 'bar', data: totalAreaIn }
     ]
   };
-
-  myChart.setOption(option);
-
+  myChart.setOption(option, true);
   const chartDom2 = chartRef2.value;
   if (!chartDom2) {
     console.error('鍥捐〃瀹瑰櫒鏈壘鍒�');
     return;
   }
-  const myChart2 = echarts.init(chartDom2);
+  // myChart2 = echarts.init(chartDom2);
+  if (!myChart2) {
+    myChart2 = echarts.init(chartDom2);
+  }
+  // else {
+  //     myChart2.clear();
+  //   }
+  let tempData;
+  let hollowOneData;
+  let hollowTwoData;
+  if (switchNoorAreaRight.value) {
+    tempData = countOut;
+    hollowOneData = hollowCountOutOne;
+    hollowTwoData = hollowCountOutTwo;
+  } else {
+    tempData = totalAreaOut;
+    hollowOneData = hollowTotalAreaOutOne;
+    hollowTwoData = hollowTotalAreaOutTwo;
+  }
   const option2 = {
     title: { text: '' },
     tooltip: { trigger: 'axis' },
     legend: {
       data: [
-        t('large.totalAreaOut'),
         t('large.countOut'),
-        t('large.hollowTotalAreaOutOne'),
+        // t('large.totalAreaOut'),
         t('large.hollowCountOutOne'),
+        // t('large.hollowTotalAreaOutOne'),
         t('large.hollowCountOutTwo'),
-        t('large.hollowTotalAreaOutTwo')
+        // t('large.hollowTotalAreaOutTwo')
       ]
     },
     grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
-    toolbox: { feature: { saveAsImage: {} } },
+    toolbox: {
+      feature: {
+        saveAsImage: {},
+        myTool1: {
+          show: true,
+          title: t('large.switch'),
+          icon: 'path://M512 0C229.234 0 0 229.234 0 512s229.234 512 512 512 512-229.234 512-512S794.766 0 512 0z m0 960C264.602 960 64 759.398 64 512S264.602 64 512 64s448 200.602 448 448-200.602 448-448 448z m0-768c-176.448 0-320 143.552-320 320s143.552 320 320 320 320-143.552 320-320-143.552-320-320-320z', // 鍦嗗舰鎸夐挳鍥炬爣锛堝彲鎹級
+          onclick: function () {
+            switchNoorAreaRight.value = !switchNoorAreaRight.value;
+            createchart(productionVO);
+            // customButtonClick(); // 璋冪敤浣犺嚜瀹氫箟鐨勬柟娉�
+          }
+        }
+      }
+    },
     xAxis: {
       type: 'category',
-      boundaryGap: false,
+      boundaryGap: true,
       data: categories // 杩欐槸鏃ユ湡鏁版嵁
     },
-    yAxis: { type: 'value' },
+    yAxis: {
+      type: 'value',
+      name: switchNoorAreaRight.value==true?t('large.quantity'):t('large.are'), // 鍧愭爣杞村悕绉�
+      axisLabel: {
+        formatter: '{value}'
+      }
+    },
     series: [
-      { name: t('large.totalAreaOut'), type: 'bar', data: totalAreaOut },
-      { name: t('large.countOut'), type: 'bar', data: countOut },
-      { name: t('large.hollowTotalAreaOutOne'), type: 'bar', data: hollowTotalAreaOutOne },
-      { name: t('large.hollowCountOutOne'), type: 'bar', data: hollowCountOutOne },
-      { name: t('large.hollowCountOutTwo'), type: 'bar', data: hollowCountOutTwo },
-      { name: t('large.hollowTotalAreaOutTwo'), type: 'bar', data: hollowTotalAreaOutTwo }
+      // { name: t('large.totalAreaOut'), type: 'bar', data: tempData },
+      { name: t('large.countOut'), type: 'bar', data: tempData },
+      // { name: t('large.hollowTotalAreaOutOne'), type: 'bar', data: hollowOneData },
+      { name: t('large.hollowCountOutOne'), type: 'bar', data: hollowOneData },
+      // { name: t('large.hollowTotalAreaOutTwo'), type: 'bar', data: hollowTwoData },
+      { name: t('large.hollowCountOutTwo'), type: 'bar', data: hollowTwoData }
     ]
   };
-
-  myChart2.setOption(option2);
+  myChart2.setOption(option2, true);
+}
+let handleMessage5 = (data) => {
+  productionVO.value = data.productionVO[0];
+  createchart(productionVO);
 };
 // 灏嗗師濮嬫暟鎹浆鎹负 ECharts 鍥捐〃鎵�闇�鏍煎紡
 let categories = ref([]); // 鑾峰彇鏃ユ湡浣滀负 x 杞�
@@ -543,7 +484,6 @@
 let hollowTotalAreaOutOne = ref([]);
 let totalAreaIn = ref([]);
 let countOutOne = ref([]);
-
 const tableDatad = ref([]);
 const patternUsage = async () => {
   try {
@@ -559,7 +499,14 @@
     console.error(error);
   }
 }
-
+const exportToExcel = async () => {
+  try {
+    window.open(`http://${WebSocketHost}:10011/largenScreen/exportDailyProduction`, '_blank');
+  }
+  catch (error) {
+    console.error(error);
+  }
+}
 const tableData = ref([]);
 const dynamicColumns = ref([]);
 const flowCardDetail = async (orderId) => {
@@ -578,7 +525,6 @@
           prop: key,
           label: key,
         }));
-
         // 瑙f瀽鏁版嵁骞跺皢 JSON 瀛楃涓茶浆鎹负瀵硅薄
         tableData.value = response.data.map((item) => {
           const reportData = JSON.parse(item.reportWorkQuantity || "{}");
@@ -596,7 +542,6 @@
     console.error(error);
   }
 }
-
 const ptnusage = ref({
   width: '',
   height: '',
@@ -610,31 +555,61 @@
 };
 const chartRef = ref(null)
 const chartRef2 = ref(null)
-const chartOne = ref(null)
-const chartTwo = ref(null)
-const chartThree = ref(null)
-const chartFour = ref(null)
-
-
+const chartLoad = ref(null)
+const chartEdg = ref(null)
+const chartTemp = ref(null)
+const chartHollow = ref(null)
+const cleanupWebSocketData = (completeCleanup) => {
+  if (completeCleanup) {
+    // 瀹屽叏娓呯悊
+    rawGlassStorageDetailList.value = [];
+    orderDTOS.value = [];
+  } else {
+    // 閮ㄥ垎娓呯悊 - 淇濈暀鏈�杩戞暟鎹�
+    const MAX_ITEMS = 50;
+    rawGlassStorageDetailList.value = rawGlassStorageDetailList.value.slice(-MAX_ITEMS);
+    orderDTOS.value = orderDTOS.value.slice(-MAX_ITEMS);
+  }
+  // 娓呯悊鍥捐〃
+  [myChart, myChart2, myChartLoad, myChartEdg, myChartTemp, myChartHollow].forEach(chart => {
+    if (chart) {
+      chart.clear();
+      // 濡傛灉闇�瑕侊紝鍙互閲嶆柊鍒濆鍖栧浘琛�
+    }
+  });
+};
 // 鍦ㄧ粍浠舵寕杞芥椂璁剧疆榛樿鏃堕棿鑼冨洿
 onMounted(async () => {
-
-  boxStart();
-  boxStart2();
-  boxStart3();
-  boxStart4();
-  requestAnimationFrame(animate);
-  socket = initializeWebSocket(socketUrl, handleMessage);
-  socket1 = initializeWebSocket(socketUrl1, handleMessage1);
-  socket2 = initializeWebSocket(socketUrl2, handleMessage2);
-  socket3 = initializeWebSocket(socketUrl3, handleMessage3);
-  socket4 = initializeWebSocket(socketUrl4, handleMessage4);
-  socket5 = initializeWebSocket(socketUrl5, handleMessage5);
+  socketManager.init(socketUrl, handleMessage);
+  socketManager.init(socketUrl1, handleMessage1);
+  socketManager.init(socketUrl2, handleMessage2);
+  socketManager.init(socketUrl3, handleMessage3);
+  socketManager.init(socketUrl4, handleMessage4);
+  socketManager.init(socketUrl5, handleMessage5);
+  // socket = initializeWebSocket(socketUrl, handleMessage);
+  // socket1 = initializeWebSocket(socketUrl1, handleMessage1);
+  // socket2 = initializeWebSocket(socketUrl2, handleMessage2);
+  // socket3 = initializeWebSocket(socketUrl3, handleMessage3);
+  // socket4 = initializeWebSocket(socketUrl4, handleMessage4);
+  // socket5 = initializeWebSocket(socketUrl5, handleMessage5);
   const endTime = dayjs().startOf('minute'); // 褰撳墠鏃堕棿锛岀簿纭埌鍒嗛挓
   const startTime = endTime.subtract(1, 'day').startOf('minute'); // 褰撳墠鏃堕棿鐨勫墠涓�澶╋紝绮剧‘鍒板垎閽�
   // 璁剧疆鏃堕棿鑼冨洿涓� [寮�濮嬫椂闂�, 缁撴潫鏃堕棿]
   // timeRange.value = [startTime.format('YYYY-MM-DD HH:mm:ss'), endTime.format('YYYY-MM-DD HH:mm:ss')];
-
+  const cleanupInterval = setInterval(() => {
+    cleanupWebSocketData(true); // 瀹屽叏娓呯悊
+  }, 300000);
+  // 姣忔鏀跺埌娑堟伅鏃舵鏌ユ暟鎹噺
+  const originalHandleMessage = handleMessage;
+  handleMessage = (data) => {
+    originalHandleMessage(data);
+    cleanupWebSocketData(false); // 閮ㄥ垎娓呯悊
+  };
+  onUnmounted(() => {
+  socketManager.closeAll();
+    clearInterval(cleanupInterval);
+    cleanupWebSocketData(true); // 缁勪欢鍗歌浇鏃跺畬鍏ㄦ竻鐞�
+  });
 });
 // onMounted(() => {
 //   socket = initializeWebSocket(socketUrl, handleMessage);
@@ -649,194 +624,225 @@
     closeWebSocket(socket5);
   }
 });
-onBeforeUnmount(() => {
-  closeWebSocket();
-});
-const numBoxes = ref(5);
-const numBoxes2 = ref(5);
-const numBoxes3 = ref(5);
-const numBoxes4 = ref(1);
+const numBoxes = ref(0);
+const numBoxes2 = ref(0);
+const numBoxes3 = ref(0);
+const numBoxes4 = ref(0);
 const speed = 0.1;
-const maxX = 200; // 缁堢偣X鍧愭爣
-const maxY = -75; // 缁堢偣Y鍧愭爣
-const maxX2 = 313; // 缁堢偣X鍧愭爣
-const maxY2 = -165; // 缁堢偣Y鍧愭爣
-const maxX3 = 95; // 缁堢偣X鍧愭爣
-const maxY3 = -85; // 缁堢偣Y鍧愭爣
-const maxX4 = 60; // 缁堢偣X鍧愭爣
-const maxY4 = 0; // 缁堢偣Y鍧愭爣
-const delayFrames = 600; // 姣忎釜 div 鐨勫欢杩熷抚鏁�
-const boxes = ref([]);
-const boxes2 = ref([]);
-const boxes3 = ref([]);
-const boxes4 = ref([]);
-// 鍒濆鍖� div 鏁版嵁
-const boxStart = () => {
-  boxes.value = [];
-  for (let i = 0; i < numBoxes.value; i++) {
-    boxes.value.push({
-      x: 0,
-      y: 0, // 鍒濆浣嶇疆鍦ㄥ簳閮�
-      direction: 'up',
-      delay: i * delayFrames,
-      style: {
-        width: '15px',
-        height: '15px',
-        backgroundColor: i % 2 === 0 ? '#911005' : '#911005',
-        position: 'absolute',
-        transform: `translate(0px, 0px)`
-      }
-    });
-  }
-}
-const boxStart2 = () => {
-  boxes2.value = [];
-  for (let i = 0; i < numBoxes2.value; i++) {
-    boxes2.value.push({
-      x: 0,
-      y: 0, // 鍒濆浣嶇疆鍦ㄥ簳閮�
-      direction: 'up',
-      delay: i * delayFrames,
-      style: {
-        width: '15px',
-        height: '15px',
-        backgroundColor: i % 2 === 0 ? '#911005' : '#911005',
-        position: 'absolute',
-        transform: `translate(0px, 0px)`
-      }
-    });
-  }
-}
-const boxStart3 = () => {
-  boxes3.value = [];
-  for (let i = 0; i < numBoxes3.value; i++) {
-    boxes3.value.push({
-      x: 0,
-      y: 0, // 鍒濆浣嶇疆鍦ㄥ簳閮�
-      direction: 'left',
-      delay: i * delayFrames,
-      style: {
-        width: '15px',
-        height: '15px',
-        backgroundColor: i % 2 === 0 ? '#911005' : '#911005',
-        position: 'absolute',
-        transform: `translate(0px, 0px)`
-      }
-    });
-  }
-}
-const boxStart4 = () => {
-  boxes4.value = [];
-  for (let i = 0; i < numBoxes4.value; i++) {
-    boxes4.value.push({
-      x: 0,
-      y: 0, // 鍒濆浣嶇疆鍦ㄥ簳閮�
-      direction: 'right',
-      delay: i * delayFrames,
-      style: {
-        width: '15px',
-        height: '15px',
-        backgroundColor: i % 2 === 0 ? '#911005' : '#911005',
-        position: 'absolute',
-        transform: `translate(0px, 0px)`
-      }
-    });
-  }
-}
-const animate = () => {
-  boxes.value.forEach((box) => {
-    if (box.delay > 0) {
-      box.delay--;
-      return;
+const delayFrames = 600;
+const maxCoords = {
+  box1: { x: 250, y: -165 },
+  box2: { x: 190, y: -75 },
+  box3: { x: 95, y: -85 },
+  box4: { x: 60, y: 0 },
+};
+let boxes = ref([]);
+let boxes2 = ref([]);
+let boxes3 = ref([]);
+let boxes4 = ref([]);
+const boxRefs = [];
+const boxRefs2 = [];
+const boxRefs3 = [];
+const boxRefs4 = [];
+let rafId = null;
+// 鉁� 鍒濆鍖� boxes锛屽幓闄� style锛屼繚鐣� el
+const initBoxes = (arr, countRef, direction) => {
+  const count = countRef.value;
+  const existing = arr.value;
+  for (let i = 0; i < count; i++) {
+    if (!existing[i]) {
+      existing.push({
+        x: 0,
+        y: 0,
+        direction,
+        delay: i * delayFrames,
+        frameCount: 0,
+        el: null
+      });
+    } else {
+      // 閲嶇疆宸叉湁鐨� box 鏁版嵁
+      // existing[i].x = 0;
+      // existing[i].y = 0;
+      // existing[i].direction = direction;
+      // existing[i].delay = i * delayFrames;
+      // existing[i].frameCount = 0;
     }
-    if (box.direction === 'up') {
+  }
+  if (existing.length > count) {
+    existing.length = count;
+  }
+};
+// 鉁� 鍔ㄧ敾鍑芥暟
+const animateBox = (box, maxX, maxY) => {
+  if (box.delay > 0) {
+    box.delay--;
+    return;
+  }
+  switch (box.direction) {
+    case 'firstup':
       box.y -= speed;
-      if (box.y <= maxY) {
-        // box.y = 0; // 纭繚涓嶄細瓒呭嚭鐣岄檺
-        box.direction = 'left';
-      }
-    } else if (box.direction === 'left') {
+      if (box.y <= maxY) box.direction = 'firstleft';
+      break;
+    case 'firstleft':
       box.x -= speed;
       if (box.x <= -maxX) {
         box.x = 0;
-        box.y = 0; // 閲嶆柊鍥炲埌搴曢儴
-        box.direction = 'up';
+        box.y = 0;
+        box.direction = 'firstup';
       }
-    }
-    box.style = {
-      ...box.style,
-      transform: `translate(${box.x}px, ${box.y}px)`
-    };
-  });
-  boxes2.value.forEach((box) => {
-    if (box.delay > 0) {
-      box.delay--;
-      return;
-    }
-    if (box.direction === 'up') {
+      break;
+    case 'secondup':
       box.y -= speed;
-      if (box.y <= maxY2) {
-        // box.y = 0; // 纭繚涓嶄細瓒呭嚭鐣岄檺
-        box.direction = 'left';
-      }
-    } else if (box.direction === 'left') {
-      box.x -= speed;
-      if (box.x <= -maxX2) {
+      if (box.y <= maxY) {
         box.x = 0;
-        box.y = 0; // 閲嶆柊鍥炲埌搴曢儴
-        box.direction = 'up';
+        box.y = 0;
+        box.direction = 'secondleft';
       }
-    }
-    box.style = {
-      ...box.style,
-      transform: `translate(${box.x}px, ${box.y}px)`
-    };
-  });
-  boxes3.value.forEach((box) => {
-    if (box.delay > 0) {
-      box.delay--;
-      return;
-    }
-    if (box.direction === 'up') {
-      box.y -= speed;
-      if (box.y <= maxY3) {
-        // box.y = 0; // 纭繚涓嶄細瓒呭嚭鐣岄檺
-        box.direction = 'left';
-        box.x = 0;
-        box.y = 0; // 閲嶆柊鍥炲埌搴曢儴
-      }
-    } else if (box.direction === 'left') {
+      break;
+    case 'secondleft':
       box.x -= speed;
-      if (box.x <= -maxX3) {
-
-        box.direction = 'up';
+      if (box.x <= -maxX) {
+        box.direction = 'secondup';
       }
-    }
-    box.style = {
-      ...box.style,
-      transform: `translate(${box.x}px, ${box.y}px)`
-    };
-  });
-  boxes4.value.forEach((box) => {
-    if (box.delay > 0) {
-      box.delay--;
-      return;
-    }
-    if (box.direction === 'right') {
+      break;
+    case 'right':
       box.x += speed;
-      if (box.x >= maxX4) {
-        // box.y = 0; // 纭繚涓嶄細瓒呭嚭鐣岄檺
+      if (box.x >= maxX) {
         box.x = 0;
-        box.y = 0; // 閲嶆柊鍥炲埌搴曢儴
+        box.y = 0;
       }
+      break;
+  }
+  box.frameCount++;
+  if (box.frameCount % 2 === 0 && box.el) {
+    box.el.style.top = `${box.y}px`;
+    if (box.x > 0) {
+      if (box.direction == "right") {
+        box.el.style.right = `-${box.x}px`;
+      } else {
+        box.el.style.right = `${box.x}px`;
+      }
+      box.el.style.left = '';
+    } else {
+      box.el.style.left = `${box.x}px`;
+      box.el.style.right = '';
     }
-    box.style = {
-      ...box.style,
-      transform: `translate(${box.x}px, ${box.y}px)`
-    };
-  });
-  requestAnimationFrame(animate);
+  }
 };
+// 浼樺寲鍔ㄧ敾鎬ц兘
+const animate = () => {
+  if (!rafId) {
+    const start = performance.now();
+    const updateBoxes = (boxes, maxX, maxY) => {
+      boxes.value.forEach(box => {
+        if (box.delay > 0) {
+          box.delay--;
+          return;
+        }
+        // 绠�鍖栧姩鐢婚�昏緫
+        switch (box.direction) {
+          case 'firstup':
+            box.y = Math.max(box.y - speed, maxY);
+            if (box.y <= maxY) box.direction = 'firstleft';
+            break;
+          case 'firstleft':
+            box.x = Math.max(box.x - speed, -maxX);
+            if (box.x <= -maxX) {
+              box.x = 0;
+              box.y = 0;
+              box.direction = 'firstup';
+            }
+            break;
+          // 鍏朵粬case绠�鍖�...
+        }
+        // 鎵归噺鏇存柊DOM
+        requestAnimationFrame(() => {
+          if (box.el) {
+            box.el.style.transform = `translate(${box.x}px, ${box.y}px)`;
+          }
+        });
+      });
+    };
+    updateBoxes(boxes, maxCoords.box1.x, maxCoords.box1.y);
+    updateBoxes(boxes2, maxCoords.box2.x, maxCoords.box2.y);
+    updateBoxes(boxes3, maxCoords.box3.x, maxCoords.box3.y);
+    updateBoxes(boxes4, maxCoords.box4.x, maxCoords.box4.y);
+    rafId = requestAnimationFrame(animate);
+  }
+};
+// const animate = () => {
+//   boxes.value.forEach(box => animateBox(box, maxCoords.box1.x, maxCoords.box1.y));
+//   boxes2.value.forEach(box => animateBox(box, maxCoords.box2.x, maxCoords.box2.y));
+//   boxes3.value.forEach(box => animateBox(box, maxCoords.box3.x, maxCoords.box3.y));
+//   boxes4.value.forEach(box => animateBox(box, maxCoords.box4.x, maxCoords.box4.y));
+//   rafId = requestAnimationFrame(animate);
+// };
+const boxStart = () => {
+  initBoxes(boxes, numBoxes, 'firstup');
+  initBoxes(boxes2, numBoxes2, 'firstup');
+  initBoxes(boxes3, numBoxes3, 'secondleft');
+  initBoxes(boxes4, numBoxes4, 'right');
+};
+watch(
+  () => boxes.value,
+  async (newVal) => {
+    await nextTick();
+    newVal.forEach((box, i) => {
+      box.el = boxRefs[i];
+    });
+  },
+  { deep: true, immediate: true }
+);
+watch(
+  () => boxes2.value,
+  async (newVal) => {
+    await nextTick();
+    newVal.forEach((box, i) => {
+      box.el = boxRefs2[i];
+    });
+  },
+  { deep: true, immediate: true }
+);
+watch(
+  () => boxes3.value,
+  async (newVal) => {
+    await nextTick();
+    newVal.forEach((box, i) => {
+      box.el = boxRefs3[i];
+    });
+  },
+  { deep: true, immediate: true }
+);
+watch(
+  () => boxes4.value,
+  async (newVal) => {
+    await nextTick();
+    newVal.forEach((box, i) => {
+      box.el = boxRefs4[i];
+    });
+  },
+  { deep: true, immediate: true }
+);
+onMounted(() => {
+  boxStart();
+  animate();
+});
+onBeforeUnmount(() => {
+  cancelAnimationFrame(rafId);
+  rafId = null;
+  boxes.value.length = 0;
+  boxes2.value.length = 0;
+  boxes3.value.length = 0;
+  boxes4.value.length = 0;
+});
+onUnmounted(() => {
+  if (rafId) {
+    cancelAnimationFrame(rafId); // 鍋滄鍔ㄧ敾锛岄槻姝㈠唴瀛樻硠婕�
+  }
+});
+// onBeforeUnmount(() => {
+//   cancelAnimationFrame(rafId);
+// });
 //宓屽叆鍘嗗彶浠诲姟
 const iframeUrl1 = ref('');
 const iframe1 = ref(false);
@@ -898,6 +904,21 @@
   iframe10.value = true;
   iframeUrl10.value = `${window.location.origin}/#/largescreendisplay/statistics`;
 };
+const iframeUrl11 = ref('');
+const iframe11 = ref(false);
+const handlehistorical11 = () => {
+  iframe11.value = true;
+  iframeUrl11.value = `${window.location.origin}/#/largescreendisplay/productionstatistics`;
+};
+const iframeUrl12 = ref('');
+const iframe12 = ref(false);
+const handlehistorical12 = (key) => {
+  iframe12.value = true;
+  const params = new URLSearchParams({
+    key: key,
+  });
+  iframeUrl12.value = `${window.location.origin}/#/largescreendisplay/timeaxis?${params.toString()}`;
+};
 const transposedData = computed(() => {
   const keys = Object.keys(fieldNames); // 鎸� fieldNames 鐨勯『搴�
   return keys.map(key => {
@@ -908,7 +929,6 @@
     return row;
   });
 });
-
 const fieldNames = {
   date: t('large.date'),
   countOutOne: t('large.countOutOne'),
@@ -924,8 +944,43 @@
   hollowCountOutTwo: t('large.hollowCountOutTwo'),
   hollowTotalAreaOutTwo: t('large.hollowTotalAreaOutTwo'),
 };
-
-
+// 淇敼鍥捐〃鍒濆鍖栭�昏緫锛屾坊鍔犳噿鍔犺浇鍜岄攢姣佹満鍒�
+const chartInstances = {
+  chartLoad: null,
+  chartEdg: null,
+  chartTemp: null,
+  chartHollow: null,
+  chartRef: null,
+  chartRef2: null
+};
+const initChart = (refName, option) => {
+  if (!chartInstances[refName] && templateRefs[refName]) {
+    chartInstances[refName] = echarts.init(templateRefs[refName]);
+    chartInstances[refName].setOption(option);
+  }
+};
+const disposeChart = (refName) => {
+  if (chartInstances[refName]) {
+    chartInstances[refName].dispose();
+    chartInstances[refName] = null;
+  }
+};
+// 浣跨敤Intersection Observer瀹炵幇鍥捐〃鎳掑姞杞�
+const observer = new IntersectionObserver((entries) => {
+  entries.forEach(entry => {
+    if (entry.isIntersecting) {
+      const refName = entry.target.getAttribute('data-chart-name');
+      if (refName && !chartInstances[refName]) {
+        // 鍒濆鍖栧浘琛ㄩ�昏緫
+      }
+    }
+  });
+}, { threshold: 0.1 });
+onMounted(() => {
+  document.querySelectorAll('[data-chart-name]').forEach(el => {
+    observer.observe(el);
+  });
+});
 </script>
 <template>
   <div style="height: 500px;">
@@ -966,74 +1021,93 @@
         frameborder="0"></iframe>
     </el-dialog>
     <el-dialog v-model="iframe10" top="5vh" width="95%" @close="iframeUrl10 = ''">
-      <iframe :src="iframeUrl10" marginwidth="2000px" marginheight="2000px" width="100%" height="750px"
+      <iframe :src="iframeUrl10" marginwidth="2000px" marginheight="2000px" width="100%" height="700px"
         frameborder="0"></iframe>
     </el-dialog>
-
+    <el-dialog v-model="iframe11" top="5vh" width="95%" @close="iframeUrl11 = ''">
+      <iframe :src="iframeUrl11" marginwidth="2000px" marginheight="2000px" width="100%" height="750px"
+        frameborder="0"></iframe>
+    </el-dialog>
+    <el-dialog v-model="iframe12" top="5vh" width="95%" @close="iframeUrl12 = ''">
+      <iframe :src="iframeUrl12" marginwidth="2000px" marginheight="2000px" width="100%" height="750px"
+        frameborder="0"></iframe>
+    </el-dialog>
     <div class="awatch" style="display: flex;">
       <!-- 鐢熶骇缁熻 -->
       <div style="height: 100px;width: 25%;float: right;">
         <div id="ss" style="width: 100%; display: flex; justify-content: center;">
-          <div ref="chartRef" style="width: 600px; height: 400px;" @dblclick="handlehistorical10()"></div>
+          <div ref="chartRef" style="width: 600px; height: 400px;" @dblclick="handlehistorical10()">
+          </div>
         </div>
         <div style="width: 100%;height: 245px;display: flex;">
-          <div ref="chartOne" style="width: 100%;"></div>
+          <div ref="chartLoad" style="width: 100%;" @dblclick="handlehistorical12(1)"></div>
         </div>
         <div style="width: 100%;height: 245px;display: flex;">
-          <div ref="chartTwo" style="width: 100%;"></div>
+          <div ref="chartEdg" style="width: 100%;" @dblclick="handlehistorical12(2)"></div>
         </div>
       </div>
       <div style="width: 50%;">
         <div class="img-screen" alt="Screen">
+          <div>
+            <el-button type="primary" style="top:40px;left:670px;position: absolute;" @click="exportToExcel()">{{
+              $t('large.statistics') }}</el-button>
+          </div>
           <!-- 閽㈠寲鍗婇�忔槑鑹插潡 -->
           <div
-            style="width: 80px;height: 40px;top: 130px;left: 130px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOut : 0 }}鐗�</div>
+            style="width: 80px;height: 40px;top: 315px;left: 130px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOut : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaOut : 0 }}m虏</div>
           </div>
           <!-- 涓┖涓�绾垮崐閫忔槑鑹插潡 -->
           <div
-            style="width: 80px;height: 40px;top: 315px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].hollowCountOutOne : 0 }}鐗�</div>
+            style="width: 80px;height: 40px;top: 235px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].hollowCountOutOne : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].hollowTotalAreaOutOne : 0 }}m虏</div>
           </div>
           <!-- 涓┖浜岀嚎鍗婇�忔槑鑹插潡 -->
           <div
-            style="width: 80px;height: 40px;top: 230px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].hollowCountOutTwo : 0 }}鐗�</div>
+            style="width: 80px;height: 40px;top: 130px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].hollowCountOutTwo : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].hollowTotalAreaOutTwo : 0 }}m虏</div>
           </div>
           <!-- 鍒囧壊浜岀嚎鍗婇�忔槑鑹插潡 -->
           <div
             style="width: 80px;height: 40px;top: 542px;left: 410px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutOne : 0 }}鐗�</div>
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutOne : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaOutOne : 0 }}m虏</div>
           </div>
           <!-- 鍒囧壊涓�绾垮崐閫忔槑鑹插潡 -->
           <div
             style="width: 80px;height: 40px;top: 490px;left: 410px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutTwo : 0 }}鐗�</div>
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutTwo : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaOutTwo : 0 }}m虏</div>
           </div>
           <!-- 纾ㄨ竟涓�绾垮崐閫忔槑鑹插潡 -->
           <div
             style="width: 80px;height: 40px;top: 369px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutOne : 0 }}鐗�</div>
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutOne : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaOutOne : 0 }}m虏</div>
           </div>
           <!-- 纾ㄨ竟浜岀嚎鍗婇�忔槑鑹插潡 -->
           <div
             style="width: 80px;height: 40px;top: 410px;left: 450px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutTwo : 0 }}鐗�</div>
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countOutTwo : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaOutTwo : 0 }}m虏</div>
           </div>
-          <!-- 閽㈠寲鍓嶅ぇ鐞嗙墖鍗婇�忔槑鑹插潡 -->
+          <!-- 閽㈠寲鍓嶅ぇ鐞唟{ $t('large.slice') }}鍗婇�忔槑鑹插潡 -->
           <div
             style="width: 80px;height: 40px;top: 380px;left: 290px;position: absolute;background-color: rgba(0, 0, 0, 0.5);color: white;font-size: 12px;z-index: 999;">
-            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countIn : 0 }}鐗�</div>
+            <div>{{ $t('large.quantity') }}:{{ productionVO.length > 0 ? productionVO[6].countIn : 0 }}{{
+              $t('large.slice') }}</div>
             <div>{{ $t('large.are') }}:{{ productionVO.length > 0 ? productionVO[6].totalAreaIn : 0 }}m虏</div>
           </div>
-
           <!-- 閽㈠寲鑹插潡 -->
           <div v-if="temperingGlassInfoInList > 0" class="tempering"
             style="width: 44px;height: 19px;top: 284px;left: 178px;position: absolute;background-color: #911005;"></div>
@@ -1074,21 +1148,22 @@
           <!-- 纾ㄨ竟鑹插潡 -->
           <div class="container"
             style="position: relative;width: 15px;height: 15px;top: 500px;left: 638px;position: absolute;">
-            <div v-for="(box, index) in boxes2" :key="index" class="box" :style="box.style"></div>
+            <div v-for="(box, i) in boxes2" :key="`b1-${i}`" class="moving-rect" :ref="el => boxRefs2[i] = el" />
           </div>
           <div class="container"
             style="position: relative;width: 15px;height: 15px;top: 548px;left: 690px;position: absolute;">
-            <div v-for="(box, index) in boxes" :key="index" class="box" :style="box.style"></div>
+            <div v-for="(box, i) in boxes" :key="`b1-${i}`" class="moving-rect" :ref="el => boxRefs[i] = el" />
           </div>
           <!-- 閽㈠寲杩愬姩鑹插潡 -->
           <div class="container"
-            style="position: relative;width: 15px;height: 15px;top: 370px;left: 195px;position: absolute;background-color: red;">
-            <div v-for="(box, index) in boxes3" :key="index" class="box" :style="box.style"></div>
+            style="position: relative;width: 15px;height: 15px;top: 370px;left: 195px;position: absolute;">
+            <div v-for="(box, i) in boxes3" :key="`b1-${i}`" class="moving-rect" :ref="el => boxRefs3[i] = el" />
           </div>
           <div class="container"
             style="position: relative;width: 15px;height: 15px;top: 284px;left: 489px;position: absolute;">
-            <div v-for="(box, index) in boxes4" :key="index" class="box" :style="box.style"></div>
+            <div v-for="(box, i) in boxes4" :key="`b1-${i}`" class="moving-rect" :ref="el => boxRefs4[i] = el" />
           </div>
+          <!-- <div  class="moving-rect lipiana" v-show="true">1111111111</div> -->
           <!-- 閽㈠寲鍓嶅ぇ鐞嗙墖鑹插潡 -->
           <div class="container" v-for="(item, index) in bigStorageCageUsage.slice(0, 1)" :key="index"
             :style='"position: relative;width: " + (37 * item.percentage / 100) + "px;height: 13px;top: 374px;left: 309px;position: absolute;background-color: #911005;"'>
@@ -1121,8 +1196,8 @@
           <div class="clickable-area" @click="handlehistorical"
             style="position: relative;width: 108px;height: 134px;top: 478px;left: 290px;"></div>
         </div>
-        <div style="height: 190px;width: 100%;float: right;">
-          <el-table height="190" ref="table" :data="orderDTOS"
+        <div style="height: 175px;width: 100%;float: right;">
+          <el-table height="175" ref="table" :data="orderDTOS"
             :header-cell-style="{ background: '#F2F3F5 ', color: '#1D2129' }">
             <el-table-column prop="orderId" align="center" :label="$t('large.orderId')" min-width="50" />
             <el-table-column prop="customerName" align="center" :show-overflow-tooltip="true"
@@ -1140,16 +1215,15 @@
           </el-table>
         </div>
       </div>
-
       <div style="height: 100px;width: 25%;float: right;">
         <div id="ss" style="width: 100%; display: flex; justify-content: center;">
           <div ref="chartRef2" style="width: 600px; height: 400px;" @dblclick="handlehistorical10()"></div>
         </div>
         <div style="width: 100%;height: 245px;display: flex;">
-          <div ref="chartThree" style="width: 100%;"></div>
+          <div ref="chartTemp" style="width: 100%;" @dblclick="handlehistorical12(3)"></div>
         </div>
         <div style="width: 100%;height: 245px;display: flex;">
-          <div ref="chartFour" style="width: 100%;"></div>
+          <div ref="chartHollow" style="width: 100%;" @dblclick="handlehistorical12(4)"></div>
         </div>
       </div>
     </div>
@@ -1229,19 +1303,16 @@
   line-height: 20px;
   margin-left: 100px;
 }
-
 #dta {
   display: block;
   float: left;
   line-height: 20px;
   margin-left: 80%;
 }
-
 #dialog-footer {
   text-align: center;
   margin-top: -15px;
 }
-
 #message {
   text-align: center;
   align-items: center;
@@ -1251,18 +1322,17 @@
   background-color: #337ecc;
   margin-left: 28%;
 }
-
 #awatch {
   height: 460px;
 }
-
+/* 浼樺寲鑳屾櫙鍥剧墖鍔犺浇 */
 .img-screen {
   /* max-width: 48%;
   max-height: 100%; */
   /* margin-top: 50px; */
   /* float: left; */
   position: relative;
-  background-image: url('../../assets/screen.png');
+  background-image: url('/screen.png');
   width: 795px;
   height: 700px;
   background-size: contain;
@@ -1271,8 +1341,9 @@
   /* width: 100%; 
   height: 0; 
   padding-bottom: 50%;  */
+  image-rendering: -webkit-optimize-contrast;
+  image-rendering: crisp-edges;
 }
-
 .clickable-area {
   cursor: pointer;
   /* 鎸囩ず杩欐槸涓�涓彲鐐瑰嚮鐨勫尯鍩� */
@@ -1281,11 +1352,37 @@
   line-height: 95px;
   /* 濡傛灉闇�瑕侊紝浣挎枃鏈瀭鐩村眳涓� */
 }
-
 /* .awatch{
   height: 460px;
   /* max-width: 100%; */
 .box {
   transition: transform 0.016s linear;
 }
+.lipiana {
+  width: 15px;
+  height: 9px;
+  background-color: #529b2e;
+  top: 190px;
+  right: 530px;
+  transform: translateX(-50%);
+  animation: move-lipiana 1s infinite;
+}
+@keyframes move-lipiana {
+  0% {
+    right: 530px;
+  }
+  100% {
+    right: calc(100% - 350px);
+  }
+}
+/* 浣跨敤CSS纭欢鍔犻�� */
+.moving-rect {
+  width: 15px;
+  height: 15px;
+  background-color: #911005;
+  position: absolute;
+  will-change: transform;
+  backface-visibility: hidden;
+  perspective: 1000px;
+}
 </style>
\ No newline at end of file

--
Gitblit v1.8.0