项目实战八-系统模块

权限管理分析

  1. 权限管理:对已经认证成功的用户进行授权
    1. 认证成功:比如使用用户名、密码登录成功
    2. 授权:比如赋值相应的操作权限(资源)
  2. 实现方案
    1. 最简单粗暴:用户直接跟资源(权限)挂钩
      1. 设计成3张表:用户表(sys_user)、资源表(sys_resource)、用户资源表(sys_user_resource)

         sys_user
         id      name
         1       jack
         2       rose
                    
         sys_resource
         id      name
         1       用户-查询
         2       用户-添加
         3       用户-删除
                    
         sys_user_resource
         user_id     resource_id
         1           1
         1           3
         2           2
         2           3
        
      2. 缺点:sys_user_resource表中数据冗余

    2. 建议采用:RBAC(Role-base Access Control),以角色为基础的访问控制
      1. 用户跟角色挂钩、角色与资源挂钩,设计成5张表:用户表(sys_user)、角色表(sys_role)、资源(sys_resource)、用户角色表(sys_user_role)、角色资源表(sys_role_resource) 图1
       sys_user
       id      name
       1       jack
       2       rose
              
       sys_role
       id      name
       1       总经理
       2       销售经理
       3       前台
              
       sys_resource
       id      name
       1       用户-查询
       2       用户-添加
       3       用户-删除
              
       sys_role_resource
       role_id     resource_id
       1           1
       1           2
       1           3
       2           1
       2           3
       3           1
              
       sys_user_role
       user_id     role_id
       1           1
       2           2
       2           3
      

初始化各个层的类

  1. 在EasyCode-MybatisCodeHepler中新增erqVo模板、vo模板
  2. 同时选中sys_xxx的5张表,右击,通过EasyCode-MybatisCodeHepler生成对应层的类
  3. 简单改造各个层
    1. 删除SysUserRoleController、SysRoleResourceController、SysRoleResourceReqVo、SysUserRoleReqVo
    2. vo/req/save下面的xxxreqvo,添加后台校验的注解字段

       SysResourceReqVo
       SysRoleReqVo
       SysUserReqVo
      
    3. vo/list下面的返回值xxxVo

       //资源列表
       SysResourceVo
       //角色列表
       SysRoleVo
       //用户列表
       SysUserVo
      
    4. po包下SysRoleResource、SysUserRole添加注解外键关联

       @Data
       public class SysUserRole {
           /**
           * 角色id
           */
           @ForeignField(SysRole.class)
           private Short roleId;
           /**
           * 用户id
           */
           @ForeignField(SysUser.class)
           private Integer userId;
       }
              
       @Data
       public class SysRoleResource {
           /**
           * 角色id
           */
           @ForeignField(SysRole.class)
           private Short roleId;
           /**
           * 资源id
           */
           @ForeignField(SysResource.class)
           private Short resourceId;
       }
      

用户模块

