菜單管理又稱爲資源管理,是系統資源對外的表現形式。本模塊主要是實現對菜單進行添加、修改、查詢、刪除等操做。javascript
CREATE TABLE `sys_menus` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL COMMENT '資源名稱', `url` varchar(200) DEFAULT NULL COMMENT '資源URL', `type` int(11) DEFAULT NULL COMMENT '類型 1:菜單 2:按鈕', `sort` int(11) DEFAULT NULL COMMENT '排序', `note` varchar(100) DEFAULT NULL COMMENT '備註', `parentId` int(11) DEFAULT NULL COMMENT '父菜單ID,一級菜單爲0', `permission` varchar(500) DEFAULT NULL COMMENT '受權(如:sys:user:create)', `createdTime` datetime DEFAULT NULL COMMENT '建立時間', `modifiedTime` datetime DEFAULT NULL COMMENT '修改時間', `createdUser` varchar(20) DEFAULT NULL COMMENT '建立用戶', `modifiedUser` varchar(20) DEFAULT NULL COMMENT '修改用戶', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='資源管理';
菜單表與角色表是多對多的關係,在表設計時,多對多關係一般由中間表(關係表)進行維護css
基於角色菜單表的設計,其角色和菜單對應的關係數據要存儲到關係表中,其具體存儲形式
菜單與角色的關係表腳本設計以下:html
CREATE TABLE `sys_role_menus` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_id` int(11) DEFAULT NULL COMMENT '角色ID', `menu_id` int(11) DEFAULT NULL COMMENT 'ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='角色與菜單對應關係';
當在主頁左側菜單欄,點擊菜單管理時,在主頁內容呈現區,呈現菜單列表頁面java
當在菜單列表頁面點擊添加按鈕時,異步加載菜單編輯頁面,並在列表內容呈現區,呈現菜單編輯頁面,如圖-4所示。node
在菜單編輯頁面選擇上級菜單時,異步加載菜單信息,並以樹結構的形式呈現上級菜單jquery
菜單管理業務後臺API分層架構及調用關係如圖web
▪ 業務描述與設計實現ajax
首先準備菜單列表頁面(/templates/pages/sys/menu_list.html),而後在starter.html頁面中點擊菜單管理時異步加載菜單列表頁面。spring
▪ 關鍵代碼設計與實現數據庫
找到項目中的starter.html頁面,頁面加載完成之後,註冊菜單管理項的點擊事件,當點擊菜單管理時,執行事件處理函數。關鍵代碼以下:
$(function(){ … doLoadUI("load-menu-id","menu/menu_list") })
說明:對於doLoadUI函數,假如在starter.html中已經定義,則無需再次定義.
function doLoadUI(id,url){ $("#"+id).click(function(){ $("#mainContentId").load(url); }); }
其中,load函數爲jquery中的ajax異步請求函數。
▪ 業務描述與設計實現
本頁面呈現菜單信息時要以樹結構形式進行呈現。此樹結構會藉助jquery中的treeGrid插件進行實現,因此在菜單列表頁面須要引入treeGrid相關JS。可是,具體的treeGrid怎麼用可自行在網上進行查詢(已比較成熟)。
▪ 關鍵代碼設計與實現:
關鍵JS引入(menu_list.html),代碼以下:
<script type="text/javascript" src="bower_components/treegrid/jquery.treegrid.extension.js"></script> <script type="text/javascript" src="bowe r_components/treegrid/jquery.treegrid.min.js"></script> <script type="text/javascript" src="bower_components/treegrid/tree.table.js"></script>
頁面數據展現
菜單列表頁面加載完成,啓動菜單數據異步加載操做,本次菜單列表頁面要呈現菜單以及上級菜單信息,其數據查詢時,數據的封裝及傳遞過程
頁面菜單數據刪除展現
基於用戶在列表頁面上選擇的的菜單記錄ID,執行刪除操做,本次刪除業務實現中,首先要基於id判斷當前菜單是否有子菜單,假若有子菜單則不容許刪除,沒有則先刪除菜單角色關係數據,而後再刪除菜單自身信息。
上級菜單頁面展現
在菜單編輯頁面上,點擊上級菜單時,其數據加載時序分析
菜單數據添加實現
用戶在菜單編輯頁面輸入數據,而後異步提交到服務端,其簡易數據傳遞基本架構
用戶在菜單添加頁面中填寫好菜單數據,而後點擊保存按鈕,將用戶填寫的數據添加到數據庫。
菜單數據更新展現
當點擊編輯頁面更新按鈕時
第一步:建立SysMenuDao層接口
package com.cy.pj.sys.dao; import com.cy.pj.common.pojo.Node; import com.cy.pj.sys.pojo.SysMenu; import com.cy.pj.sys.pojo.SysUserMenu; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @Mapper public interface SysMenuDao { List<SysUserMenu> findMenusByIds(List<Integer> menuIds); //基於菜單ID獲取受權表示 List<String> findPermissions(List<Integer> menuIds); int updateObject(SysMenu entity); @Insert(" insert into sys_menus " + "(name,url,type,sort,note,parentId,permission,createdTime,modifiedTime,createdUser,modifiedUser) " + "values " + "(#{name},#{url},#{type},#{sort},#{note},#{parentId},#{permission},now(),now(),#{createdUser},#{modifiedUser})") int insertObject(SysMenu entity); @Select("select id,name,parentId from sys_menus") List<Node> findZtreeMenuNodes(); @Select("select count(*) from sys_menus where parentId=#{id}") int getChildCount(Integer id); @Delete("delete from sys_menus where id=#{id}") int deleteObject(Integer id); //查詢全部菜單信息 List<Map<String,Object>> findObjects(); }
第二步:建立SysMenuMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cy.pj.sys.dao.SysMenuDao"> <resultMap type="com.cy.pj.sys.pojo.SysUserMenu" id="sysUserMenu"> <!-- 一級菜單映射 --> <id property="id" column="id"/> <result property="name" column="name"/> <result property="url" column="url"/> <!-- 二級菜單映射 --> <collection property="childs" ofType="com.cy.pj.sys.pojo.SysUserMenu"> <id property="id" column="cid"/> <result property="name" column="cname"/> <result property="url" column="curl"/> </collection> </resultMap> <select id="findMenusByIds" resultMap="sysUserMenu"> select p.id,p.name,p.url,c.id cid,c.name cname,c.url curl from sys_menus p join sys_menus c on c.parentId=p.id <where> <foreach collection="menuIds" open="(" close=")" separator="or" item="menuId"> c.id=#{menuId} </foreach> and p.parentId is null </where> </select> <select id="findPermissions" resultType="string"> select permission <!-- sys:user:update --> from sys_menus where id in <foreach collection="menuIds" open="(" close=")" separator="," item="item"> #{item} </foreach> </select> <!--查詢全部菜單以及菜單對應的上級菜單,當沒有上級菜單時,當前菜單的上級菜單顯示爲null--> <select id="findObjects" resultType="map"> /*方法1(左外關聯查詢)*/ /*select c.*,p.name parentName from sys_menus c left join sys_menus p on c.parentId=p.id*/ /*方法2(嵌套查詢)*/ select c.*,(select p.name from sys_menus p where c.parentId=p.id) parentName from sys_menus c </select> <update id="updateObject" parameterType="com.cy.pj.sys.pojo.SysMenu"> update sys_menus set name=#{name}, type=#{type}, sort=#{sort}, url=#{url}, parentId=#{parentId}, permission=#{permission}, modifiedUser=#{modifiedUser}, modifiedTime=now() where id=#{id} </update> </mapper>
第三步:建立SysMenuService接口
在菜單查詢中,業務層對象主要是藉助數據層對象完成菜單數據的查詢。後續還能夠基於AOP對數據進行緩存,記錄訪問日誌等。
package com.cy.pj.sys.servive; import com.cy.pj.common.pojo.Node; import com.cy.pj.sys.pojo.SysMenu; import com.cy.pj.sys.pojo.SysUserMenu; import java.util.List; import java.util.Map; public interface SysMenuService { List<SysUserMenu> findUserMenusByUserId(Integer id); int updateObject(SysMenu entity); int saveObject(SysMenu entity); List<Node> findZtreeMenuNodes(); int deleteObject(Integer id); List<Map<String,Object>> findObjects(); }
第四步:建立SysMenuServiceImpl實現類
package com.cy.pj.sys.servive.impl; import com.cy.pj.common.exception.ServiceException; import com.cy.pj.common.pojo.Node; import com.cy.pj.sys.dao.SysUserRoleDao; import com.cy.pj.sys.pojo.SysMenu; import com.cy.pj.sys.dao.SysMenuDao; import com.cy.pj.sys.dao.SysRoleMenuDao; import com.cy.pj.sys.pojo.SysUserMenu; import com.cy.pj.sys.servive.SysMenuService; import io.micrometer.core.instrument.util.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class SysMenuServiceImpl implements SysMenuService { @Autowired private SysMenuDao sysMenuDao; @Autowired private SysRoleMenuDao sysRoleMenuDao; @Autowired private SysUserRoleDao sysUserRoleDao; @Override public List<SysUserMenu> findUserMenusByUserId(Integer id) { //1.對用戶id進行判斷 //2.基於用戶id查找用戶對應的角色id List<Integer> roleIds= sysUserRoleDao.findRoleIdsByUserId(id); //3.基於角色id獲取角色對應的菜單信息,並進行封裝. List<Integer> menuIds= sysRoleMenuDao.findMenuIdsByRoleIds(roleIds); //4.基於菜單id獲取用戶對應的菜單信息並返回 return sysMenuDao.findMenusByIds(menuIds); } @Override public int updateObject(SysMenu entity) { //1.合法驗證 if(entity==null) throw new ServiceException("保存對象不能爲空"); if(StringUtils.isEmpty(entity.getName())) throw new ServiceException("菜單名不能爲空"); //2.更新數據 int rows=sysMenuDao.updateObject(entity); if(rows==0) throw new ServiceException("記錄可能已經不存在"); //3.返回數據 return rows; } @Override public int saveObject(SysMenu entity) { //1.合法驗證 if(entity==null) throw new IllegalArgumentException("保存對象不能爲空"); if(StringUtils.isEmpty(entity.getName())) throw new IllegalArgumentException("菜單名不能爲空"); //2.保存數據 int rows=sysMenuDao.insertObject(entity); //3.返回數據 return rows; } @Override public List<Node> findZtreeMenuNodes() { return sysMenuDao.findZtreeMenuNodes(); } @Override public int deleteObject(Integer id) { //1,參數校驗 if(id==null||id<1) throw new IllegalArgumentException("id值無效"); //2,斷定菜單是否有子菜單,有則不容許刪除 int childCount=sysMenuDao.getChildCount(id); if(childCount>0) throw new ServiceException("請先刪除子菜單"); //3,刪除關係數據 sysRoleMenuDao.deleteObjectsByMenuId(id); int rows=sysMenuDao.deleteObject(id); //4,刪除自身信息 if(rows==0) throw new ServiceException("記錄可能已經不存在"); return rows; } @Override public List<Map<String, Object>> findObjects() { return sysMenuDao.findObjects(); } }
第五步:建立SysMenuController控制層
控制層對象主要負責請求和響應數據的處理,例如,本模塊經過業務層對象執行業務邏輯,再經過VO對象封裝響應結果(主要對業務層數據添加狀態信息),最後將響應結果轉換爲JSON格式的字符串響應到客戶端。
package com.cy.pj.sys.controller; import com.cy.pj.common.pojo.JsonResult; import com.cy.pj.sys.pojo.SysMenu; import com.cy.pj.sys.servive.SysMenuService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SysMenuController { @Autowired private SysMenuService sysMenuService; @RequestMapping("/menu/doUpdateObject") public JsonResult doUpdateObject(SysMenu entity){ sysMenuService.updateObject(entity); return new JsonResult("update ok"); } @RequestMapping("/menu/doSaveObject") public JsonResult doSaveObject(SysMenu entity){ sysMenuService.saveObject(entity); return new JsonResult("save ok"); } @RequestMapping("/menu/doFindZtreeMenuNodes") public JsonResult doFindZtreeMenuNodes(){ return new JsonResult( sysMenuService.findZtreeMenuNodes()); } @RequestMapping("/menu/doDeleteObject") public JsonResult doDeleteObject(Integer id){ sysMenuService.deleteObject(id); return new JsonResult("delete ok"); } @GetMapping("menu/doFindObjects") public JsonResult doFindObjects(){ return new JsonResult(sysMenuService.findObjects()); } }
第六步:建立SysRoleMenuDao接口
package com.cy.pj.sys.dao; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; @Mapper public interface SysRoleMenuDao { List<Integer> findMenuIdsByRoleIds( @Param("roleIds")List<Integer> roleIds); int insertObjects( @Param("roleId")Integer roleId, @Param("menuIds")Integer[] menuIds); @Delete("delete from sys_role_menus where role_id=#{roleId}") int deleteObjectsByRoleId(Integer roleId); //基於菜單id執行關係 @Delete("delete from sys_role_menus where menu_id=#{menuId}") int deleteObjectsByMenuId(Integer menuId); }
第七步:建立SysRoleMenuMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.cy.pj.sys.dao.SysRoleMenuDao"> <select id="findMenuIdsByRoleIds" resultType="int"> select menu_id from sys_role_menus where role_id in <foreach collection="roleIds" open="(" close=")" separator="," item="item"> #{item} </foreach> </select> <select id="findMenuIdsByRoleId" resultType="int"> select menu_id from sys_role_menus where role_id=#{id} </select> <insert id="insertObjects"> insert into sys_role_menus (role_id,menu_id) values <foreach collection="menuIds" separator="," item="menuId"> (#{roleId},#{menuId}) </foreach> </insert> </mapper>
第八步:建立Node 類
定義值對象封裝查詢到的上級菜單id,name,parentId信息。
package com.cy.pj.common.pojo; import lombok.Data; import java.io.Serializable; @Data public class Node implements Serializable { private static final long serialVersionUID = -7022202313802285223L; private Integer id; private String name; private Integer parentId; }
第九步:建立SysMenu 類
定義持久化對象,封裝客戶端請求數據,並將數據傳遞到數據層進行持久化。
package com.cy.pj.sys.pojo; import lombok.Data; import java.io.Serializable; import java.util.Date; @Data public class SysMenu implements Serializable { private static final long serialVersionUID = -1086340530112865421L; private Integer id; /**菜單名稱*/ private String name; /**菜單url: log/doFindPageObjects*/ private String url; /**菜單類型(兩種:按鈕,普通菜單)*/ private Integer type=1; /**排序(序號)*/ private Integer sort; /**備註*/ private String note; /**上級菜單id*/ private Integer parentId; /**菜單對應的權限標識(sys:log:delete)*/ private String permission; /**建立用戶*/ private String createdUser; /**修改用戶*/ private String modifiedUser; private Date createdTime; private Date modifiedTime; }
menu_list.html
<div class="row"> <div class="col-xs-12"> <div class="box"> <div class="box-header"> <h3 class="box-title"> 菜單管理</h3> <div class="box-tools"> <div class="input-group input-group-sm" style="width: 100px;"> <div class="input-group-btn"> <button type="button" class="btn btn-success btn-delete"> 刪除</button> <button type="button" class="btn btn-default btn-add">添加</button> <button type="button" class="btn btn-default btn-update">修改</button> </div> </div> </div> </div> <!-- /.box-header --> <div class="box-body table-responsive no-padding"> <table id="menuTable" class="table table-hover"> <thead> <tr> <th data-field="selectItem" data-checkbox="true"></th> </tr> </thead> </table> </div> </div> <!-- /.box --> </div> </div> <script type="text/javascript" src="bower_components/treegrid/jquery.treegrid.extension.js"></script> <script type="text/javascript" src="bower_components/treegrid/jquery.treegrid.min.js"></script> <script type="text/javascript" src="bower_components/treegrid/tree.table.js"></script> <script type="text/javascript"> /** * 初始化表格的列 */ var columns = [ { field : 'selectItem', radio : true }, { title : '菜單ID', field : 'id', align : 'center', valign : 'middle', width : '80px' }, { title : '菜單名稱', field : 'name', align : 'center', valign : 'middle', width : '130px' }, { title : '上級菜單', field : 'parentName', align : 'center', valign : 'middle', sortable : true, width : '100px' }, { title : '類型', field : 'type', align : 'center', valign : 'middle', width : '70px', formatter : function(item, index) { if (item.type == 1) { return '<span class="label label-success">菜單</span>'; } if (item.type == 2) { return '<span class="label label-warning">按鈕</span>'; } } }, { title : '排序號', field : 'sort', align : 'center', valign : 'middle', sortable : true, width : '70px' }, { title : '菜單URL', field : 'url', align : 'center', valign : 'middle', width : '160px' }, { title : '受權標識',//要顯示的標題名稱 field : 'permission',//json串中的key align : 'center',//水平居中 valign : 'middle',//垂直居中 sortable : false //是否排序 } ];//格式來自官方demos -->treeGrid(jquery擴展的一個網格樹插件) $(function(){ doGetObjects(); $(".input-group-btn") .on("click",".btn-delete",doDeleteObject) .on("click",".btn-add,.btn-update",doLoadEditUI); }) function doLoadEditUI(){ var title; //基於點擊對象的class屬性值,修改標題 if($(this).hasClass("btn-add")){ title="添加菜單"; }else{ title="修改菜單"; var item=doGetCheckedItem(); if(!item){ alert("請先選擇"); return; } $("#mainContentId") .data("rowData",item); } //異步加載編輯頁面 var url="menu/menu_edit"; $("#mainContentId").load(url,function(){ $(".box-title").html(title); }) } function doGetCheckedItem(){ return $("tbody input[type='radio']:checked") .parents("tr").data("rowData"); } function doGetCheckedId(){ //方法1: //var radio=$("tbody input[type='radio']:checked"); //if(radio)return radio.val(); //方法2: //1.獲取選中的記錄 var selections=$("#menuTable") //bootstrapTreeTable是treeGrid插件內部定義的jquery擴展函數 //getSelections爲擴展函數內部要調用的一個方法 .bootstrapTreeTable("getSelections"); //2.對記錄進行斷定 if(selections.length==1) return selections[0].id; } function doDeleteObject(){ //1.獲取選中記錄的id值 var id=doGetCheckedId(); console.log("id="+id); if(!id){ alert("請先選中"); return; } //2.給出提示是否確認刪除 if(!confirm("確認刪除嗎"))return; //3.發送異步請求執行刪除操做 //3.1定義請求參數 var params={"id":id}; //3.2定義請求url var url="menu/doDeleteObject"; //3.3發送異步請求 $.post(url,params,function(result){ if(result.state==1){ alert(result.message); $("tbody input[type='radio']:checked") .parents("tr").remove(); }else{ alert(result.message); } }) } function doGetObjects(){ //移除mainContentId位置的數據 $("#mainContentId").removeData(); var treeTable=new TreeTable( "menuTable",//tableId "menu/doFindObjects",//url columns);//表中列的配置 //treeTable.setExpandColumn(2); //作表格初始化 treeTable.init(); //發起ajax請求(藉助ajax函數) }
菜單列表頁面(/templates/pages/sys/menu_edit.html)
<!-- Horizontal Form --> <div class="box box-info"> <div class="box-header with-border"> <h3 class="box-title">添加菜單</h3> </div> <!-- /.box-header --> <!-- form start --> <form class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label for="nameId" class="col-sm-2 control-label">類型</label> <div class="col-sm-10 typeRadio"> <label class="radio-inline"> <input type="radio" name="typeId" value="1" checked> 菜單 </label> <label class="radio-inline"> <input type="radio" name="typeId" value="2"> 按鈕 </label> </div> </div> <div class="form-group"> <label for="nameId" class="col-sm-2 control-label">菜單名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" id="nameId" placeholder="名稱"> </div> </div> <div class="form-group"> <label for="parentId" class="col-sm-2 control-label">上級菜單</label> <div class="col-sm-10"> <input type="text" class="form-control load-sys-menu" readonly="readonly" id="parentId" placeholder="上級菜單"> </div> </div> <div class="form-group"> <label for="urlId" class="col-sm-2 control-label">菜單URL</label> <div class="col-sm-10"> <input type="text" class="form-control" id="urlId" placeholder="url"> </div> </div> <div class="form-group"> <label for="permissionId" class="col-sm-2 control-label">受權標識:</label> <div class="col-sm-10"> <input type="text" id="permissionId" placeholder="多個用逗號分隔,如:user:list,user:create" class="form-control"> </div> </div> <div class="form-group"> <label for="sortId" class="col-sm-2 control-label">排序號:</label> <div class="col-sm-10"> <input type="text" id="sortId" placeholder="排序號" class="form-control"> </div> </div> </div> <!-- /.box-body --> <div class="box-footer"> <button type="button" class="btn btn-default btn-cancel">Cancel</button> <button type="button" class="btn btn-info pull-right btn-save">Save</button> </div> <!-- /.box-footer --> </form> <!-- zTree 對應的div --> <div class="layui-layer layui-layer-page layui-layer-molv layer-anim" id="menuLayer" type="page" times="2" showtime="0" contype="object" style="z-index:59891016; width: 300px; height: 450px; top: 100px; left: 500px; display:none"> <div class="layui-layer-title" style="cursor: move;">選擇菜單</div> <div class="layui-layer-content" style="height: 358px;"> <div style="padding: 10px;" class="layui-layer-wrap"> <ul id="menuTree" class="ztree"></ul> <!-- 動態加載樹 --> </div> </div> <span class="layui-layer-setwin"> <a class="layui-layer-ico layui-layer-close layui-layer-close1 btn-cancel" ></a></span> <div class="layui-layer-btn layui-layer-btn-"> <a class="layui-layer-btn0 btn-confirm">肯定</a> <a class="layui-layer-btn1 btn-cancel">取消</a> </div> </div> </div> <script type="text/javascript" src="bower_components/ztree/jquery.ztree.all.min.js"></script> <script type="text/javascript" src="bower_components/layer/layer.js"> </script> <script type="text/javascript"> var zTree; //zTree是第三方擴展的一個Jquery插件 //初始化zTree時會用到 var setting = { data : { simpleData : { enable : true,//表示使用簡單數據模式 idKey : "id", //節點數據中保存惟一標識的屬性名稱 pIdKey : "parentId", //節點數據中保存其父節點惟一標識的屬性名稱 rootPId : null //根節點id }//json 格式javascript對象 } }//json 格式的javascript對象 $(function(){ $(".form-horizontal")//事件不能註冊到$("#mainContentId")對象上 .on("click",".load-sys-menu",doLoadZtreeNodes); $("#menuLayer") .on("click",".btn-confirm",doSetSelectNode) .on("click",".btn-cancel",doHideTree); $(".box-footer") .on("click",".btn-cancel",doCancel) .on("click",".btn-save",doSaveOrUpdate) var data=$("#mainContentId").data("rowData"); if(data)doInitEditFormData(data); }) function doInitEditFormData(data){ /* $("input[type='radio']").each(function(){ if($(this).val()==data.type){ $(this).prop("checked",true); } }) */ $(".typeRadio input[value='"+data.type+"']").prop("checked",true); $("#nameId").val(data.name); $("#sortId").val(data.sort); $("#urlId").val(data.url); $("#permissionId").val(data.permission); $("#parentId").val(data.parentName); $("#parentId").data("parentId",data.parentId); } //獲取表單數據 function doGetEditFormData(){ var params={ type:$("form input[name='typeId']:checked").val(), name:$("#nameId").val(), url:$("#urlId").val(), sort:$("#sortId").val(), permission:$("#permissionId").val(), parentId:$("#parentId").data("parentId") } return params; } function doSaveOrUpdate(){ //1.獲取表單數據 var params=doGetEditFormData(); var rowData= $("#mainContentId").data("rowData"); //2.異步提交表單數據(post) var insertUrl="menu/doSaveObject"; var updateUrl="menu/doUpdateObject"; var url=rowData?updateUrl:insertUrl; if(rowData)params.id=rowData.id; $.post(url,params,function(result){ if(result.state==1){ alert(result.message); doCancel(); }else{ alert(result.message); } }); } //編輯頁面cancel事件處理 function doCancel(){ //1.定義url var url="menu/menu_list"; //2.異步加載列表頁面 $("#mainContentId").load(url); } //zTree取消按鈕事件處理函數 function doHideTree(){ $("#menuLayer").css("display","none"); } //zTree肯定按鈕事件處理函數 function doSetSelectNode(){ //1.獲取選中的節點對象 var nodes=zTree.getSelectedNodes(); if(nodes.length==1){ var selectedNode=nodes[0]; console.log("selectNode",selectedNode); var rowData=$("#mainContentId").data("rowData"); if(rowData){//修改時作以下處理 //斷定當前選中的上級菜單節點是否爲當前要修改節點的子節點. var flag=isChild(rowData.id,selectedNode); if(flag){ alert("不能選擇當前節點以及對應子節點"); return; } } //2.將對象中內容,填充到表單 $("#parentId").data("parentId",selectedNode.id); $("#parentId").val(selectedNode.name); } //3.隱藏樹對象 doHideTree(); } //斷定當前選中節點是不是當前節點的子節點 function isChild(currentNodeId,selectNode){ if(selectNode.id==currentNodeId)return true; var node=selectNode.getParentNode(); if(!node)return false; return isChild(currentNodeId,node); } function doLoadZtreeNodes(){ var url="menu/doFindZtreeMenuNodes"; //異步加載數據,並初始化數據 $.getJSON(url,function(result){ if(result.state==1){ //使用init函數須要先引入ztree對應的js文件 zTree=$.fn.zTree.init( $("#menuTree"), setting, result.data);//id,name,parentId //doRemoveNodeFromZtree();//修改時,可考慮此方案 //顯示zTree對應的div $("#menuLayer").css("display","block"); }else{ alert(result.message); } }) } function doRemoveNodeFromZtree(){ //斷定是不是修改,假如是修改,從zTree中移除當前菜單以及對應子菜單 var rowData=$("#mainContentId").data("rowData"); if(rowData){//rowData有值,表示是修改. console.log("zTree",zTree); //1.獲取當前的菜單對象 var node=zTree.getNodeByParam("id",rowData.id,null); console.log("node",node); //2.移除當前菜單. zTree.removeNode(node); } } </script>