• 尚好房 09_权限管理


    尚好房:权限管理

    一、业务介绍

    1. 数据库表关系

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x9agv9ZW-1661871694240)(images/09/img_001.png)]

    2. 权限表介绍

    2.1 表结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-btEi4NNj-1661871694245)(images/09/img_002.png)]

    2.2 表数据

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lu50aspt-1661871694247)(images/09/img_003.png)]

    3. 页面效果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBjiiuU4-1661871694248)(images/09/img_004.png)]

    二、权限管理模块

    前面已经做了用户管理与角色管理,目前我们在此基础上完善权限管理功能

    1. 给用户分配角色功能

    1.1 显示分配角色页面
    1.1.1 持久层
    1.1.1.1 AdminRoleMapper接口

    service-acl项目中创建com.atguigu.mapper.AdminRoleMapper接口

    public interface AdminRoleMapper extends BaseMapper<AdminRole> {
        /**
         * 根据用户id查询其分配的角色id列表
         * @param adminId
         * @return
         */
        List<Long> findRoleIdListByAdminId(Long adminId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.1.1.1 AdminRoleMapper.xml映射配置文件

    service-acl项目中创建resources/mappers/AdminRoleMapper.xml映射配置文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.atguigu.mapper.AdminRoleMapper">
        <select id="findRoleIdListByAdminId" resultType="long">
            select role_id from acl_admin_role where admin_id=#{adminId} and is_deleted=0
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1.1.2 业务层
    1.1.2.1 RoleService接口

    service-api项目中的com.atguigu.service.RoleService接口中新增

    /**
     * 查询用户的角色列表
     * @param adminId
     * @return
     */
    Map<String,List<Role>> findRolesByAdminId(Long adminId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.1.2.2 RoleServiceImpl实现类

    service-acl项目中的com.atguigu.service.impl.RoleServiceImpl实现类中新增

    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Override
    public Map<String, List<Role>> findRolesByAdminId(Long adminId) {
        //1. 查询所有角色
        List<Role> allRoleList = roleMapper.findAll();
        //2. 查询用户已分配的角色id列表
        List<Long> assignRoleIdList = adminRoleMapper.findRoleIdListByAdminId(adminId);
        //3. 创建俩List分别存储用户已分配和未分配的角色
        List<Role> unAssignRoleList = new ArrayList<>();
        List<Role> assignRoleList = new ArrayList<>();
        //4. 筛选用户已分配和未分配角色
        for (Role role : allRoleList) {
            if (assignRoleIdList.contains(role.getId())) {
                //已分配
                assignRoleList.add(role);
            }else {
                //未分配
                unAssignRoleList.add(role);
            }
        }
        Map<String,List<Role>> roleMap = new HashMap<>();
        roleMap.put("unAssignRoleList",unAssignRoleList);
        roleMap.put("assignRoleList",assignRoleList);
        return roleMap;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1.1.3 表现层

    web-admin项目中的com.atguigu.controller.AdminController中新增

    @GetMapping("/assignShow/{id}")
    public String assignShow(@PathVariable("id") Long id,
                             Model model){
        //1. 调用业务层的方法获取用户已分配和未分配的角色列表
        Map<String, List<Role>> roleListMap = roleService.findRolesByAdminId(id);
        //2. 将查询到的数据存储到请求域,请求域中的key分别是assignRoleList和unAssignRoleList
    
        //3. 将id存储到请求域: 为了在分配角色页面中拿到adminId
        model.addAttribute("adminId",id);
    
        model.addAllAttributes(roleListMap);
        return PAGE_ASSIGN_SHOW;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.1.4 前端页面

    ① 在web-admin项目中的templates/admin/index.html中新增

    新增标签

    <a class="assign" th:attr="data-id=${item.id}" >分配角色a>
    
    • 1

    绑定点击事件

    $(".assign").on("click",function () {
        var id = $(this).attr("data-id");
        opt.openWin('/admin/assignShow/'+id,'分配角色',550,450)
    });
    
    • 1
    • 2
    • 3
    • 4

    ② 在web-admin项目中创建templates/admin/assignShow.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head th:include="common/head :: head">head>
    
    <style type="text/css">
        select option{
            width:260px;
            height:25px;
            line-height:25px;
            padding: 5px 5px;
        }
    style>
    <body class="gray-bg">
    <div class="wrapper wrapper-content animated fadeInRight">
        <div class="ibox float-e-margins">
            <form id="ec" th:action="@{/admin/assignRole}" method="post" class="form-horizontal">
                <input type="hidden" name="adminId" th:value="${adminId}">
                <input type="hidden" name="roleIds" id="roleIds" value="">
                <div style="text-align: center;padding-left: 20px;">
                    <div id="s1" style="float: left;">
                        <div style="font-weight:900;">未选择div>
                        <select id="select1" multiple="multiple" style="width: 220px;height: 280px;overflow-y:auto;" ondblclick="funRight()">
                            <option th:each="item: ${unAssignRoleList}" th:value="${item.id}" th:text="${item.roleName}">11option>
                        select>
                    div>
                    <div style="float: left;padding-top:120px;">
                        <br />
                        <button type="button" id="right"> >> button><br /><br />
    
                        <button type="button" id="left">  << button>
    
                    div>
                    <div id="s2" style="float: left;">
                        <div style="font-weight:900;">已选择div>
                        <select id="select2" multiple="multiple" style="width: 220px;height: 280px;overflow-y:auto;" ondblclick="funLeft()">
                            <option th:each="item: ${assignRoleList}" th:value="${item.id}" th:text="${item.roleName}">11option>
                        select>
                    div>
    
                    <div class="form-group" style="clear: left;padding-top: 20px;">
                        <button type="button" class="btn btn-sm btn-primary "  style="margin-left: 10px;"> 保存button>
                        <button type="button" class="btn btn-sm btn-primary "  style="margin-left: 10px;"> 重置button>
                        <button class="btn btn-sm btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消button>
                    div>
                    <br/>
                div>
            form>
        div>
    div>
    <script th:inline="javascript">
        $(function(){
            $("#right").on("click",function() {
                $("#select1 option").each(function(index, item){
                    if(item.selected == true){
                        document.getElementById("select2").appendChild(item);
                    }
                });
            });
    
            $("#left").on("click",function() {
                $("#select2 option").each(function(index, item){
                    if(item.selected == true){
                        document.getElementById("select1").appendChild(item);
                    }
                });
            });
        });
    
        function funRight() {
            $("#right").trigger("click");
        }
    
        function funLeft() {
            $("#left").trigger("click");
        }
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    1.2 保存角色分配
    1.2.1 持久层
    1.2.1.1 AdminRoleMapper接口

    service-acl项目的com.atguigu.mapper.AdminRoleMapper接口中新增

    /**
     * 查询用户是否绑定过该角色
     * @param adminId
     * @param roleId
     * @return
     */
    AdminRole findByAdminIdAndRoleId(@Param("adminId") Long adminId,@Param("roleId") Long roleId);
    
    /**
     * 移除用户的角色
     * @param adminId
     * @param removeRoleIdList
     */
    void removeAdminRole(@Param("adminId") Long adminId,@Param("roleIds") List<Long> removeRoleIdList);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1.2.1.2 AdminRoleMapper.xml映射配置文件

    service-acl项目的resources/mappers/AdminRoleMapper.xml中新增

    <sql id="columns">
        select id,role_id,admin_id,create_time,update_time,is_deleted
    sql>
    <select id="findByAdminIdAndRoleId" resultType="AdminRole">
        <include refid="columns">include>
        from acl_admin_role
        where admin_id=#{adminId} and role_id=#{roleId}
    select>
    <update id="removeAdminRole">
        update acl_admin_role
        set is_deleted=1
        where admin_id=#{adminId}
        and role_id in (
        <foreach collection="roleIds" item="roleId" separator=",">
            #{roleId}
        foreach>
        )
    update>
    <insert id="insert">
        insert into acl_admin_role (
        id ,
        role_id ,
        admin_id
        ) values (
        #{id} ,
        #{roleId} ,
        #{adminId}
        )
    insert>
    <update id="update">
        update acl_admin_role set is_deleted=#{isDeleted} where id=#{id}
    update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1.2.2 业务层
    1.2.2.1 RoleService接口

    service-api项目中的com.atguigu.service.RoleService接口中新增

    /**
     * 保存用户角色
     * @param adminId
     * @param roleIdList
     */
    void saveAdminRole(Long adminId,List<Long> roleIdList);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.2.2.2 RoleServiceImpl实现类

    service-acl项目中的com.atguigu.service.impl.RoleServiceImpl实现类中新增

    @Override
    public void saveAdminRole(Long adminId, List<Long> roleIds) {
        //1. 查询当前用户已分配的id集合
        List<Long> assignRoleIds = adminRoleMapper.findRoleIdListByAdminId(adminId);
        //2. 找出需要移除的角色id
        //使用Stream流完成
        /*List removeRoleIds = assignRoleIds.stream()
                    .filter(roleId -> !roleIds.contains(roleId)).collect(Collectors.toList());*/
    
        List<Long> removeRoleIds = new ArrayList<>();
        //不使用Stream流
        for (Long roleId : assignRoleIds) {
            if (!roleIds.contains(roleId)) {
                //要移除
                removeRoleIds.add(roleId);
            }
        }
        //3. 调用持久层的方法移除用户和这些角色的绑定
        if (removeRoleIds != null && removeRoleIds.size() > 0) {
            adminRoleMapper.removeAdminRole(adminId,removeRoleIds);
        }
    
        //4. 遍历出新传过来的每一个角色id
        for (Long roleId : roleIds) {
            //判断当前角色id是否已绑定(分配)
            AdminRole adminRole = adminRoleMapper.findByAdminIdAndRoleId(adminId, roleId);
            if (adminRole == null) {
                //说明之前从未绑定
                //新增数据
                adminRole = new AdminRole();
                adminRole.setAdminId(adminId);
                adminRole.setRoleId(roleId);
                adminRoleMapper.insert(adminRole);
            }else {
                //说明之前绑定过
                if (adminRole.getIsDeleted() == 1) {
                    //但是已经移除绑定了
                    //修改is_deleted为0
                    adminRole.setIsDeleted(0);
                    adminRoleMapper.update(adminRole);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    1.2.3 表现层

    web-admin项目中的com.atguigu.controller.AdminController中新增

    @PostMapping("/assignRole")
    public String assignRole(@RequestParam("adminId") Long adminId,
                             @RequestParam("roleIds") List<Long> roleIds,
                             Model model){
        roleService.saveAdminRole(adminId,roleIds);
        return successPage(model,"保存角色成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1.2.4 前端页面

    web-admin项目中的templates/admin/assignShow.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head th:include="common/head :: head">head>
    
    <style type="text/css">
        select option{
            width:260px;
            height:25px;
            line-height:25px;
            padding: 5px 5px;
        }
    style>
    <body class="gray-bg">
    <div class="wrapper wrapper-content animated fadeInRight">
        <div class="ibox float-e-margins">
            <form id="ec" th:action="@{/admin/assignRole}" method="post" class="form-horizontal">
                <input type="hidden" name="adminId" th:value="${adminId}">
                <input type="hidden" name="roleIds" id="roleIds" value="">
                <div style="text-align: center;padding-left: 20px;">
                    <div id="s1" style="float: left;">
                        <div style="font-weight:900;">未选择div>
                        <select id="select1" multiple="multiple" style="width: 220px;height: 280px;overflow-y:auto;" ondblclick="funRight()">
                            <option th:each="item: ${unAssignRoleList}" th:value="${item.id}" th:text="${item.roleName}">11option>
                        select>
                    div>
                    <div style="float: left;padding-top:120px;">
                        <br />
                        <button type="button" id="right"> >> button><br /><br />
    
                        <button type="button" id="left">  << button>
    
                    div>
                    <div id="s2" style="float: left;">
                        <div style="font-weight:900;">已选择div>
                        <select id="select2" multiple="multiple" style="width: 220px;height: 280px;overflow-y:auto;" ondblclick="funLeft()">
                            <option th:each="item: ${assignRoleList}" th:value="${item.id}" th:text="${item.roleName}">11option>
                        select>
                    div>
    
                    <div class="form-group" style="clear: left;padding-top: 20px;">
                        <button type="button" class="btn btn-sm btn-primary " onclick="add()" style="margin-left: 10px;"> 保存button>
                        <button type="button" class="btn btn-sm btn-primary " onclick="cancel()" style="margin-left: 10px;"> 重置button>
                        <button class="btn btn-sm btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消button>
                    div>
                    <br/>
                div>
            form>
        div>
    div>
    <script th:inline="javascript">
        $(function(){
            $("#right").on("click",function() {
                $("#select1 option").each(function(index, item){
                    if(item.selected == true){
                        document.getElementById("select2").appendChild(item);
                    }
                });
            });
    
            $("#left").on("click",function() {
                $("#select2 option").each(function(index, item){
                    if(item.selected == true){
                        document.getElementById("select1").appendChild(item);
                    }
                });
            });
        });
    
        function funRight() {
            $("#right").trigger("click");
        }
    
        function funLeft() {
            $("#left").trigger("click");
        }
    
        function add() {
            var roleIds = "";
            for (let i = 0; i < $("#select2 option").length; i++) {
                if (i < $("#select2 option").length - 1){
                    roleIds += $("#select2 option")[i].value + ",";
                }else {
                    roleIds += $("#select2 option")[i].value
                }
            }
            $("#roleIds").val(roleIds);
            document.forms.ec.submit();
        }
    
        function cancel() {
            location.reload();
        }
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    2. 给角色分配权限

    2.1 显示分配权限页面
    2.1.1 持久层
    2.1.1.1 PermissionMapper接口

    service-acl项目中创建com.atguigu.mapper.PermissionMapper接口

    public interface PermissionMapper extends BaseMapper<Permission> {
        /**
         * 查询所有权限列表
         * @return
         */
        List<Permission> findAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2.1.1.2 RolePermissionMapper接口

    service-acl项目中创建com.atguigu.mapper.RolePermissionMapper接口

    public interface RolePermissionMapper extends BaseMapper<RolePermission> {
        /**
        * 根据roleId查询permissionId集合
        * @param roleId
        * @return
        */
        List<Long> findPermissionIdListByRoleId(Long roleId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    2.1.1.3 PermissionMapper.xml映射配置文件

    service-acl项目中创建resources/mappers/PermissionMapper.xml映射配置文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.atguigu.mapper.PermissionMapper">
        <sql id="columns">
            select id,parent_id,name,url,code,type,sort,create_time,update_time,is_deleted
        sql>
        <select id="findAll" resultType="Permission">
            <include refid="columns">include>
            from acl_permission
            where is_deleted=0
            order by sort
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    2.1.1.4 RolePermissionMapper.xml映射配置文件

    service-acl项目中创建resources/mappers/RolePermissionMapper.xml映射配置文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.atguigu.mapper.RolePermissionMapper">
        <select id="findPermissionIdListByRoleId" resultType="long">
            select permission_id from acl_role_permission
            where role_id=#{roleId} and is_deleted=0
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2.1.2 业务层
    2.1.2.1 PermissionService接口

    service-api项目中创建com.atguigu.service.PermissionService接口

    public interface PermissionService extends BaseService<Permission> {
        /**
         * 根据角色获取权限数据
         * @param roleId
         * @return
         */
        List<Map<String,Object>> findPermissionByRoleId(Long roleId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    2.1.2.2 PermissionServiceImpl实现类

    service-acl项目中创建com.atguigu.service.impl.PermissionServiceImpl实现类

    @Service(interfaceClass = PermissionService.class)
    public class PermissionServiceImpl extends BaseServiceImpl<Permission> implements PermissionService {
        @Autowired
        private PermissionMapper permissionMapper;
        @Autowired
        private RolePermissionMapper rolePermissionMapper;
        @Override
        protected BaseMapper<Permission> getEntityMapper() {
            return permissionMapper;
        }
    	
        @Override
        public List<Map<String, Object>> findPermissionByRoleId(Long roleId) {
            //查询所有权限信息
            List<Permission> allPermissionList = permissionMapper.findAll();
            //查询出当前角色已分配的权限id
            List<Long> assignPermissionIdList = rolePermissionMapper.findPermissionIdListByRoleId(roleId);
            //创建一个List用于存储返回数据
            List<Map<String,Object>> permissionList = new ArrayList<>();
            //遍历出所有权限信息
            for (Permission permission : allPermissionList) {
                //创建一个Map用于存储返回数据
                Map<String,Object> map = new HashMap<>();
                //判断当前权限是否已分配
                if (assignPermissionIdList.contains(permission.getId())){
                    //已分配
                    map.put("checked",true);
                }else {
                    //未分配
                    map.put("checked",false);
                }
                //设置id
                map.put("id",permission.getId());
                //设置pId
                map.put("pId",permission.getParentId());
                //设置name
                map.put("name",permission.getName());
                //设置open
                map.put("open",true);
                //将map添加到List中
                permissionList.add(map);
            }
            return permissionList;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    2.1.3 表现层

    web-admin项目的com.atguigu.controller.RoleController中新增

    @Reference
    private PermissionService permissionService;
    private static final String PAGE_ASSIGN_SHOW = "role/assignShow";
    
    @GetMapping("/assignShow/{roleId}")
    public String assignShow(@PathVariable("roleId") Long roleId,Model model){
        List<Map<String, Object>> zNodes = permissionService.findPermissionByRoleId(roleId);
        model.addAttribute("zNodes", JSON.toJSONString(zNodes));
        model.addAttribute("roleId",roleId);
        return PAGE_ASSIGN_SHOW;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2.1.4 前端页面

    ① 在web-admin项目中的templates/role/index.html页面中新增

    新增标签

    <a class="assgin" th:attr="data-id=${item.id}">分配权限a>
    
    • 1

    绑定点击事件

    $(".assgin").on("click",function () {
        var id = $(this).attr("data-id");
        opt.openWin("/role/assignShow/"+id,'修改',580,430);
    });
    
    • 1
    • 2
    • 3
    • 4

    ② 在web-admin项目中创建templates/role/assignShow.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
        <head th:include="common/head :: head">head>
    
        <link rel="stylesheet" th:href="@{/static/js/plugins/zTree_v3/zTreeStyle.css}" type="text/css">
        <script type="text/javascript" th:src="@{/static/js/plugins/zTree_v3/jquery.ztree.core.js}">script>
        <script type="text/javascript" th:src="@{/static/js/plugins/zTree_v3/jquery.ztree.excheck.js}">script>
        <body class="gray-bg">
            <div class="wrapper wrapper-content animated fadeInRight">
                <div class="ibox float-e-margins">
                    <div class="ibox-content" style="width: 98%;">
                        <form id="ec" th:action="@{/role/assignPermission}" method="post" class="form-horizontal">
                            <input type="hidden" name="roleId" th:value="${roleId}">
                            <input type="hidden" name="permissionIds" id="permissionIds" value="">
                            <div class="zTreeDemoBackground left">
                                <ul id="treeDemo" class="ztree">ul>
                            div>
                            <div class="hr-line-dashed">div>
                            <div class="form-group posf">
                                <div class="col-sm-4 col-sm-offset-2 text-right">
                                    <button class="btn btn-primary" type="button" id="button">确定button>
                                    <button class="btn btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消
                                    button>
                                div>
                            div>
                        form>
                    div>
                div>
            div>
            <script th:inline="javascript">
                $(function () {
                    // 文档地址:http://www.treejs.cn/v3/demo.php#_201
                    var setting = {
                        check: {
                            enable: true
                        },
                        data: {
                            simpleData: {
                                enable: true
                            }
                        }
                    };
    
                    var zNodes = JSON.parse([[${zNodes}]]);
                    //var zNodes = [[${zNodes}]];
                    // var zNodes =[
                    //     { id:1, pId:0, name:"随意勾选 1", open:true},
                    //     { id:11, pId:1, name:"随意勾选 1-1", open:true},
                    //     { id:111, pId:11, name:"随意勾选 1-1-1"},
                    //     { id:112, pId:11, name:"随意勾选 1-1-2"},
                    //     { id:12, pId:1, name:"随意勾选 1-2", open:true},
                    //     { id:121, pId:12, name:"随意勾选 1-2-1"},
                    //     { id:122, pId:12, name:"随意勾选 1-2-2"},
                    //     { id:2, pId:0, name:"随意勾选 2", checked:true, open:true},
                    //     { id:21, pId:2, name:"随意勾选 2-1"},
                    //     { id:22, pId:2, name:"随意勾选 2-2", open:true},
                    //     { id:221, pId:22, name:"随意勾选 2-2-1", checked:true},
                    //     { id:222, pId:22, name:"随意勾选 2-2-2"},
                    //     { id:23, pId:2, name:"随意勾选 2-3"}
                    // ];
    
                    var zTree = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
                    zTree.expandAll(true);
                });
            script>
        body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    2.2 保存分配权限
    2.2.1 持久层
    2.2.1.1 RolePermissionMapper接口

    service-acl项目的com.atguigu.mapper.RolePermissionMapper接口中新增

    /**
    * 删除角色的权限
    * @param roleId
    * @param removePermissionIdList
    */
    void removeRolePermission(@Param("roleId") Long roleId,@Param("removePermissionIdList") List<Long> removePermissionIdList);
    
    /**
    * 根据roleId和permissionId查询
    * @param roleId
    * @param permissionId
    * @return
    */
    RolePermission findByRoleIdAndPermissionId(@Param("roleId") Long roleId,@Param("permissionId") Long permissionId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.2.1.2 RolePermissionMapper.xml映射配置文件

    service-acl项目的resources/mappers/RolePermissionMapper.xml映射配置文件中新增

    <sql id="columns">
        select id,role_id,permission_id,create_time,update_time,is_deleted
    sql>
    <select id="findByRoleIdAndPermissionId" resultType="RolePermission">
        <include refid="columns">include>
        from acl_role_permission
        where role_id=#{roleId} and permission_id=#{permissionId}
    select>
    <update id="removeRolePermission">
        update acl_role_permission
        set is_deleted=1
        where role_id=#{roleId}
        and permission_id in
        (
        <foreach collection="removePermissionIdList" item="permissionId" separator=",">
            #{permissionId}
        foreach>
        )
    update>
    <update id="update">
        update acl_role_permission
        <set>
            <if test="roleId != null and roleId != ''">
                role_id=#{roleId},
            if>
            <if test="permissionId != null and permissionId != ''">
                permission_id=#{permissionId},
            if>
            <if test="isDeleted != null and isDeleted != '' or isDeleted == 0">
                is_deleted=#{isDeleted},
            if>
            update_time=now()
        set>
        where id=#{id}
    update>
    <insert id="insert">
        insert into acl_role_permission (id,role_id,permission_id)
        values (#{id},#{roleId},#{permissionId})
    insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    2.2.2 业务层
    2.2.2.1 PermissionService接口

    service-api项目的com.atguigu.service.PermissionService接口中新增

    /**
    * 保存权限角色信息
    * @param roleId
    * @param permissionIdList
    */
    void saveRolePermission(Long roleId,List<Long> permissionIdList);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2.2.2.2 PermissionServiceImpl实现类

    service-acl项目中的com.atguigu.service.impl.PermissionServiceImpl实现类中新增

    @Override
    public void saveRolePermission(Long roleId, List<Long> permissionIdList) {
        //查询当前角色的所有permissionId
        List<Long> rolePermissionIdList = rolePermissionMapper.findPermissionIdListByRoleId(roleId);
        //找出要移除的permissionId
        List<Long> removePermissionIdList = rolePermissionIdList.stream()
            .filter(item -> !permissionIdList.contains(item))
            .collect(Collectors.toList());
        //删除角色权限
        if (removePermissionIdList != null && removePermissionIdList.size() > 0) {
            rolePermissionMapper.removeRolePermission(roleId,removePermissionIdList);
        }
    
        //给角色添加权限
        for (Long permissionId : permissionIdList) {
            //根据roleId和permissionId查询角色权限信息
            RolePermission rolePermission = rolePermissionMapper.findByRoleIdAndPermissionId(roleId,permissionId);
            //判断当前roleId和permissionId是否存在关联
            if (rolePermission == null) {
                rolePermission = new RolePermission();
                rolePermission.setPermissionId(permissionId);
                rolePermission.setRoleId(roleId);
                rolePermissionMapper.insert(rolePermission);
            }else {
                if (rolePermission.getIsDeleted() == 1){
                    rolePermission.setIsDeleted(0);
                    rolePermissionMapper.update(rolePermission);
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    2.2.3 表现层

    web-admin项目中的com.atguigu.controller.RoleController中新增

    @PostMapping("/assignPermission")
    public String assignPermission(@RequestParam("roleId") Long roleId,
                                   @RequestParam("permissionIds") List<Long> permissionIds,
                                   Model model){
        permissionService.saveRolePermission(roleId,permissionIds);
        return successPage(model,"设置角色权限成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2.2.4 前端页面

    web-admin项目中的templates/role/assignShow.html页面中新增

    $("#button").on("click", function () {
        var checkedNodes = zTree.getCheckedNodes();
        console.log(checkedNodes)
        var permissionIdList = [];
        for (var i = 0; i < checkedNodes.length; i++) {
            permissionIdList.push(checkedNodes[i].id)
        }
        $("#permissionIds").val(permissionIdList.join(","));
        document.forms.ec.submit();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、左侧动态菜单

    1. 需求和实现思路
    1.1 需求

    前面给用户分配了角色,给角色分配了权限,那么用户登录成功后就可以获取到左侧的动态菜单,分配了哪些菜单,那么左侧就显示哪些菜单。

    当前菜单我们是直接写在frame/index.html页面的,现在我们要改成动态菜单。

    权限处理过程中,系统会默认一个超级管理员,默认就有所以权限,当前默认admin账号为超级管理员。

    1.2 实现思路

    用户登录成功后(用户登录后续与spring security一起讲解,当前用默认用户admin),根据用户id获取角色列表,然后根据角色获取用户的菜单权限。

    2. 持久层
    2.1 PermissionMapper接口

    service-acl项目中的com.atguigu.mapper.PermissionMapper接口中新增

    /**
    * 查询用户的菜单权限列表
    * @param adminId
    * @return
    */
    List<Permission> findPermissionListByAdminId(Long adminId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2.2 PermissionMapper.xml映射配置文件

    service-acl项目中的resources/mappers/PermissionMapper.xml映射配置文件中新增

    <select id="findPermissionListByAdminId" resultType="Permission">
        <include refid="columns">include>
        from acl_permission where is_deleted=0
        and
        id in (select permission_id from acl_role_permission where is_deleted=0 and role_id in (
        select role_id from acl_admin_role where is_deleted=0 and admin_id=#{adminId}
        ))
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    3. 业务层
    3.1 PermissionService接口

    service-api项目的com.atguigu.service.PermissionService接口中新增

    /**
    * 查询用户的所有权限
    * @param adminId
    * @return
    */
    List<Permission> findMenuPermissionByAdminId(Long adminId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    3.2 PermissionServiceImpl实现类

    service-acl项目的com.atguigu.service.impl.PermissionServiceImpl实现类中新增

    @Override
    public List<Permission> findMenuPermissionByAdminId(Long adminId) {
        List<Permission> permissionList = null;
        //判断是否是超级管理员
        if (adminId == 1) {
            //超级管理员
            permissionList = permissionMapper.findAll();
        }else {
            //根据adminId查询权限列表
            permissionList = permissionMapper.findPermissionListByAdminId(adminId);
        }
        //构建树形菜单
        return PermissionHelper.build(permissionList);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    从资源文件引入helper/PermissionHelper帮助类(可以不自己写),放到service-acl项目的com.atguigu.helper包中

    public class PermissionHelper {
        public static List<Permission> build(List<Permission> originalPermissionList){
            List<Permission> treeNodes = new ArrayList<>();
            for (Permission treeNode : originalPermissionList) {
                if (treeNode.getParentId() == 0) {
                    //一级菜单
                    treeNode.setLevel(1);
                    treeNode.setChildren(getChildren(treeNode,originalPermissionList));
                    treeNodes.add(treeNode);
                }
            }
    
            return treeNodes;
        }
    
        /**
         * 获取子菜单列表
         * @return
         */
        private static List<Permission> getChildren(Permission treeNode,List<Permission> originalPermissionList) {
    
            List<Permission> children = new ArrayList<>();
            for (Permission childTreeNode : originalPermissionList) {
                //找出子节点
                if (treeNode.getId().longValue() == childTreeNode.getParentId().longValue()) {
                    //设置子节菜单级别
                    childTreeNode.setLevel(treeNode.getLevel() + 1);
                    //设置子菜单的父菜单名
                    childTreeNode.setParentName(treeNode.getName());
                    //给子菜单设置子菜单
                    childTreeNode.setChildren(getChildren(childTreeNode,originalPermissionList));
    
                    children.add(childTreeNode);
                }
            }
            return children;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    4. 表现层

    web-admin项目中修改com.atguigu.controller.IndexController类的index()方法

    @Reference
    private AdminService adminService;
    @Reference
    private PermissionService permissionService;
    private static final String PAGE_INDEX = "frame/index";
    @GetMapping("/")
    public String index(Model model){
        //因为现在还未引入权限认证框架,没有登录,所以现在先将用户的id写死,等集成了权限认证框架之后,再获取当前登录的用户
        Long adminId = 1L;
        Admin admin = adminService.getById(adminId);
        //查询用户的权限列表
        List<Permission> permissionList = permissionService.findMenuPermissionByAdminId(adminId);
        model.addAttribute("admin",admin);
        model.addAttribute("permissionList",permissionList);
        return PAGE_INDEX;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    5. 前端页面

    修改web-admin项目的templates/frame/index.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta name="renderer" content="webkit"/>
    
        <title>尚好房平台管理系统title>
    
        <meta name="keywords" content="尚好房平台管理系统,后台HTML,响应式后台"/>
        <meta name="description" content="尚好房平台管理系统,后台HTML,响应式后台"/>
    
        
    
        <link rel="shortcut icon" th:href="@{/static/favicon.ico}"/>
        <link th:href="@{/static/css/bootstrap.min.css(v=3.3.7)}" rel="stylesheet"/>
        <link th:href="@{/static/css/font-awesome.min.css(v=4.4.0)}" rel="stylesheet"/>
        <link th:href="@{/static/css/animate.css}" rel="stylesheet"/>
        <link th:href="@{/static/css/style.css(v=4.1.0)}" rel="stylesheet"/>
        <link th:href="@{/static/css/jquery.contextMenu.min.css}" rel="stylesheet"/>
    head>
    
    <body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden;">
    <div id="wrapper">
        
        <nav class="navbar-default navbar-static-side" role="navigation">
            <div class="nav-close"><i class="fa fa-times-circle">i>div>
            <div class="sidebar-collapse">
                <ul class="nav" id="side-menu">
                    <li class="nav-header">
                        <div class="dropdown profile-element">
                            <span><img alt="image" class="img-circle" th:src="${admin.headUrl}"/>span>
                            <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                               <span class="clear">
                                  <span class="block m-t-xs"><strong class="font-bold" th:text="${admin.name}">Beaut-zihanstrong>span>
                                  <span class="text-muted text-xs block">超级管理员<b class="caret">b>span>
                               span>
                            a>
                            <ul class="dropdown-menu animated fadeInRight m-t-xs">
                                <li><a class="J_menuItem" href="javascript:">修改头像a>li>
                                <li><a class="J_menuItem" href="javascript:">个人资料a>li>
                                <li><a class="J_menuItem" href="javascript:">联系我们a>li>
                                <li><a class="J_menuItem" href="javascript:">信箱a>li>
                                <li class="divider">li>
                                <li><a href="/logout">安全退出a>li>
                            ul>
                        div>
                        <div class="logo-element">H+div>
                    li>
                    <li th:each="one: ${permissionList}">
                        <a href="#">
                            <i class="fa fa-home">i>
                            <span class="nav-label" th:text="${one.name}">系统管理span>
                            <span class="fa arrow">span>
                        a>
                        <ul class="nav nav-second-level collapse">
                            <li th:each="two,it: ${one.children}">
                                <a class="J_menuItem" th:href="${two.url}"
                                   th:data-index="${it.count}"
                                   th:text="${two.name}">用户管理a>li>
                        ul>
                    li>
                ul>
            div>
        nav>
        
        
        <div id="page-wrapper" class="gray-bg dashbard-1">
            <div class="row border-bottom">
                <nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0;">
                    <div class="navbar-header">
                        <a class="navbar-minimalize minimalize-styl-2 btn btn-primary" href="#"><i class="fa fa-bars">i>
                        a>
                        <form role="search" class="navbar-form-custom" method="post" action="search_results.html">
                            <div class="form-group">
                                <input type="text" placeholder="请输入您需要查找的内容 …" class="form-control" name="top-search"
                                       id="top-search"/>
                            div>
                        form>
                    div>
                nav>
            div>
            <div class="row content-tabs">
                <button class="roll-nav roll-left J_tabLeft"><i class="fa fa-backward">i>button>
                <nav class="page-tabs J_menuTabs">
                    <div class="page-tabs-content">
                        <a href="javascript:;" class="active J_menuTab" data-id="index_v1.html">首页a>
                    div>
                nav>
                <button class="roll-nav roll-right J_tabRight"><i class="fa fa-forward">i>button>
                <div class="btn-group roll-nav roll-right">
                    <button class="dropdown" data-toggle="dropdown">页签操作<span class="caret">span>button>
                    <ul role="menu" class="dropdown-menu dropdown-menu-right">
                        <li class="tabCloseCurrent"><a>关闭当前a>li>
                        <li class="J_tabCloseOther"><a>关闭其他a>li>
                        <li class="J_tabCloseAll"><a>全部关闭a>li>
                    ul>
                div>
                <a href="#" class="roll-nav roll-right tabReload"><i class="fa fa-refresh">i> 刷新a>
            div>
            <div class="row J_mainContent" id="content-main">
            
            <iframe class="J_iframe" name="iframe0" width="100%" height="100%" th:src="@{/main}" frameborder="0"
                    data-id="index_v1.html" seamless>iframe>
        div>
            <div class="footer">
                <div class="pull-right">© 2014-2015 <a href="http://www.zi-han.net/" target="_blank">zihan's bloga>
                div>
            div>
        div>
        
        
        
    div>
    
    
    <script th:src="@{/static/js/jquery.min.js(v=2.1.4)}">script>
    <script th:src="@{/static/js/bootstrap.min.js(v=3.3.7)}">script>
    <script th:src="@{/static/js/plugins/metisMenu/jquery.metisMenu.js}">script>
    <script th:src="@{/static/js/plugins/slimscroll/jquery.slimscroll.min.js}">script>
    <script th:src="@{/static/js/plugins/contextMenu/jquery.contextMenu.min.js}">script>
    <script th:src="@{/static/js/plugins/layer/layer.min.js}">script>
    
    
    <script th:src="@{/static/js/hplus.js(v=4.1.0)}">script>
    <script type="text/javascript" th:src="@{/static/js/contabs.js}">script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    6. 测试

    使用当前用户adminId=1分配好角色与权限,更改当前用户adminId测试菜单

    四、菜单管理(自己参考代码完成)

    1. 显示菜单管理列表功能
    1.1 业务层
    1.1.1 PermissionService接口

    service-api项目的com.atguigu.service.PermissionService接口中新增

    /**
    * 查询所有菜单
    * @return
    */
    List<Permission> findAllMenu();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.1.2 PermissionServiceImpl实现类

    service-acl项目的com.atguigu.service.impl.PermissionServiceImpl实现类中新增

    @Override
    public List<Permission> findAllMenu() {
        List<Permission> permissionList = permissionMapper.findAll();
        return PermissionHelper.build(permissionList);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.2 表现层

    web-admin项目中创建com.atguigu.controller.PermissionController

    @Controller
    @RequestMapping("/permission")
    public class PermissionController extends BaseController {
        private final static String PAGE_INDEX = "permission/index";
        @Reference
        private PermissionService permissionService;
        
        @GetMapping
        public String index(Model model){
            List<Permission> permissionList = permissionService.findAllMenu();
            model.addAttribute("list",permissionList);
    
            return PAGE_INDEX;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1.3 前端页面

    web-admin项目中创建templates/permission/index.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
          xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    
    <head th:include="common/head :: head">head>
    
    <body class="gray-bg">
    <form id="ec" action="#" method="post">
        <div class="wrapper wrapper-content animated fadeInRight">
    
            <div class="row">
                <div class="col-sm-12">
                    <div class="ibox float-e-margins">
                        <div class="ibox-content">
                            <div>
                                <button type="button" class="btn btn-sm btn-primary create"
                                        th:attr="data-id=0,data-type=1,data-name='一级菜单'">新增一级菜单
                                button>
                                <button type="button" id="loading-example-btn"
                                        onclick="javascript:window.location.reload();" class="btn btn-white btn-sm">刷新
                                button>
                            div>
                            <table class="table table-striped table-bordered table-hover dataTables-example">
                                <thead>
                                <tr>
                                    <th>权限名称th>
                                    <th>菜单urlth>
                                    <th>权限标识th>
                                    <th>类型th>
                                    <th>排序th>
                                    <th>创建时间th>
                                    <th>操作th>
                                tr>
                                thead>
                                <tbody>
                                <div th:each="one: ${list}">
                                    <tr class="gradeX">
                                        <td th:text="${one.name}">22td>
                                        <td th:text="${one.url}">33td>
                                        <td th:text="${one.code}">22td>
                                        <td>
                                            <strong><span th:if="${one.type } eq 1" style="color: blue">菜单span>strong>
                                            <strong><span th:if="${one.type } eq 2">按钮span>strong>
                                        td>
                                        <td th:text="${one.sort}">22td>
                                        <td th:text="${#dates.format(one.createTime,'yyyy-MM-dd HH:mm:ss')}">33td>
                                        <td class="text-center">
                                            <a class="create" th:attr="data-id=${one.id},data-type=1,data-name=${one.name}">新增二级菜单a>
                                            <a class="edit"
                                               th:attr="data-id=${one.id}">修改a>
                                            <a class="delete"
                                               th:attr="data-id=${one.id}">删除a>
                                        td>
                                    tr>
                                    <div th:each="two: ${one.children}">
                                        <tr class="gradeX">
                                            <td th:text="'      ' + ${two.name}">22td>
                                            <td th:text="${two.url}">33td>
                                            <td th:text="${two.code}">22td>
                                            <td>
                                                <strong><span th:if="${two.type } eq 1"
                                                              style="color: blue">菜单span>strong>
                                                <strong><span th:if="${two.type } eq 2">按钮span>strong>
                                            td>
                                            <td th:text="${two.sort}">22td>
                                            <td th:text="${#dates.format(two.createTime,'yyyy-MM-dd HH:mm:ss')}">33td>
                                            <td class="text-center">
                                                <a class="create"
                                                   th:attr="data-id=${two.id},data-type=2,data-name=${two.name}">新增功能按钮a>
                                                <a class="edit"
                                                   th:attr="data-id=${two.id}">修改a>
                                                <a class="delete"
                                                   th:attr="data-id=${two.id}">删除a>
                                            td>
                                        tr>
                                        <div th:each="three: ${two.children}">
                                            <tr class="gradeX">
                                                <td th:text="'            ' + ${three.name}">
                                                    22
                                                td>
                                                <td th:text="${three.url}">33td>
                                                <td th:text="${three.code}">22td>
                                                <td>
                                                    <strong><span th:if="${three.type } eq 1" style="color: blue">菜单span>strong>
                                                    <strong><span th:if="${three.type } eq 2">按钮span>strong>
                                                td>
                                                <td th:text="${three.sort}">22td>
                                                <td th:text="${#dates.format(three.createTime,'yyyy-MM-dd HH:mm:ss')}">33
                                                td>
                                                <td class="text-center">
                                                    <a class="edit"
                                                       th:attr="data-id=${three.id}">修改a>
                                                    <a class="delete"
                                                       th:attr="data-id=${three.id}">删除a>
                                                td>
                                            tr>
                                        div>
                                    div>
                                div>
                                tbody>
                            table>
                        div>
                    div>
                div>
            div>
        div>
    form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    2. 显示新增菜单页面功能
    2.1 表现层

    web-admin项目中的com.atguigu.controller.PermissionController类中新增

    private static final String PAGE_CREATE = "permission/create";
    @GetMapping("/create")
    public String create(Permission permission,Model model){
        model.addAttribute("permission",permission);
        return PAGE_CREATE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2.2 前端页面

    web-admin项目中的templates/permission/index.html页面绑定点击事件

    <script th:inline="javascript">
        $(function () {
            $(".create").on("click", function () {
                var parentId = $(this).attr("data-id");
                var type = $(this).attr("data-type");
                var parentName = $(this).attr("data-name");
                opt.openWin('/permission/create?parentId=' + parentId + '&type=' + type + '&parentName=' + parentName, '新增', 630, 430)
            });
        });
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    web-admin项目中创建templates/permission/create.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
        <head th:include="common/head :: head">head>
        <script type="text/javascript">
            $(function () {
                $('#ec').validate({
                    rules: {
                        name: "required"
                    },
                    messages: {
                        name: "权限名称必须输入"
                    },
                    submitHandler: function (form) {
                        $(form).find(":submit").attr("disabled", true).text("正在提交...");
                        form.submit();
                    }
                });
            });
        script>
        <body class="gray-bg">
            <div class="wrapper wrapper-content animated fadeInRight">
                <div class="ibox float-e-margins">
                    <div class="ibox-content" style="width: 98%;">
                        <form id="ec" th:action="@{/permission/save}" method="post" class="form-horizontal">
                            <input type="hidden" name="parentId" th:value="${permission.parentId}"/>
                            <input type="hidden" name="type" th:value="${permission.type}"/>
                            <div class="form-group">
                                <label class="col-sm-2 control-label">上级权限:label>
                                <div class="col-sm-10">
                                    <input type="text" name="parentName" id="parentName" th:value="${permission.parentName}"
                                           disabled="disabled" class="form-control"/>
                                div>
                            div>
                            <div class="form-group">
                                <label class="col-sm-2 control-label">权限名称:label>
                                <div class="col-sm-10">
                                    <input type="text" name="name" id="name" value="" class="form-control"/>
                                div>
                            div>
                            <div class="hr-line-dashed">div>
                            <div class="form-group" th:if="${permission.type == 1}">
                                <label class="col-sm-2 control-label">菜单url:label>
                                <div class="col-sm-10">
                                    <input type="text" name="url" id="url" class="form-control"
                                           style="width:100%;height: 50px;">input>
                            div>
                            div>
                        <div class="hr-line-dashed" th:if="${permission.type == 1}">div>
                        <div class="form-group" th:if="${permission.type == 2}">
                            <label class="col-sm-2 control-label">权限值:label>
                            <div class="col-sm-10">
                                <input type="text" name="code" id="code" class="form-control"
                                       style="width:100%;height: 50px;">input>
                        div>
                    div>
                    <div class="hr-line-dashed" th:if="${permission.type == 2}">div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">排序:label>
                        <div class="col-sm-10">
                            <input type="text" name="sort" id="sort" value="1" class="form-control"/>
                        div>
                    div>
                    <div class="hr-line-dashed">div>
                    <div class="form-group posf">
                        <div class="col-sm-4 col-sm-offset-2 text-right">
                            <button class="btn btn-primary" type="submit">确定button>
                            <button class="btn btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消
                            button>
                        div>
                    div>
                    form>
            div>
            div>
        div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    3. 新增菜单功能
    2.1 持久层
    2.1.1 PermissionMapper.xml映射配置文件

    service-acl项目的resources/mappers/PermissionMapper.xml映射配置文件中新增

    <insert id="insert">
        insert into acl_permission (id,parent_id,name,url,code,type,sort,is_deleted)
        values (#{id},#{parentId},#{name},#{url},#{code},#{type},#{sort},0)
    insert>
    
    • 1
    • 2
    • 3
    • 4
    2.2 表现层

    web-admin项目中的com.atguigu.controller.PermissionController类中新增

    @PostMapping("/save")
    public String save(Permission permission,Model model){
        permissionService.insert(permission);
        return successPage(model,"添加菜单成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4. 删除菜单功能
    4.1 持久层
    4.1.1 PermissionMapper.xml映射配置文件

    service-acl项目的resources/mappers/PermissionMapper.xml映射配置文件中新增

    <update id="delete">
        update acl_permission
        set is_deleted=1
        where id=#{id}
    update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.2表现层

    web-admin项目中的com.atguigu.controller.PermissionController类中新增

    private static final String LIST_ACTION = "redirect:/permission";
    @GetMapping("/delete/{id}")
    public String delete(@PathVariable("id") Long id,Model model){
        permissionService.delete(id);
        return LIST_ACTION;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    4.3 前端页面

    web-admin项目中的templates/permission/index.html页面绑定点击事件

    $(".delete").on("click", function () {
        var id = $(this).attr("data-id");
        opt.confirm('/permission/delete/' + id);
    });
    
    • 1
    • 2
    • 3
    • 4
    5. 显示修改菜单页面功能
    5.1 持久层
    5.1.1 PermissionMapper.xml映射配置文件

    service-acl项目的resources/mappers/PermissionMapper.xml映射配置文件中新增

    <select id="getById" resultType="Permission">
        <include refid="columns">include>
        from acl_permission
        where id=#{id} and is_deleted=0
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    5.2表现层

    web-admin项目中的com.atguigu.controller.PermissionController类中新增

    private static final String PAGE_EDIT = "permission/edit";
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id,Model model){
        Permission permission = permissionService.getById(id);
        model.addAttribute("permission",permission);
        return PAGE_EDIT;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    5.3 前端页面

    web-admin项目中的templates/permission/index.html页面绑定点击事件

    $(".edit").on("click", function () {
        var id = $(this).attr("data-id");
        opt.openWin('/permission/edit/' + id, '修改', 580, 430);
    });
    
    • 1
    • 2
    • 3
    • 4

    web-admin项目中创建templates/permission/edit.html页面

    DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head th:include="common/head :: head">head>
    <script type="text/javascript">
        $(function () {
            $('#ec').validate({
                rules: {
                    name: "required"
                },
                messages: {
                    name: "权限名称必须输入"
                },
                submitHandler: function (form) {
                    $(form).find(":submit").attr("disabled", true).text("正在提交...");
                    form.submit();
                }
            });
        });
    script>
    <body class="gray-bg">
    <div class="wrapper wrapper-content animated fadeInRight">
        <div class="ibox float-e-margins">
            <div class="ibox-content" style="width: 98%;">
                <form id="ec" th:action="@{/permission/update}" method="post"
                      class="form-horizontal">
                    <input type="hidden" name="id" th:value="${permission.id}"/>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">权限名称:label>
                        <div class="col-sm-10">
                            <input type="text" name="name" id="name" th:value="${permission.name}" class="form-control"/>
                        div>
                    div>
                    <div class="hr-line-dashed">div>
                    <div class="form-group" th:if="${permission.type == 1}">
                        <label class="col-sm-2 control-label">菜单url:label>
                        <div class="col-sm-10">
                            <input type="text" name="url" id="url" th:value="${permission.url}" class="form-control"
                                   style="width:100%;height: 50px;">input>
                        div>
                    div>
                    <div class="hr-line-dashed" th:if="${permission.type == 1}">div>
                    <div class="form-group" th:if="${permission.type == 2}">
                        <label class="col-sm-2 control-label">权限值:label>
                        <div class="col-sm-10">
                            <input type="text" name="code" id="code" th:value="${permission.code}" class="form-control"
                                   style="width:100%;height: 50px;">input>
                        div>
                    div>
                    <div class="hr-line-dashed" th:if="${permission.type == 2}">div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">排序:label>
                        <div class="col-sm-10">
                            <input type="text" name="sort" id="sort" th:value="${permission.sort}" class="form-control"/>
                        div>
                    div>
                    <div class="hr-line-dashed">div>
                    <div class="form-group posf">
                        <div class="col-sm-4 col-sm-offset-2 text-right">
                            <button class="btn btn-primary" type="submit">确定button>
                            <button class="btn btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消
                            button>
                        div>
                    div>
                form>
            div>
        div>
    div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    6. 保存修改菜单功能
    6.1 持久层
    6.1.1 PermissionMapper.xml映射配置文件

    service-acl项目的resources/mappers/PermissionMapper.xml映射配置文件中新增

    <update id="update">
        update acl_permission
        <set>
            <if test="parentId != null and perentId != ''">
                parent_id=#{parentId},
            if>
            <if test="name != null and name != ''">
                name=#{name},
            if>
            <if test="url != null and url != ''">
                url=#{url},
            if>
            <if test="code != null and code != ''">
                code=#{code},
            if>
            <if test="type != null and type != ''">
                type=#{type},
            if>
            <if test="sort != null and sort != ''">
                sort=#{sort},
            if>
            <if test="type != null and type != ''">
                type=#{type},
            if>
            <if test="type != null and type != ''">
                type=#{type},
            if>
        set>
        where id=#{id}
    update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    6.2表现层

    web-admin项目中的com.atguigu.controller.PermissionController类中新增

    @PostMapping("/update")
    public String update(Permission permission,Model model){
        permissionService.update(permission);
        return successPage(model,"修改菜单成功");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    18.cuBLAS开发指南中文版--cuBLAS中的Level-2函数gbmv()
    JuiceFS 元数据引擎选型指南
    SPA项目开发之动态树+数据表格+分页
    C语言基础知识理论版(很详细)
    使用Testconainers来进行JAVA测试
    为什么要学习TypeScript
    Nacos启动时报错No DataSource set排查
    SpringCloud复习:(3)LoadBalancerInterceptor
    【2023七夕】星河漫舞,七夕的璀璨之夜。分享:七夕表白的前端特效(附完整原代码+详细注释),情不知何起,却一往情深。愿天下有情人终成眷属
    【go】反射系列文章
  • 原文地址:https://blog.csdn.net/lbw18/article/details/126614524