From c2e8526f8f857be5e3a8c6f2b39c5efd424de33e Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 15 十月 2026 11:50:24 +0800
Subject: [PATCH] refactor(auth): 优化认证逻辑和界面组件结构

---
 src/views/bi/warehouse/index.vue |  103 ++++++++++++++-------------------------------------
 1 files changed, 28 insertions(+), 75 deletions(-)

diff --git a/src/views/bi/warehouse/index.vue b/src/views/bi/warehouse/index.vue
index dca30fd..120caaa 100644
--- a/src/views/bi/warehouse/index.vue
+++ b/src/views/bi/warehouse/index.vue
@@ -17,6 +17,7 @@
 } from '#/api/bi/warehouseCoordinate';
 
 import ClockWidget from '../dashboard/modules/ClockWidget.vue';
+import RealtimeTable from '../dashboard/modules/RealtimeTable.vue';
 import {
   getChinaMapOptions,
   getWarehouseAreaLineOptions,
@@ -30,19 +31,29 @@
 const charts = ref<BiDashboardApi.ChartItem[]>([]);
 const loading = ref(true);
 const lastUpdateTime = ref('');
+let fetching = false;
+let disposed = false;
 
-async function loadData() {
+async function loadData(background = false) {
+  if (fetching || disposed) return false;
+  fetching = true;
   try {
-    loading.value = true;
+    if (!background) loading.value = true;
     const data = await getDashboardData('warehouse');
+    if (disposed) return false;
     charts.value = data.length > 0 ? data : [];
     lastUpdateTime.value = new Date().toLocaleTimeString('zh-CN', { hour12: false });
+    return true;
   } catch {
-    charts.value = [];
+    if (!background && !disposed) charts.value = [];
+    return false;
   } finally {
-    loading.value = false;
-    await nextTick();
-    resizeAllCharts();
+    fetching = false;
+    if (!disposed) {
+      loading.value = false;
+      await nextTick();
+      if (!disposed) resizeAllCharts();
+    }
   }
 }
 
@@ -233,10 +244,7 @@
 
 // ======== 琛ㄦ牸鏁版嵁 ========
 const tableData = computed(() => tableChart.value?.data || []);
-const tableColumns = computed(() => {
-  if (tableData.value.length === 0) return [];
-  return Object.keys(tableData.value[0] || {});
-});
+
 
 // ======== 搴撳瓨棰勮 ========
 const warningList = computed(() => {
@@ -428,7 +436,8 @@
 function setupTimer() {
   clearTimer();
   refreshTimer = setInterval(async () => {
-    await loadData();
+    if (document.hidden || editMode.value || disposed) return;
+    if (!(await loadData(true))) return;
     await nextTick();
     await renderAllCharts();
     if (editMode.value) await nextTick().then(() => attachMapListeners());
@@ -497,13 +506,16 @@
   resizeObserver = new ResizeObserver(() => resizeAllCharts());
   if (dashboardRef.value) resizeObserver.observe(dashboardRef.value);
   await loadCoordinates();
+  if (disposed) return;
   await loadData();
+  if (disposed) return;
   await nextTick();
   await renderAllCharts();
   setupTimer();
 });
 
 onBeforeUnmount(() => {
+  disposed = true;
   document.removeEventListener('fullscreenchange', onFullscreenChange);
   resizeObserver?.disconnect();
   clearTimer();
@@ -720,26 +732,11 @@
           鏈�杩戝叆搴撹褰�
           <span class="wh-table-badge">瀹炴椂婊氬姩</span>
         </div>
-        <div v-if="tableData.length > 0" class="wh-table-wrap">
-          <table class="wh-table">
-            <thead>
-              <tr>
-                <th v-for="col in tableColumns" :key="col">{{ col }}</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr
-                v-for="(row, ri) in tableData"
-                :key="ri"
-                :style="{ animationDelay: `${ri * 50}ms` }"
-              >
-                <td v-for="col in tableColumns" :key="col">
-                  {{ getCellValue(row, col) }}
-                </td>
-              </tr>
-            </tbody>
-          </table>
-        </div>
+        <RealtimeTable
+          v-if="tableData.length > 0"
+          :rows="tableData"
+          :format-cell="getCellValue"
+        />
         <Empty v-else description="鏆傛棤鏁版嵁" />
       </div>
     </template>
@@ -1187,50 +1184,6 @@
   padding: 2px 8px; border-radius: 10px;
   background: rgba(0,255,136,0.08); color: var(--green);
   border: 1px solid rgba(0,255,136,0.15);
-}
-
-.wh-table-wrap {
-  overflow-x: auto; border-radius: 8px;
-  background: rgba(4, 14, 36, 0.55);
-  backdrop-filter: blur(6px);
-  -webkit-backdrop-filter: blur(6px);
-  border: 1px solid rgba(0, 229, 255, 0.08);
-}
-
-.wh-table {
-  width: 100%; border-collapse: collapse; font-size: 12px;
-}
-
-.wh-table thead th {
-  background: rgba(6, 18, 42, 0.8);
-  color: var(--text-secondary);
-  font-weight: 600; font-size: 10px;
-  text-transform: uppercase; letter-spacing: 0.8px;
-  padding: 10px 14px; text-align: left;
-  border-bottom: 1px solid rgba(0,229,255,0.12);
-  white-space: nowrap;
-}
-
-.wh-table tbody td {
-  padding: 9px 14px; color: var(--text-primary);
-  border-bottom: 1px solid rgba(0, 229, 255, 0.04);
-  white-space: nowrap;
-}
-
-.wh-table tbody tr {
-  transition: all 0.25s;
-  opacity: 0;
-  animation: row-fade-in 0.45s ease forwards;
-}
-
-.wh-table tbody tr:hover {
-  background: rgba(0, 229, 255, 0.06);
-  box-shadow: inset 0 0 20px rgba(0, 229, 255, 0.03);
-}
-
-@keyframes row-fade-in {
-  from { opacity: 0; transform: translateY(6px); }
-  to { opacity: 1; transform: translateY(0); }
 }
 
 /* ======== 鍏ㄥ睆 ======== */

--
Gitblit v1.9.3