Files
smartDriveEEUniApp/App.vue
2026-01-20 08:46:36 +08:00

408 lines
12 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.

<script>
import initApp from '@/common/appInit.js';
import openApp from '@/common/openApp.js';
// #ifdef H5
openApp() //创建在h5端全局悬浮引导用户下载app的功能
// #endif
import checkIsAgree from '@/pages/uni-agree/utils/uni-agree.js';
import uniIdPageInit from '@/uni_modules/uni-id-pages/init.js';
import { store } from '@/uni_modules/uni-id-pages/common/store.js';
export default {
globalData: {
searchText: '',
appVersion: {},
config: {},
$i18n: {},
$t: {}
},
onLaunch: async function() {
console.log('App Launch')
this.globalData.$i18n = this.$i18n
this.globalData.$t = str => this.$t(str)
initApp();
await uniIdPageInit()
// #ifdef H5
this.hideEduTabIfNeed() // 初始化尝试隐藏教务 tab非教务角色
uni.$on('tabbar:refresh', this.hideEduTabIfNeed) // 登录后触发
// #endif
// 设置全局路由拦截,检查登录状态
this.setupRouteInterceptor()
// #ifdef MP-WEIXIN
// 微信小程序:先快速检查登录状态,如果未登录则立即跳转,避免首页闪烁
// 延迟一小段时间确保页面栈已初始化
setTimeout(() => {
if (!this.isLoggedIn()) {
this.redirectToLogin()
} else {
// 已登录,检查当前页面
this.checkCurrentPageLogin()
}
}, 300)
// #endif
// #ifndef MP-WEIXIN
// 其他平台:延迟检查登录状态
setTimeout(() => {
this.checkCurrentPageLogin()
}, 100)
// #endif
// #ifdef APP
//checkIsAgree(); APP端暂时先用原生默认生成的。目前自定义方式启动vue界面时原生层已经请求了部分权限这并不符合国家的法规
// #endif
// #ifdef H5
// checkIsAgree(); // 默认不开启。目前全球,仅欧盟国家有网页端同意隐私权限的需要。如果需要可以自己去掉注视后生效
// #endif
// #ifdef APP-PLUS
//idfa有需要的用户在应用首次启动时自己获取存储到storage中
/*var idfa = '';
var manager = plus.ios.invoke('ASIdentifierManager', 'sharedManager');
if(plus.ios.invoke(manager, 'isAdvertisingTrackingEnabled')){
var identifier = plus.ios.invoke(manager, 'advertisingIdentifier');
idfa = plus.ios.invoke(identifier, 'UUIDString');
plus.ios.deleteObject(identifier);
}
plus.ios.deleteObject(manager);
console.log('idfa = '+idfa);*/
// #endif
},
onShow: function() {
console.log('App Show')
// 每次应用显示时也检查当前页面是否需要登录
this.checkCurrentPageLogin()
// #ifdef H5
// 返回前台时再尝试隐藏一次
this.hideEduTabIfNeed()
// #endif
},
onHide: function() {
console.log('App Hide')
},
methods: {
// #ifdef H5
/**
* H5 平台:根据当前登录角色,动态控制原生 tabbar 可见项
*
* 规则:
* - admin不限制所有 tab 都显示
* - speaking_training_teacher仅显示【教务、语音、表达、我的】
* - speaking_training_students仅显示【作业、语音、表达、我的】
* - 其他角色:隐藏【作业、教务、语音、表达】
*/
hideEduTabIfNeed() {
try {
const normalize = (val) =>
typeof val === 'string'
? val
.split(',')
.map((s) => s.trim().toLowerCase())
.filter(Boolean)
: [];
const storedRole = uni.getStorageSync('backend-role-name') || '';
const loginResp = uni.getStorageSync('backend-login-response') || {};
const respRole = loginResp.roleName || '';
const roles = [...normalize(storedRole), ...normalize(respRole)];
const isTeacher = roles.includes('speaking_training_teacher');
const isStudent = roles.includes('speaking_training_students');
const isAdmin = roles.includes('admin');
const isMeetingAdmin = roles.includes('meeting_admin');
const isAdminFurniture = roles.includes('admin_furniture');
// 检查是否有任何角色名等于 "furniture" 字符串(精确匹配)
const hasFurnitureRole = roles.includes('furniture');
// 会议相关的tab标签
const meetingTabLabels = ['总结和统计'];
const teacherAllowed = ['我的'];
const studentAllowed = ['我的'];
const otherHidden = ['作业', '教务', '语音', '表达'];
// tabBar 顺序(根据 pages.json 中的 tabBar.list 顺序)
// 0: 接待, 1: 客户, 2: 团队
// 3: 总结和统计, 4: 接待(furniture_reception), 5: 开始接待(common_begin_reception), 6: 客户(furniture_customer), 7: 销冠(furniture_top_sales), 8: 我的(ucenter)
const meetingTabIndices = [3]; // 会议相关tab的索引位置
const furnitureTabIndices = [4, 6, 7]; // 家具相关tab的索引位置接待、客户、销冠
const ucenterIndex = 8; // "我的"(ucenter)的索引位置
const shouldShow = (label, index) => {
// 任何角色都应该能看到"我的"ucenter索引8
if (label === '我的') {
return true;
}
// admin_furniture 和 furniture 角色:显示 furniture_reception, furniture_customer, furniture_top_sales 和 ucenter
if (isAdminFurniture || hasFurnitureRole) {
// 显示家具相关的tab索引4, 6, 7和"我的"索引8
return furnitureTabIndices.includes(index) || index === ucenterIndex;
}
// 隐藏"接待"和"客户"这两个tab索引0和1
if (label === '接待' || label === '客户') {
return false;
}
// meeting_admin 角色显示会议相关的tab和"我的"
if (isMeetingAdmin) {
return meetingTabIndices.includes(index);
}
// 非 meeting_admin 角色隐藏所有会议相关的tab和家具相关的tab
if (meetingTabIndices.includes(index) || furnitureTabIndices.includes(index)) {
return false;
}
// 对于非会议相关的tab按角色判断
if (isAdmin) return true;
if (isTeacher) return teacherAllowed.includes(label);
if (isStudent) return studentAllowed.includes(label);
// 其他角色:只隐藏指定的几个,其余保留
return !otherHidden.includes(label);
};
// 延迟+多次尝试,等待原生 tabbar DOM 渲染
let attempts = 0;
const maxAttempts = 15;
const timer = setInterval(() => {
attempts += 1;
const items = Array.from(document.querySelectorAll('.uni-tabbar .uni-tabbar__item'));
if (items && items.length) {
items.forEach((el, index) => {
const label = (el.textContent || '').trim();
const show = shouldShow(label, index);
if (show) {
el.style.display = '';
el.style.flex = '';
el.style.width = '';
el.style.padding = '';
} else {
el.style.display = 'none';
el.style.flex = '0 0 0';
el.style.width = '0';
el.style.padding = '0';
}
});
console.log('[TabBar][H5 role-hide] roles:', roles, 'isAdmin:', isAdmin, 'isTeacher:', isTeacher, 'isStudent:', isStudent, 'items:', items.length, 'attempt:', attempts);
clearInterval(timer);
}
if (attempts >= maxAttempts) {
clearInterval(timer);
}
}, 200);
} catch (e) {
console.warn('[TabBar][H5 hide] failed:', e);
}
},
// #endif
/**
* 设置全局路由拦截
*/
setupRouteInterceptor() {
const app = this
// 拦截路由跳转(适用于所有平台)
uni.addInterceptor('navigateTo', {
invoke: (options) => {
if (app.shouldRedirectToLogin(options.url)) {
app.redirectToLogin()
return false // 阻止跳转
}
}
})
uni.addInterceptor('redirectTo', {
invoke: (options) => {
if (app.shouldRedirectToLogin(options.url)) {
app.redirectToLogin()
return false // 阻止跳转
}
}
})
uni.addInterceptor('switchTab', {
invoke: (options) => {
if (app.shouldRedirectToLogin(options.url)) {
app.redirectToLogin()
return false // 阻止跳转
}
}
})
uni.addInterceptor('reLaunch', {
invoke: (options) => {
if (app.shouldRedirectToLogin(options.url)) {
app.redirectToLogin()
return false // 阻止跳转
}
}
})
},
/**
* 判断是否需要跳转到登录页
*/
shouldRedirectToLogin(url) {
if (!url) return false
// 排除登录相关页面
const excludePaths = [
'/uni_modules/uni-id-pages/pages/login',
'/uni_modules/uni-id-pages/pages/register',
'/uni_modules/uni-id-pages/pages/retrieve'
]
// 检查是否在排除列表中
for (let excludePath of excludePaths) {
if (url.includes(excludePath)) {
return false
}
}
// 检查登录状态
return !this.isLoggedIn()
},
/**
* 检查是否已登录
*/
isLoggedIn() {
// 优先检查后端登录态
const backendToken = uni.getStorageSync('backend-token')
if (backendToken) {
return true
}
// 其次检查 uni-id 的登录态
return store.hasLogin
},
/**
* 跳转到登录页
*/
redirectToLogin() {
const loginPage = '/uni_modules/uni-id-pages/pages/login/login-withpwd'
const pages = getCurrentPages()
// 如果当前已经在登录页,不重复跳转
if (pages.length > 0) {
const currentPage = pages[pages.length - 1]
if (currentPage.route && currentPage.route.includes('login')) {
return
}
}
// #ifdef MP-WEIXIN
// 微信小程序登录页在subPackage中必须使用reLaunch
// redirectTo不能用于跳转到subPackage页面只能用于主包页面
uni.reLaunch({
url: loginPage,
success: () => {
console.log('跳转登录页成功')
},
fail: (err) => {
console.error('跳转登录页失败:', err)
// 如果reLaunch失败可能是路径问题尝试不带前导斜杠
const loginPageWithoutSlash = loginPage.startsWith('/') ? loginPage.substring(1) : loginPage
uni.reLaunch({
url: loginPageWithoutSlash,
fail: (err2) => {
console.error('跳转登录页失败(重试):', err2)
}
})
}
})
// #endif
// #ifndef MP-WEIXIN
// 其他平台使用reLaunch
uni.reLaunch({
url: loginPage,
fail: (err) => {
console.error('跳转登录页失败:', err)
}
})
// #endif
},
/**
* 判断是否为tabBar页面
*/
isTabBarPage(route) {
if (!route) return false
const tabBarPages = [
'pages/reception/reception',
'pages/customer/customer',
'pages/team/team',
'pages/meeting_summary/meeting_summary',
'pages/furniture_reception/furniture_reception',
'pages/furniture_reception/common_begin_reception',
'pages/furniture_customer/furniture_customer',
'pages/furniture_top_sales/furniture_top_sales',
'pages/ucenter/ucenter'
]
return tabBarPages.includes(route)
},
/**
* 检查当前页面是否需要登录
*/
checkCurrentPageLogin() {
const pages = getCurrentPages()
if (pages.length === 0) {
// #ifdef MP-WEIXIN
// 微信小程序:如果页面栈为空,延迟重试
setTimeout(() => {
this.checkCurrentPageLogin()
}, 200)
// #endif
return
}
const currentPage = pages[pages.length - 1]
if (!currentPage || !currentPage.route) {
// #ifdef MP-WEIXIN
// 微信小程序:如果页面信息不完整,延迟重试
setTimeout(() => {
this.checkCurrentPageLogin()
}, 200)
// #endif
return
}
const currentRoute = '/' + currentPage.route
// 排除登录相关页面
if (currentRoute.includes('/uni_modules/uni-id-pages/pages/login') ||
currentRoute.includes('/uni_modules/uni-id-pages/pages/register') ||
currentRoute.includes('/uni_modules/uni-id-pages/pages/retrieve')) {
return
}
// 如果未登录,跳转到登录页
if (!this.isLoggedIn()) {
// #ifdef MP-WEIXIN
// 微信小程序确保页面已完全加载后再跳转使用setTimeout代替$nextTick
setTimeout(() => {
this.redirectToLogin()
}, 100)
// #endif
// #ifndef MP-WEIXIN
this.redirectToLogin()
// #endif
}
}
}
}
</script>
<style>
/*每个页面公共css */
</style>