/** * 初始化idata扫描模块 */ export function useInit() { //获取module var barcodeModel = uni.requireNativePlugin("iData-BarcodePlugin-BarcodeModule"); //使用示例 barcodeModel.initScan((ret) => { console.log("初始化扫描", ret); }); return barcodeModel; } // 检查WeakRef是否可用 const isWeakRefSupported = typeof WeakRef !== 'undefined'; // 存储当前活跃页面的回调函数 const callbackRegistry = { activePagePath: null, callbacks: new Map(), // 使用Map存储每个页面路径对应的回调函数 pageInstances: new Map(), // 存储页面实例,用于自动清理 }; /** * 全局事件处理函数 - 内部使用 * 只执行当前活跃页面的回调函数 */ const globalEventHandler = function(e) { if (!callbackRegistry.activePagePath) { console.warn("收到扫描事件,但没有活跃页面"); return; } const callback = callbackRegistry.callbacks.get(callbackRegistry.activePagePath); if (callback) { try { // 只执行当前活跃页面的回调 callback(e); } catch (error) { console.error(`页面 ${callbackRegistry.activePagePath} 的扫描回调执行出错:`, error); } } else { console.warn(`活跃页面 ${callbackRegistry.activePagePath} 没有注册扫描回调`); } }; // 初始化全局事件监听器 let isGlobalListenerInitialized = false; let globalEvent = null; function initGlobalListener() { if (isGlobalListenerInitialized) return; try { globalEvent = uni.requireNativePlugin("globalEvent"); // 确保移除任何可能存在的旧监听器 globalEvent.removeEventListener("iDataBarcodeEvent", globalEventHandler); // 添加全局单一监听器 globalEvent.addEventListener("iDataBarcodeEvent", globalEventHandler); isGlobalListenerInitialized = true; console.log("全局扫描监听器已初始化"); } catch (error) { console.error("初始化全局扫描监听器失败:", error); } } /** * 获取当前页面路径的安全方法 */ function getCurrentPagePath() { try { const pages = getCurrentPages(); if (!pages || pages.length === 0) { console.warn("getCurrentPages() 返回空数组"); return null; } const currentPage = pages[pages.length - 1]; if (!currentPage || !currentPage.route) { console.warn("当前页面对象或路径无效"); return null; } return currentPage.route; } catch (error) { console.error("获取当前页面路径失败:", error); return null; } } /** * 全局监听扫描后结果 * @param onChange 回调函数 * @returns {Function} 返回移除监听器的函数 */ export function useGlobalEvent(onChange) { if (typeof onChange !== 'function') { console.error("useGlobalEvent: onChange 必须是一个函数"); return () => {}; } // 确保全局监听器已初始化 initGlobalListener(); // 获取当前页面路径 const pagePath = getCurrentPagePath(); if (!pagePath) { console.error("useGlobalEvent: 无法获取当前页面路径"); return () => {}; } // 检查是否已经注册过回调 if (callbackRegistry.callbacks.has(pagePath)) { console.warn(`页面 ${pagePath} 已经注册过扫描回调,将覆盖之前的回调`); } // 更新当前活跃页面 callbackRegistry.activePagePath = pagePath; // 注册当前页面的回调 callbackRegistry.callbacks.set(pagePath, onChange); // 存储页面实例用于自动清理(如果可能的话) try { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; if (currentPage) { // 根据WeakRef支持情况选择存储方式 if (isWeakRefSupported) { callbackRegistry.pageInstances.set(pagePath, new WeakRef(currentPage)); } else { // 如果不支持WeakRef,存储普通引用 // 注意:这可能导致内存泄漏,需要手动清理 callbackRegistry.pageInstances.set(pagePath, currentPage); console.warn("WeakRef不支持,使用普通引用,请确保在页面卸载时手动清理"); } } } catch (error) { console.warn("无法存储页面实例引用:", error); } console.log(`页面 ${pagePath} 已注册扫描回调,当前注册页面数: ${callbackRegistry.callbacks.size}`); // 返回一个清理函数,用于手动移除监听器 return () => { removePageCallback(pagePath); }; } /** * 更新当前活跃页面,在页面显示时调用 * 在App.vue的onShow中调用 */ export function updateActivePageOnShow() { // #ifdef APP-PLUS const pagePath = getCurrentPagePath(); if (!pagePath) { console.error("updateActivePageOnShow: 无法获取当前页面路径"); return; } // 更新当前活跃页面 callbackRegistry.activePagePath = pagePath; console.log(`当前活跃页面已更新为: ${pagePath}`); // 检查并清理无效的页面引用 cleanupInvalidPageReferences(); // #endif } /** * 清理无效的页面引用 * 自动移除已经被销毁的页面的回调 */ function cleanupInvalidPageReferences() { const currentPages = getCurrentPages(); const currentPagePaths = new Set(currentPages.map(page => page.route)); // 查找已经不存在的页面 const pagesToRemove = []; for (const [pagePath, pageRef] of callbackRegistry.pageInstances) { let shouldRemove = false; // 如果页面不在当前页面栈中 if (!currentPagePaths.has(pagePath)) { shouldRemove = true; } else if (isWeakRefSupported && pageRef) { // 如果支持WeakRef且WeakRef已经被回收 if (!pageRef.deref()) { shouldRemove = true; } } // 如果不支持WeakRef,我们只能依赖页面栈检查 if (shouldRemove) { pagesToRemove.push(pagePath); } } // 移除这些页面的回调 pagesToRemove.forEach(pagePath => { callbackRegistry.callbacks.delete(pagePath); callbackRegistry.pageInstances.delete(pagePath); console.log(`自动清理页面 ${pagePath} 的扫描回调`); }); if (pagesToRemove.length > 0) { console.log(`自动清理了 ${pagesToRemove.length} 个无效页面的回调,当前注册页面数: ${callbackRegistry.callbacks.size}`); } } /** * 全局卸载监听事件 * 完全移除全局事件监听器 */ export function useGlobalEventRemove() { try { if (globalEvent && isGlobalListenerInitialized) { globalEvent.removeEventListener("iDataBarcodeEvent", globalEventHandler); } isGlobalListenerInitialized = false; globalEvent = null; callbackRegistry.callbacks.clear(); callbackRegistry.pageInstances.clear(); callbackRegistry.activePagePath = null; console.log("全局扫描监听器已完全移除,所有回调已清理"); } catch (error) { console.error("移除全局扫描监听器时出错:", error); } } /** * 移除特定页面的回调 * @param pagePath 页面路径,如果不提供则移除当前页面的回调 */ export function removePageCallback(pagePath) { if (!pagePath) { pagePath = getCurrentPagePath(); } if (!pagePath) { console.error("removePageCallback: 无法获取页面路径"); return; } const hasCallback = callbackRegistry.callbacks.has(pagePath); callbackRegistry.callbacks.delete(pagePath); callbackRegistry.pageInstances.delete(pagePath); // 如果移除的是当前活跃页面,清空活跃页面 if (callbackRegistry.activePagePath === pagePath) { callbackRegistry.activePagePath = null; } if (hasCallback) { console.log(`页面 ${pagePath} 的扫描回调已移除,当前注册页面数: ${callbackRegistry.callbacks.size}`); } else { console.warn(`页面 ${pagePath} 没有注册过扫描回调`); } } /** * 获取当前注册状态(调试用) */ export function getRegistryStatus() { return { activePagePath: callbackRegistry.activePagePath, registeredPages: Array.from(callbackRegistry.callbacks.keys()), totalCallbacks: callbackRegistry.callbacks.size, isGlobalListenerInitialized }; } /** * 在页面卸载时调用,确保清理回调 * 建议在页面的 onUnload 生命周期中调用 */ export function cleanupOnPageUnload() { const pagePath = getCurrentPagePath(); if (pagePath) { removePageCallback(pagePath); } }