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