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