尚籌網(wǎng)-8.Admin-Role-Auth驗(yàn)證

1. 權(quán)限驗(yàn)證

2. 給Admin分配Role

2.1 創(chuàng)建中間表

CREATE TABLE inner_admin_role (
    id INT (11) NOT NULL auto_increment,
    admin_id INT (11),
    role_id INT (11),
    PRIMARY KEY (id)
);

※說明:不做逆向工程,直接使用SQL操作。

2.2 思路

2.3 調(diào)整“分配”按鈕

  • 所在工程:atcrowdfunding-admin-1-webui
  • 所在文件:admin-page.jsp

修改前:

<button type="button" class="btn btn-success btn-xs">
    <i class=" glyphicon glyphicon-check"></i>
</button>

修改后:

<a href="assign/to/assign/role/page.html?adminId=${admin.id }&pageNum=${requestScope['PAGE-INFO'].pageNum}" class="btn btn-success btn-xs">
    <i class=" glyphicon glyphicon-check"></i>
</a>

2.4 創(chuàng)建AssignHandler

@Controller
public class AssignHandler {    
    @Autowired
    private RoleService roleService;
    @RequestMapping("/assign/to/assign/role/page")
    public String toAssignRolePage(@RequestParam("adminId") Integer adminId, Model model) {
        // 1.查詢已分配角色
        List<Role> assignedRoleList = roleService.getAssignedRoleList(adminId);
        // 2.查詢未分配角色
        List<Role> unAssignedRoleList = roleService.getUnAssignedRoleList(adminId);
        // 3.存入模型
        model.addAttribute("assignedRoleList", assignedRoleList);
        model.addAttribute("unAssignedRoleList", unAssignedRoleList);   
        return "assign-role";
    }
}

2.5 查詢已分配、未分配角色的SQL

<select id="selectAssignedRoleList" resultMap="BaseResultMap">
    SELECT
        r.id,
        r.`name`
    FROM
        t_role r
    LEFT JOIN inner_admin_role ar ON r.id = ar.role_id
    WHERE
        ar.admin_id = #{adminId}
</select>
<select id="selectUnAssignedRoleList" resultMap="BaseResultMap">
    SELECT
        id,
        `name`
    FROM
        t_role
    WHERE
        id NOT IN (
            SELECT
                role_id
            FROM
                inner_admin_role
            WHERE
                admin_id = #{adminId}
        )
</select>

2.6 創(chuàng)建assign-role.jsp

/atcrowdfunding-admin-1-webui/src/main/webapp/WEB-INF/assign-role.jsp

表單內(nèi)容

<form action="assign/role.html" method="post" role="form"
      class="form-inline">
    <input type="hidden" name="adminId" value="${param.adminId }"/>
    <input type="hidden" name="pageNum" value="${param.pageNum }"/>
    <div class="form-group">
        <label for="exampleInputPassword1">未分配角色列表</label><br>
        <select
                id="leftSelect" class="form-control" multiple size="10"
                style="width: 100px; overflow-y: auto;">
            <c:forEach items="${requestScope.unAssignedRoleList }" var="role">
                <option value="${role.id }">${role.name }</option>
            </c:forEach>
        </select>
    </div>
    <div class="form-group">
        <ul>
            <li id="rightBtn"
                class="btn btn-default glyphicon glyphicon-chevron-right"></li>
            <br>
            <li id="leftBtn"
                class="btn btn-default glyphicon glyphicon-chevron-left"
                style="margin-top: 20px;"></li>
        </ul>
    </div>
    <div class="form-group" style="margin-left: 40px;">
        <label for="exampleInputPassword1">已分配角色列表</label><br>
        <select
                id="rightSelect" name="roleIdList" class="form-control"
                multiple size="10" style="width: 100px; overflow-y: auto;">
            <c:forEach items="${requestScope.assignedRoleList }" var="role">
                <option value="${role.id }">${role.name }</option>
            </c:forEach>
        </select>
    </div>
    <button id="submitBtn" type="submit" style="width: 200px;"
            class="btn btn-success btn-lg btn-block">分配
    </button>
</form>

2.7 左右移動(dòng)option

$("#rightBtn").click(function(){
    $("#leftSelect>option:selected").appendTo("#rightSelect");
});
$("#leftBtn").click(function(){
    $("#rightSelect>option:selected").appendTo("#leftSelect");
});

2.8 執(zhí)行分配的handler方法

