尚硅谷在线教育项目权限管理模块中bug的解决

文章的原文链接
https://www.qiwu.ga/archives/gulibug

在线教育项目后台系统权限管理模块bug修复

这次的问题有这几点:

  1. 树型表格不能加载: 想用树型表格来加载权限列表但是死活不能展开也找不到按钮, 确认了api已经返回了正确的Json数据.

  2. 复选框全选与单选的对应效果不匹配: 用户角色分配功能区, 在为用户分配角色的时候发现勾选全选复选框之后剩下的复选框没有被选中的效果; 反之, 其余复选框全部勾选后,全选复选框没有选中效果.

  3. 用户登录系统选左侧菜单重复加载

  4. 用户使用非超级管理员身份登录不能显示左侧菜单: 确认是api返回数据中"data"属性为空.

1. 树型表格不能加载的解决

ElementUI版本太低需要升级

npm uninstall element-ui -S
npm install element-ui -S

2. 复选框Bug的解决

本项目来源于B站项目, 项目来源: 整合SpringSecurity

建议,可以把data()中绑定的isIndeterminate: false初始化为这样,默认什么都不选中. 否则在没有任何复选框被选中情况下全选复选框默认是"-".

在这里插入图片描述

ps.你们的代码可能全是Cities什么城市有关的变量,我这里为了看着舒服我自行修改了变量, 变成Items相关的变量.

  1. 全选复选框:
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>

indeterminate : false 不会选中; true 显示"-"表示未全选.
v-model="checkAll" : 双向绑定数据,判断全选复选框是否勾选.
@change="handleCheckAllChange" : 事件监听, 一旦用户点击选框就会触发事件.

  1. 复选框列表
<el-checkbox-group v-model="checkedItems" @change="handleCheckedItemsChange">
        <el-checkbox v-for="item in items" :label="item.id" :key="item.id">{
   
   {item.roleName}}</el-checkbox>
</el-checkbox-group>

v-model="checkedItems" : 已经被选择的复选框列表.
@change="handleCheckedItemsChange" : 勾选复选框的触发事件.

bug位置–1

在这里插入图片描述

修复后代码

handleCheckAllChange(val) {
        //console.log('全选按钮勾选后' + val);
        this.checkedItems = val ? this.getJsonToList(this.items,"id") : [];
        //console.log(this.checkedItems);
        this.isIndeterminate = false;
      },

这里使用一个已提供的功能函数, 从角色Json数据中取出id,组合成字符数组.因为this.checkedItems需要是一个id字符数组才能被识别那些复选框被选中, 大概是因为复选框的label值设置为了id.

这里修复了以后就可以保证,全选复选框勾选之后,其余的复选框都自动被勾选.

bug位置–2

在这里插入图片描述

添加代码,结果如下:

getById(userId){
          userApi.getAssign(userId).then(response => {
              var jsonObj = response.data.assignRoles
              this.checkedItems = this.getJsonToList(jsonObj,"id")
              this.items = response.data.allRolesList
              this.isIndeterminate = this.checkedItems.length > 0 && this.checkedItems.length < this.items.length;
              this.checkAll = this.checkedItems.length === this.items.length;
	})
},

最后面添加两行代码, 设置isIndeterminate有复选框选中的时候全选复选框会变成"-". 判断checkAll是否为true,一旦全部子复选框被勾选,全选复选框就会自动变成.

这里修改完成以后就保证了自复选框全选后,全选复选框能显示勾选.

自此, 复选框有关的bug应该解决完毕, 如果其他功能部分的复选框有问题按此修改即可!

补充说明一个细节

getJsonToList(json,key){
    //把JSON字符串转成对象
    var list = JSON.parse(JSON.stringify(json));
    //var list = JSON.parse(json)
    var strText = []
    //遍历这个集合对象,获取key的值
    for(var i = 0; i < list.length; i++){
        strText.push(list[i][key])
    }
    return strText;
},

这段代码的意思是把json数据转成string再转成array对象,这样就可以遍历这个返回的数据取出其中的每相属性进行操作,这个操作很值得学习!

3. 左侧菜单重复加载的解决办法

这个很容易解决. 因为使用了动态路由,所以到 root 文件夹的 index.js 文件下把原来的 export const asyncRoutes = [...我们开始编写的静态路由] 修改成export const asyncRoutes = [],即直接让它初始化为一个空数组. 因为路由规则要根据用户角色权限从后台api获取.

4. 用户使用非超级管理员身份登录不能显示左侧菜单解决办法

在浏览器的控制台中可以发现, 使用其他用户登录的时候, getMenu方法返回的data"permissionList"属性值是空的. 很容易就把问题定位到了后台的 getMenu 接口(请求url:/admin/acl/index/menu).

首先从控制台我们可以发现这个接口执行的一个sql语句

select
    p.id,
    p.pid,
    p.name,
    p.type,
    p.permission_value,
    path,
    p.component,
    p.icon,
    p.status,
    p.is_deleted,
    p.gmt_create,
    p.gmt_modified
from
    acl_user_role ur
        inner join
    acl_role_permission rp
    on rp.role_id = ur.role_id
        inner join
    acl_permission p
    on p.id = rp.permission_id
where
        ur.user_id = '2'
  and ur.is_deleted = 0
  and rp.is_deleted = 0
  and p.is_deleted = 0

我们单独执行这条sql发现是有返回值的

在这里插入图片描述

那这就很好办了,排除了数据本身的问题. 这样问题基本就出在了数据的整合上, 因为我们这里要返回到前端的数据需要自行拼装成树型结构, 后台的很多方法都已经写好了逻辑也不是很复杂.

通过断点输出调试,发现存在bug的方法在于这个方法,位于PermissionServiceImpl.java文件下:

在这里插入图片描述

通过分别输出selectPermissionList, permissionList, result 发现数据丢失从permissionList开始.

接着我们把问题聚焦于

PermissionHelper.bulid(selectPermissionList);

的build的方法, 其中代码如下

在这里插入图片描述

这是一个递归构造子树的逻辑, 根节点是pid为0的权限, 查看数据库以下就发现是一条默认name为"全部数据"的数据项. 然而, 我们在开始的sql查询中没有把他查询出来. 但这一个数据项是一个通用项,是全部菜单权限的根节点,所以我们可以手动对其进行添加.
注意修改的代码在PermissionServiceImpl.java文件下

    @Override
    public List<JSONObject> selectPermissionByUserId(String userId) {
    
    
        List<Permission> selectPermissionList = null;
        if(this.isSysAdmin(userId)) {
    
    
            //如果是超级管理员,获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
        } else {
    
    
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
            QueryWrapper<Permission> wrapper = new QueryWrapper<>();
            wrapper.eq("id",1);
            selectPermissionList.add(baseMapper.selectOne(wrapper));
        }

        List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
        List<JSONObject> result = MemuHelper.bulid(permissionList);
        System.out.println(result);
        return result;
    }

添加的3行代码是:

QueryWrapper<Permission> wrapper = new QueryWrapper<>();
wrapper.eq("id",1);
selectPermissionList.add(baseMapper.selectOne(wrapper));

我们查询出这个通用根,把它加入到权限列表中即可, 随后使用子树构造的方法就可以构造出路由菜单来了.

猜你喜欢

转载自blog.csdn.net/weixin_38708854/article/details/108025324