尚好房 09_权限管理

尚好房:权限管理

一、业务介绍

1. 数据库表关系

尚好房 09_权限管理_第1张图片

2. 权限表介绍

2.1 表结构

尚好房 09_权限管理_第2张图片

2.2 表数据

尚好房 09_权限管理_第3张图片

3. 页面效果

尚好房 09_权限管理_第4张图片

二、权限管理模块

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

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.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.1.2 业务层
1.1.2.1 RoleService接口

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

/**
 * 查询用户的角色列表
 * @param adminId
 * @return
 */
Map<String,List<Role>> findRolesByAdminId(Long adminId);
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.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.1.4 前端页面

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

新增标签

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

绑定点击事件

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

② 在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 保存角色分配

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.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.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.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 表现层

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.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>

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();
}
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);
}
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>
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>
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);
}
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;
    }
}
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;
}
2.1.4 前端页面

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

新增标签

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

绑定点击事件

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

② 在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>

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);
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>
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);
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);
            }
        }
    }
}
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,"设置角色权限成功");
}
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. 需求和实现思路

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);
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>

3. 业务层

3.1 PermissionService接口

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

/**
* 查询用户的所有权限
* @param adminId
* @return
*/
List<Permission> findMenuPermissionByAdminId(Long adminId);
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);
}

从资源文件引入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;
    }
}

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;
}

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>

6. 测试

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

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

1. 显示菜单管理列表功能

1.1 业务层
1.1.1 PermissionService接口

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

/**
* 查询所有菜单
* @return
*/
List<Permission> findAllMenu();
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 表现层

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.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>

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;
}
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>

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>

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>
2.2 表现层

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

@PostMapping("/save")
public String save(Permission permission,Model model){
    permissionService.insert(permission);
    return successPage(model,"添加菜单成功");
}

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>
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;
}
4.3 前端页面

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

$(".delete").on("click", function () {
    var id = $(this).attr("data-id");
    opt.confirm('/permission/delete/' + id);
});

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>
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;
}
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);
});

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>

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>
6.2表现层

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

@PostMapping("/update")
public String update(Permission permission,Model model){
    permissionService.update(permission);
    return successPage(model,"修改菜单成功");
}

你可能感兴趣的:(尚好房,数据库,sql,mysql)