182 lines
4.5 KiB
Vue
182 lines
4.5 KiB
Vue
<script>
|
||
import { hasValidToken, redirectToLogin } from './api/utils/auth';
|
||
import { appApi } from './api/modules/app';
|
||
import UpdateModal from './components/UpdateModal.vue';
|
||
|
||
export default {
|
||
components: {
|
||
UpdateModal
|
||
},
|
||
data() {
|
||
return {
|
||
// #ifdef APP-PLUS
|
||
// 更新弹窗相关数据(仅APP端)
|
||
showUpdateModal: false,
|
||
updateInfo: {
|
||
version: '',
|
||
updateContent: '',
|
||
downloadUrl: '',
|
||
forceUpdate: false
|
||
}
|
||
// #endif
|
||
};
|
||
},
|
||
onLaunch: function() {
|
||
console.log('App Launch');
|
||
// 检测APP更新
|
||
this.checkAppUpdate();
|
||
// 全局检查token
|
||
this.checkToken();
|
||
},
|
||
onShow: function() {
|
||
console.log('App Show');
|
||
// 每次显示时检测APP更新
|
||
this.checkAppUpdate();
|
||
// 应用恢复时再次检查token
|
||
this.checkToken();
|
||
},
|
||
onHide: function() {
|
||
console.log('App Hide');
|
||
},
|
||
methods: {
|
||
// 检查token是否有效并处理跳转
|
||
checkToken() {
|
||
// 获取当前页面
|
||
const pages = getCurrentPages();
|
||
const currentPage = pages.length ? pages[pages.length - 1] : null;
|
||
const currentRoute = currentPage ? currentPage.route : '';
|
||
|
||
// 如果token无效且不在登录页面,则跳转到登录页面
|
||
if (!hasValidToken() && currentRoute && currentRoute !== 'pages/login/index') {
|
||
console.log('Token无效,从', currentRoute, '重定向到登录页面');
|
||
redirectToLogin();
|
||
}
|
||
},
|
||
|
||
// 检测APP更新
|
||
async checkAppUpdate() {
|
||
// #ifdef APP-PLUS
|
||
try {
|
||
console.log('开始检测APP更新...');
|
||
const res = await appApi.checkUpdate();
|
||
console.log('更新检测结果:', res);
|
||
|
||
if (res.code === 200 && res.data) {
|
||
const data = res.data;
|
||
|
||
// 清理 downloadUrl 中的换行符
|
||
const downloadUrl = data.downloadUrl ? data.downloadUrl.trim() : '';
|
||
|
||
// 设置更新信息
|
||
this.updateInfo = {
|
||
version: data.version || '',
|
||
updateContent: data.updateContent || '本次更新包含性能优化和问题修复',
|
||
downloadUrl: downloadUrl,
|
||
forceUpdate: data.forceUpdate || false
|
||
};
|
||
|
||
// 显示更新弹窗
|
||
this.showUpdateModal = true;
|
||
}
|
||
} catch (error) {
|
||
console.error('检测更新失败:', error);
|
||
// 更新检测失败不影响应用正常使用,只记录日志
|
||
}
|
||
// #endif
|
||
},
|
||
|
||
// 处理更新确认
|
||
handleUpdateConfirm(downloadUrl) {
|
||
// #ifdef APP-PLUS
|
||
if (downloadUrl) {
|
||
plus.runtime.openURL(downloadUrl);
|
||
}
|
||
// #endif
|
||
this.showUpdateModal = false;
|
||
},
|
||
|
||
// 处理更新取消
|
||
handleUpdateCancel() {
|
||
if (this.updateInfo.forceUpdate) {
|
||
// 强制更新时,取消则退出应用
|
||
// #ifdef APP-PLUS
|
||
plus.runtime.quit();
|
||
// #endif
|
||
} else {
|
||
// 关闭弹窗
|
||
this.showUpdateModal = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
export function getSafeAreaHeight() {
|
||
// 1. 优先使用 CSS 环境变量
|
||
if (CSS.supports("padding-top", "env(safe-area-inset-top)")) {
|
||
const safeAreaTop = getComputedStyle(
|
||
document.documentElement,
|
||
).getPropertyValue("env(safe-area-inset-top)");
|
||
const height = parseInt(safeAreaTop) || 0;
|
||
if (height > 0) return height;
|
||
}
|
||
|
||
// 2. 设备检测
|
||
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
||
const isAndroid = /Android/.test(navigator.userAgent);
|
||
const isAppMode = getSetting("isAppMode");
|
||
if (isIOS && isAppMode) {
|
||
// iOS 设备
|
||
const isIPhoneX = window.screen.height >= 812;
|
||
return isIPhoneX ? 44 : 20;
|
||
} else if (isAndroid) {
|
||
// Android 设备
|
||
return 24;
|
||
}
|
||
|
||
// 3. 默认值
|
||
return 0;
|
||
}
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<!-- #ifdef APP-PLUS -->
|
||
<!-- 更新弹窗(仅APP端) -->
|
||
<UpdateModal
|
||
:show="showUpdateModal"
|
||
:version="updateInfo.version"
|
||
:updateContent="updateInfo.updateContent"
|
||
:downloadUrl="updateInfo.downloadUrl"
|
||
:forceUpdate="updateInfo.forceUpdate"
|
||
@confirm="handleUpdateConfirm"
|
||
@cancel="handleUpdateCancel"
|
||
/>
|
||
<!-- #endif -->
|
||
</template>
|
||
|
||
<style lang="scss">
|
||
/*每个页面公共css */
|
||
@import 'uview-ui/index.scss';
|
||
/* 引入阿里图标库 */
|
||
@import '/static/iconfont/iconfont.css';
|
||
|
||
/* 页面通用样式 */
|
||
page {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
background-color: #fff;
|
||
}
|
||
|
||
/* 安全区适配 */
|
||
// .safe-area-inset-bottom {
|
||
// padding-bottom: constant(safe-area-inset-bottom);
|
||
// padding-bottom: env(safe-area-inset-bottom);
|
||
// }
|
||
|
||
/* 字体图标支持 */
|
||
@font-face {
|
||
font-family: "SF Pro Display";
|
||
src: url("https://sf.abarba.me/SF-Pro-Display-Regular.otf");
|
||
}
|
||
</style>
|