2025-04-09 09:34:27 +08:00
|
|
|
|
<script>
|
|
|
|
|
|
import { hasValidToken, redirectToLogin } from './api/utils/auth';
|
2025-11-03 14:07:15 +08:00
|
|
|
|
import { appApi } from './api/modules/app';
|
|
|
|
|
|
import UpdateModal from './components/UpdateModal.vue';
|
2025-04-09 09:34:27 +08:00
|
|
|
|
|
|
|
|
|
|
export default {
|
2025-11-03 14:07:15 +08:00
|
|
|
|
components: {
|
|
|
|
|
|
UpdateModal
|
|
|
|
|
|
},
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
|
// 更新弹窗相关数据(仅APP端)
|
|
|
|
|
|
showUpdateModal: false,
|
|
|
|
|
|
updateInfo: {
|
|
|
|
|
|
version: '',
|
|
|
|
|
|
updateContent: '',
|
|
|
|
|
|
downloadUrl: '',
|
|
|
|
|
|
forceUpdate: false
|
|
|
|
|
|
}
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
2025-04-09 09:34:27 +08:00
|
|
|
|
onLaunch: function() {
|
|
|
|
|
|
console.log('App Launch');
|
2025-11-03 14:07:15 +08:00
|
|
|
|
// 检测APP更新
|
|
|
|
|
|
this.checkAppUpdate();
|
2025-04-09 09:34:27 +08:00
|
|
|
|
// 全局检查token
|
|
|
|
|
|
this.checkToken();
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow: function() {
|
|
|
|
|
|
console.log('App Show');
|
2025-11-03 14:07:15 +08:00
|
|
|
|
// 每次显示时检测APP更新
|
|
|
|
|
|
this.checkAppUpdate();
|
2025-04-09 09:34:27 +08:00
|
|
|
|
// 应用恢复时再次检查token
|
|
|
|
|
|
this.checkToken();
|
|
|
|
|
|
},
|
|
|
|
|
|
onHide: function() {
|
|
|
|
|
|
console.log('App Hide');
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
// 检查token是否有效并处理跳转
|
|
|
|
|
|
checkToken() {
|
|
|
|
|
|
// 获取当前页面
|
|
|
|
|
|
const pages = getCurrentPages();
|
|
|
|
|
|
const currentPage = pages.length ? pages[pages.length - 1] : null;
|
2025-11-03 14:07:15 +08:00
|
|
|
|
const currentRoute = currentPage ? currentPage.route : '';
|
2025-04-09 09:34:27 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果token无效且不在登录页面,则跳转到登录页面
|
2025-11-03 14:07:15 +08:00
|
|
|
|
if (!hasValidToken() && currentRoute && currentRoute !== 'pages/login/index') {
|
|
|
|
|
|
console.log('Token无效,从', currentRoute, '重定向到登录页面');
|
2025-04-09 09:34:27 +08:00
|
|
|
|
redirectToLogin();
|
|
|
|
|
|
}
|
2025-11-03 14:07:15 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 检测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;
|
2025-04-09 09:34:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-03 14:07:15 +08:00
|
|
|
|
}
|
2025-04-09 09:34:27 +08:00
|
|
|
|
}
|
2025-08-30 17:14:57 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-09 09:34:27 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
2025-11-03 14:07:15 +08:00
|
|
|
|
<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>
|
|
|
|
|
|
|
2025-04-09 09:34:27 +08:00
|
|
|
|
<style lang="scss">
|
|
|
|
|
|
/*每个页面公共css */
|
|
|
|
|
|
@import 'uview-ui/index.scss';
|
|
|
|
|
|
/* 引入阿里图标库 */
|
|
|
|
|
|
@import '/static/iconfont/iconfont.css';
|
|
|
|
|
|
|
|
|
|
|
|
/* 页面通用样式 */
|
|
|
|
|
|
page {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 安全区适配 */
|
2025-08-30 17:14:57 +08:00
|
|
|
|
// .safe-area-inset-bottom {
|
|
|
|
|
|
// padding-bottom: constant(safe-area-inset-bottom);
|
|
|
|
|
|
// padding-bottom: env(safe-area-inset-bottom);
|
|
|
|
|
|
// }
|
2025-04-09 09:34:27 +08:00
|
|
|
|
|
|
|
|
|
|
/* 字体图标支持 */
|
|
|
|
|
|
@font-face {
|
|
|
|
|
|
font-family: "SF Pro Display";
|
|
|
|
|
|
src: url("https://sf.abarba.me/SF-Pro-Display-Regular.otf");
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|