// WebView 事件类型定义 const WebviewEvents = { /** * 获取平台信息 */ GET_PLATFORM: 'getPlatform', /** * 获取状态栏高度 */ GET_STATUS_BAR_HEIGHT: 'getStatusBarHeight', /** * 扫码 */ SCAN: 'scan', /** * 苹果支付 */ APPLE_PAY: 'applePay', APPLE_PAY_RESTORE: 'applePayRestore', /** * 微信是否安装 */ CHECK_WECHAT_INSTALLED: 'checkWechatInstalled', /** * 获取升级信息 */ GET_UPGRADE_INFO: 'getUpgradeInfo', /** * 下载升级 */ DOWNLOAD_UPGRADE: 'downloadAndInstall', /** * 打开 iframe */ OPEN_IFRAME: 'openIframe' } as const; // 定义 WebView 事件键类型 type WebviewEventKey = keyof typeof WebviewEvents; type WebviewEventValue = typeof WebviewEvents[WebviewEventKey]; // 定义 uni.webView 类型 interface UniWebView { postMessage: (options: { data: { action: string; data: { callbackAction: string; data?: any; }; }; }) => void; } // 扩展 uni 命名空间 declare global { interface Uni { webView?: UniWebView; } // 扩展 Window 接口 interface Window { // 平台标识 platform?: string; // WebView Bridge 实例 webviewBridge: WebviewBridge; // 下载进度回调 onDownloadProgress?: (progress: any) => void; // 动态回调函数 [key: `webviewCallback_${string}`]: ((data: any) => void) | undefined; } } /** * 重置 window 回调函数 * @param callbackEvent 回调事件名称 */ function resetWindowCallback(callbackEvent: string): void { const key = callbackEvent as keyof Window; if (window[key]) { window[key] = undefined as never; delete window[key]; } } /** * 获取 WebView 回调 * @param event 事件名称 * @param args 参数 * @returns Promise */ async function getWebviewCallback( event: string, args?: any ): Promise { if (!uni.webView) { return Promise.reject(new Error('uni环境异常,请检查uni.webview是否正确引入')); } if (window.platform === 'h5') { return Promise.reject(new Error('请在app中使用')); } const callbackEvent = `webviewCallback_${event}`; try { return await new Promise((resolve, reject) => { // 设置回调函数 (window as any)[callbackEvent] = (data: T) => { resolve(data); resetWindowCallback(callbackEvent); }; // 发送消息到 WebView uni.webView?.postMessage({ data: { action: event, data: { callbackAction: callbackEvent, data: args } } }); }); } catch (error) { return Promise.reject(new Error('webview初始化失败,请检查是否正确引入uni.webview')); } } /** * WebView Bridge 类 * 用于与原生 App 进行通信 */ class WebviewBridge { constructor() {} /** * 获取平台信息 * @returns Promise */ getPaltform(): Promise { return getWebviewCallback(WebviewEvents.GET_PLATFORM); } /** * 扫码功能 * @param args 扫码参数 * @returns Promise */ scan(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.SCAN, args); } /** * 苹果支付 * @param args 支付参数 * @returns Promise */ applePay(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.APPLE_PAY, args); } /** * 苹果支付恢复 * @param args 恢复参数 * @returns Promise */ applePayRestore(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.APPLE_PAY_RESTORE, args); } /** * 检查微信是否已安装 * @param args 参数 * @returns Promise */ checkWechatInstalled(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.CHECK_WECHAT_INSTALLED, args); } /** * 获取状态栏高度 * @returns Promise */ getStatusBarHeight(): Promise { return getWebviewCallback(WebviewEvents.GET_STATUS_BAR_HEIGHT); } /** * 获取升级信息 * @param args 参数 * @returns Promise */ getUpgradeInfo(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.GET_UPGRADE_INFO, args); } /** * 打开 iframe * @param args 参数 * @returns Promise */ openIframe(...args: any[]): Promise { return getWebviewCallback(WebviewEvents.OPEN_IFRAME, args); } /** * 下载升级包 * @param url 下载地址 * @param progressCb 进度回调函数 * @returns Promise */ downloadUpgrade(url: string, progressCb?: (progress: any) => void): Promise { if (progressCb) { window.onDownloadProgress = progressCb; } return getWebviewCallback(WebviewEvents.DOWNLOAD_UPGRADE, { url, progressCb: 'onDownloadProgress' }); } } // 创建实例并挂载到 window const webviewBridge = new WebviewBridge(); window.webviewBridge = webviewBridge; export default webviewBridge; export { WebviewBridge, WebviewEvents };