255 lines
6.6 KiB
JavaScript
255 lines
6.6 KiB
JavaScript
/**
|
||
* 通用路由守卫
|
||
*/
|
||
|
||
import { whiteList } from '@/common/config.js'
|
||
|
||
/**
|
||
* 判断用户是否已登录
|
||
* @returns {Boolean} true表示已登录,false表示未登录
|
||
*/
|
||
function isLogin() {
|
||
// 从本地存储获取用户token或其他登录凭证
|
||
const token = uni.getStorageSync('token');
|
||
return !!token;
|
||
}
|
||
|
||
/**
|
||
* 判断URL是否在白名单中
|
||
* @param {String} url 需要检查的URL
|
||
* @returns {Boolean} 是否在白名单中
|
||
*/
|
||
function isInWhiteList(url) {
|
||
if (!url) return false;
|
||
|
||
// 去除URL开头的斜杠,以便与白名单匹配
|
||
const cleanUrl = url.startsWith('/') ? url.substring(1) : url;
|
||
|
||
// 提取路径部分(不含参数)
|
||
const pathPart = cleanUrl.split('?')[0];
|
||
|
||
// 检查是否在白名单中
|
||
return whiteList.some(item => {
|
||
// 确保白名单项目不带/开头,以实现一致的比较
|
||
const cleanItem = item.startsWith('/') ? item.substring(1) : item;
|
||
return pathPart === cleanItem || pathPart.startsWith(cleanItem + '/') || pathPart.startsWith(cleanItem + '?');
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 返回上一页,如果上一页是登录页则跳过它
|
||
* @returns {Promise} 返回操作结果的Promise
|
||
*/
|
||
export function navigateBack(delta = 1) {
|
||
return new Promise((resolve, reject) => {
|
||
const pages = getCurrentPages();
|
||
|
||
// 如果页面栈不足,直接返回首页
|
||
if (pages.length <= 1) {
|
||
return navigateTo('/pages/shouye/index', {}, 'reLaunch')
|
||
.then(resolve)
|
||
.catch(reject);
|
||
}
|
||
|
||
// 查看前一个页面是否是登录页
|
||
if (pages.length > 1 && pages[pages.length - 2].route === 'pages/user/login') {
|
||
// 如果前一个页面是登录页,则返回两步
|
||
uni.navigateBack({
|
||
delta: 2,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
} else {
|
||
// 正常返回
|
||
uni.navigateBack({
|
||
delta,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 通用路由跳转方法
|
||
* @param {Object} options 跳转配置
|
||
* @param {String} options.url 跳转地址
|
||
* @param {Object} options.params 请求参数,可选
|
||
* @param {String} options.type 跳转方式,可选:navigateTo(默认)、switchTab、redirectTo、reLaunch
|
||
* @returns {Promise} 返回一个Promise对象
|
||
*/
|
||
export function routerTo(options) {
|
||
return new Promise((resolve, reject) => {
|
||
// 处理参数
|
||
let { url, params, type } = options;
|
||
|
||
// 判断url是否存在
|
||
if (!url || url.length === 0) {
|
||
reject('跳转地址不能为空');
|
||
return;
|
||
}
|
||
|
||
// 拼接参数
|
||
if (params && Object.keys(params).length > 0) {
|
||
const queryString = Object.keys(params)
|
||
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
||
.join('&');
|
||
|
||
url += (url.indexOf('?') === -1 ? '?' : '&') + queryString;
|
||
}
|
||
|
||
// 检查是否需要登录
|
||
const needLogin = !isInWhiteList(url);
|
||
|
||
if (needLogin && !isLogin()) {
|
||
// 需要登录但未登录,跳转到登录页面
|
||
// 先保存当前URL用于登录后重定向
|
||
uni.setStorageSync('redirect', url);
|
||
|
||
// 使用navigateTo而非redirectTo,保留页面栈
|
||
uni.navigateTo({
|
||
url: '/pages/user/login',
|
||
success: () => {
|
||
console.log('跳转到登录页面成功,保存的重定向地址:', url);
|
||
},
|
||
fail: (err) => {
|
||
console.error('跳转到登录页面失败:', err);
|
||
reject(err);
|
||
}
|
||
});
|
||
|
||
// 拒绝当前的导航请求
|
||
return reject(new Error('需要登录'));
|
||
}
|
||
|
||
// 根据type选择跳转方式
|
||
if (type) {
|
||
// 指定了跳转方式,直接使用
|
||
switch (type) {
|
||
case 'switchTab':
|
||
uni.switchTab({
|
||
url,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
break;
|
||
case 'redirectTo':
|
||
uni.redirectTo({
|
||
url,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
break;
|
||
case 'reLaunch':
|
||
uni.reLaunch({
|
||
url,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
break;
|
||
case 'navigateTo':
|
||
default:
|
||
uni.navigateTo({
|
||
url,
|
||
success: resolve,
|
||
fail: reject
|
||
});
|
||
break;
|
||
}
|
||
} else {
|
||
// console.log('url',url,params,type,isInWhiteList(url),isLogin());
|
||
|
||
// 未指定跳转方式,先尝试navigateTo,失败后尝试switchTab
|
||
uni.navigateTo({
|
||
url,
|
||
success: resolve,
|
||
fail: (err) => {
|
||
// navigateTo失败,尝试switchTab
|
||
uni.switchTab({
|
||
url,
|
||
success: resolve,
|
||
fail: (switchErr) => {
|
||
// 两种方式都失败,返回错误
|
||
reject(switchErr);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 简化版路由跳转方法
|
||
* @param {String} url 跳转地址
|
||
* @param {Object} params 请求参数,可选
|
||
* @param {String} type 跳转方式,可选
|
||
* @returns {Promise} 返回Promise对象
|
||
*/
|
||
export function navigateTo(url, params = {}, type = '') {
|
||
return routerTo({
|
||
url,
|
||
params,
|
||
type
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 收集白名单路径
|
||
* @param {String} path 需要添加到白名单的路径
|
||
* @returns {Array} 返回更新后的白名单数组
|
||
*/
|
||
export function collectWhitePath(path) {
|
||
// 缓存的键名
|
||
const WHITELIST_CACHE_KEY = 'APP_WHITELIST_PATHS';
|
||
|
||
// 从缓存中获取现有白名单
|
||
let cachedWhitelist = uni.getStorageSync(WHITELIST_CACHE_KEY) || [];
|
||
|
||
// 如果不是数组,则初始化为空数组
|
||
if (!Array.isArray(cachedWhitelist)) {
|
||
cachedWhitelist = [];
|
||
}
|
||
|
||
// 检查路径是否已存在于白名单中
|
||
if (path && path.trim() && !cachedWhitelist.includes(path)) {
|
||
// 添加新路径到白名单
|
||
cachedWhitelist.push(path);
|
||
|
||
// 保存更新后的白名单到缓存
|
||
uni.setStorageSync(WHITELIST_CACHE_KEY, cachedWhitelist);
|
||
|
||
console.log('添加白名单路径成功:', path);
|
||
}
|
||
|
||
return cachedWhitelist;
|
||
}
|
||
|
||
/**
|
||
* 获取已收集的白名单路径
|
||
* @returns {Array} 返回缓存中的白名单数组
|
||
*/
|
||
export function getCollectedWhitePaths() {
|
||
const WHITELIST_CACHE_KEY = 'APP_WHITELIST_PATHS';
|
||
return uni.getStorageSync(WHITELIST_CACHE_KEY) || [];
|
||
}
|
||
|
||
/**
|
||
* 清空已收集的白名单路径
|
||
* @returns {Boolean} 返回操作结果
|
||
*/
|
||
export function clearCollectedWhitePaths() {
|
||
const WHITELIST_CACHE_KEY = 'APP_WHITELIST_PATHS';
|
||
uni.setStorageSync(WHITELIST_CACHE_KEY, []);
|
||
return true;
|
||
}
|
||
|
||
// 更新默认导出
|
||
export default {
|
||
routerTo,
|
||
navigateTo,
|
||
navigateBack,
|
||
collectWhitePath,
|
||
getCollectedWhitePaths,
|
||
clearCollectedWhitePaths
|
||
};
|