From 2812a2504ec3d0a98fa7e6204e6048584723adab Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期三, 08 四月 2026 14:08:34 +0800
Subject: [PATCH] #

---
 rsf-design/src/hooks/core/useTable.js |  177 ++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 97 insertions(+), 80 deletions(-)

diff --git a/rsf-design/src/hooks/core/useTable.js b/rsf-design/src/hooks/core/useTable.js
index 7525702..e9a5c83 100644
--- a/rsf-design/src/hooks/core/useTable.js
+++ b/rsf-design/src/hooks/core/useTable.js
@@ -1,5 +1,6 @@
 import { ref, reactive, computed, onMounted, onUnmounted, nextTick, readonly } from 'vue'
 import { useWindowSize } from '@vueuse/core'
+import { hash } from 'ohash'
 import { useTableColumns } from './useTableColumns'
 import { TableCache, CacheInvalidationStrategy } from '../../utils/table/tableCache'
 import {
@@ -59,12 +60,14 @@
   const error = ref(null)
   const data = ref([])
   let abortController = null
+  let inflightRequest = null
+  let inflightRequestKey = ''
   let cacheCleanupTimer = null
   const searchParams = reactive(
     Object.assign(
       {
         [pageKey]: 1,
-        [sizeKey]: 10
+        [sizeKey]: 20
       },
       apiParams || {}
     )
@@ -113,6 +116,27 @@
     cacheUpdateTrigger.value++
   }
   const fetchData = async (params, useCache = enableCache) => {
+    let requestParams = Object.assign(
+      {},
+      searchParams,
+      {
+        [pageKey]: pagination.current,
+        [sizeKey]: pagination.size
+      },
+      params || {}
+    )
+    if (excludeParams.length > 0) {
+      const filteredParams = { ...requestParams }
+      excludeParams.forEach((key) => {
+        delete filteredParams[key]
+      })
+      requestParams = filteredParams
+    }
+    const requestKey = hash(requestParams)
+    if (inflightRequest && inflightRequestKey === requestKey) {
+      logger.log('澶嶇敤杩涜涓殑璇锋眰')
+      return inflightRequest
+    }
     if (abortController) {
       abortController.abort()
     }
@@ -120,88 +144,81 @@
     abortController = currentController
     loadingState.value = 'loading'
     error.value = null
-    try {
-      let requestParams = Object.assign(
-        {},
-        searchParams,
-        {
-          [pageKey]: pagination.current,
-          [sizeKey]: pagination.size
-        },
-        params || {}
-      )
-      if (excludeParams.length > 0) {
-        const filteredParams = { ...requestParams }
-        excludeParams.forEach((key) => {
-          delete filteredParams[key]
-        })
-        requestParams = filteredParams
-      }
-      if (useCache && cache) {
-        const cachedItem = cache.get(requestParams)
-        if (cachedItem) {
-          data.value = cachedItem.data
-          updatePaginationFromResponse(pagination, cachedItem.response)
-          const paramsRecord2 = searchParams
-          if (paramsRecord2[pageKey] !== pagination.current) {
-            paramsRecord2[pageKey] = pagination.current
+    const currentRequest = (async () => {
+      try {
+        if (useCache && cache) {
+          const cachedItem = cache.get(requestParams)
+          if (cachedItem) {
+            data.value = cachedItem.data
+            updatePaginationFromResponse(pagination, cachedItem.response)
+            const paramsRecord2 = searchParams
+            if (paramsRecord2[pageKey] !== pagination.current) {
+              paramsRecord2[pageKey] = pagination.current
+            }
+            if (paramsRecord2[sizeKey] !== pagination.size) {
+              paramsRecord2[sizeKey] = pagination.size
+            }
+            loadingState.value = 'success'
+            if (onCacheHit) {
+              onCacheHit(cachedItem.data, cachedItem.response)
+            }
+            logger.log(`缂撳瓨鍛戒腑`)
+            return cachedItem.response
           }
-          if (paramsRecord2[sizeKey] !== pagination.size) {
-            paramsRecord2[sizeKey] = pagination.size
-          }
-          loadingState.value = 'success'
-          if (onCacheHit) {
-            onCacheHit(cachedItem.data, cachedItem.response)
-          }
-          logger.log(`缂撳瓨鍛戒腑`)
-          return cachedItem.response
+        }
+        const response = await apiFn(requestParams)
+        if (currentController.signal.aborted) {
+          throw new Error('璇锋眰宸插彇娑�')
+        }
+        const standardResponse = responseAdapter(response)
+        let tableData = extractTableData(standardResponse)
+        if (dataTransformer) {
+          tableData = dataTransformer(tableData)
+        }
+        data.value = tableData
+        updatePaginationFromResponse(pagination, standardResponse)
+        const paramsRecord = searchParams
+        if (paramsRecord[pageKey] !== pagination.current) {
+          paramsRecord[pageKey] = pagination.current
+        }
+        if (paramsRecord[sizeKey] !== pagination.size) {
+          paramsRecord[sizeKey] = pagination.size
+        }
+        if (useCache && cache) {
+          cache.set(requestParams, tableData, standardResponse)
+          cacheUpdateTrigger.value++
+          logger.log(`鏁版嵁宸茬紦瀛榒)
+        }
+        loadingState.value = 'success'
+        if (onSuccess) {
+          onSuccess(tableData, standardResponse)
+        }
+        return standardResponse
+      } catch (err) {
+        if (
+          err instanceof Error &&
+          (err.message === '璇锋眰宸插彇娑�' || err.code === 'REQUEST_CANCELLED')
+        ) {
+          loadingState.value = 'idle'
+          return { records: [], total: 0, current: 1, size: 10 }
+        }
+        loadingState.value = 'error'
+        data.value = []
+        const tableError = handleError(err, '鑾峰彇琛ㄦ牸鏁版嵁澶辫触')
+        throw tableError
+      } finally {
+        if (abortController === currentController) {
+          abortController = null
+        }
+        if (inflightRequest === currentRequest) {
+          inflightRequest = null
+          inflightRequestKey = ''
         }
       }
-      const response = await apiFn(requestParams)
-      if (currentController.signal.aborted) {
-        throw new Error('璇锋眰宸插彇娑�')
-      }
-      const standardResponse = responseAdapter(response)
-      let tableData = extractTableData(standardResponse)
-      if (dataTransformer) {
-        tableData = dataTransformer(tableData)
-      }
-      data.value = tableData
-      updatePaginationFromResponse(pagination, standardResponse)
-      const paramsRecord = searchParams
-      if (paramsRecord[pageKey] !== pagination.current) {
-        paramsRecord[pageKey] = pagination.current
-      }
-      if (paramsRecord[sizeKey] !== pagination.size) {
-        paramsRecord[sizeKey] = pagination.size
-      }
-      if (useCache && cache) {
-        cache.set(requestParams, tableData, standardResponse)
-        cacheUpdateTrigger.value++
-        logger.log(`鏁版嵁宸茬紦瀛榒)
-      }
-      loadingState.value = 'success'
-      if (onSuccess) {
-        onSuccess(tableData, standardResponse)
-      }
-      return standardResponse
-    } catch (err) {
-      if (
-        err instanceof Error &&
-        (err.message === '璇锋眰宸插彇娑�' || err.code === 'REQUEST_CANCELLED')
-      ) {
-        loadingState.value = 'idle'
-        return { records: [], total: 0, current: 1, size: 10 }
-      }
-      loadingState.value = 'error'
-      data.value = []
-      const tableError = handleError(err, '鑾峰彇琛ㄦ牸鏁版嵁澶辫触')
-      throw tableError
-    } finally {
-      if (abortController === currentController) {
-        abortController = null
-      }
-    }
+    })()
+    inflightRequest = currentRequest
+    inflightRequestKey = requestKey
+    return currentRequest
   }
   const getData = async (params) => {
     try {

--
Gitblit v1.9.1