/**
* 手机绑定拦截器使用示例:
* import {phoneBindNavigateToInterceptor, phoneBindSwitchTabInterceptor} from '@/utils/interceptor/checkPhone.uts'
*
onPageShow(()=>{ // 推荐用onPageShow,避免页面缓存导致拦截失效
uni.addInterceptor('switchTab', phoneBindSwitchTabInterceptor)
uni.addInterceptor('navigateTo', phoneBindNavigateToInterceptor)
})
onUnload(() => {
uni.removeInterceptor('navigateTo');
uni.removeInterceptor('switchTab');
});
*/
import { userState } from '@/store/user-store.uts'
// 导入全局导航锁和公共方法(与登录拦截器共用)
import { lock, getCurrentPagePath, getPureUrl } from '@/utils/common/lock-common.uts'
import {
VITE_APP_USER_LOGIN_PAGE,
VITE_APP_USER_REGISTER_PAGE,
VITE_APP_USER_RESET_PASSWROD_PAGE,
VITE_APP_USER_HELP_PAGE,
VITE_APP_TABBAR_HOME_PAGE,
VITE_APP_USER_BIND_PHONE_PAGE,
VITE_APP_USER_WECHAT_AUTH_PAGE,
VITE_APP_AGREEMENT_PAGE,
VITE_APP_PRIVACY_PAGE
} from '@/config/page-setting.uts'
// 绑手机页面路径
const BIND_PHONE_PAGE_URL = VITE_APP_USER_BIND_PHONE_PAGE;
const BIND_PHONE_PAGE_ROUTE = BIND_PHONE_PAGE_URL.replace(/^\//, ''); // 去掉开头/,匹配页面route格式
const HOME_PAGE_FULL_URL = VITE_APP_USER_HELP_PAGE; // 首页完整路径
const HOME_PAGE_SHORT_URL = '/'; // 首页简写路径
// 无需绑定手机的路由白名单(按需添加)
const NO_PHONE_BIND_WHITE_LIST = [
//首页
'/',
VITE_APP_TABBAR_HOME_PAGE,
//登录
VITE_APP_USER_LOGIN_PAGE,
//注册
VITE_APP_USER_REGISTER_PAGE,
//重置密码
VITE_APP_USER_RESET_PASSWROD_PAGE,
//帮助
VITE_APP_USER_HELP_PAGE,
//绑定手机
VITE_APP_USER_BIND_PHONE_PAGE,
//微信授权
VITE_APP_USER_WECHAT_AUTH_PAGE,
VITE_APP_AGREEMENT_PAGE,
VITE_APP_PRIVACY_PAGE
];
/**
* navigateTo 手机绑定拦截器
*/
const phoneBindNavigateToInterceptor = {
invoke: function (options: NavigateToOptions) {
if (!options.url) return; // 避免空url导致的异常
const targetUrl = getPureUrl(options.url); // 获取目标纯路径
// 目标是首页则直接放行(不管其他条件)
if (targetUrl === HOME_PAGE_FULL_URL || targetUrl === HOME_PAGE_SHORT_URL) {
return;
}
// 白名单判断(兼容带参数URL)
if (NO_PHONE_BIND_WHITE_LIST.includes(getPureUrl(options.url))) return;
//console.log('拦截 navigateTo 接口(手机绑定校验):', options);
// 放行条件:已绑定手机 / 已在绑手机页 / 正在导航中
if (userState.phone || getCurrentPagePath() === BIND_PHONE_PAGE_ROUTE || lock.isPhoneNavigating || lock.isLoginSuccessTempPass) {
return;
}
lock.isPhoneNavigating = true; // 上锁
// 弹框提示绑定手机
uni.showModal({
title: '提示',
content: '根据国家法律规定,请先绑定实名手机号',
confirmText: '去绑定',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
// 异步跳转绑手机页面,避免同步冲突
setTimeout(() => {
uni.navigateTo({
url: BIND_PHONE_PAGE_URL,
complete: () => {
lock.isPhoneNavigating = false; // 释放导航锁
}
});
}, 300);
} else {
// 用户取消绑定,释放导航锁
lock.isPhoneNavigating = false;
}
},
fail: () => {
// 弹框异常,兜底释放锁
lock.isPhoneNavigating = false;
}
});
// 超时兜底释放锁,防止弹框/跳转中断导致锁残留
setTimeout(()=>{
if(lock.isPhoneNavigating){
lock.isPhoneNavigating = false
}
},1000)
// 返回false阻止原navigateTo执行
return false;
},
} as AddInterceptorOptions;
/**
* switchTab 手机绑定拦截器
*/
const phoneBindSwitchTabInterceptor = {
invoke: function (options: SwitchTabOptions) {
if (!options.url) return; // 避免空url导致的异常
const targetUrl = getPureUrl(options.url); // 获取目标纯路径
// 目标是首页则直接放行(不管其他条件)
if (targetUrl === HOME_PAGE_FULL_URL || targetUrl === HOME_PAGE_SHORT_URL) {
return;
}
//console.log('url路径:',options.url)
// 白名单判断(兼容带参数URL)
if (NO_PHONE_BIND_WHITE_LIST.includes(getPureUrl(options.url))) return;
//console.log('拦截 switchTab 接口(手机绑定校验):', options);
// 放行条件:已绑定手机 / 已在绑手机页 / 正在导航中
if (userState.phone || getCurrentPagePath() === BIND_PHONE_PAGE_ROUTE || lock.isPhoneSwitching || lock.isLoginSuccessTempPass) {
return;
}
lock.isPhoneSwitching = true; // 上锁
// 弹框提示绑定手机
uni.showModal({
title: '提示',
content: '根据国家法律规定,请先绑定实名手机号',
confirmText: '去绑定',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
// 异步跳转绑手机页面(switchTab不能直接跳非tab页,用navigateTo)
setTimeout(() => {
uni.navigateTo({
url: BIND_PHONE_PAGE_URL,
complete: () => {
lock.isPhoneSwitching = false; // 释放导航锁
}
});
}, 300);
} else {
// 用户取消绑定,释放导航锁
lock.isPhoneSwitching = false;
}
},
fail: () => {
// 弹框异常,兜底释放锁
lock.isPhoneSwitching = false;
}
});
// 超时兜底释放锁,防止弹框/跳转中断导致锁残留
setTimeout(()=>{
if(lock.isPhoneSwitching){
lock.isPhoneSwitching = false
}
},1000)
// 返回false阻止原switchTab执行
return false;
},
} as AddInterceptorOptions;
export {
phoneBindNavigateToInterceptor,
phoneBindSwitchTabInterceptor
};