物联网问题解决,只差最后测试完善
This commit is contained in:
317
pc-cattle-transportation/MENU_PERMISSION_PAGE_FIX_REPORT.md
Normal file
317
pc-cattle-transportation/MENU_PERMISSION_PAGE_FIX_REPORT.md
Normal file
@@ -0,0 +1,317 @@
|
||||
# 菜单权限管理页面修复报告
|
||||
|
||||
## 问题描述
|
||||
|
||||
用户反映:**菜单权限管理**功能页面只需要对于菜单的隐藏管理,不需要按钮的管理。按钮的管理是操作权限的内容。
|
||||
|
||||
从图片可以看出,当前的"菜单权限管理"页面确实包含了按钮权限的管理,包括:
|
||||
- "创建装车订单"、"编辑"、"删除"、"装车"等操作按钮
|
||||
- 提示文字写着"勾选菜单和按钮后"
|
||||
- 这些按钮权限的复选框可以被勾选或取消勾选
|
||||
|
||||
## 问题根本原因
|
||||
|
||||
### 1. 权限类型混淆
|
||||
|
||||
当前的"菜单权限管理"页面将菜单权限和按钮权限混淆了:
|
||||
|
||||
- **菜单权限**:应该只包含菜单项(type=0,1),用于控制左侧菜单栏的显示/隐藏
|
||||
- **按钮权限**:应该包含操作按钮(type=2),用于控制页面内按钮的显示/隐藏
|
||||
|
||||
### 2. 页面功能不明确
|
||||
|
||||
**文件**:`pc-cattle-transportation/src/views/permission/menuPermission.vue`
|
||||
|
||||
**问题**:
|
||||
- 第77行提示文字:"勾选菜单和按钮后,该用户登录系统时可以访问这些菜单页面和执行相应的操作"
|
||||
- 第105-111行显示按钮标签:"按钮"
|
||||
- 第205-220行 `loadMenuTree` 方法加载所有菜单和按钮
|
||||
- 第223-238行 `loadRoleMenus` 方法加载所有权限(包括按钮)
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 1. 修改提示文字
|
||||
|
||||
**修改前**:
|
||||
```html
|
||||
勾选菜单和按钮后,该用户登录系统时可以访问这些菜单页面和执行相应的操作
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```html
|
||||
勾选菜单后,该用户登录系统时可以访问这些菜单页面。按钮权限请在"操作权限管理"页面中设置。
|
||||
```
|
||||
|
||||
### 2. 过滤菜单树,只显示菜单项
|
||||
|
||||
**修改文件**:`pc-cattle-transportation/src/views/permission/menuPermission.vue`
|
||||
|
||||
**修改内容**:
|
||||
```javascript
|
||||
// 加载菜单树(只显示菜单,不显示按钮)
|
||||
const loadMenuTree = async () => {
|
||||
permissionLoading.value = true;
|
||||
try {
|
||||
const res = await getMenuTree();
|
||||
if (res.code === 200) {
|
||||
// 过滤掉按钮权限(type=2),只保留菜单(type=0,1)
|
||||
const filteredTree = filterMenuTree(res.data || []);
|
||||
menuTree.value = filteredTree;
|
||||
console.log('=== 菜单权限管理 - 过滤后的菜单树 ===', filteredTree);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载菜单树失败:', error);
|
||||
ElMessage.error('加载菜单树失败');
|
||||
} finally {
|
||||
permissionLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 过滤菜单树,只保留菜单项(type=0,1),移除按钮(type=2)
|
||||
const filterMenuTree = (tree) => {
|
||||
return tree.map(node => {
|
||||
const filteredNode = { ...node };
|
||||
|
||||
// 如果当前节点是按钮(type=2),返回null(会被过滤掉)
|
||||
if (node.type === 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果有子节点,递归过滤
|
||||
if (node.children && node.children.length > 0) {
|
||||
const filteredChildren = filterMenuTree(node.children).filter(child => child !== null);
|
||||
filteredNode.children = filteredChildren;
|
||||
}
|
||||
|
||||
return filteredNode;
|
||||
}).filter(node => node !== null);
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 过滤菜单权限,只加载菜单权限
|
||||
|
||||
**修改内容**:
|
||||
```javascript
|
||||
// 加载角色已分配的菜单(只加载菜单权限,不加载按钮权限)
|
||||
const loadRoleMenus = async (roleId) => {
|
||||
try {
|
||||
const res = await getRoleMenuIds(roleId);
|
||||
if (res.code === 200) {
|
||||
const allMenuIds = res.data || [];
|
||||
|
||||
// 过滤掉按钮权限,只保留菜单权限
|
||||
const menuOnlyIds = await filterMenuOnlyIds(allMenuIds);
|
||||
checkedMenuIds.value = menuOnlyIds;
|
||||
|
||||
console.log('=== 菜单权限管理 - 过滤后的菜单权限 ===', {
|
||||
allMenuIds: allMenuIds,
|
||||
menuOnlyIds: menuOnlyIds
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
if (menuTreeRef.value) {
|
||||
menuTreeRef.value.setCheckedKeys(checkedMenuIds.value);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载角色菜单失败:', error);
|
||||
ElMessage.error('加载角色菜单失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 过滤菜单ID列表,只保留菜单项(type=0,1),移除按钮(type=2)
|
||||
const filterMenuOnlyIds = async (menuIds) => {
|
||||
try {
|
||||
// 获取所有菜单信息
|
||||
const menuListRes = await getMenuList();
|
||||
if (menuListRes.code !== 200) {
|
||||
return menuIds; // 如果获取失败,返回原始列表
|
||||
}
|
||||
|
||||
const allMenus = menuListRes.data || [];
|
||||
const menuMap = new Map(allMenus.map(menu => [menu.id, menu]));
|
||||
|
||||
// 过滤掉按钮权限
|
||||
const menuOnlyIds = menuIds.filter(id => {
|
||||
const menu = menuMap.get(id);
|
||||
return menu && menu.type !== 2; // 只保留菜单项(type=0,1)
|
||||
});
|
||||
|
||||
return menuOnlyIds;
|
||||
} catch (error) {
|
||||
console.error('过滤菜单权限失败:', error);
|
||||
return menuIds; // 如果过滤失败,返回原始列表
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 4. 修改保存逻辑,只保存菜单权限
|
||||
|
||||
**修改内容**:
|
||||
```javascript
|
||||
// 保存菜单权限(只保存菜单权限,不保存按钮权限)
|
||||
const handleSaveMenuPermissions = async () => {
|
||||
if (!currentRole.value) {
|
||||
ElMessage.warning('请先选择用户');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取选中的节点(包括半选中的父节点)
|
||||
const checkedKeys = menuTreeRef.value.getCheckedKeys();
|
||||
const halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys();
|
||||
const allKeys = [...checkedKeys, ...halfCheckedKeys];
|
||||
|
||||
// 过滤掉按钮权限,只保留菜单权限
|
||||
const menuOnlyIds = await filterMenuOnlyIds(allKeys);
|
||||
|
||||
console.log('=== 保存菜单权限 ===', {
|
||||
user: currentRole.value,
|
||||
allKeys: allKeys,
|
||||
menuOnlyIds: menuOnlyIds
|
||||
});
|
||||
|
||||
saveLoading.value = true;
|
||||
try {
|
||||
const res = await assignRoleMenus({
|
||||
roleId: currentRole.value.roleId,
|
||||
menuIds: menuOnlyIds, // 只保存菜单权限
|
||||
});
|
||||
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(`菜单权限保存成功,共保存 ${menuOnlyIds.length} 个菜单权限`);
|
||||
} else {
|
||||
ElMessage.error(res.msg || '保存失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存菜单权限失败:', error);
|
||||
ElMessage.error('保存失败');
|
||||
} finally {
|
||||
saveLoading.value = false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 5. 修改一键分配功能,只分配菜单权限
|
||||
|
||||
**修改内容**:
|
||||
```javascript
|
||||
// 一键分配全部菜单权限(只分配菜单权限,不分配按钮权限)
|
||||
const handleQuickAssignAll = async () => {
|
||||
// ... 确认对话框修改为只分配菜单权限
|
||||
|
||||
// 获取所有菜单
|
||||
const menuListRes = await getMenuList();
|
||||
if (menuListRes.code !== 200) {
|
||||
throw new Error('获取菜单列表失败');
|
||||
}
|
||||
|
||||
const allMenus = menuListRes.data || [];
|
||||
|
||||
// 过滤掉按钮权限,只保留菜单权限
|
||||
const menuOnlyMenus = allMenus.filter(menu => menu.type !== 2);
|
||||
const menuOnlyIds = menuOnlyMenus.map(menu => menu.id);
|
||||
|
||||
console.log('=== 一键分配全部菜单权限 ===', {
|
||||
user: currentRole.value,
|
||||
totalMenus: allMenus.length,
|
||||
menuOnlyMenus: menuOnlyMenus.length,
|
||||
menuOnlyIds: menuOnlyIds
|
||||
});
|
||||
|
||||
// 分配所有菜单权限
|
||||
const res = await assignRoleMenus({
|
||||
roleId: currentRole.value.roleId,
|
||||
menuIds: menuOnlyIds,
|
||||
});
|
||||
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(`成功为用户 ${currentRole.value.name} 分配了 ${menuOnlyIds.length} 个菜单权限`);
|
||||
|
||||
// 重新加载权限显示
|
||||
await loadRoleMenus(currentRole.value.roleId);
|
||||
} else {
|
||||
ElMessage.error(res.msg || '分配失败');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 6. 修改按钮文字
|
||||
|
||||
**修改内容**:
|
||||
```html
|
||||
<!-- 修改前 -->
|
||||
一键分配全部权限
|
||||
|
||||
<!-- 修改后 -->
|
||||
一键分配全部菜单权限
|
||||
```
|
||||
|
||||
## 修复效果
|
||||
|
||||
### 修复前
|
||||
- ❌ 菜单权限管理页面包含按钮权限
|
||||
- ❌ 用户可以勾选/取消勾选按钮权限
|
||||
- ❌ 提示文字混淆了菜单和按钮权限
|
||||
- ❌ 保存时会保存按钮权限
|
||||
|
||||
### 修复后
|
||||
- ✅ 菜单权限管理页面只显示菜单项
|
||||
- ✅ 用户只能管理菜单权限,不能管理按钮权限
|
||||
- ✅ 提示文字明确说明菜单权限和按钮权限的区别
|
||||
- ✅ 保存时只保存菜单权限
|
||||
- ✅ 按钮权限管理在"操作权限管理"页面中
|
||||
|
||||
## 权限分离逻辑
|
||||
|
||||
### 菜单权限管理页面
|
||||
```
|
||||
用户选择 → 加载菜单树(过滤掉按钮) → 显示菜单项 → 保存菜单权限
|
||||
```
|
||||
|
||||
### 操作权限管理页面
|
||||
```
|
||||
用户选择 → 加载权限树(包含按钮) → 显示操作按钮 → 保存操作权限
|
||||
```
|
||||
|
||||
## 权限类型说明
|
||||
|
||||
### 菜单类型(type字段)
|
||||
- **type=0**:目录(如"系统管理")
|
||||
- **type=1**:菜单(如"装车订单")
|
||||
- **type=2**:按钮(如"编辑"、"删除")
|
||||
|
||||
### 权限管理范围
|
||||
- **菜单权限管理**:只管理 type=0,1 的项目
|
||||
- **操作权限管理**:管理所有类型(type=0,1,2)的项目
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 测试步骤
|
||||
1. **清除浏览器缓存**
|
||||
2. **访问"菜单权限管理"页面**
|
||||
3. **选择用户,检查权限树**
|
||||
4. **验证只显示菜单项,不显示按钮**
|
||||
5. **保存权限,验证只保存菜单权限**
|
||||
|
||||
### 预期结果
|
||||
- **菜单权限管理页面**:只显示菜单项(type=0,1),不显示按钮(type=2)
|
||||
- **操作权限管理页面**:显示所有权限(包括按钮)
|
||||
- **权限分离**:菜单权限和按钮权限独立管理
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `pc-cattle-transportation/src/views/permission/menuPermission.vue` - 菜单权限管理页面
|
||||
- `pc-cattle-transportation/src/views/permission/operationPermission.vue` - 操作权限管理页面
|
||||
|
||||
## 总结
|
||||
|
||||
通过过滤菜单树和权限数据,成功将菜单权限管理页面与按钮权限管理分离。修复后的系统能够:
|
||||
|
||||
1. **明确权限范围**:菜单权限管理只管理菜单项
|
||||
2. **清晰的功能分工**:菜单权限和按钮权限独立管理
|
||||
3. **用户友好的提示**:明确说明权限管理的范围
|
||||
4. **数据一致性**:确保只保存相应的权限类型
|
||||
|
||||
**修复状态**:✅ 已完成
|
||||
**测试状态**:⏳ 待验证
|
||||
**部署状态**:✅ 已部署
|
||||
Reference in New Issue
Block a user