描述:
在字典类型从表中字典类型跳转到详情的字典数据时跳到了404
解决过程:
由于我的id统一是用GUID,所以想到了路由表相关路由的正则校验,若依是int类型,我直接删掉了,改了之后还是跳404
后面想是路由表权限校验问题,又注释掉了权限,结果还是不行
传空数组和直接注释都试过,后面问gpt,还有路由没加进路由表的情况,所以想到了动态路由添加那
解决:
首先要熟悉一下这类路由跳转的大致逻辑:
大致逻辑:
1.在路由表定义相关的路由:
//...\src\router\index.js
export const dynamicRoutes = [
...
{
path: '/system/dict-data',
component: Layout,
hidden: true,
permissions: ['system:dict:list'],
children: [
{
path: 'index/:id',
component: () => import('@/views/system/dict/data'),
name: 'Data',
meta: { title: '字典数据', activeMenu: '/system/dict' }
}
]
}
...
2.路由守卫调用方法筛掉不合适的路由
...\src\permission.js -> ...\src\store\modules\permission.js
router.beforeEach() -> GenerateRoutes()->filterDynamicRoutes()
filterDynamicRoutes()相关介绍:
// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
const res = []
routes.forEach(route => {
//按权限验证
if (route.permissions) {//路由要有权限标识,及用户对应的角色权限里面也要对应有
if (auth.hasPermiOr(route.permissions)) {
res.push(route)
}
} else if (route.roles) {//按角色验证
if (auth.hasRoleOr(route.roles)) {
res.push(route)
}
}
})
return res
}
为什么需要分开:
-
灵活性: 有些场景下,系统可能既需要粗粒度的角色控制,也需要细粒度的权限控制。通过分别控制权限和角色,能够更灵活地定义不同用户的访问规则。
-
复用性: 某些权限可能跨多个角色存在,例如“编辑”权限可能存在于管理员和编辑者角色中。通过使用权限系统,可以避免重复定义每个角色的具体操作权限。
-
分层管理: 在权限控制系统中,角色一般用于管理一大类用户的访问能力,而权限则用于更加细致地控制具体功能的访问。这样,系统既可以通过角色来赋予用户权限,也可以通过单独的权限控制一些细节操作。
- 角色验证: 例如,
admin
角色可以访问管理员界面,但普通用户不能访问。 - 权限验证: 即使同为
admin
角色,有些管理员可能只具备“查看”权限,而另一些管理员具备“编辑”或“删除”权限。
3.dict.vue展示与跳转
//...\src\views\system\dict\index.vue
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<router-link :to="'/system/dict-data/index/' + scope.row.id" class="link-type">
<span>{{ scope.row.dictType }}</span>
</router-link>
</template>
</el-table-column>
路由会根据'/system/dict-data/index/' + scope.row.id生成的链接跟添加进路由表的路由(1中准备的)对比,符合的话会直接跳到路由相应的path。
router-link中to的链接要和路由中的path+children.path对应上
原因
我这跳转到404的原因是我的后端没穿相应的权限过来,导致筛路由的时候(filterDynamicRoutes())因为没有权限没把路由加进路由表。所以对比时生成的链接对了,但是找不到该路由(/system/dict-data),跳到了404。
解决:
把相应的路由加进路由表就行,即把相应的权限给传给前端。通过filterDynamicRoutes()的筛选
//...\src\store\modules\user.js
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
//根据角色获取相应权限,由token判断用户所属角色
getInfo().then(res => {
const user = res.data
const avatar = (user.avatarUrl == "" || user.avatarUrl == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatarUrl;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_ID', user.userId)
commit('SET_NAME', user.userName)
commit('SET_AVATAR', avatar)
resolve(res)
}).catch(error => {
reject(error)
})
})
},
....
//请求方法在...\src\api\login.js
// 获取用户详细信息
export function getInfo() {
return request({
headers: {
isToken: true
},
url: '/api/Auth/GetUserInfo',
method: 'get'
})
}
后端把这仨传完整:
对权限相关改造有兴趣可以看一下这个:
若依 根据角色权限 动态添加路由 学习-CSDN博客
总结
主要还是对若依路由的添加过程不太熟悉,排查的时候都没想到这个。