列表展示功能

  1. vo/req/page下新增模糊查询的的SysUserPageReqVo

     @EqualsAndHashCode(callSuper = true)
     @Data
     public class SysUserPageReqVo extends KeywordPageReqVo {}
    
  2. SysUserController如下:

     @RestController
     @RequestMapping("/sysUsers")
     public class SysUserController extends BaseController<SysUser, SysUserReqVo> {
         @Autowired
         private SysUserService service;
        
         @Override
         protected IService<SysUser> getService() {
             return service;
         }
            
         //分页查询方法
         @GetMapping
         public PageJsonVo<SysUserVo> list(SysUserPageReqVo reqVo) {
        
             return JsonVos.ok(service.list(reqVo));
         }
        
         @Override
         protected Function<SysUserReqVo, SysUser> getFunction() {
             return MapStructs.INSTANCE::reqVo2po;
         }
     }
    
  3. service层

     //SysUserService
     public interface SysUserService extends IService<SysUser> {
     PageVo<SysUserVo> list(SysUserPageReqVo reqVo);}
        
     //SysUserServiceImpl
     @Service
     @Transactional
     public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
         @Override
         @Transactional(readOnly = true)
         public PageVo<SysUserVo> list(SysUserPageReqVo reqVo) {
             //1. 单表查询直接使用MpLambdaQueryWrapper
             MpLambdaQueryWrapper<SysUser> wrapper = new MpLambdaQueryWrapper<>();
             wrapper.like(reqVo.getKeyword(),SysUser::getNickname,SysUser::getUsername);
             wrapper.orderByDesc(SysUser::getId);
             //2. 将查询的po类型结果通过po2vo转化为Vo类型
             return baseMapper.selectPage(new MpPage<>(reqVo),wrapper).buildVo(MapStructs.INSTANCE::po2vo);
         }
     }
    
  4. 运行项目会报错,有以下2个原因
    1. 原因1:MapStructs中没有增加SysUserVo<->SysUser即vo与po之间的转化方式,新增完后,运行项目还会报错
    2. 原因2:po(SysUser)的loginTime属性的类型为:Date,Vo(SysUserVo)的loginTime属性类型为Long
      1. 注意:时间的返回通常是返回给客户端毫秒的时间戳
    3. 解决办法:
      1. 新增转化格式类:

         //com.zh.jk.common.mapStruct
         public class MapStructFormatter {
             //自定义Date2Millis注解
             //必须添加@Qualifier注解,才能作为属性转化器注解
             @Qualifier
             @Target(ElementType.METHOD)
             @Retention(RetentionPolicy.CLASS)
             public @interface Date2Millis {}
                    
             //使用自定义的Date2Millis注解,注解一个方法
             @Date2Millis
             public static Long date2millis(Date date) {
                 if (date == null) return null;
                 //将Date类型转化为毫秒数
                 return date.getTime();
             }
                    
             //自定义Mills2Date注解
             //必须添加@Qualifier注解,才能作为属性转化器注解
             @Qualifier
             @Target(ElementType.METHOD)
             @Retention(RetentionPolicy.CLASS)
             public @interface Mills2Date {}
                    
             //使用自定义的Mills2Date注解,注释一个转化方法
             @Mills2Date
             public static Date millis2date(Long mills) {
                 if (mills == null) return null;
                 //将毫秒数转化为Date类型
                 return new Date(mills);
             }
         }
        
      2. MapStructs中使用

         //com.zh.jk.common.mapStruct
         /**
          * ReqVo -> Po 将客户端传递的ReqVo转化为Vo对象
          * Po -> Vo 通过Mybits-plus到数据库查询的po对象转为Vo对象传递给客户端
          */
         @Mapper(uses = {
                 //指明用哪些格式化器
                 MapStructFormatter.class
         })
         public interface MapStructs {
             MapStructs INSTANCE = Mappers.getMapper(MapStructs.class);
                    
             /**po-vo***/
             DictItemVo po2vo(DictItem po);
             DictTypeVo po2vo(DictType po);
             ExamPlaceVo po2vo(ExamPlace po);
             PlateRegionVo po2vo(PlateRegion po);
             ExamPlaceCourseVo po2vo(ExamPlaceCourse po);
             //由于数据库返回的po对象loginTime字段的类型是Date,返回给客户端的Vo对象是Long类型,因此需要做一个转化
             @Mapping(source = "loginTime",
                     target = "loginTime",
                     //通过什么转化:这里必须传递一个自定义的注解,意思是通过MapStructFormatter类中的Date2Millis注解的方法来转化
                     qualifiedBy = MapStructFormatter.Date2Millis.class)
             SysUserVo po2vo(SysUser po);
             SysRoleVo po2vo(SysRole po);
             SysResourceVo po2vo(SysResource po);
                    
             /**vo-po***/
             DictItem reqVo2po(DictItemReqVo reqVo);
             DictType reqVo2po(DictTypeReqVo reqVo);
             ExamPlace reqVo2po(ExamPlaceReqVo reqVo);
             PlateRegion reqVo2po(PlateRegionReqVo reqVo);
             ExamPlaceCourse reqVo2po(ExamPlaceCourseReqVo reqVo);
             SysUser reqVo2po(SysUserReqVo reqVo);
             SysRole reqVo2po(SysRoleReqVo reqVo);
             SysResource reqVo2po(SysResourceReqVo reqVo);
         }
        
  5. 运行项目,列表页面能够正常展示、关键字搜索

