| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /**
- * 初始化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);
- }
- }
|