From 41d885b2b3f731650328813da002be9b050d5805 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 30 一月 2026 16:29:31 +0800
Subject: [PATCH] Merge branch 'dev_New' of http://114.132.189.42:9002/r/product-inventory-management into dev_New

---
 src/hooks/useChartBackground.js |  133 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/src/hooks/useChartBackground.js b/src/hooks/useChartBackground.js
new file mode 100644
index 0000000..d69a1fb
--- /dev/null
+++ b/src/hooks/useChartBackground.js
@@ -0,0 +1,133 @@
+import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
+
+/**
+ * 鍥捐〃鑳屾櫙浣嶇疆璋冩暣 composable
+ * @param {Object} options 閰嶇疆閫夐」
+ * @param {Ref} options.wrapperRef - 鍥捐〃瀹瑰櫒鐨� ref
+ * @param {Ref} options.backgroundRef - 鑳屾櫙鍏冪礌鐨� ref
+ * @param {String} options.left - 鑳屾櫙 left 浣嶇疆锛屽 '25%' 鎴� '50%'锛岄粯璁� '50%'
+ * @param {String} options.top - 鑳屾櫙 top 浣嶇疆锛屽 '50%'锛岄粯璁� '50%'
+ * @param {String} options.offsetX - X 杞村亸绉诲�硷紝濡� '-51.5%' 鎴� '-50%'锛岄粯璁� '-50%'
+ * @param {String} options.offsetY - Y 杞村亸绉诲�硷紝濡� '-39%' 鎴� '-50%'锛岄粯璁� '-50%'
+ * @param {Ref} options.watchData - 鍙�夛紝鐩戝惉鐨勬暟鎹彉鍖栵紝鏁版嵁鍙樺寲鏃堕噸鏂拌皟鏁翠綅缃�
+ * @returns {Function} adjustBackgroundPosition - 鎵嬪姩璋冩暣鑳屾櫙浣嶇疆鐨勬柟娉�
+ */
+export function useChartBackground(options = {}) {
+  const {
+    wrapperRef,
+    backgroundRef,
+    left = '50%',
+    top = '50%',
+    offsetX = '-50%',
+    offsetY = '-50%',
+    watchData = null
+  } = options
+
+  let resizeObserver = null
+  let intersectionObserver = null
+  let retryTimers = []
+
+  const clearRetryTimers = () => {
+    if (!retryTimers.length) return
+    retryTimers.forEach((t) => clearTimeout(t))
+    retryTimers = []
+  }
+
+  // 璋冩暣鑳屾櫙浣嶇疆
+  const adjustBackgroundPosition = () => {
+    nextTick(() => {
+      if (!wrapperRef?.value || !backgroundRef?.value) {
+        return
+      }
+
+      // 鍒濆鍖栭樁娈电粡甯稿嚭鐜帮細瀹瑰櫒灏氭湭鍙/灏哄涓� 0锛堥潪鍏ㄥ睆銆乼ab銆佸姩鐢荤瓑锛�
+      // 杩欑鎯呭喌涓嬪厛涓嶅榻愶紝绛� ResizeObserver / IntersectionObserver 鍐嶈Е鍙�
+      const rect = wrapperRef.value.getBoundingClientRect()
+      if (!rect.width || !rect.height) return
+
+      const background = backgroundRef.value
+      
+      // 浣跨敤鐧惧垎姣斿畾浣� + transform 寰皟锛堣繖鏄渶鍙潬鐨勬柟寮忥級
+      background.style.left = left
+      background.style.top = top
+      background.style.transform = `translate(${offsetX}, ${offsetY})`
+    })
+  }
+
+  // 鍒濆鍖栭樁娈靛娆♀�滆ˉ鍋垮榻愨�濓紝瑕嗙洊 Echarts 棣栨娓叉煋/鍔ㄧ敾閫犳垚鐨勫欢杩熷竷灞�
+  const scheduleKickAlign = () => {
+    clearRetryTimers()
+    ;[0, 60, 180, 360, 800].forEach((ms) => {
+      retryTimers.push(
+        setTimeout(() => {
+          adjustBackgroundPosition()
+        }, ms)
+      )
+    })
+  }
+
+  // 绐楀彛 resize 澶勭悊
+  const resizeHandler = () => {
+    adjustBackgroundPosition()
+  }
+
+  // 濡傛灉鎻愪緵浜� watchData锛岀洃鍚暟鎹彉鍖栵紙闇�瑕佸湪 setup 闃舵鍒涘缓锛�
+  if (watchData) {
+    watch(watchData, () => {
+      adjustBackgroundPosition()
+    }, { deep: true })
+  }
+
+  // 鍒濆鍖�
+  const init = () => {
+    // 鐩戝惉绐楀彛 resize
+    window.addEventListener('resize', resizeHandler)
+    
+    // 浣跨敤 ResizeObserver 鐩戝惉瀹瑰櫒灏哄鍙樺寲
+    nextTick(() => {
+      if (wrapperRef?.value && window.ResizeObserver) {
+        resizeObserver = new ResizeObserver(() => {
+          adjustBackgroundPosition()
+        })
+        resizeObserver.observe(wrapperRef.value)
+      }
+
+      // 鐩戝惉鈥滀粠涓嶅彲瑙佸埌鍙鈥濓紝瑙e喅鍒濆鍖栨椂鏈榻愪絾鐑洿鏂板張姝e父鐨勯棶棰�
+      if (wrapperRef?.value && window.IntersectionObserver) {
+        intersectionObserver = new IntersectionObserver(
+          (entries) => {
+            const entry = entries?.[0]
+            if (entry?.isIntersecting) {
+              scheduleKickAlign()
+            }
+          },
+          { threshold: 0.01 }
+        )
+        intersectionObserver.observe(wrapperRef.value)
+      }
+
+      // 鍒濆鍖栧娆¤ˉ鍋垮榻愶紝纭繚鍥捐〃娓叉煋瀹屾垚
+      scheduleKickAlign()
+    })
+  }
+
+  // 娓呯悊
+  const cleanup = () => {
+    window.removeEventListener('resize', resizeHandler)
+    clearRetryTimers()
+    if (resizeObserver) {
+      resizeObserver.disconnect()
+      resizeObserver = null
+    }
+    if (intersectionObserver) {
+      intersectionObserver.disconnect()
+      intersectionObserver = null
+    }
+  }
+
+  return {
+    adjustBackgroundPosition,
+    init,
+    cleanup
+  }
+}

--
Gitblit v1.9.3