添加用户功能

  1. 点击列表左上角的添加,如下图: 图1

    1. 从上面图中可以看出,保存页面还需要获取到当前系统的所有角色信息
    2. 保存一个用户涉及2张表的保存,一个是用户表,一个是用户角色表
  2. SysRoleController新增获取全部角色的接口,提供给前端即可

     //不分页查询所有角色法
     @GetMapping("/list")
     public DataJsonVo<List<SysRoleVo>> list() {
         List<SysRoleVo> vos = Streams.map(service.list(),MapStructs.INSTANCE::po2vo);
         return JsonVos.ok(vos);
     }
    
  3. SysRoleServiceImpl重写list方法
    1. 本来不需要在SysRoleServiceImpl中写任何东西,因为list()方法本身就是mybatis-plus自带的方法
    2. 但是需要在返回值的数据进行按照一定条件排序,因此要重写mybatis-plus的list()方法

       //重写Mybatis-plus的list方法,内部设置数据的排序方式
       @Override
       @Transactional(readOnly = true)
       public List<SysRole> list() {
           MpLambdaQueryWrapper<SysRole> wrapper = new MpLambdaQueryWrapper<>();
           wrapper.orderByDesc(SysRole::getId);
           return super.list(wrapper);
       }
      
  4. SysUserController新增用户信息保存方法
    1. 注意: 该保存不能直接使用父类BaseController的save,因为保存的是2张表,需要父类的保存方法;而且不能放在controller中,需要放在service层的impl中,因为涉及到事务管理,两张表要么都成功,要么都失败,impl中使用了事务管理@Transactional
    2. 重写父类save接口

       /**
        * 添加、更新保存用户信息,包含用户绑定的角色信息
        * 这里涉及到2张表的操作:用户表、用户角色表
        * */
       //重写父类的save方法
       @Override
       public JsonVo save(@Valid SysUserReqVo reqVo) {
           if (service.saveOrUpdate(reqVo)){
               return JsonVos.ok(CodeMsg.SAVE_OK);
           }else {
               return JsonVos.error(CodeMsg.SAVE_ERROR);
           }
       }
      
    3. SysUserReqVo需要新增roleIds字段

       /**
        * 保存用户时传递的用户绑定的角色ids【多个id之间用逗号,隔开】
        * */
       private String roleIds;
      
  5. service层新增saveOrUpdate方法

     //SysUserService
     boolean saveOrUpdate(SysUserReqVo reqVo);
        
     //SysUserServiceImpl新增
     @Autowired
     private SysUserRoleService userRoleService;
     /**
      * 添加、更新保存用户信息,包含用户绑定的角色信息
      * 这里涉及到2张表的操作:用户表、用户角色表
      * */
     @Override
     public boolean saveOrUpdate(SysUserReqVo reqVo) {
         //转成PO
         SysUser po = MapStructs.INSTANCE.reqVo2po(reqVo);
         //保存用户信息
         //这里的saveOrUpdate,使用的是mybatis-plus自带的方法,添加完会自动生成一个主键id
         //但是如果需要将保存后自动生成的id赋值到po对象的id属性,需要在application.yml配置use-generated-keys: true
         if (!saveOrUpdate(po)) return false;
    
         //保存角色信息
         //拿到选择的角色id
         String roleIdsStr = reqVo.getRoleIds();
         if (Strings.isEmpty(roleIdsStr))  return true;
    
         String[] roleIds = roleIdsStr.split(",");
         List<SysUserRole>  userRoles = new ArrayList<>();
         Integer userId = po.getId();
         //构建SysUserRole的po类型对象数组
         for (String roleId : roleIds) {
             SysUserRole userRole = new SysUserRole();
             userRole.setUserId(userId);
             userRole.setRoleId(Short.parseShort(roleId));
             userRoles.add(userRole);
         }
         //mybatis-plus自带批量保存方法
         return userRoleService.saveBatch(userRoles);
     }
    
    1. application.xml中新增配置

       mybatis-plus:
         # 使用自动生成的key赋值给po的id属性
         configuration:
           use-generated-keys: true
      

