qsh-webview-sdk 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qsh-webview-sdk.es.js","sources":["../src/core/environment.js","../src/core/error-handler.js","../src/core/state-manager.js","../src/core/logger.js","../src/core/bridge.js","../src/core/weixin-config.js","../src/core/weixin-loader.js","../src/core/plugin-manager.js","../src/core/interceptor.js","../src/core/state-store.js","../src/core/error-codes.js","../src/core/error-normalizer.js","../src/core/init-pipeline.js","../src/core/base-platform.js","../src/core/messenger.js","../src/platforms/weixin.js","../src/platforms/app.js","../src/api/navigation.js","../src/api/message.js","../src/core/webview-bridge.js","../src/api/image.js","../src/api/scan.js","../src/api/location.js","../src/api/choose.js","../src/api/capability-registry.js","../src/api/share.js","../src/api/bluetooth.js","../src/api/print.js","../src/api/face.js","../src/index.js"],"sourcesContent":["/**\r\n * 环境检测模块\r\n * 检测当前运行环境(微信小程序、APP等)\r\n * 兼容 SSR/Node:所有检测均在访问全局对象前做 typeof 防护。\r\n */\r\n\r\nfunction getWindow() {\r\n return typeof window !== 'undefined' ? window : undefined;\r\n}\r\n\r\nfunction getNavigatorUA() {\r\n if (typeof navigator === 'undefined') {\r\n return '';\r\n }\r\n return navigator.userAgent || '';\r\n}\r\n\r\n/**\r\n * 检测是否在微信小程序环境\r\n * @returns {boolean}\r\n */\r\nexport function isWeixinMiniProgram() {\r\n const win = getWindow();\r\n if (!win) return false;\r\n\r\n // 1) 官方标识:小程序 web-view 中会注入该变量\r\n if (win.__wxjs_environment === 'miniprogram') {\r\n return true;\r\n }\r\n // 2) jweixin >= 1.6.0 提供 wx.miniProgram\r\n if (win.wx && win.wx.miniProgram) {\r\n return true;\r\n }\r\n // 3) 兜底:在微信内且 UA 带 miniProgram 关键词\r\n const ua = getNavigatorUA();\r\n if (ua && /micromessenger/i.test(ua) && /miniProgram/i.test(ua)) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 是否为 APP Plus 环境\r\n * @returns {boolean}\r\n */\r\nexport function isAppPlus() {\r\n const win = getWindow();\r\n return !!(win && win.plus);\r\n}\r\n\r\n/**\r\n * 是否为 NVUE 环境\r\n * @returns {boolean}\r\n */\r\nexport function isNvue() {\r\n const win = getWindow();\r\n return !!(win && (win.__dcloud_weex_postMessage || win.__dcloud_weex_));\r\n}\r\n\r\n/**\r\n * 是否为 UVUE(UniApp X)环境\r\n * @returns {boolean}\r\n */\r\nexport function isUvue() {\r\n const win = getWindow();\r\n return !!(win && (win.__uniapp_x_postMessage || win.__uniapp_x_));\r\n}\r\n\r\n/**\r\n * 是否为 UniApp H5 环境\r\n * @returns {boolean}\r\n */\r\nexport function isUniApp() {\r\n const ua = getNavigatorUA();\r\n return /uni-app/i.test(ua);\r\n}\r\n\r\n/**\r\n * 是否为 Html5Plus 环境\r\n * @returns {boolean}\r\n */\r\nexport function isHtml5Plus() {\r\n const ua = getNavigatorUA();\r\n return /Html5Plus/i.test(ua);\r\n}\r\n\r\n/**\r\n * 是否在 UniApp WebView 环境中\r\n * @returns {boolean}\r\n */\r\nexport function isUniAppWebView() {\r\n return isUniApp() || isHtml5Plus();\r\n}\r\n\r\n/**\r\n * 获取当前环境类型字符串(惰性计算,可缓存)\r\n * @returns {('weixin'|'plus'|'nvue'|'uvue'|'UniApp'|'webview'|'h5')}\r\n */\r\nexport function getEnvironment() {\r\n if (isUvue()) {\r\n return 'uvue';\r\n }\r\n if (isNvue()) {\r\n return 'nvue';\r\n }\r\n if (isWeixinMiniProgram()) {\r\n return 'weixin';\r\n }\r\n if (isAppPlus()) {\r\n return 'plus';\r\n }\r\n if (isUniAppWebView()) {\r\n return 'webview';\r\n }\r\n if (isUniApp()) {\r\n return 'UniApp';\r\n }\r\n return 'h5';\r\n}\r\n\r\nlet cachedEnvironmentInfo = null;\r\n\r\n/**\r\n * 获取或刷新环境信息对象\r\n * @param {boolean} [forceRefresh=false] 是否强制重新检测\r\n * @returns {{\r\n * isWeixinMiniProgram: boolean,\r\n * isAppPlus: boolean,\r\n * isNvue: boolean,\r\n * isUvue: boolean,\r\n * isUniApp: boolean,\r\n * isHtml5Plus: boolean,\r\n * isUniAppWebView: boolean,\r\n * type: string\r\n * }}\r\n */\r\nexport function getEnvironmentInfo(forceRefresh = false) {\r\n if (cachedEnvironmentInfo && !forceRefresh) {\r\n return cachedEnvironmentInfo;\r\n }\r\n\r\n cachedEnvironmentInfo = {\r\n isWeixinMiniProgram: isWeixinMiniProgram(),\r\n isAppPlus: isAppPlus(),\r\n isNvue: isNvue(),\r\n isUvue: isUvue(),\r\n isUniApp: isUniApp(),\r\n isHtml5Plus: isHtml5Plus(),\r\n isUniAppWebView: isUniAppWebView(),\r\n type: getEnvironment()\r\n };\r\n\r\n return cachedEnvironmentInfo;\r\n}\r\n\r\n// 保留原有导出名,保持向后兼容\r\nexport const environment = getEnvironmentInfo();","/**\r\n * 统一错误处理模块\r\n * 提供错误分类、日志记录和用户反馈机制\r\n */\r\n\r\n/**\r\n * 错误类型枚举\r\n */\r\nexport const ErrorTypes = {\r\n PLATFORM_NOT_SUPPORTED: 'PLATFORM_NOT_SUPPORTED',\r\n API_CALL_FAILED: 'API_CALL_FAILED',\r\n BRIDGE_NOT_READY: 'BRIDGE_NOT_READY',\r\n INVALID_PARAMETERS: 'INVALID_PARAMETERS',\r\n NETWORK_ERROR: 'NETWORK_ERROR',\r\n UNKNOWN_ERROR: 'UNKNOWN_ERROR'\r\n};\r\n\r\n/**\r\n * QSH SDK 自定义错误类\r\n */\r\nexport class QshError extends Error {\r\n /**\r\n * 构造函数\r\n * @param {string} type - 错误类型\r\n * @param {string} message - 错误消息\r\n * @param {Object} [context] - 错误上下文信息\r\n * @param {Error} [originalError] - 原始错误对象\r\n */\r\n constructor(type, message, context = {}, originalError = null) {\r\n super(message);\r\n this.name = 'QshError';\r\n this.type = type;\r\n this.context = context;\r\n this.originalError = originalError;\r\n this.timestamp = new Date().toISOString();\r\n \r\n // 保持错误堆栈跟踪\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, QshError);\r\n }\r\n }\r\n\r\n /**\r\n * 转换为 JSON 格式\r\n * @returns {Object} JSON 对象\r\n */\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n type: this.type,\r\n message: this.message,\r\n context: this.context,\r\n timestamp: this.timestamp,\r\n stack: this.stack\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理器类\r\n */\r\nexport class ErrorHandler {\r\n static isDebugMode = false;\r\n static errorCallbacks = [];\r\n\r\n /**\r\n * 设置调试模式\r\n * @param {boolean} enabled - 是否启用调试模式\r\n */\r\n static setDebugMode(enabled) {\r\n ErrorHandler.isDebugMode = enabled;\r\n }\r\n\r\n /**\r\n * 添加错误回调\r\n * @param {Function} callback - 错误处理回调函数\r\n */\r\n static addErrorCallback(callback) {\r\n if (typeof callback === 'function') {\r\n ErrorHandler.errorCallbacks.push(callback);\r\n }\r\n }\r\n\r\n /**\r\n * 移除错误回调\r\n * @param {Function} callback - 要移除的回调函数\r\n */\r\n static removeErrorCallback(callback) {\r\n const index = ErrorHandler.errorCallbacks.indexOf(callback);\r\n if (index > -1) {\r\n ErrorHandler.errorCallbacks.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * 处理 API 调用错误\r\n * @param {Error|string} error - 错误对象或消息\r\n * @param {Object} context - 错误上下文\r\n * @returns {QshError} 包装后的错误对象\r\n */\r\n static handleApiError(error, context = {}) {\r\n let qshError;\r\n \r\n if (error instanceof QshError) {\r\n qshError = error;\r\n } else if (error instanceof Error) {\r\n qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n error.message,\r\n context,\r\n error\r\n );\r\n } else {\r\n qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n String(error),\r\n context\r\n );\r\n }\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理平台不支持错误\r\n * @param {string} platformType - 平台类型\r\n * @param {string} apiName - API 名称\r\n * @returns {QshError} 错误对象\r\n */\r\n static handlePlatformNotSupported(platformType, apiName) {\r\n const qshError = new QshError(\r\n ErrorTypes.PLATFORM_NOT_SUPPORTED,\r\n `API \"${apiName}\" is not supported on platform \"${platformType}\"`,\r\n { platformType, apiName }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理桥接未就绪错误\r\n * @param {string} apiName - API 名称\r\n * @returns {QshError} 错误对象\r\n */\r\n static handleBridgeNotReady(apiName) {\r\n const qshError = new QshError(\r\n ErrorTypes.BRIDGE_NOT_READY,\r\n `Bridge is not ready when calling \"${apiName}\"`,\r\n { apiName }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理参数验证错误\r\n * @param {string} apiName - API 名称\r\n * @param {string} paramName - 参数名称\r\n * @param {string} expectedType - 期望的参数类型\r\n * @param {any} actualValue - 实际参数值\r\n * @returns {QshError} 错误对象\r\n */\r\n static handleInvalidParameters(apiName, paramName, expectedType, actualValue) {\r\n const qshError = new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n `Invalid parameter \"${paramName}\" in \"${apiName}\": expected ${expectedType}, got ${typeof actualValue}`,\r\n { apiName, paramName, expectedType, actualValue }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 安全地包装函数执行,捕获并处理错误\r\n * @param {Function} fn - 要执行的函数\r\n * @param {Object} context - 执行上下文\r\n * @returns {any} 函数执行结果\r\n */\r\n static safeExecute(fn, context = {}) {\r\n try {\r\n return fn();\r\n } catch (error) {\r\n return ErrorHandler.handleApiError(error, context);\r\n }\r\n }\r\n\r\n /**\r\n * 异步安全包装\r\n * @param {Function} fn - 异步函数\r\n * @param {Object} context - 执行上下文\r\n * @returns {Promise} Promise 对象\r\n */\r\n static async safeExecuteAsync(fn, context = {}) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n return ErrorHandler.handleApiError(error, context);\r\n }\r\n }\r\n\r\n /**\r\n * 记录错误日志\r\n * @param {QshError} error - 错误对象\r\n * @private\r\n */\r\n static logError(error) {\r\n if (typeof console !== 'undefined') {\r\n const logMessage = `[QSH-SDK Error] ${error.type}: ${error.message}`;\r\n \r\n if (ErrorHandler.isDebugMode) {\r\n console.error(logMessage, {\r\n context: error.context,\r\n originalError: error.originalError,\r\n stack: error.stack,\r\n timestamp: error.timestamp\r\n });\r\n } else {\r\n console.error(logMessage);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 通知错误回调\r\n * @param {QshError} error - 错误对象\r\n * @private\r\n */\r\n static notifyCallbacks(error) {\r\n ErrorHandler.errorCallbacks.forEach(callback => {\r\n try {\r\n callback(error);\r\n } catch (callbackError) {\r\n // 避免回调错误导致无限循环\r\n if (typeof console !== 'undefined') {\r\n console.error('[QSH-SDK] Error in error callback:', callbackError);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 创建错误处理装饰器\r\n * @param {Object} context - 装饰器上下文\r\n * @returns {Function} 装饰器函数\r\n */\r\n static createErrorDecorator(context = {}) {\r\n return function(target, propertyKey, descriptor) {\r\n const originalMethod = descriptor.value;\r\n \r\n descriptor.value = function(...args) {\r\n return ErrorHandler.safeExecute(() => {\r\n return originalMethod.apply(this, args);\r\n }, { ...context, method: propertyKey, target: target.constructor.name });\r\n };\r\n \r\n return descriptor;\r\n };\r\n }\r\n}\r\n","/**\r\n * 状态管理器\r\n * 管理 SDK 初始化状态,优化性能\r\n */\r\n\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * SDK 状态枚举\r\n */\r\nexport const SDKStates = {\r\n UNINITIALIZED: 'uninitialized',\r\n INITIALIZING: 'initializing',\r\n READY: 'ready',\r\n ERROR: 'error'\r\n};\r\n\r\n/**\r\n * 状态管理器类(单例模式)\r\n */\r\nclass StateManager {\r\n constructor() {\r\n this.state = SDKStates.UNINITIALIZED;\r\n this.readyPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.initializationError = null;\r\n \r\n // 绑定方法,避免 this 丢失\r\n this.handleBridgeReady = this.handleBridgeReady.bind(this);\r\n this.handleInitializationError = this.handleInitializationError.bind(this);\r\n }\r\n\r\n /**\r\n * 获取当前状态\r\n * @returns {string} 当前状态\r\n */\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * 检查是否已准备就绪\r\n * @returns {boolean} 是否就绪\r\n */\r\n isReady() {\r\n return this.state === SDKStates.READY;\r\n }\r\n\r\n /**\r\n * 检查是否正在初始化\r\n * @returns {boolean} 是否正在初始化\r\n */\r\n isInitializing() {\r\n return this.state === SDKStates.INITIALIZING;\r\n }\r\n\r\n /**\r\n * 检查是否出错\r\n * @returns {boolean} 是否出错\r\n */\r\n hasError() {\r\n return this.state === SDKStates.ERROR;\r\n }\r\n\r\n /**\r\n * 获取初始化错误\r\n * @returns {Error|null} 错误对象\r\n */\r\n getInitializationError() {\r\n return this.initializationError;\r\n }\r\n\r\n /**\r\n * 等待 SDK 准备就绪(单例 Promise)\r\n * @returns {Promise<void>} 准备就绪的 Promise\r\n */\r\n waitForReady() {\r\n // 如果已经就绪,立即返回\r\n if (this.isReady()) {\r\n return Promise.resolve();\r\n }\r\n\r\n // 如果有错误,返回拒绝的 Promise\r\n if (this.hasError()) {\r\n return Promise.reject(this.initializationError);\r\n }\r\n\r\n // 如果还没有 Promise 实例,创建一个\r\n if (!this.readyPromise) {\r\n this.readyPromise = new Promise((resolve, reject) => {\r\n if (this.isReady()) {\r\n resolve();\r\n } else if (this.hasError()) {\r\n reject(this.initializationError);\r\n } else {\r\n // 添加到回调列表\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n }\r\n });\r\n }\r\n\r\n return this.readyPromise;\r\n }\r\n\r\n /**\r\n * 开始初始化\r\n * @param {Function} initFunction - 初始化函数\r\n * @returns {Promise<void>} 初始化 Promise\r\n */\r\n async startInitialization(initFunction) {\r\n if (this.state !== SDKStates.UNINITIALIZED) {\r\n return this.waitForReady();\r\n }\r\n\r\n this.state = SDKStates.INITIALIZING;\r\n\r\n try {\r\n await initFunction();\r\n this.handleBridgeReady();\r\n } catch (error) {\r\n this.handleInitializationError(error);\r\n throw error;\r\n }\r\n\r\n return this.waitForReady();\r\n }\r\n\r\n /**\r\n * 处理桥接就绪事件\r\n * @private\r\n */\r\n handleBridgeReady() {\r\n if (this.state !== SDKStates.INITIALIZING) {\r\n return;\r\n }\r\n\r\n this.state = SDKStates.READY;\r\n \r\n // 通知所有等待的回调\r\n this.readyCallbacks.forEach(callback => {\r\n try {\r\n callback();\r\n } catch (error) {\r\n ErrorHandler.handleApiError(error, { context: 'StateManager.handleBridgeReady' });\r\n }\r\n });\r\n\r\n // 清空回调列表\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n }\r\n\r\n /**\r\n * 处理初始化错误\r\n * @param {Error} error - 错误对象\r\n * @private\r\n */\r\n handleInitializationError(error) {\r\n this.state = SDKStates.ERROR;\r\n this.initializationError = error;\r\n\r\n // 通知所有等待的错误回调\r\n this.errorCallbacks.forEach(callback => {\r\n try {\r\n callback(error);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'StateManager.handleInitializationError' });\r\n }\r\n });\r\n\r\n // 清空回调列表\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n }\r\n\r\n /**\r\n * 重置状态管理器(用于测试或重新初始化)\r\n */\r\n reset() {\r\n this.state = SDKStates.UNINITIALIZED;\r\n this.readyPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.initializationError = null;\r\n }\r\n\r\n /**\r\n * 添加状态变化监听器\r\n * @param {string} targetState - 目标状态\r\n * @param {Function} callback - 回调函数\r\n * @returns {Function} 移除监听器的函数\r\n */\r\n onStateChange(targetState, callback) {\r\n if (this.state === targetState) {\r\n // 状态已经匹配,立即调用\r\n setTimeout(() => callback(this.state), 0);\r\n return () => {}; // 返回空的移除函数\r\n }\r\n\r\n const stateHandler = () => {\r\n if (this.state === targetState) {\r\n callback(this.state);\r\n }\r\n };\r\n\r\n if (targetState === SDKStates.READY) {\r\n this.readyCallbacks.push(stateHandler);\r\n } else if (targetState === SDKStates.ERROR) {\r\n this.errorCallbacks.push(stateHandler);\r\n }\r\n\r\n // 返回移除监听器的函数\r\n return () => {\r\n const readyIndex = this.readyCallbacks.indexOf(stateHandler);\r\n if (readyIndex > -1) {\r\n this.readyCallbacks.splice(readyIndex, 1);\r\n }\r\n\r\n const errorIndex = this.errorCallbacks.indexOf(stateHandler);\r\n if (errorIndex > -1) {\r\n this.errorCallbacks.splice(errorIndex, 1);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 获取状态统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n getStats() {\r\n return {\r\n state: this.state,\r\n readyCallbacksCount: this.readyCallbacks.length,\r\n errorCallbacksCount: this.errorCallbacks.length,\r\n hasReadyPromise: !!this.readyPromise,\r\n hasInitializationError: !!this.initializationError\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst stateManager = new StateManager();\r\n\r\n// 导出单例实例和类\r\nexport { stateManager as default, StateManager };\r\n\r\n/**\r\n * 便利函数:等待 SDK 就绪\r\n * @returns {Promise<void>}\r\n */\r\nexport const waitForReady = () => stateManager.waitForReady();\r\n\r\n/**\r\n * 便利函数:检查是否就绪\r\n * @returns {boolean}\r\n */\r\nexport const isReady = () => stateManager.isReady();\r\n\r\n/**\r\n * 便利函数:获取当前状态\r\n * @returns {string}\r\n */\r\nexport const getState = () => stateManager.getState();\r\n","/**\r\n * 日志记录模块\r\n * 提供分级日志记录和调试功能\r\n */\r\n\r\n/**\r\n * 日志级别枚举\r\n */\r\nexport const LogLevels = {\r\n ERROR: 0,\r\n WARN: 1,\r\n INFO: 2,\r\n DEBUG: 3,\r\n TRACE: 4\r\n};\r\n\r\n/**\r\n * 日志级别名称映射\r\n */\r\nconst LogLevelNames = {\r\n [LogLevels.ERROR]: 'ERROR',\r\n [LogLevels.WARN]: 'WARN',\r\n [LogLevels.INFO]: 'INFO',\r\n [LogLevels.DEBUG]: 'DEBUG',\r\n [LogLevels.TRACE]: 'TRACE'\r\n};\r\n\r\n/**\r\n * 日志记录器类\r\n */\r\nexport class Logger {\r\n static currentLevel = LogLevels.ERROR; // 生产环境默认只显示错误\r\n static enabledModules = new Set(); // 启用日志的模块\r\n static logHistory = []; // 日志历史(最多保留1000条)\r\n static maxHistorySize = 1000;\r\n static prefix = '[QSH-SDK]';\r\n static reporter = null; // 可注入的外部 reporter\r\n\r\n /**\r\n * 设置日志级别\r\n * @param {number} level - 日志级别\r\n */\r\n static setLevel(level) {\r\n if (level >= LogLevels.ERROR && level <= LogLevels.TRACE) {\r\n Logger.currentLevel = level;\r\n Logger.log(LogLevels.INFO, 'Logger', `日志级别设置为: ${LogLevelNames[level]}`);\r\n }\r\n }\r\n\r\n /**\r\n * 启用开发模式(显示所有日志)\r\n */\r\n static enableDevMode() {\r\n Logger.setLevel(LogLevels.DEBUG);\r\n Logger.log(LogLevels.INFO, 'Logger', '开发模式已启用');\r\n }\r\n\r\n /**\r\n * 启用生产模式(只显示错误和警告)\r\n */\r\n static enableProdMode() {\r\n Logger.setLevel(LogLevels.WARN);\r\n Logger.log(LogLevels.INFO, 'Logger', '生产模式已启用');\r\n }\r\n\r\n /**\r\n * 启用特定模块的日志\r\n * @param {string} module - 模块名称\r\n */\r\n static enableModule(module) {\r\n Logger.enabledModules.add(module);\r\n Logger.log(LogLevels.INFO, 'Logger', `模块日志已启用: ${module}`);\r\n }\r\n\r\n /**\r\n * 禁用特定模块的日志\r\n * @param {string} module - 模块名称\r\n */\r\n static disableModule(module) {\r\n Logger.enabledModules.delete(module);\r\n Logger.log(LogLevels.INFO, 'Logger', `模块日志已禁用: ${module}`);\r\n }\r\n\r\n /**\r\n * 检查是否应该记录日志\r\n * @param {number} level - 日志级别\r\n * @param {string} module - 模块名称\r\n * @returns {boolean} 是否应该记录\r\n * @private\r\n */\r\n static shouldLog(level, module) {\r\n // 检查日志级别\r\n if (level > Logger.currentLevel) {\r\n return false;\r\n }\r\n\r\n // 检查模块是否启用(如果有指定模块)\r\n if (module && Logger.enabledModules.size > 0) {\r\n return Logger.enabledModules.has(module);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * 核心日志记录方法\r\n * @param {number} level - 日志级别\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 日志消息\r\n * @param {any[]} args - 额外参数\r\n * @private\r\n */\r\n static log(level, module, message, ...args) {\r\n if (!Logger.shouldLog(level, module)) {\r\n return;\r\n }\r\n\r\n const timestamp = new Date().toISOString();\r\n const levelName = LogLevelNames[level];\r\n const modulePrefix = module ? `[${module}]` : '';\r\n const logMessage = `${Logger.prefix} ${modulePrefix} ${message}`;\r\n\r\n // 记录到历史\r\n const logEntry = {\r\n timestamp,\r\n level,\r\n levelName,\r\n module,\r\n message,\r\n args\r\n };\r\n\r\n Logger.addToHistory(logEntry);\r\n\r\n // 可选外部 reporter(用于观测/上报)\r\n if (typeof Logger.reporter === 'function') {\r\n try {\r\n Logger.reporter(logEntry);\r\n } catch (e) {\r\n // reporter 不应影响主流程\r\n }\r\n }\r\n\r\n // 输出到控制台\r\n Logger.outputToConsole(level, logMessage, ...args);\r\n }\r\n\r\n /**\r\n * 添加日志到历史记录\r\n * @param {Object} logEntry - 日志条目\r\n * @private\r\n */\r\n static addToHistory(logEntry) {\r\n Logger.logHistory.push(logEntry);\r\n \r\n // 限制历史记录大小\r\n if (Logger.logHistory.length > Logger.maxHistorySize) {\r\n Logger.logHistory.shift();\r\n }\r\n }\r\n\r\n /**\r\n * 输出到控制台\r\n * @param {number} level - 日志级别\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n * @private\r\n */\r\n static outputToConsole(level, message, ...args) {\r\n if (typeof console === 'undefined') {\r\n return;\r\n }\r\n\r\n const hasArgs = args && args.length > 0;\r\n\r\n switch (level) {\r\n case LogLevels.ERROR:\r\n hasArgs ? console.error(message, ...args) : console.error(message);\r\n break;\r\n case LogLevels.WARN:\r\n hasArgs ? console.warn(message, ...args) : console.warn(message);\r\n break;\r\n case LogLevels.INFO:\r\n hasArgs ? console.info(message, ...args) : console.info(message);\r\n break;\r\n case LogLevels.DEBUG:\r\n case LogLevels.TRACE:\r\n hasArgs ? console.log(message, ...args) : console.log(message);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * 错误级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static error(module, message, ...args) {\r\n Logger.log(LogLevels.ERROR, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 警告级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static warn(module, message, ...args) {\r\n Logger.log(LogLevels.WARN, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 信息级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static info(module, message, ...args) {\r\n Logger.log(LogLevels.INFO, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 调试级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static debug(module, message, ...args) {\r\n Logger.log(LogLevels.DEBUG, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 跟踪级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static trace(module, message, ...args) {\r\n Logger.log(LogLevels.TRACE, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 获取日志历史\r\n * @param {number} [count] - 获取的条数,默认全部\r\n * @returns {Array} 日志条目数组\r\n */\r\n static getHistory(count) {\r\n if (count && count > 0) {\r\n return Logger.logHistory.slice(-count);\r\n }\r\n return [...Logger.logHistory];\r\n }\r\n\r\n /**\r\n * 清空日志历史\r\n */\r\n static clearHistory() {\r\n Logger.logHistory = [];\r\n Logger.log(LogLevels.INFO, 'Logger', '日志历史已清空');\r\n }\r\n\r\n /**\r\n * 获取日志统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n static getStats() {\r\n const stats = {\r\n currentLevel: Logger.currentLevel,\r\n currentLevelName: LogLevelNames[Logger.currentLevel],\r\n enabledModules: Array.from(Logger.enabledModules),\r\n historySize: Logger.logHistory.length,\r\n maxHistorySize: Logger.maxHistorySize\r\n };\r\n\r\n // 按级别统计日志数量\r\n const levelCounts = {};\r\n for (const level of Object.keys(LogLevelNames)) {\r\n levelCounts[LogLevelNames[level]] = 0;\r\n }\r\n\r\n Logger.logHistory.forEach(entry => {\r\n levelCounts[entry.levelName]++;\r\n });\r\n\r\n stats.levelCounts = levelCounts;\r\n return stats;\r\n }\r\n\r\n /**\r\n * 导出日志到 JSON\r\n * @param {number} [count] - 导出的条数,默认全部\r\n * @returns {string} JSON 字符串\r\n */\r\n static exportToJSON(count) {\r\n const history = Logger.getHistory(count);\r\n const stats = Logger.getStats();\r\n \r\n return JSON.stringify({\r\n exportTime: new Date().toISOString(),\r\n stats,\r\n logs: history\r\n }, null, 2);\r\n }\r\n\r\n /**\r\n * 创建模块专用日志器\r\n * @param {string} moduleName - 模块名称\r\n * @returns {Object} 模块日志器对象\r\n */\r\n static createModuleLogger(moduleName) {\r\n return {\r\n error: (message, ...args) => Logger.error(moduleName, message, ...args),\r\n warn: (message, ...args) => Logger.warn(moduleName, message, ...args),\r\n info: (message, ...args) => Logger.info(moduleName, message, ...args),\r\n debug: (message, ...args) => Logger.debug(moduleName, message, ...args),\r\n trace: (message, ...args) => Logger.trace(moduleName, message, ...args)\r\n };\r\n }\r\n\r\n /**\r\n * 设置外部 reporter,用于接入自定义观测/上报\r\n * @param {(entry: any) => void|null} reporter\r\n */\r\n static setReporter(reporter) {\r\n Logger.reporter = typeof reporter === 'function' ? reporter : null;\r\n }\r\n}\r\n\r\n// 根据环境自动设置日志级别\r\nif (typeof window !== 'undefined') {\r\n // 检查是否在开发环境\r\n const isLocalhost = window.location && (\r\n window.location.hostname === 'localhost' ||\r\n window.location.hostname === '127.0.0.1' ||\r\n window.location.hostname.includes('192.168.')\r\n );\r\n\r\n // 检查是否有调试参数\r\n const hasDebugParam = window.location && (\r\n window.location.search.includes('debug=true') ||\r\n window.location.search.includes('qsh_debug=1')\r\n );\r\n\r\n // 检查localStorage调试标志\r\n let hasDebugStorage = false;\r\n try {\r\n hasDebugStorage = localStorage && localStorage.getItem('qsh_debug') === 'true';\r\n } catch (e) {\r\n // localStorage 访问失败,忽略\r\n }\r\n\r\n if (isLocalhost || hasDebugParam || hasDebugStorage) {\r\n Logger.enableDevMode();\r\n }\r\n}\r\n\r\n// 创建常用模块的日志器\r\nexport const bridgeLogger = Logger.createModuleLogger('Bridge');\r\nexport const platformLogger = Logger.createModuleLogger('Platform');\r\nexport const apiLogger = Logger.createModuleLogger('API');\r\nexport const stateLogger = Logger.createModuleLogger('State');\r\n\r\nexport default Logger;\r\n","/**\r\n * JSBridge 初始化模块\r\n * 负责初始化与原生端的桥接\r\n */\r\n\r\nimport { isUniApp, isHtml5Plus, isUvue, isNvue, isAppPlus } from './environment.js';\r\nimport stateManager, { SDKStates } from './state-manager.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\nimport { bridgeLogger } from './logger.js';\r\n\r\n// 文档准备状态正则\r\nconst READY_STATE_REGEX = /complete|loaded|interactive/;\r\n\r\n\r\n/**\r\n * 在 APP 环境初始化\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否进入了 APP 初始化流程\r\n * @since 2.0.0\r\n */\r\nfunction initializeInApp(callback) {\r\n if (isUniApp() || isHtml5Plus()) {\r\n bridgeLogger.debug('检测到 APP 环境,开始初始化');\r\n \r\n if (window.__uniapp_x_postMessage || window.__uniapp_x_ || \r\n window.__dcloud_weex_postMessage || window.__dcloud_weex_) {\r\n // NVUE/UVUE:等待 DOMContentLoaded 再回调\r\n bridgeLogger.debug('NVUE/UVUE 环境,等待 DOMContentLoaded');\r\n document.addEventListener('DOMContentLoaded', callback);\r\n } else if (window.plus && READY_STATE_REGEX.test(document.readyState)) {\r\n // plus 已可用且文档已就绪\r\n bridgeLogger.debug('Plus 环境已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else {\r\n // 传统 plus 场景:等待 plusready 事件\r\n bridgeLogger.debug('Plus 环境,等待 plusready 事件');\r\n document.addEventListener('plusready', callback);\r\n }\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 在微信小程序环境初始化\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否进入了微信初始化流程\r\n * @since 2.0.0\r\n */\r\nfunction initializeInWeixin(callback) {\r\n if (window.wx && window.wx.miniProgram) {\r\n bridgeLogger.debug('检测到微信小程序环境,开始初始化');\r\n \r\n if (window.WeixinJSBridge && window.WeixinJSBridge.invoke) {\r\n bridgeLogger.debug('微信 JSBridge 已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else {\r\n bridgeLogger.debug('微信 JSBridge 未就绪,等待 WeixinJSBridgeReady 事件');\r\n document.addEventListener('WeixinJSBridgeReady', callback);\r\n }\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 初始化 JSBridge\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否成功开始初始化\r\n * @example\r\n * initializeBridge(() => console.log('ready'))\r\n * @since 2.0.0\r\n */\r\nexport function initializeBridge(callback) {\r\n bridgeLogger.info('开始初始化 JSBridge');\r\n \r\n // 尝试 APP 环境初始化\r\n if (initializeInApp(callback)) {\r\n bridgeLogger.info('使用 APP 环境初始化');\r\n return true;\r\n }\r\n \r\n // 尝试微信小程序环境初始化\r\n if (initializeInWeixin(callback)) {\r\n bridgeLogger.info('使用微信小程序环境初始化');\r\n return true;\r\n }\r\n \r\n // 默认情况下,在 DOM 加载完成后初始化;若已完成则立即回调\r\n bridgeLogger.debug('使用默认 H5 环境初始化');\r\n if (READY_STATE_REGEX.test(document.readyState)) {\r\n bridgeLogger.debug('DOM 已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else {\r\n bridgeLogger.debug('DOM 未就绪,等待 DOMContentLoaded');\r\n document.addEventListener('DOMContentLoaded', callback);\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * 触发 JSBridge 准备就绪事件(优化版)\r\n * @returns {void}\r\n * @since 2.0.0\r\n */\r\nfunction fireJSBridgeReadyEvent() {\r\n return ErrorHandler.safeExecute(() => {\r\n window.UniAppJSBridge = true;\r\n document.dispatchEvent(new CustomEvent('UniAppJSBridgeReady', {\r\n bubbles: true,\r\n cancelable: true\r\n }));\r\n \r\n // 通知状态管理器\r\n stateManager.handleBridgeReady();\r\n }, { context: 'fireJSBridgeReadyEvent' });\r\n}\r\n\r\n/**\r\n * 等待 JSBridge 准备就绪(性能优化版)\r\n * @returns {Promise<void>} 当触发 UniAppJSBridgeReady 后 resolve\r\n * @example\r\n * await waitForBridge()\r\n * @since 2.0.0\r\n */\r\nexport function waitForBridge() {\r\n // 使用状态管理器的单例 Promise\r\n return stateManager.waitForReady();\r\n}\r\n\r\n/**\r\n * 检查桥接是否就绪\r\n * @returns {boolean} 是否就绪\r\n * @since 2.0.0\r\n */\r\nexport function isBridgeReady() {\r\n return stateManager.isReady();\r\n}\r\n\r\n// 导出 fireJSBridgeReadyEvent\r\nexport { fireJSBridgeReadyEvent };\r\n\r\n/**\r\n * 手动初始化 Bridge(性能优化版)\r\n * @returns {Promise<void>} 初始化完成的 Promise\r\n * @since 2.0.0\r\n */\r\nexport function initBridge() {\r\n return stateManager.startInitialization(async () => {\r\n return new Promise((resolve, reject) => {\r\n const handleReady = () => {\r\n resolve();\r\n };\r\n\r\n const handleError = (error) => {\r\n const bridgeError = ErrorHandler.handleApiError(error, { \r\n context: 'bridge initialization' \r\n });\r\n reject(bridgeError);\r\n };\r\n\r\n try {\r\n initializeBridge(() => {\r\n handleReady();\r\n });\r\n } catch (syncError) {\r\n handleError(syncError);\r\n }\r\n });\r\n });\r\n}","/**\r\n * 微信 JS-SDK 自动配置管理器\r\n * 实现约定优于配置的自动化配置方案\r\n */\r\n\r\nimport { ErrorHandler, ErrorTypes, QshError } from './error-handler.js';\r\nimport { platformLogger } from './logger.js';\r\n\r\n/**\r\n * 微信配置状态枚举\r\n */\r\nexport const WeixinConfigStates = {\r\n UNINITIALIZED: 'uninitialized',\r\n CONFIGURING: 'configuring',\r\n CONFIGURED: 'configured',\r\n ERROR: 'error'\r\n};\r\n\r\nexport function isWeixinJSSDKAvailable() {\r\n if (typeof window === 'undefined' || !window.wx) {\r\n return false;\r\n }\r\n\r\n return (\r\n typeof window.wx.config === 'function' &&\r\n typeof window.wx.ready === 'function' &&\r\n typeof window.wx.error === 'function'\r\n );\r\n}\r\n\r\n/**\r\n * 微信配置管理器类\r\n */\r\nexport class WeixinConfigManager {\r\n constructor() {\r\n this.state = WeixinConfigStates.UNINITIALIZED;\r\n this.configPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.lastError = null;\r\n \r\n // 固定配置 - 支持开发环境代理\r\n this.runtimeConfig = {\r\n clientId: null,\r\n isProd: false\r\n };\r\n this.CONFIG_API_URL = this.getConfigApiUrl(this.runtimeConfig.isProd);\r\n this.DEFAULT_JS_API_LIST = ['chooseImage', 'uploadImage','previewImage','downloadImage','getLocalImgData', 'scanQRCode', 'getLocation', 'openLocation', \"updateAppMessageShareData\", \"updateTimelineShareData\"]; // 默认测试API\r\n \r\n // 绑定方法,避免 this 丢失\r\n this.handleConfigSuccess = this.handleConfigSuccess.bind(this);\r\n this.handleConfigError = this.handleConfigError.bind(this);\r\n }\r\n\r\n configure(config = {}) {\r\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'config参数异常',\r\n { config }\r\n );\r\n }\r\n\r\n if (!Object.prototype.hasOwnProperty.call(config, 'clientId')) {\r\n throw this.createMissingClientIdError();\r\n }\r\n\r\n if (typeof config.clientId !== 'string' || !config.clientId.trim()) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'clientId参数异常',\r\n { clientId: config.clientId }\r\n );\r\n }\r\n\r\n if (\r\n Object.prototype.hasOwnProperty.call(config, 'isProd') &&\r\n typeof config.isProd !== 'boolean'\r\n ) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'isProd参数异常',\r\n { isProd: config.isProd }\r\n );\r\n }\r\n\r\n const nextClientId = config.clientId.trim();\r\n const nextIsProd = config.isProd === true;\r\n const hasChanged =\r\n nextClientId !== this.runtimeConfig.clientId ||\r\n nextIsProd !== this.runtimeConfig.isProd;\r\n\r\n this.runtimeConfig = {\r\n ...this.runtimeConfig,\r\n clientId: nextClientId,\r\n isProd: nextIsProd\r\n };\r\n this.CONFIG_API_URL = this.getConfigApiUrl(nextIsProd);\r\n\r\n const shouldReset =\r\n this.state === WeixinConfigStates.ERROR ||\r\n (hasChanged && (\r\n this.state === WeixinConfigStates.CONFIGURING ||\r\n this.state === WeixinConfigStates.CONFIGURED\r\n ));\r\n\r\n if (shouldReset) {\r\n this.reset();\r\n }\r\n\r\n platformLogger.info('Updated Weixin runtime config', {\r\n clientId: this.runtimeConfig.clientId,\r\n isProd: this.runtimeConfig.isProd,\r\n configApiUrl: this.CONFIG_API_URL\r\n });\r\n\r\n return this.getRuntimeConfig();\r\n }\r\n\r\n getRuntimeConfig() {\r\n return {\r\n ...this.runtimeConfig\r\n };\r\n }\r\n\r\n hasClientId() {\r\n return typeof this.runtimeConfig.clientId === 'string' && this.runtimeConfig.clientId.length > 0;\r\n }\r\n\r\n hasRequiredConfig() {\r\n return this.isTestMode() || this.hasClientId();\r\n }\r\n\r\n createMissingClientIdError() {\r\n return new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'clientId错误',\r\n { field: 'clientId' }\r\n );\r\n }\r\n\r\n /**\r\n * 获取配置API的URL(支持开发环境代理)\r\n * @returns {string} API URL\r\n * @private\r\n */\r\n getConfigApiUrl(isProd = false) {\r\n if (isProd) {\r\n return 'https://tyck-service.xj-agri.gov.cn/api/wechat/mp/jssdk-sign';\r\n }\r\n\r\n return 'https://unified-platform-service.xjy2.cn/api/wechat/mp/jssdk-sign';\r\n }\r\n\r\n /**\r\n * 获取当前页面URL(不包含hash部分)\r\n * @returns {string} 页面URL\r\n * @private\r\n */\r\n getCurrentPageUrl() {\r\n if (typeof window === 'undefined' || !window.location) {\r\n throw new Error('无法获取当前页面URL');\r\n }\r\n \r\n const url = window.location.href;\r\n const hashIndex = url.indexOf('#');\r\n return hashIndex !== -1 ? url.substring(0, hashIndex) : url;\r\n }\r\n\r\n /**\r\n * 获取微信配置\r\n * @returns {Promise<Object>} 配置对象\r\n * @private\r\n */\r\n async fetchWeixinConfig() {\r\n const currentUrl = this.getCurrentPageUrl();\r\n \r\n // 检查是否为测试模式\r\n if (this.isTestMode()) {\r\n platformLogger.info('使用测试模式,返回模拟配置');\r\n return this.getMockConfig();\r\n }\r\n\r\n if (!this.hasClientId()) {\r\n throw this.createMissingClientIdError();\r\n }\r\n\r\n const configApiUrl = this.getConfigApiUrl(this.runtimeConfig.isProd);\r\n this.CONFIG_API_URL = configApiUrl;\r\n const requestUrl = `${configApiUrl}?clientId=${this.runtimeConfig.clientId}&url=${encodeURIComponent(currentUrl)}`;\r\n platformLogger.debug('请求微信配置', { url: requestUrl });\r\n \r\n try {\r\n const response = await fetch(requestUrl);\r\n \r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n \r\n const result = await response.json();\r\n platformLogger.debug('微信配置响应', result);\r\n \r\n // 检查响应格式\r\n if (!result.success || result.code !== 200) {\r\n throw new Error(`配置获取失败: ${result.message || '未知错误'}`);\r\n }\r\n \r\n // 验证必需的字段\r\n const { data } = result;\r\n if (!data || !data.appId || !data.timestamp || !data.nonceStr || !data.signature) {\r\n throw new Error('配置数据格式不正确,缺少必需字段');\r\n }\r\n \r\n return data;\r\n \r\n } catch (error) {\r\n platformLogger.error('获取微信配置失败', error);\r\n \r\n // 如果在开发环境且不是真正的微信环境,提供降级方案\r\n if (this.shouldUseTestMode(error)) {\r\n platformLogger.warn('网络请求失败,降级到测试模式');\r\n return this.getMockConfig();\r\n }\r\n \r\n throw new QshError(\r\n ErrorTypes.NETWORK_ERROR,\r\n `获取微信配置失败: ${error.message}`,\r\n { url: requestUrl, originalError: error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 检查是否为测试模式\r\n * @returns {boolean}\r\n * @private\r\n */\r\n isTestMode() {\r\n if (typeof window === 'undefined') return false;\r\n \r\n // 通过URL参数启用测试模式\r\n const urlParams = new URLSearchParams(window.location.search);\r\n if (urlParams.get('qsh_test') === 'true') return true;\r\n \r\n // 通过localStorage启用测试模式\r\n try {\r\n if (localStorage.getItem('qsh_test') === 'true') return true;\r\n } catch (e) {\r\n // localStorage访问失败,忽略\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * 检查是否应该降级到测试模式\r\n * @param {Error} error - 网络错误\r\n * @returns {boolean}\r\n * @private\r\n */\r\n shouldUseTestMode(error) {\r\n // 在开发环境且不是真正的微信小程序环境时,可以降级\r\n if (typeof window === 'undefined') return false;\r\n\r\n const isDev = window.location.hostname === 'localhost' || \r\n window.location.hostname.includes('natappfree.cc');\r\n const notInWeixin = !window.wx || !window.wx.miniProgram;\r\n const isCorsError = error.message.includes('CORS') || error.message.includes('Failed to fetch');\r\n \r\n return isDev && notInWeixin && isCorsError;\r\n }\r\n\r\n /**\r\n * 获取模拟配置(用于测试)\r\n * @returns {Object} 模拟的配置对象\r\n * @private\r\n */\r\n getMockConfig() {\r\n return {\r\n appId: 'wx_test_app_id',\r\n timestamp: Math.floor(Date.now() / 1000).toString(),\r\n nonceStr: Math.random().toString(36).substring(2, 15),\r\n signature: 'test_signature_' + Math.random().toString(36).substring(2, 10)\r\n };\r\n }\r\n\r\n /**\r\n * 执行微信配置\r\n * @param {Object} configData - 配置数据\r\n * @private\r\n */\r\n executeWeixinConfig(configData) {\r\n // 检查是否为测试模式\r\n if (this.isTestMode() || configData.appId === 'wx_test_app_id') {\r\n platformLogger.info('测试模式:模拟微信配置成功');\r\n // 延迟执行成功回调,模拟异步配置过程\r\n setTimeout(() => {\r\n this.handleConfigSuccess();\r\n }, 100);\r\n return;\r\n }\r\n \r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信JS-SDK未加载');\r\n }\r\n \r\n const configOptions = {\r\n debug: false, // 生产环境关闭调试\r\n appId: configData.appId,\r\n timestamp: parseInt(configData.timestamp),\r\n nonceStr: configData.nonceStr,\r\n signature: configData.signature,\r\n jsApiList: this.DEFAULT_JS_API_LIST\r\n };\r\n \r\n platformLogger.info('执行微信配置', configOptions);\r\n \r\n // 设置成功和错误回调\r\n window.wx.ready(this.handleConfigSuccess);\r\n window.wx.error(this.handleConfigError);\r\n \r\n // 执行配置\r\n window.wx.config(configOptions);\r\n }\r\n\r\n /**\r\n * 处理配置成功\r\n * @private\r\n */\r\n handleConfigSuccess() {\r\n platformLogger.info('微信配置成功');\r\n this.state = WeixinConfigStates.CONFIGURED;\r\n this.lastError = null;\r\n this.configPromise = null;\r\n\r\n const readyCallbacks = [...this.readyCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n readyCallbacks.forEach(callback => {\r\n try {\r\n callback();\r\n } catch (error) {\r\n ErrorHandler.handleApiError(error, { context: 'WeixinConfigManager.handleConfigSuccess' });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 处理配置错误\r\n * @param {Object} res - 微信返回的错误信息\r\n * @private\r\n */\r\n handleConfigError(res) {\r\n const errorMessage = `微信配置验证失败: ${JSON.stringify(res)}`;\r\n platformLogger.error(errorMessage, res);\r\n \r\n const qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n errorMessage,\r\n { weixinErrorResponse: res }\r\n );\r\n \r\n // 通知所有等待的错误回调\r\n\r\n this.state = WeixinConfigStates.ERROR;\r\n this.lastError = qshError;\r\n this.configPromise = null;\r\n\r\n const errorCallbacks = [...this.errorCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n errorCallbacks.forEach((callback) => {\r\n try {\r\n callback(qshError);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'WeixinConfigManager.handleConfigError' });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 自动配置微信JS-SDK\r\n * @returns {Promise<void>} 配置完成的Promise\r\n */\r\n async autoConfig() {\r\n if (!this.hasRequiredConfig()) {\r\n platformLogger.warn('clientId为空,等待qsh.config({ clientId })');\r\n return Promise.resolve();\r\n }\r\n\r\n // 如果已经配置过,直接返回\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n return Promise.resolve();\r\n }\r\n \r\n // 如果出错,返回错误\r\n if (this.state === WeixinConfigStates.ERROR) {\r\n return Promise.reject(this.lastError);\r\n }\r\n \r\n // 如果正在配置中,返回现有的Promise\r\n if (this.configPromise) {\r\n return this.configPromise;\r\n }\r\n \r\n // 开始配置\r\n this.state = WeixinConfigStates.CONFIGURING;\r\n \r\n this.configPromise = this.performAutoConfig();\r\n return this.configPromise;\r\n }\r\n\r\n /**\r\n * 执行自动配置逻辑\r\n * @returns {Promise<void>}\r\n * @private\r\n */\r\n async performAutoConfig() {\r\n try {\r\n // 检查环境\r\n if (typeof window === 'undefined') {\r\n throw new Error('非浏览器环境无法执行微信配置');\r\n }\r\n \r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信JS-SDK未加载,无法执行配置');\r\n }\r\n \r\n // 获取配置数据\r\n const configData = await this.fetchWeixinConfig();\r\n \r\n // 执行配置\r\n this.executeWeixinConfig(configData);\r\n \r\n // 等待配置完成\r\n return await new Promise((resolve, reject) => {\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n resolve();\r\n return;\r\n }\r\n \r\n if (this.state === WeixinConfigStates.ERROR) {\r\n reject(this.lastError);\r\n return;\r\n }\r\n \r\n // 添加到回调列表\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n });\r\n } catch (error) {\r\n const qshError = error instanceof QshError\r\n ? error\r\n : ErrorHandler.handleApiError(error, { context: 'WeixinConfigManager.performAutoConfig' });\r\n\r\n this.state = WeixinConfigStates.ERROR;\r\n this.lastError = qshError;\r\n this.configPromise = null;\r\n\r\n const errorCallbacks = [...this.errorCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n errorCallbacks.forEach((callback) => {\r\n try {\r\n callback(qshError);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'WeixinConfigManager.performAutoConfig.errorCallback' });\r\n }\r\n });\r\n\r\n throw qshError;\r\n }\r\n }\r\n /**\r\n * 等待配置完成\r\n * @returns {Promise<void>} 配置完成的Promise\r\n */\r\n waitForReady() {\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n return Promise.resolve();\r\n }\r\n \r\n if (this.state === WeixinConfigStates.ERROR) {\r\n return Promise.reject(this.lastError);\r\n }\r\n \r\n if (!this.hasRequiredConfig()) {\r\n return Promise.reject(this.createMissingClientIdError());\r\n }\r\n // 如果未开始配置,先启动配置\r\n if (this.state === WeixinConfigStates.UNINITIALIZED) {\r\n return this.autoConfig();\r\n }\r\n \r\n // 等待配置完成\r\n return new Promise((resolve, reject) => {\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n });\r\n }\r\n\r\n /**\r\n * 检查配置状态\r\n * @returns {boolean} 是否已配置\r\n */\r\n isReady() {\r\n return this.state === WeixinConfigStates.CONFIGURED;\r\n }\r\n\r\n /**\r\n * 获取当前状态\r\n * @returns {string} 当前状态\r\n */\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * 获取最后的错误\r\n * @returns {Error|null} 错误对象\r\n */\r\n getLastError() {\r\n return this.lastError;\r\n }\r\n\r\n /**\r\n * 重置配置管理器(用于重试或测试)\r\n */\r\n reset() {\r\n this.state = WeixinConfigStates.UNINITIALIZED;\r\n this.configPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.lastError = null;\r\n \r\n platformLogger.debug('微信配置管理器已重置');\r\n }\r\n\r\n /**\r\n * 获取配置统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n getStats() {\r\n return {\r\n state: this.state,\r\n readyCallbacksCount: this.readyCallbacks.length,\r\n errorCallbacksCount: this.errorCallbacks.length,\r\n hasConfigPromise: !!this.configPromise,\r\n hasLastError: !!this.lastError,\r\n configApiUrl: this.CONFIG_API_URL,\r\n clientId: this.runtimeConfig.clientId,\r\n isProd: this.runtimeConfig.isProd,\r\n jsApiList: this.DEFAULT_JS_API_LIST\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst weixinConfigManager = new WeixinConfigManager();\r\n\r\nexport default weixinConfigManager;\r\n","/**\r\n * 微信 JS-SDK 自动加载器和配置器\r\n * 在检测到微信小程序 web-view 环境时:\r\n * 1. 自动注入 jweixin 脚本(如果未引入)\r\n * 2. 自动获取配置并执行 wx.config\r\n */\r\n\r\nimport weixinConfigManager, { isWeixinJSSDKAvailable } from './weixin-config.js';\r\nimport { platformLogger } from './logger.js';\r\n\r\nlet isLoadingWeixinSDK = false;\r\nlet weixinSDKLoaded = false;\r\nlet weixinSDKLoadPromise = null;\r\nlet autoConfigStarted = false;\r\n\r\nfunction waitForExistingWeixinScript(script) {\r\n return new Promise((resolve) => {\r\n let settled = false;\r\n let timeoutId = null;\r\n\r\n const finish = async (loaded) => {\r\n if (settled) return;\r\n settled = true;\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n isLoadingWeixinSDK = false;\r\n weixinSDKLoaded = loaded;\r\n\r\n if (loaded) {\r\n try {\r\n await autoConfigWeixin();\r\n } catch (error) {\r\n platformLogger.error('微信配置失败,将使用消息桥作为后备', error);\r\n }\r\n }\r\n\r\n resolve();\r\n };\r\n\r\n const handleLoad = () => finish(isWeixinJSSDKAvailable());\r\n const handleError = () => {\r\n platformLogger.warn('已存在的微信 JS-SDK 脚本加载失败,SDK 将使用消息桥作为后备');\r\n finish(false);\r\n };\r\n\r\n script.addEventListener('load', handleLoad, { once: true });\r\n script.addEventListener('error', handleError, { once: true });\r\n\r\n setTimeout(() => {\r\n if (isWeixinJSSDKAvailable()) {\r\n handleLoad();\r\n }\r\n }, 0);\r\n\r\n timeoutId = setTimeout(() => {\r\n finish(isWeixinJSSDKAvailable());\r\n }, 3000);\r\n });\r\n}\r\n\r\nasync function ensureWeixinJSSDKLoaded(options = {}) {\r\n const { force = false, recoverFromError = false } = options;\r\n\r\n await loadWeixinJSSDKIfNeeded({ force });\r\n\r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信 JS-SDK 未正确加载,无法执行配置');\r\n }\r\n\r\n if (recoverFromError) {\r\n recoverWeixinConfigStateIfNeeded();\r\n }\r\n}\r\n\r\n/**\r\n * 判断是否需要加载 jweixin\r\n * @returns {boolean}\r\n */\r\nfunction shouldLoadWeixinSDK(force = false) {\r\n if (typeof window === 'undefined') return false;\r\n if (isWeixinJSSDKAvailable()) {\r\n weixinSDKLoaded = true;\r\n return false;\r\n }\r\n if (weixinSDKLoaded) return false;\r\n if (force) return true;\r\n const ua = navigator.userAgent || '';\r\n const inWeixin = /micromessenger/i.test(ua);\r\n const inMiniProgramUA = /miniProgram/i.test(ua);\r\n const hintedMiniProgram = typeof window.__wxjs_environment !== 'undefined' && window.__wxjs_environment === 'miniprogram';\r\n const hasMiniProgramBridge = !!(window.wx && window.wx.miniProgram);\r\n return inWeixin && (inMiniProgramUA || hintedMiniProgram || hasMiniProgramBridge);\r\n}\r\n\r\nfunction recoverWeixinConfigStateIfNeeded() {\r\n if (weixinConfigManager.getState() === 'error') {\r\n weixinConfigManager.reset();\r\n autoConfigStarted = false;\r\n }\r\n}\r\n\r\n/**\r\n * 自动执行微信配置\r\n * @returns {Promise<void>}\r\n * @private\r\n */\r\nasync function autoConfigWeixin() {\r\n if (autoConfigStarted) {\r\n return weixinConfigManager.waitForReady();\r\n }\r\n \r\n autoConfigStarted = true;\r\n platformLogger.info('开始自动配置微信JS-SDK');\r\n \r\n try {\r\n await weixinConfigManager.autoConfig();\r\n platformLogger.info('微信JS-SDK自动配置完成');\r\n } catch (error) {\r\n platformLogger.error('微信JS-SDK自动配置失败', error);\r\n // 不抛出错误,让SDK继续运行,使用消息桥作为后备\r\n }\r\n}\r\n\r\n/**\r\n * 按需加载微信 JS-SDK 并自动配置(幂等)\r\n * @returns {Promise<void>}\r\n * @example\r\n * await loadWeixinJSSDKIfNeeded()\r\n * @since 2.0.0\r\n */\r\nexport function loadWeixinJSSDKIfNeeded(options = {}) {\r\n const { force = false } = options;\r\n\r\n if (typeof window === 'undefined') {\r\n return Promise.resolve();\r\n }\r\n\r\n if (isWeixinJSSDKAvailable()) {\r\n weixinSDKLoaded = true;\r\n return Promise.resolve();\r\n }\r\n\r\n // 避免重复注入\r\n const existingScript = document.getElementById('weixin-jssdk');\r\n if (existingScript) {\r\n if (weixinSDKLoadPromise) {\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n isLoadingWeixinSDK = true;\r\n weixinSDKLoadPromise = waitForExistingWeixinScript(existingScript).finally(() => {\r\n weixinSDKLoadPromise = null;\r\n });\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n if (!shouldLoadWeixinSDK(force)) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (weixinSDKLoadPromise) {\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n weixinSDKLoadPromise = new Promise((resolve) => {\r\n isLoadingWeixinSDK = true;\r\n \r\n try {\r\n const script = document.createElement('script');\r\n script.id = 'weixin-jssdk';\r\n script.type = 'text/javascript';\r\n script.async = true;\r\n script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.2.js';\r\n \r\n script.onload = async function() {\r\n weixinSDKLoaded = true;\r\n isLoadingWeixinSDK = false;\r\n platformLogger.info('微信 JS-SDK 已自动加载');\r\n \r\n // 自动执行配置\r\n try {\r\n await autoConfigWeixin();\r\n } catch (error) {\r\n platformLogger.error('微信配置失败,将使用消息桥作为后备', error);\r\n }\r\n resolve();\r\n };\r\n \r\n script.onerror = function() {\r\n isLoadingWeixinSDK = false;\r\n platformLogger.warn('微信 JS-SDK 加载失败,SDK 将使用消息桥作为后备');\r\n resolve(); // 即使加载失败也resolve,让SDK继续运行\r\n };\r\n\r\n // 尽可能早插入到 <head>\r\n const head = document.getElementsByTagName('head')[0] || document.documentElement;\r\n head.appendChild(script);\r\n } catch (err) {\r\n isLoadingWeixinSDK = false;\r\n platformLogger.error('注入微信 JS-SDK 失败', err);\r\n resolve(); // 即使注入失败也resolve,让SDK继续运行\r\n }\r\n }).finally(() => {\r\n weixinSDKLoadPromise = null;\r\n });\r\n\r\n return weixinSDKLoadPromise;\r\n}\r\n\r\n/**\r\n * 等待微信配置完成\r\n * @returns {Promise<void>} 配置完成的Promise\r\n * @example\r\n * await waitForWeixinConfig()\r\n * @since 2.0.0\r\n */\r\nexport function waitForWeixinConfig() {\r\n return ensureWeixinJSSDKLoaded({ force: true, recoverFromError: true })\r\n .then(() => weixinConfigManager.waitForReady());\r\n}\r\n\r\nexport function configureWeixin(options = {}) {\r\n const runtimeConfig = weixinConfigManager.configure(options);\r\n\r\n if (typeof window === 'undefined') {\r\n return runtimeConfig;\r\n }\r\n\r\n ensureWeixinJSSDKLoaded({\r\n force: true,\r\n recoverFromError: weixinConfigManager.getState() === 'error'\r\n })\r\n .then(() => {\r\n if (!weixinConfigManager.isReady()) {\r\n return weixinConfigManager.waitForReady().catch((error) => {\r\n platformLogger.error('Failed to auto-configure Weixin after qsh.config()', error);\r\n });\r\n }\r\n\r\n if (window.wx && !isWeixinJSSDKAvailable()) {\r\n platformLogger.warn('window.wx 已存在,但微信 JS-SDK 尚未就绪,跳过自动配置');\r\n }\r\n\r\n return undefined;\r\n })\r\n .catch((error) => {\r\n platformLogger.error('Failed to preload Weixin JS-SDK', error);\r\n });\r\n\r\n return runtimeConfig;\r\n}\r\n\r\n/**\r\n * 检查微信配置是否完成\r\n * @returns {boolean} 是否已配置\r\n * @example\r\n * if (isWeixinConfigReady()) { console.log('ready') }\r\n * @since 2.0.0\r\n */\r\nexport function isWeixinConfigReady() {\r\n return weixinConfigManager.isReady();\r\n}\r\n\r\n/**\r\n * 获取微信配置状态\r\n * @returns {string} 配置状态\r\n * @example\r\n * console.log(getWeixinConfigState()) // returns state string\r\n * @since 2.0.0\r\n */\r\nexport function getWeixinConfigState() {\r\n return weixinConfigManager.getState();\r\n}\r\n\r\n/**\r\n * 获取微信配置管理器(用于调试)\r\n * @returns {Object} 配置管理器实例\r\n * @example\r\n * const stats = getWeixinConfigManager().getStats()\r\n * @since 2.0.0\r\n */\r\nexport function getWeixinConfigManager() {\r\n return weixinConfigManager;\r\n}\r\n\r\n/**\r\n * 手动重试微信配置(用于错误恢复)\r\n * @returns {Promise<void>} 配置完成的Promise\r\n * @example\r\n * await retryWeixinConfig()\r\n * @since 2.0.0\r\n */\r\nexport async function retryWeixinConfig() {\r\n platformLogger.info('手动重试微信配置');\r\n weixinConfigManager.reset();\r\n autoConfigStarted = false;\r\n await ensureWeixinJSSDKLoaded({ force: true });\r\n return weixinConfigManager.waitForReady();\r\n}\r\n","/**\r\n * 插件管理器\r\n * 提供插件注册、安装、卸载等功能\r\n */\r\n\r\nimport { apiLogger } from './logger.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * 插件接口定义\r\n * @typedef {Object} Plugin\r\n * @property {string} name - 插件名称\r\n * @property {string} version - 插件版本\r\n * @property {Function} install - 安装函数 (qsh) => void\r\n * @property {Function} [uninstall] - 卸载函数 (qsh) => void (可选)\r\n * @property {string[]} [dependencies] - 依赖的其他插件 (可选)\r\n */\r\n\r\n/**\r\n * 插件管理器类(单例)\r\n */\r\nexport class PluginManager {\r\n constructor() {\r\n // 已注册的插件\r\n this.plugins = new Map();\r\n \r\n // 已安装的插件\r\n this.installed = new Set();\r\n \r\n // 插件安装顺序(用于卸载时反向执行)\r\n this.installOrder = [];\r\n \r\n apiLogger.debug('插件管理器已初始化');\r\n }\r\n\r\n /**\r\n * 注册插件\r\n * @param {Plugin} plugin - 插件对象\r\n * @returns {PluginManager} 返回自身以支持链式调用\r\n * @example\r\n * pluginManager.register(imagePlugin)\r\n */\r\n register(plugin) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 验证插件对象\r\n this.validatePlugin(plugin);\r\n \r\n const { name, version } = plugin;\r\n \r\n // 检查是否已注册\r\n if (this.plugins.has(name)) {\r\n const existing = this.plugins.get(name);\r\n apiLogger.warn(`插件 ${name} 已注册(版本 ${existing.version}),将被覆盖为版本 ${version}`);\r\n }\r\n \r\n // 注册插件\r\n this.plugins.set(name, plugin);\r\n apiLogger.info(`插件已注册: ${name}@${version}`);\r\n \r\n return this;\r\n }, { \r\n context: 'PluginManager.register',\r\n pluginName: plugin?.name \r\n });\r\n }\r\n\r\n /**\r\n * 验证插件对象\r\n * @param {Plugin} plugin - 插件对象\r\n * @throws {Error} 验证失败时抛出错误\r\n * @private\r\n */\r\n validatePlugin(plugin) {\r\n if (!plugin || typeof plugin !== 'object') {\r\n throw new Error('插件必须是一个对象');\r\n }\r\n \r\n if (!plugin.name || typeof plugin.name !== 'string') {\r\n throw new Error('插件必须有 name 属性(字符串)');\r\n }\r\n \r\n if (!plugin.version || typeof plugin.version !== 'string') {\r\n throw new Error(`插件 ${plugin.name} 必须有 version 属性(字符串)`);\r\n }\r\n \r\n if (!plugin.install || typeof plugin.install !== 'function') {\r\n throw new Error(`插件 ${plugin.name} 必须实现 install 方法`);\r\n }\r\n \r\n // 验证依赖项\r\n if (plugin.dependencies) {\r\n if (!Array.isArray(plugin.dependencies)) {\r\n throw new Error(`插件 ${plugin.name} 的 dependencies 必须是数组`);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 安装插件到 qsh 实例\r\n * @param {string} name - 插件名称\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.install('image', qsh)\r\n */\r\n async install(name, qshInstance) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 检查插件是否已注册\r\n if (!this.plugins.has(name)) {\r\n throw new Error(`插件 ${name} 未注册`);\r\n }\r\n \r\n // 检查是否已安装\r\n if (this.installed.has(name)) {\r\n apiLogger.debug(`插件 ${name} 已安装,跳过`);\r\n return;\r\n }\r\n \r\n const plugin = this.plugins.get(name);\r\n \r\n // 安装依赖项\r\n if (plugin.dependencies && plugin.dependencies.length > 0) {\r\n apiLogger.debug(`安装插件 ${name} 的依赖:`, plugin.dependencies);\r\n for (const depName of plugin.dependencies) {\r\n await this.install(depName, qshInstance);\r\n }\r\n }\r\n \r\n // 执行插件安装\r\n apiLogger.info(`开始安装插件: ${name}@${plugin.version}`);\r\n await plugin.install(qshInstance);\r\n \r\n // 标记为已安装\r\n this.installed.add(name);\r\n this.installOrder.push(name);\r\n \r\n apiLogger.info(`插件安装成功: ${name}@${plugin.version}`);\r\n \r\n }, { \r\n context: 'PluginManager.install',\r\n pluginName: name \r\n });\r\n }\r\n\r\n /**\r\n * 卸载插件\r\n * @param {string} name - 插件名称\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.uninstall('image', qsh)\r\n */\r\n async uninstall(name, qshInstance) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 检查是否已安装\r\n if (!this.installed.has(name)) {\r\n apiLogger.debug(`插件 ${name} 未安装,跳过卸载`);\r\n return;\r\n }\r\n \r\n const plugin = this.plugins.get(name);\r\n \r\n // 执行卸载(如果有)\r\n if (plugin.uninstall && typeof plugin.uninstall === 'function') {\r\n apiLogger.info(`开始卸载插件: ${name}`);\r\n await plugin.uninstall(qshInstance);\r\n }\r\n \r\n // 移除安装标记\r\n this.installed.delete(name);\r\n const orderIndex = this.installOrder.indexOf(name);\r\n if (orderIndex > -1) {\r\n this.installOrder.splice(orderIndex, 1);\r\n }\r\n \r\n apiLogger.info(`插件已卸载: ${name}`);\r\n \r\n }, { \r\n context: 'PluginManager.uninstall',\r\n pluginName: name \r\n });\r\n }\r\n\r\n /**\r\n * 卸载所有已安装的插件\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n */\r\n async uninstallAll(qshInstance) {\r\n // 按安装顺序的反向卸载\r\n const names = [...this.installOrder].reverse();\r\n for (const name of names) {\r\n await this.uninstall(name, qshInstance);\r\n }\r\n }\r\n\r\n /**\r\n * 批量注册插件\r\n * @param {Plugin[]} plugins - 插件数组\r\n * @returns {PluginManager} 返回自身以支持链式调用\r\n * @example\r\n * pluginManager.registerAll([imagePlugin, locationPlugin])\r\n */\r\n registerAll(plugins) {\r\n if (!Array.isArray(plugins)) {\r\n throw new Error('plugins 必须是数组');\r\n }\r\n \r\n plugins.forEach(plugin => this.register(plugin));\r\n return this;\r\n }\r\n\r\n /**\r\n * 批量安装插件\r\n * @param {string[]} names - 插件名称数组\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.installAll(['image', 'location'], qsh)\r\n */\r\n async installAll(names, qshInstance) {\r\n if (!Array.isArray(names)) {\r\n throw new Error('names 必须是数组');\r\n }\r\n \r\n for (const name of names) {\r\n await this.install(name, qshInstance);\r\n }\r\n }\r\n\r\n /**\r\n * 检查插件是否已注册\r\n * @param {string} name - 插件名称\r\n * @returns {boolean}\r\n */\r\n isRegistered(name) {\r\n return this.plugins.has(name);\r\n }\r\n\r\n /**\r\n * 检查插件是否已安装\r\n * @param {string} name - 插件名称\r\n * @returns {boolean}\r\n */\r\n isInstalled(name) {\r\n return this.installed.has(name);\r\n }\r\n\r\n /**\r\n * 获取插件信息\r\n * @param {string} name - 插件名称\r\n * @returns {Plugin|undefined}\r\n */\r\n getPlugin(name) {\r\n return this.plugins.get(name);\r\n }\r\n\r\n /**\r\n * 获取所有已注册的插件列表\r\n * @returns {Array<{name: string, version: string, installed: boolean}>}\r\n */\r\n getPluginList() {\r\n return Array.from(this.plugins.entries()).map(([name, plugin]) => ({\r\n name,\r\n version: plugin.version,\r\n installed: this.installed.has(name),\r\n dependencies: plugin.dependencies || []\r\n }));\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n registered: this.plugins.size,\r\n installed: this.installed.size,\r\n plugins: this.getPluginList()\r\n };\r\n }\r\n\r\n /**\r\n * 清空所有插件(仅用于测试)\r\n * @private\r\n */\r\n clear() {\r\n this.plugins.clear();\r\n this.installed.clear();\r\n this.installOrder = [];\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst pluginManager = new PluginManager();\r\n\r\nexport default pluginManager;\r\n\r\n","/**\r\n * 拦截器链\r\n * 提供请求和响应的拦截机制\r\n */\r\n\r\nimport { apiLogger } from './logger.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * 拦截器上下文\r\n * @typedef {Object} InterceptorContext\r\n * @property {string} apiName - API 名称\r\n * @property {Object} params - 参数对象\r\n * @property {Object} callbacks - 回调函数\r\n * @property {number} timestamp - 时间戳\r\n * @property {boolean} abort - 是否中止执行\r\n * @property {any} [metadata] - 元数据(可由拦截器添加)\r\n */\r\n\r\n/**\r\n * 拦截器函数\r\n * @callback InterceptorFunction\r\n * @param {InterceptorContext} context - 上下文对象\r\n * @returns {Promise<InterceptorContext|void>|InterceptorContext|void}\r\n */\r\n\r\n/**\r\n * 拦截器链类\r\n */\r\nexport class InterceptorChain {\r\n constructor() {\r\n // 请求拦截器列表\r\n this.requestInterceptors = [];\r\n \r\n // 响应拦截器列表\r\n this.responseInterceptors = [];\r\n \r\n apiLogger.debug('拦截器链已初始化');\r\n }\r\n\r\n /**\r\n * 注册请求拦截器\r\n * @param {InterceptorFunction} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @param {number} [options.priority=0] - 优先级(数字越大越先执行)\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * const unregister = chain.useRequest(async (ctx) => {\r\n * console.log('API 调用:', ctx.apiName)\r\n * return ctx\r\n * })\r\n */\r\n useRequest(interceptor, options = {}) {\r\n if (typeof interceptor !== 'function') {\r\n throw new Error('拦截器必须是函数');\r\n }\r\n \r\n const { priority = 0 } = options;\r\n \r\n // 添加到列表\r\n this.requestInterceptors.push({\r\n fn: interceptor,\r\n priority\r\n });\r\n \r\n // 按优先级排序(降序)\r\n this.requestInterceptors.sort((a, b) => b.priority - a.priority);\r\n \r\n apiLogger.debug('请求拦截器已注册', { priority });\r\n \r\n // 返回移除函数\r\n return () => {\r\n const index = this.requestInterceptors.findIndex(item => item.fn === interceptor);\r\n if (index > -1) {\r\n this.requestInterceptors.splice(index, 1);\r\n apiLogger.debug('请求拦截器已移除');\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 注册响应拦截器\r\n * @param {Function} interceptor - 拦截器函数 (result, context) => result\r\n * @param {Object} [options] - 选项\r\n * @param {number} [options.priority=0] - 优先级(数字越大越先执行)\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * const unregister = chain.useResponse(async (result, ctx) => {\r\n * console.log('API 完成:', ctx.apiName)\r\n * return result\r\n * })\r\n */\r\n useResponse(interceptor, options = {}) {\r\n if (typeof interceptor !== 'function') {\r\n throw new Error('拦截器必须是函数');\r\n }\r\n \r\n const { priority = 0 } = options;\r\n \r\n // 添加到列表\r\n this.responseInterceptors.push({\r\n fn: interceptor,\r\n priority\r\n });\r\n \r\n // 按优先级排序(降序)\r\n this.responseInterceptors.sort((a, b) => b.priority - a.priority);\r\n \r\n apiLogger.debug('响应拦截器已注册', { priority });\r\n \r\n // 返回移除函数\r\n return () => {\r\n const index = this.responseInterceptors.findIndex(item => item.fn === interceptor);\r\n if (index > -1) {\r\n this.responseInterceptors.splice(index, 1);\r\n apiLogger.debug('响应拦截器已移除');\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 执行请求拦截链\r\n * @param {InterceptorContext} context - 上下文\r\n * @returns {Promise<InterceptorContext>}\r\n * @private\r\n */\r\n async runRequest(context) {\r\n let ctx = { ...context };\r\n \r\n for (const { fn } of this.requestInterceptors) {\r\n if (ctx.abort) {\r\n apiLogger.debug('请求被中止', { apiName: ctx.apiName });\r\n break;\r\n }\r\n \r\n try {\r\n const result = await fn(ctx);\r\n // 拦截器可以返回新的 context 或不返回(使用原 context)\r\n if (result) {\r\n ctx = result;\r\n }\r\n } catch (error) {\r\n apiLogger.error('请求拦截器执行失败', error);\r\n // 标记中止\r\n ctx.abort = true;\r\n ctx.error = error;\r\n break;\r\n }\r\n }\r\n \r\n return ctx;\r\n }\r\n\r\n /**\r\n * 执行响应拦截链\r\n * @param {any} result - 响应结果\r\n * @param {InterceptorContext} context - 上下文\r\n * @returns {Promise<any>}\r\n * @private\r\n */\r\n async runResponse(result, context) {\r\n let res = result;\r\n \r\n for (const { fn } of this.responseInterceptors) {\r\n try {\r\n const newResult = await fn(res, context);\r\n // 拦截器可以返回新的 result 或不返回(使用原 result)\r\n if (newResult !== undefined) {\r\n res = newResult;\r\n }\r\n } catch (error) {\r\n apiLogger.error('响应拦截器执行失败', error);\r\n // 响应拦截器失败不中断流程,只记录日志\r\n }\r\n }\r\n \r\n return res;\r\n }\r\n\r\n /**\r\n * 清空所有拦截器\r\n */\r\n clear() {\r\n this.requestInterceptors = [];\r\n this.responseInterceptors = [];\r\n apiLogger.debug('所有拦截器已清空');\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n requestInterceptors: this.requestInterceptors.length,\r\n responseInterceptors: this.responseInterceptors.length\r\n };\r\n }\r\n}\r\n\r\n// 创建全局拦截器链实例\r\nconst interceptorChain = new InterceptorChain();\r\n\r\nexport default interceptorChain;\r\n\r\n// ========== 内置拦截器 ==========\r\n\r\n/**\r\n * 日志拦截器\r\n * 记录 API 调用的开始和结束\r\n */\r\nexport const loggingInterceptor = {\r\n /**\r\n * 请求日志\r\n */\r\n request: (ctx) => {\r\n ctx.startTime = Date.now();\r\n apiLogger.debug(`[API 调用] ${ctx.apiName}`, {\r\n params: ctx.params\r\n });\r\n return ctx;\r\n },\r\n \r\n /**\r\n * 响应日志\r\n */\r\n response: (result, ctx) => {\r\n const duration = Date.now() - ctx.startTime;\r\n apiLogger.debug(`[API 完成] ${ctx.apiName}`, {\r\n duration: `${duration}ms`,\r\n success: result?.success\r\n });\r\n return result;\r\n }\r\n};\r\n\r\n/**\r\n * 性能监控拦截器\r\n * 收集 API 调用性能数据\r\n */\r\nexport const performanceInterceptor = {\r\n // 性能数据存储\r\n metrics: new Map(),\r\n \r\n /**\r\n * 记录开始时间\r\n */\r\n request: (ctx) => {\r\n ctx.perfStartTime = performance.now();\r\n return ctx;\r\n },\r\n \r\n /**\r\n * 记录性能数据\r\n */\r\n response: (result, ctx) => {\r\n const duration = performance.now() - ctx.perfStartTime;\r\n \r\n // 更新统计信息\r\n if (!performanceInterceptor.metrics.has(ctx.apiName)) {\r\n performanceInterceptor.metrics.set(ctx.apiName, {\r\n count: 0,\r\n totalTime: 0,\r\n minTime: Infinity,\r\n maxTime: 0,\r\n avgTime: 0\r\n });\r\n }\r\n \r\n const metrics = performanceInterceptor.metrics.get(ctx.apiName);\r\n metrics.count++;\r\n metrics.totalTime += duration;\r\n metrics.minTime = Math.min(metrics.minTime, duration);\r\n metrics.maxTime = Math.max(metrics.maxTime, duration);\r\n metrics.avgTime = metrics.totalTime / metrics.count;\r\n \r\n return result;\r\n },\r\n \r\n /**\r\n * 获取性能报告\r\n */\r\n getReport: () => {\r\n const report = {};\r\n performanceInterceptor.metrics.forEach((value, key) => {\r\n report[key] = { ...value };\r\n });\r\n return report;\r\n },\r\n \r\n /**\r\n * 清空性能数据\r\n */\r\n clearMetrics: () => {\r\n performanceInterceptor.metrics.clear();\r\n }\r\n};\r\n\r\n/**\r\n * 重试拦截器\r\n * 失败时自动重试\r\n * @param {Object} options - 选项\r\n * @param {number} [options.maxRetries=3] - 最大重试次数\r\n * @param {number} [options.retryDelay=1000] - 重试延迟(毫秒)\r\n * @param {Function} [options.shouldRetry] - 判断是否应该重试的函数\r\n */\r\nexport function createRetryInterceptor(options = {}) {\r\n const {\r\n maxRetries = 3,\r\n retryDelay = 1000,\r\n shouldRetry = (result) => !result.success\r\n } = options;\r\n \r\n return {\r\n response: async (result, ctx) => {\r\n // 初始化重试次数\r\n if (!ctx.retryCount) {\r\n ctx.retryCount = 0;\r\n }\r\n \r\n // 检查是否需要重试\r\n if (shouldRetry(result) && ctx.retryCount < maxRetries) {\r\n ctx.retryCount++;\r\n \r\n apiLogger.warn(`API 调用失败,第 ${ctx.retryCount} 次重试: ${ctx.apiName}`);\r\n \r\n // 延迟后重新调用(需要在 WebViewBridge 中支持)\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n \r\n // 标记需要重试\r\n result.shouldRetry = true;\r\n result.retryContext = ctx;\r\n }\r\n \r\n return result;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * 参数验证拦截器\r\n * @param {Object} rules - 验证规则 { apiName: validatorFn }\r\n */\r\nexport function createValidationInterceptor(rules = {}) {\r\n return {\r\n request: (ctx) => {\r\n const validator = rules[ctx.apiName];\r\n \r\n if (validator && typeof validator === 'function') {\r\n const error = validator(ctx.params);\r\n if (error) {\r\n apiLogger.error(`参数验证失败: ${ctx.apiName}`, error);\r\n ctx.abort = true;\r\n ctx.validationError = error;\r\n }\r\n }\r\n \r\n return ctx;\r\n }\r\n };\r\n}\r\n\r\n","/**\r\n * 状态仓库\r\n * 提供分层的状态管理和订阅机制\r\n */\r\n\r\nimport { stateLogger } from './logger.js';\r\nimport { environment } from './environment.js';\r\n\r\n/**\r\n * 状态仓库类(单例)\r\n */\r\nexport class StateStore {\r\n constructor() {\r\n // 初始状态\r\n this.state = {\r\n // SDK 状态\r\n sdk: {\r\n status: 'uninitialized', // 'uninitialized' | 'initializing' | 'ready' | 'error'\r\n version: '2.0.5',\r\n error: null\r\n },\r\n \r\n // 平台信息\r\n platform: {\r\n type: environment.type,\r\n isWeixinMiniProgram: environment.isWeixinMiniProgram,\r\n isAppPlus: environment.isAppPlus,\r\n isNvue: environment.isNvue,\r\n isUvue: environment.isUvue,\r\n features: {} // 平台支持的特性\r\n },\r\n \r\n // 微信配置状态\r\n weixin: {\r\n configStatus: 'pending', // 'pending' | 'configuring' | 'configured' | 'failed'\r\n jsApiList: [],\r\n configError: null\r\n },\r\n \r\n // 网络状态\r\n network: {\r\n online: typeof navigator !== 'undefined' ? navigator.onLine : true,\r\n type: 'unknown' // 'wifi' | '4g' | '3g' | '2g' | 'unknown'\r\n },\r\n \r\n // 权限状态\r\n permissions: {\r\n camera: 'prompt', // 'granted' | 'denied' | 'prompt'\r\n location: 'prompt',\r\n album: 'prompt'\r\n },\r\n \r\n // API 调用状态\r\n api: {\r\n // 格式: { apiName: { loading: boolean, lastCall: timestamp, lastResult: any } }\r\n }\r\n };\r\n \r\n // 订阅者映射 { path: Set<listener> }\r\n this.listeners = new Map();\r\n \r\n // 通配符订阅者\r\n this.wildcardListeners = new Set();\r\n \r\n // 初始化网络状态监听\r\n this.initNetworkListener();\r\n \r\n stateLogger.debug('状态仓库已初始化');\r\n }\r\n\r\n /**\r\n * 获取状态值\r\n * @param {string} path - 状态路径(用 . 分隔)\r\n * @returns {any} 状态值\r\n * @example\r\n * store.get('sdk.status') // 'ready'\r\n * store.get('platform') // { type: 'weixin', ... }\r\n */\r\n get(path) {\r\n const keys = path.split('.');\r\n return keys.reduce((obj, key) => {\r\n return obj !== undefined && obj !== null ? obj[key] : undefined;\r\n }, this.state);\r\n }\r\n\r\n /**\r\n * 设置状态值\r\n * @param {string} path - 状态路径\r\n * @param {any} value - 新值\r\n * @example\r\n * store.set('sdk.status', 'ready')\r\n * store.set('network.online', false)\r\n */\r\n set(path, value) {\r\n const keys = path.split('.');\r\n const lastKey = keys.pop();\r\n \r\n // 获取目标对象\r\n const target = keys.reduce((obj, key) => {\r\n if (!obj[key] || typeof obj[key] !== 'object') {\r\n obj[key] = {};\r\n }\r\n return obj[key];\r\n }, this.state);\r\n \r\n // 检查值是否变化\r\n const oldValue = target[lastKey];\r\n if (oldValue === value) {\r\n return; // 值未变化,不触发更新\r\n }\r\n \r\n // 设置新值\r\n target[lastKey] = value;\r\n \r\n stateLogger.debug(`状态已更新: ${path}`, { oldValue, newValue: value });\r\n \r\n // 通知订阅者\r\n this.notify(path, value, oldValue);\r\n }\r\n\r\n /**\r\n * 批量更新状态\r\n * @param {Object} updates - 更新对象 { path: value }\r\n * @example\r\n * store.batchUpdate({\r\n * 'sdk.status': 'ready',\r\n * 'network.online': true\r\n * })\r\n */\r\n batchUpdate(updates) {\r\n Object.entries(updates).forEach(([path, value]) => {\r\n this.set(path, value);\r\n });\r\n }\r\n\r\n /**\r\n * 订阅状态变化\r\n * @param {string} path - 状态路径(支持通配符 * )\r\n * @param {Function} listener - 监听函数 (newValue, oldValue, path) => void\r\n * @returns {Function} 取消订阅的函数\r\n * @example\r\n * const unsubscribe = store.subscribe('network.online', (online) => {\r\n * console.log('网络状态:', online)\r\n * })\r\n * // 取消订阅\r\n * unsubscribe()\r\n */\r\n subscribe(path, listener) {\r\n if (typeof listener !== 'function') {\r\n throw new Error('listener 必须是函数');\r\n }\r\n \r\n // 通配符订阅\r\n if (path === '*') {\r\n this.wildcardListeners.add(listener);\r\n stateLogger.debug('添加通配符订阅者');\r\n \r\n return () => {\r\n this.wildcardListeners.delete(listener);\r\n stateLogger.debug('移除通配符订阅者');\r\n };\r\n }\r\n \r\n // 普通订阅\r\n if (!this.listeners.has(path)) {\r\n this.listeners.set(path, new Set());\r\n }\r\n \r\n this.listeners.get(path).add(listener);\r\n stateLogger.debug(`添加订阅者: ${path}`);\r\n \r\n // 返回取消订阅函数\r\n return () => {\r\n const listeners = this.listeners.get(path);\r\n if (listeners) {\r\n listeners.delete(listener);\r\n if (listeners.size === 0) {\r\n this.listeners.delete(path);\r\n }\r\n stateLogger.debug(`移除订阅者: ${path}`);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 订阅一次(只触发一次后自动取消)\r\n * @param {string} path - 状态路径\r\n * @param {Function} listener - 监听函数\r\n * @returns {Function} 取消订阅的函数\r\n */\r\n subscribeOnce(path, listener) {\r\n const unsubscribe = this.subscribe(path, (newValue, oldValue, p) => {\r\n listener(newValue, oldValue, p);\r\n unsubscribe();\r\n });\r\n return unsubscribe;\r\n }\r\n\r\n /**\r\n * 通知订阅者\r\n * @param {string} path - 状态路径\r\n * @param {any} newValue - 新值\r\n * @param {any} oldValue - 旧值\r\n * @private\r\n */\r\n notify(path, newValue, oldValue) {\r\n // 通知精确路径的订阅者\r\n const listeners = this.listeners.get(path);\r\n if (listeners) {\r\n listeners.forEach(listener => {\r\n try {\r\n listener(newValue, oldValue, path);\r\n } catch (error) {\r\n stateLogger.error('订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n \r\n // 通知父路径的订阅者(例如 'sdk.status' 变化通知 'sdk' 的订阅者)\r\n const keys = path.split('.');\r\n for (let i = 1; i < keys.length; i++) {\r\n const parentPath = keys.slice(0, i).join('.');\r\n const parentListeners = this.listeners.get(parentPath);\r\n if (parentListeners) {\r\n const parentValue = this.get(parentPath);\r\n parentListeners.forEach(listener => {\r\n try {\r\n listener(parentValue, undefined, parentPath);\r\n } catch (error) {\r\n stateLogger.error('父路径订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n }\r\n \r\n // 通知通配符订阅者\r\n this.wildcardListeners.forEach(listener => {\r\n try {\r\n listener(newValue, oldValue, path);\r\n } catch (error) {\r\n stateLogger.error('通配符订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 初始化网络状态监听\r\n * @private\r\n */\r\n initNetworkListener() {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n // 监听在线/离线事件\r\n window.addEventListener('online', () => {\r\n this.set('network.online', true);\r\n });\r\n \r\n window.addEventListener('offline', () => {\r\n this.set('network.online', false);\r\n });\r\n \r\n // 监听网络类型变化(如果支持)\r\n if (navigator.connection) {\r\n const connection = navigator.connection;\r\n \r\n const updateConnectionType = () => {\r\n this.set('network.type', connection.effectiveType || 'unknown');\r\n };\r\n \r\n connection.addEventListener('change', updateConnectionType);\r\n updateConnectionType();\r\n }\r\n }\r\n\r\n /**\r\n * 记录 API 调用开始\r\n * @param {string} apiName - API 名称\r\n */\r\n setApiLoading(apiName, loading = true) {\r\n const apiPath = `api.${apiName}`;\r\n const apiState = this.get(apiPath) || {};\r\n \r\n this.set(apiPath, {\r\n ...apiState,\r\n loading,\r\n lastCall: loading ? Date.now() : apiState.lastCall\r\n });\r\n }\r\n\r\n /**\r\n * 记录 API 调用结果\r\n * @param {string} apiName - API 名称\r\n * @param {any} result - 结果\r\n */\r\n setApiResult(apiName, result) {\r\n const apiPath = `api.${apiName}`;\r\n const apiState = this.get(apiPath) || {};\r\n \r\n this.set(apiPath, {\r\n ...apiState,\r\n loading: false,\r\n lastResult: result,\r\n lastCallEnd: Date.now()\r\n });\r\n }\r\n\r\n /**\r\n * 获取完整状态快照\r\n * @returns {Object} 状态快照\r\n */\r\n getSnapshot() {\r\n return JSON.parse(JSON.stringify(this.state));\r\n }\r\n\r\n /**\r\n * 重置状态(用于测试)\r\n * @private\r\n */\r\n reset() {\r\n // 保留一些基础信息\r\n const { platform } = this.state;\r\n \r\n this.state = {\r\n sdk: {\r\n status: 'uninitialized',\r\n version: '2.0.5',\r\n error: null\r\n },\r\n platform,\r\n weixin: {\r\n configStatus: 'pending',\r\n jsApiList: [],\r\n configError: null\r\n },\r\n network: {\r\n online: typeof navigator !== 'undefined' ? navigator.onLine : true,\r\n type: 'unknown'\r\n },\r\n permissions: {\r\n camera: 'prompt',\r\n location: 'prompt',\r\n album: 'prompt'\r\n },\r\n api: {}\r\n };\r\n \r\n stateLogger.debug('状态已重置');\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n listeners: this.listeners.size,\r\n wildcardListeners: this.wildcardListeners.size,\r\n apiStates: Object.keys(this.state.api).length\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst stateStore = new StateStore();\r\n\r\nexport default stateStore;\r\n\r\n","/**\r\n * 统一错误码定义\r\n * 格式:E_[模块]_[序号]\r\n */\r\n\r\n// ==================== 错误码定义 ====================\r\n\r\n/**\r\n * 错误码枚举\r\n */\r\nexport const ErrorCodes = {\r\n // SDK 核心错误 (E_SDK_xxx)\r\n SDK_NOT_READY: 'E_SDK_001',\r\n SDK_INIT_FAILED: 'E_SDK_002',\r\n SDK_CONFIG_FAILED: 'E_SDK_003',\r\n PLATFORM_NOT_SUPPORTED: 'E_SDK_004',\r\n \r\n // 网络错误 (E_NET_xxx)\r\n NETWORK_ERROR: 'E_NET_001',\r\n NETWORK_TIMEOUT: 'E_NET_002',\r\n NETWORK_OFFLINE: 'E_NET_003',\r\n \r\n // 图片错误 (E_IMG_xxx)\r\n IMAGE_CANCELLED: 'E_IMG_001', // 用户取消\r\n IMAGE_NO_PERMISSION: 'E_IMG_002', // 无权限\r\n IMAGE_SIZE_EXCEED: 'E_IMG_003', // 图片过大\r\n IMAGE_COUNT_EXCEED: 'E_IMG_004', // 数量超限\r\n IMAGE_FORMAT_ERROR: 'E_IMG_005', // 格式错误\r\n IMAGE_CONFIG_NOT_READY: 'E_IMG_006', // 配置未完成\r\n \r\n // 定位错误 (E_LOC_xxx)\r\n LOCATION_CANCELLED: 'E_LOC_001',\r\n LOCATION_NO_PERMISSION: 'E_LOC_002',\r\n LOCATION_UNAVAILABLE: 'E_LOC_003',\r\n LOCATION_TIMEOUT: 'E_LOC_004',\r\n \r\n // 扫码错误 (E_SCAN_xxx)\r\n SCAN_CANCELLED: 'E_SCAN_001', // 用户取消\r\n SCAN_NO_PERMISSION: 'E_SCAN_002', // 无相机权限\r\n SCAN_INVALID_CODE: 'E_SCAN_003', // 无效的码\r\n SCAN_CONFIG_NOT_READY: 'E_SCAN_004', // 配置未完成\r\n \r\n // 权限错误 (E_PERM_xxx)\r\n PERMISSION_DENIED: 'E_PERM_001',\r\n PERMISSION_CAMERA: 'E_PERM_002',\r\n PERMISSION_LOCATION: 'E_PERM_003',\r\n PERMISSION_ALBUM: 'E_PERM_004',\r\n PERMISSION_MICROPHONE: 'E_PERM_005',\r\n \r\n // 参数错误 (E_PARAM_xxx)\r\n PARAM_INVALID: 'E_PARAM_001',\r\n PARAM_MISSING: 'E_PARAM_002',\r\n PARAM_TYPE_ERROR: 'E_PARAM_003',\r\n \r\n // 超时错误 (E_TIMEOUT_xxx)\r\n API_TIMEOUT: 'E_TIMEOUT_001',\r\n \r\n // 通用错误\r\n UNKNOWN_ERROR: 'E_UNKNOWN_999'\r\n};\r\n\r\n/**\r\n * 错误消息映射\r\n */\r\nexport const ErrorMessages = {\r\n // SDK 核心\r\n [ErrorCodes.SDK_NOT_READY]: 'SDK 未就绪',\r\n [ErrorCodes.SDK_INIT_FAILED]: 'SDK 初始化失败',\r\n [ErrorCodes.SDK_CONFIG_FAILED]: 'SDK 配置失败',\r\n [ErrorCodes.PLATFORM_NOT_SUPPORTED]: '当前平台不支持此功能',\r\n \r\n // 网络\r\n [ErrorCodes.NETWORK_ERROR]: '网络错误',\r\n [ErrorCodes.NETWORK_TIMEOUT]: '网络超时',\r\n [ErrorCodes.NETWORK_OFFLINE]: '网络已断开',\r\n \r\n // 图片\r\n [ErrorCodes.IMAGE_CANCELLED]: '用户取消选择图片',\r\n [ErrorCodes.IMAGE_NO_PERMISSION]: '无相机/相册权限',\r\n [ErrorCodes.IMAGE_SIZE_EXCEED]: '图片大小超出限制',\r\n [ErrorCodes.IMAGE_COUNT_EXCEED]: '图片数量超出限制',\r\n [ErrorCodes.IMAGE_FORMAT_ERROR]: '图片格式不支持',\r\n [ErrorCodes.IMAGE_CONFIG_NOT_READY]: '微信配置未完成',\r\n \r\n // 定位\r\n [ErrorCodes.LOCATION_CANCELLED]: '用户取消定位',\r\n [ErrorCodes.LOCATION_NO_PERMISSION]: '无定位权限',\r\n [ErrorCodes.LOCATION_UNAVAILABLE]: '定位服务不可用',\r\n [ErrorCodes.LOCATION_TIMEOUT]: '定位超时',\r\n \r\n // 扫码\r\n [ErrorCodes.SCAN_CANCELLED]: '用户取消扫码',\r\n [ErrorCodes.SCAN_NO_PERMISSION]: '无相机权限',\r\n [ErrorCodes.SCAN_INVALID_CODE]: '无效的二维码/条形码',\r\n [ErrorCodes.SCAN_CONFIG_NOT_READY]: '微信配置未完成',\r\n \r\n // 权限\r\n [ErrorCodes.PERMISSION_DENIED]: '权限被拒绝',\r\n [ErrorCodes.PERMISSION_CAMERA]: '无相机权限',\r\n [ErrorCodes.PERMISSION_LOCATION]: '无定位权限',\r\n [ErrorCodes.PERMISSION_ALBUM]: '无相册权限',\r\n [ErrorCodes.PERMISSION_MICROPHONE]: '无麦克风权限',\r\n \r\n // 参数\r\n [ErrorCodes.PARAM_INVALID]: '参数无效',\r\n [ErrorCodes.PARAM_MISSING]: '缺少必需参数',\r\n [ErrorCodes.PARAM_TYPE_ERROR]: '参数类型错误',\r\n \r\n // 超时\r\n [ErrorCodes.API_TIMEOUT]: 'API 调用超时',\r\n \r\n // 通用\r\n [ErrorCodes.UNKNOWN_ERROR]: '未知错误'\r\n};\r\n\r\n/**\r\n * 错误分类\r\n */\r\nexport const ErrorCategory = {\r\n USER_CANCEL: 'user_cancel', // 用户主动取消\r\n PERMISSION: 'permission', // 权限问题\r\n NETWORK: 'network', // 网络问题\r\n PARAM: 'param', // 参数问题\r\n SYSTEM: 'system', // 系统问题\r\n CONFIG: 'config', // 配置问题\r\n UNKNOWN: 'unknown' // 未知问题\r\n};\r\n\r\n// ==================== 错误映射规则 ====================\r\n\r\n/**\r\n * 旧版错误码映射(image.js 中使用的格式)\r\n * 格式:CATEGORY/ERROR_NAME → E_XXX_NNN\r\n */\r\nexport const LegacyErrorMapping = {\r\n // 图片相关\r\n 'IMAGE/USER_CANCEL': ErrorCodes.IMAGE_CANCELLED,\r\n 'IMAGE/PERMISSION_DENIED': ErrorCodes.IMAGE_NO_PERMISSION,\r\n \r\n // 通用错误\r\n 'COMMON/UNKNOWN': ErrorCodes.UNKNOWN_ERROR,\r\n 'COMMON/CONFIG_NOT_READY': ErrorCodes.IMAGE_CONFIG_NOT_READY,\r\n 'COMMON/PLATFORM_NOT_SUPPORTED': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n};\r\n\r\n/**\r\n * 平台原始错误映射(原始 errMsg → 统一错误码)\r\n */\r\nexport const PlatformErrorMapping = {\r\n // 微信平台错误模式\r\n weixin: {\r\n patterns: [\r\n { pattern: /cancel/i, code: ErrorCodes.IMAGE_CANCELLED },\r\n { pattern: /permission|auth\\s*deny/i, code: ErrorCodes.IMAGE_NO_PERMISSION },\r\n { pattern: /config/i, code: ErrorCodes.IMAGE_CONFIG_NOT_READY },\r\n { pattern: /timeout/i, code: ErrorCodes.API_TIMEOUT },\r\n { pattern: /network/i, code: ErrorCodes.NETWORK_ERROR }\r\n ],\r\n default: ErrorCodes.UNKNOWN_ERROR\r\n },\r\n \r\n // UniApp 平台错误模式\r\n uniapp: {\r\n patterns: [\r\n { pattern: /cancel/i, code: ErrorCodes.IMAGE_CANCELLED },\r\n { pattern: /permission|denied/i, code: ErrorCodes.IMAGE_NO_PERMISSION },\r\n { pattern: /timeout/i, code: ErrorCodes.API_TIMEOUT },\r\n { pattern: /network/i, code: ErrorCodes.NETWORK_ERROR },\r\n { pattern: /not_in_container/i, code: ErrorCodes.PLATFORM_NOT_SUPPORTED }\r\n ],\r\n default: ErrorCodes.UNKNOWN_ERROR\r\n }\r\n};\r\n\r\n/**\r\n * API 特定的错误映射\r\n */\r\nexport const ApiErrorMapping = {\r\n chooseImage: {\r\n 'fail cancel': ErrorCodes.IMAGE_CANCELLED,\r\n 'fail auth deny': ErrorCodes.IMAGE_NO_PERMISSION,\r\n 'fail No Permission': ErrorCodes.IMAGE_NO_PERMISSION,\r\n 'NOT_IN_CONTAINER': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n },\r\n scanCode: {\r\n 'fail cancel': ErrorCodes.SCAN_CANCELLED,\r\n 'fail auth deny': ErrorCodes.SCAN_NO_PERMISSION,\r\n 'fail No Permission': ErrorCodes.SCAN_NO_PERMISSION,\r\n 'NOT_IN_CONTAINER': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n }\r\n};\r\n\r\n// ==================== 辅助函数 ====================\r\n\r\n/**\r\n * 根据错误码获取错误分类\r\n * @param {string} code - 错误码\r\n * @returns {string} 错误分类\r\n */\r\nexport function getErrorCategory(code) {\r\n if (!code) return ErrorCategory.UNKNOWN;\r\n \r\n // 用户取消类\r\n if (code.includes('CANCEL')) {\r\n return ErrorCategory.USER_CANCEL;\r\n }\r\n \r\n // 权限类\r\n if (code.includes('PERM') || code.includes('PERMISSION')) {\r\n return ErrorCategory.PERMISSION;\r\n }\r\n \r\n // 网络类\r\n if (code.includes('NET') || code.includes('NETWORK')) {\r\n return ErrorCategory.NETWORK;\r\n }\r\n \r\n // 参数类\r\n if (code.includes('PARAM')) {\r\n return ErrorCategory.PARAM;\r\n }\r\n \r\n // 配置类\r\n if (code.includes('CONFIG')) {\r\n return ErrorCategory.CONFIG;\r\n }\r\n \r\n // 系统类\r\n if (code.includes('SDK') || code.includes('PLATFORM')) {\r\n return ErrorCategory.SYSTEM;\r\n }\r\n \r\n return ErrorCategory.UNKNOWN;\r\n}\r\n\r\n/**\r\n * 检测错误是否可重试\r\n * @param {string} code - 错误码\r\n * @returns {boolean}\r\n */\r\nexport function isRetriableError(code) {\r\n // 网络错误、超时错误通常可重试\r\n return code.includes('NET_') || \r\n code.includes('TIMEOUT') ||\r\n code === ErrorCodes.NETWORK_ERROR ||\r\n code === ErrorCodes.NETWORK_TIMEOUT ||\r\n code === ErrorCodes.API_TIMEOUT;\r\n}\r\n\r\n/**\r\n * 检测是否为用户主动操作(不需要提示)\r\n * @param {string} code - 错误码\r\n * @returns {boolean}\r\n */\r\nexport function isUserAction(code) {\r\n return code.includes('CANCEL') ||\r\n getErrorCategory(code) === ErrorCategory.USER_CANCEL;\r\n}\r\n\r\n/**\r\n * 获取错误码的友好描述\r\n * @param {string} code - 错误码\r\n * @returns {string}\r\n */\r\nexport function getErrorMessage(code) {\r\n return ErrorMessages[code] || ErrorMessages[ErrorCodes.UNKNOWN_ERROR];\r\n}\r\n\r\n","/**\r\n * 错误标准化模块\r\n * 将各种格式的错误转换为统一的标准错误格式\r\n */\r\n\r\nimport { \r\n ErrorCodes, \r\n ErrorMessages, \r\n ErrorCategory,\r\n LegacyErrorMapping,\r\n PlatformErrorMapping,\r\n ApiErrorMapping,\r\n getErrorCategory,\r\n isRetriableError,\r\n isUserAction,\r\n getErrorMessage\r\n} from './error-codes.js';\r\nimport { environment } from './environment.js';\r\nimport { apiLogger } from './logger.js';\r\n\r\n/**\r\n * 标准化错误类\r\n */\r\nexport class StandardError extends Error {\r\n /**\r\n * 构造函数\r\n * @param {string} code - 错误码\r\n * @param {string} message - 错误消息\r\n * @param {Object} options - 选项\r\n */\r\n constructor(code, message, options = {}) {\r\n super(message);\r\n \r\n this.name = 'StandardError';\r\n this.code = code;\r\n this.message = message || getErrorMessage(code);\r\n this.platform = options.platform || environment.type;\r\n this.apiName = options.apiName;\r\n this.category = options.category || getErrorCategory(code);\r\n this.retriable = options.retriable !== undefined ? options.retriable : isRetriableError(code);\r\n this.originalError = options.originalError;\r\n this.details = options.details || {};\r\n this.timestamp = Date.now();\r\n }\r\n\r\n /**\r\n * 是否可重试\r\n * @returns {boolean}\r\n */\r\n isRetriable() {\r\n return this.retriable;\r\n }\r\n\r\n /**\r\n * 是否用户主动操作(不需要提示)\r\n * @returns {boolean}\r\n */\r\n isUserAction() {\r\n return isUserAction(this.code);\r\n }\r\n\r\n /**\r\n * 转为普通对象\r\n * @returns {Object}\r\n */\r\n toJSON() {\r\n return {\r\n code: this.code,\r\n message: this.message,\r\n platform: this.platform,\r\n apiName: this.apiName,\r\n category: this.category,\r\n retriable: this.retriable,\r\n timestamp: this.timestamp,\r\n details: this.details,\r\n // 调试模式下包含原始错误\r\n ...(process.env.NODE_ENV !== 'production' && this.originalError ? {\r\n originalError: this.originalError\r\n } : {})\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * 标准化错误(核心函数)\r\n * @param {any} error - 原始错误对象\r\n * @param {Object} context - 上下文信息\r\n * @returns {StandardError}\r\n */\r\nexport function normalizeError(error, context = {}) {\r\n // 已经是标准化错误,直接返回\r\n if (error instanceof StandardError) {\r\n return error;\r\n }\r\n\r\n const { apiName, platform = environment.type } = context;\r\n\r\n // 1. 处理 image.js 旧版错误格式(兼容现有代码)\r\n if (error && typeof error.code === 'string' && error.code.includes('/')) {\r\n return normalizeLegacyError(error, { apiName, platform });\r\n }\r\n\r\n // 2. 处理平台原始错误(errMsg 字符串)\r\n if (error && (error.errMsg || error.message)) {\r\n return normalizePlatformError(error, { apiName, platform });\r\n }\r\n\r\n // 3. 处理字符串错误\r\n if (typeof error === 'string') {\r\n return new StandardError(\r\n ErrorCodes.UNKNOWN_ERROR,\r\n error,\r\n { apiName, platform, originalError: error }\r\n );\r\n }\r\n\r\n // 4. 未知错误\r\n return new StandardError(\r\n ErrorCodes.UNKNOWN_ERROR,\r\n '未知错误',\r\n { \r\n apiName, \r\n platform, \r\n originalError: error,\r\n details: { errorType: typeof error }\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 标准化旧版错误格式(image.js 使用的 CATEGORY/ERROR_NAME 格式)\r\n * @param {Object} error - 旧版错误对象\r\n * @param {Object} context - 上下文\r\n * @returns {StandardError}\r\n * @private\r\n */\r\nfunction normalizeLegacyError(error, context) {\r\n const { apiName, platform } = context;\r\n const legacyCode = error.code;\r\n \r\n // 查找映射的新错误码\r\n const newCode = LegacyErrorMapping[legacyCode] || ErrorCodes.UNKNOWN_ERROR;\r\n \r\n apiLogger.debug('转换旧版错误码', { \r\n legacy: legacyCode, \r\n new: newCode \r\n });\r\n\r\n return new StandardError(\r\n newCode,\r\n error.message || getErrorMessage(newCode),\r\n {\r\n apiName,\r\n platform: error.platform || platform,\r\n originalError: error,\r\n details: {\r\n legacyCode,\r\n legacyVersion: error.version,\r\n ...error.details\r\n }\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 标准化平台原始错误(微信/UniApp 的 errMsg)\r\n * @param {Object} error - 平台错误对象\r\n * @param {Object} context - 上下文\r\n * @returns {StandardError}\r\n * @private\r\n */\r\nfunction normalizePlatformError(error, context) {\r\n const { apiName, platform } = context;\r\n const errMsg = (error.errMsg || error.message || '').toLowerCase();\r\n \r\n // 1. 尝试 API 特定映射\r\n if (apiName && ApiErrorMapping[apiName]) {\r\n const apiMapping = ApiErrorMapping[apiName];\r\n for (const [pattern, code] of Object.entries(apiMapping)) {\r\n if (errMsg.includes(pattern.toLowerCase())) {\r\n return new StandardError(code, getErrorMessage(code), {\r\n apiName,\r\n platform,\r\n originalError: error\r\n });\r\n }\r\n }\r\n }\r\n\r\n // 2. 尝试平台通用模式匹配\r\n const platformMapping = PlatformErrorMapping[platform] || PlatformErrorMapping.uniapp;\r\n for (const { pattern, code } of platformMapping.patterns) {\r\n if (pattern.test(errMsg)) {\r\n return new StandardError(code, getErrorMessage(code), {\r\n apiName,\r\n platform,\r\n originalError: error\r\n });\r\n }\r\n }\r\n\r\n // 3. 使用默认错误码\r\n const defaultCode = platformMapping.default || ErrorCodes.UNKNOWN_ERROR;\r\n return new StandardError(\r\n defaultCode,\r\n error.errMsg || error.message || getErrorMessage(defaultCode),\r\n {\r\n apiName,\r\n platform,\r\n originalError: error\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 错误标准化拦截器(用于拦截器链)\r\n */\r\nexport const errorNormalizerInterceptor = {\r\n /**\r\n * 响应拦截器\r\n * @param {Object} result - API 响应结果\r\n * @param {Object} ctx - 拦截器上下文\r\n * @returns {Object} 处理后的结果\r\n */\r\n response: (result, ctx) => {\r\n // 只处理失败的响应\r\n if (!result.success && result.error) {\r\n const standardError = normalizeError(result.error, {\r\n apiName: ctx.apiName,\r\n platform: environment.type\r\n });\r\n\r\n // 替换为标准化错误对象\r\n result.error = standardError.toJSON();\r\n\r\n // 添加便捷字段\r\n result.errorCode = standardError.code;\r\n result.errorCategory = standardError.category;\r\n result.retriable = standardError.isRetriable();\r\n\r\n apiLogger.debug('错误已标准化', {\r\n api: ctx.apiName,\r\n code: standardError.code,\r\n category: standardError.category\r\n });\r\n }\r\n\r\n return result;\r\n }\r\n};\r\n\r\n/**\r\n * 创建标准错误(便捷函数)\r\n * @param {string} code - 错误码\r\n * @param {Object} options - 选项\r\n * @returns {StandardError}\r\n */\r\nexport function createError(code, options = {}) {\r\n return new StandardError(code, getErrorMessage(code), options);\r\n}\r\n\r\n/**\r\n * 判断是否为标准错误\r\n * @param {any} error - 错误对象\r\n * @returns {boolean}\r\n */\r\nexport function isStandardError(error) {\r\n return error instanceof StandardError;\r\n}\r\n\r\n","/**\r\n * 启动管线:按顺序执行初始化任务,支持超时与统一错误处理\r\n */\r\n\r\nfunction withTimeout(promiseFactory, timeoutMs, name) {\r\n if (!timeoutMs) return promiseFactory();\r\n return Promise.race([\r\n promiseFactory(),\r\n new Promise((_, reject) => setTimeout(() => reject(new Error(`Init task timeout: ${name}`)), timeoutMs))\r\n ]);\r\n}\r\n\r\n/**\r\n * 运行初始化任务列表\r\n * @param {Array<{name?: string, run: Function, timeoutMs?: number, onError?: Function, onSuccess?: Function}>} tasks\r\n * @param {Object} options\r\n * @param {(error: Error, task: any) => void} [options.onError]\r\n * @returns {Promise<void>}\r\n */\r\nexport async function runInitPipeline(tasks = [], options = {}) {\r\n for (const task of tasks) {\r\n const name = task?.name || 'anonymous-task';\r\n const run = task?.run || task;\r\n if (typeof run !== 'function') {\r\n continue;\r\n }\r\n\r\n try {\r\n await withTimeout(() => Promise.resolve().then(() => run()), task.timeoutMs, name);\r\n if (typeof task.onSuccess === 'function') {\r\n task.onSuccess();\r\n }\r\n } catch (error) {\r\n if (typeof task.onError === 'function') {\r\n task.onError(error);\r\n }\r\n if (typeof options.onError === 'function') {\r\n options.onError(error, task);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n","/**\r\n * 基础平台抽象类\r\n * 提供平台间的公共逻辑,减少代码重复\r\n */\r\n\r\n/**\r\n * 平台基类\r\n * 定义了所有平台的通用接口和公共逻辑\r\n */\r\nexport class BasePlatform {\r\n /**\r\n * 构造函数\r\n * @param {string} name - 平台名称\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * 处理导航选项的公共逻辑\r\n * @param {Object} options - 导航选项\r\n * @returns {Object} 处理后的选项\r\n */\r\n processNavigationOptions(options = {}) {\r\n const { url, delta = 1 } = options;\r\n \r\n // URL 编码处理\r\n const processedUrl = url ? encodeURI(url) : url;\r\n \r\n // Delta 参数转换\r\n const processedDelta = parseInt(delta) || 1;\r\n \r\n return {\r\n ...options,\r\n url: processedUrl,\r\n delta: processedDelta\r\n };\r\n }\r\n\r\n /**\r\n * 处理消息选项的公共逻辑\r\n * @param {Object} options - 消息选项\r\n * @returns {Object} 处理后的选项\r\n */\r\n processMessageOptions(options = {}) {\r\n const { data = {} } = options;\r\n return { data };\r\n }\r\n\r\n // ===== 导航方法(子类需要实现具体逻辑)=====\r\n\r\n /**\r\n * 导航到新页面\r\n * @param {Object} options - 导航参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n navigateTo(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('navigateTo', processedOptions);\r\n }\r\n\r\n /**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回参数\r\n * @param {number} [options.delta=1] - 返回页面层级数\r\n * @returns {void}\r\n */\r\n navigateBack(options = {}) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('navigateBack', processedOptions);\r\n }\r\n\r\n /**\r\n * 切换 Tab\r\n * @param {Object} options - 切换参数\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n */\r\n switchTab(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('switchTab', processedOptions);\r\n }\r\n\r\n /**\r\n * 重新启动并打开指定页面\r\n * @param {Object} options - 参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n reLaunch(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('reLaunch', processedOptions);\r\n }\r\n\r\n /**\r\n * 重定向到指定页面\r\n * @param {Object} options - 参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n redirectTo(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('redirectTo', processedOptions);\r\n }\r\n\r\n // ===== 消息方法(子类需要实现具体逻辑)=====\r\n\r\n /**\r\n * 发送消息到原生容器\r\n * @param {Object} [options] - 参数\r\n * @param {any} [options.data] - 需要发送的数据\r\n * @returns {void}\r\n */\r\n postMessage(options = {}) {\r\n const processedOptions = this.processMessageOptions(options);\r\n return this.performPostMessage(processedOptions);\r\n }\r\n\r\n /**\r\n * 获取环境信息\r\n * @param {Function} callback - 回调函数,参数为环境信息对象\r\n * @returns {void}\r\n */\r\n getEnv(callback) {\r\n return this.performGetEnv(callback);\r\n }\r\n\r\n // ===== 抽象方法(子类必须实现)=====\r\n\r\n /**\r\n * 执行具体的导航操作(抽象方法)\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n throw new Error(`${this.name} platform must implement performNavigation method`);\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作(抽象方法)\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n throw new Error(`${this.name} platform must implement performPostMessage method`);\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作(抽象方法)\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n throw new Error(`${this.name} platform must implement performGetEnv method`);\r\n }\r\n}\r\n\r\n/**\r\n * 创建平台适配器的工厂方法\r\n * @param {string} platformType - 平台类型\r\n * @returns {BasePlatform} 平台实例\r\n */\r\nexport function createPlatform(platformType) {\r\n switch (platformType) {\r\n case 'weixin':\r\n // 动态导入避免循环依赖\r\n return import('../platforms/weixin.js').then(module => new module.WeixinPlatform());\r\n case 'app':\r\n return import('../platforms/app.js').then(module => new module.AppPlatform());\r\n default:\r\n throw new Error(`Unsupported platform type: ${platformType}`);\r\n }\r\n}\r\n","/**\r\n * 消息通信核心模块\r\n * 负责与原生端进行消息通信\r\n */\r\n\r\nimport { isUvue, isNvue, isAppPlus } from './environment.js';\r\n\r\n// 存储 webview ID 列表\r\nlet webviewIds = [];\r\n\r\n/**\r\n * 设置 webview ID\r\n * @param {string[]} ids - webview ID 列表\r\n * @since 2.0.0\r\n */\r\nexport function setWebviewIds(ids) {\r\n webviewIds = ids;\r\n}\r\n\r\n/**\r\n * 获取当前 webview ID 列表\r\n * @returns {string[]} webview ID 列表\r\n * @throws {Error} 当 plus.webview.currentWebview 不可用时抛出\r\n * @since 2.0.0\r\n */\r\nfunction getCurrentWebviewId() {\r\n if (webviewIds.length === 0 && window.plus) {\r\n const currentWebview = plus.webview.currentWebview();\r\n if (!currentWebview) {\r\n throw new Error('plus.webview.currentWebview() is undefined');\r\n }\r\n const parent = currentWebview.parent();\r\n const webviewId = parent ? parent.id : currentWebview.id;\r\n webviewIds.push(webviewId);\r\n }\r\n return webviewIds;\r\n}\r\n\r\n/**\r\n * 发送消息到 UniApp X\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToUniAppX(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n if (name === 'postMessage') {\r\n const postData = { data: data };\r\n if (window.__uniapp_x_postMessage) {\r\n return window.__uniapp_x_postMessage(postData);\r\n }\r\n return window.__uniapp_x_.postMessage(JSON.stringify(postData));\r\n }\r\n\r\n const serviceMessage = {\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: webviewIds\r\n }\r\n };\r\n\r\n if (window.__uniapp_x_postMessage) {\r\n window.__uniapp_x_postMessageToService(serviceMessage);\r\n } else {\r\n window.__uniapp_x_.postMessageToService(JSON.stringify(serviceMessage));\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到 NVUE\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToNvue(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n if (name === 'postMessage') {\r\n const postData = { data: [data] };\r\n if (window.__dcloud_weex_postMessage) {\r\n return window.__dcloud_weex_postMessage(postData);\r\n }\r\n return window.__dcloud_weex_.postMessage(JSON.stringify(postData));\r\n }\r\n\r\n const serviceMessage = {\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: webviewIds\r\n }\r\n };\r\n\r\n if (window.__dcloud_weex_postMessage) {\r\n window.__dcloud_weex_postMessageToService(serviceMessage);\r\n } else {\r\n window.__dcloud_weex_.postMessageToService(JSON.stringify(serviceMessage));\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到 Plus 环境\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToPlus(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n const currentWebviewIds = getCurrentWebviewId();\r\n\r\n if (plus.webview.getWebviewById('__uniapp__service')) {\r\n plus.webview.postMessageToUniNView({\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: currentWebviewIds\r\n }\r\n }, '__uniapp__service');\r\n } else {\r\n const jsonMessage = JSON.stringify(message);\r\n const jsonWebviewIds = JSON.stringify(currentWebviewIds);\r\n plus.webview.getLaunchWebview().evalJS(\r\n `UniPlusBridge.subscribeHandler(\"WEB_INVOKE_APPSERVICE\",${jsonMessage},${jsonWebviewIds});`\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到父窗口(H5环境)\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToParent(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n window.parent.postMessage({\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n data: message,\r\n pageId: ''\r\n }, '*');\r\n}\r\n\r\n/**\r\n * 统一消息发送接口\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n * @example\r\n * sendMessage('postMessage', { foo: 1 })\r\n * @since 2.0.0\r\n */\r\nexport function sendMessage(name, data) {\r\n // console.log('环境', {\r\n // isAppPlus: isAppPlus(),\r\n // plus: !!window.plus,\r\n // uniappPostMessage: !!window.__uniapp_x_postMessage\r\n // })\r\n if (isUvue()) {\r\n sendToUniAppX(name, data);\r\n } else if (isNvue()) {\r\n sendToNvue(name, data);\r\n } else if (isAppPlus()) {\r\n sendToPlus(name, data);\r\n } else {\r\n // H5 环境或其他\r\n sendToParent(name, data);\r\n }\r\n}","/**\r\n * 微信小程序平台适配层\r\n */\r\n\r\nimport { BasePlatform } from '../core/base-platform.js';\r\nimport { sendMessage } from '../core/messenger.js';\r\nimport { ErrorHandler, ErrorTypes } from '../core/error-handler.js';\r\nimport { platformLogger } from '../core/logger.js';\r\n\r\n/**\r\n * 微信小程序平台适配器\r\n */\r\nexport class WeixinPlatform extends BasePlatform {\r\n constructor() {\r\n super('weixin');\r\n }\r\n\r\n /**\r\n * 检查微信 API 是否可用\r\n * @returns {boolean}\r\n * @private\r\n */\r\n isWeixinApiAvailable() {\r\n return typeof window !== 'undefined' && window.wx && window.wx.miniProgram;\r\n }\r\n\r\n /**\r\n * 执行具体的导航操作\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { url, delta } = options;\r\n \r\n platformLogger.debug(`微信平台执行导航操作: ${type}`, options);\r\n \r\n // 如果有原生 wx.miniProgram API,优先使用\r\n if (this.isWeixinApiAvailable()) {\r\n const wxMethod = window.wx.miniProgram[type];\r\n if (typeof wxMethod === 'function') {\r\n platformLogger.debug(`使用微信原生 API: wx.miniProgram.${type}`);\r\n const wxOptions = type === 'navigateBack' ? { delta } : { url };\r\n return wxMethod.call(window.wx.miniProgram, wxOptions);\r\n }\r\n }\r\n \r\n // 否则使用消息通信\r\n platformLogger.debug(`使用消息桥接执行: ${type}`);\r\n const messageData = type === 'navigateBack' ? { delta } : { url };\r\n sendMessage(type, messageData);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performNavigation', \r\n navigationType: type,\r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { data } = options;\r\n \r\n if (this.isWeixinApiAvailable()) {\r\n return window.wx.miniProgram.postMessage({ data });\r\n }\r\n \r\n // 使用消息通信\r\n sendMessage('postMessage', data);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performPostMessage', \r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!callback || typeof callback !== 'function') {\r\n throw new Error('Callback function is required for getEnv');\r\n }\r\n\r\n if (this.isWeixinApiAvailable() && window.wx.miniProgram.getEnv) {\r\n return window.wx.miniProgram.getEnv(callback);\r\n }\r\n \r\n // 回调微信环境信息\r\n callback({\r\n miniprogram: true,\r\n weixin: true\r\n });\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performGetEnv' \r\n });\r\n }\r\n}\r\n\r\n// 创建平台实例\r\nconst weixinPlatform = new WeixinPlatform();\r\n\r\n// 保持向后兼容性 - 导出原有的函数式 API\r\nexport const navigateTo = (options) => weixinPlatform.navigateTo(options);\r\nexport const navigateBack = (options) => weixinPlatform.navigateBack(options);\r\nexport const switchTab = (options) => weixinPlatform.switchTab(options);\r\nexport const reLaunch = (options) => weixinPlatform.reLaunch(options);\r\nexport const redirectTo = (options) => weixinPlatform.redirectTo(options);\r\nexport const postMessage = (options) => weixinPlatform.postMessage(options);\r\nexport const getEnv = (callback) => weixinPlatform.getEnv(callback);","/**\r\n * APP 平台适配层(Plus/Weex/UniX)\r\n */\r\n\r\nimport { BasePlatform } from '../core/base-platform.js';\r\nimport { sendMessage } from '../core/messenger.js';\r\nimport { ErrorHandler, ErrorTypes } from '../core/error-handler.js';\r\nimport { isUvue, isNvue, isAppPlus } from '../core/environment.js';\r\n\r\n/**\r\n * APP 平台适配器\r\n */\r\nexport class AppPlatform extends BasePlatform {\r\n constructor() {\r\n super('app');\r\n }\r\n\r\n /**\r\n * 执行具体的导航操作\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { url, delta } = options;\r\n \r\n // APP 平台使用消息通信\r\n const messageData = type === 'navigateBack' ? { delta } : { url };\r\n sendMessage(type, messageData);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performNavigation', \r\n navigationType: type,\r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { data } = options;\r\n \r\n // APP 平台使用消息通信\r\n sendMessage('postMessage', data);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performPostMessage', \r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!callback || typeof callback !== 'function') {\r\n throw new Error('Callback function is required for getEnv');\r\n }\r\n\r\n const envInfo = {};\r\n let isAppEnv = false;\r\n\r\n if (isUvue()) {\r\n envInfo.uvue = true;\r\n isAppEnv = true;\r\n } else if (isNvue()) {\r\n envInfo.nvue = true;\r\n isAppEnv = true;\r\n } else if (isAppPlus()) {\r\n envInfo.plus = true;\r\n isAppEnv = true;\r\n }\r\n\r\n if (isAppEnv) {\r\n envInfo.app = true;\r\n } else {\r\n envInfo.h5 = true;\r\n }\r\n\r\n callback(envInfo);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performGetEnv' \r\n });\r\n }\r\n}\r\n\r\n// 创建平台实例\r\nconst appPlatform = new AppPlatform();\r\n\r\n// 保持向后兼容性 - 导出原有的函数式 API\r\nexport const navigateTo = (options) => appPlatform.navigateTo(options);\r\nexport const navigateBack = (options) => appPlatform.navigateBack(options);\r\nexport const switchTab = (options) => appPlatform.switchTab(options);\r\nexport const reLaunch = (options) => appPlatform.reLaunch(options);\r\nexport const redirectTo = (options) => appPlatform.redirectTo(options);\r\nexport const postMessage = (options) => appPlatform.postMessage(options);\r\nexport const getEnv = (callback) => appPlatform.getEnv(callback);","/**\r\n * 导航 API 模块\r\n * 提供统一的导航接口\r\n */\r\n\r\nimport { isWeixinMiniProgram } from '../core/environment.js';\r\nimport * as weixinPlatform from '../platforms/weixin.js';\r\nimport * as appPlatform from '../platforms/app.js';\r\n\r\n/**\r\n * 获取当前平台的导航实现\r\n */\r\nfunction getPlatformNavigation() {\r\n if (isWeixinMiniProgram()) {\r\n return weixinPlatform;\r\n }\r\n return appPlatform;\r\n}\r\n\r\n/**\r\n * 导航到新页面\r\n * @param {Object} options - 导航选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateTo({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nexport function navigateTo(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.navigateTo(options);\r\n}\r\n\r\n/**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回选项\r\n * @param {number} [options.delta=1] - 返回页面层级数\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateBack({ delta: 1 })\r\n * @since 2.0.0\r\n */\r\nexport function navigateBack(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.navigateBack(options);\r\n}\r\n\r\n/**\r\n * 切换至 Tab 页面\r\n * @param {Object} options - 切换选项\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.switchTab({ url: '/pages/tabbar/home' })\r\n * @since 2.0.0\r\n */\r\nexport function switchTab(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.switchTab(options);\r\n}\r\n\r\n/**\r\n * 关闭所有页面并打开到应用内某页面\r\n * @param {Object} options - 重启选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.reLaunch({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nexport function reLaunch(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.reLaunch(options);\r\n}\r\n\r\n/**\r\n * 关闭当前页面并跳转到应用内某页面\r\n * @param {Object} options - 重定向选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.redirectTo({ url: '/pages/detail/index' })\r\n * @since 2.0.0\r\n */\r\nexport function redirectTo(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.redirectTo(options);\r\n}","/**\r\n * 消息通信 API 模块\r\n * 提供与原生端的消息通信接口\r\n */\r\n\r\nimport { isWeixinMiniProgram } from '../core/environment.js';\r\nimport * as weixinPlatform from '../platforms/weixin.js';\r\nimport * as appPlatform from '../platforms/app.js';\r\n\r\n/**\r\n * 获取当前平台的消息实现\r\n */\r\nfunction getPlatformMessage() {\r\n if (isWeixinMiniProgram()) {\r\n return weixinPlatform;\r\n }\r\n return appPlatform;\r\n}\r\n\r\n/**\r\n * 发送消息到原生容器\r\n * @param {Object} [options] - 消息选项\r\n * @param {any} [options.data] - 要发送的数据对象\r\n * @returns {void}\r\n * @example\r\n * qsh.postMessage({ data: { orderId: '123' } })\r\n * @since 2.0.0\r\n */\r\nexport function postMessage(options = {}) {\r\n const platform = getPlatformMessage();\r\n return platform.postMessage(options);\r\n}\r\n\r\n/**\r\n * 获取当前环境信息(回调形式)\r\n * @param {Function} callback - 回调函数,参数为环境信息对象\r\n * @returns {void}\r\n * @example\r\n * qsh.getEnv((info) => console.log(info))\r\n * @since 2.0.0\r\n */\r\nexport function getEnv(callback) {\r\n const platform = getPlatformMessage();\r\n return platform.getEnv(callback);\r\n}","/**\r\n * WebView 通信桥接模块\r\n * 实现网页与 UniApp 主应用的双向通信\r\n */\r\n\r\nimport { bridgeLogger } from './logger.js';\r\nimport { ErrorHandler, ErrorTypes, QshError } from './error-handler.js';\r\nimport { sendMessage } from './messenger.js';\r\nimport interceptorChain from './interceptor.js';\r\nimport stateStore from './state-store.js';\r\n// 注意:SDK 核心不应强依赖 Vue;此处避免引入 'vue' 以免库构建失败\r\n\r\n// 仅用于日志打印:在 Vue 响应式对象场景下尽量“脱壳”,否则直接返回原值\r\nfunction toRawLike(value) {\r\n // Vue3 Proxy 内部可能暴露 __v_raw(非官方 API),这里做最小兼容\r\n if (value && typeof value === 'object' && value.__v_raw) return value.__v_raw;\r\n return value;\r\n}\r\n/**\r\n * 生成唯一的回调ID\r\n * @returns {string} 唯一标识符\r\n */\r\nfunction generateCallbackId() {\r\n return 'qsh_callback_' + Date.now() + '_' + Math.random().toString(36).substring(2, 9);\r\n}\r\n\r\n/**\r\n * WebView 桥接管理器类\r\n */\r\nexport class WebViewBridge {\r\n constructor() {\r\n // 回调函数映射表\r\n this.callbacks = new Map();\r\n\r\n // 回调超时定时器映射\r\n this.timeouts = new Map();\r\n\r\n // 持久回调按 API 记录\r\n this.persistentCallbacksByApi = new Map();\r\n\r\n // 默认超时时间(30秒)\r\n this.defaultTimeout = 30000;\r\n\r\n // 初始化全局回调对象\r\n if (typeof window !== 'undefined') {\r\n if (!window.qshWebviewCallbacks) {\r\n window.qshWebviewCallbacks = {};\r\n }\r\n }\r\n\r\n bridgeLogger.debug('WebView 桥接器已初始化');\r\n }\r\n\r\n /**\r\n * 向主应用发送 API 调用消息\r\n * @param {string} apiName - API 名称\r\n * @param {Object} params - 参数对象\r\n * @param {Object} callbacks - 回调函数 {success, fail, complete}\r\n * @returns {void}\r\n */\r\n async callApi(apiName, params = {}, callbacks = {}) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 纯 H5 顶层页面:没有容器承接消息,直接失败\r\n const isTopLevelH5 = typeof window !== 'undefined'\r\n && window === window.parent\r\n && !window.plus\r\n && !window.__uniapp_x_postMessage && !window.__uniapp_x_\r\n && !window.__dcloud_weex_postMessage && !window.__dcloud_weex_;\r\n if (isTopLevelH5) {\r\n const error = new QshError(\r\n ErrorTypes.PLATFORM_NOT_SUPPORTED,\r\n '当前不在宿主 WebView 容器中,无法发送消息'\r\n );\r\n if (callbacks && typeof callbacks.fail === 'function') {\r\n callbacks.fail({ errMsg: error.message, code: 'NOT_IN_CONTAINER' });\r\n }\r\n if (callbacks && typeof callbacks.complete === 'function') {\r\n callbacks.complete({ success: false, error: { errMsg: error.message } });\r\n }\r\n return;\r\n }\r\n\r\n // 构建拦截器上下文\r\n const context = {\r\n apiName,\r\n params,\r\n callbacks,\r\n timestamp: Date.now(),\r\n abort: false,\r\n metadata: {}\r\n };\r\n // 更新状态:API 调用开始\r\n stateStore.setApiLoading(apiName, true);\r\n\r\n // 执行请求拦截器\r\n const interceptedContext = await interceptorChain.runRequest(context);\r\n\r\n // 检查是否被中止\r\n if (interceptedContext.abort) {\r\n bridgeLogger.warn('API 调用被拦截器中止', { api: apiName });\r\n stateStore.setApiLoading(apiName, false);\r\n\r\n // 触发失败回调\r\n if (callbacks.fail) {\r\n callbacks.fail({\r\n errMsg: interceptedContext.error?.message || 'API 调用被中止',\r\n code: 'INTERCEPTED'\r\n });\r\n }\r\n if (callbacks.complete) {\r\n callbacks.complete({ success: false });\r\n }\r\n return;\r\n }\r\n\r\n const callbackId = generateCallbackId();\r\n // 存储回调函数和上下文\r\n if (callbacks.success || callbacks.fail || callbacks.complete) {\r\n this.callbacks.set(callbackId, {\r\n ...callbacks,\r\n context: interceptedContext // 保存上下文用于响应拦截\r\n });\r\n\r\n // 设置全局回调函数\r\n window.qshWebviewCallbacks[callbackId] = (result) => {\r\n this.handleCallback(callbackId, result);\r\n };\r\n\r\n if (params.isPersistent) {\r\n if (!this.persistentCallbacksByApi.has(apiName)) {\r\n this.persistentCallbacksByApi.set(apiName, new Set());\r\n }\r\n this.persistentCallbacksByApi.get(apiName).add(callbackId);\r\n }\r\n\r\n // 检查是否禁用超时(支持 isPersistent 或 disableTimeout 参数)\r\n const shouldDisableTimeout = params.isPersistent || params.disableTimeout;\r\n \r\n // 设置超时清理(30秒后自动清理)\r\n if (!shouldDisableTimeout) {\r\n const timeoutId = setTimeout(() => {\r\n bridgeLogger.warn('API 调用超时,自动清理回调', { api: apiName, callbackId });\r\n if (callbacks.fail) {\r\n callbacks.fail({\r\n errMsg: `API ${apiName} 调用超时`,\r\n code: 'TIMEOUT'\r\n });\r\n }\r\n this.cleanupCallback(callbackId);\r\n }, params.timeout || this.defaultTimeout);\r\n\r\n this.timeouts.set(callbackId, timeoutId);\r\n } else {\r\n // ✅ 对持久事件(监听型 API)或禁用超时的 API 跳过超时清理\r\n bridgeLogger.info(`API ${apiName} 禁用超时清理,将等待回调返回后清理`, { \r\n callbackId,\r\n isPersistent: params.isPersistent,\r\n disableTimeout: params.disableTimeout\r\n });\r\n }\r\n\r\n // 构造消息(使用拦截后的参数)\r\n const message = {\r\n type: 'qsh_api_call',\r\n api: apiName,\r\n params: interceptedContext.params,\r\n callbackId: callbackId,\r\n timestamp: Date.now()\r\n };\r\n\r\n bridgeLogger.info('发送 API 调用消息', {\r\n api: apiName,\r\n callbackId: callbackId,\r\n hasSuccess: !!callbacks.success,\r\n hasFail: !!callbacks.fail\r\n });\r\n console.log('message:', JSON.stringify(toRawLike(message), null, 2))\r\n // 通过统一 messenger 发送(兼容 UvUE/NVUE/Plus/H5 Parent)\r\n sendMessage('postMessage', message);\r\n }\r\n }, {\r\n context: 'WebViewBridge.callApi',\r\n api: apiName\r\n });\r\n }\r\n\r\n /**\r\n * 处理来自主应用的回调\r\n * @param {string} callbackId - 回调ID\r\n * @param {Object} result - 结果对象\r\n * @private\r\n */\r\n async handleCallback(callbackId, result) {\r\n return ErrorHandler.safeExecute(async () => {\r\n const callbackData = this.callbacks.get(callbackId);\r\n\r\n if (!callbackData) {\r\n bridgeLogger.warn('未找到回调函数', { callbackId });\r\n return;\r\n }\r\n\r\n const { success, fail, complete, context } = callbackData;\r\n\r\n bridgeLogger.debug('处理回调', { callbackId, result });\r\n\r\n // 执行响应拦截器\r\n const interceptedResult = await interceptorChain.runResponse(result, context);\r\n\r\n // 更新状态:API 调用完成\r\n if (context) {\r\n stateStore.setApiResult(context.apiName, interceptedResult);\r\n }\r\n\r\n // 执行对应的回调\r\n if (interceptedResult.success && success) {\r\n success(interceptedResult.data);\r\n } else if (!interceptedResult.success && fail) {\r\n fail(interceptedResult.error || { errMsg: '操作失败' });\r\n }\r\n\r\n // 执行 complete 回调\r\n if (complete) {\r\n complete(interceptedResult);\r\n }\r\n\r\n // 清理回调和超时定时器\r\n // 只有持久监听型 API(isPersistent)才保留回调,其他都清理\r\n const isPersistent = callbackData.context?.params?.isPersistent;\r\n \r\n if (!isPersistent) {\r\n this.cleanupCallback(callbackId);\r\n bridgeLogger.debug('回调执行完成,已清理', { callbackId });\r\n } else {\r\n bridgeLogger.debug('持久监听API:保留回调', { callbackId });\r\n }\r\n\r\n }, {\r\n context: 'WebViewBridge.handleCallback',\r\n callbackId\r\n });\r\n }\r\n\r\n /**\r\n * 清理回调和相关资源\r\n * @param {string} callbackId - 回调ID\r\n * @private\r\n */\r\n cleanupCallback(callbackId) {\r\n // 清除超时定时器\r\n const timeoutId = this.timeouts.get(callbackId);\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n this.timeouts.delete(callbackId);\r\n }\r\n\r\n // 清除回调函数\r\n this.callbacks.delete(callbackId);\r\n\r\n // 清除全局回调\r\n if (typeof window !== 'undefined' && window.qshWebviewCallbacks) {\r\n delete window.qshWebviewCallbacks[callbackId];\r\n }\r\n\r\n if (this.persistentCallbacksByApi && this.persistentCallbacksByApi.size > 0) {\r\n const emptyApis = [];\r\n this.persistentCallbacksByApi.forEach((callbackIds, apiName) => {\r\n if (callbackIds.has(callbackId)) {\r\n callbackIds.delete(callbackId);\r\n if (callbackIds.size === 0) {\r\n emptyApis.push(apiName);\r\n }\r\n }\r\n });\r\n emptyApis.forEach(apiName => this.persistentCallbacksByApi.delete(apiName));\r\n }\r\n }\r\n\r\n /**\r\n * 清理所有待处理的回调\r\n */\r\n clearCallbacks() {\r\n bridgeLogger.debug('清理所有回调', { count: this.callbacks.size });\r\n\r\n // 清除所有超时定时器\r\n this.timeouts.forEach(timeoutId => clearTimeout(timeoutId));\r\n this.timeouts.clear();\r\n\r\n // 清除回调映射\r\n this.callbacks.clear();\r\n\r\n if (this.persistentCallbacksByApi) {\r\n this.persistentCallbacksByApi.clear();\r\n }\r\n\r\n // 清除全局回调对象\r\n if (typeof window !== 'undefined' && window.qshWebviewCallbacks) {\r\n Object.keys(window.qshWebviewCallbacks).forEach(key => {\r\n if (key.startsWith('qsh_callback_')) {\r\n delete window.qshWebviewCallbacks[key];\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 清理指定 API 的持久回调\r\n * @param {string} apiName - API 名称\r\n * @returns {number} 清理数量\r\n */\r\n cleanupPersistentCallbacksByApi(apiName) {\r\n const callbackIds = this.persistentCallbacksByApi.get(apiName);\r\n if (!callbackIds || callbackIds.size === 0) {\r\n return 0;\r\n }\r\n const ids = Array.from(callbackIds);\r\n ids.forEach((callbackId) => this.cleanupCallback(callbackId));\r\n this.persistentCallbacksByApi.delete(apiName);\r\n bridgeLogger.info('已清理持久回调', { api: apiName, count: ids.length });\r\n return ids.length;\r\n }\r\n\r\n /**\r\n * 获取桥接器状态信息\r\n * @returns {Object} 状态信息\r\n */\r\n getStatus() {\r\n return {\r\n isSupported: typeof window !== 'undefined' &&\r\n window.uni &&\r\n typeof window.uni.postMessage === 'function',\r\n activeCallbacks: this.callbacks.size,\r\n globalCallbacksCount: typeof window !== 'undefined' && window.qshWebviewCallbacks ?\r\n Object.keys(window.qshWebviewCallbacks).length : 0\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst webViewBridge = new WebViewBridge();\r\n\r\n// 导出便利函数\r\nexport const callApiInWebView = (apiName, params, callbacks) =>\r\n webViewBridge.callApi(apiName, params, callbacks);\r\n\r\nexport const getWebViewBridgeStatus = () => webViewBridge.getStatus();\r\n\r\nexport const clearWebViewCallbacks = () => webViewBridge.clearCallbacks();\r\n\r\nexport const clearPersistentCallbacksByApi = (apiName) =>\r\n webViewBridge.cleanupPersistentCallbacksByApi(apiName);\r\n\r\nexport default webViewBridge;\r\n","/**\r\n * 图片选择 API 模块\r\n * 统一封装微信和UniApp的图片选择功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 图片来源类型枚举\r\n */\r\nexport const ImageSourceTypes = {\r\n ALBUM: 'album', // 相册\r\n CAMERA: 'camera' // 相机\r\n};\r\n\r\n/**\r\n * 图片大小类型枚举\r\n */\r\nexport const ImageSizeTypes = {\r\n ORIGINAL: 'original', // 原图\r\n COMPRESSED: 'compressed' // 压缩图\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n count: 9,\r\n sizeType: [ImageSizeTypes.ORIGINAL, ImageSizeTypes.COMPRESSED],\r\n sourceType: [ImageSourceTypes.ALBUM, ImageSourceTypes.CAMERA]\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 确保数组格式\r\n if (!Array.isArray(normalized.sizeType)) {\r\n normalized.sizeType = [normalized.sizeType].filter(Boolean);\r\n }\r\n if (!Array.isArray(normalized.sourceType)) {\r\n normalized.sourceType = [normalized.sourceType].filter(Boolean);\r\n }\r\n \r\n // 数量限制 1-9\r\n normalized.count = Math.max(1, Math.min(9, parseInt(normalized.count) || 1));\r\n \r\n // 空数组回退默认值\r\n if (normalized.sizeType.length === 0) {\r\n normalized.sizeType = [ImageSizeTypes.COMPRESSED];\r\n }\r\n if (normalized.sourceType.length === 0) {\r\n normalized.sourceType = [ImageSourceTypes.ALBUM];\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持图片选择\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的图片选择\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseImageInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = { \r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => chooseImageInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信 API\r\n apiLogger.debug('调用微信图片选择', options);\r\n \r\n window.wx.chooseImage({\r\n count: options.count,\r\n sizeType: options.sizeType,\r\n sourceType: options.sourceType,\r\n success: (res) => {\r\n apiLogger.info('微信图片选择成功', { count: res.localIds?.length || 0 });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信图片选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseImageInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的图片选择(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseImageInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用图片选择', options);\r\n \r\n // 通过桥接层调用(禁用超时清理,等待用户选择完成)\r\n callApiInWebView('chooseImage', { ...options, disableTimeout: true }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 图片选择成功', { \r\n count: res?.tempFilePaths?.length || 0 \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 图片选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseImageInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 选择图片(统一入口)\r\n * \r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.count=9] - 最多选择的图片数量\r\n * @param {string[]} [options.sizeType] - 图片质量类型 ['original', 'compressed']\r\n * @param {string[]} [options.sourceType] - 图片来源类型 ['album', 'camera']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.chooseImage({\r\n * count: 1,\r\n * success: (res) => {\r\n * // 微信环境: res.localIds\r\n * // UniApp环境: res.tempFilePaths\r\n * console.log('选择成功:', res);\r\n * },\r\n * fail: (error) => {\r\n * console.error('选择失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 完整配置\r\n * qsh.chooseImage({\r\n * count: 3,\r\n * sizeType: ['compressed'],\r\n * sourceType: ['album'],\r\n * success: (res) => console.log(res),\r\n * fail: (err) => console.error(err)\r\n * });\r\n */\r\nexport function chooseImage(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持图片选择功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持图片选择', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始选择图片', {\r\n platform: environment.type,\r\n count: normalizedOptions.count,\r\n sizeType: normalizedOptions.sizeType,\r\n sourceType: normalizedOptions.sourceType\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n chooseImageInWeixin(normalizedOptions);\r\n } else {\r\n chooseImageInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'chooseImage',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的图片选择\r\n * \r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const result = await qsh.chooseImageAsync({ count: 1 });\r\n * console.log('选择的图片:', result);\r\n * } catch (error) {\r\n * console.error('选择失败:', error);\r\n * }\r\n */\r\nexport function chooseImageAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseImage({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取图片功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getImageCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n */\r\nexport function getImageCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n multipleSelection: true, // 支持多选\r\n sizeTypeSelection: true, // 支持质量选择\r\n sourceTypeSelection: true, // 支持来源选择\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}\r\n","/**\r\n * 扫码 API 模块\r\n * 统一封装微信和UniApp的扫码功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 扫码类型枚举\r\n */\r\nexport const ScanTypes = {\r\n QR_CODE: 'qrCode', // 二维码\r\n BAR_CODE: 'barCode', // 一维码(条形码)\r\n DATA_MATRIX: 'datamatrix', // Data Matrix 码\r\n PDF417: 'pdf417' // PDF417 条码\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n onlyFromCamera: true, // 只从相机扫码\r\n scanType: [ScanTypes.QR_CODE, ScanTypes.BAR_CODE] // 支持二维码和一维码\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 确保 scanType 是数组\r\n if (!Array.isArray(normalized.scanType)) {\r\n normalized.scanType = [normalized.scanType].filter(Boolean);\r\n }\r\n \r\n // 空数组回退默认值\r\n if (normalized.scanType.length === 0) {\r\n normalized.scanType = [ScanTypes.QR_CODE, ScanTypes.BAR_CODE];\r\n }\r\n \r\n // 确保 onlyFromCamera 是布尔值\r\n normalized.onlyFromCamera = !!normalized.onlyFromCamera;\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持扫码\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的扫码\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction scanCodeInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => scanCodeInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信扫码 API\r\n apiLogger.debug('调用微信扫码', options);\r\n \r\n // 微信 API:wx.scanQRCode\r\n window.wx.scanQRCode({\r\n needResult: 1, // 直接返回扫码结果\r\n scanType: options.scanType,\r\n success: (res) => {\r\n apiLogger.info('微信扫码成功', { result: res.resultStr });\r\n \r\n // 转换为统一格式(与 UniApp 一致)\r\n const result = {\r\n result: res.resultStr, // 扫码内容\r\n scanType: detectScanType(res.resultStr), // 推测扫码类型\r\n charSet: 'utf-8', // 微信默认 UTF-8\r\n errMsg: 'scanCode:ok'\r\n };\r\n \r\n options.success?.(result);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信扫码失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'scanCodeInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n/**\r\n * 根据内容推测扫码类型(辅助函数)\r\n * @param {string} content - 扫码内容\r\n * @returns {string} 扫码类型\r\n * @private\r\n */\r\nfunction detectScanType(content) {\r\n if (!content) return 'unknown';\r\n \r\n // 简单规则:长度较长或包含特殊字符通常是二维码\r\n if (content.length > 50 || /[^\\d]/.test(content)) {\r\n return ScanTypes.QR_CODE;\r\n }\r\n \r\n // 纯数字且长度适中,可能是条形码\r\n return ScanTypes.BAR_CODE;\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的扫码(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction scanCodeInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用扫码', options);\r\n \r\n // 通过桥接层调用(禁用超时清理,等待用户扫码完成)\r\n callApiInWebView('scanCode', { ...options, disableTimeout: true }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 扫码成功', { \r\n result: res?.result,\r\n scanType: res?.scanType\r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 扫码失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'scanCodeInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 扫码(统一入口)\r\n * \r\n * @param {Object} [options] - 扫码参数\r\n * @param {boolean} [options.onlyFromCamera=true] - 是否只能从相机扫码\r\n * @param {string[]} [options.scanType] - 扫码类型 ['qrCode', 'barCode']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.scanCode({\r\n * success: (res) => {\r\n * console.log('扫码结果:', res.result);\r\n * console.log('扫码类型:', res.scanType);\r\n * },\r\n * fail: (error) => {\r\n * console.error('扫码失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 只扫二维码\r\n * qsh.scanCode({\r\n * scanType: ['qrCode'],\r\n * success: (res) => console.log(res.result)\r\n * });\r\n * \r\n * @example\r\n * // 允许从相册选择\r\n * qsh.scanCode({\r\n * onlyFromCamera: false,\r\n * success: (res) => console.log(res.result)\r\n * });\r\n */\r\nexport function scanCode(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持扫码功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持扫码', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始扫码', {\r\n platform: environment.type,\r\n onlyFromCamera: normalizedOptions.onlyFromCamera,\r\n scanType: normalizedOptions.scanType\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n scanCodeInWeixin(normalizedOptions);\r\n } else {\r\n scanCodeInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'scanCode',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的扫码\r\n * \r\n * @param {Object} [options] - 扫码参数(不包含回调函数)\r\n * @returns {Promise} 扫码结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const result = await qsh.scanCodeAsync({\r\n * scanType: ['qrCode']\r\n * });\r\n * console.log('扫码结果:', result.result);\r\n * console.log('扫码类型:', result.scanType);\r\n * } catch (error) {\r\n * if (error.code === qsh.errors.codes.SCAN_CANCELLED) {\r\n * console.log('用户取消扫码');\r\n * } else {\r\n * console.error('扫码失败:', error);\r\n * }\r\n * }\r\n */\r\nexport function scanCodeAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n scanCode({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取扫码功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getScanCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n */\r\nexport function getScanCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n onlyFromCamera: true, // 支持只从相机扫码\r\n scanTypeSelection: true, // 支持扫码类型选择\r\n multipleTypes: true, // 支持多种扫码类型\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}\r\n\r\n","/**\r\n * 地理位置 API 模块\r\n * 统一封装微信和UniApp的地理位置功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView, clearPersistentCallbacksByApi } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 坐标类型枚举\r\n */\r\nexport const CoordinateTypes = {\r\n WGS84: 'wgs84', // GPS 坐标\r\n GCJ02: 'gcj02', // 国测局坐标(火星坐标)\r\n BD09: 'bd09' // 百度坐标\r\n};\r\n\r\n/**\r\n * 默认选项 - getLocation\r\n */\r\nconst DEFAULT_LOCATION_OPTIONS = {\r\n type: CoordinateTypes.WGS84,\r\n altitude: false\r\n};\r\n\r\n/**\r\n * 默认选项 - openLocation\r\n */\r\nconst DEFAULT_OPEN_LOCATION_OPTIONS = {\r\n scale: 18 // 地图缩放级别 1-28\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化 getLocation 选项\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeLocationOptions(options = {}) {\r\n const normalized = { ...DEFAULT_LOCATION_OPTIONS, ...options };\r\n \r\n // 确保 type 是合法值\r\n if (!Object.values(CoordinateTypes).includes(normalized.type)) {\r\n normalized.type = CoordinateTypes.WGS84;\r\n }\r\n \r\n // 确保 altitude 是布尔值\r\n normalized.altitude = !!normalized.altitude;\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 标准化位置更新参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeLocationUpdateOptions(options = {}) {\r\n const normalized = { ...options };\r\n\r\n if (!Object.values(CoordinateTypes).includes(normalized.type)) {\r\n normalized.type = CoordinateTypes.WGS84;\r\n }\r\n\r\n normalized.needFullAccuracy = !!normalized.needFullAccuracy;\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * 标准化 openLocation 选项\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOpenLocationOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPEN_LOCATION_OPTIONS, ...options };\r\n \r\n // 验证 latitude(纬度)\r\n if (normalized.latitude === undefined || normalized.latitude === null) {\r\n const error = {\r\n errMsg: '缺少必需参数:latitude(纬度)',\r\n code: 'PARAM_MISSING'\r\n };\r\n throw error;\r\n }\r\n \r\n if (typeof normalized.latitude !== 'number') {\r\n const error = {\r\n errMsg: `latitude 参数类型错误:期望 number,实际 ${typeof normalized.latitude}`,\r\n code: 'PARAM_TYPE_ERROR',\r\n details: {\r\n param: 'latitude',\r\n expected: 'number',\r\n actual: typeof normalized.latitude,\r\n value: normalized.latitude\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证纬度范围 -90 ~ 90\r\n if (normalized.latitude < -90 || normalized.latitude > 90) {\r\n const error = {\r\n errMsg: `latitude 超出范围:有效范围 -90 ~ 90,实际值 ${normalized.latitude}`,\r\n code: 'PARAM_INVALID',\r\n details: {\r\n param: 'latitude',\r\n value: normalized.latitude,\r\n validRange: '-90 ~ 90'\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证 longitude(经度)\r\n if (normalized.longitude === undefined || normalized.longitude === null) {\r\n const error = {\r\n errMsg: '缺少必需参数:longitude(经度)',\r\n code: 'PARAM_MISSING'\r\n };\r\n throw error;\r\n }\r\n \r\n if (typeof normalized.longitude !== 'number') {\r\n const error = {\r\n errMsg: `longitude 参数类型错误:期望 number,实际 ${typeof normalized.longitude}`,\r\n code: 'PARAM_TYPE_ERROR',\r\n details: {\r\n param: 'longitude',\r\n expected: 'number',\r\n actual: typeof normalized.longitude,\r\n value: normalized.longitude\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证经度范围 -180 ~ 180\r\n if (normalized.longitude < -180 || normalized.longitude > 180) {\r\n const error = {\r\n errMsg: `longitude 超出范围:有效范围 -180 ~ 180,实际值 ${normalized.longitude}`,\r\n code: 'PARAM_INVALID',\r\n details: {\r\n param: 'longitude',\r\n value: normalized.longitude,\r\n validRange: '-180 ~ 180'\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 缩放级别限制 1-28\r\n if (normalized.scale !== undefined && normalized.scale !== null) {\r\n // 尝试转换为数字\r\n const scaleNum = Number(normalized.scale);\r\n if (isNaN(scaleNum)) {\r\n apiLogger.warn('scale 参数无效,使用默认值 18', { scale: normalized.scale });\r\n normalized.scale = 18;\r\n } else {\r\n normalized.scale = Math.max(1, Math.min(28, Math.floor(scaleNum)));\r\n }\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持地理位置\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下获取位置\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction getLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => getLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信定位 API\r\n apiLogger.debug('调用微信定位', options);\r\n \r\n window.wx.getLocation({\r\n type: options.type,\r\n success: (res) => {\r\n apiLogger.info('微信定位成功', { \r\n latitude: res.latitude, \r\n longitude: res.longitude \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信定位失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'getLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n/**\r\n * 微信环境下查看位置\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction openLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => openLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信查看位置 API\r\n apiLogger.debug('调用微信查看位置', options);\r\n \r\n window.wx.openLocation({\r\n latitude: options.latitude,\r\n longitude: options.longitude,\r\n name: options.name || '',\r\n address: options.address || '',\r\n scale: options.scale || 18,\r\n infoUrl: options.infoUrl || '',\r\n success: (res) => {\r\n apiLogger.info('微信查看位置成功');\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信查看位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'openLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下获取位置(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction getLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用获取位置', options);\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('getLocation', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 获取位置成功', { \r\n latitude: res?.latitude, \r\n longitude: res?.longitude \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 获取位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'getLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n/**\r\n * UniApp 环境下查看位置(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction openLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用查看位置', options);\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('openLocation', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 查看位置成功');\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 查看位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'openLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 获取当前地理位置(统一入口)\r\n * \r\n * @param {Object} [options] - 定位参数\r\n * @param {string} [options.type='wgs84'] - 坐标类型 'wgs84' | 'gcj02' | 'bd09'\r\n * @param {boolean} [options.altitude=false] - 是否返回高度信息\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.getLocation({\r\n * success: (res) => {\r\n * console.log('纬度:', res.latitude);\r\n * console.log('经度:', res.longitude);\r\n * console.log('精度:', res.accuracy);\r\n * },\r\n * fail: (error) => {\r\n * console.error('定位失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 获取火星坐标(gcj02)\r\n * qsh.getLocation({\r\n * type: 'gcj02',\r\n * altitude: true,\r\n * success: (res) => {\r\n * console.log('位置:', res.latitude, res.longitude);\r\n * console.log('高度:', res.altitude);\r\n * }\r\n * });\r\n */\r\nexport function getLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持定位功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持定位', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeLocationOptions(options);\r\n \r\n apiLogger.info('开始获取位置', {\r\n platform: environment.type,\r\n type: normalizedOptions.type,\r\n altitude: normalizedOptions.altitude\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n getLocationInWeixin(normalizedOptions);\r\n } else {\r\n getLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'getLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * 查看位置(统一入口)\r\n * \r\n * @param {Object} options - 位置参数\r\n * @param {number} options.latitude - 纬度(必填,数字类型,范围 -90 ~ 90)\r\n * @param {number} options.longitude - 经度(必填,数字类型,范围 -180 ~ 180)\r\n * @param {string} [options.name] - 位置名称\r\n * @param {string} [options.address] - 详细地址\r\n * @param {number} [options.scale=18] - 地图缩放级别 1-28\r\n * @param {string} [options.infoUrl] - 底部链接\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门',\r\n * address: '北京市东城区',\r\n * success: () => {\r\n * console.log('打开地图成功');\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 完整配置\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门广场',\r\n * address: '北京市东城区东长安街',\r\n * scale: 15,\r\n * infoUrl: 'https://example.com/detail',\r\n * success: () => console.log('成功'),\r\n * fail: (err) => console.error(err)\r\n * });\r\n */\r\nexport function openLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持查看位置功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持查看位置', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数(包含参数验证)\r\n let normalizedOptions;\r\n try {\r\n normalizedOptions = normalizeOpenLocationOptions(options);\r\n } catch (validationError) {\r\n // 参数验证失败,触发 fail 回调\r\n apiLogger.error('参数验证失败', validationError);\r\n options.fail?.(validationError);\r\n options.complete?.();\r\n return;\r\n }\r\n \r\n apiLogger.info('开始查看位置', {\r\n platform: environment.type,\r\n latitude: normalizedOptions.latitude,\r\n longitude: normalizedOptions.longitude,\r\n name: normalizedOptions.name\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n openLocationInWeixin(normalizedOptions);\r\n } else {\r\n openLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'openLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的获取位置\r\n * \r\n * @param {Object} [options] - 定位参数(不包含回调函数)\r\n * @returns {Promise} 定位结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const location = await qsh.getLocationAsync({\r\n * type: 'gcj02'\r\n * });\r\n * console.log('纬度:', location.latitude);\r\n * console.log('经度:', location.longitude);\r\n * } catch (error) {\r\n * if (error.code === qsh.errors.codes.LOCATION_CANCELLED) {\r\n * console.log('用户拒绝授权');\r\n * } else {\r\n * console.error('定位失败:', error);\r\n * }\r\n * }\r\n */\r\nexport function getLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n getLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的查看位置\r\n * \r\n * @param {Object} options - 位置参数(不包含回调函数)\r\n * @returns {Promise} 操作结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * await qsh.openLocationAsync({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门'\r\n * });\r\n * console.log('地图已打开');\r\n * } catch (error) {\r\n * console.error('打开地图失败:', error);\r\n * }\r\n */\r\nexport function openLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取地理位置功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getLocationCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n */\r\nexport function getLocationCapabilities() {\r\n const isWeixin = isWeixinMiniProgram();\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixin ? 'weixin' : 'webview',\r\n features: {\r\n getLocation: true, // 获取位置\r\n openLocation: true, // 查看位置\r\n coordinateTypes: true, // 支持坐标类型选择\r\n altitudeSupport: true, // 支持高度信息\r\n asyncSupport: true, // 支持 Promise\r\n onLocationChange: !isWeixin, // 支持位置监听(微信环境不支持)\r\n }\r\n };\r\n}\r\n\r\n// ==================== 位置监听回调管理 ====================\r\n\r\nconst locationChangeCallbacks = new Set();\r\nconst locationChangeErrorCallbacks = new Set();\r\n\r\nfunction notifyCallbacks(callbacks, payload, context) {\r\n callbacks.forEach((callback) => {\r\n if (typeof callback === 'function') {\r\n ErrorHandler.safeExecute(() => callback(payload), { context });\r\n return;\r\n }\r\n apiLogger.warn('监听回调不是函数,已跳过', { type: typeof callback });\r\n });\r\n}\r\n\r\n/**\r\n * 开启前台持续定位服务\r\n * 对应原生:uni.startLocationUpdate\r\n */\r\nexport function startLocationUpdate(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持该接口`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('当前环境不支持此接口', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n };\r\n\r\n const normalizedOptions = normalizeLocationUpdateOptions(options);\r\n\r\n apiLogger.info('正在开启定位监听');\r\n callApiInWebView('startLocationUpdate', {\r\n type: normalizedOptions.type,\r\n needFullAccuracy: normalizedOptions.needFullAccuracy\r\n }, {\r\n success: (res) => {\r\n apiLogger.info('定位监听已启动');\r\n options.success?.(res);\r\n },\r\n fail: (err) => options.fail?.(err),\r\n complete: options.complete\r\n });\r\n }, { context: 'startLocationUpdate' });\r\n}\r\n\r\n/**\r\n * 停止前台持续定位服务\r\n * 对应原生:uni.stopLocationUpdate\r\n */\r\nexport function stopLocationUpdate(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持该接口`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('当前环境不支持此接口', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n };\r\n\r\n apiLogger.info('正在停止定位监听');\r\n callApiInWebView('stopLocationUpdate', options, {\r\n success: (res) => {\r\n apiLogger.info('定位监听已停止');\r\n options.success?.(res);\r\n },\r\n fail: (err) => options.fail?.(err),\r\n complete: options.complete\r\n });\r\n }, { context: 'stopLocationUpdate' });\r\n}\r\n\r\n/**\r\n * 监听实时地理位置变化事件\r\n * 对应原生:uni.onLocationChange\r\n * 核心:通过 isPersistent: true 告知桥接层保留回调函数\r\n * \r\n * 注意:位置变化时调用回调函数,监听错误由 onLocationChangeError 处理\r\n * \r\n * @param {Function} callback - 回调函数,入参为位置信息对象\r\n * \r\n * @example\r\n * // 直接传入回调函数\r\n * qsh.onLocationChange((res) => {\r\n * console.log('位置:', res.latitude, res.longitude);\r\n * console.log('精度:', res.accuracy, '米');\r\n * });\r\n */\r\nexport function onLocationChange(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 验证必须是函数\r\n if (typeof callback !== 'function') {\r\n apiLogger.error('onLocationChange 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'onLocationChange 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n const hasListener = locationChangeCallbacks.size > 0;\r\n locationChangeCallbacks.add(callback);\r\n\r\n if (!hasListener) {\r\n apiLogger.debug('注册实时位置变化监听器');\r\n callApiInWebView('onLocationChange', { isPersistent: true }, {\r\n success: (res) => {\r\n apiLogger.debug('收到实时位置推送', res);\r\n notifyCallbacks(locationChangeCallbacks, res, 'onLocationChange');\r\n },\r\n fail: (error) => {\r\n // 监听错误由 onLocationChangeError 处理,此处仅记录日志\r\n apiLogger.warn('位置变化监听出错,请通过 onLocationChangeError 监听错误', error);\r\n locationChangeCallbacks.delete(callback);\r\n if (locationChangeCallbacks.size === 0) {\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n }\r\n }\r\n });\r\n }\r\n }, { context: 'onLocationChange' });\r\n}\r\n\r\n/**\r\n * 移除实时地理位置变化事件的监听函数\r\n * 对应原生:uni.offLocationChange\r\n * \r\n * 注意:调用此方法会停止监听位置变化事件\r\n * \r\n * @param {Function} [callback] - 可选回调,用于取消指定监听\r\n * @example\r\n * // 移除监听\r\n * qsh.offLocationChange();\r\n */\r\nexport function offLocationChange(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n if (callback && typeof callback !== 'function') {\r\n apiLogger.error('offLocationChange 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'offLocationChange 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n if (callback) {\r\n locationChangeCallbacks.delete(callback);\r\n } else {\r\n locationChangeCallbacks.clear();\r\n }\r\n\r\n if (locationChangeCallbacks.size > 0) {\r\n return;\r\n }\r\n\r\n apiLogger.info('移除位置变化监听器');\r\n callApiInWebView('offLocationChange', {}, {\r\n success: () => {\r\n apiLogger.info('位置变化监听已移除');\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n },\r\n fail: (error) => {\r\n apiLogger.error('移除位置变化监听失败', error);\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n }\r\n });\r\n }, { context: 'offLocationChange' });\r\n}\r\n\r\n/**\r\n * 监听持续定位接口返回失败时触发\r\n * 对应原生:uni.onLocationChangeError\r\n * \r\n * 注意:此监听器用于捕获位置更新过程中的错误,需要配合 startLocationUpdate 和 onLocationChange 使用\r\n * \r\n * @param {Function} callback - 错误回调函数,入参为错误对象\r\n * \r\n * @example\r\n * // 直接传入回调函数\r\n * qsh.onLocationChangeError((err) => {\r\n * console.error('位置监听出错:', err.code, err.message);\r\n * });\r\n */\r\nexport function onLocationChangeError(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 验证必须是函数\r\n if (typeof callback !== 'function') {\r\n apiLogger.error('onLocationChangeError 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'onLocationChangeError 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n const hasListener = locationChangeErrorCallbacks.size > 0;\r\n locationChangeErrorCallbacks.add(callback);\r\n\r\n if (!hasListener) {\r\n apiLogger.debug('注册位置更新错误监听器');\r\n callApiInWebView('onLocationChangeError', { isPersistent: true }, {\r\n success: (err) => {\r\n apiLogger.warn('持续定位发生异常', err);\r\n notifyCallbacks(locationChangeErrorCallbacks, err, 'onLocationChangeError');\r\n },\r\n fail: (error) => {\r\n apiLogger.warn('位置更新错误监听注册失败', error);\r\n locationChangeErrorCallbacks.delete(callback);\r\n if (locationChangeErrorCallbacks.size === 0) {\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n }\r\n }\r\n });\r\n }\r\n }, { context: 'onLocationChangeError' });\r\n}\r\n\r\n/**\r\n * 取消注册位置更新错误回调\r\n * 对应原生:uni.offLocationChangeError\r\n * \r\n * 注意:调用此方法会停止监听位置更新错误事件\r\n * \r\n * @param {Function} [callback] - 可选回调,用于取消指定监听\r\n * @example\r\n * // 移除错误监听\r\n * qsh.offLocationChangeError();\r\n */\r\nexport function offLocationChangeError(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n if (callback && typeof callback !== 'function') {\r\n apiLogger.error('offLocationChangeError 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'offLocationChangeError 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n if (callback) {\r\n locationChangeErrorCallbacks.delete(callback);\r\n } else {\r\n locationChangeErrorCallbacks.clear();\r\n }\r\n\r\n if (locationChangeErrorCallbacks.size > 0) {\r\n return;\r\n }\r\n\r\n apiLogger.info('移除定位错误监听器');\r\n callApiInWebView('offLocationChangeError', {}, {\r\n success: () => {\r\n apiLogger.info('定位错误监听已移除');\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n },\r\n fail: (error) => {\r\n apiLogger.error('移除定位错误监听失败', error);\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n }\r\n });\r\n }, { context: 'offLocationChangeError' });\r\n}","/**\r\n * 位置选择 API 模块\r\n * 统一封装微信和UniApp的位置选择功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n latitude: null, // 目标地纬度\r\n longitude: null // 目标地经度\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 验证 latitude(如果提供)\r\n if (normalized.latitude !== null && normalized.latitude !== undefined) {\r\n if (typeof normalized.latitude !== 'number') {\r\n apiLogger.warn('latitude 参数类型错误,已忽略', { \r\n latitude: normalized.latitude \r\n });\r\n normalized.latitude = null;\r\n } else if (normalized.latitude < -90 || normalized.latitude > 90) {\r\n apiLogger.warn('latitude 超出范围,已忽略', { \r\n latitude: normalized.latitude \r\n });\r\n normalized.latitude = null;\r\n }\r\n }\r\n \r\n // 验证 longitude(如果提供)\r\n if (normalized.longitude !== null && normalized.longitude !== undefined) {\r\n if (typeof normalized.longitude !== 'number') {\r\n apiLogger.warn('longitude 参数类型错误,已忽略', { \r\n longitude: normalized.longitude \r\n });\r\n normalized.longitude = null;\r\n } else if (normalized.longitude < -180 || normalized.longitude > 180) {\r\n apiLogger.warn('longitude 超出范围,已忽略', { \r\n longitude: normalized.longitude \r\n });\r\n normalized.longitude = null;\r\n }\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持位置选择\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的位置选择\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => chooseLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信位置选择 API\r\n apiLogger.debug('调用微信位置选择', options);\r\n \r\n // 构建微信 API 参数\r\n const wxOptions = {\r\n success: (res) => {\r\n apiLogger.info('微信位置选择成功', { \r\n name: res.name,\r\n address: res.address,\r\n latitude: res.latitude,\r\n longitude: res.longitude\r\n });\r\n \r\n // 统一返回格式\r\n const result = {\r\n name: res.name, // 位置名称\r\n address: res.address, // 详细地址\r\n latitude: res.latitude, // 纬度\r\n longitude: res.longitude, // 经度\r\n errMsg: 'chooseLocation:ok'\r\n };\r\n \r\n options.success?.(result);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信位置选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n };\r\n \r\n // 构建微信 chooseLocation 参数\r\n const weixinParams = {};\r\n \r\n // 微信支持 latitude 和 longitude 参数\r\n if (options.latitude !== null && options.latitude !== undefined) {\r\n weixinParams.latitude = options.latitude;\r\n }\r\n if (options.longitude !== null && options.longitude !== undefined) {\r\n weixinParams.longitude = options.longitude;\r\n }\r\n \r\n window.wx.chooseLocation({\r\n ...weixinParams,\r\n success: wxOptions.success,\r\n fail: wxOptions.fail,\r\n complete: wxOptions.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的位置选择(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用位置选择', options);\r\n \r\n // 构建 UniApp API 参数(不使用超时清理)\r\n const uniOptions = {\r\n // 禁用超时清理,等待用户操作完成后才清理\r\n disableTimeout: true,\r\n success: (res) => {\r\n apiLogger.info('UniApp 位置选择成功', { \r\n name: res?.name,\r\n address: res?.address,\r\n latitude: res?.latitude,\r\n longitude: res?.longitude\r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 位置选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n };\r\n \r\n // 构建 UniApp chooseLocation 参数\r\n if (options.latitude !== null && options.latitude !== undefined) {\r\n uniOptions.latitude = options.latitude;\r\n }\r\n if (options.longitude !== null && options.longitude !== undefined) {\r\n uniOptions.longitude = options.longitude;\r\n }\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('chooseLocation', uniOptions, {\r\n success: (res) => {\r\n uniOptions.success(res);\r\n },\r\n fail: (error) => {\r\n uniOptions.fail(error);\r\n },\r\n complete: uniOptions.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 选择位置(统一入口)\r\n * \r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.latitude] - 目标地纬度\r\n * @param {number} [options.longitude] - 目标地经度\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.chooseLocation({\r\n * success: (res) => {\r\n * console.log('位置名称:', res.name);\r\n * console.log('详细地址:', res.address);\r\n * console.log('纬度:', res.latitude);\r\n * console.log('经度:', res.longitude);\r\n * },\r\n * fail: (error) => {\r\n * console.error('选择失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 指定目标地中心点\r\n * qsh.chooseLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * success: (res) => {\r\n * console.log('已选择:', res.name);\r\n * }\r\n * });\r\n */\r\nexport function chooseLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持位置选择功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持位置选择', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始选择位置', {\r\n platform: environment.type,\r\n latitude: normalizedOptions.latitude,\r\n longitude: normalizedOptions.longitude\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n chooseLocationInWeixin(normalizedOptions);\r\n } else {\r\n chooseLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'chooseLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的位置选择\r\n * \r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const location = await qsh.chooseLocationAsync();\r\n * console.log('位置名称:', location.name);\r\n * console.log('详细地址:', location.address);\r\n * console.log('坐标:', location.latitude, location.longitude);\r\n * } catch (error) {\r\n * if (error.errMsg.includes('cancel')) {\r\n * console.log('用户取消选择');\r\n * } else {\r\n * console.error('选择失败:', error);\r\n * }\r\n * }\r\n * \r\n * @example\r\n * // 指定目标地中心点\r\n * async function selectNearbyPlace() {\r\n * try {\r\n * const location = await qsh.chooseLocationAsync({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470\r\n * });\r\n * return location;\r\n * } catch (error) {\r\n * console.error('选择位置失败:', error);\r\n * throw error;\r\n * }\r\n * }\r\n */\r\nexport function chooseLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取位置选择功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getChooseLocationCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n * console.log('支持的特性:', capabilities.features);\r\n */\r\nexport function getChooseLocationCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n chooseLocation: true, // 支持位置选择\r\n centerPoint: true, // 支持指定中心点(latitude/longitude)\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}","/**\r\n * 能力适配注册表\r\n * 提供平台 -> 实现的映射,便于扩展和测试\r\n */\r\n\r\nconst registry = new Map();\r\n\r\n/**\r\n * 注册能力实现\r\n * @param {string} apiName API 名称\r\n * @param {Object<string, Function>} implementations 按环境类型映射的实现\r\n */\r\nexport function registerCapability(apiName, implementations = {}) {\r\n registry.set(apiName, implementations);\r\n}\r\n\r\n/**\r\n * 解析能力实现\r\n * @param {string} apiName API 名称\r\n * @param {string} environmentType 当前环境类型\r\n * @returns {Function|undefined}\r\n */\r\nexport function resolveCapability(apiName, environmentType) {\r\n const impls = registry.get(apiName);\r\n if (!impls) return undefined;\r\n return impls[environmentType] || impls.default;\r\n}\r\n\r\n/**\r\n * 调用能力实现\r\n * @param {string} apiName API 名称\r\n * @param {string} environmentType 当前环境类型\r\n * @param {...any} args 传递给实现的参数\r\n * @returns {any}\r\n */\r\nexport function invokeCapability(apiName, environmentType, ...args) {\r\n const impl = resolveCapability(apiName, environmentType);\r\n if (typeof impl !== 'function') {\r\n throw new Error(`[Capability] No implementation registered for ${apiName} under ${environmentType}`);\r\n }\r\n return impl(...args);\r\n}\r\n\r\n/**\r\n * 导出注册表快照(只读)\r\n */\r\nexport function getCapabilityRegistry() {\r\n return registry;\r\n}\r\n\r\n\r\n","/**\r\n * 微信分享 API 模块\r\n * 统一封装微信和 UniApp WebView 的分享能力\r\n */\r\n\r\nimport { getEnvironmentInfo, isWeixinMiniProgram } from \"../core/environment.js\";\r\nimport { ErrorHandler } from \"../core/error-handler.js\";\r\nimport { apiLogger } from \"../core/logger.js\";\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from \"../core/weixin-loader.js\";\r\nimport { callApiInWebView } from \"../core/webview-bridge.js\";\r\nimport { registerCapability, resolveCapability } from \"./capability-registry.js\";\r\n\r\n// ==================== 常量定义 ====================\r\n/**\r\n * 分享去向类型枚举\r\n */\r\nexport const shareToTypes = {\r\n 0: \"WXSceneSession\", // 聊天界面\r\n 1: \"WXSceneTimeline\", // 朋友圈\r\n};\r\n/**\r\n * 分享内容类型枚举\r\n */\r\nexport const shareValueTypes = {\r\n 0: \"图文/网页\",\r\n 1: \"纯文字\",\r\n 2: \"纯图片\",\r\n 3: \"音乐\",\r\n 4: \"视频\",\r\n 5: \"小程序\",\r\n};\r\n// ==================== 工具函数 ====================\r\n// ==================== 微信环境实现 ====================\r\n\r\nfunction toShareInWeixin(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n if (typeof window === \"undefined\" || !window.wx) {\r\n const error = { errMsg: \"微信JS-SDK未加载\", code: \"WEIXIN_SDK_NOT_LOADED\" };\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info(\"等待微信配置完成\");\r\n return waitForWeixinConfig().then(() => toShareInWeixin(options));\r\n }\r\n\r\n const normalized = normalizeWeixinOptions(options);\r\n if (!normalized.success) {\r\n const error = { errMsg: normalized.message || \"参数校验失败\", code: \"INVALID_PARAMS\" };\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const params = normalized.params;\r\n apiLogger.debug(\"调用微信分享\", params);\r\n\r\n return new Promise((resolve, reject) => {\r\n window.wx[params.scene]({\r\n ...params,\r\n success: () => {\r\n const result = { errMsg: \"weixinShare:ok\" };\r\n options.success?.(result);\r\n resolve(result);\r\n },\r\n fail: (error) => {\r\n const wrappedError = { errMsg: error?.errMsg || \"weixinShare:fail\", details: error };\r\n apiLogger.error(\"微信分享失败\", wrappedError);\r\n options.fail?.(wrappedError);\r\n reject(wrappedError);\r\n },\r\n complete: options.complete,\r\n });\r\n });\r\n },\r\n {\r\n context: \"toShareInWeixin\",\r\n platform: \"weixin\",\r\n }\r\n );\r\n}\r\n\r\nfunction normalizeWeixinOptions(options = {}) {\r\n const normalized = { ...options };\r\n const params = {\r\n scene: normalized.scene === 1 ? \"updateTimelineShareData\" : \"updateAppMessageShareData\",\r\n };\r\n apiLogger.info(\"格式化微信参数\", normalized);\r\n\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"title\")) {\r\n return { message: \"参数字段title值缺少!\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"imageUrl\")) {\r\n return { message: \"参数字段imageUrl值缺少!\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"path\")) {\r\n return { message: \"参数字段path值缺少!\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"summary\")) {\r\n return { message: \"参数字段summary值缺少!\", success: false };\r\n }\r\n\r\n params.title = normalized.title;\r\n params.imgUrl = normalized.imageUrl;\r\n params.link = normalized.path;\r\n params.desc = normalized.summary;\r\n\r\n return { params, success: true };\r\n}\r\n// ==================== UniApp 环境实现 ====================\r\nfunction toShareInUniApp(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n apiLogger.debug(\"通过 WebView 桥接调用微信分享\", options);\r\n\r\n return new Promise((resolve, reject) => {\r\n callApiInWebView(\"toShareData\", options, {\r\n success: res => {\r\n options.success?.(res);\r\n resolve(res);\r\n },\r\n fail: error => {\r\n apiLogger.error(\"UniApp 微信分享失败\", error);\r\n options.fail?.(error);\r\n reject(error);\r\n },\r\n complete: options.complete,\r\n });\r\n });\r\n },\r\n {\r\n context: \"toShareInUniApp\",\r\n platform: \"uniapp\",\r\n }\r\n );\r\n}\r\nfunction normalizeUniAppOptions(options = {}) {\r\n const normalized = { ...options };\r\n const params = {\r\n provider: \"weixin\",\r\n scene: \"WXSceneSession\",\r\n };\r\n apiLogger.info(\"格式化 UniApp 参数\", normalized);\r\n // 确保scene(分享去向)是可枚举类型 0: 聊天框 1:朋友圈\r\n if ([0, 1].some(item => parseInt(item) === parseInt(normalized.scene))) {\r\n params.scene = shareToTypes[normalized.scene];\r\n } else {\r\n // 否则默认聊天框\r\n params.scene = \"WXSceneSession\";\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"type\")) {\r\n const typeValue = Number(normalized.type);\r\n // 确保type(分享内容)是可枚举类型 0:图文 1:文字 2:图片 5:小程序\r\n const types = Object.keys(shareValueTypes);\r\n if (types.some(item => parseInt(item) === typeValue)) {\r\n params.type = typeValue;\r\n if ([0].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"path\")) {\r\n params.href = normalized.path;\r\n } else {\r\n return { message: `参数字段path值缺少!`, success: false };\r\n }\r\n }\r\n if ([0, 1].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"summary\")) {\r\n params.summary = normalized.summary;\r\n } else {\r\n return { message: `参数字段summary值缺少!`, success: false };\r\n }\r\n }\r\n if ([0, 2, 5].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"imageUrl\")) {\r\n params.imageUrl = normalized.imageUrl;\r\n } else {\r\n return { message: `参数字段imageUrl值缺少!`, success: false };\r\n }\r\n }\r\n if ([5].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"miniProgram\")) {\r\n const miniProgram = { ...normalized.miniProgram };\r\n // if()\r\n //\r\n }\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"title\")) {\r\n params.title = normalized.title;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"success\")) {\r\n params.success = normalized.success;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"fail\")) {\r\n params.fail = normalized.fail;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"complete\")) {\r\n params.complete = normalized.complete;\r\n }\r\n } else {\r\n return { message: `参数字段type值有误!`, success: false };\r\n }\r\n } else {\r\n return { message: `参数字段type缺少!`, success: false };\r\n }\r\n return { params, success: true };\r\n}\r\n// ==================== 公共 API ====================\r\n\r\nconst SHARE_CAPABILITY_KEY = \"share.toShare\";\r\n\r\nregisterCapability(SHARE_CAPABILITY_KEY, {\r\n weixin: toShareInWeixin,\r\n webview: toShareInUniApp,\r\n plus: toShareInUniApp,\r\n nvue: toShareInUniApp,\r\n uvue: toShareInUniApp,\r\n UniApp: toShareInUniApp,\r\n h5: toShareInUniApp,\r\n default: undefined\r\n});\r\n\r\n/**\r\n * 微信分享(统一入口)\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShare(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n const env = getEnvironmentInfo();\r\n const impl = resolveCapability(SHARE_CAPABILITY_KEY, env.type);\r\n\r\n if (typeof impl !== \"function\") {\r\n const error = {\r\n errMsg: `当前环境 (${env.type}) 不支持微信分享功能`,\r\n code: \"PLATFORM_NOT_SUPPORTED\",\r\n };\r\n apiLogger.error(\"平台不支持微信分享\", { platform: env.type });\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const normalized = isWeixinMiniProgram()\r\n ? normalizeWeixinOptions(options)\r\n : normalizeUniAppOptions(options);\r\n\r\n if (!normalized.success) {\r\n const error = { errMsg: normalized.message || \"参数校验失败\", code: \"INVALID_PARAMS\" };\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const params = normalized.params;\r\n apiLogger.info(\"开始微信分享\", { platform: env.type, type: params?.type });\r\n return impl(params);\r\n },\r\n {\r\n context: \"toShare\",\r\n options,\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Promise 版本\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShareAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n toShare({\r\n ...options,\r\n success: resolve,\r\n fail: reject,\r\n });\r\n });\r\n}\r\n","/**\r\n * 蓝牙 API 模块\r\n * 统一封装微信和 UniApp 的蓝牙功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 蓝牙状态枚举\r\n */\r\nexport const BluetoothStates = {\r\n OFF: 'off', // 蓝牙关闭\r\n ON: 'on', // 蓝牙开启\r\n UNAVAILABLE: 'unavailable', // 不支持蓝牙\r\n UNAUTHORIZED: 'unauthorized' // 未授权\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n allowDuplicatesKey: false, // 是否允许重复上报同一设备\r\n services: [] // 指定服务 UUID 列表\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\nfunction normalizeOptions(options = {}) {\r\n return { ...DEFAULT_OPTIONS, ...options };\r\n}\r\n\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\nfunction openBluetoothAdapterInWeixin(options) {\r\n return ErrorHandler.safeExecute(async () => {\r\n if (!window.wx) {\r\n const error = { errMsg: '微信JS-SDK未加载', code: 'WEIXIN_SDK_NOT_LOADED' };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n await waitForWeixinConfig();\r\n }\r\n\r\n // 初始化蓝牙模块\r\n wx.openBluetoothAdapter({\r\n success: () => {\r\n apiLogger.info('微信蓝牙适配器已打开');\r\n onBluetoothDeviceFound(options);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('蓝牙适配器打开失败', error);\r\n options.fail?.(error);\r\n }\r\n });\r\n }, { context: 'openBluetoothAdapterInWeixin' });\r\n}\r\n\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\nfunction bluetoothInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙功能', options);\r\n callApiInWebView('bluetooth', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 蓝牙调用成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 蓝牙调用失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }, { context: 'bluetoothInUniApp' });\r\n}\r\n\r\n/**\r\n * 在 UniApp(WebView)中开始搜索蓝牙设备\r\n * \r\n * @param {Object} options - 搜索参数\r\n */\r\nfunction startBluetoothDevicesDiscoveryInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙设备搜索功能', options);\r\n callApiInWebView('bluetoothDevicesDiscovery', {\r\n action: 'startBluetoothDevicesDiscovery',\r\n params: {\r\n services: options.services || [],\r\n allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n console.log('[Bluetooth] 设备开启搜索成功:', res);\r\n apiLogger.info('UniApp 蓝牙设备开启搜索成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 设备开启搜索失败:', error);\r\n apiLogger.error('UniApp 蓝牙设备开启搜索失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }, { context: 'startBluetoothDevicesDiscoveryInUniApp' });\r\n}\r\n/**\r\n * 在 UniApp(WebView)中开始搜索蓝牙设备\r\n * \r\n * @param {Object} options - 搜索参数\r\n */\r\n// function onBluetoothDeviceFoundInUniApp(options) {\r\n// return ErrorHandler.safeExecute(() => {\r\n// apiLogger.debug('通过 WebView 桥接调用蓝牙设备搜索功能', options);\r\n// callApiInWebView('onBluetoothDeviceFound', {\r\n// action: 'onBluetoothDeviceFound',\r\n// isPersistent: true, // ✅ 添加此字段,告诉桥接层不要清理\r\n// params: {\r\n// services: options.services || [],\r\n// allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n// }\r\n// }, {\r\n// success: (res) => {\r\n// console.log('[Bluetooth] 设备搜索成功:', res);\r\n// apiLogger.info('UniApp 蓝牙设备搜索成功', res);\r\n// options.success?.(res);\r\n// },\r\n// fail: (error) => {\r\n// console.error('[Bluetooth] 设备搜索失败:', error);\r\n// apiLogger.error('UniApp 蓝牙设备搜索失败', error);\r\n// options.fail?.(error);\r\n// },\r\n// complete: options.complete\r\n// });\r\n// }, { context: 'onBluetoothDeviceFoundInUniApp' });\r\n// }\r\n\r\nconst bluetoothDeviceFoundCallbacks = new Set();\r\n\r\nfunction onBluetoothDeviceFoundInUniApp(callback, options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // ✅ 保存用户的真实回调\r\n bluetoothDeviceFoundCallbacks.add(callback);\r\n\r\n // ✅ 只有第一次注册时,启动监听\r\n if (bluetoothDeviceFoundCallbacks.size === 1) {\r\n callApiInWebView('onBluetoothDeviceFound', {\r\n action: 'onBluetoothDeviceFound',\r\n isPersistent: true,\r\n params: {\r\n services: options.services || [],\r\n allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n bluetoothDeviceFoundCallbacks.forEach(cb => {\r\n if (typeof cb === 'function') {\r\n ErrorHandler.safeExecute(() => cb(res), { context: 'BluetoothDeviceCallback' });\r\n } else {\r\n console.warn('[BluetoothDeviceCallback] 不是函数:', cb);\r\n }\r\n });\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 搜索失败:', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }\r\n\r\n // ✅ 返回取消订阅函数\r\n return () => bluetoothDeviceFoundCallbacks.delete(callback);\r\n }, { context: 'qsh_onBluetoothDeviceFound' });\r\n}\r\n\r\n\r\n/**\r\n * 在 UniApp/WebView 环境中创建蓝牙连接\r\n * @param {Object} options - 参数对象\r\n * @param {string} options.deviceId - 蓝牙设备 ID(必填)\r\n * @param {boolean} [options.autoConnect=false] - 是否自动重连\r\n * @param {Function} [options.success] - 连接成功回调\r\n * @param {Function} [options.fail] - 连接失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nfunction createBLEConnectionInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙连接功能', options);\r\n\r\n callApiInWebView('bluetoothConnection', {\r\n action: 'createBLEConnection',\r\n params: {\r\n deviceId: options.deviceId,\r\n name: options.name,\r\n autoConnect: options.autoConnect ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n console.log('[Bluetooth] 蓝牙连接成功:', res);\r\n apiLogger.info('UniApp 蓝牙连接成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 蓝牙连接失败:', error);\r\n apiLogger.error('UniApp 蓝牙连接失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n\r\n }, { context: 'createBLEConnectionInUniApp' });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 初始化并搜索蓝牙设备\r\n * \r\n * @param {Object} [options] - 蓝牙参数\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报\r\n * @param {string[]} [options.services=[]] - 指定服务UUID列表\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nexport function openBluetoothAdapter(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n const normalizedOptions = normalizeOptions(options);\r\n apiLogger.info('开始蓝牙操作', {\r\n platform: environment.type,\r\n services: normalizedOptions.services,\r\n allowDuplicatesKey: normalizedOptions.allowDuplicatesKey\r\n });\r\n if (isWeixinMiniProgram()) {\r\n openBluetoothAdapterInWeixin(normalizedOptions);\r\n } else {\r\n bluetoothInUniApp(normalizedOptions);\r\n }\r\n }, { context: 'openBluetoothAdapter', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的蓝牙调用\r\n * \r\n * @param {Object} [options] - 参数(不包含回调函数)\r\n * @returns {Promise} 蓝牙调用结果 Promise\r\n */\r\nexport function openBluetoothAdapterAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openBluetoothAdapter({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n/**\r\n * 开始搜索蓝牙设备\r\n *\r\n * @param {Object} [options] - 蓝牙搜索参数\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报同一设备\r\n * @param {string[]} [options.services=[]] - 指定服务 UUID 列表\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nexport function startBluetoothDevicesDiscovery(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n\r\n // 3️⃣ 记录日志\r\n apiLogger.info('开始搜索蓝牙设备', {\r\n platform: environment.type,\r\n services: normalizedOptions.services,\r\n allowDuplicatesKey: normalizedOptions.allowDuplicatesKey\r\n });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n startBluetoothDevicesDiscoveryInWeixin(normalizedOptions);\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n startBluetoothDevicesDiscoveryInUniApp(normalizedOptions);\r\n }\r\n }, { context: 'startBluetoothDevicesDiscovery', options });\r\n}\r\n/**\r\n * Promise 版本的蓝牙调用\r\n * \r\n * @param {Object} [options] - 参数(不包含回调函数)\r\n * @returns {Promise} 蓝牙调用结果 Promise\r\n */\r\nexport function startBluetoothDevicesDiscoveryAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n startBluetoothDevicesDiscovery({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 监听蓝牙设备发现事件\r\n *\r\n * @param {Object} [options] - 蓝牙监听参数\r\n * @param {Function} [options.success] - 每次发现设备时回调,参数为设备数组\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调(出错或注册成功均调用)\r\n */\r\nexport function onBluetoothDeviceFound(callback, options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n\r\n // 3️⃣ 日志记录\r\n apiLogger.info('注册蓝牙设备发现监听', { platform: environment.type });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n onBluetoothDeviceFoundInWeixin(normalizedOptions);\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n onBluetoothDeviceFoundInUniApp(callback, normalizedOptions);\r\n }\r\n }, { context: 'onBluetoothDeviceFound', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的蓝牙设备发现监听\r\n * 第一次触发 resolve,后续通过 success 回调继续处理\r\n *\r\n * @returns {Promise<Array>} 首次发现的设备列表\r\n */\r\nexport function onBluetoothDeviceFoundAsync() {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n onBluetoothDeviceFound({\r\n success: resolve,\r\n fail: reject\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n/**\r\n * 创建蓝牙连接\r\n * @param {Object} options - 参数对象\r\n * @param {string} options.deviceId - 蓝牙设备 ID(必填)\r\n * @param {boolean} [options.autoConnect=false] - 是否自动重连\r\n * @param {Function} [options.success] - 连接成功回调\r\n * @param {Function} [options.fail] - 连接失败回调\r\n * @param {Function} [options.complete] - 完成回调(无论成功失败都会调用)\r\n */\r\nexport function createBLEConnection(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙连接', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n const { name, deviceId, autoConnect = false } = normalizedOptions;\r\n\r\n if (!deviceId) {\r\n const error = { errMsg: '缺少 deviceId 参数', code: 'INVALID_PARAMS' };\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 3️⃣ 日志记录\r\n apiLogger.info('创建蓝牙连接', { deviceId, autoConnect, platform: environment.type });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n uni.createBLEConnection({\r\n deviceId,\r\n autoConnect,\r\n success: options.success,\r\n fail: options.fail,\r\n complete: options.complete\r\n });\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n // 假设你有一个封装的原生调用方法\r\n createBLEConnectionInUniApp(normalizedOptions);\r\n }\r\n\r\n }, { context: 'createBLEConnection', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的创建蓝牙连接\r\n * 第一次成功连接触发 resolve,后续通过 success 回调继续处理\r\n *\r\n * @param {Object} options - 参数\r\n * @param {string} options.deviceId - 蓝牙设备 id\r\n * @param {boolean} [options.autoConnect=false] - 是否自动连接\r\n * @returns {Promise<Object>} 首次连接成功的设备信息\r\n */\r\nexport function createBLEConnectionAsync(options) {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n createBLEConnection({\r\n ...options,\r\n success: (res) => {\r\n resolve(res); // 首次成功连接触发 resolve\r\n // 后续逻辑可通过 options.success 或其他回调处理\r\n if (typeof options.success === 'function') {\r\n options.success(res);\r\n }\r\n },\r\n fail: (err) => {\r\n reject(err);\r\n if (typeof options.fail === 'function') {\r\n options.fail(err);\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * 获取蓝牙功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n */\r\nexport function getBluetoothCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n discovery: true,\r\n connect: true,\r\n readWrite: true,\r\n notify: true,\r\n asyncSupport: true\r\n }\r\n };\r\n}\r\n","/**\r\n * 打印PDF API 模块\r\n * 统一封装微信和UniApp的打印PDF功能\r\n */\r\n\r\nimport { environment } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n // TODO: 添加更多默认配置\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // TODO: 参数验证和标准化\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持打印\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['webview','UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的打印PDF(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction printPdfInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用打印PDF', options);\r\n \r\n // 通过桥接层调用,禁用超时自动清理\r\n callApiInWebView('printPdf', {\r\n ...options,\r\n isPersistent: true // 强制禁用超时自动清理\r\n }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 打印PDF成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 打印PDF失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'printPdfInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 打印PDF(统一入口)\r\n * \r\n * @param {Object} [options] - 打印PDF参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * qsh.printPdf({\r\n * success: (res) => console.log('打印PDF成功'),\r\n * fail: (error) => console.error('打印PDF失败:', error)\r\n * });\r\n */\r\nexport function printPdf(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持打印PDF功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持打印PDF', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始打印PDF', { platform: environment.type });\r\n\r\n // 只支持 APP 端,通过 WebView 桥接调用\r\n printPdfInUniApp(normalizedOptions);\r\n \r\n }, { \r\n context: 'printPdf',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的打印PDF\r\n * \r\n * @param {Object} [options] - 打印PDF参数(不包含回调函数)\r\n * @returns {Promise} 打印PDF结果的Promise\r\n * \r\n * @example\r\n * try {\r\n * await qsh.printPdfAsync();\r\n * console.log('打印PDF成功');\r\n * } catch (error) {\r\n * console.error('打印PDF失败:', error);\r\n * }\r\n */\r\nexport function printPdfAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n printPdf({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取打印PDF功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getPrintCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n */\r\nexport function getPrintCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: 'uniapp',\r\n features: {\r\n asyncSupport: true\r\n }\r\n };\r\n}\r\n","/**\r\n * 人脸识别 API 模块\r\n * 仅支持微信小程序环境\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\n\r\n// ==================== 工具函数 ====================\r\n\r\nconst FACE_PAGE_PATH = '/pages/face/index';\r\n\r\n/**\r\n * 标准化人脸识别参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...options };\r\n\r\n // 验证 name\r\n if (!normalized.name || typeof normalized.name !== 'string' || !normalized.name.trim()) {\r\n throw {\r\n errMsg: '缺少必需参数:name(姓名)',\r\n code: 'PARAM_MISSING'\r\n };\r\n }\r\n normalized.name = normalized.name.trim();\r\n\r\n // 验证 idCardNumber\r\n if (!normalized.idCardNumber || typeof normalized.idCardNumber !== 'string' || !normalized.idCardNumber.trim()) {\r\n throw {\r\n errMsg: '缺少必需参数:idCardNumber(身份证号)',\r\n code: 'PARAM_MISSING'\r\n };\r\n }\r\n normalized.idCardNumber = normalized.idCardNumber.trim();\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持人脸识别(仅微信小程序环境)\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n return isWeixinMiniProgram();\r\n}\r\n\r\nfunction isMiniProgramNavigateAvailable() {\r\n return (\r\n typeof window !== 'undefined' &&\r\n window.wx &&\r\n window.wx.miniProgram &&\r\n typeof window.wx.miniProgram.navigateTo === 'function'\r\n );\r\n}\r\n\r\nfunction buildFacePageUrl(options) {\r\n const params = {\r\n ...options,\r\n title: document.title || '',\r\n url: window.location.href || ''\r\n };\r\n\r\n const query = Object.entries(params)\r\n .filter(([, value]) => value !== undefined && value !== null && value !== '')\r\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\r\n .join('&');\r\n\r\n return query ? `${FACE_PAGE_PATH}?${query}` : FACE_PAGE_PATH;\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的人脸识别\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction faceVerifyInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!isMiniProgramNavigateAvailable()) {\r\n apiLogger.error('微信小程序导航API不可用');\r\n return;\r\n }\r\n\r\n const targetUrl = buildFacePageUrl(options);\r\n\r\n apiLogger.debug('跳转宿主人脸识别页面', {\r\n name: options.name,\r\n targetUrl\r\n });\r\n\r\n window.wx.miniProgram.navigateTo({\r\n url: targetUrl,\r\n success: () => {\r\n apiLogger.info('已跳转到宿主人脸识别页面', { targetUrl });\r\n },\r\n fail: (error) => {\r\n apiLogger.error('跳转宿主人脸识别页面失败', error);\r\n }\r\n });\r\n\r\n }, {\r\n context: 'faceVerifyInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 人脸识别(统一入口)\r\n * 只发送请求,不返回任何结果给调用者\r\n *\r\n * @param {Object} options - 人脸识别参数\r\n * @param {string} options.name - 姓名(必填)\r\n * @param {string} options.idCardNumber - 身份证号(必填)\r\n * @returns {void}\r\n *\r\n * @example\r\n * qsh.faceVerify({\r\n * name: '张三',\r\n * idCardNumber: '110101199001011234'\r\n * });\r\n */\r\nexport function faceVerify(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n apiLogger.error('平台不支持人脸识别', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 标准化参数(含参数校验)\r\n let normalizedOptions;\r\n try {\r\n normalizedOptions = normalizeOptions(options);\r\n } catch (error) {\r\n apiLogger.error('人脸识别参数校验失败', error);\r\n return;\r\n }\r\n\r\n apiLogger.info('开始人脸识别', {\r\n platform: environment.type,\r\n name: normalizedOptions.name,\r\n pagePath: FACE_PAGE_PATH\r\n });\r\n\r\n // 调用微信实现\r\n faceVerifyInWeixin(normalizedOptions);\r\n\r\n }, {\r\n context: 'faceVerify',\r\n options\r\n });\r\n}\r\n\r\n/**\r\n * 获取人脸识别功能能力信息\r\n *\r\n * @returns {Object} 能力信息\r\n *\r\n * @example\r\n * const capabilities = qsh.getFaceCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n */\r\nexport function getFaceCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: 'weixin',\r\n features: {\r\n asyncSupport: true,\r\n hostPageNavigation: true\r\n }\r\n };\r\n}\r\n","/*\r\n * @Description: \r\n * @Author: TK\r\n * @Date: 2025-08-06 09:54:28\r\n * @LastEditors: sqian0625 460635145@qq.com\r\n * @LastEditTime: 2025-10-17 16:03:18\r\n */\r\n/**\r\n * UniApp WebView SDK\r\n * 支持微信小程序和 APP 端的 WebView 通信\r\n */\r\n\r\n// 导入核心模块\r\nimport { waitForBridge, initBridge, isBridgeReady } from './core/bridge.js';\r\nimport { getEnvironmentInfo } from './core/environment.js';\r\nimport { \r\n loadWeixinJSSDKIfNeeded, \r\n configureWeixin,\r\n waitForWeixinConfig,\r\n isWeixinConfigReady,\r\n getWeixinConfigState,\r\n getWeixinConfigManager,\r\n retryWeixinConfig\r\n} from './core/weixin-loader.js';\r\nimport stateManager, { waitForReady, isReady, getState } from './core/state-manager.js';\r\nimport Logger from './core/logger.js';\r\nimport { ErrorHandler } from './core/error-handler.js';\r\nimport pluginManager from './core/plugin-manager.js';\r\nimport interceptorChain, { loggingInterceptor, performanceInterceptor, createRetryInterceptor, createValidationInterceptor } from './core/interceptor.js';\r\nimport stateStore from './core/state-store.js';\r\nimport { ErrorCodes, ErrorMessages, ErrorCategory } from './core/error-codes.js';\r\nimport { errorNormalizerInterceptor, normalizeError, createError, isStandardError } from './core/error-normalizer.js';\r\nimport { runInitPipeline } from './core/init-pipeline.js';\r\n\r\n// 惰性获取环境信息(缓存),避免在 SSR 场景访问不存在的全局对象\r\nconst environment = getEnvironmentInfo();\r\n\r\nfunction shouldWaitForWeixinConfigInReady() {\r\n if (typeof window === 'undefined') {\r\n return false;\r\n }\r\n\r\n const runtimeEnvironment = getEnvironmentInfo(true);\r\n if (!runtimeEnvironment.isWeixinMiniProgram) {\r\n return false;\r\n }\r\n\r\n const runtimeConfig = getWeixinConfigManager().getRuntimeConfig();\r\n return typeof runtimeConfig.clientId === 'string' && runtimeConfig.clientId.length > 0;\r\n}\r\n\r\nasync function readySDK() {\r\n await waitForBridge();\r\n\r\n if (!shouldWaitForWeixinConfigInReady()) {\r\n return;\r\n }\r\n\r\n await waitForWeixinConfig();\r\n}\r\n\r\n// 导入 API 模块(以 raw 别名保留原始实现)\r\nimport {\r\n navigateTo as rawNavigateTo,\r\n navigateBack as rawNavigateBack,\r\n switchTab as rawSwitchTab,\r\n reLaunch as rawReLaunch,\r\n redirectTo as rawRedirectTo\r\n} from './api/navigation.js';\r\n\r\nimport {\r\n postMessage as rawPostMessage,\r\n getEnv as rawGetEnv\r\n} from './api/message.js';\r\n\r\nimport {\r\n chooseImage as rawChooseImage,\r\n chooseImageAsync as rawChooseImageAsync,\r\n getImageCapabilities,\r\n ImageSourceTypes,\r\n ImageSizeTypes\r\n} from './api/image.js';\r\n\r\nimport {\r\n scanCode as rawScanCode,\r\n scanCodeAsync as rawScanCodeAsync,\r\n getScanCapabilities,\r\n ScanTypes\r\n} from './api/scan.js';\r\n\r\nimport {\r\n getLocation as rawGetLocation,\r\n getLocationAsync as rawGetLocationAsync,\r\n openLocation as rawOpenLocation,\r\n openLocationAsync as rawOpenLocationAsync,\r\n getLocationCapabilities,\r\n CoordinateTypes,\r\n onLocationChange as rawOnLocationChange,\r\n offLocationChange as rawOffLocationChange,\r\n onLocationChangeError as rawOnLocationChangeError,\r\n offLocationChangeError as rawOffLocationChangeError,\r\n startLocationUpdate as rawStartLocationUpdate,\r\n stopLocationUpdate as rawStopLocationUpdate\r\n} from './api/location.js';\r\n\r\nimport {\r\n chooseLocation as rawChooseLocation,\r\n chooseLocationAsync as rawChooseLocationAsync,\r\n getChooseLocationCapabilities\r\n} from './api/choose.js';\r\n\r\n\r\nimport { toShare as rawToShare, toShareAsync as rawToShareAsync } from \"./api/share.js\";\r\n\r\nimport {\r\n openBluetoothAdapter as rawOpenBluetooth,\r\n openBluetoothAdapterAsync as rawOpenBluetoothAsync,\r\n startBluetoothDevicesDiscovery as rawBluetoothDevicesDiscovery,\r\n startBluetoothDevicesDiscoveryAsync as rawBluetoothDevicesDiscoveryAsync,\r\n onBluetoothDeviceFound as rawOnBluetoothDeviceFound,\r\n onBluetoothDeviceFoundAsync as rawOnBluetoothDeviceFoundAsync,\r\n createBLEConnection as rawCreateBLEConnection,\r\n createBLEConnectionAsync as rawCreateBLEConnectionAsync,\r\n getBluetoothCapabilities,\r\n BluetoothStates\r\n} from './api/bluetooth.js';\r\n\r\nimport {\r\n printPdf as rawPrintPdf,\r\n printPdfAsync as rawPrintPdfAsync,\r\n getPrintCapabilities\r\n} from './api/print.js';\r\n\r\nimport {\r\n faceVerify as rawFaceVerify,\r\n getFaceCapabilities\r\n} from './api/face.js';\r\n// 平台特定 API 不在此处直接导入,按需在各模块内处理\r\n\r\n// 注册内置错误标准化拦截器(最高优先级)\r\ninterceptorChain.useResponse(errorNormalizerInterceptor.response, { priority: 1000 });\r\n\r\n// 自动初始化逻辑 - 确保在 DOM 准备好后初始化\r\nlet autoInitStarted = false;\r\n\r\nfunction startAutoInit() {\r\n if (autoInitStarted) return;\r\n autoInitStarted = true;\r\n\r\n const initTasks = [\r\n { name: 'load-weixin-sdk', run: loadWeixinJSSDKIfNeeded, timeoutMs: 8000 },\r\n { name: 'init-bridge', run: initBridge, timeoutMs: 8000 }\r\n ];\r\n\r\n runInitPipeline(initTasks, {\r\n onError: (error, step) => {\r\n console.error(`[QSH-SDK] 初始化失败(${step?.name || 'unknown'}):`, error);\r\n }\r\n });\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n if (document.readyState === 'complete' || document.readyState === 'interactive') {\r\n setTimeout(startAutoInit, 0);\r\n } else {\r\n document.addEventListener('DOMContentLoaded', startAutoInit);\r\n }\r\n}\r\n\r\n// 封装:自动等待 Bridge 就绪后再调用(可等待、兼容回调)\r\nfunction ensureReadyInvoke(apiFn, { apiName } = {}) {\r\n return function(options = {}, ...rest) {\r\n const hasCallbacks = options && typeof options === 'object' && (\r\n typeof options.success === 'function' ||\r\n typeof options.fail === 'function' ||\r\n typeof options.complete === 'function'\r\n );\r\n const normalizedOptions = options && typeof options === 'object' ? options : {};\r\n\r\n const execute = () => {\r\n if (hasCallbacks) {\r\n return apiFn(normalizedOptions, ...rest);\r\n }\r\n\r\n // Promise 化:当未提供回调时,返回一个可等待的 Promise\r\n return new Promise((resolve, reject) => {\r\n const wrapped = {\r\n ...normalizedOptions,\r\n success: (res) => {\r\n if (typeof normalizedOptions.success === 'function') {\r\n normalizedOptions.success(res);\r\n }\r\n resolve(res);\r\n },\r\n fail: (err) => {\r\n if (typeof normalizedOptions.fail === 'function') {\r\n normalizedOptions.fail(err);\r\n }\r\n reject(err);\r\n },\r\n complete: normalizedOptions.complete\r\n };\r\n apiFn(wrapped, ...rest);\r\n });\r\n };\r\n\r\n const readyPromise = (typeof window === 'undefined') ? Promise.resolve() : waitForReady();\r\n\r\n return readyPromise\r\n .then(() => execute())\r\n .catch(error => {\r\n console.error(`[QSH-SDK] ${apiName || 'API'} call failed:`, error);\r\n throw error;\r\n });\r\n };\r\n}\r\n\r\nfunction normalizeCallbackOptions(input) {\r\n if (typeof input === 'function') {\r\n return { success: input };\r\n }\r\n if (input && typeof input === 'object') {\r\n return input;\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * 导航到新页面\r\n * @param {Object} options - 导航参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateTo({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nconst navigateTo = ensureReadyInvoke(rawNavigateTo);\r\n/**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回参数\r\n * @param {number} [options.delta=1] - 返回的页面层级数\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateBack({ delta: 1 })\r\n * @since 2.0.0\r\n */\r\nconst navigateBack = ensureReadyInvoke(rawNavigateBack);\r\n/**\r\n * 切换至 Tab 页面\r\n * @param {Object} options - 切换参数\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.switchTab({ url: '/pages/tabbar/home' })\r\n * @since 2.0.0\r\n */\r\nconst switchTab = ensureReadyInvoke(rawSwitchTab);\r\n/**\r\n * 关闭所有页面并打开到应用内某页面\r\n * @param {Object} options - 打开参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.reLaunch({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nconst reLaunch = ensureReadyInvoke(rawReLaunch);\r\n/**\r\n * 关闭当前页面并跳转到应用内某页面\r\n * @param {Object} options - 跳转参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.redirectTo({ url: '/pages/detail/index' })\r\n * @since 2.0.0\r\n */\r\nconst redirectTo = ensureReadyInvoke(rawRedirectTo);\r\n/**\r\n * 发送消息至原生容器\r\n * @param {Object} [options] - 消息参数\r\n * @param {any} [options.data] - 需要透传的数据对象\r\n * @returns {void}\r\n * @example\r\n * qsh.postMessage({ data: { foo: 'bar' } })\r\n * @since 2.0.0\r\n */\r\nconst postMessage = ensureReadyInvoke(rawPostMessage);\r\n\r\n/**\r\n * 获取当前运行环境信息(回调形式)\r\n * 注意:兼容旧版回调签名,内部会在 Bridge 就绪后再调用。\r\n * @param {Function} callback - 回调函数,入参为环境信息对象\r\n * @returns {void}\r\n * @example\r\n * qsh.getEnv((info) => { console.log(info.miniprogram) })\r\n * @since 2.0.0\r\n */\r\nfunction getEnv(callback) {\r\n const exec = () => rawGetEnv(callback);\r\n const readyPromise = (typeof window === 'undefined') ? Promise.resolve() : waitForReady();\r\n return readyPromise.then(() => exec());\r\n}\r\n\r\n/**\r\n * 选择图片\r\n * 统一封装微信和UniApp的图片选择功能,自动根据环境选择合适的实现\r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.count=9] - 最多选择的图片数量\r\n * @param {string[]} [options.sizeType] - 图片质量类型 ['original', 'compressed']\r\n * @param {string[]} [options.sourceType] - 图片来源类型 ['album', 'camera']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * @example\r\n * qsh.chooseImage({\r\n * count: 1,\r\n * success: (res) => console.log('选择的图片:', res)\r\n * })\r\n * @since 2.0.0\r\n */\r\nconst chooseImage = ensureReadyInvoke(rawChooseImage);\r\n\r\n/**\r\n * 选择图片(Promise版本)\r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * @example\r\n * const result = await qsh.chooseImageAsync({ count: 1 })\r\n * @since 2.0.0\r\n */\r\nfunction chooseImageAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseImage({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 打印\r\n * @param {Object} [options] - 打印参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * @example\r\n * qsh.printPdf({\r\n * success: (res) => console.log('打印PDF成功')\r\n * })\r\n * @since 2.0.0\r\n */\r\nconst printPdf = ensureReadyInvoke(rawPrintPdf);\r\n\r\n/**\r\n * 打印PDF(Promise版本)\r\n * @param {Object} [options] - 打印PDF参数(不包含回调函数)\r\n * @returns {Promise} 打印PDF结果的Promise\r\n * @example\r\n * await qsh.printPdfAsync()\r\n * @since 2.0.0\r\n */\r\nfunction printPdfAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n printPdf({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 扫码\r\n * @param {Object} [options] - 扫码参数\r\n * @param {boolean} [options.onlyFromCamera=true] - 是否只能从相机扫码\r\n * @param {string[]} [options.scanType] - 扫码类型 ['qrCode', 'barCode']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.scanCode({\r\n * success: (res) => console.log('扫码结果:', res.result)\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst scanCode = ensureReadyInvoke(rawScanCode);\r\n\r\n/**\r\n * 人脸识别(仅支持微信小程序环境)\r\n * 通过 wx.miniProgram.navigateTo 跳转宿主 /pages/face/index,不返回任何结果给调用者\r\n * @param {Object} options - 人脸识别参数\r\n * @param {string} options.name - 姓名(必填)\r\n * @param {string} options.idCardNumber - 身份证号(必填)\r\n * @returns {void}\r\n * @example\r\n * qsh.faceVerify({\r\n * name: '张三',\r\n * idCardNumber: '110101199001011234'\r\n * })\r\n */\r\nconst faceVerify = ensureReadyInvoke(rawFaceVerify);\r\n\r\n/**\r\n * 扫码(Promise版本)\r\n * @param {Object} [options] - 扫码参数(不包含回调函数)\r\n * @returns {Promise} 扫码结果的Promise\r\n * @example\r\n * const result = await qsh.scanCodeAsync({ scanType: ['qrCode'] })\r\n * @since 2.1.0\r\n */\r\nfunction scanCodeAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n scanCode({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n// /////////////////////////////////\r\n/**\r\n * \r\n * \r\n * \r\n */\r\n\r\nconst toShare = ensureReadyInvoke(rawToShare);\r\n\r\n// //////////////////////////////////////////////////////////\r\n\r\n/**\r\n * 获取当前位置\r\n * @param {Object} [options] - 定位参数\r\n * @param {string} [options.type='wgs84'] - 坐标类型\r\n * @param {boolean} [options.altitude=false] - 是否返回高度\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.getLocation({\r\n * type: 'gcj02',\r\n * success: (res) => console.log(res.latitude, res.longitude)\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst getLocationAPI = ensureReadyInvoke(rawGetLocation);\r\n\r\n/**\r\n * 获取位置(Promise版本)\r\n * @param {Object} [options] - 定位参数(不包含回调函数)\r\n * @returns {Promise} 定位结果的Promise\r\n * @example\r\n * const location = await qsh.getLocationAsync({ type: 'gcj02' })\r\n * @since 2.1.0\r\n */\r\nfunction getLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n getLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 查看位置\r\n * @param {Object} options - 位置参数\r\n * @param {number} options.latitude - 纬度(必填)\r\n * @param {number} options.longitude - 经度(必填)\r\n * @param {string} [options.name] - 位置名称\r\n * @param {string} [options.address] - 详细地址\r\n * @param {number} [options.scale=18] - 缩放级别\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门'\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst openLocationAPI = ensureReadyInvoke(rawOpenLocation);\r\n\r\n/**\r\n * 查看位置(Promise版本)\r\n * @param {Object} options - 位置参数(不包含回调函数)\r\n * @returns {Promise} 操作结果的Promise\r\n * @example\r\n * await qsh.openLocationAsync({ latitude: 39.908823, longitude: 116.397470 })\r\n * @since 2.1.0\r\n */\r\nfunction openLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 选择位置\r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.latitude] - 目标纬度(UniApp支持,微信不支持)\r\n * @param {number} [options.longitude] - 目标经度(UniApp支持,微信不支持)\r\n * @param {string} [options.keyword] - 搜索关键字(UniApp支持,微信不支持)\r\n * @param {string} [options.category] - POI分类(UniApp支持,微信不支持)\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.chooseLocation({\r\n * success: (res) => {\r\n * console.log('位置名称:', res.name)\r\n * console.log('详细地址:', res.address)\r\n * }\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst chooseLocationAPI = ensureReadyInvoke(rawChooseLocation);\r\n\r\n/**\r\n * 选择位置(Promise版本)\r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * @example\r\n * const location = await qsh.chooseLocationAsync({ keyword: '餐厅' })\r\n * @since 2.1.0\r\n */\r\nfunction chooseLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 蓝牙\r\n * @param {Object} [options] - 蓝牙参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.openBluetoothAdapter({\r\n * success: (res) => console.log('蓝牙设备:', res.devices)\r\n * })\r\n */\r\nconst openBluetoothAdapter = ensureReadyInvoke(rawOpenBluetooth);\r\n\r\n/**\r\n * 蓝牙(Promise版本)\r\n * @param {Object} [options] - 参数\r\n * @returns {Promise} 蓝牙结果 Promise\r\n */\r\nfunction openBluetoothAdapterAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openBluetoothAdapter({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 开始搜索蓝牙设备\r\n * @param {Object} [options] - 蓝牙搜索参数\r\n * @param {Array<string>} [options.services] - 蓝牙设备主服务 UUID 列表\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报同一设备\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.startBluetoothDevicesDiscovery({\r\n * services: ['FFF0'],\r\n * allowDuplicatesKey: false,\r\n * success: (res) => console.log('开始搜索蓝牙设备', res)\r\n * })\r\n */\r\nconst startBluetoothDevicesDiscovery = ensureReadyInvoke(rawBluetoothDevicesDiscovery);\r\n\r\n/**\r\n * 开始搜索蓝牙设备(Promise版本)\r\n * @param {Object} [options] - 参数\r\n * @returns {Promise} 蓝牙搜索结果 Promise\r\n */\r\nfunction startBluetoothDevicesDiscoveryAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n startBluetoothDevicesDiscovery({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n/**\r\n * 监听蓝牙设备发现事件(Callback 方式)\r\n * @param {Function} callback - 回调函数,每次发现设备时触发,参数为设备列表\r\n * @returns {void}\r\n * @example\r\n * qsh.onBluetoothDeviceFound((devices) => {\r\n * console.log('发现蓝牙设备:', devices)\r\n * })\r\n */\r\nconst onBluetoothDeviceFound = ensureReadyInvoke(rawOnBluetoothDeviceFound)\r\n\r\n/**\r\n * 监听蓝牙设备发现事件(Promise版本)\r\n * 第一次发现设备时 resolve,后续可通过回调继续处理\r\n * @returns {Promise<Array>} 发现的设备列表\r\n * @example\r\n * const devices = await qsh.onBluetoothDeviceFoundAsync()\r\n * console.log('首次发现设备:', devices)\r\n */\r\nfunction onBluetoothDeviceFoundAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n onBluetoothDeviceFound({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n })\r\n}\r\n\r\nconst createBLEConnection = ensureReadyInvoke(rawCreateBLEConnection);\r\n\r\n/**\r\n * 创建蓝牙连接(Promise 版本)\r\n * @param {Object} options - 参数\r\n * @param {string} options.deviceId - 蓝牙设备 id\r\n * @param {boolean} [options.autoConnect=false] - 是否自动连接\r\n * @returns {Promise} 连接结果 Promise\r\n */\r\nfunction createBLEConnectionAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n createBLEConnection({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n// 创建 uni 对象\r\nconst uni = {\r\n // 导航 API\r\n navigateTo,\r\n navigateBack,\r\n switchTab,\r\n reLaunch,\r\n redirectTo,\r\n \r\n // 消息 API\r\n postMessage,\r\n getEnv,\r\n \r\n // 图片 API\r\n chooseImage,\r\n chooseImageAsync,\r\n \r\n // 扫码 API\r\n scanCode,\r\n scanCodeAsync,\r\n \r\n // 位置 API\r\n getLocation: getLocationAPI,\r\n getLocationAsync: getLocationAsyncAPI,\r\n openLocation: openLocationAPI,\r\n openLocationAsync: openLocationAsyncAPI,\r\n chooseLocation: chooseLocationAPI,\r\n chooseLocationAsync: chooseLocationAsyncAPI,\r\n \r\n // 位置监听 API(保留回调签名)\r\n onLocationChange: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOnLocationChange(options.success);\r\n }, { apiName: 'onLocationChange' })(normalizeCallbackOptions(callback)),\r\n offLocationChange: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOffLocationChange(options.success);\r\n }, { apiName: 'offLocationChange' })(normalizeCallbackOptions(callback)),\r\n onLocationChangeError: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOnLocationChangeError(options.success);\r\n }, { apiName: 'onLocationChangeError' })(normalizeCallbackOptions(callback)),\r\n offLocationChangeError: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOffLocationChangeError(options.success);\r\n }, { apiName: 'offLocationChangeError' })(normalizeCallbackOptions(callback)),\r\n startLocationUpdate: ensureReadyInvoke(rawStartLocationUpdate, { apiName: 'startLocationUpdate' }),\r\n stopLocationUpdate: ensureReadyInvoke(rawStopLocationUpdate, { apiName: 'stopLocationUpdate' }),\r\n \r\n // 环境信息\r\n environment,\r\n \r\n /**\r\n * Wait for SDK readiness.\r\n * In Weixin mini-program web-view, if qsh.config({ clientId }) was called,\r\n * this also waits for wx.config to complete.\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.ready()\r\n * @since 2.0.0\r\n */\r\n ready: readySDK,\r\n \r\n /**\r\n * 手动初始化 JSBridge\r\n * 默认会在 DOM 就绪时自动初始化;如需更早或手动控制,可调用本方法。\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.init()\r\n * @since 2.0.0\r\n */\r\n init: initBridge,\r\n \r\n /**\r\n * 检查 JSBridge 是否就绪\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.isReady()) { console.log('ready') }\r\n * @since 2.0.0\r\n */\r\n isReady,\r\n \r\n /**\r\n * 获取当前 SDK 状态\r\n * @returns {string}\r\n * @example\r\n * console.log(qsh.getState()) // 'ready'\r\n * @since 2.0.0\r\n */\r\n getState,\r\n\r\n config: configureWeixin,\r\n\r\n // 微信配置 API\r\n weixin: {\r\n /**\r\n * 等待微信配置完成\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.weixin.waitForConfig()\r\n * @since 2.0.0\r\n */\r\n config: configureWeixin,\r\n waitForConfig: waitForWeixinConfig,\r\n \r\n /**\r\n * 检查微信配置是否完成\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.weixin.isConfigReady()) { wx.chooseImage({}) }\r\n * @since 2.0.0\r\n */\r\n isConfigReady: isWeixinConfigReady,\r\n \r\n /**\r\n * 获取微信配置状态\r\n * @returns {string}\r\n * @example\r\n * console.log(qsh.weixin.getConfigState()) // 'configured'\r\n * @since 2.0.0\r\n */\r\n getConfigState: getWeixinConfigState,\r\n \r\n /**\r\n * 手动重试微信配置\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.weixin.retryConfig()\r\n * @since 2.0.0\r\n */\r\n retryConfig: retryWeixinConfig\r\n },\r\n \r\n // WebView 对象(兼容旧版本)\r\n webView: null,\r\n\r\n // 图片相关常量\r\n ImageSourceTypes,\r\n ImageSizeTypes,\r\n \r\n /**\r\n * 获取图片功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getImageCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.0.0\r\n */\r\n getImageCapabilities,\r\n \r\n // 扫码相关常量\r\n ScanTypes,\r\n \r\n /**\r\n * 获取扫码功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getScanCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getScanCapabilities,\r\n \r\n // 位置相关常量\r\n CoordinateTypes,\r\n \r\n /**\r\n * 获取位置功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getLocationCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getLocationCapabilities,\r\n \r\n /**\r\n * 获取位置选择功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getChooseLocationCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getChooseLocationCapabilities,\r\n\r\n\r\n // 蓝牙 API\r\n openBluetoothAdapter,\r\n openBluetoothAdapterAsync,\r\n startBluetoothDevicesDiscovery,\r\n startBluetoothDevicesDiscoveryAsync,\r\n onBluetoothDeviceFound,\r\n onBluetoothDeviceFoundAsync,\r\n createBLEConnection,\r\n createBLEConnectionAsync,\r\n // 蓝牙相关常量\r\n BluetoothStates,\r\n //微信分享\r\n toShare,\r\n\r\n /**\r\n * 获取蓝牙功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getBluetoothCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n */\r\n getBluetoothCapabilities,\r\n\r\n // 打印PDF API\r\n printPdf,\r\n printPdfAsync,\r\n \r\n /**\r\n * 获取打印PDF功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getPrintCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n */\r\n getPrintCapabilities,\r\n\r\n // 人脸识别 API(仅支持微信小程序环境)\r\n faceVerify,\r\n getFaceCapabilities,\r\n\r\n\r\n // 插件系统\r\n plugins: {\r\n /**\r\n * 插件管理器\r\n */\r\n manager: pluginManager,\r\n \r\n /**\r\n * 注册插件\r\n * @param {Object} plugin - 插件对象\r\n * @returns {Object} pluginManager 实例\r\n * @example\r\n * qsh.plugins.register(myPlugin)\r\n */\r\n register: (plugin) => pluginManager.register(plugin),\r\n \r\n /**\r\n * 安装插件\r\n * @param {string} name - 插件名称\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.plugins.install('image')\r\n */\r\n install: (name) => pluginManager.install(name, uni),\r\n \r\n /**\r\n * 获取插件列表\r\n * @returns {Array} 插件列表\r\n * @example\r\n * console.log(qsh.plugins.list())\r\n */\r\n list: () => pluginManager.getPluginList()\r\n },\r\n \r\n // 拦截器系统\r\n interceptors: {\r\n /**\r\n * 拦截器链\r\n */\r\n chain: interceptorChain,\r\n \r\n /**\r\n * 注册请求拦截器\r\n * @param {Function} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * qsh.interceptors.useRequest(async (ctx) => {\r\n * console.log('API 调用:', ctx.apiName)\r\n * return ctx\r\n * })\r\n */\r\n useRequest: (interceptor, options) => interceptorChain.useRequest(interceptor, options),\r\n \r\n /**\r\n * 注册响应拦截器\r\n * @param {Function} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * qsh.interceptors.useResponse(async (result, ctx) => {\r\n * console.log('API 完成:', ctx.apiName)\r\n * return result\r\n * })\r\n */\r\n useResponse: (interceptor, options) => interceptorChain.useResponse(interceptor, options),\r\n \r\n /**\r\n * 内置拦截器\r\n */\r\n builtin: {\r\n logging: loggingInterceptor,\r\n performance: performanceInterceptor,\r\n createRetry: createRetryInterceptor,\r\n createValidation: createValidationInterceptor,\r\n errorNormalizer: errorNormalizerInterceptor\r\n }\r\n },\r\n\r\n // 观测指标\r\n metrics: {\r\n /**\r\n * 获取性能指标报告\r\n */\r\n getPerformanceReport: () => performanceInterceptor.getReport(),\r\n /**\r\n * 清空性能指标\r\n */\r\n clearPerformanceMetrics: () => performanceInterceptor.clearMetrics()\r\n },\r\n \r\n // 错误处理工具\r\n errors: {\r\n /**\r\n * 错误码枚举\r\n */\r\n codes: ErrorCodes,\r\n \r\n /**\r\n * 错误消息\r\n */\r\n messages: ErrorMessages,\r\n \r\n /**\r\n * 错误分类\r\n */\r\n categories: ErrorCategory,\r\n \r\n /**\r\n * 标准化错误\r\n * @param {any} error - 原始错误\r\n * @param {Object} context - 上下文\r\n * @returns {Object} 标准化错误\r\n * @example\r\n * const standardError = qsh.errors.normalize(error, { apiName: 'chooseImage' })\r\n */\r\n normalize: normalizeError,\r\n \r\n /**\r\n * 创建标准错误\r\n * @param {string} code - 错误码\r\n * @param {Object} options - 选项\r\n * @returns {Object} 标准错误\r\n * @example\r\n * const error = qsh.errors.create('E_IMG_001', { apiName: 'chooseImage' })\r\n */\r\n create: createError,\r\n \r\n /**\r\n * 判断是否为标准错误\r\n * @param {any} error - 错误对象\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.errors.isStandard(error)) { ... }\r\n */\r\n isStandard: isStandardError\r\n },\r\n \r\n // 状态管理\r\n store: {\r\n /**\r\n * 状态仓库实例\r\n */\r\n instance: stateStore,\r\n \r\n /**\r\n * 获取状态\r\n * @param {string} path - 状态路径\r\n * @returns {any} 状态值\r\n * @example\r\n * const status = qsh.store.get('sdk.status')\r\n */\r\n get: (path) => stateStore.get(path),\r\n \r\n /**\r\n * 设置状态\r\n * @param {string} path - 状态路径\r\n * @param {any} value - 新值\r\n * @example\r\n * qsh.store.set('sdk.status', 'ready')\r\n */\r\n set: (path, value) => stateStore.set(path, value),\r\n \r\n /**\r\n * 订阅状态变化\r\n * @param {string} path - 状态路径\r\n * @param {Function} listener - 监听函数\r\n * @returns {Function} 取消订阅的函数\r\n * @example\r\n * const unsubscribe = qsh.store.subscribe('network.online', (online) => {\r\n * console.log('网络状态:', online)\r\n * })\r\n */\r\n subscribe: (path, listener) => stateStore.subscribe(path, listener),\r\n \r\n /**\r\n * 获取状态快照\r\n * @returns {Object} 状态快照\r\n * @example\r\n * console.log(qsh.store.getSnapshot())\r\n */\r\n getSnapshot: () => stateStore.getSnapshot()\r\n },\r\n \r\n // 调试工具(生产环境可能被优化掉)\r\n debug: {\r\n /**\r\n * 日志记录器\r\n */\r\n logger: Logger,\r\n /**\r\n * 设置外部日志 reporter,便于对接埋点/观测\r\n */\r\n setLogReporter: (reporter) => Logger.setReporter(reporter),\r\n \r\n /**\r\n * 错误处理器\r\n */\r\n errorHandler: ErrorHandler,\r\n \r\n /**\r\n * 状态管理器\r\n */\r\n stateManager,\r\n \r\n /**\r\n * 启用调试模式\r\n * @example\r\n * qsh.debug.enableDevMode()\r\n */\r\n enableDevMode: () => Logger.enableDevMode(),\r\n \r\n /**\r\n * 获取日志历史\r\n * @param {number} [count] - 获取条数\r\n * @returns {Array} 日志历史\r\n * @example\r\n * console.log(qsh.debug.getLogs(10))\r\n */\r\n getLogs: (count) => Logger.getHistory(count),\r\n \r\n /**\r\n * 获取 SDK 统计信息\r\n * @returns {Object} 统计信息\r\n * @example\r\n * console.log(qsh.debug.getStats())\r\n */\r\n getStats: () => ({\r\n logger: Logger.getStats(),\r\n state: stateManager.getStats(),\r\n weixinConfig: getWeixinConfigManager().getStats(),\r\n plugins: pluginManager.getStats(),\r\n interceptors: interceptorChain.getStats(),\r\n store: stateStore.getStats()\r\n }),\r\n \r\n /**\r\n * 获取微信配置管理器\r\n * @returns {Object} 微信配置管理器\r\n * @example\r\n * console.log(qsh.debug.getWeixinConfigManager().getStats())\r\n */\r\n getWeixinConfigManager,\r\n \r\n /**\r\n * 导出调试信息\r\n * @returns {string} JSON 格式的调试信息\r\n * @example\r\n * console.log(qsh.debug.exportDebugInfo())\r\n */\r\n exportDebugInfo: () => Logger.exportToJSON()\r\n }\r\n};\r\n\r\n// 设置 webView 对象\r\nif (environment.isWeixinMiniProgram) {\r\n uni.webView = window.wx && window.wx.miniProgram;\r\n} else {\r\n uni.webView = {\r\n navigateTo,\r\n navigateBack,\r\n switchTab,\r\n reLaunch,\r\n redirectTo,\r\n postMessage,\r\n getEnv,\r\n chooseImage,\r\n scanCode,\r\n getLocation: getLocationAPI,\r\n openLocation: openLocationAPI,\r\n chooseLocation: chooseLocationAPI\r\n };\r\n}\r\n\r\n// 保留对原始 uni 对象的引用(如果存在)\r\nconst originalUni = typeof window.uni !== 'undefined' ? window.uni : {};\r\n\r\n// 合并原有的 uni 对象属性(如果存在)\r\nObject.keys(originalUni).forEach(key => {\r\n if (!uni.hasOwnProperty(key)) {\r\n uni[key] = originalUni[key];\r\n }\r\n});\r\n\r\n// 导出\r\nexport default uni;\r\n\r\n// 自动挂载到全局(UMD 模式)\r\nif (typeof window !== 'undefined') {\r\n // 仅挂载新全局名,不再暴露 window.uni\r\n window.qsh = uni;\r\n}\r\n"],"names":["getWindow","getNavigatorUA","isWeixinMiniProgram","win","ua","isAppPlus","isNvue","isUvue","isUniApp","isHtml5Plus","isUniAppWebView","getEnvironment","cachedEnvironmentInfo","getEnvironmentInfo","forceRefresh","environment","ErrorTypes","QshError","type","message","context","originalError","_ErrorHandler","enabled","callback","index","error","qshError","platformType","apiName","paramName","expectedType","actualValue","fn","_0","__async","logMessage","callbackError","target","propertyKey","descriptor","originalMethod","args","__spreadProps","__spreadValues","__publicField","ErrorHandler","SDKStates","StateManager","resolve","reject","initFunction","targetState","stateHandler","readyIndex","errorIndex","stateManager","waitForReady","isReady","getState","LogLevels","LogLevelNames","_Logger","level","module","timestamp","levelName","modulePrefix","logEntry","e","hasArgs","count","stats","levelCounts","entry","history","moduleName","reporter","Logger","isLocalhost","hasDebugParam","hasDebugStorage","bridgeLogger","platformLogger","apiLogger","stateLogger","READY_STATE_REGEX","initializeInApp","initializeInWeixin","initializeBridge","waitForBridge","initBridge","handleReady","handleError","bridgeError","syncError","WeixinConfigStates","isWeixinJSSDKAvailable","WeixinConfigManager","config","nextClientId","nextIsProd","hasChanged","isProd","url","hashIndex","currentUrl","configApiUrl","requestUrl","response","result","data","isDev","notInWeixin","isCorsError","configData","configOptions","readyCallbacks","res","errorMessage","errorCallbacks","weixinConfigManager","isLoadingWeixinSDK","weixinSDKLoaded","weixinSDKLoadPromise","autoConfigStarted","waitForExistingWeixinScript","script","settled","timeoutId","finish","loaded","autoConfigWeixin","handleLoad","ensureWeixinJSSDKLoaded","options","force","recoverFromError","loadWeixinJSSDKIfNeeded","recoverWeixinConfigStateIfNeeded","shouldLoadWeixinSDK","inWeixin","inMiniProgramUA","hintedMiniProgram","hasMiniProgramBridge","existingScript","err","waitForWeixinConfig","configureWeixin","runtimeConfig","isWeixinConfigReady","getWeixinConfigState","getWeixinConfigManager","retryWeixinConfig","PluginManager","plugin","name","version","existing","qshInstance","depName","orderIndex","names","plugins","pluginManager","InterceptorChain","interceptor","priority","a","b","item","ctx","newResult","interceptorChain","loggingInterceptor","duration","performanceInterceptor","metrics","report","value","key","createRetryInterceptor","maxRetries","retryDelay","shouldRetry","createValidationInterceptor","rules","validator","StateStore","path","obj","keys","lastKey","oldValue","updates","listener","listeners","unsubscribe","newValue","p","i","parentPath","parentListeners","parentValue","connection","updateConnectionType","loading","apiPath","apiState","platform","stateStore","ErrorCodes","ErrorMessages","ErrorCategory","LegacyErrorMapping","PlatformErrorMapping","ApiErrorMapping","getErrorCategory","code","isRetriableError","isUserAction","getErrorMessage","StandardError","normalizeError","normalizeLegacyError","normalizePlatformError","legacyCode","newCode","errMsg","apiMapping","pattern","platformMapping","defaultCode","errorNormalizerInterceptor","standardError","createError","isStandardError","withTimeout","promiseFactory","timeoutMs","_","runInitPipeline","tasks","task","run","BasePlatform","delta","processedUrl","processedDelta","processedOptions","webviewIds","getCurrentWebviewId","currentWebview","parent","webviewId","sendToUniAppX","postData","serviceMessage","sendToNvue","sendToPlus","currentWebviewIds","jsonMessage","jsonWebviewIds","sendToParent","sendMessage","WeixinPlatform","wxMethod","wxOptions","weixinPlatform","navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv","AppPlatform","envInfo","isAppEnv","appPlatform","getPlatformNavigation","getPlatformMessage","toRawLike","generateCallbackId","WebViewBridge","params","callbacks","_a","interceptedContext","callbackId","_b","callbackData","success","fail","complete","interceptedResult","emptyApis","callbackIds","ids","webViewBridge","callApiInWebView","clearPersistentCallbacksByApi","ImageSourceTypes","ImageSizeTypes","DEFAULT_OPTIONS","normalizeOptions","normalized","isSupported","chooseImageInWeixin","chooseImageInUniApp","chooseImage","normalizedOptions","getImageCapabilities","ScanTypes","scanCodeInWeixin","detectScanType","content","scanCodeInUniApp","scanCode","getScanCapabilities","CoordinateTypes","DEFAULT_LOCATION_OPTIONS","DEFAULT_OPEN_LOCATION_OPTIONS","normalizeLocationOptions","normalizeLocationUpdateOptions","normalizeOpenLocationOptions","scaleNum","getLocationInWeixin","openLocationInWeixin","getLocationInUniApp","openLocationInUniApp","getLocation","openLocation","_c","validationError","getLocationCapabilities","isWeixin","locationChangeCallbacks","locationChangeErrorCallbacks","notifyCallbacks","payload","startLocationUpdate","stopLocationUpdate","onLocationChange","hasListener","offLocationChange","onLocationChangeError","offLocationChangeError","chooseLocationInWeixin","weixinParams","chooseLocationInUniApp","uniOptions","chooseLocation","getChooseLocationCapabilities","registry","registerCapability","implementations","resolveCapability","environmentType","impls","shareToTypes","shareValueTypes","toShareInWeixin","normalizeWeixinOptions","wrappedError","toShareInUniApp","normalizeUniAppOptions","typeValue","SHARE_CAPABILITY_KEY","toShare","env","impl","BluetoothStates","openBluetoothAdapterInWeixin","onBluetoothDeviceFound","bluetoothInUniApp","startBluetoothDevicesDiscoveryInUniApp","bluetoothDeviceFoundCallbacks","onBluetoothDeviceFoundInUniApp","cb","createBLEConnectionInUniApp","openBluetoothAdapter","startBluetoothDevicesDiscovery","createBLEConnection","_d","deviceId","autoConnect","getBluetoothCapabilities","printPdfInUniApp","printPdf","getPrintCapabilities","FACE_PAGE_PATH","isMiniProgramNavigateAvailable","buildFacePageUrl","query","faceVerifyInWeixin","targetUrl","faceVerify","getFaceCapabilities","shouldWaitForWeixinConfigInReady","readySDK","autoInitStarted","startAutoInit","step","ensureReadyInvoke","apiFn","rest","hasCallbacks","execute","wrapped","normalizeCallbackOptions","input","rawNavigateTo","rawNavigateBack","rawSwitchTab","rawReLaunch","rawRedirectTo","rawPostMessage","exec","rawGetEnv","rawChooseImage","chooseImageAsync","rawPrintPdf","printPdfAsync","rawScanCode","rawFaceVerify","scanCodeAsync","rawToShare","getLocationAPI","rawGetLocation","getLocationAsyncAPI","openLocationAPI","rawOpenLocation","openLocationAsyncAPI","chooseLocationAPI","rawChooseLocation","chooseLocationAsyncAPI","rawOpenBluetooth","openBluetoothAdapterAsync","rawBluetoothDevicesDiscovery","startBluetoothDevicesDiscoveryAsync","rawOnBluetoothDeviceFound","onBluetoothDeviceFoundAsync","rawCreateBLEConnection","createBLEConnectionAsync","uni","rawOnLocationChange","rawOffLocationChange","rawOnLocationChangeError","rawOffLocationChangeError","rawStartLocationUpdate","rawStopLocationUpdate","originalUni"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"qsh-webview-sdk.es.js","sources":["../src/core/environment.js","../src/core/error-handler.js","../src/core/state-manager.js","../src/core/logger.js","../src/core/bridge.js","../src/core/weixin-config.js","../src/core/weixin-loader.js","../src/core/plugin-manager.js","../src/core/interceptor.js","../src/core/state-store.js","../src/core/error-codes.js","../src/core/error-normalizer.js","../src/core/init-pipeline.js","../src/core/base-platform.js","../src/core/messenger.js","../src/platforms/weixin.js","../src/platforms/app.js","../src/api/navigation.js","../src/api/message.js","../src/core/webview-bridge.js","../src/api/image.js","../src/api/scan.js","../src/api/location.js","../src/api/choose.js","../src/api/capability-registry.js","../src/api/share.js","../src/api/bluetooth.js","../src/api/print.js","../src/api/face.js","../src/index.js"],"sourcesContent":["/**\r\n * 环境检测模块\r\n * 检测当前运行环境(微信小程序、APP等)\r\n * 兼容 SSR/Node:所有检测均在访问全局对象前做 typeof 防护。\r\n */\r\n\r\nfunction getWindow() {\r\n return typeof window !== 'undefined' ? window : undefined;\r\n}\r\n\r\nfunction getNavigatorUA() {\r\n if (typeof navigator === 'undefined') {\r\n return '';\r\n }\r\n return navigator.userAgent || '';\r\n}\r\n\r\n/**\r\n * 检测是否在微信小程序环境\r\n * @returns {boolean}\r\n */\r\nexport function isWeixinMiniProgram() {\r\n const win = getWindow();\r\n if (!win) return false;\r\n\r\n // 1) 官方标识:小程序 web-view 中会注入该变量\r\n if (win.__wxjs_environment === 'miniprogram') {\r\n return true;\r\n }\r\n // 2) jweixin >= 1.6.0 提供 wx.miniProgram\r\n if (win.wx && win.wx.miniProgram) {\r\n return true;\r\n }\r\n // 3) 兜底:在微信内且 UA 带 miniProgram 关键词\r\n const ua = getNavigatorUA();\r\n if (ua && /micromessenger/i.test(ua) && /miniProgram/i.test(ua)) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 是否为 APP Plus 环境\r\n * @returns {boolean}\r\n */\r\nexport function isAppPlus() {\r\n const win = getWindow();\r\n return !!(win && win.plus);\r\n}\r\n\r\n/**\r\n * 是否为 NVUE 环境\r\n * @returns {boolean}\r\n */\r\nexport function isNvue() {\r\n const win = getWindow();\r\n return !!(win && (win.__dcloud_weex_postMessage || win.__dcloud_weex_));\r\n}\r\n\r\n/**\r\n * 是否为 UVUE(UniApp X)环境\r\n * @returns {boolean}\r\n */\r\nexport function isUvue() {\r\n const win = getWindow();\r\n return !!(win && (win.__uniapp_x_postMessage || win.__uniapp_x_));\r\n}\r\n\r\n/**\r\n * 是否为 UniApp H5 环境\r\n * @returns {boolean}\r\n */\r\nexport function isUniApp() {\r\n const ua = getNavigatorUA();\r\n return /uni-app/i.test(ua);\r\n}\r\n\r\n/**\r\n * 是否为 Html5Plus 环境\r\n * @returns {boolean}\r\n */\r\nexport function isHtml5Plus() {\r\n const ua = getNavigatorUA();\r\n return /Html5Plus/i.test(ua);\r\n}\r\n\r\n/**\r\n * 是否在 UniApp WebView 环境中\r\n * @returns {boolean}\r\n */\r\nexport function isUniAppWebView() {\r\n return isUniApp() || isHtml5Plus();\r\n}\r\n\r\n/**\r\n * 获取当前环境类型字符串(惰性计算,可缓存)\r\n * @returns {('weixin'|'plus'|'nvue'|'uvue'|'UniApp'|'webview'|'h5')}\r\n */\r\nexport function getEnvironment() {\r\n if (isUvue()) {\r\n return 'uvue';\r\n }\r\n if (isNvue()) {\r\n return 'nvue';\r\n }\r\n if (isWeixinMiniProgram()) {\r\n return 'weixin';\r\n }\r\n if (isAppPlus()) {\r\n return 'plus';\r\n }\r\n if (isUniAppWebView()) {\r\n return 'webview';\r\n }\r\n if (isUniApp()) {\r\n return 'UniApp';\r\n }\r\n return 'h5';\r\n}\r\n\r\nlet cachedEnvironmentInfo = null;\r\n\r\n/**\r\n * 获取或刷新环境信息对象\r\n * @param {boolean} [forceRefresh=false] 是否强制重新检测\r\n * @returns {{\r\n * isWeixinMiniProgram: boolean,\r\n * isAppPlus: boolean,\r\n * isNvue: boolean,\r\n * isUvue: boolean,\r\n * isUniApp: boolean,\r\n * isHtml5Plus: boolean,\r\n * isUniAppWebView: boolean,\r\n * type: string\r\n * }}\r\n */\r\nexport function getEnvironmentInfo(forceRefresh = false) {\r\n if (cachedEnvironmentInfo && !forceRefresh) {\r\n return cachedEnvironmentInfo;\r\n }\r\n\r\n cachedEnvironmentInfo = {\r\n isWeixinMiniProgram: isWeixinMiniProgram(),\r\n isAppPlus: isAppPlus(),\r\n isNvue: isNvue(),\r\n isUvue: isUvue(),\r\n isUniApp: isUniApp(),\r\n isHtml5Plus: isHtml5Plus(),\r\n isUniAppWebView: isUniAppWebView(),\r\n type: getEnvironment()\r\n };\r\n\r\n return cachedEnvironmentInfo;\r\n}\r\n\r\n// 保留原有导出名,保持向后兼容\r\nexport const environment = getEnvironmentInfo();","/**\r\n * 统一错误处理模块\r\n * 提供错误分类、日志记录和用户反馈机制\r\n */\r\n\r\n/**\r\n * 错误类型枚举\r\n */\r\nexport const ErrorTypes = {\r\n PLATFORM_NOT_SUPPORTED: 'PLATFORM_NOT_SUPPORTED',\r\n API_CALL_FAILED: 'API_CALL_FAILED',\r\n BRIDGE_NOT_READY: 'BRIDGE_NOT_READY',\r\n INVALID_PARAMETERS: 'INVALID_PARAMETERS',\r\n NETWORK_ERROR: 'NETWORK_ERROR',\r\n UNKNOWN_ERROR: 'UNKNOWN_ERROR'\r\n};\r\n\r\n/**\r\n * QSH SDK 自定义错误类\r\n */\r\nexport class QshError extends Error {\r\n /**\r\n * 构造函数\r\n * @param {string} type - 错误类型\r\n * @param {string} message - 错误消息\r\n * @param {Object} [context] - 错误上下文信息\r\n * @param {Error} [originalError] - 原始错误对象\r\n */\r\n constructor(type, message, context = {}, originalError = null) {\r\n super(message);\r\n this.name = 'QshError';\r\n this.type = type;\r\n this.context = context;\r\n this.originalError = originalError;\r\n this.timestamp = new Date().toISOString();\r\n \r\n // 保持错误堆栈跟踪\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, QshError);\r\n }\r\n }\r\n\r\n /**\r\n * 转换为 JSON 格式\r\n * @returns {Object} JSON 对象\r\n */\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n type: this.type,\r\n message: this.message,\r\n context: this.context,\r\n timestamp: this.timestamp,\r\n stack: this.stack\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * 错误处理器类\r\n */\r\nexport class ErrorHandler {\r\n static isDebugMode = false;\r\n static errorCallbacks = [];\r\n\r\n /**\r\n * 设置调试模式\r\n * @param {boolean} enabled - 是否启用调试模式\r\n */\r\n static setDebugMode(enabled) {\r\n ErrorHandler.isDebugMode = enabled;\r\n }\r\n\r\n /**\r\n * 添加错误回调\r\n * @param {Function} callback - 错误处理回调函数\r\n */\r\n static addErrorCallback(callback) {\r\n if (typeof callback === 'function') {\r\n ErrorHandler.errorCallbacks.push(callback);\r\n }\r\n }\r\n\r\n /**\r\n * 移除错误回调\r\n * @param {Function} callback - 要移除的回调函数\r\n */\r\n static removeErrorCallback(callback) {\r\n const index = ErrorHandler.errorCallbacks.indexOf(callback);\r\n if (index > -1) {\r\n ErrorHandler.errorCallbacks.splice(index, 1);\r\n }\r\n }\r\n\r\n /**\r\n * 处理 API 调用错误\r\n * @param {Error|string} error - 错误对象或消息\r\n * @param {Object} context - 错误上下文\r\n * @returns {QshError} 包装后的错误对象\r\n */\r\n static handleApiError(error, context = {}) {\r\n let qshError;\r\n \r\n if (error instanceof QshError) {\r\n qshError = error;\r\n } else if (error instanceof Error) {\r\n qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n error.message,\r\n context,\r\n error\r\n );\r\n } else {\r\n qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n String(error),\r\n context\r\n );\r\n }\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理平台不支持错误\r\n * @param {string} platformType - 平台类型\r\n * @param {string} apiName - API 名称\r\n * @returns {QshError} 错误对象\r\n */\r\n static handlePlatformNotSupported(platformType, apiName) {\r\n const qshError = new QshError(\r\n ErrorTypes.PLATFORM_NOT_SUPPORTED,\r\n `API \"${apiName}\" is not supported on platform \"${platformType}\"`,\r\n { platformType, apiName }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理桥接未就绪错误\r\n * @param {string} apiName - API 名称\r\n * @returns {QshError} 错误对象\r\n */\r\n static handleBridgeNotReady(apiName) {\r\n const qshError = new QshError(\r\n ErrorTypes.BRIDGE_NOT_READY,\r\n `Bridge is not ready when calling \"${apiName}\"`,\r\n { apiName }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 处理参数验证错误\r\n * @param {string} apiName - API 名称\r\n * @param {string} paramName - 参数名称\r\n * @param {string} expectedType - 期望的参数类型\r\n * @param {any} actualValue - 实际参数值\r\n * @returns {QshError} 错误对象\r\n */\r\n static handleInvalidParameters(apiName, paramName, expectedType, actualValue) {\r\n const qshError = new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n `Invalid parameter \"${paramName}\" in \"${apiName}\": expected ${expectedType}, got ${typeof actualValue}`,\r\n { apiName, paramName, expectedType, actualValue }\r\n );\r\n\r\n ErrorHandler.logError(qshError);\r\n ErrorHandler.notifyCallbacks(qshError);\r\n \r\n return qshError;\r\n }\r\n\r\n /**\r\n * 安全地包装函数执行,捕获并处理错误\r\n * @param {Function} fn - 要执行的函数\r\n * @param {Object} context - 执行上下文\r\n * @returns {any} 函数执行结果\r\n */\r\n static safeExecute(fn, context = {}) {\r\n try {\r\n return fn();\r\n } catch (error) {\r\n return ErrorHandler.handleApiError(error, context);\r\n }\r\n }\r\n\r\n /**\r\n * 异步安全包装\r\n * @param {Function} fn - 异步函数\r\n * @param {Object} context - 执行上下文\r\n * @returns {Promise} Promise 对象\r\n */\r\n static async safeExecuteAsync(fn, context = {}) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n return ErrorHandler.handleApiError(error, context);\r\n }\r\n }\r\n\r\n /**\r\n * 记录错误日志\r\n * @param {QshError} error - 错误对象\r\n * @private\r\n */\r\n static logError(error) {\r\n if (typeof console !== 'undefined') {\r\n const logMessage = `[QSH-SDK Error] ${error.type}: ${error.message}`;\r\n \r\n if (ErrorHandler.isDebugMode) {\r\n console.error(logMessage, {\r\n context: error.context,\r\n originalError: error.originalError,\r\n stack: error.stack,\r\n timestamp: error.timestamp\r\n });\r\n } else {\r\n console.error(logMessage);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 通知错误回调\r\n * @param {QshError} error - 错误对象\r\n * @private\r\n */\r\n static notifyCallbacks(error) {\r\n ErrorHandler.errorCallbacks.forEach(callback => {\r\n try {\r\n callback(error);\r\n } catch (callbackError) {\r\n // 避免回调错误导致无限循环\r\n if (typeof console !== 'undefined') {\r\n console.error('[QSH-SDK] Error in error callback:', callbackError);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 创建错误处理装饰器\r\n * @param {Object} context - 装饰器上下文\r\n * @returns {Function} 装饰器函数\r\n */\r\n static createErrorDecorator(context = {}) {\r\n return function(target, propertyKey, descriptor) {\r\n const originalMethod = descriptor.value;\r\n \r\n descriptor.value = function(...args) {\r\n return ErrorHandler.safeExecute(() => {\r\n return originalMethod.apply(this, args);\r\n }, { ...context, method: propertyKey, target: target.constructor.name });\r\n };\r\n \r\n return descriptor;\r\n };\r\n }\r\n}\r\n","/**\r\n * 状态管理器\r\n * 管理 SDK 初始化状态,优化性能\r\n */\r\n\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * SDK 状态枚举\r\n */\r\nexport const SDKStates = {\r\n UNINITIALIZED: 'uninitialized',\r\n INITIALIZING: 'initializing',\r\n READY: 'ready',\r\n ERROR: 'error'\r\n};\r\n\r\n/**\r\n * 状态管理器类(单例模式)\r\n */\r\nclass StateManager {\r\n constructor() {\r\n this.state = SDKStates.UNINITIALIZED;\r\n this.readyPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.initializationError = null;\r\n \r\n // 绑定方法,避免 this 丢失\r\n this.handleBridgeReady = this.handleBridgeReady.bind(this);\r\n this.handleInitializationError = this.handleInitializationError.bind(this);\r\n }\r\n\r\n /**\r\n * 获取当前状态\r\n * @returns {string} 当前状态\r\n */\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * 检查是否已准备就绪\r\n * @returns {boolean} 是否就绪\r\n */\r\n isReady() {\r\n return this.state === SDKStates.READY;\r\n }\r\n\r\n /**\r\n * 检查是否正在初始化\r\n * @returns {boolean} 是否正在初始化\r\n */\r\n isInitializing() {\r\n return this.state === SDKStates.INITIALIZING;\r\n }\r\n\r\n /**\r\n * 检查是否出错\r\n * @returns {boolean} 是否出错\r\n */\r\n hasError() {\r\n return this.state === SDKStates.ERROR;\r\n }\r\n\r\n /**\r\n * 获取初始化错误\r\n * @returns {Error|null} 错误对象\r\n */\r\n getInitializationError() {\r\n return this.initializationError;\r\n }\r\n\r\n /**\r\n * 等待 SDK 准备就绪(单例 Promise)\r\n * @returns {Promise<void>} 准备就绪的 Promise\r\n */\r\n waitForReady() {\r\n // 如果已经就绪,立即返回\r\n if (this.isReady()) {\r\n return Promise.resolve();\r\n }\r\n\r\n // 如果有错误,返回拒绝的 Promise\r\n if (this.hasError()) {\r\n return Promise.reject(this.initializationError);\r\n }\r\n\r\n // 如果还没有 Promise 实例,创建一个\r\n if (!this.readyPromise) {\r\n this.readyPromise = new Promise((resolve, reject) => {\r\n if (this.isReady()) {\r\n resolve();\r\n } else if (this.hasError()) {\r\n reject(this.initializationError);\r\n } else {\r\n // 添加到回调列表\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n }\r\n });\r\n }\r\n\r\n return this.readyPromise;\r\n }\r\n\r\n /**\r\n * 开始初始化\r\n * @param {Function} initFunction - 初始化函数\r\n * @returns {Promise<void>} 初始化 Promise\r\n */\r\n async startInitialization(initFunction) {\r\n if (this.state !== SDKStates.UNINITIALIZED) {\r\n return this.waitForReady();\r\n }\r\n\r\n this.state = SDKStates.INITIALIZING;\r\n\r\n try {\r\n await initFunction();\r\n this.handleBridgeReady();\r\n } catch (error) {\r\n this.handleInitializationError(error);\r\n throw error;\r\n }\r\n\r\n return this.waitForReady();\r\n }\r\n\r\n /**\r\n * 处理桥接就绪事件\r\n * @private\r\n */\r\n handleBridgeReady() {\r\n if (this.state !== SDKStates.INITIALIZING) {\r\n return;\r\n }\r\n\r\n this.state = SDKStates.READY;\r\n \r\n // 通知所有等待的回调\r\n this.readyCallbacks.forEach(callback => {\r\n try {\r\n callback();\r\n } catch (error) {\r\n ErrorHandler.handleApiError(error, { context: 'StateManager.handleBridgeReady' });\r\n }\r\n });\r\n\r\n // 清空回调列表\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n }\r\n\r\n /**\r\n * 处理初始化错误\r\n * @param {Error} error - 错误对象\r\n * @private\r\n */\r\n handleInitializationError(error) {\r\n this.state = SDKStates.ERROR;\r\n this.initializationError = error;\r\n\r\n // 通知所有等待的错误回调\r\n this.errorCallbacks.forEach(callback => {\r\n try {\r\n callback(error);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'StateManager.handleInitializationError' });\r\n }\r\n });\r\n\r\n // 清空回调列表\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n }\r\n\r\n /**\r\n * 重置状态管理器(用于测试或重新初始化)\r\n */\r\n reset() {\r\n this.state = SDKStates.UNINITIALIZED;\r\n this.readyPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.initializationError = null;\r\n }\r\n\r\n /**\r\n * 添加状态变化监听器\r\n * @param {string} targetState - 目标状态\r\n * @param {Function} callback - 回调函数\r\n * @returns {Function} 移除监听器的函数\r\n */\r\n onStateChange(targetState, callback) {\r\n if (this.state === targetState) {\r\n // 状态已经匹配,立即调用\r\n setTimeout(() => callback(this.state), 0);\r\n return () => {}; // 返回空的移除函数\r\n }\r\n\r\n const stateHandler = () => {\r\n if (this.state === targetState) {\r\n callback(this.state);\r\n }\r\n };\r\n\r\n if (targetState === SDKStates.READY) {\r\n this.readyCallbacks.push(stateHandler);\r\n } else if (targetState === SDKStates.ERROR) {\r\n this.errorCallbacks.push(stateHandler);\r\n }\r\n\r\n // 返回移除监听器的函数\r\n return () => {\r\n const readyIndex = this.readyCallbacks.indexOf(stateHandler);\r\n if (readyIndex > -1) {\r\n this.readyCallbacks.splice(readyIndex, 1);\r\n }\r\n\r\n const errorIndex = this.errorCallbacks.indexOf(stateHandler);\r\n if (errorIndex > -1) {\r\n this.errorCallbacks.splice(errorIndex, 1);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 获取状态统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n getStats() {\r\n return {\r\n state: this.state,\r\n readyCallbacksCount: this.readyCallbacks.length,\r\n errorCallbacksCount: this.errorCallbacks.length,\r\n hasReadyPromise: !!this.readyPromise,\r\n hasInitializationError: !!this.initializationError\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst stateManager = new StateManager();\r\n\r\n// 导出单例实例和类\r\nexport { stateManager as default, StateManager };\r\n\r\n/**\r\n * 便利函数:等待 SDK 就绪\r\n * @returns {Promise<void>}\r\n */\r\nexport const waitForReady = () => stateManager.waitForReady();\r\n\r\n/**\r\n * 便利函数:检查是否就绪\r\n * @returns {boolean}\r\n */\r\nexport const isReady = () => stateManager.isReady();\r\n\r\n/**\r\n * 便利函数:获取当前状态\r\n * @returns {string}\r\n */\r\nexport const getState = () => stateManager.getState();\r\n","/**\r\n * 日志记录模块\r\n * 提供分级日志记录和调试功能\r\n */\r\n\r\n/**\r\n * 日志级别枚举\r\n */\r\nexport const LogLevels = {\r\n ERROR: 0,\r\n WARN: 1,\r\n INFO: 2,\r\n DEBUG: 3,\r\n TRACE: 4\r\n};\r\n\r\n/**\r\n * 日志级别名称映射\r\n */\r\nconst LogLevelNames = {\r\n [LogLevels.ERROR]: 'ERROR',\r\n [LogLevels.WARN]: 'WARN',\r\n [LogLevels.INFO]: 'INFO',\r\n [LogLevels.DEBUG]: 'DEBUG',\r\n [LogLevels.TRACE]: 'TRACE'\r\n};\r\n\r\n/**\r\n * 日志记录器类\r\n */\r\nexport class Logger {\r\n static currentLevel = LogLevels.ERROR; // 生产环境默认只显示错误\r\n static enabledModules = new Set(); // 启用日志的模块\r\n static logHistory = []; // 日志历史(最多保留1000条)\r\n static maxHistorySize = 1000;\r\n static prefix = '[QSH-SDK]';\r\n static reporter = null; // 可注入的外部 reporter\r\n\r\n /**\r\n * 设置日志级别\r\n * @param {number} level - 日志级别\r\n */\r\n static setLevel(level) {\r\n if (level >= LogLevels.ERROR && level <= LogLevels.TRACE) {\r\n Logger.currentLevel = level;\r\n Logger.log(LogLevels.INFO, 'Logger', `日志级别设置为: ${LogLevelNames[level]}`);\r\n }\r\n }\r\n\r\n /**\r\n * 启用开发模式(显示所有日志)\r\n */\r\n static enableDevMode() {\r\n Logger.setLevel(LogLevels.DEBUG);\r\n Logger.log(LogLevels.INFO, 'Logger', '开发模式已启用');\r\n }\r\n\r\n /**\r\n * 启用生产模式(只显示错误和警告)\r\n */\r\n static enableProdMode() {\r\n Logger.setLevel(LogLevels.WARN);\r\n Logger.log(LogLevels.INFO, 'Logger', '生产模式已启用');\r\n }\r\n\r\n /**\r\n * 启用特定模块的日志\r\n * @param {string} module - 模块名称\r\n */\r\n static enableModule(module) {\r\n Logger.enabledModules.add(module);\r\n Logger.log(LogLevels.INFO, 'Logger', `模块日志已启用: ${module}`);\r\n }\r\n\r\n /**\r\n * 禁用特定模块的日志\r\n * @param {string} module - 模块名称\r\n */\r\n static disableModule(module) {\r\n Logger.enabledModules.delete(module);\r\n Logger.log(LogLevels.INFO, 'Logger', `模块日志已禁用: ${module}`);\r\n }\r\n\r\n /**\r\n * 检查是否应该记录日志\r\n * @param {number} level - 日志级别\r\n * @param {string} module - 模块名称\r\n * @returns {boolean} 是否应该记录\r\n * @private\r\n */\r\n static shouldLog(level, module) {\r\n // 检查日志级别\r\n if (level > Logger.currentLevel) {\r\n return false;\r\n }\r\n\r\n // 检查模块是否启用(如果有指定模块)\r\n if (module && Logger.enabledModules.size > 0) {\r\n return Logger.enabledModules.has(module);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * 核心日志记录方法\r\n * @param {number} level - 日志级别\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 日志消息\r\n * @param {any[]} args - 额外参数\r\n * @private\r\n */\r\n static log(level, module, message, ...args) {\r\n if (!Logger.shouldLog(level, module)) {\r\n return;\r\n }\r\n\r\n const timestamp = new Date().toISOString();\r\n const levelName = LogLevelNames[level];\r\n const modulePrefix = module ? `[${module}]` : '';\r\n const logMessage = `${Logger.prefix} ${modulePrefix} ${message}`;\r\n\r\n // 记录到历史\r\n const logEntry = {\r\n timestamp,\r\n level,\r\n levelName,\r\n module,\r\n message,\r\n args\r\n };\r\n\r\n Logger.addToHistory(logEntry);\r\n\r\n // 可选外部 reporter(用于观测/上报)\r\n if (typeof Logger.reporter === 'function') {\r\n try {\r\n Logger.reporter(logEntry);\r\n } catch (e) {\r\n // reporter 不应影响主流程\r\n }\r\n }\r\n\r\n // 输出到控制台\r\n Logger.outputToConsole(level, logMessage, ...args);\r\n }\r\n\r\n /**\r\n * 添加日志到历史记录\r\n * @param {Object} logEntry - 日志条目\r\n * @private\r\n */\r\n static addToHistory(logEntry) {\r\n Logger.logHistory.push(logEntry);\r\n \r\n // 限制历史记录大小\r\n if (Logger.logHistory.length > Logger.maxHistorySize) {\r\n Logger.logHistory.shift();\r\n }\r\n }\r\n\r\n /**\r\n * 输出到控制台\r\n * @param {number} level - 日志级别\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n * @private\r\n */\r\n static outputToConsole(level, message, ...args) {\r\n if (typeof console === 'undefined') {\r\n return;\r\n }\r\n\r\n const hasArgs = args && args.length > 0;\r\n\r\n switch (level) {\r\n case LogLevels.ERROR:\r\n hasArgs ? console.error(message, ...args) : console.error(message);\r\n break;\r\n case LogLevels.WARN:\r\n hasArgs ? console.warn(message, ...args) : console.warn(message);\r\n break;\r\n case LogLevels.INFO:\r\n hasArgs ? console.info(message, ...args) : console.info(message);\r\n break;\r\n case LogLevels.DEBUG:\r\n case LogLevels.TRACE:\r\n hasArgs ? console.log(message, ...args) : console.log(message);\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * 错误级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static error(module, message, ...args) {\r\n Logger.log(LogLevels.ERROR, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 警告级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static warn(module, message, ...args) {\r\n Logger.log(LogLevels.WARN, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 信息级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static info(module, message, ...args) {\r\n Logger.log(LogLevels.INFO, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 调试级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static debug(module, message, ...args) {\r\n Logger.log(LogLevels.DEBUG, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 跟踪级别日志\r\n * @param {string} module - 模块名称\r\n * @param {string} message - 消息\r\n * @param {any[]} args - 额外参数\r\n */\r\n static trace(module, message, ...args) {\r\n Logger.log(LogLevels.TRACE, module, message, ...args);\r\n }\r\n\r\n /**\r\n * 获取日志历史\r\n * @param {number} [count] - 获取的条数,默认全部\r\n * @returns {Array} 日志条目数组\r\n */\r\n static getHistory(count) {\r\n if (count && count > 0) {\r\n return Logger.logHistory.slice(-count);\r\n }\r\n return [...Logger.logHistory];\r\n }\r\n\r\n /**\r\n * 清空日志历史\r\n */\r\n static clearHistory() {\r\n Logger.logHistory = [];\r\n Logger.log(LogLevels.INFO, 'Logger', '日志历史已清空');\r\n }\r\n\r\n /**\r\n * 获取日志统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n static getStats() {\r\n const stats = {\r\n currentLevel: Logger.currentLevel,\r\n currentLevelName: LogLevelNames[Logger.currentLevel],\r\n enabledModules: Array.from(Logger.enabledModules),\r\n historySize: Logger.logHistory.length,\r\n maxHistorySize: Logger.maxHistorySize\r\n };\r\n\r\n // 按级别统计日志数量\r\n const levelCounts = {};\r\n for (const level of Object.keys(LogLevelNames)) {\r\n levelCounts[LogLevelNames[level]] = 0;\r\n }\r\n\r\n Logger.logHistory.forEach(entry => {\r\n levelCounts[entry.levelName]++;\r\n });\r\n\r\n stats.levelCounts = levelCounts;\r\n return stats;\r\n }\r\n\r\n /**\r\n * 导出日志到 JSON\r\n * @param {number} [count] - 导出的条数,默认全部\r\n * @returns {string} JSON 字符串\r\n */\r\n static exportToJSON(count) {\r\n const history = Logger.getHistory(count);\r\n const stats = Logger.getStats();\r\n \r\n return JSON.stringify({\r\n exportTime: new Date().toISOString(),\r\n stats,\r\n logs: history\r\n }, null, 2);\r\n }\r\n\r\n /**\r\n * 创建模块专用日志器\r\n * @param {string} moduleName - 模块名称\r\n * @returns {Object} 模块日志器对象\r\n */\r\n static createModuleLogger(moduleName) {\r\n return {\r\n error: (message, ...args) => Logger.error(moduleName, message, ...args),\r\n warn: (message, ...args) => Logger.warn(moduleName, message, ...args),\r\n info: (message, ...args) => Logger.info(moduleName, message, ...args),\r\n debug: (message, ...args) => Logger.debug(moduleName, message, ...args),\r\n trace: (message, ...args) => Logger.trace(moduleName, message, ...args)\r\n };\r\n }\r\n\r\n /**\r\n * 设置外部 reporter,用于接入自定义观测/上报\r\n * @param {(entry: any) => void|null} reporter\r\n */\r\n static setReporter(reporter) {\r\n Logger.reporter = typeof reporter === 'function' ? reporter : null;\r\n }\r\n}\r\n\r\n// 根据环境自动设置日志级别\r\nif (typeof window !== 'undefined') {\r\n // 检查是否在开发环境\r\n const isLocalhost = window.location && (\r\n window.location.hostname === 'localhost' ||\r\n window.location.hostname === '127.0.0.1' ||\r\n window.location.hostname.includes('192.168.')\r\n );\r\n\r\n // 检查是否有调试参数\r\n const hasDebugParam = window.location && (\r\n window.location.search.includes('debug=true') ||\r\n window.location.search.includes('qsh_debug=1')\r\n );\r\n\r\n // 检查localStorage调试标志\r\n let hasDebugStorage = false;\r\n try {\r\n hasDebugStorage = localStorage && localStorage.getItem('qsh_debug') === 'true';\r\n } catch (e) {\r\n // localStorage 访问失败,忽略\r\n }\r\n\r\n if (isLocalhost || hasDebugParam || hasDebugStorage) {\r\n Logger.enableDevMode();\r\n }\r\n}\r\n\r\n// 创建常用模块的日志器\r\nexport const bridgeLogger = Logger.createModuleLogger('Bridge');\r\nexport const platformLogger = Logger.createModuleLogger('Platform');\r\nexport const apiLogger = Logger.createModuleLogger('API');\r\nexport const stateLogger = Logger.createModuleLogger('State');\r\n\r\nexport default Logger;\r\n","/**\r\n * JSBridge 初始化模块\r\n * 负责初始化与原生端的桥接\r\n */\r\n\r\nimport { isUniApp, isHtml5Plus, isUvue, isNvue, isAppPlus } from './environment.js';\r\nimport stateManager, { SDKStates } from './state-manager.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\nimport { bridgeLogger } from './logger.js';\r\n\r\n// 文档准备状态正则\r\nconst READY_STATE_REGEX = /complete|loaded|interactive/;\r\n\r\n\r\n/**\r\n * 在 APP 环境初始化\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否进入了 APP 初始化流程\r\n * @since 2.0.0\r\n */\r\nfunction initializeInApp(callback) {\r\n if (isUniApp() || isHtml5Plus()) {\r\n bridgeLogger.debug('检测到 APP 环境,开始初始化');\r\n \r\n if (window.__uniapp_x_postMessage || window.__uniapp_x_ || \r\n window.__dcloud_weex_postMessage || window.__dcloud_weex_) {\r\n // NVUE/UVUE:等待 DOMContentLoaded 再回调\r\n bridgeLogger.debug('NVUE/UVUE 环境,等待 DOMContentLoaded');\r\n document.addEventListener('DOMContentLoaded', callback);\r\n } else if (window.plus && READY_STATE_REGEX.test(document.readyState)) {\r\n // plus 已可用且文档已就绪\r\n bridgeLogger.debug('Plus 环境已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else if (window.plus) {\r\n // 传统 plus 场景:等待 plusready 事件\r\n bridgeLogger.debug(\"Plus 环境,等待 plusready 事件\");\r\n // 只有真正有 plus 注入时才等 plusready\r\n document.addEventListener(\"plusready\", callback);\r\n } else {\r\n // plus 未注入:走 WebView/H5 的桥初始化路径\r\n if (READY_STATE_REGEX.test(document.readyState)) {\r\n setTimeout(callback, 0);\r\n } else {\r\n document.addEventListener(\"DOMContentLoaded\", callback, { once: true });\r\n }\r\n }\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 在微信小程序环境初始化\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否进入了微信初始化流程\r\n * @since 2.0.0\r\n */\r\nfunction initializeInWeixin(callback) {\r\n if (window.wx && window.wx.miniProgram) {\r\n bridgeLogger.debug('检测到微信小程序环境,开始初始化');\r\n \r\n if (window.WeixinJSBridge && window.WeixinJSBridge.invoke) {\r\n bridgeLogger.debug('微信 JSBridge 已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else {\r\n bridgeLogger.debug('微信 JSBridge 未就绪,等待 WeixinJSBridgeReady 事件');\r\n document.addEventListener('WeixinJSBridgeReady', callback);\r\n }\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * 初始化 JSBridge\r\n * @param {Function} callback - 初始化完成回调\r\n * @returns {boolean} 是否成功开始初始化\r\n * @example\r\n * initializeBridge(() => console.log('ready'))\r\n * @since 2.0.0\r\n */\r\nexport function initializeBridge(callback) {\r\n bridgeLogger.info('开始初始化 JSBridge');\r\n \r\n // 尝试 APP 环境初始化\r\n if (initializeInApp(callback)) {\r\n bridgeLogger.info('使用 APP 环境初始化');\r\n return true;\r\n }\r\n \r\n // 尝试微信小程序环境初始化\r\n if (initializeInWeixin(callback)) {\r\n bridgeLogger.info('使用微信小程序环境初始化');\r\n return true;\r\n }\r\n \r\n // 默认情况下,在 DOM 加载完成后初始化;若已完成则立即回调\r\n bridgeLogger.debug('使用默认 H5 环境初始化');\r\n if (READY_STATE_REGEX.test(document.readyState)) {\r\n bridgeLogger.debug('DOM 已就绪,立即初始化');\r\n setTimeout(callback, 0);\r\n } else {\r\n bridgeLogger.debug('DOM 未就绪,等待 DOMContentLoaded');\r\n document.addEventListener('DOMContentLoaded', callback);\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * 触发 JSBridge 准备就绪事件(优化版)\r\n * @returns {void}\r\n * @since 2.0.0\r\n */\r\nfunction fireJSBridgeReadyEvent() {\r\n return ErrorHandler.safeExecute(() => {\r\n window.UniAppJSBridge = true;\r\n document.dispatchEvent(new CustomEvent('UniAppJSBridgeReady', {\r\n bubbles: true,\r\n cancelable: true\r\n }));\r\n \r\n // 通知状态管理器\r\n stateManager.handleBridgeReady();\r\n }, { context: 'fireJSBridgeReadyEvent' });\r\n}\r\n\r\n/**\r\n * 等待 JSBridge 准备就绪(性能优化版)\r\n * @returns {Promise<void>} 当触发 UniAppJSBridgeReady 后 resolve\r\n * @example\r\n * await waitForBridge()\r\n * @since 2.0.0\r\n */\r\nexport function waitForBridge() {\r\n // 使用状态管理器的单例 Promise\r\n return stateManager.waitForReady();\r\n}\r\n\r\n/**\r\n * 检查桥接是否就绪\r\n * @returns {boolean} 是否就绪\r\n * @since 2.0.0\r\n */\r\nexport function isBridgeReady() {\r\n return stateManager.isReady();\r\n}\r\n\r\n// 导出 fireJSBridgeReadyEvent\r\nexport { fireJSBridgeReadyEvent };\r\n\r\n/**\r\n * 手动初始化 Bridge(性能优化版)\r\n * @returns {Promise<void>} 初始化完成的 Promise\r\n * @since 2.0.0\r\n */\r\nexport function initBridge() {\r\n return stateManager.startInitialization(async () => {\r\n return new Promise((resolve, reject) => {\r\n const handleReady = () => {\r\n resolve();\r\n };\r\n\r\n const handleError = (error) => {\r\n const bridgeError = ErrorHandler.handleApiError(error, { \r\n context: 'bridge initialization' \r\n });\r\n reject(bridgeError);\r\n };\r\n\r\n try {\r\n initializeBridge(() => {\r\n handleReady();\r\n });\r\n } catch (syncError) {\r\n handleError(syncError);\r\n }\r\n });\r\n });\r\n}","/**\r\n * 微信 JS-SDK 自动配置管理器\r\n * 实现约定优于配置的自动化配置方案\r\n */\r\n\r\nimport { ErrorHandler, ErrorTypes, QshError } from './error-handler.js';\r\nimport { platformLogger } from './logger.js';\r\n\r\n/**\r\n * 微信配置状态枚举\r\n */\r\nexport const WeixinConfigStates = {\r\n UNINITIALIZED: 'uninitialized',\r\n CONFIGURING: 'configuring',\r\n CONFIGURED: 'configured',\r\n ERROR: 'error'\r\n};\r\n\r\nexport function isWeixinJSSDKAvailable() {\r\n if (typeof window === 'undefined' || !window.wx) {\r\n return false;\r\n }\r\n\r\n return (\r\n typeof window.wx.config === 'function' &&\r\n typeof window.wx.ready === 'function' &&\r\n typeof window.wx.error === 'function'\r\n );\r\n}\r\n\r\n/**\r\n * 微信配置管理器类\r\n */\r\nexport class WeixinConfigManager {\r\n constructor() {\r\n this.state = WeixinConfigStates.UNINITIALIZED;\r\n this.configPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.lastError = null;\r\n \r\n // 固定配置 - 支持开发环境代理\r\n this.runtimeConfig = {\r\n clientId: null,\r\n isProd: false\r\n };\r\n this.CONFIG_API_URL = this.getConfigApiUrl(this.runtimeConfig.isProd);\r\n this.DEFAULT_JS_API_LIST = ['chooseImage', 'uploadImage','previewImage','downloadImage','getLocalImgData', 'scanQRCode', 'getLocation', 'openLocation', \"updateAppMessageShareData\", \"updateTimelineShareData\"]; // 默认测试API\r\n \r\n // 绑定方法,避免 this 丢失\r\n this.handleConfigSuccess = this.handleConfigSuccess.bind(this);\r\n this.handleConfigError = this.handleConfigError.bind(this);\r\n }\r\n\r\n configure(config = {}) {\r\n if (!config || typeof config !== 'object' || Array.isArray(config)) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'config参数异常',\r\n { config }\r\n );\r\n }\r\n\r\n if (!Object.prototype.hasOwnProperty.call(config, 'clientId')) {\r\n throw this.createMissingClientIdError();\r\n }\r\n\r\n if (typeof config.clientId !== 'string' || !config.clientId.trim()) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'clientId参数异常',\r\n { clientId: config.clientId }\r\n );\r\n }\r\n\r\n if (\r\n Object.prototype.hasOwnProperty.call(config, 'isProd') &&\r\n typeof config.isProd !== 'boolean'\r\n ) {\r\n throw new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'isProd参数异常',\r\n { isProd: config.isProd }\r\n );\r\n }\r\n\r\n const nextClientId = config.clientId.trim();\r\n const nextIsProd = config.isProd === true;\r\n const hasChanged =\r\n nextClientId !== this.runtimeConfig.clientId ||\r\n nextIsProd !== this.runtimeConfig.isProd;\r\n\r\n this.runtimeConfig = {\r\n ...this.runtimeConfig,\r\n clientId: nextClientId,\r\n isProd: nextIsProd\r\n };\r\n this.CONFIG_API_URL = this.getConfigApiUrl(nextIsProd);\r\n\r\n const shouldReset =\r\n this.state === WeixinConfigStates.ERROR ||\r\n (hasChanged && (\r\n this.state === WeixinConfigStates.CONFIGURING ||\r\n this.state === WeixinConfigStates.CONFIGURED\r\n ));\r\n\r\n if (shouldReset) {\r\n this.reset();\r\n }\r\n\r\n platformLogger.info('Updated Weixin runtime config', {\r\n clientId: this.runtimeConfig.clientId,\r\n isProd: this.runtimeConfig.isProd,\r\n configApiUrl: this.CONFIG_API_URL\r\n });\r\n\r\n return this.getRuntimeConfig();\r\n }\r\n\r\n getRuntimeConfig() {\r\n return {\r\n ...this.runtimeConfig\r\n };\r\n }\r\n\r\n hasClientId() {\r\n return typeof this.runtimeConfig.clientId === 'string' && this.runtimeConfig.clientId.length > 0;\r\n }\r\n\r\n hasRequiredConfig() {\r\n return this.isTestMode() || this.hasClientId();\r\n }\r\n\r\n createMissingClientIdError() {\r\n return new QshError(\r\n ErrorTypes.INVALID_PARAMETERS,\r\n 'clientId错误',\r\n { field: 'clientId' }\r\n );\r\n }\r\n\r\n /**\r\n * 获取配置API的URL(支持开发环境代理)\r\n * @returns {string} API URL\r\n * @private\r\n */\r\n getConfigApiUrl(isProd = false) {\r\n if (isProd) {\r\n return 'https://tyck-service.xj-agri.gov.cn/api/wechat/mp/jssdk-sign';\r\n }\r\n\r\n return 'https://unified-platform-service.xjy2.cn/api/wechat/mp/jssdk-sign';\r\n }\r\n\r\n /**\r\n * 获取当前页面URL(不包含hash部分)\r\n * @returns {string} 页面URL\r\n * @private\r\n */\r\n getCurrentPageUrl() {\r\n if (typeof window === 'undefined' || !window.location) {\r\n throw new Error('无法获取当前页面URL');\r\n }\r\n \r\n const url = window.location.href;\r\n const hashIndex = url.indexOf('#');\r\n return hashIndex !== -1 ? url.substring(0, hashIndex) : url;\r\n }\r\n\r\n /**\r\n * 获取微信配置\r\n * @returns {Promise<Object>} 配置对象\r\n * @private\r\n */\r\n async fetchWeixinConfig() {\r\n const currentUrl = this.getCurrentPageUrl();\r\n \r\n // 检查是否为测试模式\r\n if (this.isTestMode()) {\r\n platformLogger.info('使用测试模式,返回模拟配置');\r\n return this.getMockConfig();\r\n }\r\n\r\n if (!this.hasClientId()) {\r\n throw this.createMissingClientIdError();\r\n }\r\n\r\n const configApiUrl = this.getConfigApiUrl(this.runtimeConfig.isProd);\r\n this.CONFIG_API_URL = configApiUrl;\r\n const requestUrl = `${configApiUrl}?clientId=${this.runtimeConfig.clientId}&url=${encodeURIComponent(currentUrl)}`;\r\n platformLogger.debug('请求微信配置', { url: requestUrl });\r\n \r\n try {\r\n const response = await fetch(requestUrl);\r\n \r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n \r\n const result = await response.json();\r\n platformLogger.debug('微信配置响应', result);\r\n \r\n // 检查响应格式\r\n if (!result.success || result.code !== 200) {\r\n throw new Error(`配置获取失败: ${result.message || '未知错误'}`);\r\n }\r\n \r\n // 验证必需的字段\r\n const { data } = result;\r\n if (!data || !data.appId || !data.timestamp || !data.nonceStr || !data.signature) {\r\n throw new Error('配置数据格式不正确,缺少必需字段');\r\n }\r\n \r\n return data;\r\n \r\n } catch (error) {\r\n platformLogger.error('获取微信配置失败', error);\r\n \r\n // 如果在开发环境且不是真正的微信环境,提供降级方案\r\n if (this.shouldUseTestMode(error)) {\r\n platformLogger.warn('网络请求失败,降级到测试模式');\r\n return this.getMockConfig();\r\n }\r\n \r\n throw new QshError(\r\n ErrorTypes.NETWORK_ERROR,\r\n `获取微信配置失败: ${error.message}`,\r\n { url: requestUrl, originalError: error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * 检查是否为测试模式\r\n * @returns {boolean}\r\n * @private\r\n */\r\n isTestMode() {\r\n if (typeof window === 'undefined') return false;\r\n \r\n // 通过URL参数启用测试模式\r\n const urlParams = new URLSearchParams(window.location.search);\r\n if (urlParams.get('qsh_test') === 'true') return true;\r\n \r\n // 通过localStorage启用测试模式\r\n try {\r\n if (localStorage.getItem('qsh_test') === 'true') return true;\r\n } catch (e) {\r\n // localStorage访问失败,忽略\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * 检查是否应该降级到测试模式\r\n * @param {Error} error - 网络错误\r\n * @returns {boolean}\r\n * @private\r\n */\r\n shouldUseTestMode(error) {\r\n // 在开发环境且不是真正的微信小程序环境时,可以降级\r\n if (typeof window === 'undefined') return false;\r\n\r\n const isDev = window.location.hostname === 'localhost' || \r\n window.location.hostname.includes('natappfree.cc');\r\n const notInWeixin = !window.wx || !window.wx.miniProgram;\r\n const isCorsError = error.message.includes('CORS') || error.message.includes('Failed to fetch');\r\n \r\n return isDev && notInWeixin && isCorsError;\r\n }\r\n\r\n /**\r\n * 获取模拟配置(用于测试)\r\n * @returns {Object} 模拟的配置对象\r\n * @private\r\n */\r\n getMockConfig() {\r\n return {\r\n appId: 'wx_test_app_id',\r\n timestamp: Math.floor(Date.now() / 1000).toString(),\r\n nonceStr: Math.random().toString(36).substring(2, 15),\r\n signature: 'test_signature_' + Math.random().toString(36).substring(2, 10)\r\n };\r\n }\r\n\r\n /**\r\n * 执行微信配置\r\n * @param {Object} configData - 配置数据\r\n * @private\r\n */\r\n executeWeixinConfig(configData) {\r\n // 检查是否为测试模式\r\n if (this.isTestMode() || configData.appId === 'wx_test_app_id') {\r\n platformLogger.info('测试模式:模拟微信配置成功');\r\n // 延迟执行成功回调,模拟异步配置过程\r\n setTimeout(() => {\r\n this.handleConfigSuccess();\r\n }, 100);\r\n return;\r\n }\r\n \r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信JS-SDK未加载');\r\n }\r\n \r\n const configOptions = {\r\n debug: false, // 生产环境关闭调试\r\n appId: configData.appId,\r\n timestamp: parseInt(configData.timestamp),\r\n nonceStr: configData.nonceStr,\r\n signature: configData.signature,\r\n jsApiList: this.DEFAULT_JS_API_LIST\r\n };\r\n \r\n platformLogger.info('执行微信配置', configOptions);\r\n \r\n // 设置成功和错误回调\r\n window.wx.ready(this.handleConfigSuccess);\r\n window.wx.error(this.handleConfigError);\r\n \r\n // 执行配置\r\n window.wx.config(configOptions);\r\n }\r\n\r\n /**\r\n * 处理配置成功\r\n * @private\r\n */\r\n handleConfigSuccess() {\r\n platformLogger.info('微信配置成功');\r\n this.state = WeixinConfigStates.CONFIGURED;\r\n this.lastError = null;\r\n this.configPromise = null;\r\n\r\n const readyCallbacks = [...this.readyCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n readyCallbacks.forEach(callback => {\r\n try {\r\n callback();\r\n } catch (error) {\r\n ErrorHandler.handleApiError(error, { context: 'WeixinConfigManager.handleConfigSuccess' });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 处理配置错误\r\n * @param {Object} res - 微信返回的错误信息\r\n * @private\r\n */\r\n handleConfigError(res) {\r\n const errorMessage = `微信配置验证失败: ${JSON.stringify(res)}`;\r\n platformLogger.error(errorMessage, res);\r\n \r\n const qshError = new QshError(\r\n ErrorTypes.API_CALL_FAILED,\r\n errorMessage,\r\n { weixinErrorResponse: res }\r\n );\r\n \r\n // 通知所有等待的错误回调\r\n\r\n this.state = WeixinConfigStates.ERROR;\r\n this.lastError = qshError;\r\n this.configPromise = null;\r\n\r\n const errorCallbacks = [...this.errorCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n errorCallbacks.forEach((callback) => {\r\n try {\r\n callback(qshError);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'WeixinConfigManager.handleConfigError' });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 自动配置微信JS-SDK\r\n * @returns {Promise<void>} 配置完成的Promise\r\n */\r\n async autoConfig() {\r\n if (!this.hasRequiredConfig()) {\r\n platformLogger.warn('clientId为空,等待qsh.config({ clientId })');\r\n return Promise.resolve();\r\n }\r\n\r\n // 如果已经配置过,直接返回\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n return Promise.resolve();\r\n }\r\n \r\n // 如果出错,返回错误\r\n if (this.state === WeixinConfigStates.ERROR) {\r\n return Promise.reject(this.lastError);\r\n }\r\n \r\n // 如果正在配置中,返回现有的Promise\r\n if (this.configPromise) {\r\n return this.configPromise;\r\n }\r\n \r\n // 开始配置\r\n this.state = WeixinConfigStates.CONFIGURING;\r\n \r\n this.configPromise = this.performAutoConfig();\r\n return this.configPromise;\r\n }\r\n\r\n /**\r\n * 执行自动配置逻辑\r\n * @returns {Promise<void>}\r\n * @private\r\n */\r\n async performAutoConfig() {\r\n try {\r\n // 检查环境\r\n if (typeof window === 'undefined') {\r\n throw new Error('非浏览器环境无法执行微信配置');\r\n }\r\n \r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信JS-SDK未加载,无法执行配置');\r\n }\r\n \r\n // 获取配置数据\r\n const configData = await this.fetchWeixinConfig();\r\n \r\n // 执行配置\r\n this.executeWeixinConfig(configData);\r\n \r\n // 等待配置完成\r\n return await new Promise((resolve, reject) => {\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n resolve();\r\n return;\r\n }\r\n \r\n if (this.state === WeixinConfigStates.ERROR) {\r\n reject(this.lastError);\r\n return;\r\n }\r\n \r\n // 添加到回调列表\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n });\r\n } catch (error) {\r\n const qshError = error instanceof QshError\r\n ? error\r\n : ErrorHandler.handleApiError(error, { context: 'WeixinConfigManager.performAutoConfig' });\r\n\r\n this.state = WeixinConfigStates.ERROR;\r\n this.lastError = qshError;\r\n this.configPromise = null;\r\n\r\n const errorCallbacks = [...this.errorCallbacks];\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n\r\n errorCallbacks.forEach((callback) => {\r\n try {\r\n callback(qshError);\r\n } catch (callbackError) {\r\n ErrorHandler.handleApiError(callbackError, { context: 'WeixinConfigManager.performAutoConfig.errorCallback' });\r\n }\r\n });\r\n\r\n throw qshError;\r\n }\r\n }\r\n /**\r\n * 等待配置完成\r\n * @returns {Promise<void>} 配置完成的Promise\r\n */\r\n waitForReady() {\r\n if (this.state === WeixinConfigStates.CONFIGURED) {\r\n return Promise.resolve();\r\n }\r\n \r\n if (this.state === WeixinConfigStates.ERROR) {\r\n return Promise.reject(this.lastError);\r\n }\r\n \r\n if (!this.hasRequiredConfig()) {\r\n return Promise.reject(this.createMissingClientIdError());\r\n }\r\n // 如果未开始配置,先启动配置\r\n if (this.state === WeixinConfigStates.UNINITIALIZED) {\r\n return this.autoConfig();\r\n }\r\n \r\n // 等待配置完成\r\n return new Promise((resolve, reject) => {\r\n this.readyCallbacks.push(resolve);\r\n this.errorCallbacks.push(reject);\r\n });\r\n }\r\n\r\n /**\r\n * 检查配置状态\r\n * @returns {boolean} 是否已配置\r\n */\r\n isReady() {\r\n return this.state === WeixinConfigStates.CONFIGURED;\r\n }\r\n\r\n /**\r\n * 获取当前状态\r\n * @returns {string} 当前状态\r\n */\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n /**\r\n * 获取最后的错误\r\n * @returns {Error|null} 错误对象\r\n */\r\n getLastError() {\r\n return this.lastError;\r\n }\r\n\r\n /**\r\n * 重置配置管理器(用于重试或测试)\r\n */\r\n reset() {\r\n this.state = WeixinConfigStates.UNINITIALIZED;\r\n this.configPromise = null;\r\n this.readyCallbacks = [];\r\n this.errorCallbacks = [];\r\n this.lastError = null;\r\n \r\n platformLogger.debug('微信配置管理器已重置');\r\n }\r\n\r\n /**\r\n * 获取配置统计信息\r\n * @returns {Object} 统计信息\r\n */\r\n getStats() {\r\n return {\r\n state: this.state,\r\n readyCallbacksCount: this.readyCallbacks.length,\r\n errorCallbacksCount: this.errorCallbacks.length,\r\n hasConfigPromise: !!this.configPromise,\r\n hasLastError: !!this.lastError,\r\n configApiUrl: this.CONFIG_API_URL,\r\n clientId: this.runtimeConfig.clientId,\r\n isProd: this.runtimeConfig.isProd,\r\n jsApiList: this.DEFAULT_JS_API_LIST\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst weixinConfigManager = new WeixinConfigManager();\r\n\r\nexport default weixinConfigManager;\r\n","/**\r\n * 微信 JS-SDK 自动加载器和配置器\r\n * 在检测到微信小程序 web-view 环境时:\r\n * 1. 自动注入 jweixin 脚本(如果未引入)\r\n * 2. 自动获取配置并执行 wx.config\r\n */\r\n\r\nimport weixinConfigManager, { isWeixinJSSDKAvailable } from './weixin-config.js';\r\nimport { platformLogger } from './logger.js';\r\n\r\nlet isLoadingWeixinSDK = false;\r\nlet weixinSDKLoaded = false;\r\nlet weixinSDKLoadPromise = null;\r\nlet autoConfigStarted = false;\r\n\r\nfunction waitForExistingWeixinScript(script) {\r\n return new Promise((resolve) => {\r\n let settled = false;\r\n let timeoutId = null;\r\n\r\n const finish = async (loaded) => {\r\n if (settled) return;\r\n settled = true;\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n isLoadingWeixinSDK = false;\r\n weixinSDKLoaded = loaded;\r\n\r\n if (loaded) {\r\n try {\r\n await autoConfigWeixin();\r\n } catch (error) {\r\n platformLogger.error('微信配置失败,将使用消息桥作为后备', error);\r\n }\r\n }\r\n\r\n resolve();\r\n };\r\n\r\n const handleLoad = () => finish(isWeixinJSSDKAvailable());\r\n const handleError = () => {\r\n platformLogger.warn('已存在的微信 JS-SDK 脚本加载失败,SDK 将使用消息桥作为后备');\r\n finish(false);\r\n };\r\n\r\n script.addEventListener('load', handleLoad, { once: true });\r\n script.addEventListener('error', handleError, { once: true });\r\n\r\n setTimeout(() => {\r\n if (isWeixinJSSDKAvailable()) {\r\n handleLoad();\r\n }\r\n }, 0);\r\n\r\n timeoutId = setTimeout(() => {\r\n finish(isWeixinJSSDKAvailable());\r\n }, 3000);\r\n });\r\n}\r\n\r\nasync function ensureWeixinJSSDKLoaded(options = {}) {\r\n const { force = false, recoverFromError = false } = options;\r\n\r\n await loadWeixinJSSDKIfNeeded({ force });\r\n\r\n if (!isWeixinJSSDKAvailable()) {\r\n throw new Error('微信 JS-SDK 未正确加载,无法执行配置');\r\n }\r\n\r\n if (recoverFromError) {\r\n recoverWeixinConfigStateIfNeeded();\r\n }\r\n}\r\n\r\n/**\r\n * 判断是否需要加载 jweixin\r\n * @returns {boolean}\r\n */\r\nfunction shouldLoadWeixinSDK(force = false) {\r\n if (typeof window === 'undefined') return false;\r\n if (isWeixinJSSDKAvailable()) {\r\n weixinSDKLoaded = true;\r\n return false;\r\n }\r\n if (weixinSDKLoaded) return false;\r\n if (force) return true;\r\n const ua = navigator.userAgent || '';\r\n const inWeixin = /micromessenger/i.test(ua);\r\n const inMiniProgramUA = /miniProgram/i.test(ua);\r\n const hintedMiniProgram = typeof window.__wxjs_environment !== 'undefined' && window.__wxjs_environment === 'miniprogram';\r\n const hasMiniProgramBridge = !!(window.wx && window.wx.miniProgram);\r\n return inWeixin && (inMiniProgramUA || hintedMiniProgram || hasMiniProgramBridge);\r\n}\r\n\r\nfunction recoverWeixinConfigStateIfNeeded() {\r\n if (weixinConfigManager.getState() === 'error') {\r\n weixinConfigManager.reset();\r\n autoConfigStarted = false;\r\n }\r\n}\r\n\r\n/**\r\n * 自动执行微信配置\r\n * @returns {Promise<void>}\r\n * @private\r\n */\r\nasync function autoConfigWeixin() {\r\n if (autoConfigStarted) {\r\n return weixinConfigManager.waitForReady();\r\n }\r\n \r\n autoConfigStarted = true;\r\n platformLogger.info('开始自动配置微信JS-SDK');\r\n \r\n try {\r\n await weixinConfigManager.autoConfig();\r\n platformLogger.info('微信JS-SDK自动配置完成');\r\n } catch (error) {\r\n platformLogger.error('微信JS-SDK自动配置失败', error);\r\n // 不抛出错误,让SDK继续运行,使用消息桥作为后备\r\n }\r\n}\r\n\r\n/**\r\n * 按需加载微信 JS-SDK 并自动配置(幂等)\r\n * @returns {Promise<void>}\r\n * @example\r\n * await loadWeixinJSSDKIfNeeded()\r\n * @since 2.0.0\r\n */\r\nexport function loadWeixinJSSDKIfNeeded(options = {}) {\r\n const { force = false } = options;\r\n\r\n if (typeof window === 'undefined') {\r\n return Promise.resolve();\r\n }\r\n\r\n if (isWeixinJSSDKAvailable()) {\r\n weixinSDKLoaded = true;\r\n return Promise.resolve();\r\n }\r\n\r\n // 避免重复注入\r\n const existingScript = document.getElementById('weixin-jssdk');\r\n if (existingScript) {\r\n if (weixinSDKLoadPromise) {\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n isLoadingWeixinSDK = true;\r\n weixinSDKLoadPromise = waitForExistingWeixinScript(existingScript).finally(() => {\r\n weixinSDKLoadPromise = null;\r\n });\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n if (!shouldLoadWeixinSDK(force)) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (weixinSDKLoadPromise) {\r\n return weixinSDKLoadPromise;\r\n }\r\n\r\n weixinSDKLoadPromise = new Promise((resolve) => {\r\n isLoadingWeixinSDK = true;\r\n \r\n try {\r\n const script = document.createElement('script');\r\n script.id = 'weixin-jssdk';\r\n script.type = 'text/javascript';\r\n script.async = true;\r\n script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.2.js';\r\n \r\n script.onload = async function() {\r\n weixinSDKLoaded = true;\r\n isLoadingWeixinSDK = false;\r\n platformLogger.info('微信 JS-SDK 已自动加载');\r\n \r\n // 自动执行配置\r\n try {\r\n await autoConfigWeixin();\r\n } catch (error) {\r\n platformLogger.error('微信配置失败,将使用消息桥作为后备', error);\r\n }\r\n resolve();\r\n };\r\n \r\n script.onerror = function() {\r\n isLoadingWeixinSDK = false;\r\n platformLogger.warn('微信 JS-SDK 加载失败,SDK 将使用消息桥作为后备');\r\n resolve(); // 即使加载失败也resolve,让SDK继续运行\r\n };\r\n\r\n // 尽可能早插入到 <head>\r\n const head = document.getElementsByTagName('head')[0] || document.documentElement;\r\n head.appendChild(script);\r\n } catch (err) {\r\n isLoadingWeixinSDK = false;\r\n platformLogger.error('注入微信 JS-SDK 失败', err);\r\n resolve(); // 即使注入失败也resolve,让SDK继续运行\r\n }\r\n }).finally(() => {\r\n weixinSDKLoadPromise = null;\r\n });\r\n\r\n return weixinSDKLoadPromise;\r\n}\r\n\r\n/**\r\n * 等待微信配置完成\r\n * @returns {Promise<void>} 配置完成的Promise\r\n * @example\r\n * await waitForWeixinConfig()\r\n * @since 2.0.0\r\n */\r\nexport function waitForWeixinConfig() {\r\n return ensureWeixinJSSDKLoaded({ force: true, recoverFromError: true })\r\n .then(() => weixinConfigManager.waitForReady());\r\n}\r\n\r\nexport function configureWeixin(options = {}) {\r\n const runtimeConfig = weixinConfigManager.configure(options);\r\n\r\n if (typeof window === 'undefined') {\r\n return runtimeConfig;\r\n }\r\n\r\n ensureWeixinJSSDKLoaded({\r\n force: true,\r\n recoverFromError: weixinConfigManager.getState() === 'error'\r\n })\r\n .then(() => {\r\n if (!weixinConfigManager.isReady()) {\r\n return weixinConfigManager.waitForReady().catch((error) => {\r\n platformLogger.error('Failed to auto-configure Weixin after qsh.config()', error);\r\n });\r\n }\r\n\r\n if (window.wx && !isWeixinJSSDKAvailable()) {\r\n platformLogger.warn('window.wx 已存在,但微信 JS-SDK 尚未就绪,跳过自动配置');\r\n }\r\n\r\n return undefined;\r\n })\r\n .catch((error) => {\r\n platformLogger.error('Failed to preload Weixin JS-SDK', error);\r\n });\r\n\r\n return runtimeConfig;\r\n}\r\n\r\n/**\r\n * 检查微信配置是否完成\r\n * @returns {boolean} 是否已配置\r\n * @example\r\n * if (isWeixinConfigReady()) { console.log('ready') }\r\n * @since 2.0.0\r\n */\r\nexport function isWeixinConfigReady() {\r\n return weixinConfigManager.isReady();\r\n}\r\n\r\n/**\r\n * 获取微信配置状态\r\n * @returns {string} 配置状态\r\n * @example\r\n * console.log(getWeixinConfigState()) // returns state string\r\n * @since 2.0.0\r\n */\r\nexport function getWeixinConfigState() {\r\n return weixinConfigManager.getState();\r\n}\r\n\r\n/**\r\n * 获取微信配置管理器(用于调试)\r\n * @returns {Object} 配置管理器实例\r\n * @example\r\n * const stats = getWeixinConfigManager().getStats()\r\n * @since 2.0.0\r\n */\r\nexport function getWeixinConfigManager() {\r\n return weixinConfigManager;\r\n}\r\n\r\n/**\r\n * 手动重试微信配置(用于错误恢复)\r\n * @returns {Promise<void>} 配置完成的Promise\r\n * @example\r\n * await retryWeixinConfig()\r\n * @since 2.0.0\r\n */\r\nexport async function retryWeixinConfig() {\r\n platformLogger.info('手动重试微信配置');\r\n weixinConfigManager.reset();\r\n autoConfigStarted = false;\r\n await ensureWeixinJSSDKLoaded({ force: true });\r\n return weixinConfigManager.waitForReady();\r\n}\r\n","/**\r\n * 插件管理器\r\n * 提供插件注册、安装、卸载等功能\r\n */\r\n\r\nimport { apiLogger } from './logger.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * 插件接口定义\r\n * @typedef {Object} Plugin\r\n * @property {string} name - 插件名称\r\n * @property {string} version - 插件版本\r\n * @property {Function} install - 安装函数 (qsh) => void\r\n * @property {Function} [uninstall] - 卸载函数 (qsh) => void (可选)\r\n * @property {string[]} [dependencies] - 依赖的其他插件 (可选)\r\n */\r\n\r\n/**\r\n * 插件管理器类(单例)\r\n */\r\nexport class PluginManager {\r\n constructor() {\r\n // 已注册的插件\r\n this.plugins = new Map();\r\n \r\n // 已安装的插件\r\n this.installed = new Set();\r\n \r\n // 插件安装顺序(用于卸载时反向执行)\r\n this.installOrder = [];\r\n \r\n apiLogger.debug('插件管理器已初始化');\r\n }\r\n\r\n /**\r\n * 注册插件\r\n * @param {Plugin} plugin - 插件对象\r\n * @returns {PluginManager} 返回自身以支持链式调用\r\n * @example\r\n * pluginManager.register(imagePlugin)\r\n */\r\n register(plugin) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 验证插件对象\r\n this.validatePlugin(plugin);\r\n \r\n const { name, version } = plugin;\r\n \r\n // 检查是否已注册\r\n if (this.plugins.has(name)) {\r\n const existing = this.plugins.get(name);\r\n apiLogger.warn(`插件 ${name} 已注册(版本 ${existing.version}),将被覆盖为版本 ${version}`);\r\n }\r\n \r\n // 注册插件\r\n this.plugins.set(name, plugin);\r\n apiLogger.info(`插件已注册: ${name}@${version}`);\r\n \r\n return this;\r\n }, { \r\n context: 'PluginManager.register',\r\n pluginName: plugin?.name \r\n });\r\n }\r\n\r\n /**\r\n * 验证插件对象\r\n * @param {Plugin} plugin - 插件对象\r\n * @throws {Error} 验证失败时抛出错误\r\n * @private\r\n */\r\n validatePlugin(plugin) {\r\n if (!plugin || typeof plugin !== 'object') {\r\n throw new Error('插件必须是一个对象');\r\n }\r\n \r\n if (!plugin.name || typeof plugin.name !== 'string') {\r\n throw new Error('插件必须有 name 属性(字符串)');\r\n }\r\n \r\n if (!plugin.version || typeof plugin.version !== 'string') {\r\n throw new Error(`插件 ${plugin.name} 必须有 version 属性(字符串)`);\r\n }\r\n \r\n if (!plugin.install || typeof plugin.install !== 'function') {\r\n throw new Error(`插件 ${plugin.name} 必须实现 install 方法`);\r\n }\r\n \r\n // 验证依赖项\r\n if (plugin.dependencies) {\r\n if (!Array.isArray(plugin.dependencies)) {\r\n throw new Error(`插件 ${plugin.name} 的 dependencies 必须是数组`);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 安装插件到 qsh 实例\r\n * @param {string} name - 插件名称\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.install('image', qsh)\r\n */\r\n async install(name, qshInstance) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 检查插件是否已注册\r\n if (!this.plugins.has(name)) {\r\n throw new Error(`插件 ${name} 未注册`);\r\n }\r\n \r\n // 检查是否已安装\r\n if (this.installed.has(name)) {\r\n apiLogger.debug(`插件 ${name} 已安装,跳过`);\r\n return;\r\n }\r\n \r\n const plugin = this.plugins.get(name);\r\n \r\n // 安装依赖项\r\n if (plugin.dependencies && plugin.dependencies.length > 0) {\r\n apiLogger.debug(`安装插件 ${name} 的依赖:`, plugin.dependencies);\r\n for (const depName of plugin.dependencies) {\r\n await this.install(depName, qshInstance);\r\n }\r\n }\r\n \r\n // 执行插件安装\r\n apiLogger.info(`开始安装插件: ${name}@${plugin.version}`);\r\n await plugin.install(qshInstance);\r\n \r\n // 标记为已安装\r\n this.installed.add(name);\r\n this.installOrder.push(name);\r\n \r\n apiLogger.info(`插件安装成功: ${name}@${plugin.version}`);\r\n \r\n }, { \r\n context: 'PluginManager.install',\r\n pluginName: name \r\n });\r\n }\r\n\r\n /**\r\n * 卸载插件\r\n * @param {string} name - 插件名称\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.uninstall('image', qsh)\r\n */\r\n async uninstall(name, qshInstance) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 检查是否已安装\r\n if (!this.installed.has(name)) {\r\n apiLogger.debug(`插件 ${name} 未安装,跳过卸载`);\r\n return;\r\n }\r\n \r\n const plugin = this.plugins.get(name);\r\n \r\n // 执行卸载(如果有)\r\n if (plugin.uninstall && typeof plugin.uninstall === 'function') {\r\n apiLogger.info(`开始卸载插件: ${name}`);\r\n await plugin.uninstall(qshInstance);\r\n }\r\n \r\n // 移除安装标记\r\n this.installed.delete(name);\r\n const orderIndex = this.installOrder.indexOf(name);\r\n if (orderIndex > -1) {\r\n this.installOrder.splice(orderIndex, 1);\r\n }\r\n \r\n apiLogger.info(`插件已卸载: ${name}`);\r\n \r\n }, { \r\n context: 'PluginManager.uninstall',\r\n pluginName: name \r\n });\r\n }\r\n\r\n /**\r\n * 卸载所有已安装的插件\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n */\r\n async uninstallAll(qshInstance) {\r\n // 按安装顺序的反向卸载\r\n const names = [...this.installOrder].reverse();\r\n for (const name of names) {\r\n await this.uninstall(name, qshInstance);\r\n }\r\n }\r\n\r\n /**\r\n * 批量注册插件\r\n * @param {Plugin[]} plugins - 插件数组\r\n * @returns {PluginManager} 返回自身以支持链式调用\r\n * @example\r\n * pluginManager.registerAll([imagePlugin, locationPlugin])\r\n */\r\n registerAll(plugins) {\r\n if (!Array.isArray(plugins)) {\r\n throw new Error('plugins 必须是数组');\r\n }\r\n \r\n plugins.forEach(plugin => this.register(plugin));\r\n return this;\r\n }\r\n\r\n /**\r\n * 批量安装插件\r\n * @param {string[]} names - 插件名称数组\r\n * @param {Object} qshInstance - qsh SDK 实例\r\n * @returns {Promise<void>}\r\n * @example\r\n * await pluginManager.installAll(['image', 'location'], qsh)\r\n */\r\n async installAll(names, qshInstance) {\r\n if (!Array.isArray(names)) {\r\n throw new Error('names 必须是数组');\r\n }\r\n \r\n for (const name of names) {\r\n await this.install(name, qshInstance);\r\n }\r\n }\r\n\r\n /**\r\n * 检查插件是否已注册\r\n * @param {string} name - 插件名称\r\n * @returns {boolean}\r\n */\r\n isRegistered(name) {\r\n return this.plugins.has(name);\r\n }\r\n\r\n /**\r\n * 检查插件是否已安装\r\n * @param {string} name - 插件名称\r\n * @returns {boolean}\r\n */\r\n isInstalled(name) {\r\n return this.installed.has(name);\r\n }\r\n\r\n /**\r\n * 获取插件信息\r\n * @param {string} name - 插件名称\r\n * @returns {Plugin|undefined}\r\n */\r\n getPlugin(name) {\r\n return this.plugins.get(name);\r\n }\r\n\r\n /**\r\n * 获取所有已注册的插件列表\r\n * @returns {Array<{name: string, version: string, installed: boolean}>}\r\n */\r\n getPluginList() {\r\n return Array.from(this.plugins.entries()).map(([name, plugin]) => ({\r\n name,\r\n version: plugin.version,\r\n installed: this.installed.has(name),\r\n dependencies: plugin.dependencies || []\r\n }));\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n registered: this.plugins.size,\r\n installed: this.installed.size,\r\n plugins: this.getPluginList()\r\n };\r\n }\r\n\r\n /**\r\n * 清空所有插件(仅用于测试)\r\n * @private\r\n */\r\n clear() {\r\n this.plugins.clear();\r\n this.installed.clear();\r\n this.installOrder = [];\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst pluginManager = new PluginManager();\r\n\r\nexport default pluginManager;\r\n\r\n","/**\r\n * 拦截器链\r\n * 提供请求和响应的拦截机制\r\n */\r\n\r\nimport { apiLogger } from './logger.js';\r\nimport { ErrorHandler } from './error-handler.js';\r\n\r\n/**\r\n * 拦截器上下文\r\n * @typedef {Object} InterceptorContext\r\n * @property {string} apiName - API 名称\r\n * @property {Object} params - 参数对象\r\n * @property {Object} callbacks - 回调函数\r\n * @property {number} timestamp - 时间戳\r\n * @property {boolean} abort - 是否中止执行\r\n * @property {any} [metadata] - 元数据(可由拦截器添加)\r\n */\r\n\r\n/**\r\n * 拦截器函数\r\n * @callback InterceptorFunction\r\n * @param {InterceptorContext} context - 上下文对象\r\n * @returns {Promise<InterceptorContext|void>|InterceptorContext|void}\r\n */\r\n\r\n/**\r\n * 拦截器链类\r\n */\r\nexport class InterceptorChain {\r\n constructor() {\r\n // 请求拦截器列表\r\n this.requestInterceptors = [];\r\n \r\n // 响应拦截器列表\r\n this.responseInterceptors = [];\r\n \r\n apiLogger.debug('拦截器链已初始化');\r\n }\r\n\r\n /**\r\n * 注册请求拦截器\r\n * @param {InterceptorFunction} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @param {number} [options.priority=0] - 优先级(数字越大越先执行)\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * const unregister = chain.useRequest(async (ctx) => {\r\n * console.log('API 调用:', ctx.apiName)\r\n * return ctx\r\n * })\r\n */\r\n useRequest(interceptor, options = {}) {\r\n if (typeof interceptor !== 'function') {\r\n throw new Error('拦截器必须是函数');\r\n }\r\n \r\n const { priority = 0 } = options;\r\n \r\n // 添加到列表\r\n this.requestInterceptors.push({\r\n fn: interceptor,\r\n priority\r\n });\r\n \r\n // 按优先级排序(降序)\r\n this.requestInterceptors.sort((a, b) => b.priority - a.priority);\r\n \r\n apiLogger.debug('请求拦截器已注册', { priority });\r\n \r\n // 返回移除函数\r\n return () => {\r\n const index = this.requestInterceptors.findIndex(item => item.fn === interceptor);\r\n if (index > -1) {\r\n this.requestInterceptors.splice(index, 1);\r\n apiLogger.debug('请求拦截器已移除');\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 注册响应拦截器\r\n * @param {Function} interceptor - 拦截器函数 (result, context) => result\r\n * @param {Object} [options] - 选项\r\n * @param {number} [options.priority=0] - 优先级(数字越大越先执行)\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * const unregister = chain.useResponse(async (result, ctx) => {\r\n * console.log('API 完成:', ctx.apiName)\r\n * return result\r\n * })\r\n */\r\n useResponse(interceptor, options = {}) {\r\n if (typeof interceptor !== 'function') {\r\n throw new Error('拦截器必须是函数');\r\n }\r\n \r\n const { priority = 0 } = options;\r\n \r\n // 添加到列表\r\n this.responseInterceptors.push({\r\n fn: interceptor,\r\n priority\r\n });\r\n \r\n // 按优先级排序(降序)\r\n this.responseInterceptors.sort((a, b) => b.priority - a.priority);\r\n \r\n apiLogger.debug('响应拦截器已注册', { priority });\r\n \r\n // 返回移除函数\r\n return () => {\r\n const index = this.responseInterceptors.findIndex(item => item.fn === interceptor);\r\n if (index > -1) {\r\n this.responseInterceptors.splice(index, 1);\r\n apiLogger.debug('响应拦截器已移除');\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 执行请求拦截链\r\n * @param {InterceptorContext} context - 上下文\r\n * @returns {Promise<InterceptorContext>}\r\n * @private\r\n */\r\n async runRequest(context) {\r\n let ctx = { ...context };\r\n \r\n for (const { fn } of this.requestInterceptors) {\r\n if (ctx.abort) {\r\n apiLogger.debug('请求被中止', { apiName: ctx.apiName });\r\n break;\r\n }\r\n \r\n try {\r\n const result = await fn(ctx);\r\n // 拦截器可以返回新的 context 或不返回(使用原 context)\r\n if (result) {\r\n ctx = result;\r\n }\r\n } catch (error) {\r\n apiLogger.error('请求拦截器执行失败', error);\r\n // 标记中止\r\n ctx.abort = true;\r\n ctx.error = error;\r\n break;\r\n }\r\n }\r\n \r\n return ctx;\r\n }\r\n\r\n /**\r\n * 执行响应拦截链\r\n * @param {any} result - 响应结果\r\n * @param {InterceptorContext} context - 上下文\r\n * @returns {Promise<any>}\r\n * @private\r\n */\r\n async runResponse(result, context) {\r\n let res = result;\r\n \r\n for (const { fn } of this.responseInterceptors) {\r\n try {\r\n const newResult = await fn(res, context);\r\n // 拦截器可以返回新的 result 或不返回(使用原 result)\r\n if (newResult !== undefined) {\r\n res = newResult;\r\n }\r\n } catch (error) {\r\n apiLogger.error('响应拦截器执行失败', error);\r\n // 响应拦截器失败不中断流程,只记录日志\r\n }\r\n }\r\n \r\n return res;\r\n }\r\n\r\n /**\r\n * 清空所有拦截器\r\n */\r\n clear() {\r\n this.requestInterceptors = [];\r\n this.responseInterceptors = [];\r\n apiLogger.debug('所有拦截器已清空');\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n requestInterceptors: this.requestInterceptors.length,\r\n responseInterceptors: this.responseInterceptors.length\r\n };\r\n }\r\n}\r\n\r\n// 创建全局拦截器链实例\r\nconst interceptorChain = new InterceptorChain();\r\n\r\nexport default interceptorChain;\r\n\r\n// ========== 内置拦截器 ==========\r\n\r\n/**\r\n * 日志拦截器\r\n * 记录 API 调用的开始和结束\r\n */\r\nexport const loggingInterceptor = {\r\n /**\r\n * 请求日志\r\n */\r\n request: (ctx) => {\r\n ctx.startTime = Date.now();\r\n apiLogger.debug(`[API 调用] ${ctx.apiName}`, {\r\n params: ctx.params\r\n });\r\n return ctx;\r\n },\r\n \r\n /**\r\n * 响应日志\r\n */\r\n response: (result, ctx) => {\r\n const duration = Date.now() - ctx.startTime;\r\n apiLogger.debug(`[API 完成] ${ctx.apiName}`, {\r\n duration: `${duration}ms`,\r\n success: result?.success\r\n });\r\n return result;\r\n }\r\n};\r\n\r\n/**\r\n * 性能监控拦截器\r\n * 收集 API 调用性能数据\r\n */\r\nexport const performanceInterceptor = {\r\n // 性能数据存储\r\n metrics: new Map(),\r\n \r\n /**\r\n * 记录开始时间\r\n */\r\n request: (ctx) => {\r\n ctx.perfStartTime = performance.now();\r\n return ctx;\r\n },\r\n \r\n /**\r\n * 记录性能数据\r\n */\r\n response: (result, ctx) => {\r\n const duration = performance.now() - ctx.perfStartTime;\r\n \r\n // 更新统计信息\r\n if (!performanceInterceptor.metrics.has(ctx.apiName)) {\r\n performanceInterceptor.metrics.set(ctx.apiName, {\r\n count: 0,\r\n totalTime: 0,\r\n minTime: Infinity,\r\n maxTime: 0,\r\n avgTime: 0\r\n });\r\n }\r\n \r\n const metrics = performanceInterceptor.metrics.get(ctx.apiName);\r\n metrics.count++;\r\n metrics.totalTime += duration;\r\n metrics.minTime = Math.min(metrics.minTime, duration);\r\n metrics.maxTime = Math.max(metrics.maxTime, duration);\r\n metrics.avgTime = metrics.totalTime / metrics.count;\r\n \r\n return result;\r\n },\r\n \r\n /**\r\n * 获取性能报告\r\n */\r\n getReport: () => {\r\n const report = {};\r\n performanceInterceptor.metrics.forEach((value, key) => {\r\n report[key] = { ...value };\r\n });\r\n return report;\r\n },\r\n \r\n /**\r\n * 清空性能数据\r\n */\r\n clearMetrics: () => {\r\n performanceInterceptor.metrics.clear();\r\n }\r\n};\r\n\r\n/**\r\n * 重试拦截器\r\n * 失败时自动重试\r\n * @param {Object} options - 选项\r\n * @param {number} [options.maxRetries=3] - 最大重试次数\r\n * @param {number} [options.retryDelay=1000] - 重试延迟(毫秒)\r\n * @param {Function} [options.shouldRetry] - 判断是否应该重试的函数\r\n */\r\nexport function createRetryInterceptor(options = {}) {\r\n const {\r\n maxRetries = 3,\r\n retryDelay = 1000,\r\n shouldRetry = (result) => !result.success\r\n } = options;\r\n \r\n return {\r\n response: async (result, ctx) => {\r\n // 初始化重试次数\r\n if (!ctx.retryCount) {\r\n ctx.retryCount = 0;\r\n }\r\n \r\n // 检查是否需要重试\r\n if (shouldRetry(result) && ctx.retryCount < maxRetries) {\r\n ctx.retryCount++;\r\n \r\n apiLogger.warn(`API 调用失败,第 ${ctx.retryCount} 次重试: ${ctx.apiName}`);\r\n \r\n // 延迟后重新调用(需要在 WebViewBridge 中支持)\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n \r\n // 标记需要重试\r\n result.shouldRetry = true;\r\n result.retryContext = ctx;\r\n }\r\n \r\n return result;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * 参数验证拦截器\r\n * @param {Object} rules - 验证规则 { apiName: validatorFn }\r\n */\r\nexport function createValidationInterceptor(rules = {}) {\r\n return {\r\n request: (ctx) => {\r\n const validator = rules[ctx.apiName];\r\n \r\n if (validator && typeof validator === 'function') {\r\n const error = validator(ctx.params);\r\n if (error) {\r\n apiLogger.error(`参数验证失败: ${ctx.apiName}`, error);\r\n ctx.abort = true;\r\n ctx.validationError = error;\r\n }\r\n }\r\n \r\n return ctx;\r\n }\r\n };\r\n}\r\n\r\n","/**\r\n * 状态仓库\r\n * 提供分层的状态管理和订阅机制\r\n */\r\n\r\nimport { stateLogger } from './logger.js';\r\nimport { environment } from './environment.js';\r\n\r\n/**\r\n * 状态仓库类(单例)\r\n */\r\nexport class StateStore {\r\n constructor() {\r\n // 初始状态\r\n this.state = {\r\n // SDK 状态\r\n sdk: {\r\n status: 'uninitialized', // 'uninitialized' | 'initializing' | 'ready' | 'error'\r\n version: '2.0.5',\r\n error: null\r\n },\r\n \r\n // 平台信息\r\n platform: {\r\n type: environment.type,\r\n isWeixinMiniProgram: environment.isWeixinMiniProgram,\r\n isAppPlus: environment.isAppPlus,\r\n isNvue: environment.isNvue,\r\n isUvue: environment.isUvue,\r\n features: {} // 平台支持的特性\r\n },\r\n \r\n // 微信配置状态\r\n weixin: {\r\n configStatus: 'pending', // 'pending' | 'configuring' | 'configured' | 'failed'\r\n jsApiList: [],\r\n configError: null\r\n },\r\n \r\n // 网络状态\r\n network: {\r\n online: typeof navigator !== 'undefined' ? navigator.onLine : true,\r\n type: 'unknown' // 'wifi' | '4g' | '3g' | '2g' | 'unknown'\r\n },\r\n \r\n // 权限状态\r\n permissions: {\r\n camera: 'prompt', // 'granted' | 'denied' | 'prompt'\r\n location: 'prompt',\r\n album: 'prompt'\r\n },\r\n \r\n // API 调用状态\r\n api: {\r\n // 格式: { apiName: { loading: boolean, lastCall: timestamp, lastResult: any } }\r\n }\r\n };\r\n \r\n // 订阅者映射 { path: Set<listener> }\r\n this.listeners = new Map();\r\n \r\n // 通配符订阅者\r\n this.wildcardListeners = new Set();\r\n \r\n // 初始化网络状态监听\r\n this.initNetworkListener();\r\n \r\n stateLogger.debug('状态仓库已初始化');\r\n }\r\n\r\n /**\r\n * 获取状态值\r\n * @param {string} path - 状态路径(用 . 分隔)\r\n * @returns {any} 状态值\r\n * @example\r\n * store.get('sdk.status') // 'ready'\r\n * store.get('platform') // { type: 'weixin', ... }\r\n */\r\n get(path) {\r\n const keys = path.split('.');\r\n return keys.reduce((obj, key) => {\r\n return obj !== undefined && obj !== null ? obj[key] : undefined;\r\n }, this.state);\r\n }\r\n\r\n /**\r\n * 设置状态值\r\n * @param {string} path - 状态路径\r\n * @param {any} value - 新值\r\n * @example\r\n * store.set('sdk.status', 'ready')\r\n * store.set('network.online', false)\r\n */\r\n set(path, value) {\r\n const keys = path.split('.');\r\n const lastKey = keys.pop();\r\n \r\n // 获取目标对象\r\n const target = keys.reduce((obj, key) => {\r\n if (!obj[key] || typeof obj[key] !== 'object') {\r\n obj[key] = {};\r\n }\r\n return obj[key];\r\n }, this.state);\r\n \r\n // 检查值是否变化\r\n const oldValue = target[lastKey];\r\n if (oldValue === value) {\r\n return; // 值未变化,不触发更新\r\n }\r\n \r\n // 设置新值\r\n target[lastKey] = value;\r\n \r\n stateLogger.debug(`状态已更新: ${path}`, { oldValue, newValue: value });\r\n \r\n // 通知订阅者\r\n this.notify(path, value, oldValue);\r\n }\r\n\r\n /**\r\n * 批量更新状态\r\n * @param {Object} updates - 更新对象 { path: value }\r\n * @example\r\n * store.batchUpdate({\r\n * 'sdk.status': 'ready',\r\n * 'network.online': true\r\n * })\r\n */\r\n batchUpdate(updates) {\r\n Object.entries(updates).forEach(([path, value]) => {\r\n this.set(path, value);\r\n });\r\n }\r\n\r\n /**\r\n * 订阅状态变化\r\n * @param {string} path - 状态路径(支持通配符 * )\r\n * @param {Function} listener - 监听函数 (newValue, oldValue, path) => void\r\n * @returns {Function} 取消订阅的函数\r\n * @example\r\n * const unsubscribe = store.subscribe('network.online', (online) => {\r\n * console.log('网络状态:', online)\r\n * })\r\n * // 取消订阅\r\n * unsubscribe()\r\n */\r\n subscribe(path, listener) {\r\n if (typeof listener !== 'function') {\r\n throw new Error('listener 必须是函数');\r\n }\r\n \r\n // 通配符订阅\r\n if (path === '*') {\r\n this.wildcardListeners.add(listener);\r\n stateLogger.debug('添加通配符订阅者');\r\n \r\n return () => {\r\n this.wildcardListeners.delete(listener);\r\n stateLogger.debug('移除通配符订阅者');\r\n };\r\n }\r\n \r\n // 普通订阅\r\n if (!this.listeners.has(path)) {\r\n this.listeners.set(path, new Set());\r\n }\r\n \r\n this.listeners.get(path).add(listener);\r\n stateLogger.debug(`添加订阅者: ${path}`);\r\n \r\n // 返回取消订阅函数\r\n return () => {\r\n const listeners = this.listeners.get(path);\r\n if (listeners) {\r\n listeners.delete(listener);\r\n if (listeners.size === 0) {\r\n this.listeners.delete(path);\r\n }\r\n stateLogger.debug(`移除订阅者: ${path}`);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * 订阅一次(只触发一次后自动取消)\r\n * @param {string} path - 状态路径\r\n * @param {Function} listener - 监听函数\r\n * @returns {Function} 取消订阅的函数\r\n */\r\n subscribeOnce(path, listener) {\r\n const unsubscribe = this.subscribe(path, (newValue, oldValue, p) => {\r\n listener(newValue, oldValue, p);\r\n unsubscribe();\r\n });\r\n return unsubscribe;\r\n }\r\n\r\n /**\r\n * 通知订阅者\r\n * @param {string} path - 状态路径\r\n * @param {any} newValue - 新值\r\n * @param {any} oldValue - 旧值\r\n * @private\r\n */\r\n notify(path, newValue, oldValue) {\r\n // 通知精确路径的订阅者\r\n const listeners = this.listeners.get(path);\r\n if (listeners) {\r\n listeners.forEach(listener => {\r\n try {\r\n listener(newValue, oldValue, path);\r\n } catch (error) {\r\n stateLogger.error('订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n \r\n // 通知父路径的订阅者(例如 'sdk.status' 变化通知 'sdk' 的订阅者)\r\n const keys = path.split('.');\r\n for (let i = 1; i < keys.length; i++) {\r\n const parentPath = keys.slice(0, i).join('.');\r\n const parentListeners = this.listeners.get(parentPath);\r\n if (parentListeners) {\r\n const parentValue = this.get(parentPath);\r\n parentListeners.forEach(listener => {\r\n try {\r\n listener(parentValue, undefined, parentPath);\r\n } catch (error) {\r\n stateLogger.error('父路径订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n }\r\n \r\n // 通知通配符订阅者\r\n this.wildcardListeners.forEach(listener => {\r\n try {\r\n listener(newValue, oldValue, path);\r\n } catch (error) {\r\n stateLogger.error('通配符订阅者执行失败', error);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * 初始化网络状态监听\r\n * @private\r\n */\r\n initNetworkListener() {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n // 监听在线/离线事件\r\n window.addEventListener('online', () => {\r\n this.set('network.online', true);\r\n });\r\n \r\n window.addEventListener('offline', () => {\r\n this.set('network.online', false);\r\n });\r\n \r\n // 监听网络类型变化(如果支持)\r\n if (navigator.connection) {\r\n const connection = navigator.connection;\r\n \r\n const updateConnectionType = () => {\r\n this.set('network.type', connection.effectiveType || 'unknown');\r\n };\r\n \r\n connection.addEventListener('change', updateConnectionType);\r\n updateConnectionType();\r\n }\r\n }\r\n\r\n /**\r\n * 记录 API 调用开始\r\n * @param {string} apiName - API 名称\r\n */\r\n setApiLoading(apiName, loading = true) {\r\n const apiPath = `api.${apiName}`;\r\n const apiState = this.get(apiPath) || {};\r\n \r\n this.set(apiPath, {\r\n ...apiState,\r\n loading,\r\n lastCall: loading ? Date.now() : apiState.lastCall\r\n });\r\n }\r\n\r\n /**\r\n * 记录 API 调用结果\r\n * @param {string} apiName - API 名称\r\n * @param {any} result - 结果\r\n */\r\n setApiResult(apiName, result) {\r\n const apiPath = `api.${apiName}`;\r\n const apiState = this.get(apiPath) || {};\r\n \r\n this.set(apiPath, {\r\n ...apiState,\r\n loading: false,\r\n lastResult: result,\r\n lastCallEnd: Date.now()\r\n });\r\n }\r\n\r\n /**\r\n * 获取完整状态快照\r\n * @returns {Object} 状态快照\r\n */\r\n getSnapshot() {\r\n return JSON.parse(JSON.stringify(this.state));\r\n }\r\n\r\n /**\r\n * 重置状态(用于测试)\r\n * @private\r\n */\r\n reset() {\r\n // 保留一些基础信息\r\n const { platform } = this.state;\r\n \r\n this.state = {\r\n sdk: {\r\n status: 'uninitialized',\r\n version: '2.0.5',\r\n error: null\r\n },\r\n platform,\r\n weixin: {\r\n configStatus: 'pending',\r\n jsApiList: [],\r\n configError: null\r\n },\r\n network: {\r\n online: typeof navigator !== 'undefined' ? navigator.onLine : true,\r\n type: 'unknown'\r\n },\r\n permissions: {\r\n camera: 'prompt',\r\n location: 'prompt',\r\n album: 'prompt'\r\n },\r\n api: {}\r\n };\r\n \r\n stateLogger.debug('状态已重置');\r\n }\r\n\r\n /**\r\n * 获取统计信息\r\n * @returns {Object}\r\n */\r\n getStats() {\r\n return {\r\n listeners: this.listeners.size,\r\n wildcardListeners: this.wildcardListeners.size,\r\n apiStates: Object.keys(this.state.api).length\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst stateStore = new StateStore();\r\n\r\nexport default stateStore;\r\n\r\n","/**\r\n * 统一错误码定义\r\n * 格式:E_[模块]_[序号]\r\n */\r\n\r\n// ==================== 错误码定义 ====================\r\n\r\n/**\r\n * 错误码枚举\r\n */\r\nexport const ErrorCodes = {\r\n // SDK 核心错误 (E_SDK_xxx)\r\n SDK_NOT_READY: 'E_SDK_001',\r\n SDK_INIT_FAILED: 'E_SDK_002',\r\n SDK_CONFIG_FAILED: 'E_SDK_003',\r\n PLATFORM_NOT_SUPPORTED: 'E_SDK_004',\r\n \r\n // 网络错误 (E_NET_xxx)\r\n NETWORK_ERROR: 'E_NET_001',\r\n NETWORK_TIMEOUT: 'E_NET_002',\r\n NETWORK_OFFLINE: 'E_NET_003',\r\n \r\n // 图片错误 (E_IMG_xxx)\r\n IMAGE_CANCELLED: 'E_IMG_001', // 用户取消\r\n IMAGE_NO_PERMISSION: 'E_IMG_002', // 无权限\r\n IMAGE_SIZE_EXCEED: 'E_IMG_003', // 图片过大\r\n IMAGE_COUNT_EXCEED: 'E_IMG_004', // 数量超限\r\n IMAGE_FORMAT_ERROR: 'E_IMG_005', // 格式错误\r\n IMAGE_CONFIG_NOT_READY: 'E_IMG_006', // 配置未完成\r\n \r\n // 定位错误 (E_LOC_xxx)\r\n LOCATION_CANCELLED: 'E_LOC_001',\r\n LOCATION_NO_PERMISSION: 'E_LOC_002',\r\n LOCATION_UNAVAILABLE: 'E_LOC_003',\r\n LOCATION_TIMEOUT: 'E_LOC_004',\r\n \r\n // 扫码错误 (E_SCAN_xxx)\r\n SCAN_CANCELLED: 'E_SCAN_001', // 用户取消\r\n SCAN_NO_PERMISSION: 'E_SCAN_002', // 无相机权限\r\n SCAN_INVALID_CODE: 'E_SCAN_003', // 无效的码\r\n SCAN_CONFIG_NOT_READY: 'E_SCAN_004', // 配置未完成\r\n \r\n // 权限错误 (E_PERM_xxx)\r\n PERMISSION_DENIED: 'E_PERM_001',\r\n PERMISSION_CAMERA: 'E_PERM_002',\r\n PERMISSION_LOCATION: 'E_PERM_003',\r\n PERMISSION_ALBUM: 'E_PERM_004',\r\n PERMISSION_MICROPHONE: 'E_PERM_005',\r\n \r\n // 参数错误 (E_PARAM_xxx)\r\n PARAM_INVALID: 'E_PARAM_001',\r\n PARAM_MISSING: 'E_PARAM_002',\r\n PARAM_TYPE_ERROR: 'E_PARAM_003',\r\n \r\n // 超时错误 (E_TIMEOUT_xxx)\r\n API_TIMEOUT: 'E_TIMEOUT_001',\r\n \r\n // 通用错误\r\n UNKNOWN_ERROR: 'E_UNKNOWN_999'\r\n};\r\n\r\n/**\r\n * 错误消息映射\r\n */\r\nexport const ErrorMessages = {\r\n // SDK 核心\r\n [ErrorCodes.SDK_NOT_READY]: 'SDK 未就绪',\r\n [ErrorCodes.SDK_INIT_FAILED]: 'SDK 初始化失败',\r\n [ErrorCodes.SDK_CONFIG_FAILED]: 'SDK 配置失败',\r\n [ErrorCodes.PLATFORM_NOT_SUPPORTED]: '当前平台不支持此功能',\r\n \r\n // 网络\r\n [ErrorCodes.NETWORK_ERROR]: '网络错误',\r\n [ErrorCodes.NETWORK_TIMEOUT]: '网络超时',\r\n [ErrorCodes.NETWORK_OFFLINE]: '网络已断开',\r\n \r\n // 图片\r\n [ErrorCodes.IMAGE_CANCELLED]: '用户取消选择图片',\r\n [ErrorCodes.IMAGE_NO_PERMISSION]: '无相机/相册权限',\r\n [ErrorCodes.IMAGE_SIZE_EXCEED]: '图片大小超出限制',\r\n [ErrorCodes.IMAGE_COUNT_EXCEED]: '图片数量超出限制',\r\n [ErrorCodes.IMAGE_FORMAT_ERROR]: '图片格式不支持',\r\n [ErrorCodes.IMAGE_CONFIG_NOT_READY]: '微信配置未完成',\r\n \r\n // 定位\r\n [ErrorCodes.LOCATION_CANCELLED]: '用户取消定位',\r\n [ErrorCodes.LOCATION_NO_PERMISSION]: '无定位权限',\r\n [ErrorCodes.LOCATION_UNAVAILABLE]: '定位服务不可用',\r\n [ErrorCodes.LOCATION_TIMEOUT]: '定位超时',\r\n \r\n // 扫码\r\n [ErrorCodes.SCAN_CANCELLED]: '用户取消扫码',\r\n [ErrorCodes.SCAN_NO_PERMISSION]: '无相机权限',\r\n [ErrorCodes.SCAN_INVALID_CODE]: '无效的二维码/条形码',\r\n [ErrorCodes.SCAN_CONFIG_NOT_READY]: '微信配置未完成',\r\n \r\n // 权限\r\n [ErrorCodes.PERMISSION_DENIED]: '权限被拒绝',\r\n [ErrorCodes.PERMISSION_CAMERA]: '无相机权限',\r\n [ErrorCodes.PERMISSION_LOCATION]: '无定位权限',\r\n [ErrorCodes.PERMISSION_ALBUM]: '无相册权限',\r\n [ErrorCodes.PERMISSION_MICROPHONE]: '无麦克风权限',\r\n \r\n // 参数\r\n [ErrorCodes.PARAM_INVALID]: '参数无效',\r\n [ErrorCodes.PARAM_MISSING]: '缺少必需参数',\r\n [ErrorCodes.PARAM_TYPE_ERROR]: '参数类型错误',\r\n \r\n // 超时\r\n [ErrorCodes.API_TIMEOUT]: 'API 调用超时',\r\n \r\n // 通用\r\n [ErrorCodes.UNKNOWN_ERROR]: '未知错误'\r\n};\r\n\r\n/**\r\n * 错误分类\r\n */\r\nexport const ErrorCategory = {\r\n USER_CANCEL: 'user_cancel', // 用户主动取消\r\n PERMISSION: 'permission', // 权限问题\r\n NETWORK: 'network', // 网络问题\r\n PARAM: 'param', // 参数问题\r\n SYSTEM: 'system', // 系统问题\r\n CONFIG: 'config', // 配置问题\r\n UNKNOWN: 'unknown' // 未知问题\r\n};\r\n\r\n// ==================== 错误映射规则 ====================\r\n\r\n/**\r\n * 旧版错误码映射(image.js 中使用的格式)\r\n * 格式:CATEGORY/ERROR_NAME → E_XXX_NNN\r\n */\r\nexport const LegacyErrorMapping = {\r\n // 图片相关\r\n 'IMAGE/USER_CANCEL': ErrorCodes.IMAGE_CANCELLED,\r\n 'IMAGE/PERMISSION_DENIED': ErrorCodes.IMAGE_NO_PERMISSION,\r\n \r\n // 通用错误\r\n 'COMMON/UNKNOWN': ErrorCodes.UNKNOWN_ERROR,\r\n 'COMMON/CONFIG_NOT_READY': ErrorCodes.IMAGE_CONFIG_NOT_READY,\r\n 'COMMON/PLATFORM_NOT_SUPPORTED': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n};\r\n\r\n/**\r\n * 平台原始错误映射(原始 errMsg → 统一错误码)\r\n */\r\nexport const PlatformErrorMapping = {\r\n // 微信平台错误模式\r\n weixin: {\r\n patterns: [\r\n { pattern: /cancel/i, code: ErrorCodes.IMAGE_CANCELLED },\r\n { pattern: /permission|auth\\s*deny/i, code: ErrorCodes.IMAGE_NO_PERMISSION },\r\n { pattern: /config/i, code: ErrorCodes.IMAGE_CONFIG_NOT_READY },\r\n { pattern: /timeout/i, code: ErrorCodes.API_TIMEOUT },\r\n { pattern: /network/i, code: ErrorCodes.NETWORK_ERROR }\r\n ],\r\n default: ErrorCodes.UNKNOWN_ERROR\r\n },\r\n \r\n // UniApp 平台错误模式\r\n uniapp: {\r\n patterns: [\r\n { pattern: /cancel/i, code: ErrorCodes.IMAGE_CANCELLED },\r\n { pattern: /permission|denied/i, code: ErrorCodes.IMAGE_NO_PERMISSION },\r\n { pattern: /timeout/i, code: ErrorCodes.API_TIMEOUT },\r\n { pattern: /network/i, code: ErrorCodes.NETWORK_ERROR },\r\n { pattern: /not_in_container/i, code: ErrorCodes.PLATFORM_NOT_SUPPORTED }\r\n ],\r\n default: ErrorCodes.UNKNOWN_ERROR\r\n }\r\n};\r\n\r\n/**\r\n * API 特定的错误映射\r\n */\r\nexport const ApiErrorMapping = {\r\n chooseImage: {\r\n 'fail cancel': ErrorCodes.IMAGE_CANCELLED,\r\n 'fail auth deny': ErrorCodes.IMAGE_NO_PERMISSION,\r\n 'fail No Permission': ErrorCodes.IMAGE_NO_PERMISSION,\r\n 'NOT_IN_CONTAINER': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n },\r\n scanCode: {\r\n 'fail cancel': ErrorCodes.SCAN_CANCELLED,\r\n 'fail auth deny': ErrorCodes.SCAN_NO_PERMISSION,\r\n 'fail No Permission': ErrorCodes.SCAN_NO_PERMISSION,\r\n 'NOT_IN_CONTAINER': ErrorCodes.PLATFORM_NOT_SUPPORTED\r\n }\r\n};\r\n\r\n// ==================== 辅助函数 ====================\r\n\r\n/**\r\n * 根据错误码获取错误分类\r\n * @param {string} code - 错误码\r\n * @returns {string} 错误分类\r\n */\r\nexport function getErrorCategory(code) {\r\n if (!code) return ErrorCategory.UNKNOWN;\r\n \r\n // 用户取消类\r\n if (code.includes('CANCEL')) {\r\n return ErrorCategory.USER_CANCEL;\r\n }\r\n \r\n // 权限类\r\n if (code.includes('PERM') || code.includes('PERMISSION')) {\r\n return ErrorCategory.PERMISSION;\r\n }\r\n \r\n // 网络类\r\n if (code.includes('NET') || code.includes('NETWORK')) {\r\n return ErrorCategory.NETWORK;\r\n }\r\n \r\n // 参数类\r\n if (code.includes('PARAM')) {\r\n return ErrorCategory.PARAM;\r\n }\r\n \r\n // 配置类\r\n if (code.includes('CONFIG')) {\r\n return ErrorCategory.CONFIG;\r\n }\r\n \r\n // 系统类\r\n if (code.includes('SDK') || code.includes('PLATFORM')) {\r\n return ErrorCategory.SYSTEM;\r\n }\r\n \r\n return ErrorCategory.UNKNOWN;\r\n}\r\n\r\n/**\r\n * 检测错误是否可重试\r\n * @param {string} code - 错误码\r\n * @returns {boolean}\r\n */\r\nexport function isRetriableError(code) {\r\n // 网络错误、超时错误通常可重试\r\n return code.includes('NET_') || \r\n code.includes('TIMEOUT') ||\r\n code === ErrorCodes.NETWORK_ERROR ||\r\n code === ErrorCodes.NETWORK_TIMEOUT ||\r\n code === ErrorCodes.API_TIMEOUT;\r\n}\r\n\r\n/**\r\n * 检测是否为用户主动操作(不需要提示)\r\n * @param {string} code - 错误码\r\n * @returns {boolean}\r\n */\r\nexport function isUserAction(code) {\r\n return code.includes('CANCEL') ||\r\n getErrorCategory(code) === ErrorCategory.USER_CANCEL;\r\n}\r\n\r\n/**\r\n * 获取错误码的友好描述\r\n * @param {string} code - 错误码\r\n * @returns {string}\r\n */\r\nexport function getErrorMessage(code) {\r\n return ErrorMessages[code] || ErrorMessages[ErrorCodes.UNKNOWN_ERROR];\r\n}\r\n\r\n","/**\r\n * 错误标准化模块\r\n * 将各种格式的错误转换为统一的标准错误格式\r\n */\r\n\r\nimport { \r\n ErrorCodes, \r\n ErrorMessages, \r\n ErrorCategory,\r\n LegacyErrorMapping,\r\n PlatformErrorMapping,\r\n ApiErrorMapping,\r\n getErrorCategory,\r\n isRetriableError,\r\n isUserAction,\r\n getErrorMessage\r\n} from './error-codes.js';\r\nimport { environment } from './environment.js';\r\nimport { apiLogger } from './logger.js';\r\n\r\n/**\r\n * 标准化错误类\r\n */\r\nexport class StandardError extends Error {\r\n /**\r\n * 构造函数\r\n * @param {string} code - 错误码\r\n * @param {string} message - 错误消息\r\n * @param {Object} options - 选项\r\n */\r\n constructor(code, message, options = {}) {\r\n super(message);\r\n \r\n this.name = 'StandardError';\r\n this.code = code;\r\n this.message = message || getErrorMessage(code);\r\n this.platform = options.platform || environment.type;\r\n this.apiName = options.apiName;\r\n this.category = options.category || getErrorCategory(code);\r\n this.retriable = options.retriable !== undefined ? options.retriable : isRetriableError(code);\r\n this.originalError = options.originalError;\r\n this.details = options.details || {};\r\n this.timestamp = Date.now();\r\n }\r\n\r\n /**\r\n * 是否可重试\r\n * @returns {boolean}\r\n */\r\n isRetriable() {\r\n return this.retriable;\r\n }\r\n\r\n /**\r\n * 是否用户主动操作(不需要提示)\r\n * @returns {boolean}\r\n */\r\n isUserAction() {\r\n return isUserAction(this.code);\r\n }\r\n\r\n /**\r\n * 转为普通对象\r\n * @returns {Object}\r\n */\r\n toJSON() {\r\n return {\r\n code: this.code,\r\n message: this.message,\r\n platform: this.platform,\r\n apiName: this.apiName,\r\n category: this.category,\r\n retriable: this.retriable,\r\n timestamp: this.timestamp,\r\n details: this.details,\r\n // 调试模式下包含原始错误\r\n ...(process.env.NODE_ENV !== 'production' && this.originalError ? {\r\n originalError: this.originalError\r\n } : {})\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * 标准化错误(核心函数)\r\n * @param {any} error - 原始错误对象\r\n * @param {Object} context - 上下文信息\r\n * @returns {StandardError}\r\n */\r\nexport function normalizeError(error, context = {}) {\r\n // 已经是标准化错误,直接返回\r\n if (error instanceof StandardError) {\r\n return error;\r\n }\r\n\r\n const { apiName, platform = environment.type } = context;\r\n\r\n // 1. 处理 image.js 旧版错误格式(兼容现有代码)\r\n if (error && typeof error.code === 'string' && error.code.includes('/')) {\r\n return normalizeLegacyError(error, { apiName, platform });\r\n }\r\n\r\n // 2. 处理平台原始错误(errMsg 字符串)\r\n if (error && (error.errMsg || error.message)) {\r\n return normalizePlatformError(error, { apiName, platform });\r\n }\r\n\r\n // 3. 处理字符串错误\r\n if (typeof error === 'string') {\r\n return new StandardError(\r\n ErrorCodes.UNKNOWN_ERROR,\r\n error,\r\n { apiName, platform, originalError: error }\r\n );\r\n }\r\n\r\n // 4. 未知错误\r\n return new StandardError(\r\n ErrorCodes.UNKNOWN_ERROR,\r\n '未知错误',\r\n { \r\n apiName, \r\n platform, \r\n originalError: error,\r\n details: { errorType: typeof error }\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 标准化旧版错误格式(image.js 使用的 CATEGORY/ERROR_NAME 格式)\r\n * @param {Object} error - 旧版错误对象\r\n * @param {Object} context - 上下文\r\n * @returns {StandardError}\r\n * @private\r\n */\r\nfunction normalizeLegacyError(error, context) {\r\n const { apiName, platform } = context;\r\n const legacyCode = error.code;\r\n \r\n // 查找映射的新错误码\r\n const newCode = LegacyErrorMapping[legacyCode] || ErrorCodes.UNKNOWN_ERROR;\r\n \r\n apiLogger.debug('转换旧版错误码', { \r\n legacy: legacyCode, \r\n new: newCode \r\n });\r\n\r\n return new StandardError(\r\n newCode,\r\n error.message || getErrorMessage(newCode),\r\n {\r\n apiName,\r\n platform: error.platform || platform,\r\n originalError: error,\r\n details: {\r\n legacyCode,\r\n legacyVersion: error.version,\r\n ...error.details\r\n }\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 标准化平台原始错误(微信/UniApp 的 errMsg)\r\n * @param {Object} error - 平台错误对象\r\n * @param {Object} context - 上下文\r\n * @returns {StandardError}\r\n * @private\r\n */\r\nfunction normalizePlatformError(error, context) {\r\n const { apiName, platform } = context;\r\n const errMsg = (error.errMsg || error.message || '').toLowerCase();\r\n \r\n // 1. 尝试 API 特定映射\r\n if (apiName && ApiErrorMapping[apiName]) {\r\n const apiMapping = ApiErrorMapping[apiName];\r\n for (const [pattern, code] of Object.entries(apiMapping)) {\r\n if (errMsg.includes(pattern.toLowerCase())) {\r\n return new StandardError(code, getErrorMessage(code), {\r\n apiName,\r\n platform,\r\n originalError: error\r\n });\r\n }\r\n }\r\n }\r\n\r\n // 2. 尝试平台通用模式匹配\r\n const platformMapping = PlatformErrorMapping[platform] || PlatformErrorMapping.uniapp;\r\n for (const { pattern, code } of platformMapping.patterns) {\r\n if (pattern.test(errMsg)) {\r\n return new StandardError(code, getErrorMessage(code), {\r\n apiName,\r\n platform,\r\n originalError: error\r\n });\r\n }\r\n }\r\n\r\n // 3. 使用默认错误码\r\n const defaultCode = platformMapping.default || ErrorCodes.UNKNOWN_ERROR;\r\n return new StandardError(\r\n defaultCode,\r\n error.errMsg || error.message || getErrorMessage(defaultCode),\r\n {\r\n apiName,\r\n platform,\r\n originalError: error\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * 错误标准化拦截器(用于拦截器链)\r\n */\r\nexport const errorNormalizerInterceptor = {\r\n /**\r\n * 响应拦截器\r\n * @param {Object} result - API 响应结果\r\n * @param {Object} ctx - 拦截器上下文\r\n * @returns {Object} 处理后的结果\r\n */\r\n response: (result, ctx) => {\r\n // 只处理失败的响应\r\n if (!result.success && result.error) {\r\n const standardError = normalizeError(result.error, {\r\n apiName: ctx.apiName,\r\n platform: environment.type\r\n });\r\n\r\n // 替换为标准化错误对象\r\n result.error = standardError.toJSON();\r\n\r\n // 添加便捷字段\r\n result.errorCode = standardError.code;\r\n result.errorCategory = standardError.category;\r\n result.retriable = standardError.isRetriable();\r\n\r\n apiLogger.debug('错误已标准化', {\r\n api: ctx.apiName,\r\n code: standardError.code,\r\n category: standardError.category\r\n });\r\n }\r\n\r\n return result;\r\n }\r\n};\r\n\r\n/**\r\n * 创建标准错误(便捷函数)\r\n * @param {string} code - 错误码\r\n * @param {Object} options - 选项\r\n * @returns {StandardError}\r\n */\r\nexport function createError(code, options = {}) {\r\n return new StandardError(code, getErrorMessage(code), options);\r\n}\r\n\r\n/**\r\n * 判断是否为标准错误\r\n * @param {any} error - 错误对象\r\n * @returns {boolean}\r\n */\r\nexport function isStandardError(error) {\r\n return error instanceof StandardError;\r\n}\r\n\r\n","/**\r\n * 启动管线:按顺序执行初始化任务,支持超时与统一错误处理\r\n */\r\n\r\nfunction withTimeout(promiseFactory, timeoutMs, name) {\r\n if (!timeoutMs) return promiseFactory();\r\n return Promise.race([\r\n promiseFactory(),\r\n new Promise((_, reject) => setTimeout(() => reject(new Error(`Init task timeout: ${name}`)), timeoutMs))\r\n ]);\r\n}\r\n\r\n/**\r\n * 运行初始化任务列表\r\n * @param {Array<{name?: string, run: Function, timeoutMs?: number, onError?: Function, onSuccess?: Function}>} tasks\r\n * @param {Object} options\r\n * @param {(error: Error, task: any) => void} [options.onError]\r\n * @returns {Promise<void>}\r\n */\r\nexport async function runInitPipeline(tasks = [], options = {}) {\r\n for (const task of tasks) {\r\n const name = task?.name || 'anonymous-task';\r\n const run = task?.run || task;\r\n if (typeof run !== 'function') {\r\n continue;\r\n }\r\n\r\n try {\r\n await withTimeout(() => Promise.resolve().then(() => run()), task.timeoutMs, name);\r\n if (typeof task.onSuccess === 'function') {\r\n task.onSuccess();\r\n }\r\n } catch (error) {\r\n if (typeof task.onError === 'function') {\r\n task.onError(error);\r\n }\r\n if (typeof options.onError === 'function') {\r\n options.onError(error, task);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n","/**\r\n * 基础平台抽象类\r\n * 提供平台间的公共逻辑,减少代码重复\r\n */\r\n\r\n/**\r\n * 平台基类\r\n * 定义了所有平台的通用接口和公共逻辑\r\n */\r\nexport class BasePlatform {\r\n /**\r\n * 构造函数\r\n * @param {string} name - 平台名称\r\n */\r\n constructor(name) {\r\n this.name = name;\r\n }\r\n\r\n /**\r\n * 处理导航选项的公共逻辑\r\n * @param {Object} options - 导航选项\r\n * @returns {Object} 处理后的选项\r\n */\r\n processNavigationOptions(options = {}) {\r\n const { url, delta = 1 } = options;\r\n \r\n // URL 编码处理\r\n const processedUrl = url ? encodeURI(url) : url;\r\n \r\n // Delta 参数转换\r\n const processedDelta = parseInt(delta) || 1;\r\n \r\n return {\r\n ...options,\r\n url: processedUrl,\r\n delta: processedDelta\r\n };\r\n }\r\n\r\n /**\r\n * 处理消息选项的公共逻辑\r\n * @param {Object} options - 消息选项\r\n * @returns {Object} 处理后的选项\r\n */\r\n processMessageOptions(options = {}) {\r\n const { data = {} } = options;\r\n return { data };\r\n }\r\n\r\n // ===== 导航方法(子类需要实现具体逻辑)=====\r\n\r\n /**\r\n * 导航到新页面\r\n * @param {Object} options - 导航参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n navigateTo(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('navigateTo', processedOptions);\r\n }\r\n\r\n /**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回参数\r\n * @param {number} [options.delta=1] - 返回页面层级数\r\n * @returns {void}\r\n */\r\n navigateBack(options = {}) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('navigateBack', processedOptions);\r\n }\r\n\r\n /**\r\n * 切换 Tab\r\n * @param {Object} options - 切换参数\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n */\r\n switchTab(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('switchTab', processedOptions);\r\n }\r\n\r\n /**\r\n * 重新启动并打开指定页面\r\n * @param {Object} options - 参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n reLaunch(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('reLaunch', processedOptions);\r\n }\r\n\r\n /**\r\n * 重定向到指定页面\r\n * @param {Object} options - 参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n */\r\n redirectTo(options) {\r\n const processedOptions = this.processNavigationOptions(options);\r\n return this.performNavigation('redirectTo', processedOptions);\r\n }\r\n\r\n // ===== 消息方法(子类需要实现具体逻辑)=====\r\n\r\n /**\r\n * 发送消息到原生容器\r\n * @param {Object} [options] - 参数\r\n * @param {any} [options.data] - 需要发送的数据\r\n * @returns {void}\r\n */\r\n postMessage(options = {}) {\r\n const processedOptions = this.processMessageOptions(options);\r\n return this.performPostMessage(processedOptions);\r\n }\r\n\r\n /**\r\n * 获取环境信息\r\n * @param {Function} callback - 回调函数,参数为环境信息对象\r\n * @returns {void}\r\n */\r\n getEnv(callback) {\r\n return this.performGetEnv(callback);\r\n }\r\n\r\n // ===== 抽象方法(子类必须实现)=====\r\n\r\n /**\r\n * 执行具体的导航操作(抽象方法)\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n throw new Error(`${this.name} platform must implement performNavigation method`);\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作(抽象方法)\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n throw new Error(`${this.name} platform must implement performPostMessage method`);\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作(抽象方法)\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n throw new Error(`${this.name} platform must implement performGetEnv method`);\r\n }\r\n}\r\n\r\n/**\r\n * 创建平台适配器的工厂方法\r\n * @param {string} platformType - 平台类型\r\n * @returns {BasePlatform} 平台实例\r\n */\r\nexport function createPlatform(platformType) {\r\n switch (platformType) {\r\n case 'weixin':\r\n // 动态导入避免循环依赖\r\n return import('../platforms/weixin.js').then(module => new module.WeixinPlatform());\r\n case 'app':\r\n return import('../platforms/app.js').then(module => new module.AppPlatform());\r\n default:\r\n throw new Error(`Unsupported platform type: ${platformType}`);\r\n }\r\n}\r\n","/**\r\n * 消息通信核心模块\r\n * 负责与原生端进行消息通信\r\n */\r\n\r\nimport { isUvue, isNvue, isAppPlus } from './environment.js';\r\n\r\n// 存储 webview ID 列表\r\nlet webviewIds = [];\r\n\r\n/**\r\n * 设置 webview ID\r\n * @param {string[]} ids - webview ID 列表\r\n * @since 2.0.0\r\n */\r\nexport function setWebviewIds(ids) {\r\n webviewIds = ids;\r\n}\r\n\r\n/**\r\n * 获取当前 webview ID 列表\r\n * @returns {string[]} webview ID 列表\r\n * @throws {Error} 当 plus.webview.currentWebview 不可用时抛出\r\n * @since 2.0.0\r\n */\r\nfunction getCurrentWebviewId() {\r\n if (webviewIds.length === 0 && window.plus) {\r\n const currentWebview = plus.webview.currentWebview();\r\n if (!currentWebview) {\r\n throw new Error('plus.webview.currentWebview() is undefined');\r\n }\r\n const parent = currentWebview.parent();\r\n const webviewId = parent ? parent.id : currentWebview.id;\r\n webviewIds.push(webviewId);\r\n }\r\n return webviewIds;\r\n}\r\n\r\n/**\r\n * 发送消息到 UniApp X\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToUniAppX(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n if (name === 'postMessage') {\r\n const postData = { data: data };\r\n if (window.__uniapp_x_postMessage) {\r\n return window.__uniapp_x_postMessage(postData);\r\n }\r\n return window.__uniapp_x_.postMessage(JSON.stringify(postData));\r\n }\r\n\r\n const serviceMessage = {\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: webviewIds\r\n }\r\n };\r\n\r\n if (window.__uniapp_x_postMessage) {\r\n window.__uniapp_x_postMessageToService(serviceMessage);\r\n } else {\r\n window.__uniapp_x_.postMessageToService(JSON.stringify(serviceMessage));\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到 NVUE\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToNvue(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n if (name === 'postMessage') {\r\n const postData = { data: [data] };\r\n if (window.__dcloud_weex_postMessage) {\r\n return window.__dcloud_weex_postMessage(postData);\r\n }\r\n return window.__dcloud_weex_.postMessage(JSON.stringify(postData));\r\n }\r\n\r\n const serviceMessage = {\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: webviewIds\r\n }\r\n };\r\n\r\n if (window.__dcloud_weex_postMessage) {\r\n window.__dcloud_weex_postMessageToService(serviceMessage);\r\n } else {\r\n window.__dcloud_weex_.postMessageToService(JSON.stringify(serviceMessage));\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到 Plus 环境\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToPlus(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n const currentWebviewIds = getCurrentWebviewId();\r\n\r\n if (plus.webview.getWebviewById('__uniapp__service')) {\r\n plus.webview.postMessageToUniNView({\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n args: {\r\n data: message,\r\n webviewIds: currentWebviewIds\r\n }\r\n }, '__uniapp__service');\r\n } else {\r\n const jsonMessage = JSON.stringify(message);\r\n const jsonWebviewIds = JSON.stringify(currentWebviewIds);\r\n plus.webview.getLaunchWebview().evalJS(\r\n `UniPlusBridge.subscribeHandler(\"WEB_INVOKE_APPSERVICE\",${jsonMessage},${jsonWebviewIds});`\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * 发送消息到父窗口(H5环境)\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n */\r\nfunction sendToParent(name, data) {\r\n const message = {\r\n options: {\r\n timestamp: +new Date()\r\n },\r\n name: name,\r\n arg: data\r\n };\r\n\r\n window.parent.postMessage({\r\n type: 'WEB_INVOKE_APPSERVICE',\r\n data: message,\r\n pageId: ''\r\n }, '*');\r\n}\r\n\r\n/**\r\n * 统一消息发送接口\r\n * @param {string} name - 消息名称\r\n * @param {object} data - 消息数据\r\n * @returns {void}\r\n * @example\r\n * sendMessage('postMessage', { foo: 1 })\r\n * @since 2.0.0\r\n */\r\nexport function sendMessage(name, data) {\r\n // console.log('环境', {\r\n // isAppPlus: isAppPlus(),\r\n // plus: !!window.plus,\r\n // uniappPostMessage: !!window.__uniapp_x_postMessage\r\n // })\r\n if (isUvue()) {\r\n sendToUniAppX(name, data);\r\n } else if (isNvue()) {\r\n sendToNvue(name, data);\r\n } else if (isAppPlus()) {\r\n sendToPlus(name, data);\r\n } else {\r\n // H5 环境或其他\r\n sendToParent(name, data);\r\n }\r\n}","/**\r\n * 微信小程序平台适配层\r\n */\r\n\r\nimport { BasePlatform } from '../core/base-platform.js';\r\nimport { sendMessage } from '../core/messenger.js';\r\nimport { ErrorHandler, ErrorTypes } from '../core/error-handler.js';\r\nimport { platformLogger } from '../core/logger.js';\r\n\r\n/**\r\n * 微信小程序平台适配器\r\n */\r\nexport class WeixinPlatform extends BasePlatform {\r\n constructor() {\r\n super('weixin');\r\n }\r\n\r\n /**\r\n * 检查微信 API 是否可用\r\n * @returns {boolean}\r\n * @private\r\n */\r\n isWeixinApiAvailable() {\r\n return typeof window !== 'undefined' && window.wx && window.wx.miniProgram;\r\n }\r\n\r\n /**\r\n * 执行具体的导航操作\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { url, delta } = options;\r\n \r\n platformLogger.debug(`微信平台执行导航操作: ${type}`, options);\r\n \r\n // 如果有原生 wx.miniProgram API,优先使用\r\n if (this.isWeixinApiAvailable()) {\r\n const wxMethod = window.wx.miniProgram[type];\r\n if (typeof wxMethod === 'function') {\r\n platformLogger.debug(`使用微信原生 API: wx.miniProgram.${type}`);\r\n const wxOptions = type === 'navigateBack' ? { delta } : { url };\r\n return wxMethod.call(window.wx.miniProgram, wxOptions);\r\n }\r\n }\r\n \r\n // 否则使用消息通信\r\n platformLogger.debug(`使用消息桥接执行: ${type}`);\r\n const messageData = type === 'navigateBack' ? { delta } : { url };\r\n sendMessage(type, messageData);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performNavigation', \r\n navigationType: type,\r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { data } = options;\r\n \r\n if (this.isWeixinApiAvailable()) {\r\n return window.wx.miniProgram.postMessage({ data });\r\n }\r\n \r\n // 使用消息通信\r\n sendMessage('postMessage', data);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performPostMessage', \r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!callback || typeof callback !== 'function') {\r\n throw new Error('Callback function is required for getEnv');\r\n }\r\n\r\n if (this.isWeixinApiAvailable() && window.wx.miniProgram.getEnv) {\r\n return window.wx.miniProgram.getEnv(callback);\r\n }\r\n \r\n // 回调微信环境信息\r\n callback({\r\n miniprogram: true,\r\n weixin: true\r\n });\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performGetEnv' \r\n });\r\n }\r\n}\r\n\r\n// 创建平台实例\r\nconst weixinPlatform = new WeixinPlatform();\r\n\r\n// 保持向后兼容性 - 导出原有的函数式 API\r\nexport const navigateTo = (options) => weixinPlatform.navigateTo(options);\r\nexport const navigateBack = (options) => weixinPlatform.navigateBack(options);\r\nexport const switchTab = (options) => weixinPlatform.switchTab(options);\r\nexport const reLaunch = (options) => weixinPlatform.reLaunch(options);\r\nexport const redirectTo = (options) => weixinPlatform.redirectTo(options);\r\nexport const postMessage = (options) => weixinPlatform.postMessage(options);\r\nexport const getEnv = (callback) => weixinPlatform.getEnv(callback);","/**\r\n * APP 平台适配层(Plus/Weex/UniX)\r\n */\r\n\r\nimport { BasePlatform } from '../core/base-platform.js';\r\nimport { sendMessage } from '../core/messenger.js';\r\nimport { ErrorHandler, ErrorTypes } from '../core/error-handler.js';\r\nimport { isUvue, isNvue, isAppPlus } from '../core/environment.js';\r\n\r\n/**\r\n * APP 平台适配器\r\n */\r\nexport class AppPlatform extends BasePlatform {\r\n constructor() {\r\n super('app');\r\n }\r\n\r\n /**\r\n * 执行具体的导航操作\r\n * @param {string} type - 导航类型\r\n * @param {Object} options - 处理后的选项\r\n * @returns {void}\r\n */\r\n performNavigation(type, options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { url, delta } = options;\r\n \r\n // APP 平台使用消息通信\r\n const messageData = type === 'navigateBack' ? { delta } : { url };\r\n sendMessage(type, messageData);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performNavigation', \r\n navigationType: type,\r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的消息发送操作\r\n * @param {Object} options - 处理后的消息选项\r\n * @returns {void}\r\n */\r\n performPostMessage(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n const { data } = options;\r\n \r\n // APP 平台使用消息通信\r\n sendMessage('postMessage', data);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performPostMessage', \r\n options \r\n });\r\n }\r\n\r\n /**\r\n * 执行具体的环境信息获取操作\r\n * @param {Function} callback - 回调函数\r\n * @returns {void}\r\n */\r\n performGetEnv(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!callback || typeof callback !== 'function') {\r\n throw new Error('Callback function is required for getEnv');\r\n }\r\n\r\n const envInfo = {};\r\n let isAppEnv = false;\r\n\r\n if (isUvue()) {\r\n envInfo.uvue = true;\r\n isAppEnv = true;\r\n } else if (isNvue()) {\r\n envInfo.nvue = true;\r\n isAppEnv = true;\r\n } else if (isAppPlus()) {\r\n envInfo.plus = true;\r\n isAppEnv = true;\r\n }\r\n\r\n if (isAppEnv) {\r\n envInfo.app = true;\r\n } else {\r\n envInfo.h5 = true;\r\n }\r\n\r\n callback(envInfo);\r\n \r\n }, { \r\n platform: this.name, \r\n method: 'performGetEnv' \r\n });\r\n }\r\n}\r\n\r\n// 创建平台实例\r\nconst appPlatform = new AppPlatform();\r\n\r\n// 保持向后兼容性 - 导出原有的函数式 API\r\nexport const navigateTo = (options) => appPlatform.navigateTo(options);\r\nexport const navigateBack = (options) => appPlatform.navigateBack(options);\r\nexport const switchTab = (options) => appPlatform.switchTab(options);\r\nexport const reLaunch = (options) => appPlatform.reLaunch(options);\r\nexport const redirectTo = (options) => appPlatform.redirectTo(options);\r\nexport const postMessage = (options) => appPlatform.postMessage(options);\r\nexport const getEnv = (callback) => appPlatform.getEnv(callback);","/**\r\n * 导航 API 模块\r\n * 提供统一的导航接口\r\n */\r\n\r\nimport { isWeixinMiniProgram } from '../core/environment.js';\r\nimport * as weixinPlatform from '../platforms/weixin.js';\r\nimport * as appPlatform from '../platforms/app.js';\r\n\r\n/**\r\n * 获取当前平台的导航实现\r\n */\r\nfunction getPlatformNavigation() {\r\n if (isWeixinMiniProgram()) {\r\n return weixinPlatform;\r\n }\r\n return appPlatform;\r\n}\r\n\r\n/**\r\n * 导航到新页面\r\n * @param {Object} options - 导航选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateTo({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nexport function navigateTo(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.navigateTo(options);\r\n}\r\n\r\n/**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回选项\r\n * @param {number} [options.delta=1] - 返回页面层级数\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateBack({ delta: 1 })\r\n * @since 2.0.0\r\n */\r\nexport function navigateBack(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.navigateBack(options);\r\n}\r\n\r\n/**\r\n * 切换至 Tab 页面\r\n * @param {Object} options - 切换选项\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.switchTab({ url: '/pages/tabbar/home' })\r\n * @since 2.0.0\r\n */\r\nexport function switchTab(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.switchTab(options);\r\n}\r\n\r\n/**\r\n * 关闭所有页面并打开到应用内某页面\r\n * @param {Object} options - 重启选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.reLaunch({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nexport function reLaunch(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.reLaunch(options);\r\n}\r\n\r\n/**\r\n * 关闭当前页面并跳转到应用内某页面\r\n * @param {Object} options - 重定向选项\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.redirectTo({ url: '/pages/detail/index' })\r\n * @since 2.0.0\r\n */\r\nexport function redirectTo(options) {\r\n const platform = getPlatformNavigation();\r\n return platform.redirectTo(options);\r\n}","/**\r\n * 消息通信 API 模块\r\n * 提供与原生端的消息通信接口\r\n */\r\n\r\nimport { isWeixinMiniProgram } from '../core/environment.js';\r\nimport * as weixinPlatform from '../platforms/weixin.js';\r\nimport * as appPlatform from '../platforms/app.js';\r\n\r\n/**\r\n * 获取当前平台的消息实现\r\n */\r\nfunction getPlatformMessage() {\r\n if (isWeixinMiniProgram()) {\r\n return weixinPlatform;\r\n }\r\n return appPlatform;\r\n}\r\n\r\n/**\r\n * 发送消息到原生容器\r\n * @param {Object} [options] - 消息选项\r\n * @param {any} [options.data] - 要发送的数据对象\r\n * @returns {void}\r\n * @example\r\n * qsh.postMessage({ data: { orderId: '123' } })\r\n * @since 2.0.0\r\n */\r\nexport function postMessage(options = {}) {\r\n const platform = getPlatformMessage();\r\n return platform.postMessage(options);\r\n}\r\n\r\n/**\r\n * 获取当前环境信息(回调形式)\r\n * @param {Function} callback - 回调函数,参数为环境信息对象\r\n * @returns {void}\r\n * @example\r\n * qsh.getEnv((info) => console.log(info))\r\n * @since 2.0.0\r\n */\r\nexport function getEnv(callback) {\r\n const platform = getPlatformMessage();\r\n return platform.getEnv(callback);\r\n}","/**\r\n * WebView 通信桥接模块\r\n * 实现网页与 UniApp 主应用的双向通信\r\n */\r\n\r\nimport { bridgeLogger } from './logger.js';\r\nimport { ErrorHandler, ErrorTypes, QshError } from './error-handler.js';\r\nimport { sendMessage } from './messenger.js';\r\nimport interceptorChain from './interceptor.js';\r\nimport stateStore from './state-store.js';\r\n// 注意:SDK 核心不应强依赖 Vue;此处避免引入 'vue' 以免库构建失败\r\n\r\n// 仅用于日志打印:在 Vue 响应式对象场景下尽量“脱壳”,否则直接返回原值\r\nfunction toRawLike(value) {\r\n // Vue3 Proxy 内部可能暴露 __v_raw(非官方 API),这里做最小兼容\r\n if (value && typeof value === 'object' && value.__v_raw) return value.__v_raw;\r\n return value;\r\n}\r\n/**\r\n * 生成唯一的回调ID\r\n * @returns {string} 唯一标识符\r\n */\r\nfunction generateCallbackId() {\r\n return 'qsh_callback_' + Date.now() + '_' + Math.random().toString(36).substring(2, 9);\r\n}\r\n\r\n/**\r\n * WebView 桥接管理器类\r\n */\r\nexport class WebViewBridge {\r\n constructor() {\r\n // 回调函数映射表\r\n this.callbacks = new Map();\r\n\r\n // 回调超时定时器映射\r\n this.timeouts = new Map();\r\n\r\n // 持久回调按 API 记录\r\n this.persistentCallbacksByApi = new Map();\r\n\r\n // 默认超时时间(30秒)\r\n this.defaultTimeout = 30000;\r\n\r\n // 初始化全局回调对象\r\n if (typeof window !== 'undefined') {\r\n if (!window.qshWebviewCallbacks) {\r\n window.qshWebviewCallbacks = {};\r\n }\r\n }\r\n\r\n bridgeLogger.debug('WebView 桥接器已初始化');\r\n }\r\n\r\n /**\r\n * 向主应用发送 API 调用消息\r\n * @param {string} apiName - API 名称\r\n * @param {Object} params - 参数对象\r\n * @param {Object} callbacks - 回调函数 {success, fail, complete}\r\n * @returns {void}\r\n */\r\n async callApi(apiName, params = {}, callbacks = {}) {\r\n return ErrorHandler.safeExecute(async () => {\r\n // 纯 H5 顶层页面:没有容器承接消息,直接失败\r\n const isTopLevelH5 = typeof window !== 'undefined'\r\n && window === window.parent\r\n && !window.plus\r\n && !window.__uniapp_x_postMessage && !window.__uniapp_x_\r\n && !window.__dcloud_weex_postMessage && !window.__dcloud_weex_;\r\n if (isTopLevelH5) {\r\n const error = new QshError(\r\n ErrorTypes.PLATFORM_NOT_SUPPORTED,\r\n '当前不在宿主 WebView 容器中,无法发送消息'\r\n );\r\n if (callbacks && typeof callbacks.fail === 'function') {\r\n callbacks.fail({ errMsg: error.message, code: 'NOT_IN_CONTAINER' });\r\n }\r\n if (callbacks && typeof callbacks.complete === 'function') {\r\n callbacks.complete({ success: false, error: { errMsg: error.message } });\r\n }\r\n return;\r\n }\r\n\r\n // 构建拦截器上下文\r\n const context = {\r\n apiName,\r\n params,\r\n callbacks,\r\n timestamp: Date.now(),\r\n abort: false,\r\n metadata: {}\r\n };\r\n // 更新状态:API 调用开始\r\n stateStore.setApiLoading(apiName, true);\r\n\r\n // 执行请求拦截器\r\n const interceptedContext = await interceptorChain.runRequest(context);\r\n\r\n // 检查是否被中止\r\n if (interceptedContext.abort) {\r\n bridgeLogger.warn('API 调用被拦截器中止', { api: apiName });\r\n stateStore.setApiLoading(apiName, false);\r\n\r\n // 触发失败回调\r\n if (callbacks.fail) {\r\n callbacks.fail({\r\n errMsg: interceptedContext.error?.message || 'API 调用被中止',\r\n code: 'INTERCEPTED'\r\n });\r\n }\r\n if (callbacks.complete) {\r\n callbacks.complete({ success: false });\r\n }\r\n return;\r\n }\r\n\r\n const callbackId = generateCallbackId();\r\n // 存储回调函数和上下文\r\n if (callbacks.success || callbacks.fail || callbacks.complete) {\r\n this.callbacks.set(callbackId, {\r\n ...callbacks,\r\n context: interceptedContext // 保存上下文用于响应拦截\r\n });\r\n\r\n // 设置全局回调函数\r\n window.qshWebviewCallbacks[callbackId] = (result) => {\r\n this.handleCallback(callbackId, result);\r\n };\r\n\r\n if (params.isPersistent) {\r\n if (!this.persistentCallbacksByApi.has(apiName)) {\r\n this.persistentCallbacksByApi.set(apiName, new Set());\r\n }\r\n this.persistentCallbacksByApi.get(apiName).add(callbackId);\r\n }\r\n\r\n // 检查是否禁用超时(支持 isPersistent 或 disableTimeout 参数)\r\n const shouldDisableTimeout = params.isPersistent || params.disableTimeout;\r\n \r\n // 设置超时清理(30秒后自动清理)\r\n if (!shouldDisableTimeout) {\r\n const timeoutId = setTimeout(() => {\r\n bridgeLogger.warn('API 调用超时,自动清理回调', { api: apiName, callbackId });\r\n if (callbacks.fail) {\r\n callbacks.fail({\r\n errMsg: `API ${apiName} 调用超时`,\r\n code: 'TIMEOUT'\r\n });\r\n }\r\n this.cleanupCallback(callbackId);\r\n }, params.timeout || this.defaultTimeout);\r\n\r\n this.timeouts.set(callbackId, timeoutId);\r\n } else {\r\n // ✅ 对持久事件(监听型 API)或禁用超时的 API 跳过超时清理\r\n bridgeLogger.info(`API ${apiName} 禁用超时清理,将等待回调返回后清理`, { \r\n callbackId,\r\n isPersistent: params.isPersistent,\r\n disableTimeout: params.disableTimeout\r\n });\r\n }\r\n\r\n // 构造消息(使用拦截后的参数)\r\n const message = {\r\n type: 'qsh_api_call',\r\n api: apiName,\r\n params: interceptedContext.params,\r\n callbackId: callbackId,\r\n timestamp: Date.now()\r\n };\r\n\r\n bridgeLogger.info('发送 API 调用消息', {\r\n api: apiName,\r\n callbackId: callbackId,\r\n hasSuccess: !!callbacks.success,\r\n hasFail: !!callbacks.fail\r\n });\r\n console.log('message:', JSON.stringify(toRawLike(message), null, 2))\r\n // 通过统一 messenger 发送(兼容 UvUE/NVUE/Plus/H5 Parent)\r\n sendMessage('postMessage', message);\r\n }\r\n }, {\r\n context: 'WebViewBridge.callApi',\r\n api: apiName\r\n });\r\n }\r\n\r\n /**\r\n * 处理来自主应用的回调\r\n * @param {string} callbackId - 回调ID\r\n * @param {Object} result - 结果对象\r\n * @private\r\n */\r\n async handleCallback(callbackId, result) {\r\n return ErrorHandler.safeExecute(async () => {\r\n const callbackData = this.callbacks.get(callbackId);\r\n\r\n if (!callbackData) {\r\n bridgeLogger.warn('未找到回调函数', { callbackId });\r\n return;\r\n }\r\n\r\n const { success, fail, complete, context } = callbackData;\r\n\r\n bridgeLogger.debug('处理回调', { callbackId, result });\r\n\r\n // 执行响应拦截器\r\n const interceptedResult = await interceptorChain.runResponse(result, context);\r\n\r\n // 更新状态:API 调用完成\r\n if (context) {\r\n stateStore.setApiResult(context.apiName, interceptedResult);\r\n }\r\n\r\n // 执行对应的回调\r\n if (interceptedResult.success && success) {\r\n success(interceptedResult.data);\r\n } else if (!interceptedResult.success && fail) {\r\n fail(interceptedResult.error || { errMsg: '操作失败' });\r\n }\r\n\r\n // 执行 complete 回调\r\n if (complete) {\r\n complete(interceptedResult);\r\n }\r\n\r\n // 清理回调和超时定时器\r\n // 只有持久监听型 API(isPersistent)才保留回调,其他都清理\r\n const isPersistent = callbackData.context?.params?.isPersistent;\r\n \r\n if (!isPersistent) {\r\n this.cleanupCallback(callbackId);\r\n bridgeLogger.debug('回调执行完成,已清理', { callbackId });\r\n } else {\r\n bridgeLogger.debug('持久监听API:保留回调', { callbackId });\r\n }\r\n\r\n }, {\r\n context: 'WebViewBridge.handleCallback',\r\n callbackId\r\n });\r\n }\r\n\r\n /**\r\n * 清理回调和相关资源\r\n * @param {string} callbackId - 回调ID\r\n * @private\r\n */\r\n cleanupCallback(callbackId) {\r\n // 清除超时定时器\r\n const timeoutId = this.timeouts.get(callbackId);\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n this.timeouts.delete(callbackId);\r\n }\r\n\r\n // 清除回调函数\r\n this.callbacks.delete(callbackId);\r\n\r\n // 清除全局回调\r\n if (typeof window !== 'undefined' && window.qshWebviewCallbacks) {\r\n delete window.qshWebviewCallbacks[callbackId];\r\n }\r\n\r\n if (this.persistentCallbacksByApi && this.persistentCallbacksByApi.size > 0) {\r\n const emptyApis = [];\r\n this.persistentCallbacksByApi.forEach((callbackIds, apiName) => {\r\n if (callbackIds.has(callbackId)) {\r\n callbackIds.delete(callbackId);\r\n if (callbackIds.size === 0) {\r\n emptyApis.push(apiName);\r\n }\r\n }\r\n });\r\n emptyApis.forEach(apiName => this.persistentCallbacksByApi.delete(apiName));\r\n }\r\n }\r\n\r\n /**\r\n * 清理所有待处理的回调\r\n */\r\n clearCallbacks() {\r\n bridgeLogger.debug('清理所有回调', { count: this.callbacks.size });\r\n\r\n // 清除所有超时定时器\r\n this.timeouts.forEach(timeoutId => clearTimeout(timeoutId));\r\n this.timeouts.clear();\r\n\r\n // 清除回调映射\r\n this.callbacks.clear();\r\n\r\n if (this.persistentCallbacksByApi) {\r\n this.persistentCallbacksByApi.clear();\r\n }\r\n\r\n // 清除全局回调对象\r\n if (typeof window !== 'undefined' && window.qshWebviewCallbacks) {\r\n Object.keys(window.qshWebviewCallbacks).forEach(key => {\r\n if (key.startsWith('qsh_callback_')) {\r\n delete window.qshWebviewCallbacks[key];\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * 清理指定 API 的持久回调\r\n * @param {string} apiName - API 名称\r\n * @returns {number} 清理数量\r\n */\r\n cleanupPersistentCallbacksByApi(apiName) {\r\n const callbackIds = this.persistentCallbacksByApi.get(apiName);\r\n if (!callbackIds || callbackIds.size === 0) {\r\n return 0;\r\n }\r\n const ids = Array.from(callbackIds);\r\n ids.forEach((callbackId) => this.cleanupCallback(callbackId));\r\n this.persistentCallbacksByApi.delete(apiName);\r\n bridgeLogger.info('已清理持久回调', { api: apiName, count: ids.length });\r\n return ids.length;\r\n }\r\n\r\n /**\r\n * 获取桥接器状态信息\r\n * @returns {Object} 状态信息\r\n */\r\n getStatus() {\r\n return {\r\n isSupported: typeof window !== 'undefined' &&\r\n window.uni &&\r\n typeof window.uni.postMessage === 'function',\r\n activeCallbacks: this.callbacks.size,\r\n globalCallbacksCount: typeof window !== 'undefined' && window.qshWebviewCallbacks ?\r\n Object.keys(window.qshWebviewCallbacks).length : 0\r\n };\r\n }\r\n}\r\n\r\n// 创建单例实例\r\nconst webViewBridge = new WebViewBridge();\r\n\r\n// 导出便利函数\r\nexport const callApiInWebView = (apiName, params, callbacks) =>\r\n webViewBridge.callApi(apiName, params, callbacks);\r\n\r\nexport const getWebViewBridgeStatus = () => webViewBridge.getStatus();\r\n\r\nexport const clearWebViewCallbacks = () => webViewBridge.clearCallbacks();\r\n\r\nexport const clearPersistentCallbacksByApi = (apiName) =>\r\n webViewBridge.cleanupPersistentCallbacksByApi(apiName);\r\n\r\nexport default webViewBridge;\r\n","/**\r\n * 图片选择 API 模块\r\n * 统一封装微信和UniApp的图片选择功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 图片来源类型枚举\r\n */\r\nexport const ImageSourceTypes = {\r\n ALBUM: 'album', // 相册\r\n CAMERA: 'camera' // 相机\r\n};\r\n\r\n/**\r\n * 图片大小类型枚举\r\n */\r\nexport const ImageSizeTypes = {\r\n ORIGINAL: 'original', // 原图\r\n COMPRESSED: 'compressed' // 压缩图\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n count: 9,\r\n sizeType: [ImageSizeTypes.ORIGINAL, ImageSizeTypes.COMPRESSED],\r\n sourceType: [ImageSourceTypes.ALBUM, ImageSourceTypes.CAMERA]\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 确保数组格式\r\n if (!Array.isArray(normalized.sizeType)) {\r\n normalized.sizeType = [normalized.sizeType].filter(Boolean);\r\n }\r\n if (!Array.isArray(normalized.sourceType)) {\r\n normalized.sourceType = [normalized.sourceType].filter(Boolean);\r\n }\r\n \r\n // 数量限制 1-9\r\n normalized.count = Math.max(1, Math.min(9, parseInt(normalized.count) || 1));\r\n \r\n // 空数组回退默认值\r\n if (normalized.sizeType.length === 0) {\r\n normalized.sizeType = [ImageSizeTypes.COMPRESSED];\r\n }\r\n if (normalized.sourceType.length === 0) {\r\n normalized.sourceType = [ImageSourceTypes.ALBUM];\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持图片选择\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的图片选择\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseImageInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = { \r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => chooseImageInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信 API\r\n apiLogger.debug('调用微信图片选择', options);\r\n \r\n window.wx.chooseImage({\r\n count: options.count,\r\n sizeType: options.sizeType,\r\n sourceType: options.sourceType,\r\n success: (res) => {\r\n apiLogger.info('微信图片选择成功', { count: res.localIds?.length || 0 });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信图片选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseImageInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的图片选择(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseImageInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用图片选择', options);\r\n \r\n // 通过桥接层调用(禁用超时清理,等待用户选择完成)\r\n callApiInWebView('chooseImage', { ...options, disableTimeout: true }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 图片选择成功', { \r\n count: res?.tempFilePaths?.length || 0 \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 图片选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseImageInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 选择图片(统一入口)\r\n * \r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.count=9] - 最多选择的图片数量\r\n * @param {string[]} [options.sizeType] - 图片质量类型 ['original', 'compressed']\r\n * @param {string[]} [options.sourceType] - 图片来源类型 ['album', 'camera']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.chooseImage({\r\n * count: 1,\r\n * success: (res) => {\r\n * // 微信环境: res.localIds\r\n * // UniApp环境: res.tempFilePaths\r\n * console.log('选择成功:', res);\r\n * },\r\n * fail: (error) => {\r\n * console.error('选择失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 完整配置\r\n * qsh.chooseImage({\r\n * count: 3,\r\n * sizeType: ['compressed'],\r\n * sourceType: ['album'],\r\n * success: (res) => console.log(res),\r\n * fail: (err) => console.error(err)\r\n * });\r\n */\r\nexport function chooseImage(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持图片选择功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持图片选择', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始选择图片', {\r\n platform: environment.type,\r\n count: normalizedOptions.count,\r\n sizeType: normalizedOptions.sizeType,\r\n sourceType: normalizedOptions.sourceType\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n chooseImageInWeixin(normalizedOptions);\r\n } else {\r\n chooseImageInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'chooseImage',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的图片选择\r\n * \r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const result = await qsh.chooseImageAsync({ count: 1 });\r\n * console.log('选择的图片:', result);\r\n * } catch (error) {\r\n * console.error('选择失败:', error);\r\n * }\r\n */\r\nexport function chooseImageAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseImage({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取图片功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getImageCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n */\r\nexport function getImageCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n multipleSelection: true, // 支持多选\r\n sizeTypeSelection: true, // 支持质量选择\r\n sourceTypeSelection: true, // 支持来源选择\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}\r\n","/**\r\n * 扫码 API 模块\r\n * 统一封装微信和UniApp的扫码功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 扫码类型枚举\r\n */\r\nexport const ScanTypes = {\r\n QR_CODE: 'qrCode', // 二维码\r\n BAR_CODE: 'barCode', // 一维码(条形码)\r\n DATA_MATRIX: 'datamatrix', // Data Matrix 码\r\n PDF417: 'pdf417' // PDF417 条码\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n onlyFromCamera: true, // 只从相机扫码\r\n scanType: [ScanTypes.QR_CODE, ScanTypes.BAR_CODE] // 支持二维码和一维码\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 确保 scanType 是数组\r\n if (!Array.isArray(normalized.scanType)) {\r\n normalized.scanType = [normalized.scanType].filter(Boolean);\r\n }\r\n \r\n // 空数组回退默认值\r\n if (normalized.scanType.length === 0) {\r\n normalized.scanType = [ScanTypes.QR_CODE, ScanTypes.BAR_CODE];\r\n }\r\n \r\n // 确保 onlyFromCamera 是布尔值\r\n normalized.onlyFromCamera = !!normalized.onlyFromCamera;\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持扫码\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的扫码\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction scanCodeInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => scanCodeInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信扫码 API\r\n apiLogger.debug('调用微信扫码', options);\r\n \r\n // 微信 API:wx.scanQRCode\r\n window.wx.scanQRCode({\r\n needResult: 1, // 直接返回扫码结果\r\n scanType: options.scanType,\r\n success: (res) => {\r\n apiLogger.info('微信扫码成功', { result: res.resultStr });\r\n \r\n // 转换为统一格式(与 UniApp 一致)\r\n const result = {\r\n result: res.resultStr, // 扫码内容\r\n scanType: detectScanType(res.resultStr), // 推测扫码类型\r\n charSet: 'utf-8', // 微信默认 UTF-8\r\n errMsg: 'scanCode:ok'\r\n };\r\n \r\n options.success?.(result);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信扫码失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'scanCodeInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n/**\r\n * 根据内容推测扫码类型(辅助函数)\r\n * @param {string} content - 扫码内容\r\n * @returns {string} 扫码类型\r\n * @private\r\n */\r\nfunction detectScanType(content) {\r\n if (!content) return 'unknown';\r\n \r\n // 简单规则:长度较长或包含特殊字符通常是二维码\r\n if (content.length > 50 || /[^\\d]/.test(content)) {\r\n return ScanTypes.QR_CODE;\r\n }\r\n \r\n // 纯数字且长度适中,可能是条形码\r\n return ScanTypes.BAR_CODE;\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的扫码(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction scanCodeInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用扫码', options);\r\n \r\n // 通过桥接层调用(禁用超时清理,等待用户扫码完成)\r\n callApiInWebView('scanCode', { ...options, disableTimeout: true }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 扫码成功', { \r\n result: res?.result,\r\n scanType: res?.scanType\r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 扫码失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'scanCodeInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 扫码(统一入口)\r\n * \r\n * @param {Object} [options] - 扫码参数\r\n * @param {boolean} [options.onlyFromCamera=true] - 是否只能从相机扫码\r\n * @param {string[]} [options.scanType] - 扫码类型 ['qrCode', 'barCode']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.scanCode({\r\n * success: (res) => {\r\n * console.log('扫码结果:', res.result);\r\n * console.log('扫码类型:', res.scanType);\r\n * },\r\n * fail: (error) => {\r\n * console.error('扫码失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 只扫二维码\r\n * qsh.scanCode({\r\n * scanType: ['qrCode'],\r\n * success: (res) => console.log(res.result)\r\n * });\r\n * \r\n * @example\r\n * // 允许从相册选择\r\n * qsh.scanCode({\r\n * onlyFromCamera: false,\r\n * success: (res) => console.log(res.result)\r\n * });\r\n */\r\nexport function scanCode(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持扫码功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持扫码', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始扫码', {\r\n platform: environment.type,\r\n onlyFromCamera: normalizedOptions.onlyFromCamera,\r\n scanType: normalizedOptions.scanType\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n scanCodeInWeixin(normalizedOptions);\r\n } else {\r\n scanCodeInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'scanCode',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的扫码\r\n * \r\n * @param {Object} [options] - 扫码参数(不包含回调函数)\r\n * @returns {Promise} 扫码结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const result = await qsh.scanCodeAsync({\r\n * scanType: ['qrCode']\r\n * });\r\n * console.log('扫码结果:', result.result);\r\n * console.log('扫码类型:', result.scanType);\r\n * } catch (error) {\r\n * if (error.code === qsh.errors.codes.SCAN_CANCELLED) {\r\n * console.log('用户取消扫码');\r\n * } else {\r\n * console.error('扫码失败:', error);\r\n * }\r\n * }\r\n */\r\nexport function scanCodeAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n scanCode({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取扫码功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getScanCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n */\r\nexport function getScanCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n onlyFromCamera: true, // 支持只从相机扫码\r\n scanTypeSelection: true, // 支持扫码类型选择\r\n multipleTypes: true, // 支持多种扫码类型\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}\r\n\r\n","/**\r\n * 地理位置 API 模块\r\n * 统一封装微信和UniApp的地理位置功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView, clearPersistentCallbacksByApi } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 坐标类型枚举\r\n */\r\nexport const CoordinateTypes = {\r\n WGS84: 'wgs84', // GPS 坐标\r\n GCJ02: 'gcj02', // 国测局坐标(火星坐标)\r\n BD09: 'bd09' // 百度坐标\r\n};\r\n\r\n/**\r\n * 默认选项 - getLocation\r\n */\r\nconst DEFAULT_LOCATION_OPTIONS = {\r\n type: CoordinateTypes.WGS84,\r\n altitude: false\r\n};\r\n\r\n/**\r\n * 默认选项 - openLocation\r\n */\r\nconst DEFAULT_OPEN_LOCATION_OPTIONS = {\r\n scale: 18 // 地图缩放级别 1-28\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化 getLocation 选项\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeLocationOptions(options = {}) {\r\n const normalized = { ...DEFAULT_LOCATION_OPTIONS, ...options };\r\n \r\n // 确保 type 是合法值\r\n if (!Object.values(CoordinateTypes).includes(normalized.type)) {\r\n normalized.type = CoordinateTypes.WGS84;\r\n }\r\n \r\n // 确保 altitude 是布尔值\r\n normalized.altitude = !!normalized.altitude;\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 标准化位置更新参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeLocationUpdateOptions(options = {}) {\r\n const normalized = { ...options };\r\n\r\n if (!Object.values(CoordinateTypes).includes(normalized.type)) {\r\n normalized.type = CoordinateTypes.WGS84;\r\n }\r\n\r\n normalized.needFullAccuracy = !!normalized.needFullAccuracy;\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * 标准化 openLocation 选项\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOpenLocationOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPEN_LOCATION_OPTIONS, ...options };\r\n \r\n // 验证 latitude(纬度)\r\n if (normalized.latitude === undefined || normalized.latitude === null) {\r\n const error = {\r\n errMsg: '缺少必需参数:latitude(纬度)',\r\n code: 'PARAM_MISSING'\r\n };\r\n throw error;\r\n }\r\n \r\n if (typeof normalized.latitude !== 'number') {\r\n const error = {\r\n errMsg: `latitude 参数类型错误:期望 number,实际 ${typeof normalized.latitude}`,\r\n code: 'PARAM_TYPE_ERROR',\r\n details: {\r\n param: 'latitude',\r\n expected: 'number',\r\n actual: typeof normalized.latitude,\r\n value: normalized.latitude\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证纬度范围 -90 ~ 90\r\n if (normalized.latitude < -90 || normalized.latitude > 90) {\r\n const error = {\r\n errMsg: `latitude 超出范围:有效范围 -90 ~ 90,实际值 ${normalized.latitude}`,\r\n code: 'PARAM_INVALID',\r\n details: {\r\n param: 'latitude',\r\n value: normalized.latitude,\r\n validRange: '-90 ~ 90'\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证 longitude(经度)\r\n if (normalized.longitude === undefined || normalized.longitude === null) {\r\n const error = {\r\n errMsg: '缺少必需参数:longitude(经度)',\r\n code: 'PARAM_MISSING'\r\n };\r\n throw error;\r\n }\r\n \r\n if (typeof normalized.longitude !== 'number') {\r\n const error = {\r\n errMsg: `longitude 参数类型错误:期望 number,实际 ${typeof normalized.longitude}`,\r\n code: 'PARAM_TYPE_ERROR',\r\n details: {\r\n param: 'longitude',\r\n expected: 'number',\r\n actual: typeof normalized.longitude,\r\n value: normalized.longitude\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 验证经度范围 -180 ~ 180\r\n if (normalized.longitude < -180 || normalized.longitude > 180) {\r\n const error = {\r\n errMsg: `longitude 超出范围:有效范围 -180 ~ 180,实际值 ${normalized.longitude}`,\r\n code: 'PARAM_INVALID',\r\n details: {\r\n param: 'longitude',\r\n value: normalized.longitude,\r\n validRange: '-180 ~ 180'\r\n }\r\n };\r\n throw error;\r\n }\r\n \r\n // 缩放级别限制 1-28\r\n if (normalized.scale !== undefined && normalized.scale !== null) {\r\n // 尝试转换为数字\r\n const scaleNum = Number(normalized.scale);\r\n if (isNaN(scaleNum)) {\r\n apiLogger.warn('scale 参数无效,使用默认值 18', { scale: normalized.scale });\r\n normalized.scale = 18;\r\n } else {\r\n normalized.scale = Math.max(1, Math.min(28, Math.floor(scaleNum)));\r\n }\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持地理位置\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下获取位置\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction getLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => getLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信定位 API\r\n apiLogger.debug('调用微信定位', options);\r\n \r\n window.wx.getLocation({\r\n type: options.type,\r\n success: (res) => {\r\n apiLogger.info('微信定位成功', { \r\n latitude: res.latitude, \r\n longitude: res.longitude \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信定位失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'getLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n/**\r\n * 微信环境下查看位置\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction openLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => openLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信查看位置 API\r\n apiLogger.debug('调用微信查看位置', options);\r\n \r\n window.wx.openLocation({\r\n latitude: options.latitude,\r\n longitude: options.longitude,\r\n name: options.name || '',\r\n address: options.address || '',\r\n scale: options.scale || 18,\r\n infoUrl: options.infoUrl || '',\r\n success: (res) => {\r\n apiLogger.info('微信查看位置成功');\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信查看位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'openLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下获取位置(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction getLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用获取位置', options);\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('getLocation', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 获取位置成功', { \r\n latitude: res?.latitude, \r\n longitude: res?.longitude \r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 获取位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'getLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n/**\r\n * UniApp 环境下查看位置(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction openLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用查看位置', options);\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('openLocation', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 查看位置成功');\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 查看位置失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'openLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 获取当前地理位置(统一入口)\r\n * \r\n * @param {Object} [options] - 定位参数\r\n * @param {string} [options.type='wgs84'] - 坐标类型 'wgs84' | 'gcj02' | 'bd09'\r\n * @param {boolean} [options.altitude=false] - 是否返回高度信息\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.getLocation({\r\n * success: (res) => {\r\n * console.log('纬度:', res.latitude);\r\n * console.log('经度:', res.longitude);\r\n * console.log('精度:', res.accuracy);\r\n * },\r\n * fail: (error) => {\r\n * console.error('定位失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 获取火星坐标(gcj02)\r\n * qsh.getLocation({\r\n * type: 'gcj02',\r\n * altitude: true,\r\n * success: (res) => {\r\n * console.log('位置:', res.latitude, res.longitude);\r\n * console.log('高度:', res.altitude);\r\n * }\r\n * });\r\n */\r\nexport function getLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持定位功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持定位', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeLocationOptions(options);\r\n \r\n apiLogger.info('开始获取位置', {\r\n platform: environment.type,\r\n type: normalizedOptions.type,\r\n altitude: normalizedOptions.altitude\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n getLocationInWeixin(normalizedOptions);\r\n } else {\r\n getLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'getLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * 查看位置(统一入口)\r\n * \r\n * @param {Object} options - 位置参数\r\n * @param {number} options.latitude - 纬度(必填,数字类型,范围 -90 ~ 90)\r\n * @param {number} options.longitude - 经度(必填,数字类型,范围 -180 ~ 180)\r\n * @param {string} [options.name] - 位置名称\r\n * @param {string} [options.address] - 详细地址\r\n * @param {number} [options.scale=18] - 地图缩放级别 1-28\r\n * @param {string} [options.infoUrl] - 底部链接\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门',\r\n * address: '北京市东城区',\r\n * success: () => {\r\n * console.log('打开地图成功');\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 完整配置\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门广场',\r\n * address: '北京市东城区东长安街',\r\n * scale: 15,\r\n * infoUrl: 'https://example.com/detail',\r\n * success: () => console.log('成功'),\r\n * fail: (err) => console.error(err)\r\n * });\r\n */\r\nexport function openLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持查看位置功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持查看位置', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数(包含参数验证)\r\n let normalizedOptions;\r\n try {\r\n normalizedOptions = normalizeOpenLocationOptions(options);\r\n } catch (validationError) {\r\n // 参数验证失败,触发 fail 回调\r\n apiLogger.error('参数验证失败', validationError);\r\n options.fail?.(validationError);\r\n options.complete?.();\r\n return;\r\n }\r\n \r\n apiLogger.info('开始查看位置', {\r\n platform: environment.type,\r\n latitude: normalizedOptions.latitude,\r\n longitude: normalizedOptions.longitude,\r\n name: normalizedOptions.name\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n openLocationInWeixin(normalizedOptions);\r\n } else {\r\n openLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'openLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的获取位置\r\n * \r\n * @param {Object} [options] - 定位参数(不包含回调函数)\r\n * @returns {Promise} 定位结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const location = await qsh.getLocationAsync({\r\n * type: 'gcj02'\r\n * });\r\n * console.log('纬度:', location.latitude);\r\n * console.log('经度:', location.longitude);\r\n * } catch (error) {\r\n * if (error.code === qsh.errors.codes.LOCATION_CANCELLED) {\r\n * console.log('用户拒绝授权');\r\n * } else {\r\n * console.error('定位失败:', error);\r\n * }\r\n * }\r\n */\r\nexport function getLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n getLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的查看位置\r\n * \r\n * @param {Object} options - 位置参数(不包含回调函数)\r\n * @returns {Promise} 操作结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * await qsh.openLocationAsync({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门'\r\n * });\r\n * console.log('地图已打开');\r\n * } catch (error) {\r\n * console.error('打开地图失败:', error);\r\n * }\r\n */\r\nexport function openLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取地理位置功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getLocationCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n */\r\nexport function getLocationCapabilities() {\r\n const isWeixin = isWeixinMiniProgram();\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixin ? 'weixin' : 'webview',\r\n features: {\r\n getLocation: true, // 获取位置\r\n openLocation: true, // 查看位置\r\n coordinateTypes: true, // 支持坐标类型选择\r\n altitudeSupport: true, // 支持高度信息\r\n asyncSupport: true, // 支持 Promise\r\n onLocationChange: !isWeixin, // 支持位置监听(微信环境不支持)\r\n }\r\n };\r\n}\r\n\r\n// ==================== 位置监听回调管理 ====================\r\n\r\nconst locationChangeCallbacks = new Set();\r\nconst locationChangeErrorCallbacks = new Set();\r\n\r\nfunction notifyCallbacks(callbacks, payload, context) {\r\n callbacks.forEach((callback) => {\r\n if (typeof callback === 'function') {\r\n ErrorHandler.safeExecute(() => callback(payload), { context });\r\n return;\r\n }\r\n apiLogger.warn('监听回调不是函数,已跳过', { type: typeof callback });\r\n });\r\n}\r\n\r\n/**\r\n * 开启前台持续定位服务\r\n * 对应原生:uni.startLocationUpdate\r\n */\r\nexport function startLocationUpdate(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持该接口`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('当前环境不支持此接口', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n };\r\n\r\n const normalizedOptions = normalizeLocationUpdateOptions(options);\r\n\r\n apiLogger.info('正在开启定位监听');\r\n callApiInWebView('startLocationUpdate', {\r\n type: normalizedOptions.type,\r\n needFullAccuracy: normalizedOptions.needFullAccuracy\r\n }, {\r\n success: (res) => {\r\n apiLogger.info('定位监听已启动');\r\n options.success?.(res);\r\n },\r\n fail: (err) => options.fail?.(err),\r\n complete: options.complete\r\n });\r\n }, { context: 'startLocationUpdate' });\r\n}\r\n\r\n/**\r\n * 停止前台持续定位服务\r\n * 对应原生:uni.stopLocationUpdate\r\n */\r\nexport function stopLocationUpdate(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持该接口`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('当前环境不支持此接口', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n };\r\n\r\n apiLogger.info('正在停止定位监听');\r\n callApiInWebView('stopLocationUpdate', options, {\r\n success: (res) => {\r\n apiLogger.info('定位监听已停止');\r\n options.success?.(res);\r\n },\r\n fail: (err) => options.fail?.(err),\r\n complete: options.complete\r\n });\r\n }, { context: 'stopLocationUpdate' });\r\n}\r\n\r\n/**\r\n * 监听实时地理位置变化事件\r\n * 对应原生:uni.onLocationChange\r\n * 核心:通过 isPersistent: true 告知桥接层保留回调函数\r\n * \r\n * 注意:位置变化时调用回调函数,监听错误由 onLocationChangeError 处理\r\n * \r\n * @param {Function} callback - 回调函数,入参为位置信息对象\r\n * \r\n * @example\r\n * // 直接传入回调函数\r\n * qsh.onLocationChange((res) => {\r\n * console.log('位置:', res.latitude, res.longitude);\r\n * console.log('精度:', res.accuracy, '米');\r\n * });\r\n */\r\nexport function onLocationChange(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 验证必须是函数\r\n if (typeof callback !== 'function') {\r\n apiLogger.error('onLocationChange 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'onLocationChange 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n const hasListener = locationChangeCallbacks.size > 0;\r\n locationChangeCallbacks.add(callback);\r\n\r\n if (!hasListener) {\r\n apiLogger.debug('注册实时位置变化监听器');\r\n callApiInWebView('onLocationChange', { isPersistent: true }, {\r\n success: (res) => {\r\n apiLogger.debug('收到实时位置推送', res);\r\n notifyCallbacks(locationChangeCallbacks, res, 'onLocationChange');\r\n },\r\n fail: (error) => {\r\n // 监听错误由 onLocationChangeError 处理,此处仅记录日志\r\n apiLogger.warn('位置变化监听出错,请通过 onLocationChangeError 监听错误', error);\r\n locationChangeCallbacks.delete(callback);\r\n if (locationChangeCallbacks.size === 0) {\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n }\r\n }\r\n });\r\n }\r\n }, { context: 'onLocationChange' });\r\n}\r\n\r\n/**\r\n * 移除实时地理位置变化事件的监听函数\r\n * 对应原生:uni.offLocationChange\r\n * \r\n * 注意:调用此方法会停止监听位置变化事件\r\n * \r\n * @param {Function} [callback] - 可选回调,用于取消指定监听\r\n * @example\r\n * // 移除监听\r\n * qsh.offLocationChange();\r\n */\r\nexport function offLocationChange(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n if (callback && typeof callback !== 'function') {\r\n apiLogger.error('offLocationChange 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'offLocationChange 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n if (callback) {\r\n locationChangeCallbacks.delete(callback);\r\n } else {\r\n locationChangeCallbacks.clear();\r\n }\r\n\r\n if (locationChangeCallbacks.size > 0) {\r\n return;\r\n }\r\n\r\n apiLogger.info('移除位置变化监听器');\r\n callApiInWebView('offLocationChange', {}, {\r\n success: () => {\r\n apiLogger.info('位置变化监听已移除');\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n },\r\n fail: (error) => {\r\n apiLogger.error('移除位置变化监听失败', error);\r\n clearPersistentCallbacksByApi('onLocationChange');\r\n }\r\n });\r\n }, { context: 'offLocationChange' });\r\n}\r\n\r\n/**\r\n * 监听持续定位接口返回失败时触发\r\n * 对应原生:uni.onLocationChangeError\r\n * \r\n * 注意:此监听器用于捕获位置更新过程中的错误,需要配合 startLocationUpdate 和 onLocationChange 使用\r\n * \r\n * @param {Function} callback - 错误回调函数,入参为错误对象\r\n * \r\n * @example\r\n * // 直接传入回调函数\r\n * qsh.onLocationChangeError((err) => {\r\n * console.error('位置监听出错:', err.code, err.message);\r\n * });\r\n */\r\nexport function onLocationChangeError(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 验证必须是函数\r\n if (typeof callback !== 'function') {\r\n apiLogger.error('onLocationChangeError 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'onLocationChangeError 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n const hasListener = locationChangeErrorCallbacks.size > 0;\r\n locationChangeErrorCallbacks.add(callback);\r\n\r\n if (!hasListener) {\r\n apiLogger.debug('注册位置更新错误监听器');\r\n callApiInWebView('onLocationChangeError', { isPersistent: true }, {\r\n success: (err) => {\r\n apiLogger.warn('持续定位发生异常', err);\r\n notifyCallbacks(locationChangeErrorCallbacks, err, 'onLocationChangeError');\r\n },\r\n fail: (error) => {\r\n apiLogger.warn('位置更新错误监听注册失败', error);\r\n locationChangeErrorCallbacks.delete(callback);\r\n if (locationChangeErrorCallbacks.size === 0) {\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n }\r\n }\r\n });\r\n }\r\n }, { context: 'onLocationChangeError' });\r\n}\r\n\r\n/**\r\n * 取消注册位置更新错误回调\r\n * 对应原生:uni.offLocationChangeError\r\n * \r\n * 注意:调用此方法会停止监听位置更新错误事件\r\n * \r\n * @param {Function} [callback] - 可选回调,用于取消指定监听\r\n * @example\r\n * // 移除错误监听\r\n * qsh.offLocationChangeError();\r\n */\r\nexport function offLocationChangeError(callback) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (isWeixinMiniProgram()) {\r\n apiLogger.warn('当前环境不支持此接口', { platform: environment.type });\r\n return;\r\n }\r\n\r\n if (callback && typeof callback !== 'function') {\r\n apiLogger.error('offLocationChangeError 回调不是函数', { type: typeof callback });\r\n throw {\r\n errMsg: 'offLocationChangeError 回调必须是函数',\r\n code: 'INVALID_CALLBACK'\r\n };\r\n }\r\n\r\n if (callback) {\r\n locationChangeErrorCallbacks.delete(callback);\r\n } else {\r\n locationChangeErrorCallbacks.clear();\r\n }\r\n\r\n if (locationChangeErrorCallbacks.size > 0) {\r\n return;\r\n }\r\n\r\n apiLogger.info('移除定位错误监听器');\r\n callApiInWebView('offLocationChangeError', {}, {\r\n success: () => {\r\n apiLogger.info('定位错误监听已移除');\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n },\r\n fail: (error) => {\r\n apiLogger.error('移除定位错误监听失败', error);\r\n clearPersistentCallbacksByApi('onLocationChangeError');\r\n }\r\n });\r\n }, { context: 'offLocationChangeError' });\r\n}","/**\r\n * 位置选择 API 模块\r\n * 统一封装微信和UniApp的位置选择功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n latitude: null, // 目标地纬度\r\n longitude: null // 目标地经度\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // 验证 latitude(如果提供)\r\n if (normalized.latitude !== null && normalized.latitude !== undefined) {\r\n if (typeof normalized.latitude !== 'number') {\r\n apiLogger.warn('latitude 参数类型错误,已忽略', { \r\n latitude: normalized.latitude \r\n });\r\n normalized.latitude = null;\r\n } else if (normalized.latitude < -90 || normalized.latitude > 90) {\r\n apiLogger.warn('latitude 超出范围,已忽略', { \r\n latitude: normalized.latitude \r\n });\r\n normalized.latitude = null;\r\n }\r\n }\r\n \r\n // 验证 longitude(如果提供)\r\n if (normalized.longitude !== null && normalized.longitude !== undefined) {\r\n if (typeof normalized.longitude !== 'number') {\r\n apiLogger.warn('longitude 参数类型错误,已忽略', { \r\n longitude: normalized.longitude \r\n });\r\n normalized.longitude = null;\r\n } else if (normalized.longitude < -180 || normalized.longitude > 180) {\r\n apiLogger.warn('longitude 超出范围,已忽略', { \r\n longitude: normalized.longitude \r\n });\r\n normalized.longitude = null;\r\n }\r\n }\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持位置选择\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的位置选择\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseLocationInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查微信 API\r\n if (!window.wx) {\r\n const error = {\r\n errMsg: '微信JS-SDK未加载',\r\n code: 'WEIXIN_SDK_NOT_LOADED'\r\n };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n waitForWeixinConfig()\r\n .then(() => chooseLocationInWeixin(options))\r\n .catch((error) => {\r\n apiLogger.error('微信配置失败', error);\r\n options.fail?.({ errMsg: `微信配置失败: ${error.message}` });\r\n });\r\n return;\r\n }\r\n\r\n // 调用微信位置选择 API\r\n apiLogger.debug('调用微信位置选择', options);\r\n \r\n // 构建微信 API 参数\r\n const wxOptions = {\r\n success: (res) => {\r\n apiLogger.info('微信位置选择成功', { \r\n name: res.name,\r\n address: res.address,\r\n latitude: res.latitude,\r\n longitude: res.longitude\r\n });\r\n \r\n // 统一返回格式\r\n const result = {\r\n name: res.name, // 位置名称\r\n address: res.address, // 详细地址\r\n latitude: res.latitude, // 纬度\r\n longitude: res.longitude, // 经度\r\n errMsg: 'chooseLocation:ok'\r\n };\r\n \r\n options.success?.(result);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('微信位置选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n };\r\n \r\n // 构建微信 chooseLocation 参数\r\n const weixinParams = {};\r\n \r\n // 微信支持 latitude 和 longitude 参数\r\n if (options.latitude !== null && options.latitude !== undefined) {\r\n weixinParams.latitude = options.latitude;\r\n }\r\n if (options.longitude !== null && options.longitude !== undefined) {\r\n weixinParams.longitude = options.longitude;\r\n }\r\n \r\n window.wx.chooseLocation({\r\n ...weixinParams,\r\n success: wxOptions.success,\r\n fail: wxOptions.fail,\r\n complete: wxOptions.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseLocationInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的位置选择(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction chooseLocationInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用位置选择', options);\r\n \r\n // 构建 UniApp API 参数(不使用超时清理)\r\n const uniOptions = {\r\n // 禁用超时清理,等待用户操作完成后才清理\r\n disableTimeout: true,\r\n success: (res) => {\r\n apiLogger.info('UniApp 位置选择成功', { \r\n name: res?.name,\r\n address: res?.address,\r\n latitude: res?.latitude,\r\n longitude: res?.longitude\r\n });\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 位置选择失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n };\r\n \r\n // 构建 UniApp chooseLocation 参数\r\n if (options.latitude !== null && options.latitude !== undefined) {\r\n uniOptions.latitude = options.latitude;\r\n }\r\n if (options.longitude !== null && options.longitude !== undefined) {\r\n uniOptions.longitude = options.longitude;\r\n }\r\n \r\n // 通过桥接层调用\r\n callApiInWebView('chooseLocation', uniOptions, {\r\n success: (res) => {\r\n uniOptions.success(res);\r\n },\r\n fail: (error) => {\r\n uniOptions.fail(error);\r\n },\r\n complete: uniOptions.complete\r\n });\r\n \r\n }, { \r\n context: 'chooseLocationInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 选择位置(统一入口)\r\n * \r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.latitude] - 目标地纬度\r\n * @param {number} [options.longitude] - 目标地经度\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * // 基础使用\r\n * qsh.chooseLocation({\r\n * success: (res) => {\r\n * console.log('位置名称:', res.name);\r\n * console.log('详细地址:', res.address);\r\n * console.log('纬度:', res.latitude);\r\n * console.log('经度:', res.longitude);\r\n * },\r\n * fail: (error) => {\r\n * console.error('选择失败:', error);\r\n * }\r\n * });\r\n * \r\n * @example\r\n * // 指定目标地中心点\r\n * qsh.chooseLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * success: (res) => {\r\n * console.log('已选择:', res.name);\r\n * }\r\n * });\r\n */\r\nexport function chooseLocation(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持位置选择功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持位置选择', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始选择位置', {\r\n platform: environment.type,\r\n latitude: normalizedOptions.latitude,\r\n longitude: normalizedOptions.longitude\r\n });\r\n\r\n // 根据环境调用对应实现\r\n if (isWeixinMiniProgram()) {\r\n chooseLocationInWeixin(normalizedOptions);\r\n } else {\r\n chooseLocationInUniApp(normalizedOptions);\r\n }\r\n \r\n }, { \r\n context: 'chooseLocation',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的位置选择\r\n * \r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * \r\n * @example\r\n * // 使用 Promise\r\n * try {\r\n * const location = await qsh.chooseLocationAsync();\r\n * console.log('位置名称:', location.name);\r\n * console.log('详细地址:', location.address);\r\n * console.log('坐标:', location.latitude, location.longitude);\r\n * } catch (error) {\r\n * if (error.errMsg.includes('cancel')) {\r\n * console.log('用户取消选择');\r\n * } else {\r\n * console.error('选择失败:', error);\r\n * }\r\n * }\r\n * \r\n * @example\r\n * // 指定目标地中心点\r\n * async function selectNearbyPlace() {\r\n * try {\r\n * const location = await qsh.chooseLocationAsync({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470\r\n * });\r\n * return location;\r\n * } catch (error) {\r\n * console.error('选择位置失败:', error);\r\n * throw error;\r\n * }\r\n * }\r\n */\r\nexport function chooseLocationAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseLocation({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取位置选择功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getChooseLocationCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n * console.log('实现类型:', capabilities.implementation);\r\n * console.log('支持的特性:', capabilities.features);\r\n */\r\nexport function getChooseLocationCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n chooseLocation: true, // 支持位置选择\r\n centerPoint: true, // 支持指定中心点(latitude/longitude)\r\n asyncSupport: true // 支持 Promise\r\n }\r\n };\r\n}","/**\r\n * 能力适配注册表\r\n * 提供平台 -> 实现的映射,便于扩展和测试\r\n */\r\n\r\nconst registry = new Map();\r\n\r\n/**\r\n * 注册能力实现\r\n * @param {string} apiName API 名称\r\n * @param {Object<string, Function>} implementations 按环境类型映射的实现\r\n */\r\nexport function registerCapability(apiName, implementations = {}) {\r\n registry.set(apiName, implementations);\r\n}\r\n\r\n/**\r\n * 解析能力实现\r\n * @param {string} apiName API 名称\r\n * @param {string} environmentType 当前环境类型\r\n * @returns {Function|undefined}\r\n */\r\nexport function resolveCapability(apiName, environmentType) {\r\n const impls = registry.get(apiName);\r\n if (!impls) return undefined;\r\n return impls[environmentType] || impls.default;\r\n}\r\n\r\n/**\r\n * 调用能力实现\r\n * @param {string} apiName API 名称\r\n * @param {string} environmentType 当前环境类型\r\n * @param {...any} args 传递给实现的参数\r\n * @returns {any}\r\n */\r\nexport function invokeCapability(apiName, environmentType, ...args) {\r\n const impl = resolveCapability(apiName, environmentType);\r\n if (typeof impl !== 'function') {\r\n throw new Error(`[Capability] No implementation registered for ${apiName} under ${environmentType}`);\r\n }\r\n return impl(...args);\r\n}\r\n\r\n/**\r\n * 导出注册表快照(只读)\r\n */\r\nexport function getCapabilityRegistry() {\r\n return registry;\r\n}\r\n\r\n\r\n","/**\r\n * 微信分享 API 模块\r\n * 统一封装微信和 UniApp WebView 的分享能力\r\n */\r\n\r\nimport { getEnvironmentInfo, isWeixinMiniProgram } from \"../core/environment.js\";\r\nimport { ErrorHandler } from \"../core/error-handler.js\";\r\nimport { apiLogger } from \"../core/logger.js\";\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from \"../core/weixin-loader.js\";\r\nimport { callApiInWebView } from \"../core/webview-bridge.js\";\r\nimport { registerCapability, resolveCapability } from \"./capability-registry.js\";\r\n\r\n// ==================== 常量定义 ====================\r\n/**\r\n * 分享去向类型枚举\r\n */\r\nexport const shareToTypes = {\r\n 0: \"WXSceneSession\", // 聊天界面\r\n 1: \"WXSceneTimeline\", // 朋友圈\r\n};\r\n/**\r\n * 分享内容类型枚举\r\n */\r\nexport const shareValueTypes = {\r\n 0: \"图文/网页\",\r\n 1: \"纯文字\",\r\n 2: \"纯图片\",\r\n 3: \"音乐\",\r\n 4: \"视频\",\r\n 5: \"小程序\",\r\n};\r\n// ==================== 工具函数 ====================\r\n// ==================== 微信环境实现 ====================\r\n\r\nfunction toShareInWeixin(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n if (typeof window === \"undefined\" || !window.wx) {\r\n const error = { errMsg: \"微信JS-SDK未加载\", code: \"WEIXIN_SDK_NOT_LOADED\" };\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n // 等待微信配置完成\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info(\"等待微信配置完成\");\r\n return waitForWeixinConfig().then(() => toShareInWeixin(options));\r\n }\r\n\r\n const params = { ...options };\r\n apiLogger.debug(\"调用微信分享\", params);\r\n if (options?.isCallBack) {\r\n return new Promise((resolve, reject) => {\r\n callApiInWebView(\"toShareData\", options, {\r\n success: res => {\r\n options.success?.(res);\r\n resolve(res);\r\n },\r\n fail: error => {\r\n apiLogger.error(\"UniApp 微信分享失败\", error);\r\n options.fail?.(error);\r\n reject(error);\r\n },\r\n complete: options.complete,\r\n });\r\n });\r\n } else {\r\n return new Promise((resolve, reject) => {\r\n window.wx[params.scene]({\r\n ...params,\r\n success: () => {\r\n const result = { errMsg: \"weixinShare:ok\" };\r\n options.success?.(result);\r\n resolve(result);\r\n },\r\n fail: error => {\r\n const wrappedError = { errMsg: error?.errMsg || \"weixinShare:fail\", details: error };\r\n apiLogger.error(\"微信分享失败\", wrappedError);\r\n options.fail?.(wrappedError);\r\n reject(wrappedError);\r\n },\r\n complete: options.complete,\r\n });\r\n });\r\n }\r\n },\r\n {\r\n context: \"toShareInWeixin\",\r\n platform: \"weixin\",\r\n }\r\n );\r\n}\r\n\r\nfunction normalizeWeixinOptions(options = {}, type) {\r\n const normalized = { ...options };\r\n const params = {\r\n scene: normalized.scene === 1 ? \"updateTimelineShareData\" : \"updateAppMessageShareData\",\r\n };\r\n apiLogger.info(\"格式化微信参数\", normalized);\r\n\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"title\")) {\r\n return { message: \"参数字段title值缺少!\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"imageUrl\")) {\r\n return { message: \"参数字段imageUrl值缺少!9999\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"path\")) {\r\n return { message: \"参数字段path值缺少!\", success: false };\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(normalized, \"summary\")) {\r\n return { message: \"参数字段summary值缺少!\", success: false };\r\n }\r\n\r\n params.title = normalized.title;\r\n params.imgUrl = normalized.imageUrl;\r\n params.link = normalized.path;\r\n params.desc = normalized.summary;\r\n\r\n return { params, success: true };\r\n}\r\n// ==================== UniApp 环境实现 ====================\r\nfunction toShareInUniApp(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n apiLogger.debug(\"通过 WebView 桥接调用微信分享\", options);\r\n console.log(\"桥接调用微信分享桥接调用微信分享:\", JSON.stringify(toRawLike(options), null, 2));\r\n\r\n return new Promise((resolve, reject) => {\r\n callApiInWebView(\"toShareData\", options, {\r\n success: res => {\r\n options.success?.(res);\r\n resolve(res);\r\n },\r\n fail: error => {\r\n apiLogger.error(\"UniApp 微信分享失败\", error);\r\n options.fail?.(error);\r\n reject(error);\r\n },\r\n complete: options.complete,\r\n });\r\n });\r\n },\r\n {\r\n context: \"toShareInUniApp\",\r\n platform: \"uniapp\",\r\n }\r\n );\r\n}\r\nfunction normalizeUniAppOptions(options = {}) {\r\n const normalized = { ...options };\r\n const params = {\r\n provider: \"weixin\",\r\n scene: \"WXSceneSession\",\r\n };\r\n apiLogger.info(\"格式化 UniApp 参数\", normalized);\r\n // 确保scene(分享去向)是可枚举类型 0: 聊天框 1:朋友圈\r\n if ([0, 1].some(item => parseInt(item) === parseInt(normalized.scene))) {\r\n params.scene = shareToTypes[normalized.scene];\r\n } else {\r\n // 否则默认聊天框\r\n params.scene = \"WXSceneSession\";\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"type\")) {\r\n const typeValue = Number(normalized.type);\r\n // 确保type(分享内容)是可枚举类型 0:图文 1:文字 2:图片 5:小程序\r\n const types = Object.keys(shareValueTypes);\r\n if (types.some(item => parseInt(item) === typeValue)) {\r\n params.type = typeValue;\r\n if ([0].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"path\")) {\r\n params.href = normalized.path;\r\n } else {\r\n return { message: `参数字段path值缺少!`, success: false };\r\n }\r\n }\r\n if ([0, 1].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"summary\")) {\r\n params.summary = normalized.summary;\r\n } else {\r\n return { message: `参数字段summary值缺少!`, success: false };\r\n }\r\n }\r\n if ([0, 2, 5].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"imageUrl\")) {\r\n params.imageUrl = normalized.imageUrl;\r\n } else {\r\n return { message: `参数字段imageUrl值缺少!`, success: false };\r\n }\r\n }\r\n if ([5].includes(typeValue)) {\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"miniProgram\")) {\r\n const miniProgram = { ...normalized.miniProgram };\r\n // if()\r\n //\r\n }\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"title\")) {\r\n params.title = normalized.title;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"success\")) {\r\n params.success = normalized.success;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"fail\")) {\r\n params.fail = normalized.fail;\r\n }\r\n if (Object.prototype.hasOwnProperty.call(normalized, \"complete\")) {\r\n params.complete = normalized.complete;\r\n }\r\n } else {\r\n return { message: `参数字段type值有误!`, success: false };\r\n }\r\n } else {\r\n return { message: `参数字段type缺少!`, success: false };\r\n }\r\n return { params, success: true };\r\n}\r\n// ==================== 公共 API ====================\r\n\r\nconst SHARE_CAPABILITY_KEY = \"share.toShare\";\r\n\r\nregisterCapability(SHARE_CAPABILITY_KEY, {\r\n weixin: toShareInWeixin,\r\n webview: toShareInUniApp,\r\n plus: toShareInUniApp,\r\n nvue: toShareInUniApp,\r\n uvue: toShareInUniApp,\r\n UniApp: toShareInUniApp,\r\n h5: toShareInUniApp,\r\n default: undefined,\r\n});\r\n// 仅用于日志打印:在 Vue 响应式对象场景下尽量“脱壳”,否则直接返回原值\r\nfunction toRawLike(value) {\r\n // Vue3 Proxy 内部可能暴露 __v_raw(非官方 API),这里做最小兼容\r\n if (value && typeof value === \"object\" && value.__v_raw) return value.__v_raw;\r\n return value;\r\n}\r\n/**\r\n * 微信分享(统一入口)\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShare(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n const env = getEnvironmentInfo();\r\n const impl = resolveCapability(SHARE_CAPABILITY_KEY, env.type);\r\n\r\n if (typeof impl !== \"function\") {\r\n const error = {\r\n errMsg: `当前环境 (${env.type}) 不支持微信分享功能`,\r\n code: \"PLATFORM_NOT_SUPPORTED\",\r\n };\r\n apiLogger.error(\"平台不支持微信分享\", { platform: env.type });\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const normalized = isWeixinMiniProgram() ? normalizeWeixinOptions(options) : normalizeUniAppOptions(options);\r\n\r\n if (!normalized.success) {\r\n const error = { errMsg: normalized.message || \"参数校验失败\", code: \"INVALID_PARAMS\" };\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const params = normalized.params;\r\n apiLogger.info(\"开始微信分享\", { platform: env.type, type: params?.type });\r\n return impl(params);\r\n },\r\n {\r\n context: \"toShare\",\r\n options,\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Promise 版本\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShareAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n toShare({\r\n ...options,\r\n success: resolve,\r\n fail: reject,\r\n });\r\n });\r\n}\r\n/**\r\n * 微信分享(统一入口)宿主回调\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShareCallBack(options = {}) {\r\n return ErrorHandler.safeExecute(\r\n () => {\r\n const env = getEnvironmentInfo();\r\n const impl = resolveCapability(SHARE_CAPABILITY_KEY, env.type);\r\n\r\n if (typeof impl !== \"function\") {\r\n const error = {\r\n errMsg: `当前环境 (${env.type}) 不支持微信分享功能`,\r\n code: \"PLATFORM_NOT_SUPPORTED\",\r\n };\r\n apiLogger.error(\"平台不支持微信分享\", { platform: env.type });\r\n options.fail?.(error);\r\n return Promise.reject(error);\r\n }\r\n\r\n const normalized = isWeixinMiniProgram() ? normalizeWeixinOptions(options, 1) : normalizeUniAppOptions(options);\r\n console.log(\"normalizednormalizednormalized:\", JSON.stringify(toRawLike(normalized), null, 2));\r\n if (!normalized.success) {\r\n const error = { errMsg: normalized.message || \"参数校验失败\", code: \"INVALID_PARAMS\" };\r\n options.fail?.(error);\r\n console.log(\"你是什么东西啊:\", JSON.stringify(toRawLike(error), null, 2));\r\n return Promise.reject(error);\r\n }\r\n\r\n const params = normalized.params;\r\n apiLogger.info(\"开始微信分享\", { platform: env.type, type: params?.type });\r\n return impl({ ...params, isCallBack: true });\r\n },\r\n {\r\n context: \"toShare\",\r\n options,\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Promise 版本\r\n * @param {Object} [options]\r\n * @returns {Promise<any>}\r\n */\r\nexport function toShareCallBackAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n toShareCallBack({\r\n ...options,\r\n success: resolve,\r\n fail: reject,\r\n });\r\n });\r\n}\r\n","/**\r\n * 蓝牙 API 模块\r\n * 统一封装微信和 UniApp 的蓝牙功能\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { waitForWeixinConfig, isWeixinConfigReady } from '../core/weixin-loader.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 蓝牙状态枚举\r\n */\r\nexport const BluetoothStates = {\r\n OFF: 'off', // 蓝牙关闭\r\n ON: 'on', // 蓝牙开启\r\n UNAVAILABLE: 'unavailable', // 不支持蓝牙\r\n UNAUTHORIZED: 'unauthorized' // 未授权\r\n};\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n allowDuplicatesKey: false, // 是否允许重复上报同一设备\r\n services: [] // 指定服务 UUID 列表\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\nfunction normalizeOptions(options = {}) {\r\n return { ...DEFAULT_OPTIONS, ...options };\r\n}\r\n\r\nfunction isSupported() {\r\n const supportedEnvs = ['weixin', 'webview', 'UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\nfunction openBluetoothAdapterInWeixin(options) {\r\n return ErrorHandler.safeExecute(async () => {\r\n if (!window.wx) {\r\n const error = { errMsg: '微信JS-SDK未加载', code: 'WEIXIN_SDK_NOT_LOADED' };\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n if (!isWeixinConfigReady()) {\r\n apiLogger.info('等待微信配置完成');\r\n await waitForWeixinConfig();\r\n }\r\n\r\n // 初始化蓝牙模块\r\n wx.openBluetoothAdapter({\r\n success: () => {\r\n apiLogger.info('微信蓝牙适配器已打开');\r\n onBluetoothDeviceFound(options);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('蓝牙适配器打开失败', error);\r\n options.fail?.(error);\r\n }\r\n });\r\n }, { context: 'openBluetoothAdapterInWeixin' });\r\n}\r\n\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\nfunction bluetoothInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙功能', options);\r\n callApiInWebView('bluetooth', options, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 蓝牙调用成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 蓝牙调用失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }, { context: 'bluetoothInUniApp' });\r\n}\r\n\r\n/**\r\n * 在 UniApp(WebView)中开始搜索蓝牙设备\r\n * \r\n * @param {Object} options - 搜索参数\r\n */\r\nfunction startBluetoothDevicesDiscoveryInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙设备搜索功能', options);\r\n callApiInWebView('bluetoothDevicesDiscovery', {\r\n action: 'startBluetoothDevicesDiscovery',\r\n params: {\r\n services: options.services || [],\r\n allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n console.log('[Bluetooth] 设备开启搜索成功:', res);\r\n apiLogger.info('UniApp 蓝牙设备开启搜索成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 设备开启搜索失败:', error);\r\n apiLogger.error('UniApp 蓝牙设备开启搜索失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }, { context: 'startBluetoothDevicesDiscoveryInUniApp' });\r\n}\r\n/**\r\n * 在 UniApp(WebView)中开始搜索蓝牙设备\r\n * \r\n * @param {Object} options - 搜索参数\r\n */\r\n// function onBluetoothDeviceFoundInUniApp(options) {\r\n// return ErrorHandler.safeExecute(() => {\r\n// apiLogger.debug('通过 WebView 桥接调用蓝牙设备搜索功能', options);\r\n// callApiInWebView('onBluetoothDeviceFound', {\r\n// action: 'onBluetoothDeviceFound',\r\n// isPersistent: true, // ✅ 添加此字段,告诉桥接层不要清理\r\n// params: {\r\n// services: options.services || [],\r\n// allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n// }\r\n// }, {\r\n// success: (res) => {\r\n// console.log('[Bluetooth] 设备搜索成功:', res);\r\n// apiLogger.info('UniApp 蓝牙设备搜索成功', res);\r\n// options.success?.(res);\r\n// },\r\n// fail: (error) => {\r\n// console.error('[Bluetooth] 设备搜索失败:', error);\r\n// apiLogger.error('UniApp 蓝牙设备搜索失败', error);\r\n// options.fail?.(error);\r\n// },\r\n// complete: options.complete\r\n// });\r\n// }, { context: 'onBluetoothDeviceFoundInUniApp' });\r\n// }\r\n\r\nconst bluetoothDeviceFoundCallbacks = new Set();\r\n\r\nfunction onBluetoothDeviceFoundInUniApp(callback, options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // ✅ 保存用户的真实回调\r\n bluetoothDeviceFoundCallbacks.add(callback);\r\n\r\n // ✅ 只有第一次注册时,启动监听\r\n if (bluetoothDeviceFoundCallbacks.size === 1) {\r\n callApiInWebView('onBluetoothDeviceFound', {\r\n action: 'onBluetoothDeviceFound',\r\n isPersistent: true,\r\n params: {\r\n services: options.services || [],\r\n allowDuplicatesKey: options.allowDuplicatesKey ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n bluetoothDeviceFoundCallbacks.forEach(cb => {\r\n if (typeof cb === 'function') {\r\n ErrorHandler.safeExecute(() => cb(res), { context: 'BluetoothDeviceCallback' });\r\n } else {\r\n console.warn('[BluetoothDeviceCallback] 不是函数:', cb);\r\n }\r\n });\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 搜索失败:', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n }\r\n\r\n // ✅ 返回取消订阅函数\r\n return () => bluetoothDeviceFoundCallbacks.delete(callback);\r\n }, { context: 'qsh_onBluetoothDeviceFound' });\r\n}\r\n\r\n\r\n/**\r\n * 在 UniApp/WebView 环境中创建蓝牙连接\r\n * @param {Object} options - 参数对象\r\n * @param {string} options.deviceId - 蓝牙设备 ID(必填)\r\n * @param {boolean} [options.autoConnect=false] - 是否自动重连\r\n * @param {Function} [options.success] - 连接成功回调\r\n * @param {Function} [options.fail] - 连接失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nfunction createBLEConnectionInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用蓝牙连接功能', options);\r\n\r\n callApiInWebView('bluetoothConnection', {\r\n action: 'createBLEConnection',\r\n params: {\r\n deviceId: options.deviceId,\r\n name: options.name,\r\n autoConnect: options.autoConnect ?? false\r\n }\r\n }, {\r\n success: (res) => {\r\n console.log('[Bluetooth] 蓝牙连接成功:', res);\r\n apiLogger.info('UniApp 蓝牙连接成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n console.error('[Bluetooth] 蓝牙连接失败:', error);\r\n apiLogger.error('UniApp 蓝牙连接失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n\r\n }, { context: 'createBLEConnectionInUniApp' });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 初始化并搜索蓝牙设备\r\n * \r\n * @param {Object} [options] - 蓝牙参数\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报\r\n * @param {string[]} [options.services=[]] - 指定服务UUID列表\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nexport function openBluetoothAdapter(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n const normalizedOptions = normalizeOptions(options);\r\n apiLogger.info('开始蓝牙操作', {\r\n platform: environment.type,\r\n services: normalizedOptions.services,\r\n allowDuplicatesKey: normalizedOptions.allowDuplicatesKey\r\n });\r\n if (isWeixinMiniProgram()) {\r\n openBluetoothAdapterInWeixin(normalizedOptions);\r\n } else {\r\n bluetoothInUniApp(normalizedOptions);\r\n }\r\n }, { context: 'openBluetoothAdapter', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的蓝牙调用\r\n * \r\n * @param {Object} [options] - 参数(不包含回调函数)\r\n * @returns {Promise} 蓝牙调用结果 Promise\r\n */\r\nexport function openBluetoothAdapterAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openBluetoothAdapter({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n/**\r\n * 开始搜索蓝牙设备\r\n *\r\n * @param {Object} [options] - 蓝牙搜索参数\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报同一设备\r\n * @param {string[]} [options.services=[]] - 指定服务 UUID 列表\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n */\r\nexport function startBluetoothDevicesDiscovery(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n\r\n // 3️⃣ 记录日志\r\n apiLogger.info('开始搜索蓝牙设备', {\r\n platform: environment.type,\r\n services: normalizedOptions.services,\r\n allowDuplicatesKey: normalizedOptions.allowDuplicatesKey\r\n });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n startBluetoothDevicesDiscoveryInWeixin(normalizedOptions);\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n startBluetoothDevicesDiscoveryInUniApp(normalizedOptions);\r\n }\r\n }, { context: 'startBluetoothDevicesDiscovery', options });\r\n}\r\n/**\r\n * Promise 版本的蓝牙调用\r\n * \r\n * @param {Object} [options] - 参数(不包含回调函数)\r\n * @returns {Promise} 蓝牙调用结果 Promise\r\n */\r\nexport function startBluetoothDevicesDiscoveryAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n startBluetoothDevicesDiscovery({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 监听蓝牙设备发现事件\r\n *\r\n * @param {Object} [options] - 蓝牙监听参数\r\n * @param {Function} [options.success] - 每次发现设备时回调,参数为设备数组\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调(出错或注册成功均调用)\r\n */\r\nexport function onBluetoothDeviceFound(callback, options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n\r\n // 3️⃣ 日志记录\r\n apiLogger.info('注册蓝牙设备发现监听', { platform: environment.type });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n onBluetoothDeviceFoundInWeixin(normalizedOptions);\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n onBluetoothDeviceFoundInUniApp(callback, normalizedOptions);\r\n }\r\n }, { context: 'onBluetoothDeviceFound', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的蓝牙设备发现监听\r\n * 第一次触发 resolve,后续通过 success 回调继续处理\r\n *\r\n * @returns {Promise<Array>} 首次发现的设备列表\r\n */\r\nexport function onBluetoothDeviceFoundAsync() {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n onBluetoothDeviceFound({\r\n success: resolve,\r\n fail: reject\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n/**\r\n * 创建蓝牙连接\r\n * @param {Object} options - 参数对象\r\n * @param {string} options.deviceId - 蓝牙设备 ID(必填)\r\n * @param {boolean} [options.autoConnect=false] - 是否自动重连\r\n * @param {Function} [options.success] - 连接成功回调\r\n * @param {Function} [options.fail] - 连接失败回调\r\n * @param {Function} [options.complete] - 完成回调(无论成功失败都会调用)\r\n */\r\nexport function createBLEConnection(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 1️⃣ 环境检测\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持蓝牙功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持蓝牙连接', { platform: environment.type });\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 2️⃣ 参数标准化\r\n const normalizedOptions = normalizeOptions(options);\r\n const { name, deviceId, autoConnect = false } = normalizedOptions;\r\n\r\n if (!deviceId) {\r\n const error = { errMsg: '缺少 deviceId 参数', code: 'INVALID_PARAMS' };\r\n options.fail?.(error);\r\n options.complete?.(error);\r\n return;\r\n }\r\n\r\n // 3️⃣ 日志记录\r\n apiLogger.info('创建蓝牙连接', { deviceId, autoConnect, platform: environment.type });\r\n\r\n // 4️⃣ 平台分支处理\r\n if (isWeixinMiniProgram()) {\r\n // 微信小程序环境\r\n uni.createBLEConnection({\r\n deviceId,\r\n autoConnect,\r\n success: options.success,\r\n fail: options.fail,\r\n complete: options.complete\r\n });\r\n } else {\r\n // 其他(如 UniApp WebView 或 App)\r\n // 假设你有一个封装的原生调用方法\r\n createBLEConnectionInUniApp(normalizedOptions);\r\n }\r\n\r\n }, { context: 'createBLEConnection', options });\r\n}\r\n\r\n/**\r\n * Promise 版本的创建蓝牙连接\r\n * 第一次成功连接触发 resolve,后续通过 success 回调继续处理\r\n *\r\n * @param {Object} options - 参数\r\n * @param {string} options.deviceId - 蓝牙设备 id\r\n * @param {boolean} [options.autoConnect=false] - 是否自动连接\r\n * @returns {Promise<Object>} 首次连接成功的设备信息\r\n */\r\nexport function createBLEConnectionAsync(options) {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n createBLEConnection({\r\n ...options,\r\n success: (res) => {\r\n resolve(res); // 首次成功连接触发 resolve\r\n // 后续逻辑可通过 options.success 或其他回调处理\r\n if (typeof options.success === 'function') {\r\n options.success(res);\r\n }\r\n },\r\n fail: (err) => {\r\n reject(err);\r\n if (typeof options.fail === 'function') {\r\n options.fail(err);\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * 获取蓝牙功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n */\r\nexport function getBluetoothCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: isWeixinMiniProgram() ? 'weixin' : 'webview',\r\n features: {\r\n discovery: true,\r\n connect: true,\r\n readWrite: true,\r\n notify: true,\r\n asyncSupport: true\r\n }\r\n };\r\n}\r\n","/**\r\n * 打印PDF API 模块\r\n * 统一封装微信和UniApp的打印PDF功能\r\n */\r\n\r\nimport { environment } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\nimport { callApiInWebView } from '../core/webview-bridge.js';\r\n\r\n// ==================== 常量定义 ====================\r\n\r\n/**\r\n * 默认选项\r\n */\r\nconst DEFAULT_OPTIONS = {\r\n // TODO: 添加更多默认配置\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n/**\r\n * 标准化选项参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // TODO: 参数验证和标准化\r\n \r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持打印\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n const supportedEnvs = ['webview','UniApp', 'plus', 'nvue', 'uvue'];\r\n return supportedEnvs.includes(environment.type);\r\n}\r\n\r\n// ==================== UniApp 环境实现 ====================\r\n\r\n/**\r\n * UniApp 环境下的打印PDF(通过 WebView 桥接)\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction printPdfInUniApp(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n apiLogger.debug('通过 WebView 桥接调用打印PDF', options);\r\n \r\n // 通过桥接层调用,禁用超时自动清理\r\n callApiInWebView('printPdf', {\r\n ...options,\r\n isPersistent: true // 强制禁用超时自动清理\r\n }, {\r\n success: (res) => {\r\n apiLogger.info('UniApp 打印PDF成功', res);\r\n options.success?.(res);\r\n },\r\n fail: (error) => {\r\n apiLogger.error('UniApp 打印PDF失败', error);\r\n options.fail?.(error);\r\n },\r\n complete: options.complete\r\n });\r\n \r\n }, { \r\n context: 'printPdfInUniApp',\r\n platform: 'uniapp'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 打印PDF(统一入口)\r\n * \r\n * @param {Object} [options] - 打印PDF参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * \r\n * @example\r\n * qsh.printPdf({\r\n * success: (res) => console.log('打印PDF成功'),\r\n * fail: (error) => console.error('打印PDF失败:', error)\r\n * });\r\n */\r\nexport function printPdf(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n const error = {\r\n errMsg: `当前环境 (${environment.type}) 不支持打印PDF功能`,\r\n code: 'PLATFORM_NOT_SUPPORTED'\r\n };\r\n apiLogger.error('平台不支持打印PDF', { platform: environment.type });\r\n options.fail?.(error);\r\n return;\r\n }\r\n\r\n // 标准化参数\r\n const normalizedOptions = normalizeOptions(options);\r\n \r\n apiLogger.info('开始打印PDF', { platform: environment.type });\r\n\r\n // 只支持 APP 端,通过 WebView 桥接调用\r\n printPdfInUniApp(normalizedOptions);\r\n \r\n }, { \r\n context: 'printPdf',\r\n options \r\n });\r\n}\r\n\r\n/**\r\n * Promise版本的打印PDF\r\n * \r\n * @param {Object} [options] - 打印PDF参数(不包含回调函数)\r\n * @returns {Promise} 打印PDF结果的Promise\r\n * \r\n * @example\r\n * try {\r\n * await qsh.printPdfAsync();\r\n * console.log('打印PDF成功');\r\n * } catch (error) {\r\n * console.error('打印PDF失败:', error);\r\n * }\r\n */\r\nexport function printPdfAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n printPdf({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 获取打印PDF功能能力信息\r\n * \r\n * @returns {Object} 能力信息\r\n * \r\n * @example\r\n * const capabilities = qsh.getPrintCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n */\r\nexport function getPrintCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: 'uniapp',\r\n features: {\r\n asyncSupport: true\r\n }\r\n };\r\n}\r\n","/**\r\n * 人脸识别 API 模块\r\n * 仅支持微信小程序环境\r\n */\r\n\r\nimport { environment, isWeixinMiniProgram } from '../core/environment.js';\r\nimport { ErrorHandler } from '../core/error-handler.js';\r\nimport { apiLogger } from '../core/logger.js';\r\n\r\n// ==================== 工具函数 ====================\r\n\r\nconst FACE_PAGE_PATH = '/pages/face/index';\r\n\r\n/**\r\n * 标准化人脸识别参数\r\n * @param {Object} options - 用户传入的选项\r\n * @returns {Object} 标准化后的选项\r\n * @private\r\n */\r\nfunction normalizeOptions(options = {}) {\r\n const normalized = { ...options };\r\n\r\n // 验证 name\r\n if (!normalized.name || typeof normalized.name !== 'string' || !normalized.name.trim()) {\r\n throw {\r\n errMsg: '缺少必需参数:name(姓名)',\r\n code: 'PARAM_MISSING'\r\n };\r\n }\r\n normalized.name = normalized.name.trim();\r\n\r\n // 验证 idCardNumber\r\n if (!normalized.idCardNumber || typeof normalized.idCardNumber !== 'string' || !normalized.idCardNumber.trim()) {\r\n throw {\r\n errMsg: '缺少必需参数:idCardNumber(身份证号)',\r\n code: 'PARAM_MISSING'\r\n };\r\n }\r\n normalized.idCardNumber = normalized.idCardNumber.trim();\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * 检查是否支持人脸识别(仅微信小程序环境)\r\n * @returns {boolean}\r\n */\r\nfunction isSupported() {\r\n return isWeixinMiniProgram();\r\n}\r\n\r\nfunction isMiniProgramNavigateAvailable() {\r\n return (\r\n typeof window !== 'undefined' &&\r\n window.wx &&\r\n window.wx.miniProgram &&\r\n typeof window.wx.miniProgram.navigateTo === 'function'\r\n );\r\n}\r\n\r\nfunction buildFacePageUrl(options) {\r\n const params = {\r\n ...options,\r\n title: document.title || '',\r\n url: window.location.href || ''\r\n };\r\n\r\n const query = Object.entries(params)\r\n .filter(([, value]) => value !== undefined && value !== null && value !== '')\r\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\r\n .join('&');\r\n\r\n return query ? `${FACE_PAGE_PATH}?${query}` : FACE_PAGE_PATH;\r\n}\r\n\r\n// ==================== 微信环境实现 ====================\r\n\r\n/**\r\n * 微信环境下的人脸识别\r\n * @param {Object} options - 选项\r\n * @private\r\n */\r\nfunction faceVerifyInWeixin(options) {\r\n return ErrorHandler.safeExecute(() => {\r\n if (!isMiniProgramNavigateAvailable()) {\r\n apiLogger.error('微信小程序导航API不可用');\r\n return;\r\n }\r\n\r\n const targetUrl = buildFacePageUrl(options);\r\n\r\n apiLogger.debug('跳转宿主人脸识别页面', {\r\n name: options.name,\r\n targetUrl\r\n });\r\n\r\n window.wx.miniProgram.navigateTo({\r\n url: targetUrl,\r\n success: () => {\r\n apiLogger.info('已跳转到宿主人脸识别页面', { targetUrl });\r\n },\r\n fail: (error) => {\r\n apiLogger.error('跳转宿主人脸识别页面失败', error);\r\n }\r\n });\r\n\r\n }, {\r\n context: 'faceVerifyInWeixin',\r\n platform: 'weixin'\r\n });\r\n}\r\n\r\n// ==================== 公共 API ====================\r\n\r\n/**\r\n * 人脸识别(统一入口)\r\n * 只发送请求,不返回任何结果给调用者\r\n *\r\n * @param {Object} options - 人脸识别参数\r\n * @param {string} options.name - 姓名(必填)\r\n * @param {string} options.idCardNumber - 身份证号(必填)\r\n * @returns {void}\r\n *\r\n * @example\r\n * qsh.faceVerify({\r\n * name: '张三',\r\n * idCardNumber: '110101199001011234'\r\n * });\r\n */\r\nexport function faceVerify(options = {}) {\r\n return ErrorHandler.safeExecute(() => {\r\n // 检查环境支持\r\n if (!isSupported()) {\r\n apiLogger.error('平台不支持人脸识别', { platform: environment.type });\r\n return;\r\n }\r\n\r\n // 标准化参数(含参数校验)\r\n let normalizedOptions;\r\n try {\r\n normalizedOptions = normalizeOptions(options);\r\n } catch (error) {\r\n apiLogger.error('人脸识别参数校验失败', error);\r\n return;\r\n }\r\n\r\n apiLogger.info('开始人脸识别', {\r\n platform: environment.type,\r\n name: normalizedOptions.name,\r\n pagePath: FACE_PAGE_PATH\r\n });\r\n\r\n // 调用微信实现\r\n faceVerifyInWeixin(normalizedOptions);\r\n\r\n }, {\r\n context: 'faceVerify',\r\n options\r\n });\r\n}\r\n\r\n/**\r\n * 获取人脸识别功能能力信息\r\n *\r\n * @returns {Object} 能力信息\r\n *\r\n * @example\r\n * const capabilities = qsh.getFaceCapabilities();\r\n * console.log('是否支持:', capabilities.supported);\r\n * console.log('当前环境:', capabilities.environment);\r\n */\r\nexport function getFaceCapabilities() {\r\n return {\r\n supported: isSupported(),\r\n environment: environment.type,\r\n implementation: 'weixin',\r\n features: {\r\n asyncSupport: true,\r\n hostPageNavigation: true\r\n }\r\n };\r\n}\r\n","/*\r\n * @Description: \r\n * @Author: TK\r\n * @Date: 2025-08-06 09:54:28\r\n * @LastEditors: sqian0625 460635145@qq.com\r\n * @LastEditTime: 2025-10-17 16:03:18\r\n */\r\n/**\r\n * UniApp WebView SDK\r\n * 支持微信小程序和 APP 端的 WebView 通信\r\n */\r\n\r\n// 导入核心模块\r\nimport { waitForBridge, initBridge, isBridgeReady } from './core/bridge.js';\r\nimport { getEnvironmentInfo } from './core/environment.js';\r\nimport { \r\n loadWeixinJSSDKIfNeeded, \r\n configureWeixin,\r\n waitForWeixinConfig,\r\n isWeixinConfigReady,\r\n getWeixinConfigState,\r\n getWeixinConfigManager,\r\n retryWeixinConfig\r\n} from './core/weixin-loader.js';\r\nimport stateManager, { waitForReady, isReady, getState } from './core/state-manager.js';\r\nimport Logger from './core/logger.js';\r\nimport { ErrorHandler } from './core/error-handler.js';\r\nimport pluginManager from './core/plugin-manager.js';\r\nimport interceptorChain, { loggingInterceptor, performanceInterceptor, createRetryInterceptor, createValidationInterceptor } from './core/interceptor.js';\r\nimport stateStore from './core/state-store.js';\r\nimport { ErrorCodes, ErrorMessages, ErrorCategory } from './core/error-codes.js';\r\nimport { errorNormalizerInterceptor, normalizeError, createError, isStandardError } from './core/error-normalizer.js';\r\nimport { runInitPipeline } from './core/init-pipeline.js';\r\n\r\n// 惰性获取环境信息(缓存),避免在 SSR 场景访问不存在的全局对象\r\nconst environment = getEnvironmentInfo();\r\n\r\nfunction shouldWaitForWeixinConfigInReady() {\r\n if (typeof window === 'undefined') {\r\n return false;\r\n }\r\n\r\n const runtimeEnvironment = getEnvironmentInfo(true);\r\n if (!runtimeEnvironment.isWeixinMiniProgram) {\r\n return false;\r\n }\r\n\r\n const runtimeConfig = getWeixinConfigManager().getRuntimeConfig();\r\n return typeof runtimeConfig.clientId === 'string' && runtimeConfig.clientId.length > 0;\r\n}\r\n\r\nasync function readySDK() {\r\n await waitForBridge();\r\n\r\n if (!shouldWaitForWeixinConfigInReady()) {\r\n return;\r\n }\r\n\r\n await waitForWeixinConfig();\r\n}\r\n\r\n// 导入 API 模块(以 raw 别名保留原始实现)\r\nimport {\r\n navigateTo as rawNavigateTo,\r\n navigateBack as rawNavigateBack,\r\n switchTab as rawSwitchTab,\r\n reLaunch as rawReLaunch,\r\n redirectTo as rawRedirectTo\r\n} from './api/navigation.js';\r\n\r\nimport {\r\n postMessage as rawPostMessage,\r\n getEnv as rawGetEnv\r\n} from './api/message.js';\r\n\r\nimport {\r\n chooseImage as rawChooseImage,\r\n chooseImageAsync as rawChooseImageAsync,\r\n getImageCapabilities,\r\n ImageSourceTypes,\r\n ImageSizeTypes\r\n} from './api/image.js';\r\n\r\nimport {\r\n scanCode as rawScanCode,\r\n scanCodeAsync as rawScanCodeAsync,\r\n getScanCapabilities,\r\n ScanTypes\r\n} from './api/scan.js';\r\n\r\nimport {\r\n getLocation as rawGetLocation,\r\n getLocationAsync as rawGetLocationAsync,\r\n openLocation as rawOpenLocation,\r\n openLocationAsync as rawOpenLocationAsync,\r\n getLocationCapabilities,\r\n CoordinateTypes,\r\n onLocationChange as rawOnLocationChange,\r\n offLocationChange as rawOffLocationChange,\r\n onLocationChangeError as rawOnLocationChangeError,\r\n offLocationChangeError as rawOffLocationChangeError,\r\n startLocationUpdate as rawStartLocationUpdate,\r\n stopLocationUpdate as rawStopLocationUpdate\r\n} from './api/location.js';\r\n\r\nimport {\r\n chooseLocation as rawChooseLocation,\r\n chooseLocationAsync as rawChooseLocationAsync,\r\n getChooseLocationCapabilities\r\n} from './api/choose.js';\r\n\r\n\r\nimport { toShare as rawToShare, toShareAsync as rawToShareAsync , toShareCallBack as rawToShareCallBack, toShareCallBackAsync as rawToShareCallBackAsync } from \"./api/share.js\";\r\n\r\nimport {\r\n openBluetoothAdapter as rawOpenBluetooth,\r\n openBluetoothAdapterAsync as rawOpenBluetoothAsync,\r\n startBluetoothDevicesDiscovery as rawBluetoothDevicesDiscovery,\r\n startBluetoothDevicesDiscoveryAsync as rawBluetoothDevicesDiscoveryAsync,\r\n onBluetoothDeviceFound as rawOnBluetoothDeviceFound,\r\n onBluetoothDeviceFoundAsync as rawOnBluetoothDeviceFoundAsync,\r\n createBLEConnection as rawCreateBLEConnection,\r\n createBLEConnectionAsync as rawCreateBLEConnectionAsync,\r\n getBluetoothCapabilities,\r\n BluetoothStates\r\n} from './api/bluetooth.js';\r\n\r\nimport {\r\n printPdf as rawPrintPdf,\r\n printPdfAsync as rawPrintPdfAsync,\r\n getPrintCapabilities\r\n} from './api/print.js';\r\n\r\nimport {\r\n faceVerify as rawFaceVerify,\r\n getFaceCapabilities\r\n} from './api/face.js';\r\n// 平台特定 API 不在此处直接导入,按需在各模块内处理\r\n\r\n// 注册内置错误标准化拦截器(最高优先级)\r\ninterceptorChain.useResponse(errorNormalizerInterceptor.response, { priority: 1000 });\r\n\r\n// 自动初始化逻辑 - 确保在 DOM 准备好后初始化\r\nlet autoInitStarted = false;\r\n\r\nfunction startAutoInit() {\r\n if (autoInitStarted) return;\r\n autoInitStarted = true;\r\n\r\n const initTasks = [\r\n { name: 'load-weixin-sdk', run: loadWeixinJSSDKIfNeeded, timeoutMs: 8000 },\r\n { name: 'init-bridge', run: initBridge, timeoutMs: 8000 }\r\n ];\r\n\r\n runInitPipeline(initTasks, {\r\n onError: (error, step) => {\r\n console.error(`[QSH-SDK] 初始化失败(${step?.name || 'unknown'}):`, error);\r\n }\r\n });\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n if (document.readyState === 'complete' || document.readyState === 'interactive') {\r\n setTimeout(startAutoInit, 0);\r\n } else {\r\n document.addEventListener('DOMContentLoaded', startAutoInit);\r\n }\r\n}\r\n\r\n// 封装:自动等待 Bridge 就绪后再调用(可等待、兼容回调)\r\nfunction ensureReadyInvoke(apiFn, { apiName } = {}) {\r\n return function(options = {}, ...rest) {\r\n const hasCallbacks = options && typeof options === 'object' && (\r\n typeof options.success === 'function' ||\r\n typeof options.fail === 'function' ||\r\n typeof options.complete === 'function'\r\n );\r\n const normalizedOptions = options && typeof options === 'object' ? options : {};\r\n\r\n const execute = () => {\r\n if (hasCallbacks) {\r\n return apiFn(normalizedOptions, ...rest);\r\n }\r\n\r\n // Promise 化:当未提供回调时,返回一个可等待的 Promise\r\n return new Promise((resolve, reject) => {\r\n const wrapped = {\r\n ...normalizedOptions,\r\n success: (res) => {\r\n if (typeof normalizedOptions.success === 'function') {\r\n normalizedOptions.success(res);\r\n }\r\n resolve(res);\r\n },\r\n fail: (err) => {\r\n if (typeof normalizedOptions.fail === 'function') {\r\n normalizedOptions.fail(err);\r\n }\r\n reject(err);\r\n },\r\n complete: normalizedOptions.complete\r\n };\r\n apiFn(wrapped, ...rest);\r\n });\r\n };\r\n\r\n const readyPromise = (typeof window === 'undefined') ? Promise.resolve() : waitForReady();\r\n\r\n return readyPromise\r\n .then(() => execute())\r\n .catch(error => {\r\n console.error(`[QSH-SDK] ${apiName || 'API'} call failed:`, error);\r\n throw error;\r\n });\r\n };\r\n}\r\n\r\nfunction normalizeCallbackOptions(input) {\r\n if (typeof input === 'function') {\r\n return { success: input };\r\n }\r\n if (input && typeof input === 'object') {\r\n return input;\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * 导航到新页面\r\n * @param {Object} options - 导航参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateTo({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nconst navigateTo = ensureReadyInvoke(rawNavigateTo);\r\n/**\r\n * 返回上一页\r\n * @param {Object} [options] - 返回参数\r\n * @param {number} [options.delta=1] - 返回的页面层级数\r\n * @returns {void}\r\n * @example\r\n * qsh.navigateBack({ delta: 1 })\r\n * @since 2.0.0\r\n */\r\nconst navigateBack = ensureReadyInvoke(rawNavigateBack);\r\n/**\r\n * 切换至 Tab 页面\r\n * @param {Object} options - 切换参数\r\n * @param {string} options.url - 目标 Tab 页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.switchTab({ url: '/pages/tabbar/home' })\r\n * @since 2.0.0\r\n */\r\nconst switchTab = ensureReadyInvoke(rawSwitchTab);\r\n/**\r\n * 关闭所有页面并打开到应用内某页面\r\n * @param {Object} options - 打开参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.reLaunch({ url: '/pages/home/index' })\r\n * @since 2.0.0\r\n */\r\nconst reLaunch = ensureReadyInvoke(rawReLaunch);\r\n/**\r\n * 关闭当前页面并跳转到应用内某页面\r\n * @param {Object} options - 跳转参数\r\n * @param {string} options.url - 目标页面路径\r\n * @returns {void}\r\n * @example\r\n * qsh.redirectTo({ url: '/pages/detail/index' })\r\n * @since 2.0.0\r\n */\r\nconst redirectTo = ensureReadyInvoke(rawRedirectTo);\r\n/**\r\n * 发送消息至原生容器\r\n * @param {Object} [options] - 消息参数\r\n * @param {any} [options.data] - 需要透传的数据对象\r\n * @returns {void}\r\n * @example\r\n * qsh.postMessage({ data: { foo: 'bar' } })\r\n * @since 2.0.0\r\n */\r\nconst postMessage = ensureReadyInvoke(rawPostMessage);\r\n\r\n/**\r\n * 获取当前运行环境信息(回调形式)\r\n * 注意:兼容旧版回调签名,内部会在 Bridge 就绪后再调用。\r\n * @param {Function} callback - 回调函数,入参为环境信息对象\r\n * @returns {void}\r\n * @example\r\n * qsh.getEnv((info) => { console.log(info.miniprogram) })\r\n * @since 2.0.0\r\n */\r\nfunction getEnv(callback) {\r\n const exec = () => rawGetEnv(callback);\r\n const readyPromise = (typeof window === 'undefined') ? Promise.resolve() : waitForReady();\r\n return readyPromise.then(() => exec());\r\n}\r\n\r\n/**\r\n * 选择图片\r\n * 统一封装微信和UniApp的图片选择功能,自动根据环境选择合适的实现\r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.count=9] - 最多选择的图片数量\r\n * @param {string[]} [options.sizeType] - 图片质量类型 ['original', 'compressed']\r\n * @param {string[]} [options.sourceType] - 图片来源类型 ['album', 'camera']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * @example\r\n * qsh.chooseImage({\r\n * count: 1,\r\n * success: (res) => console.log('选择的图片:', res)\r\n * })\r\n * @since 2.0.0\r\n */\r\nconst chooseImage = ensureReadyInvoke(rawChooseImage);\r\n\r\n/**\r\n * 选择图片(Promise版本)\r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * @example\r\n * const result = await qsh.chooseImageAsync({ count: 1 })\r\n * @since 2.0.0\r\n */\r\nfunction chooseImageAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseImage({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 打印\r\n * @param {Object} [options] - 打印参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @param {Function} [options.complete] - 完成回调\r\n * @returns {void}\r\n * @example\r\n * qsh.printPdf({\r\n * success: (res) => console.log('打印PDF成功')\r\n * })\r\n * @since 2.0.0\r\n */\r\nconst printPdf = ensureReadyInvoke(rawPrintPdf);\r\n\r\n/**\r\n * 打印PDF(Promise版本)\r\n * @param {Object} [options] - 打印PDF参数(不包含回调函数)\r\n * @returns {Promise} 打印PDF结果的Promise\r\n * @example\r\n * await qsh.printPdfAsync()\r\n * @since 2.0.0\r\n */\r\nfunction printPdfAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n printPdf({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 扫码\r\n * @param {Object} [options] - 扫码参数\r\n * @param {boolean} [options.onlyFromCamera=true] - 是否只能从相机扫码\r\n * @param {string[]} [options.scanType] - 扫码类型 ['qrCode', 'barCode']\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.scanCode({\r\n * success: (res) => console.log('扫码结果:', res.result)\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst scanCode = ensureReadyInvoke(rawScanCode);\r\n\r\n/**\r\n * 人脸识别(仅支持微信小程序环境)\r\n * 通过 wx.miniProgram.navigateTo 跳转宿主 /pages/face/index,不返回任何结果给调用者\r\n * @param {Object} options - 人脸识别参数\r\n * @param {string} options.name - 姓名(必填)\r\n * @param {string} options.idCardNumber - 身份证号(必填)\r\n * @returns {void}\r\n * @example\r\n * qsh.faceVerify({\r\n * name: '张三',\r\n * idCardNumber: '110101199001011234'\r\n * })\r\n */\r\nconst faceVerify = ensureReadyInvoke(rawFaceVerify);\r\n\r\n/**\r\n * 扫码(Promise版本)\r\n * @param {Object} [options] - 扫码参数(不包含回调函数)\r\n * @returns {Promise} 扫码结果的Promise\r\n * @example\r\n * const result = await qsh.scanCodeAsync({ scanType: ['qrCode'] })\r\n * @since 2.1.0\r\n */\r\nfunction scanCodeAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n scanCode({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n// /////////////////////////////////\r\n/**\r\n * \r\n * \r\n * \r\n */\r\n\r\nconst toShare = ensureReadyInvoke(rawToShare);\r\nconst toShareAsync = ensureReadyInvoke(rawToShareAsync);\r\nconst toShareCallBack = ensureReadyInvoke(rawToShareCallBack);\r\nconst toShareCallBackAsync = ensureReadyInvoke(rawToShareCallBackAsync);\r\n\r\n// //////////////////////////////////////////////////////////\r\n\r\n/**\r\n * 获取当前位置\r\n * @param {Object} [options] - 定位参数\r\n * @param {string} [options.type='wgs84'] - 坐标类型\r\n * @param {boolean} [options.altitude=false] - 是否返回高度\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.getLocation({\r\n * type: 'gcj02',\r\n * success: (res) => console.log(res.latitude, res.longitude)\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst getLocationAPI = ensureReadyInvoke(rawGetLocation);\r\n\r\n/**\r\n * 获取位置(Promise版本)\r\n * @param {Object} [options] - 定位参数(不包含回调函数)\r\n * @returns {Promise} 定位结果的Promise\r\n * @example\r\n * const location = await qsh.getLocationAsync({ type: 'gcj02' })\r\n * @since 2.1.0\r\n */\r\nfunction getLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n getLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 查看位置\r\n * @param {Object} options - 位置参数\r\n * @param {number} options.latitude - 纬度(必填)\r\n * @param {number} options.longitude - 经度(必填)\r\n * @param {string} [options.name] - 位置名称\r\n * @param {string} [options.address] - 详细地址\r\n * @param {number} [options.scale=18] - 缩放级别\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.openLocation({\r\n * latitude: 39.908823,\r\n * longitude: 116.397470,\r\n * name: '天安门'\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst openLocationAPI = ensureReadyInvoke(rawOpenLocation);\r\n\r\n/**\r\n * 查看位置(Promise版本)\r\n * @param {Object} options - 位置参数(不包含回调函数)\r\n * @returns {Promise} 操作结果的Promise\r\n * @example\r\n * await qsh.openLocationAsync({ latitude: 39.908823, longitude: 116.397470 })\r\n * @since 2.1.0\r\n */\r\nfunction openLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 选择位置\r\n * @param {Object} [options] - 选择参数\r\n * @param {number} [options.latitude] - 目标纬度(UniApp支持,微信不支持)\r\n * @param {number} [options.longitude] - 目标经度(UniApp支持,微信不支持)\r\n * @param {string} [options.keyword] - 搜索关键字(UniApp支持,微信不支持)\r\n * @param {string} [options.category] - POI分类(UniApp支持,微信不支持)\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.chooseLocation({\r\n * success: (res) => {\r\n * console.log('位置名称:', res.name)\r\n * console.log('详细地址:', res.address)\r\n * }\r\n * })\r\n * @since 2.1.0\r\n */\r\nconst chooseLocationAPI = ensureReadyInvoke(rawChooseLocation);\r\n\r\n/**\r\n * 选择位置(Promise版本)\r\n * @param {Object} [options] - 选择参数(不包含回调函数)\r\n * @returns {Promise} 选择结果的Promise\r\n * @example\r\n * const location = await qsh.chooseLocationAsync({ keyword: '餐厅' })\r\n * @since 2.1.0\r\n */\r\nfunction chooseLocationAsyncAPI(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n chooseLocationAPI({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 蓝牙\r\n * @param {Object} [options] - 蓝牙参数\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.openBluetoothAdapter({\r\n * success: (res) => console.log('蓝牙设备:', res.devices)\r\n * })\r\n */\r\nconst openBluetoothAdapter = ensureReadyInvoke(rawOpenBluetooth);\r\n\r\n/**\r\n * 蓝牙(Promise版本)\r\n * @param {Object} [options] - 参数\r\n * @returns {Promise} 蓝牙结果 Promise\r\n */\r\nfunction openBluetoothAdapterAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n openBluetoothAdapter({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * 开始搜索蓝牙设备\r\n * @param {Object} [options] - 蓝牙搜索参数\r\n * @param {Array<string>} [options.services] - 蓝牙设备主服务 UUID 列表\r\n * @param {boolean} [options.allowDuplicatesKey=false] - 是否允许重复上报同一设备\r\n * @param {Function} [options.success] - 成功回调\r\n * @param {Function} [options.fail] - 失败回调\r\n * @returns {void}\r\n * @example\r\n * qsh.startBluetoothDevicesDiscovery({\r\n * services: ['FFF0'],\r\n * allowDuplicatesKey: false,\r\n * success: (res) => console.log('开始搜索蓝牙设备', res)\r\n * })\r\n */\r\nconst startBluetoothDevicesDiscovery = ensureReadyInvoke(rawBluetoothDevicesDiscovery);\r\n\r\n/**\r\n * 开始搜索蓝牙设备(Promise版本)\r\n * @param {Object} [options] - 参数\r\n * @returns {Promise} 蓝牙搜索结果 Promise\r\n */\r\nfunction startBluetoothDevicesDiscoveryAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n startBluetoothDevicesDiscovery({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n/**\r\n * 监听蓝牙设备发现事件(Callback 方式)\r\n * @param {Function} callback - 回调函数,每次发现设备时触发,参数为设备列表\r\n * @returns {void}\r\n * @example\r\n * qsh.onBluetoothDeviceFound((devices) => {\r\n * console.log('发现蓝牙设备:', devices)\r\n * })\r\n */\r\nconst onBluetoothDeviceFound = ensureReadyInvoke(rawOnBluetoothDeviceFound)\r\n\r\n/**\r\n * 监听蓝牙设备发现事件(Promise版本)\r\n * 第一次发现设备时 resolve,后续可通过回调继续处理\r\n * @returns {Promise<Array>} 发现的设备列表\r\n * @example\r\n * const devices = await qsh.onBluetoothDeviceFoundAsync()\r\n * console.log('首次发现设备:', devices)\r\n */\r\nfunction onBluetoothDeviceFoundAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n onBluetoothDeviceFound({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n })\r\n}\r\n\r\nconst createBLEConnection = ensureReadyInvoke(rawCreateBLEConnection);\r\n\r\n/**\r\n * 创建蓝牙连接(Promise 版本)\r\n * @param {Object} options - 参数\r\n * @param {string} options.deviceId - 蓝牙设备 id\r\n * @param {boolean} [options.autoConnect=false] - 是否自动连接\r\n * @returns {Promise} 连接结果 Promise\r\n */\r\nfunction createBLEConnectionAsync(options = {}) {\r\n return new Promise((resolve, reject) => {\r\n createBLEConnection({\r\n ...options,\r\n success: resolve,\r\n fail: reject\r\n });\r\n });\r\n}\r\n// 创建 uni 对象\r\nconst uni = {\r\n // 导航 API\r\n navigateTo,\r\n navigateBack,\r\n switchTab,\r\n reLaunch,\r\n redirectTo,\r\n \r\n // 消息 API\r\n postMessage,\r\n getEnv,\r\n \r\n // 图片 API\r\n chooseImage,\r\n chooseImageAsync,\r\n \r\n // 扫码 API\r\n scanCode,\r\n scanCodeAsync,\r\n \r\n // 位置 API\r\n getLocation: getLocationAPI,\r\n getLocationAsync: getLocationAsyncAPI,\r\n openLocation: openLocationAPI,\r\n openLocationAsync: openLocationAsyncAPI,\r\n chooseLocation: chooseLocationAPI,\r\n chooseLocationAsync: chooseLocationAsyncAPI,\r\n \r\n // 位置监听 API(保留回调签名)\r\n onLocationChange: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOnLocationChange(options.success);\r\n }, { apiName: 'onLocationChange' })(normalizeCallbackOptions(callback)),\r\n offLocationChange: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOffLocationChange(options.success);\r\n }, { apiName: 'offLocationChange' })(normalizeCallbackOptions(callback)),\r\n onLocationChangeError: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOnLocationChangeError(options.success);\r\n }, { apiName: 'onLocationChangeError' })(normalizeCallbackOptions(callback)),\r\n offLocationChangeError: (callback) => ensureReadyInvoke((options = {}) => {\r\n return rawOffLocationChangeError(options.success);\r\n }, { apiName: 'offLocationChangeError' })(normalizeCallbackOptions(callback)),\r\n startLocationUpdate: ensureReadyInvoke(rawStartLocationUpdate, { apiName: 'startLocationUpdate' }),\r\n stopLocationUpdate: ensureReadyInvoke(rawStopLocationUpdate, { apiName: 'stopLocationUpdate' }),\r\n \r\n // 环境信息\r\n environment,\r\n \r\n /**\r\n * Wait for SDK readiness.\r\n * In Weixin mini-program web-view, if qsh.config({ clientId }) was called,\r\n * this also waits for wx.config to complete.\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.ready()\r\n * @since 2.0.0\r\n */\r\n ready: readySDK,\r\n \r\n /**\r\n * 手动初始化 JSBridge\r\n * 默认会在 DOM 就绪时自动初始化;如需更早或手动控制,可调用本方法。\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.init()\r\n * @since 2.0.0\r\n */\r\n init: initBridge,\r\n \r\n /**\r\n * 检查 JSBridge 是否就绪\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.isReady()) { console.log('ready') }\r\n * @since 2.0.0\r\n */\r\n isReady,\r\n \r\n /**\r\n * 获取当前 SDK 状态\r\n * @returns {string}\r\n * @example\r\n * console.log(qsh.getState()) // 'ready'\r\n * @since 2.0.0\r\n */\r\n getState,\r\n\r\n config: configureWeixin,\r\n\r\n // 微信配置 API\r\n weixin: {\r\n /**\r\n * 等待微信配置完成\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.weixin.waitForConfig()\r\n * @since 2.0.0\r\n */\r\n config: configureWeixin,\r\n waitForConfig: waitForWeixinConfig,\r\n \r\n /**\r\n * 检查微信配置是否完成\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.weixin.isConfigReady()) { wx.chooseImage({}) }\r\n * @since 2.0.0\r\n */\r\n isConfigReady: isWeixinConfigReady,\r\n \r\n /**\r\n * 获取微信配置状态\r\n * @returns {string}\r\n * @example\r\n * console.log(qsh.weixin.getConfigState()) // 'configured'\r\n * @since 2.0.0\r\n */\r\n getConfigState: getWeixinConfigState,\r\n \r\n /**\r\n * 手动重试微信配置\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.weixin.retryConfig()\r\n * @since 2.0.0\r\n */\r\n retryConfig: retryWeixinConfig\r\n },\r\n \r\n // WebView 对象(兼容旧版本)\r\n webView: null,\r\n\r\n // 图片相关常量\r\n ImageSourceTypes,\r\n ImageSizeTypes,\r\n \r\n /**\r\n * 获取图片功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getImageCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.0.0\r\n */\r\n getImageCapabilities,\r\n \r\n // 扫码相关常量\r\n ScanTypes,\r\n \r\n /**\r\n * 获取扫码功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getScanCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getScanCapabilities,\r\n \r\n // 位置相关常量\r\n CoordinateTypes,\r\n \r\n /**\r\n * 获取位置功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getLocationCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getLocationCapabilities,\r\n \r\n /**\r\n * 获取位置选择功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getChooseLocationCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n * @since 2.1.0\r\n */\r\n getChooseLocationCapabilities,\r\n\r\n\r\n // 蓝牙 API\r\n openBluetoothAdapter,\r\n openBluetoothAdapterAsync,\r\n startBluetoothDevicesDiscovery,\r\n startBluetoothDevicesDiscoveryAsync,\r\n onBluetoothDeviceFound,\r\n onBluetoothDeviceFoundAsync,\r\n createBLEConnection,\r\n createBLEConnectionAsync,\r\n // 蓝牙相关常量\r\n BluetoothStates,\r\n //微信分享\r\n toShare,\r\n toShareAsync,\r\n toShareCallBack,\r\n toShareCallBackAsync,\r\n\r\n /**\r\n * 获取蓝牙功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getBluetoothCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n */\r\n getBluetoothCapabilities,\r\n\r\n // 打印PDF API\r\n printPdf,\r\n printPdfAsync,\r\n \r\n /**\r\n * 获取打印PDF功能能力信息\r\n * @returns {Object} 能力信息对象\r\n * @example\r\n * const capabilities = qsh.getPrintCapabilities()\r\n * console.log('是否支持:', capabilities.supported)\r\n */\r\n getPrintCapabilities,\r\n\r\n // 人脸识别 API(仅支持微信小程序环境)\r\n faceVerify,\r\n getFaceCapabilities,\r\n\r\n\r\n // 插件系统\r\n plugins: {\r\n /**\r\n * 插件管理器\r\n */\r\n manager: pluginManager,\r\n \r\n /**\r\n * 注册插件\r\n * @param {Object} plugin - 插件对象\r\n * @returns {Object} pluginManager 实例\r\n * @example\r\n * qsh.plugins.register(myPlugin)\r\n */\r\n register: (plugin) => pluginManager.register(plugin),\r\n \r\n /**\r\n * 安装插件\r\n * @param {string} name - 插件名称\r\n * @returns {Promise<void>}\r\n * @example\r\n * await qsh.plugins.install('image')\r\n */\r\n install: (name) => pluginManager.install(name, uni),\r\n \r\n /**\r\n * 获取插件列表\r\n * @returns {Array} 插件列表\r\n * @example\r\n * console.log(qsh.plugins.list())\r\n */\r\n list: () => pluginManager.getPluginList()\r\n },\r\n \r\n // 拦截器系统\r\n interceptors: {\r\n /**\r\n * 拦截器链\r\n */\r\n chain: interceptorChain,\r\n \r\n /**\r\n * 注册请求拦截器\r\n * @param {Function} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * qsh.interceptors.useRequest(async (ctx) => {\r\n * console.log('API 调用:', ctx.apiName)\r\n * return ctx\r\n * })\r\n */\r\n useRequest: (interceptor, options) => interceptorChain.useRequest(interceptor, options),\r\n \r\n /**\r\n * 注册响应拦截器\r\n * @param {Function} interceptor - 拦截器函数\r\n * @param {Object} [options] - 选项\r\n * @returns {Function} 移除拦截器的函数\r\n * @example\r\n * qsh.interceptors.useResponse(async (result, ctx) => {\r\n * console.log('API 完成:', ctx.apiName)\r\n * return result\r\n * })\r\n */\r\n useResponse: (interceptor, options) => interceptorChain.useResponse(interceptor, options),\r\n \r\n /**\r\n * 内置拦截器\r\n */\r\n builtin: {\r\n logging: loggingInterceptor,\r\n performance: performanceInterceptor,\r\n createRetry: createRetryInterceptor,\r\n createValidation: createValidationInterceptor,\r\n errorNormalizer: errorNormalizerInterceptor\r\n }\r\n },\r\n\r\n // 观测指标\r\n metrics: {\r\n /**\r\n * 获取性能指标报告\r\n */\r\n getPerformanceReport: () => performanceInterceptor.getReport(),\r\n /**\r\n * 清空性能指标\r\n */\r\n clearPerformanceMetrics: () => performanceInterceptor.clearMetrics()\r\n },\r\n \r\n // 错误处理工具\r\n errors: {\r\n /**\r\n * 错误码枚举\r\n */\r\n codes: ErrorCodes,\r\n \r\n /**\r\n * 错误消息\r\n */\r\n messages: ErrorMessages,\r\n \r\n /**\r\n * 错误分类\r\n */\r\n categories: ErrorCategory,\r\n \r\n /**\r\n * 标准化错误\r\n * @param {any} error - 原始错误\r\n * @param {Object} context - 上下文\r\n * @returns {Object} 标准化错误\r\n * @example\r\n * const standardError = qsh.errors.normalize(error, { apiName: 'chooseImage' })\r\n */\r\n normalize: normalizeError,\r\n \r\n /**\r\n * 创建标准错误\r\n * @param {string} code - 错误码\r\n * @param {Object} options - 选项\r\n * @returns {Object} 标准错误\r\n * @example\r\n * const error = qsh.errors.create('E_IMG_001', { apiName: 'chooseImage' })\r\n */\r\n create: createError,\r\n \r\n /**\r\n * 判断是否为标准错误\r\n * @param {any} error - 错误对象\r\n * @returns {boolean}\r\n * @example\r\n * if (qsh.errors.isStandard(error)) { ... }\r\n */\r\n isStandard: isStandardError\r\n },\r\n \r\n // 状态管理\r\n store: {\r\n /**\r\n * 状态仓库实例\r\n */\r\n instance: stateStore,\r\n \r\n /**\r\n * 获取状态\r\n * @param {string} path - 状态路径\r\n * @returns {any} 状态值\r\n * @example\r\n * const status = qsh.store.get('sdk.status')\r\n */\r\n get: (path) => stateStore.get(path),\r\n \r\n /**\r\n * 设置状态\r\n * @param {string} path - 状态路径\r\n * @param {any} value - 新值\r\n * @example\r\n * qsh.store.set('sdk.status', 'ready')\r\n */\r\n set: (path, value) => stateStore.set(path, value),\r\n \r\n /**\r\n * 订阅状态变化\r\n * @param {string} path - 状态路径\r\n * @param {Function} listener - 监听函数\r\n * @returns {Function} 取消订阅的函数\r\n * @example\r\n * const unsubscribe = qsh.store.subscribe('network.online', (online) => {\r\n * console.log('网络状态:', online)\r\n * })\r\n */\r\n subscribe: (path, listener) => stateStore.subscribe(path, listener),\r\n \r\n /**\r\n * 获取状态快照\r\n * @returns {Object} 状态快照\r\n * @example\r\n * console.log(qsh.store.getSnapshot())\r\n */\r\n getSnapshot: () => stateStore.getSnapshot()\r\n },\r\n \r\n // 调试工具(生产环境可能被优化掉)\r\n debug: {\r\n /**\r\n * 日志记录器\r\n */\r\n logger: Logger,\r\n /**\r\n * 设置外部日志 reporter,便于对接埋点/观测\r\n */\r\n setLogReporter: (reporter) => Logger.setReporter(reporter),\r\n \r\n /**\r\n * 错误处理器\r\n */\r\n errorHandler: ErrorHandler,\r\n \r\n /**\r\n * 状态管理器\r\n */\r\n stateManager,\r\n \r\n /**\r\n * 启用调试模式\r\n * @example\r\n * qsh.debug.enableDevMode()\r\n */\r\n enableDevMode: () => Logger.enableDevMode(),\r\n \r\n /**\r\n * 获取日志历史\r\n * @param {number} [count] - 获取条数\r\n * @returns {Array} 日志历史\r\n * @example\r\n * console.log(qsh.debug.getLogs(10))\r\n */\r\n getLogs: (count) => Logger.getHistory(count),\r\n \r\n /**\r\n * 获取 SDK 统计信息\r\n * @returns {Object} 统计信息\r\n * @example\r\n * console.log(qsh.debug.getStats())\r\n */\r\n getStats: () => ({\r\n logger: Logger.getStats(),\r\n state: stateManager.getStats(),\r\n weixinConfig: getWeixinConfigManager().getStats(),\r\n plugins: pluginManager.getStats(),\r\n interceptors: interceptorChain.getStats(),\r\n store: stateStore.getStats()\r\n }),\r\n \r\n /**\r\n * 获取微信配置管理器\r\n * @returns {Object} 微信配置管理器\r\n * @example\r\n * console.log(qsh.debug.getWeixinConfigManager().getStats())\r\n */\r\n getWeixinConfigManager,\r\n \r\n /**\r\n * 导出调试信息\r\n * @returns {string} JSON 格式的调试信息\r\n * @example\r\n * console.log(qsh.debug.exportDebugInfo())\r\n */\r\n exportDebugInfo: () => Logger.exportToJSON()\r\n }\r\n};\r\n\r\n// 设置 webView 对象\r\nif (environment.isWeixinMiniProgram) {\r\n uni.webView = window.wx && window.wx.miniProgram;\r\n} else {\r\n uni.webView = {\r\n navigateTo,\r\n navigateBack,\r\n switchTab,\r\n reLaunch,\r\n redirectTo,\r\n postMessage,\r\n getEnv,\r\n chooseImage,\r\n scanCode,\r\n getLocation: getLocationAPI,\r\n openLocation: openLocationAPI,\r\n chooseLocation: chooseLocationAPI\r\n };\r\n}\r\n\r\n// 保留对原始 uni 对象的引用(如果存在)\r\nconst originalUni = typeof window.uni !== 'undefined' ? window.uni : {};\r\n\r\n// 合并原有的 uni 对象属性(如果存在)\r\nObject.keys(originalUni).forEach(key => {\r\n if (!uni.hasOwnProperty(key)) {\r\n uni[key] = originalUni[key];\r\n }\r\n});\r\n\r\n// 导出\r\nexport default uni;\r\n\r\n// 自动挂载到全局(UMD 模式)\r\nif (typeof window !== 'undefined') {\r\n // 仅挂载新全局名,不再暴露 window.uni\r\n window.qsh = uni;\r\n}\r\n"],"names":["getWindow","getNavigatorUA","isWeixinMiniProgram","win","ua","isAppPlus","isNvue","isUvue","isUniApp","isHtml5Plus","isUniAppWebView","getEnvironment","cachedEnvironmentInfo","getEnvironmentInfo","forceRefresh","environment","ErrorTypes","QshError","type","message","context","originalError","_ErrorHandler","enabled","callback","index","error","qshError","platformType","apiName","paramName","expectedType","actualValue","fn","_0","__async","logMessage","callbackError","target","propertyKey","descriptor","originalMethod","args","__spreadProps","__spreadValues","__publicField","ErrorHandler","SDKStates","StateManager","resolve","reject","initFunction","targetState","stateHandler","readyIndex","errorIndex","stateManager","waitForReady","isReady","getState","LogLevels","LogLevelNames","_Logger","level","module","timestamp","levelName","modulePrefix","logEntry","e","hasArgs","count","stats","levelCounts","entry","history","moduleName","reporter","Logger","isLocalhost","hasDebugParam","hasDebugStorage","bridgeLogger","platformLogger","apiLogger","stateLogger","READY_STATE_REGEX","initializeInApp","initializeInWeixin","initializeBridge","waitForBridge","initBridge","handleReady","handleError","bridgeError","syncError","WeixinConfigStates","isWeixinJSSDKAvailable","WeixinConfigManager","config","nextClientId","nextIsProd","hasChanged","isProd","url","hashIndex","currentUrl","configApiUrl","requestUrl","response","result","data","isDev","notInWeixin","isCorsError","configData","configOptions","readyCallbacks","res","errorMessage","errorCallbacks","weixinConfigManager","isLoadingWeixinSDK","weixinSDKLoaded","weixinSDKLoadPromise","autoConfigStarted","waitForExistingWeixinScript","script","settled","timeoutId","finish","loaded","autoConfigWeixin","handleLoad","ensureWeixinJSSDKLoaded","options","force","recoverFromError","loadWeixinJSSDKIfNeeded","recoverWeixinConfigStateIfNeeded","shouldLoadWeixinSDK","inWeixin","inMiniProgramUA","hintedMiniProgram","hasMiniProgramBridge","existingScript","err","waitForWeixinConfig","configureWeixin","runtimeConfig","isWeixinConfigReady","getWeixinConfigState","getWeixinConfigManager","retryWeixinConfig","PluginManager","plugin","name","version","existing","qshInstance","depName","orderIndex","names","plugins","pluginManager","InterceptorChain","interceptor","priority","a","b","item","ctx","newResult","interceptorChain","loggingInterceptor","duration","performanceInterceptor","metrics","report","value","key","createRetryInterceptor","maxRetries","retryDelay","shouldRetry","createValidationInterceptor","rules","validator","StateStore","path","obj","keys","lastKey","oldValue","updates","listener","listeners","unsubscribe","newValue","p","i","parentPath","parentListeners","parentValue","connection","updateConnectionType","loading","apiPath","apiState","platform","stateStore","ErrorCodes","ErrorMessages","ErrorCategory","LegacyErrorMapping","PlatformErrorMapping","ApiErrorMapping","getErrorCategory","code","isRetriableError","isUserAction","getErrorMessage","StandardError","normalizeError","normalizeLegacyError","normalizePlatformError","legacyCode","newCode","errMsg","apiMapping","pattern","platformMapping","defaultCode","errorNormalizerInterceptor","standardError","createError","isStandardError","withTimeout","promiseFactory","timeoutMs","_","runInitPipeline","tasks","task","run","BasePlatform","delta","processedUrl","processedDelta","processedOptions","webviewIds","getCurrentWebviewId","currentWebview","parent","webviewId","sendToUniAppX","postData","serviceMessage","sendToNvue","sendToPlus","currentWebviewIds","jsonMessage","jsonWebviewIds","sendToParent","sendMessage","WeixinPlatform","wxMethod","wxOptions","weixinPlatform","navigateTo","navigateBack","switchTab","reLaunch","redirectTo","postMessage","getEnv","AppPlatform","envInfo","isAppEnv","appPlatform","getPlatformNavigation","getPlatformMessage","toRawLike","generateCallbackId","WebViewBridge","params","callbacks","_a","interceptedContext","callbackId","_b","callbackData","success","fail","complete","interceptedResult","emptyApis","callbackIds","ids","webViewBridge","callApiInWebView","clearPersistentCallbacksByApi","ImageSourceTypes","ImageSizeTypes","DEFAULT_OPTIONS","normalizeOptions","normalized","isSupported","chooseImageInWeixin","chooseImageInUniApp","chooseImage","normalizedOptions","getImageCapabilities","ScanTypes","scanCodeInWeixin","detectScanType","content","scanCodeInUniApp","scanCode","getScanCapabilities","CoordinateTypes","DEFAULT_LOCATION_OPTIONS","DEFAULT_OPEN_LOCATION_OPTIONS","normalizeLocationOptions","normalizeLocationUpdateOptions","normalizeOpenLocationOptions","scaleNum","getLocationInWeixin","openLocationInWeixin","getLocationInUniApp","openLocationInUniApp","getLocation","openLocation","_c","validationError","getLocationCapabilities","isWeixin","locationChangeCallbacks","locationChangeErrorCallbacks","notifyCallbacks","payload","startLocationUpdate","stopLocationUpdate","onLocationChange","hasListener","offLocationChange","onLocationChangeError","offLocationChangeError","chooseLocationInWeixin","weixinParams","chooseLocationInUniApp","uniOptions","chooseLocation","getChooseLocationCapabilities","registry","registerCapability","implementations","resolveCapability","environmentType","impls","shareToTypes","shareValueTypes","toShareInWeixin","wrappedError","normalizeWeixinOptions","toShareInUniApp","normalizeUniAppOptions","typeValue","SHARE_CAPABILITY_KEY","toShare","env","impl","toShareAsync","toShareCallBack","toShareCallBackAsync","BluetoothStates","openBluetoothAdapterInWeixin","onBluetoothDeviceFound","bluetoothInUniApp","startBluetoothDevicesDiscoveryInUniApp","bluetoothDeviceFoundCallbacks","onBluetoothDeviceFoundInUniApp","cb","createBLEConnectionInUniApp","openBluetoothAdapter","startBluetoothDevicesDiscovery","createBLEConnection","_d","deviceId","autoConnect","getBluetoothCapabilities","printPdfInUniApp","printPdf","getPrintCapabilities","FACE_PAGE_PATH","isMiniProgramNavigateAvailable","buildFacePageUrl","query","faceVerifyInWeixin","targetUrl","faceVerify","getFaceCapabilities","shouldWaitForWeixinConfigInReady","readySDK","autoInitStarted","startAutoInit","step","ensureReadyInvoke","apiFn","rest","hasCallbacks","execute","wrapped","normalizeCallbackOptions","input","rawNavigateTo","rawNavigateBack","rawSwitchTab","rawReLaunch","rawRedirectTo","rawPostMessage","exec","rawGetEnv","rawChooseImage","chooseImageAsync","rawPrintPdf","printPdfAsync","rawScanCode","rawFaceVerify","scanCodeAsync","rawToShare","rawToShareAsync","rawToShareCallBack","rawToShareCallBackAsync","getLocationAPI","rawGetLocation","getLocationAsyncAPI","openLocationAPI","rawOpenLocation","openLocationAsyncAPI","chooseLocationAPI","rawChooseLocation","chooseLocationAsyncAPI","rawOpenBluetooth","openBluetoothAdapterAsync","rawBluetoothDevicesDiscovery","startBluetoothDevicesDiscoveryAsync","rawOnBluetoothDeviceFound","onBluetoothDeviceFoundAsync","rawCreateBLEConnection","createBLEConnectionAsync","uni","rawOnLocationChange","rawOffLocationChange","rawOnLocationChangeError","rawOffLocationChangeError","rawStartLocationUpdate","rawStopLocationUpdate","originalUni"],"mappings":"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"}
|