4.9 KiB
4.9 KiB
路由和权限问题修复报告
问题描述
在登录后出现了两个关键问题:
-
权限路由生成错误:
TypeError: Cannot read properties of null (reading 'replace') at capitalizeFirstLetter (permission.js:100:21) -
无限重定向问题:
[Vue Router warn]: Detected a possibly infinite redirection in a navigation guard when going from "/login" to "/shipping/loadingOrder"
根本原因分析
1. capitalizeFirstLetter 函数错误
- 原因:菜单数据中的
routeUrl字段可能为null或undefined - 影响:导致权限路由生成失败,系统无法正常加载
2. 无限重定向问题
- 原因:路由守卫和登录后的导航逻辑产生冲突
- 影响:用户无法正常进入系统,页面不断重定向
修复方案
1. 修复 capitalizeFirstLetter 函数
文件:src/store/permission.js
修复前:
function capitalizeFirstLetter(string) {
string = string.replace('/', '');
return string.charAt(0).toUpperCase() + string.toLowerCase().slice(1);
}
修复后:
function capitalizeFirstLetter(string) {
// 处理 null 或 undefined 值
if (!string || typeof string !== 'string') {
console.warn('capitalizeFirstLetter: Invalid string input:', string);
return 'Unknown';
}
string = string.replace('/', '');
return string.charAt(0).toUpperCase() + string.toLowerCase().slice(1);
}
2. 改进菜单数据处理
修复前:
menuList = menuList.map((item) => {
return {
name: capitalizeFirstLetter(item.routeUrl),
path: item.routeUrl,
// ...
};
});
修复后:
menuList = menuList.map((item) => {
// 确保 routeUrl 存在且不为空
const routeUrl = item.routeUrl || item.pageUrl || '';
return {
name: capitalizeFirstLetter(routeUrl),
path: routeUrl,
// ...
};
});
3. 修复登录导航逻辑
文件:src/views/login.vue
修复前:
const generateRoutes = () => {
getUserMenu().then((ret) => {
// 复杂的 Promise 链和错误处理
router.push({ path: targetPath }).catch((error) => {
router.push({ path: '/shipping/loadingOrder' }).catch(() => {
router.push({ path: '/' });
});
});
});
};
修复后:
const generateRoutes = async () => {
try {
const ret = await getUserMenu();
// 简化的导航逻辑
try {
await router.push({ path: targetPath });
} catch (error) {
await router.push({ path: '/' });
}
} catch (error) {
await router.push({ path: '/' });
}
};
4. 改进路由守卫错误处理
文件:src/permission.js
修复前:
usePermissionStore()
.generateRoutes()
.then((accessRoutes) => {
// 处理成功情况
});
修复后:
usePermissionStore()
.generateRoutes()
.then((accessRoutes) => {
// 处理成功情况
})
.catch((error) => {
console.error('Failed to generate routes:', error);
next({ path: '/', replace: true });
});
修复效果
✅ 解决的问题
-
权限路由生成:
- 不再因为 null 值导致崩溃
- 能够正确处理所有菜单数据
- 提供详细的调试信息
-
导航稳定性:
- 消除了无限重定向问题
- 简化了错误处理逻辑
- 提供了更好的降级方案
-
用户体验:
- 登录后能够正常进入系统
- 超级管理员正确跳转到系统管理页面
- 普通用户跳转到有权限的菜单页面
🔧 技术改进
-
错误处理:
- 添加了完整的 try-catch 错误处理
- 提供了详细的错误日志
- 实现了优雅的降级方案
-
代码质量:
- 使用 async/await 替代复杂的 Promise 链
- 改进了函数的可读性和维护性
- 添加了必要的类型检查
-
调试支持:
- 增加了详细的控制台日志
- 提供了清晰的错误信息
- 便于问题排查和调试
测试建议
-
登录测试:
- 测试超级管理员登录
- 测试普通用户登录
- 测试无权限用户登录
-
导航测试:
- 验证页面跳转是否正确
- 检查是否还有重定向问题
- 确认错误处理是否有效
-
权限测试:
- 验证菜单权限是否正确加载
- 检查权限按钮是否正常显示
- 确认权限分配功能是否正常
相关文件
src/store/permission.js- 权限存储和路由生成src/views/login.vue- 登录页面和导航逻辑src/permission.js- 路由守卫src/directive/permission/hasPermi.js- 权限指令
修复完成后,系统应该能够正常处理登录和权限管理功能。