编辑用户功能

  1. 点击编辑,展示编辑页面,除了要显示用户的信息外,还需要显示用户所绑定的角色信息
  2. 有2种数据的返回方式:
    1. 返回列表的时候将用户所绑定的角色信息返回,需要在SysUserVo新增绑定角色的字段
    2. 单独提供一个接口通过用户id查询该用户绑定的角色信息,前端点击编辑的时候请求数据
  3. 如果一个用户有n个角色,而且列表有n条数据,选用方式1比较消耗性能,因此选择方式2
  4. SysRoleController新增ids接口

     @GetMapping("/ids")
     public DataJsonVo<List<Short>> ids(Integer userId) {
         return JsonVos.ok(service.listIds(userId));
     }
    
  5. service层(SysRoleService)

     //新增接口
     List<Short> listIds(Integer userId);
        
     //impl新增实现
     //因为需要查询用户角色表,因此需要导入对应的mapper,也可以导入service
     @Autowired
     private SysUserRoleMapper userRoleMapper;
     @Override
     @Transactional(readOnly = true)
     public List<Short> listIds(Integer userId) {
         if (userId == null || userId <= 0) return null;
    
         MpLambdaQueryWrapper<SysUserRole> wrapper = new MpLambdaQueryWrapper<>();
         wrapper.select(SysUserRole::getRoleId);
         wrapper.eq(SysUserRole::getUserId, userId);
    
         List<Object> ids = userRoleMapper.selectObjs(wrapper);
         return Streams.map(ids, (id) -> ((Integer) id).shortValue());
     }
    
  6. 编辑保存也需要改造
    1. SysUserServiceImpl下的saveOrUpdate方法中新增如下代码

       //编辑->保存
       Integer id = reqVo.getId();
       if (id != null && id > 0) { // 如果是做更新
           // 删除当前用户的所有角色信息
           userRoleService.removeByUserId(reqVo.getId());
       }
       //保存角色信息
      
    2. SysUserRole的service层新增

       //新增接口
       boolean removeByUserId(Integer userId);
       //impl新增实现
       @Override
       public boolean removeByUserId(Integer userId) {
           if (userId == null || userId <= 0) return false;
           MpLambdaQueryWrapper<SysUserRole> wrapper = new MpLambdaQueryWrapper<>();
           wrapper.eq(SysUserRole::getUserId, userId);
           return baseMapper.delete(wrapper) > 0;
       }
      

资源模块

图1

  1. 从列表数据查看可知,有三种数据列表,目录数据列表、菜单数据列表、按钮数据列表,可以将这三种数据列表全部放在一张表中即可
  2. 表中数据结构如下

     id  name    uri     permission  type    icon    sn  parent_id
                           
    
    1. uri:点击跳转路径(目录才会有)
    2. permission:目录下的菜单权限(菜单才会有)
    3. type:有三种,目录、菜单、按钮,表示当前数据是哪一类
    4. sn:在当前类中的排序
    5. parent_id: 当前类的父id是什么

列表展示功能

  1. vo/req/page下新增模糊查询的的SysResourcePageReqVo

     @EqualsAndHashCode(callSuper = true)
     @Data
     public class SysResourcePageReqVo extends KeywordPageReqVo {
     }
    
  2. SysResourceController

     @RestController
     @RequestMapping("/sysRoles")
     public class SysResourceController extends BaseController<SysResource, SysResourceReqVo> {
         @Autowired
         private SysResourceService service;
        
         @Override
         protected IService<SysResource> getService() {
             return service;
         }
        
         //不分页全量查询所有数据
         @GetMapping("/list")
         public DataJsonVo<List<SysResourceVo>> list() {
             return JsonVos.ok(Streams.map(service.list(),MapStructs.INSTANCE::po2vo));
         }
         @Override
         protected Function<SysResourceReqVo, SysResource> getFunction() {
             return MapStructs.INSTANCE::reqVo2po;
         }
     }
    
  3. 上面即可完成,返回去的数据是不分页、不分树结构的全量列表数据,由前端自己根据parent_id分析展示树状结构

添加、编辑功能

  1. 在添加、编辑页面,选择父资源时,需要将所有数据,除了按钮类型(按钮不会是父资源,最底层)全部展示,因此需要服务器新增接口
  2. SysResourceController新增api

     //加载父资源:编辑、添加的时候选择父资源类型,而且父资源只有目录跟菜单
     @GetMapping("/listParents")
     public DataJsonVo<List<SysResourceVo>> listParents() {
         return JsonVos.ok(service.listParents());
     }
    
  3. service层

     public interface SysResourceService extends IService<SysResource> {
         List<SysResourceVo> listParents();
     }
        
     @Service
     @Transactional
     public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResource> implements SysResourceService {
         @Override
         @Transactional(readOnly = true)
         public List<SysResourceVo> listParents() {
             MpLambdaQueryWrapper<SysResource> wrapper = new MpLambdaQueryWrapper<>();
             //查找type不能等于2,即没有按钮类型
             wrapper.ne(SysResource::getType, Constants.SysResourceType.BTN);
             //按照type升序,再按照id降序
             wrapper.orderByAsc(SysResource::getType).orderByDesc(SysResource::getId);
             return Streams.map(baseMapper.selectList(wrapper), MapStructs.INSTANCE::po2vo);
         }
     }
    

角色模块

