Files
cunkebao_v3/Appbuild/pages/index/index.vue

1110 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<!-- 全屏web-view容器 -->
<web-view :src="currentUrl" class="webview" ref="webview" @message="handleMessage" @error="handleError"
@loading="handleLoading">
</web-view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-container">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 错误状态 -->
<view v-if="error" class="error-container">
<text class="error-text">{{ error }}</text>
<button @click="reloadPage" class="reload-btn">重新加载</button>
<button @click="switchToFallback" class="fallback-btn">使用备用地址</button>
<button @click="clearTimeout" class="clear-btn">清除超时</button>
</view>
<!-- 调试信息仅在调试模式下显示 -->
<view v-if="config.appConfig.debug" class="debug-info">
<text>当前URL: {{ currentUrl }}</text>
<text>加载状态: {{ loading ? '加载中' : '已加载' }}</text>
</view>
</view>
</template>
<script>
import config from '@/config.js';
export default {
data() {
return {
config: config,
currentUrl: '', // 初始化为空字符串
loading: false,
error: '',
loadingTimer: null,
messageQueue: [],
// 返回键监听相关
backButtonListener: null,
backButtonCount: 0,
backButtonTimer: null,
canExit: false,
lastBackTime: 0,
// 返回键状态管理
iframeCanGoBack: false,
backTimeoutId: null,
isProcessingBack: false
}
},
onLoad() {
this.initApp();
this.initBackButtonListener();
},
onShow() {
this.resumeMessageQueue();
this.resumeBackButtonListener();
},
onHide() {
console.log('WebView页面隐藏');
this.pauseBackButtonListener();
},
onUnload() {
this.cleanup();
this.removeBackButtonListener();
},
methods: {
// 获取初始URL
getInitialUrl() {
console.log('获取初始URLconfig:', this.config);
if (this.config && this.config.appConfig && this.config.appConfig.useTestPage) {
return this.config.webConfig.testUrl;
}
return this.config.webConfig.mainUrl;
},
// 初始化应用
initApp() {
console.log('UniApp: 开始初始化应用');
// 设置初始URL
this.currentUrl = this.getInitialUrl();
console.log('UniApp: 设置URL:', this.currentUrl);
this.setupLoadingTimeout();
this.initMessageHandler();
// 立即尝试注入桥接代码
console.log('UniApp: 立即注入桥接代码');
this.injectBridgeCode();
},
// 设置加载超时
setupLoadingTimeout() {
// 清除之前的定时器
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
}
// 检查是否启用超时检测
if (!this.config.appConfig.enableTimeout) {
console.log('超时检测已禁用');
return;
}
if (this.config.appConfig.loadingTimeout > 0) {
console.log('设置加载超时:', this.config.appConfig.loadingTimeout + 'ms');
this.loadingTimer = setTimeout(() => {
if (this.loading) {
console.warn('页面加载超时,当前状态:', this.loading);
this.handleTimeout();
}
}, this.config.appConfig.loadingTimeout);
}
},
// 处理加载超时
handleTimeout() {
console.warn('触发页面加载超时处理');
this.error = '页面加载超时,请检查网络连接';
this.loading = false;
// 清除定时器
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
this.loadingTimer = null;
}
},
// 初始化消息处理器
initMessageHandler() {
console.log('UniApp: 初始化消息处理器');
// 监听来自web-view的消息
window.addEventListener('message', (event) => {
console.log('UniApp: 收到window.message事件:', event.data);
this.handleIframeMessage(event);
});
},
// 设置WebView桥接
setupWebViewBridge() {
// 向web-view注入通信桥接代码
this.injectBridgeCode();
},
// 注入桥接代码
injectBridgeCode() {
console.log('UniApp: 开始注入桥接代码');
const bridgeCode = `
// UniApp WebView 桥接代码
console.log('开始注入UniApp桥接代码...');
// 检查是否已经存在桥接
if (window.uniAppBridge) {
console.log('UniApp桥接已存在跳过注入');
return;
}
window.uniAppBridge = {
// 发送消息到UniApp
postMessage: function(type, data) {
console.log('UniApp桥接发送消息:', type, data);
window.parent.postMessage({
type: type,
data: data,
timestamp: Date.now()
}, '*');
},
// 获取用户信息
getUserInfo: function() {
console.log('UniApp桥接: 请求用户信息');
this.postMessage('getUserInfo', {});
},
// 获取设备信息
getDeviceInfo: function() {
console.log('UniApp桥接: 请求设备信息');
this.postMessage('getDeviceInfo', {});
},
// 显示Toast
showToast: function(message, duration = 2000) {
console.log('UniApp桥接: 显示Toast', message, duration);
this.postMessage('toast', { message, duration });
},
// 显示Alert
showAlert: function(title, content) {
console.log('UniApp桥接: 显示Alert', title, content);
this.postMessage('alert', { title, content });
},
// 显示Confirm
showConfirm: function(title, content) {
console.log('UniApp桥接: 显示Confirm', title, content);
this.postMessage('confirm', { title, content });
},
// 分享
share: function(data) {
console.log('UniApp桥接: 分享', data);
this.postMessage('share', data);
},
// 支付
payment: function(data) {
console.log('UniApp桥接: 支付', data);
this.postMessage('payment', data);
},
// 页面导航
navigate: function(url) {
console.log('UniApp桥接: 导航', url);
this.postMessage('navigate', { url });
},
// 自定义消息
sendCustomMessage: function(type, data) {
console.log('UniApp桥接: 自定义消息', type, data);
this.postMessage(type, data);
},
// 页面准备就绪
notifyPageReady: function(data) {
console.log('UniApp桥接: 页面准备就绪', data);
this.postMessage('pageReady', data);
},
// 处理返回键
handleBackButton: function(action) {
console.log('UniApp桥接: 处理返回键', action);
switch(action) {
case 'tryBack':
// 尝试iframe内部返回
this.tryIframeBack();
break;
case 'showExitConfirm':
// 在 web-view 内显示退出确认
if (confirm('确定要退出应用吗?')) {
this.postMessage('exitApp', {});
}
break;
case 'exitApp':
// 通知 UniApp 退出应用
this.postMessage('exitApp', {});
break;
}
},
// 尝试iframe内部返回
tryIframeBack: function() {
console.log('UniApp桥接: 尝试iframe内部返回');
try {
// 检查是否可以返回
if (window.history && window.history.length > 1) {
console.log('iframe可以返回执行返回操作');
window.history.back();
// 通知UniApp返回成功
this.postMessage('backSuccess', { canGoBack: true });
} else {
console.log('iframe无法返回通知UniApp');
this.postMessage('backFailed', {
canGoBack: false,
reason: 'no_history'
});
}
} catch (error) {
console.error('iframe返回操作失败:', error);
this.postMessage('backFailed', {
canGoBack: false,
reason: 'error',
error: error.message
});
}
},
// 监听返回键事件
listenBackButton: function() {
// 监听浏览器的后退事件
window.addEventListener('popstate', (event) => {
console.log('UniApp桥接: 检测到 popstate 事件');
this.postMessage('backButton', { action: 'popstate' });
});
// 监听键盘事件
document.addEventListener('keydown', (event) => {
if (event.key === 'Backspace' || event.keyCode === 8) {
console.log('UniApp桥接: 检测到返回键');
this.postMessage('backButton', { action: 'keydown' });
}
});
// 监听页面可见性变化
document.addEventListener('visibilitychange', (event) => {
console.log('UniApp桥接: 页面可见性变化', document.hidden);
if (!document.hidden) {
// 页面重新可见时,检查是否可以返回
this.checkBackStatus();
}
});
// 监听页面加载完成
window.addEventListener('load', (event) => {
console.log('UniApp桥接: 页面加载完成');
this.checkBackStatus();
});
},
// 检查返回状态
checkBackStatus: function() {
try {
const canGoBack = window.history && window.history.length > 1;
console.log('UniApp桥接: 检查返回状态, canGoBack:', canGoBack);
// 通知UniApp当前返回状态
this.postMessage('backStatus', {
canGoBack: canGoBack,
historyLength: window.history ? window.history.length : 0,
currentUrl: window.location.href
});
} catch (error) {
console.error('UniApp桥接: 检查返回状态失败:', error);
}
}
};
// 监听来自UniApp的消息
window.addEventListener('message', function(event) {
console.log('UniApp桥接收到消息:', event.data);
if (event.data && event.data.type) {
// 触发自定义事件
const customEvent = new CustomEvent('uniAppMessage', {
detail: event.data
});
window.dispatchEvent(customEvent);
}
});
console.log('UniApp桥接代码注入成功');
// 通知UniApp页面已加载完成
window.parent.postMessage({
type: 'pageLoaded',
data: { url: window.location.href },
timestamp: Date.now()
}, '*');
// 初始化返回键监听
window.uniAppBridge.listenBackButton();
`;
// 立即尝试注入
console.log('UniApp: 立即注入桥接代码');
this.evalJS(bridgeCode);
// 延迟再次注入,确保注入成功
setTimeout(() => {
console.log('UniApp: 延迟500ms后再次注入');
this.evalJS(bridgeCode);
}, 500);
// 再次延迟注入,作为备用方案
setTimeout(() => {
console.log('UniApp: 延迟1000ms后备用注入');
this.evalJS(bridgeCode);
}, 1000);
},
// 执行JavaScript代码
evalJS(code) {
console.log('UniApp: 执行JavaScript代码');
console.log('UniApp: 当前平台:', uni.getSystemInfoSync().platform);
const webview = this.$refs.webview;
console.log('UniApp: webview引用:', webview);
// 检查是否在App环境下
// #ifdef APP-PLUS
if (webview && webview.evalJS) {
try {
webview.evalJS(code);
console.log('UniApp: JavaScript代码执行成功 (App环境)');
} catch (error) {
console.error('UniApp: JavaScript代码执行失败:', error);
}
} else {
console.warn('UniApp: webview或evalJS方法不存在 (App环境)');
// 尝试备用方案
this.tryAlternativeInjection(code);
}
// #endif
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
console.log('UniApp: 小程序环境,使用备用注入方案');
this.tryAlternativeInjection(code);
// #endif
// #ifdef H5
console.log('UniApp: H5环境使用备用注入方案');
this.tryAlternativeInjection(code);
// #endif
},
// 备用注入方案
tryAlternativeInjection(code) {
console.log('UniApp: 尝试备用注入方案');
try {
// 方案1: 直接通过postMessage发送代码
window.postMessage({
type: 'injectCode',
data: { code: code },
timestamp: Date.now()
}, '*');
console.log('UniApp: 备用方案1执行成功');
} catch (error) {
console.error('UniApp: 备用方案1失败:', error);
// 方案2: 通过web-view的message事件
try {
const webview = this.$refs.webview;
if (webview && webview.postMessage) {
webview.postMessage({
type: 'injectCode',
data: { code: code }
});
console.log('UniApp: 备用方案2执行成功');
} else {
console.error('UniApp: 备用方案2失败 - webview.postMessage不存在');
}
} catch (error2) {
console.error('UniApp: 备用方案2失败:', error2);
}
}
},
// 处理web-view组件的消息
handleMessage(event) {
console.log('收到web-view消息:', event.detail);
try {
const data = event.detail.data;
if (data && data.type) {
this.processMessage(data);
}
} catch (error) {
console.error('处理消息失败:', error);
}
},
// 处理iframe消息
handleIframeMessage(event) {
console.log('收到iframe消息:', event.data);
try {
if (event.data && event.data.type) {
// 处理页面加载完成消息
if (event.data.type === 'pageLoaded') {
console.log('收到页面加载完成消息:', event.data.data);
// 清除超时定时器
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
this.loadingTimer = null;
}
// 更新加载状态
this.loading = false;
this.processMessageQueue();
return;
}
this.processMessage(event.data);
}
} catch (error) {
console.error('处理iframe消息失败:', error);
}
},
// 处理消息
processMessage(data) {
console.log('UniApp处理消息:', data.type, data);
switch (data.type) {
case this.config.communication.messageTypes.GET_USER_INFO:
console.log('UniApp: 处理获取用户信息请求');
this.sendUserInfo();
break;
case this.config.communication.messageTypes.GET_DEVICE_INFO:
console.log('UniApp: 处理获取设备信息请求');
this.sendDeviceInfo();
break;
case this.config.communication.messageTypes.NAVIGATE:
console.log('UniApp: 处理导航请求');
this.handleNavigation(data);
break;
case this.config.communication.messageTypes.SHARE:
console.log('UniApp: 处理分享请求');
this.handleShare(data);
break;
case this.config.communication.messageTypes.PAYMENT:
console.log('UniApp: 处理支付请求');
this.handlePayment(data);
break;
case this.config.communication.messageTypes.TOAST:
console.log('UniApp: 处理Toast请求');
this.handleToast(data);
break;
case this.config.communication.messageTypes.ALERT:
console.log('UniApp: 处理Alert请求');
this.handleAlert(data);
break;
case this.config.communication.messageTypes.CONFIRM:
console.log('UniApp: 处理Confirm请求');
this.handleConfirm(data);
break;
case 'pageReady':
console.log('UniApp: 处理页面准备就绪消息');
// 可以在这里处理页面准备就绪的逻辑
break;
case 'backButton':
console.log('UniApp: 处理返回键消息');
this.handleBackButtonMessage(data);
break;
case 'backSuccess':
console.log('UniApp: 处理iframe返回成功消息');
this.handleBackSuccess(data);
break;
case 'backFailed':
console.log('UniApp: 处理iframe返回失败消息');
this.handleBackFailed(data);
break;
case 'backStatus':
console.log('UniApp: 处理iframe返回状态消息');
this.handleBackStatus(data);
break;
case 'exitApp':
console.log('UniApp: 处理退出应用消息');
this.handleExitApp();
break;
default:
console.log('UniApp: 未知消息类型:', data.type);
}
},
// 发送用户信息到iframe
sendUserInfo() {
console.log('UniApp: 发送用户信息');
const userInfo = {
type: 'userInfo',
data: this.config.userConfig.defaultUser
};
this.sendMessageToIframe(userInfo);
},
// 发送设备信息到iframe
sendDeviceInfo() {
console.log('UniApp: 发送设备信息');
const systemInfo = uni.getSystemInfoSync();
const deviceInfo = {
type: 'deviceInfo',
data: {
platform: systemInfo.platform,
model: systemInfo.model,
version: systemInfo.version,
appVersion: this.config.appConfig.version,
appName: this.config.appConfig.appName,
screenWidth: systemInfo.screenWidth,
screenHeight: systemInfo.screenHeight,
statusBarHeight: systemInfo.statusBarHeight
}
};
this.sendMessageToIframe(deviceInfo);
},
// 处理导航
handleNavigation(data) {
if (data.url) {
console.log('导航到:', data.url);
// 可以在这里处理页面跳转逻辑
}
},
// 处理分享
handleShare(data) {
console.log('UniApp: 处理分享请求', data);
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
href: data.url || this.currentUrl,
title: data.title || this.config.appConfig.appName,
summary: data.summary || '分享内容',
success: (res) => {
console.log('UniApp: 分享成功:', res);
this.sendToIframe('shareResult', { success: true });
},
fail: (err) => {
console.error('UniApp: 分享失败:', err);
this.sendToIframe('shareResult', { success: false, error: err });
}
});
},
// 处理支付
handlePayment(data) {
console.log('UniApp: 处理支付请求', data);
// 这里可以集成具体的支付功能
// 模拟支付成功
setTimeout(() => {
this.sendToIframe('paymentResult', {
success: true,
orderId: data.orderId || 'order123'
});
}, 1000);
},
// 处理Toast
handleToast(data) {
console.log('UniApp: 处理Toast请求', data);
uni.showToast({
title: data.message,
icon: 'none',
duration: data.duration || 2000
});
},
// 处理Alert
handleAlert(data) {
console.log('UniApp: 处理Alert请求', data);
uni.showModal({
title: data.title || '提示',
content: data.content,
showCancel: false
});
},
// 处理Confirm
handleConfirm(data) {
console.log('UniApp: 处理Confirm请求', data);
uni.showModal({
title: data.title || '确认',
content: data.content,
success: (res) => {
console.log('UniApp: Confirm结果:', res);
this.sendToIframe('confirmResult', {
confirmed: res.confirm
});
}
});
},
// 发送消息到iframe
sendMessageToIframe(message) {
this.messageQueue.push(message);
this.processMessageQueue();
},
// 处理消息队列
processMessageQueue() {
console.log('UniApp: 处理消息队列, 队列长度:', this.messageQueue.length, '加载状态:', this.loading);
if (this.messageQueue.length > 0 && !this.loading) {
const message = this.messageQueue.shift();
console.log('UniApp: 发送消息到iframe:', message);
this.evalJS(`
window.postMessage(${JSON.stringify(message)}, '*');
`);
}
},
// 恢复消息队列处理
resumeMessageQueue() {
this.processMessageQueue();
},
// 向iframe发送消息的通用方法
sendToIframe(type, data) {
const message = {
type: type,
data: data,
timestamp: Date.now()
};
this.sendMessageToIframe(message);
},
// 处理加载状态
handleLoading(event) {
console.log('WebView加载状态变化:', event.detail);
const newLoadingState = event.detail.loading;
console.log('加载状态从', this.loading, '变为', newLoadingState);
this.loading = newLoadingState;
if (!this.loading) {
// 页面加载完成
console.log('页面加载完成,清除超时定时器');
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
this.loadingTimer = null;
}
// 页面加载完成后立即注入桥接代码
this.injectBridgeCode();
this.processMessageQueue();
} else {
// 开始加载,设置超时
console.log('页面开始加载,设置超时检测');
this.setupLoadingTimeout();
}
},
// 处理错误
handleError(event) {
console.error('WebView错误:', event.detail);
this.error = '页面加载失败,请检查网络连接';
this.loading = false;
clearTimeout(this.loadingTimer);
},
// 重新加载页面
reloadPage() {
this.error = '';
this.loading = true;
this.setupLoadingTimeout();
const webview = this.$refs.webview;
if (webview) {
webview.reload();
}
},
// 切换到备用地址
switchToFallback() {
this.currentUrl = this.config.webConfig.fallbackUrl;
this.reloadPage();
},
// 清除超时
clearTimeout() {
console.log('手动清除超时');
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
this.loadingTimer = null;
}
this.error = '';
this.loading = false;
console.log('超时已清除');
},
// 动态设置web-view高度
setWebViewHeight(height) {
console.log('设置web-view高度:', height);
if (this.$refs.webview) {
// 方法1: 通过style直接设置
this.$refs.webview.$el.style.height = height + 'px';
// 方法2: 通过class设置
this.$refs.webview.$el.className = 'webview custom-height';
// 方法3: 强制重新计算样式
this.$nextTick(() => {
this.$refs.webview.$el.style.setProperty('height', height + 'px', 'important');
});
}
},
// 设置web-view为全屏
setWebViewFullscreen() {
const fullHeight = uni.getSystemInfoSync().windowHeight;
console.log('设置web-view全屏高度:', fullHeight);
this.setWebViewHeight(fullHeight);
},
// 设置web-view为部分高度
setWebViewPartialHeight(percentage = 0.8) {
const windowHeight = uni.getSystemInfoSync().windowHeight;
const partialHeight = windowHeight * percentage;
console.log('设置web-view部分高度:', partialHeight, '百分比:', percentage);
this.setWebViewHeight(partialHeight);
},
// 初始化返回键监听
initBackButtonListener() {
console.log('初始化返回键监听');
// 方法1: 使用 uni.addInterceptor 拦截返回事件
// #ifdef APP-PLUS
try {
uni.addInterceptor('navigateBack', {
invoke(e) {
console.log('拦截到返回事件:', e);
return false; // 阻止默认返回行为
}
});
} catch (error) {
console.warn('addInterceptor 失败:', error);
}
// #endif
// 方法2: 监听物理返回键
this.setupPhysicalBackButton();
// 方法3: 监听 web-view 内的返回事件
this.setupWebViewBackListener();
},
// 设置物理返回键监听
setupPhysicalBackButton() {
// #ifdef APP-PLUS
try {
// 监听安卓物理返回键
plus.key.addEventListener('backbutton', (e) => {
console.log('检测到物理返回键事件:', e);
this.handleBackButton();
});
} catch (error) {
console.warn('物理返回键监听失败:', error);
}
// #endif
},
// 设置 web-view 内返回监听
setupWebViewBackListener() {
// 监听 web-view 内的 popstate 事件
window.addEventListener('popstate', (event) => {
console.log('检测到 popstate 事件:', event);
this.handleBackButton();
});
// 监听 web-view 内的 beforeunload 事件
window.addEventListener('beforeunload', (event) => {
console.log('检测到 beforeunload 事件:', event);
this.handleBackButton();
});
},
// 处理返回键事件
handleBackButton() {
const now = Date.now();
const timeDiff = now - this.lastBackTime;
console.log('处理返回键事件, 时间差:', timeDiff, 'ms, iframeCanGoBack:', this.iframeCanGoBack);
// 重置计数器
if (timeDiff > 2000) {
this.backButtonCount = 0;
}
this.backButtonCount++;
this.lastBackTime = now;
// 如果正在处理返回,忽略新的返回键
if (this.isProcessingBack) {
console.log('正在处理返回,忽略新的返回键');
return;
}
// 第一次按返回键
if (this.backButtonCount === 1) {
// 如果iframe可以返回先尝试iframe返回
if (this.iframeCanGoBack) {
this.tryIframeBack();
} else {
// 如果iframe不能返回直接显示退出确认
this.showExitConfirm();
}
}
// 第二次按返回键,直接退出
else if (this.backButtonCount >= 2) {
this.exitApp();
}
},
// 尝试iframe内部返回
tryIframeBack() {
console.log('尝试iframe内部返回');
// 设置处理状态
this.isProcessingBack = true;
// 清除之前的超时
if (this.backTimeoutId) {
clearTimeout(this.backTimeoutId);
}
// 方法1: 通过桥接发送返回消息到iframe
this.sendBackButtonMessage('tryBack');
// 方法2: 直接执行JavaScript尝试返回
this.evalJS(`
try {
// 检查是否可以返回
if (window.history && window.history.length > 1) {
console.log('iframe可以返回执行返回操作');
window.history.back();
// 通知UniApp返回成功
window.parent.postMessage({
type: 'backSuccess',
data: { canGoBack: true },
timestamp: Date.now()
}, '*');
} else {
console.log('iframe无法返回通知UniApp');
window.parent.postMessage({
type: 'backFailed',
data: { canGoBack: false, reason: 'no_history' },
timestamp: Date.now()
}, '*');
}
} catch (error) {
console.error('iframe返回操作失败:', error);
window.parent.postMessage({
type: 'backFailed',
data: { canGoBack: false, reason: 'error', error: error.message },
timestamp: Date.now()
}, '*');
}
`);
// 设置超时如果iframe没有响应则显示退出确认
this.backTimeoutId = setTimeout(() => {
if (this.backButtonCount === 1 && this.isProcessingBack) {
console.log('iframe返回超时显示退出确认');
this.isProcessingBack = false;
this.showExitConfirm();
}
}, 1500); // 1.5秒超时
},
// 显示退出确认
showExitConfirm() {
console.log('显示退出确认');
// 方法1: 使用 uni.showModal
// #ifdef APP-PLUS
uni.showModal({
title: '退出确认',
content: '确定要退出应用吗?',
confirmText: '退出',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
this.exitApp();
}
}
});
// #endif
// 方法2: 通过桥接发送消息到 web-view
this.sendBackButtonMessage('showExitConfirm');
},
// 退出应用
exitApp() {
console.log('退出应用');
// 方法1: 使用 plus.runtime.quit
// #ifdef APP-PLUS
try {
plus.runtime.quit();
} catch (error) {
console.error('退出应用失败:', error);
}
// #endif
// 方法2: 通过桥接发送退出消息
this.sendBackButtonMessage('exitApp');
},
// 发送返回键消息到 web-view
sendBackButtonMessage(action) {
if (this.$refs.webview) {
try {
// 通过 postMessage 发送消息
this.$refs.webview.postMessage({
type: 'backButton',
action: action,
timestamp: Date.now()
});
} catch (error) {
console.error('发送返回键消息失败:', error);
}
}
},
// 处理返回键消息
handleBackButtonMessage(data) {
console.log('处理返回键消息:', data);
switch (data.action) {
case 'popstate':
case 'keydown':
this.handleBackButton();
break;
default:
console.log('未知的返回键动作:', data.action);
}
},
// 处理退出应用
handleExitApp() {
console.log('处理退出应用');
// #ifdef APP-PLUS
try {
plus.runtime.quit();
} catch (error) {
console.error('退出应用失败:', error);
}
// #endif
},
// 处理iframe返回成功消息
handleBackSuccess(data) {
console.log('处理iframe返回成功消息:', data);
this.isProcessingBack = false;
this.iframeCanGoBack = true;
this.backButtonCount = 0; // 重置返回键计数
this.lastBackTime = 0; // 重置最后按下时间
// 清除超时
if (this.backTimeoutId) {
clearTimeout(this.backTimeoutId);
this.backTimeoutId = null;
}
},
// 处理iframe返回失败消息
handleBackFailed(data) {
console.log('处理iframe返回失败消息:', data);
this.isProcessingBack = false;
this.iframeCanGoBack = false;
this.backButtonCount = 0; // 重置返回键计数
this.lastBackTime = 0; // 重置最后按下时间
// 清除超时
if (this.backTimeoutId) {
clearTimeout(this.backTimeoutId);
this.backTimeoutId = null;
}
// 显示退出确认
this.showExitConfirm();
},
// 处理iframe返回状态消息
handleBackStatus(data) {
console.log('处理iframe返回状态消息:', data);
this.iframeCanGoBack = data.data.canGoBack;
console.log('更新iframe返回状态:', this.iframeCanGoBack);
},
// 恢复返回键监听
resumeBackButtonListener() {
console.log('恢复返回键监听');
this.backButtonCount = 0;
this.lastBackTime = 0;
},
// 暂停返回键监听
pauseBackButtonListener() {
console.log('暂停返回键监听');
this.backButtonCount = 0;
},
// 移除返回键监听
removeBackButtonListener() {
console.log('移除返回键监听');
// #ifdef APP-PLUS
try {
// 移除物理返回键监听
plus.key.removeEventListener('backbutton');
// 移除拦截器
uni.removeInterceptor('navigateBack');
} catch (error) {
console.warn('移除返回键监听失败:', error);
}
// #endif
// 清除定时器
if (this.backButtonTimer) {
clearTimeout(this.backButtonTimer);
this.backButtonTimer = null;
}
},
// 清理资源
cleanup() {
if (this.loadingTimer) {
clearTimeout(this.loadingTimer);
}
if (this.backTimeoutId) {
clearTimeout(this.backTimeoutId);
this.backTimeoutId = null;
}
this.removeBackButtonListener();
}
}
}
</script>
<style>
@import url("index.css");
</style>