@RequestMapping("/assign/role")
public String doAssignRole(
    // roleIdList不一定每一次都能夠提供,沒有提供我們也接受
    @RequestParam(value="roleIdList", required=false) List<Integer> roleIdList, 
    @RequestParam("adminId") Integer adminId,
    @RequestParam("pageNum") String pageNum) {  
    roleService.updateRelationship(adminId, roleIdList);    
    return "redirect:/admin/query/for/search.html?pageNum="+pageNum;
}

2.9 執(zhí)行分配的service方法

@Override
public void updateRelationship(Integer adminId, List<Integer> roleIdList) {
    // 1.刪除全部舊數(shù)據(jù)
    roleMapper.deleteOldAdminRelationship(adminId);
    // 2.保存全部新數(shù)據(jù)
    if(CrowdFundingUtils.collectionEffective(roleIdList)) {
        roleMapper.insertNewAdminRelationship(adminId, roleIdList);
    }   
}

2.10 執(zhí)行分配的SQL

<delete id="deleteOldAdminRelationship">
    delete from inner_admin_role where admin_id=#{adminId}
</delete>
<insert id="insertNewAdminRelationship">
    insert into inner_admin_role(admin_id,role_id)
    values
    <foreach collection="roleIdList" item="roleId" separator=",">(#{adminId},#{roleId})</foreach>
</insert>

2.11 填坑

  • 問題描述:默認(rèn)情況下,表單只提交select中選中的option。
  • 問題解決:在表單提交前把select中所有option全部選中
$("#submitBtn").click(function(){
    $("#rightSelect>option").prop("selected","selected");
});

3. 創(chuàng)建權(quán)限模型

3.1 建表

CREATE TABLE `t_auth` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(200) DEFAULT NULL,
    `title` varchar(200) DEFAULT NULL,
    `category_id` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

3.2 字段說明

  • id:主鍵

  • name:實(shí)際權(quán)限信息。

    • user:add

    • user:delete

    • role:delete

    • role:get

    • ……

      ※這里使用的“:”沒有任何語法層面的要求,僅僅是表示“模塊:操作”含義。

  • title:頁面顯示信息

  • category_id:權(quán)限分類id。這個(gè)字段關(guān)聯(lián)本表中的其他記錄的id字段,已便于使用樹形結(jié)構(gòu)顯示權(quán)限數(shù)據(jù)。

頁面上對應(yīng)的顯示效果如下所示:

INSERT INTO t_auth(id,`name`,title,category_id) VALUES(1,'','用戶模塊',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(2,'user:delete','刪除',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(3,'user:get','查詢',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(4,'','角色模塊',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(5,'role:delete','刪除',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(6,'role:get','查詢',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(7,'role:add','新增',4);

3.3 inner_role_auth中間表

CREATE TABLE `inner_role_auth` (
  `role_id` int(11) DEFAULT NULL,
  `auth_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`role_id`,`auth_id`)
);

3.4 逆向工程

<table tableName="t_auth" domainObjectName="Auth" />

4. 角色分配權(quán)限

4.1 后端查詢?nèi)繖?quán)限數(shù)據(jù)

handler:

@ResponseBody
@RequestMapping("/assign/get/all/auth")
public ResultEntity<List<Auth>> getAllAuth() {
    List<Auth> authList = authService.getAllAuth(); 
    return ResultEntity.successWithData(authList);
}

service:

@Override
public List<Auth> getAllAuth() {
    return authMapper.selectByExample(new AuthExample());
}

4.2 準(zhǔn)備模態(tài)框頁面

/atcrowdfunding-admin-1-webui/src/main/webapp/WEB-INF/include-modal-assign-auth.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<div id="roleAssignAuthModal" class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"
                    aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">尚籌網(wǎng)系統(tǒng)彈窗</h4>
            </div>
            <div class="modal-body">
                <ul id="treeDemo" class="ztree"></ul>
            </div>
            <div class="modal-footer">
                <button id="roleAssignAuthBtn" type="button" class="btn btn-primary">分配</button>
            </div>
        </div>
    </div>
</div>
<%@ include file="/WEB-INF/include-modal-assign-auth.jsp" %>

4.3 給分配按鈕綁定單擊響應(yīng)函數(shù)

/atcrowdfunding-admin-1-webui/src/main/webapp/script/my-role.js

function generateTableBody(pageInfo) {
    ……
    for(var i = 0; i < list.length; i++) {
        ……
        var checkBtn = "<button roleId='"+role.id+"' type='button' class='btn btn-success btn-xs checkBtn'>……</button>";
        ……

role-page.jsp

$("#roleTableBody").on("click",".checkBtn",function(){
    // 將角色id存入全局變量
    window.roleId = $(this).attr("roleId");
    $("#roleAssignAuthModal").modal("show");
});

4.4 在模態(tài)框中顯示樹形結(jié)構(gòu)

4.4.1 導(dǎo)入zTree環(huán)境

role-page.jsp

<link rel="stylesheet" href="ztree/zTreeStyle.css" />
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>

zTree一定要在jQuery后面引入。如果A.js中用到了B.js里面的代碼,那么B必須在A前面引入,否則A無法使用B中的代碼。

4.4.2 zTree設(shè)置

  • 啟用簡單JSON功能

    setting.data.simpleData.enable設(shè)置為true

  • 設(shè)置顯示節(jié)點(diǎn)名稱的實(shí)體類屬性名

    setting.data.key.name設(shè)置為title

  • 設(shè)置當(dāng)前節(jié)點(diǎn)父節(jié)點(diǎn)的屬性名

    setting.data.simpleData.pIdKey設(shè)置為categoryId

  • 展開整個(gè)樹形結(jié)構(gòu)

    $.fn.zTree.getZTreeObj("treeDemo").expandAll(true);

  • 設(shè)置樹形節(jié)點(diǎn)前顯示checkbox

    setting.check.enable設(shè)置為true

最終完整設(shè)置如下:

var setting = {
    "data": {
        "simpleData": {
            "enable": true,
            "pIdKey": "categoryId"
        }, 
        "key": {
            "name": "title"
        }
    },
    "check": {
        "enable": true
    }
};

4.4.3 獲取JSON數(shù)據(jù)并顯示樹形結(jié)構(gòu)

$("#roleTableBody").on("click",".checkBtn",function(){  
    // 打開模態(tài)框
    $("#roleAssignAuthModal").modal("show");    
    // 初始化模態(tài)框中顯示的樹形結(jié)構(gòu)
    // 1.創(chuàng)建setting對象
    var setting = {
        "data": {
            "simpleData": {
                "enable": true,
                "pIdKey": "categoryId"
            }, 
            "key": {
                "name": "title"
            }
        },
        "check": {
            "enable": true
        }
    };  
    // 2.獲取JSON數(shù)據(jù)
    var ajaxResult = $.ajax({
        "url": "assign/get/all/auth.json",
        "type": "post",
        "dataType": "json",
        "async": false
    }); 
    if(ajaxResult.responseJSON.result == "FAILED") {
        layer.msg(ajaxResult.responseJSON.message);     
        return ;
    }   
    var zNodes = ajaxResult.responseJSON.data;  
    // 3.初始化樹形結(jié)構(gòu)
    $.fn.zTree.init($("#treeDemo"), setting, zNodes);   
});

4.5 回顯已分配權(quán)限

4.5.1 獲取以前分配過的權(quán)限信息

后端代碼

handler

@ResponseBody
@RequestMapping("/assign/get/assigned/auth/id/list")
public ResultEntity<List<Integer>> getAssignedAuthIdList(@RequestParam("roleId") Integer roleId) {
    List<Integer> authIdList = authService.getAssignedAuthIdList(roleId);   
    return ResultEntity.successWithData(authIdList);
}

service

@Override
public List<Integer> getAssignedAuthIdList(Integer roleId) {
    return authMapper.selectAssignedAuthIdList(roleId);
}
<select id="selectAssignedAuthIdList" resultType="int">
    select auth_id from inner_role_auth where role_id=#{roleId}
</select>

前端代碼:

在$("#roleTableBody").on("click",".checkBtn",function(){}函數(shù)內(nèi)

// 5.查詢以前已經(jīng)分配過的authId
ajaxResult = $.ajax({
    "url": "assign/get/assigned/auth/id/list.json",
    "type": "post",
    "data": {
        "roleId": $(this).attr("roleId"),
        "random": Math.random()
    },
    "dataType": "json",
    "async": false
});
if(ajaxResult.responseJSON.result == "FAILED") {
    layer.msg(ajaxResult.responseJSON.message);
    return ;
}
var authIdList = ajaxResult.responseJSON.data;

4.5.2 根據(jù)以前分配的信息勾選樹形節(jié)點(diǎn)

// 6.使用authIdList勾選對應(yīng)的樹形節(jié)點(diǎn)
// ①遍歷authIdList
for (var i = 0; i < authIdList.length; i++) {
    // ②在遍歷過程中獲取每一個(gè)authId
    var authId = authIdList[i];
    // ③根據(jù)authId查詢到一個(gè)具體的樹形節(jié)點(diǎn)
    // key:查詢節(jié)點(diǎn)的屬性名
    // value:查詢節(jié)點(diǎn)的屬性值,這里使用authId
    var key = "id";
    var treeNode = $.fn.zTree.getZTreeObj("treeDemo").getNodeByParam(key, authId);
    // ④勾選找到的節(jié)點(diǎn)
    // treeNode:當(dāng)前要勾選的節(jié)點(diǎn)
    // true:表示設(shè)置為勾選狀態(tài)
    // false:表示不聯(lián)動(dòng)
    $.fn.zTree.getZTreeObj("treeDemo").checkNode(treeNode, true, false);    
}

※為什么不能聯(lián)動(dòng):在聯(lián)動(dòng)模式下,子菜單A勾選會(huì)導(dǎo)致父菜單勾選,父菜單勾選會(huì)根據(jù)“聯(lián)動(dòng)”效果,把子菜單B、子菜單C也勾選,可是實(shí)際上B、C不應(yīng)該勾選,這就會(huì)產(chǎn)生錯(cuò)誤。

4.6 執(zhí)行分配

4.6.1前端代碼

// 給在模態(tài)框中的分配按鈕綁定單擊響應(yīng)函數(shù)
$("#roleAssignAuthBtn").click(function(){
    var authIdArray = new Array();
    // 調(diào)用zTreeObj的方法獲取當(dāng)前已經(jīng)被勾選的節(jié)點(diǎn)
    var checkedNodes = $.fn.zTree.getZTreeObj("treeDemo").getCheckedNodes();
    // 遍歷checkedNodes
    for(var i = 0; i < checkedNodes.length; i++) {
        // 獲取具體的一個(gè)節(jié)點(diǎn)
        var node = checkedNodes[i];
        // 獲取當(dāng)前節(jié)點(diǎn)的id屬性
        var authId = node.id;
        // 將authId存入數(shù)組
        authIdArray.push(authId);
    }
    // 在handler方法中使用@RequestBody接收
    // 方便使用的數(shù)據(jù)類型是:@RequestBody Map<String, List<Integer>>
    // {"roleIdList":[2],"authIdList":[2,3,5,7]}
    // 封裝要發(fā)送給handler的JSON數(shù)據(jù)
    var requestBody = {"roleIdList":[window.roleId], "authIdList": authIdArray};
    // 發(fā)送請求
    var ajaxResult = $.ajax({
        "url": "assign/do/assign.json",
        "type": "post",
        "data": JSON.stringify(requestBody),
        "contentType": "application/json;charset=UTF-8",
        "dataType": "json",
        "async": false
    });
    if(ajaxResult.responseJSON.result == "SUCCESS") {
        layer.msg("操作成功!");
    }
    if(ajaxResult.responseJSON.result == "FAILED") {
        layer.msg(ajaxResult.responseJSON.message);
    }
    $("#roleAssignAuthModal").modal("hide");
});

4.6.2 后端代碼

handler

@ResponseBody
@RequestMapping("/assign/do/assign")
public ResultEntity<String> daRoleAssignAuth(@RequestBody Map<String,List<Integer>> assignDataMap){
    authService.updateRelationShipBetweenRoleAndAuth(assignDataMap);
    return ResultEntity.successWithoutData();
}

service

@Override
public void updateRelationShipBetweenRoleAndAuth(Map<String, List<Integer>> assignDataMap) {
    // 1.獲取兩部分List數(shù)據(jù)
    List<Integer> roleIdList = assignDataMap.get("roleIdList");
    List<Integer> authIdList = assignDataMap.get("authIdList");
    // 2.取出roleId
    Integer roleId = roleIdList.get(0);
    // 3.刪除舊數(shù)據(jù)
    authMapper.deleteOldRelationship(roleId);
    // 4.保存新數(shù)據(jù)
    if(CrowdFundingUtils.collectionEffective(authIdList)) {
        authMapper.insertNewRelationship(roleId, authIdList);
    }
}

SQL

<delete id="deleteOldRelationship">
    delete from inner_role_auth where role_id=#{roleId}
</delete>
<insert id="insertNewRelationship">
    insert into inner_role_auth(role_id,auth_id)
    values
    <foreach collection="authIdList" item="authId" separator=",">(#{roleId},#{authId})</foreach>
</insert>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容