列表展示功能

  1. vo/req/page下新增模糊查询的的SysRolePageReqVo

     @EqualsAndHashCode(callSuper = true)
     @Data
     public class SysRolePageReqVo extends KeywordPageReqVo {
     }
    
  2. SysRoleController

     @RestController
     @RequestMapping("/sysRoles")
     public class SysRoleController extends BaseController<SysRole, SysRoleReqVo> {
         @Autowired
         private SysRoleService service;
        
         @Override
         protected IService<SysRole> getService() {
             return service;
         }
         //分页查询方法
         @GetMapping
         public PageJsonVo<SysRoleVo> list(SysRolePageReqVo reqVo) {
        
             return JsonVos.ok(service.list(reqVo));
         }
        
         @Override
         protected Function<SysRoleReqVo, SysRole> getFunction() {
             return MapStructs.INSTANCE::reqVo2po;
         }
     }
    
  3. service层

     public interface SysRoleService extends IService<SysRole> {
         PageVo<SysRoleVo> list(SysRolePageReqVo reqVo);
     }
        
     @Service
     @Transactional
     public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
        
         @Override
         @Transactional(readOnly = true)
         public PageVo<SysRoleVo> list(SysRolePageReqVo reqVo) {
             //1. 单表查询直接使用MpLambdaQueryWrapper
             MpLambdaQueryWrapper<SysRole> wrapper = new MpLambdaQueryWrapper<>();
             wrapper.like(reqVo.getKeyword(),SysRole::getName);
             wrapper.orderByDesc(SysRole::getId);
             //2. 将查询的po类型结果通过po2vo转化为Vo类型
             return baseMapper.selectPage(new MpPage<>(reqVo),wrapper).buildVo(MapStructs.INSTANCE::po2vo);
         }
     }
    

