day17项目【权限管理】-03 权限管理功能(接口)

01-权限管理需求描述

一、权限管理需求描述

不同角色的用户登录后台管理系统拥有不同的菜单权限与功能权限,权限管理包含三个功能模块:菜单管理、角色管理和用户管理

1、菜单管理

(1)菜单列表:使用树形结构显示菜单列表

(2)添加菜单:点击添加菜单,弹框进行添加

(3)修改菜单

(4)删除菜单

2、角色管理

(1)角色列表:实现角色的条件查询带分页功能

(2)角色添加

(3)角色修改

点击修改按钮

数据回显,进行修改

(4)角色删除

普通删除

批量删除

(5)角色分配菜单

点击分配按钮

给角色分配菜单

3、用户管理

(1)用户列表

(2)用户添加

(3)用户修改

(4)用户删除

普通删除和批量删除

(5)用户分配角色



02-开发权限管理接口

一、创建权限管理服务

1、在service模块下创建子模块service_acls

2、在service_acl模块中引入依赖

<dependencies>

        <dependency>

            <groupId>com.atguigu</groupId>

            <artifactId>spring_security</artifactId>

            <version>0.0.1-SNAPSHOT</version>

        </dependency>

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>fastjson</artifactId>

        </dependency>

    </dependencies>

3、创建权限管理相关的表

4、复制权限管理接口代码

5、复制整合Spring Security代码

(1)在common模块下创建子模块spring_security

6、编写service_acl中的application.properties配置文件

# 服务端口

server.port=8009

# 服务名

spring.application.name=service-acl

# mysql数据库连接

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

spring.datasource.username=root

spring.datasource.password=123456

#返回json的全局时间格式

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

spring.jackson.time-zone=GMT+8


spring.redis.host=127.0.0.1

spring.redis.port=6379

spring.redis.database= 0

spring.redis.timeout=1800000


spring.redis.lettuce.pool.max-active=20

spring.redis.lettuce.pool.max-wait=-1

#最大阻塞等待时间(负数表示没限制)

spring.redis.lettuce.pool.max-idle=5

spring.redis.lettuce.pool.min-idle=0

#最小空闲

#配置mapper xml文件的路径

