shuishen
2025-10-11 3fc27febccd04e2fcffbd2cdd16d2daafd0b3ca3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import {
  ERROR404_PATH,
  isPathExists,
  LOGIN_PATH,
  removeQueryString,
  routes
} from "@/router"
import {useUserStore} from "@/store/index.js";
 
// 白名单路由
const whiteList = ["/"]
routes.forEach(item => {
  if (item.needLogin !== true) {
    whiteList.push(item.path)
  }
})
 
/**
 * 权限校验
 * @param {string} path
 * @returns {boolean} 是否有权限
 */
export function hasPerm (path = "") {
  if (!isPathExists(path) && path !== "/") {
    uni.redirectTo({
      url: ERROR404_PATH
    })
    return false
  }
  // 在白名单中或有token,直接放行
  const hasPermission = whiteList.includes(removeQueryString(path)) || useUserStore().$state.userInfo.access_token
  if (!hasPermission) {
    // 将用户的目标路径传递过去,这样可以实现用户登录之后,直接跳转到目标页面
    uni.redirectTo({
      url: `${LOGIN_PATH}?redirect=${encodeURIComponent(path)}`
    })
  }
  return hasPermission
}
 
function setupPermission () {
  // 注意:拦截uni.switchTab本身没有问题。但是在微信小程序端点击tabbar的底层逻辑并不是触发uni.switchTab。
  // 所以误认为拦截无效,此类场景的解决方案是在tabbar页面的页面生命周期onShow中处理。
  ;["navigateTo", "redirectTo", "reLaunch", "switchTab"].forEach(item => {
    // https://uniapp.dcloud.net.cn/api/interceptor.html
    uni.addInterceptor(item, {
      // 页面跳转前进行拦截, invoke根据返回值进行判断是否继续执行跳转
      invoke (args) {
        // args为所拦截api中的参数,比如拦截的是uni.redirectTo(OBJECT),则args对应的是OBJECT参数
        return hasPerm(args.url)
      }
    })
  })
}
 
export default setupPermission