添加功能

  1. 添加角色页面如下 图1

  2. 分析
    1. 添加页面需要获取项目的所有资源列表,而且资源列表的数据是树状数据

       [
           {
               "id": 1,
               "title": "系统",
               "spread": true,
               "children": [
                   {
                       "id": 5,
                       "title": "用户",
                       "spread": true,
                       "children": [
                           {
                               "id": 21,
                               "title": "查询",
                               "spread": true
                           }
                           ...
                       ]
                   },
                   {
                       "id": 6,
                       "title": "角色",
                       "spread": true,
                       "children": [...]
                       ...
                   }
               ]
           },
           ... 
       ]
      
    2. 点击添加时,要变更2张表:角色列表表、角色资源表

  3. 实现步骤
    1. 新增SysResourceTreeVo,用于返回树状接口数据的Vo

       //com.zh.jk.pojo.vo.list
       @Data
       public class SysResourceTreeVo {
              
           private Short id;
           private String title;
           //默认是否展开
           private boolean spread = true;
           //子资源
           private List<SysResourceTreeVo> children;
       }
      
    2. SysResourceController新增获取树状数据资源接口listTree

       @GetMapping("/listTree")
       public DataJsonVo<List<SysResourceTreeVo>> listTree() {
           return JsonVos.ok(service.listTree());
       }
      
    3. service层

       //SysResourceService
       List<SysResourceTreeVo> listTree();
          
       //SysResourceServiceImpl
       @Override
       @Transactional(readOnly = true)
       public List<SysResourceTreeVo> listTree() {
           // 里面存放的是树状结构的VO(最外层是目录类型的资源对象)
           List<SysResourceTreeVo> vos = new ArrayList<>();
          
           // 存放已经从po转换成功的vo
           //这里巧妙使用hashmap作为集合,将vo的id作为key,vo作为value存储
           Map<Short, SysResourceTreeVo> doneVos = new HashMap<>();
          
           //1. 查询出全量数据
           MpLambdaQueryWrapper<SysResource> wrapper = new MpLambdaQueryWrapper<>();
           //按照类型升序
           wrapper.orderByAsc(SysResource::getType);
           // 里面存放的是从数据库中查出来的PO
           List<SysResource> pos = baseMapper.selectList(wrapper);
          
           //2. 将数据组装成树状结构
           for (SysResource po : pos) {
               // po转vo
               SysResourceTreeVo vo = po2treeVo(po);
          
               // 将vo存放到doneVos中
               doneVos.put(vo.getId(), vo);
          
               Short type = po.getType();
               if (type == Constants.SysResourceType.DIR) { // 目录
                   vos.add(vo);
               } else { // 菜单、按钮
                   // 从doneVos中取出父VO
                   SysResourceTreeVo parentVo = doneVos.get(po.getParentId());
                   List<SysResourceTreeVo> children = parentVo.getChildren();
                   if (children == null) {
                       parentVo.setChildren(children = new ArrayList<>());
                   }
                   children.add(vo);
               }
           }
           return vos;
       }
          
       //手动实现po转vo
       private SysResourceTreeVo po2treeVo(SysResource po) {
           SysResourceTreeVo treeVo = new SysResourceTreeVo();
           treeVo.setId(po.getId());
           treeVo.setTitle(po.getName());
           return treeVo;
       }
      
    4. 新增角色保存SysRoleReqVo模型类

       @Data
       public class SysRoleReqVo {
           /**
           * 主键
           */
           private Short id;
           /**
           * 角色名称
           */
           @NotBlank(message = "名称不能为空")
           private String name;
           //资源id【多个id之间用逗号,隔开】
           private String resourceIds;
       }
      
    5. SysRoleController新增save接口
      1. 重写父类的save方法
       //重写父类save方法,自定义实现保存功能
       @Override
       public JsonVo save(@Valid SysRoleReqVo reqVo) {
           if (service.saveOrUpdate(reqVo)) {
               return JsonVos.ok(CodeMsg.SAVE_OK);
           } else {
               return JsonVos.raise(CodeMsg.SAVE_ERROR);
           }
       }
      
    6. service层

       //SysRoleService
       boolean saveOrUpdate(SysRoleReqVo reqVo);
              
       //SysRoleServiceImpl
       //用于更改角色资源表
       @Autowired
       private SysRoleResourceService roleResourceService;
       @Override
       public boolean saveOrUpdate(SysRoleReqVo reqVo) {
          
           //1. 更新角色表sys_role
           // 转成PO,用于保存角色数据
           SysRole po = MapStructs.INSTANCE.reqVo2po(reqVo);
           // 调用mybaits自封装方法,保存角色信息
           if (!saveOrUpdate(po)) return false;
          
           //2. 更新角色资源表sys_role_resource
           Short id = reqVo.getId();
           // 删除当前角色对应的所有资源信息
           roleResourceService.removeByRoleId(id);
          
           // 保存角色信息
           String resourceIdsStr = reqVo.getResourceIds();
           if (Strings.isEmpty(resourceIdsStr)) return true;
          
           String[] resourceIds = resourceIdsStr.split(",");
           List<SysRoleResource> roleResources = new ArrayList<>();
           Short roleId = po.getId();
           for (String resourceId : resourceIds) { // 构建SysUserRole对象
               SysRoleResource roleResource = new SysRoleResource();
               roleResource.setRoleId(roleId);
               roleResource.setResourceId(Short.parseShort(resourceId));
               roleResources.add(roleResource);
           }
           //调用mybaits自封装方法批量保存
           return roleResourceService.saveBatch(roleResources);
       }
      
    7. 角色资源的service层需要新增删除接口

       //SysRoleResourceService
       boolean removeByRoleId(Short roleId);
       //SysRoleResourceServiceImpl
       @Override
       public boolean removeByRoleId(Short roleId) {
           if (roleId == null || roleId <= 0) return false;
           MpLambdaQueryWrapper<SysRoleResource> wrapper = new MpLambdaQueryWrapper<>();
           wrapper.eq(SysRoleResource::getRoleId, roleId);
           return baseMapper.delete(wrapper) > 0;
       }
      

编辑功能

  1. 用户点击编辑的时候,才会去调用接口
  2. 后台接口只需要返回某个角色选中的资源ids即可,其他由前端自己完成
  3. SysResourceController控制器添加根据角色id获取资源ids接口

     //根据角色id获取设置的资源id
     @GetMapping("/ids")
     public DataJsonVo<List<Short>> ids(Integer roleId) {
         return JsonVos.ok(service.listIds(roleId));
     }
    
  4. service层

     //SysResourceService
     List<Short> listIds(Integer roleId);
        
     //SysResourceServiceImpl
     @Autowired
     private SysRoleResourceMapper roleResourceMapper;
    
     /*通过角色id查询资源ids*/
     @Override
     @Transactional(readOnly = true)
     public List<Short> listIds(Integer roleId) {
         if (roleId == null || roleId <= 0) return null;
    
         //查询sys_role_source表
         MpLambdaQueryWrapper<SysRoleResource> wrapper = new MpLambdaQueryWrapper<>();
         wrapper.select(SysRoleResource::getResourceId);
         wrapper.eq(SysRoleResource::getRoleId, roleId);
    
         List<Object> ids = roleResourceMapper.selectObjs(wrapper);
         return Streams.map(ids, (id) -> ((Integer) id).shortValue());
     }
    
Table of Contents