mybatis-plus.mapper-locations=classpath:com/atguigu/aclservice/mapper/xml/*.xml

# nacos服务地址

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#mybatis日志

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

二、开发权限管理接口

#########递归查询原则:先找到查询的入口,本案例中的入口是一层菜单。############

1、获取所有菜单

(1)PermissionController

@RestController

@RequestMapping("/admin/acl/permission")

//@CrossOrigin

public class PermissionController {

    @Autowired

    private PermissionService permissionService;


    //获取全部菜单

    @ApiOperation(value = "查询所有菜单")

    @GetMapping

    public R indexAllPermission() {

        List<Permission> list =  permissionService.queryAllMenuGuli();

        return R.ok().data("children",list);

    }

}

@RequestMapping("/admin/acl/permission")因此需要过滤。

(2)在Permission实体类添加属性

@ApiModelProperty(value = "层级")

    @TableField(exist = false)

    private Integer level;

    @ApiModelProperty(value = "下级")

    @TableField(exist = false)

    private List children;

    @ApiModelProperty(value = "是否选中")

    @TableField(exist = false)

    private boolean isSelect;

(3)PermissionServiceImpl

//========================递归查询所有菜单================================================

    //获取全部菜单

    @Override

    public List<Permission> queryAllMenuGuli() {

        //1 查询菜单表所有数据

        QueryWrapper<Permission> wrapper = new QueryWrapper<>();

        wrapper.orderByDesc("id");

        List<Permission> permissionList = baseMapper.selectList(wrapper);

        //2 把查询所有菜单list集合按照要求进行封装

        List<Permission> resultList = bulidPermission(permissionList);

        return resultList;

    }

bulidPermission方法:完成递归操作。这个方法可以写到工具类中,也可以写在当前里面。

    //把返回所有菜单list集合进行封装的方法

    public static List<Permission> bulidPermission(List<Permission> permissionList) {

        //创建list集合,用于数据最终封装

        List<Permission> finalNode = new ArrayList<>();


        //把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1

        for(Permission permissionNode : permissionList) {

            //得到顶层菜单 pid=0菜单

            if("0".equals(permissionNode.getPid())) {

                //设置顶层菜单的level是1

                permissionNode.setLevel(1);


                //根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面

                //两个参数,permissionNode一级菜单节点,permissionList所有集合

                finalNode.add(selectChildren(permissionNode,permissionList));

            }

        }

        return finalNode;

    }


    private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {

        //1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化

        permissionNode.setChildren(new ArrayList<Permission>());

        //2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同

        for(Permission it : permissionList) {

            //判断一级permissionNode的id和二级it的pid值是否相同

            if(permissionNode.getId().equals(it.getPid())) {

                //把父菜单的level值+1

                int level = permissionNode.getLevel()+1;

                it.setLevel(level);

                //如果children为空,进行初始化操作

                if(permissionNode.getChildren() == null) {

                    permissionNode.setChildren(new ArrayList<Permission>());

                }


                //把查询出来的子菜单(it)放到父菜单(即permissionNode一级)里面

                permissionNode.getChildren().add(selectChildren(it,permissionList));

            }

        }

        return permissionNode;

    }

测试:

2、递归删除菜单

比如删除id=11菜单,把11值和11菜单里面子菜单所有id都获取到。

(1)PermissionController

    @ApiOperation(value = "递归删除菜单")

    @DeleteMapping("remove/{id}")

    public R remove(@PathVariable String id) {

        permissionService.removeChildByIdGuli(id);

        return R.ok();

    }

(2)PermissionServiceImpl

//============递归删除菜单==================================

    @Override

    public void removeChildByIdGuli(String id) {

        //1 创建list集合,用于封装所有删除菜单id值

        List<String> idList = new ArrayList<>();


        //2 向idList集合设置删除菜单id,根据id在进行查询,然后把所有id封装到idList

        this.selectPermissionChildById(id,idList);

        //把当前id封装到list里面

        idList.add(id);

        baseMapper.deleteBatchIds(idList);

    }


    //2 根据当前菜单id,查询菜单里面子菜单id,封装到list集合

    private void selectPermissionChildById(String id, List<String> idList) {

        //查询菜单里面子菜单id

        QueryWrapper<Permission>  wrapper = new QueryWrapper<>();

        wrapper.eq("pid",id);

        wrapper.select("id");  //查出指定列的值

        List<Permission> childIdList = baseMapper.selectList(wrapper);


        //把childIdList里面菜单id值获取出来,封装idList里面,做递归查询

        childIdList.stream().forEach(item -> {

            //封装idList里面

            idList.add(item.getId());

            //递归查询

            this.selectPermissionChildById(item.getId(),idList);

        });

    }

测试:

3、给角色分配权限

(1)PermissionController

//roleId角色id,permissionId菜单id,角色一个但是菜单多个

    @ApiOperation(value = "给角色分配权限")

    @PostMapping("/doAssign")

    public R doAssign(String roleId,String[] permissionId) {

        permissionService.saveRolePermissionRealtionShipGuli(roleId,permissionId);

        return R.ok();

    }

(2)PermissionServiceImpl

//=========================给角色分配菜单=======================

    @Override

     //roleId角色id

    //permissionId菜单id 数组形式

    public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {

        //1 创建list集合,用于封装添加数据

        List<RolePermission> rolePermissionList = new ArrayList<>();


        //遍历所有菜单数组

        for(String perId : permissionIds) {

            //RolePermission对象

            RolePermission rolePermission = new RolePermission();

            rolePermission.setRoleId(roleId); // 角色id

            rolePermission.setPermissionId(perId);//菜单id

            //封装到list集合

            rolePermissionList.add(rolePermission);

        }


        //添加到角色菜单关系表

        rolePermissionService.saveBatch(rolePermissionList);

    }

(3)在实体类中添加填充注解

测试:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335