283 lines
7.4 KiB
JavaScript
283 lines
7.4 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;
|
||
}
|
||
|
||
// 移除路由层面的登录拦截
|
||
// 允许用户浏览所有页面,只在需要执行特定操作时才要求登录
|
||
// 登录检查应该在具体的业务操作中进行(如抽奖、下单等)
|
||
|
||
// 根据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,
|
||
requireLogin,
|
||
isLogin
|
||
};
|
||
|
||
/**
|
||
* 检查登录状态,未登录则跳转登录页
|
||
* 用于需要登录才能执行的操作(如抽奖、下单等)
|
||
* @param {String} message 提示消息,可选
|
||
* @returns {Boolean} true表示已登录,false表示未登录(会跳转登录页)
|
||
*/
|
||
export function requireLogin(message = '请先登录') {
|
||
if (isLogin()) {
|
||
return true;
|
||
}
|
||
|
||
// 保存当前页面用于登录后跳转
|
||
const pages = getCurrentPages();
|
||
const currentPage = pages[pages.length - 1];
|
||
if (currentPage) {
|
||
const currentRoute = currentPage.route;
|
||
const currentParams = currentPage.options || {};
|
||
|
||
if (currentRoute && currentRoute !== 'pages/user/login') {
|
||
let redirectPath = '/' + currentRoute;
|
||
if (Object.keys(currentParams).length > 0) {
|
||
const paramString = Object.keys(currentParams)
|
||
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(currentParams[key])}`)
|
||
.join('&');
|
||
redirectPath += '?' + paramString;
|
||
}
|
||
uni.setStorageSync('redirect', redirectPath);
|
||
}
|
||
}
|
||
|
||
// 显示提示
|
||
uni.showToast({
|
||
title: message,
|
||
icon: 'none'
|
||
});
|
||
|
||
// 跳转登录页
|
||
setTimeout(() => {
|
||
uni.navigateTo({
|
||
url: '/pages/user/login'
|
||
});
|
||
}, 100);
|
||
|
||
return false;
|
||
}
|