let currentRequest = null let currentEventChannel = null let pageResolved = false function appendQueryParam(url, key, value) { const separator = url.indexOf('?') >= 0 ? '&' : '?' return `${url}${separator}${key}=${encodeURIComponent(value)}` } function buildWebViewSrc(request) { let nextUrl = request.url nextUrl = appendQueryParam(nextUrl, 'cmrBridge', request.bridgeVersion) nextUrl = appendQueryParam(nextUrl, 'cmrKind', request.kind) return nextUrl } function emitFallbackAndClose() { if (!currentRequest || !currentEventChannel) { return } if (!pageResolved) { pageResolved = true currentEventChannel.emit('fallback', currentRequest.fallback) } wx.navigateBack({ fail() {}, }) } function emitCloseAndBack(payload) { if (currentEventChannel && !pageResolved) { pageResolved = true currentEventChannel.emit('close', payload || {}) } wx.navigateBack({ fail() {}, }) } Page({ data: { pageTitle: '内容体验', pageSubtitle: '', presentation: 'sheet', webViewSrc: '', webViewReady: false, loadErrorText: '', panelBodyHeightPx: 420, }, onLoad() { const systemInfo = wx.getSystemInfoSync() const windowHeight = typeof systemInfo.windowHeight === 'number' ? systemInfo.windowHeight : 700 pageResolved = false currentRequest = null currentEventChannel = null this.setData({ pageTitle: '内容体验', pageSubtitle: '', presentation: 'sheet', webViewSrc: '', webViewReady: false, loadErrorText: '', panelBodyHeightPx: Math.max(420, Math.floor(windowHeight * 0.62)), }) try { currentEventChannel = this.getOpenerEventChannel() } catch (error) { currentEventChannel = null } if (!currentEventChannel) { return } currentEventChannel.on('init', (request) => { currentRequest = request const presentation = request.presentation || 'sheet' const panelHeightPx = presentation === 'dialog' ? Math.max(420, Math.floor(windowHeight * 0.7)) : presentation === 'fullscreen' ? Math.max(520, windowHeight - 24) : Math.max(420, Math.floor(windowHeight * 0.72)) const headerHeightPx = presentation === 'fullscreen' ? 84 : 76 this.setData({ pageTitle: request.title || '内容体验', pageSubtitle: request.subtitle || '', presentation, webViewSrc: buildWebViewSrc(request), webViewReady: true, loadErrorText: '', panelBodyHeightPx: Math.max(240, panelHeightPx - headerHeightPx), }) }) }, onUnload() { if (currentEventChannel && !pageResolved) { currentEventChannel.emit('close', {}) } pageResolved = false currentRequest = null currentEventChannel = null }, handleWebViewMessage(event) { const dataList = event.detail && Array.isArray(event.detail.data) ? event.detail.data : [] const rawMessage = dataList.length ? dataList[dataList.length - 1] : null if (!rawMessage || typeof rawMessage !== 'object') { return } const action = rawMessage.action || rawMessage.type || '' if (!action) { return } if (action === 'close') { emitCloseAndBack(rawMessage.payload) return } if (action === 'submitResult') { if (currentEventChannel) { currentEventChannel.emit('submitResult', rawMessage.payload || {}) } return } if (action === 'fallback') { emitFallbackAndClose() } }, handleWebViewError() { this.setData({ loadErrorText: '页面打开失败,已回退原生内容', }) emitFallbackAndClose() }, handleCloseTap() { emitCloseAndBack({}) }, })