基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【七】【菜单维护模块】
2017-12-11 11:05
549 查看
大家在阅读本章的时候大家一定要把上一章的代码从GitHub上拿下来先,因此本章的以及后续章节的所有的Java代码都是基于上一章节的代码因此大家一定要记得把上一章的代码全部给clone下来,否则本章的代码大家将无法运行起来。
通过上一章节我们已经完成了我们的基本架构的开发工作,那么这一章我们将开发我们的菜单维护模块,实现对菜单的增删改查的功能,该模块的菜单树使用的是ztree的前端js的代码,首先在我们开发该模块的时候我们需要到WebMvcConfig中增加如下配置:
接着我们开始编写我们的菜单模块的代码首先建如下的文件路径,同时我们实现我们的菜单维护的业务逻辑:
首先是treeList.html的页面的代码(该页面使用了bootstrap和ztree)
最后是update.html修改菜单页面的代码:
到此我们完成了菜单模块的开发工作,由于java代码我们在上一章已经完成了全部的开发因此此处就不再继续陈述了,开发完成以后大家可以直接运行程序查看结果如下:
本章代码的GitHub地址:https://github.com/185594-5-27/csdndemo/tree/master-base-tree
上一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】
下一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【八】【完善整个项目】
QQ交流群:578746866
通过上一章节我们已经完成了我们的基本架构的开发工作,那么这一章我们将开发我们的菜单维护模块,实现对菜单的增删改查的功能,该模块的菜单树使用的是ztree的前端js的代码,首先在我们开发该模块的时候我们需要到WebMvcConfig中增加如下配置:
接着我们开始编写我们的菜单模块的代码首先建如下的文件路径,同时我们实现我们的菜单维护的业务逻辑:
首先是treeList.html的页面的代码(该页面使用了bootstrap和ztree)
<html xmlns:th="http://www.thymeleaf.org" > <head th:include="include/includebase"></head> <body> <div id="content" class="row-fluid"> <div class="col-md-3 " style="margin-top: 10px;"> <ul id="menu_tree" class="ztree" style="width:560px; overflow:auto;"></ul> </div> </div> <script th:inline="javascript"> var zTree; var demoIframe; var selectNode; function addHoverDom(treeId, treeNode) { var sObj = $("#" + treeNode.tId + "_span"); if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return; var addStr = "<span class='button remove' id='removeBtn_" + treeNode.tId + "' title='add node' onfocus='this.blur();'></span>"; addStr += "<span class='button add' id='addBtn_" + treeNode.tId + "'></span>"; addStr += "<span class='button edit' id='editBtn_" + treeNode.tId + "'></span>"; if(treeNode.isParent){ addStr += "<span class='button add' id='addParentBtn_" + treeNode.tId + "'></span>"; } sObj.after(addStr); var btn = $("#addBtn_"+treeNode.tId); if (btn) btn.bind("click", function(){ zTree = $.fn.zTree.getZTreeObj("menu_tree"); selectNode = treeNode; window.Ewin.dialog({title:"添加",url:"tree/addTreePage?id="+treeNode.id,width:400,height:650}) return false; }); var remove_btn = $("#removeBtn_"+treeNode.tId); if (remove_btn) remove_btn.bind("click", function() { zTree = $.fn.zTree.getZTreeObj("menu_tree"); if (treeNode.isParent) { window.Ewin.alert({message:"请先删除当前菜单节点底下的子菜单!"}); }else{ window.Ewin.confirm({title: '提示', message: '是否要删除您当前选中的菜单节点?', width: 500}).on(function (e) { if (e) { $.post("tree/remove",{id:treeNode.id},function(e){ if(e.result){ zTree.removeNode(treeNode); window.Ewin.alert({message:e.msg}); }else{ window.Ewin.alert({message:e.msg}); } }) } }); } return false; }); var edit_btn = $("#editBtn_"+treeNode.tId); if (edit_btn) edit_btn.bind("click", function(){ zTree = $.fn.zTree.getZTreeObj("menu_tree"); selectNode = treeNode; window.Ewin.dialog({title:"修改",url:"tree/updateTreePage?id="+treeNode.id,width:400,height:650}) return false; 4000 }); var add_parent_btn = $("#addParentBtn_"+treeNode.tId); if (add_parent_btn) add_parent_btn.bind("click", function(){ zTree = $.fn.zTree.getZTreeObj("menu_tree"); selectNode = null; window.Ewin.dialog({title:"添加",url:"tree/addTreePage",width:400,height:650}) return false; }) }; function removeHoverDom(treeId, treeNode) { $("#addBtn_"+treeNode.tId).unbind().remove(); $("#removeBtn_"+treeNode.tId).unbind().remove(); $("#editBtn_"+treeNode.tId).unbind().remove(); $("#addParentBtn_"+treeNode.tId).unbind().remove(); }; var setting = { check: { enable: false }, view: { addHoverDom: addHoverDom, removeHoverDom: removeHoverDom, dblClickExpand: false, showLine: true, selectedMulti: false }, data: { simpleData: { enable:true, idKey: "id", pIdKey: "pId", rootPId: "0" } }, callback: { beforeClick: function(treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj('menu_tree'); if (treeNode.isParent) { zTree.expandNode(treeNode); return false; } else { return true; } } } }; function loadReady() { var bodyH = demoIframe.contents().find("body").get(0).scrollHeight, htmlH = demoIframe.contents().find("html").get(0).scrollHeight, maxH = Math.max(bodyH, htmlH), minH = Math.min(bodyH, htmlH), h = demoIframe.height() >= maxH ? minH:maxH; if (h < 530){ h = 530; } demoIframe.height(h); } $(function() { $.post("/tree/loadUserTree",function(info){ var t = $("#menu_tree"); t = $.fn.zTree.init(t, setting,info.data); }) }); </script> </body> </html>接着是add.html增加菜单的页面的代码:
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <body> <form id="treeForm" role="form" method="post" action="tree/save"> <input type="hidden" name="pId" th:value="${entity.id}" /> <div class="form-group" > <label >父菜单名称:</label> <input type="text" class="form-control" th:value="${entity.name}" readonly="readonly" /> </div> <div class="form-group"> <label for="name">菜单名称:</label> <input type="text" class="form-control" name="name" id="name" placeholder="请输入菜单名称" /> </div> <div class="form-group"> <label for="url">菜单地址:</label> <input type="text" class="form-control" name="url" id="url" placeholder="请输入菜单地址" /> </div> <div class="form-group"> <label for="icon">菜单样式:</label> <input type="text" class="form-control" name="icon" id="icon" placeholder="请输入菜单样式" /> </div> <div class="form-group"> <label for="url">菜单编码:</label> <input type="text" class="form-control" name="code" id="code" placeholder="请输入菜单编码" /> </div> <div class="form-group"> <label for="treeOrder">菜单顺序:</label> <input type="text" class="form-control" name="treeOrder" id="treeOrder" placeholder="请输入菜单顺序" /> </div> <div class="form-group"> <label >菜单状态:</label> <label class='radio-inline'><input type='radio' name='state' value='1' checked="checked" />可用</label> <label class='radio-inline'><input type='radio' name='state' value='0' />禁用</label> </div> </form> <script th:inline="javascript"> <![CDATA[ $(function () { $('#treeForm').bootstrapValidator({ message: 'This value is not valid', feedbackIcons: { valid: 'glyphicon glyphicon-ok', invalid: 'glyphicon glyphicon-remove', validating: 'glyphicon glyphicon-refresh' }, fields: { name: { message: '菜单名称验证失败', validators: { notEmpty: { message: '菜单名称不能为空' } } }, url: { message: '菜单地址验证失败', validators: { notEmpty: { message: '菜单地址不能为空' } } }, code: { message: '菜单编码验证失败', validators: { notEmpty: { message: '菜单编码不能为空' } } }, treeOrder: { message: '菜单顺序验证失败', validators: { notEmpty: { message: '菜单顺序不能为空' }, regexp: { regexp: /^[0-9_]+$/, message: '菜单顺序必须为数字' }, stringLength: { min: 1, max: 18, message: '菜单顺序必须在1到18位之间' } } } } }) // 绑定dialog的确定按钮的监听事件 $("#btnOk",window.top.document).click(function() { var bootstrapValidator = $("#treeForm", window.top.document).data('bootstrapValidator'); bootstrapValidator.validate(); if(bootstrapValidator.isValid()){ var zTree = $(window.parent.document).contents().find(".tab-pane.fade.active.in iframe")[0].contentWindow.zTree; var selectNode = $(window.parent.document).contents().find(".tab-pane.fade.active.in iframe")[0].contentWindow.selectNode; $.post($("#treeForm",window.top.document).attr('action'),$("#treeForm",window.top.document).serialize(),function(e){ if(e.result){ $('.modal-dialog', window.top.document).parent('div').remove() $('body', window.top.document).find('.modal-backdrop').remove(); var entity = e.entity; zTree.addNodes(selectNode, {id:entity.id, pId:entity.pId, name:entity.name}); window.Ewin.alert({message:'增加数据成功!'}); }else{ window.Ewin.alert({message:'增加数据失败!'}); } }) } }); }) ]]> </script> </body> </html>
最后是update.html修改菜单页面的代码:
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <body> <form id="treeForm" role="form" method="post" action="tree/update"> <input type="hidden" name="pId" th:value="${entity.tree.id}" /> <input type="hidden" name="id" th:value="${entity.id}" /> <div class="form-group" > <label >父菜单名称:</label> <input type="text" class="form-control" th:value="${entity.tree.name}" readonly="readonly" /> </div> <div class="form-group"> <label for="name">菜单名称:</label> <input type="text" class="form-control" name="name" id="name" th:value="${entity.name}" placeholder="请输入菜单名称" /> </div> <div class="form-group"> <label for="url">菜单地址:</label> <input type="text" class="form-control" name="url" id="url" th:value="${entity.url}" placeholder="请输入菜单地址" /> </div> <div class="form-group"> <label for="icon">菜单样式:</label> <input type="text" class="form-control" name="icon" id="icon" th:value="${entity.icon}" placeholder="请输入菜单样式" /> </div> <div class="form-group"> <label for="url">菜单编码:</label> <input type="text" class="form-control" name="code" id="code" th:value="${entity.code}" placeholder="请输入菜单编码" /> </div> <div class="form-group"> <label for="treeOrder">菜单顺序:</label> <input type="text" class="form-control" name="treeOrder" id="treeOrder" th:value="${entity.treeOrder}" placeholder="请输入菜单顺序" /> </div> <div class="form-group"> <label for="treeOrder">菜单状态:</label> <label class='radio-inline'><input type='radio' name='state' value='1' th:checked="${entity.state} == 1?true:false" />可用</label> <label class='radio-inline'><input type='radio' name='state' value='0' th:checked="${entity.state} == 0?true:false" />禁用</label> </div> </form> <script th:inline="javascript"> <![CDATA[ $(function () { $('#treeForm').bootstrapValidator({ message: 'This value is not valid', feedbackIcons: { valid: 'glyphicon glyphicon-ok', invalid: 'glyphicon glyphicon-remove', validating: 'glyphicon glyphicon-refresh' }, fields: { name: { message: '菜单名称验证失败', validators: { notEmpty: { message: '菜单名称不能为空' } } }, url: { message: '菜单地址验证失败', validators: { notEmpty: { message: '菜单地址不能为空' } } }, code: { message: '菜单编码验证失败', validators: { notEmpty: { message: '菜单编码不能为空' } } }, treeOrder: { message: '菜单顺序验证失败', validators: { notEmpty: { message: '菜单顺序不能为空' }, regexp: { regexp: /^[0-9_]+$/, message: '菜单顺序必须为数字' }, stringLength: { min: 1, max: 18, message: '菜单顺序必须在1到18位之间' } } } } }) // 绑定dialog的确定按钮的监听事件 $("#btnOk",window.top.document).click(function() { var bootstrapValidator = $("#treeForm", window.top.document).data('bootstrapValidator'); bootstrapValidator.validate(); if(bootstrapValidator.isValid()){ var zTree = $(window.parent.document).contents().find(".tab-pane.fade.active.in iframe")[0].contentWindow.zTree; var selectNode = $(window.parent.document).contents().find(".tab-pane.fade.active.in iframe")[0].contentWindow.selectNode; $.post($("#treeForm",window.top.document).attr('action'),$("#treeForm",window.top.document).serialize(),function(e){ if(e.result){ $('.modal-dialog', window.top.document).parent('div').remove() $('body', window.top.document).find('.modal-backdrop').remove(); var entity = e.entity; selectNode.name = entity.name; zTree.updateNode(selectNode); window.Ewin.alert({message:'修改数据成功!'}); }else{ window.Ewin.alert({message:'修改数据失败!'}); } }) } }); }) ]]> </script> </body> </html>
到此我们完成了菜单模块的开发工作,由于java代码我们在上一章已经完成了全部的开发因此此处就不再继续陈述了,开发完成以后大家可以直接运行程序查看结果如下:
本章代码的GitHub地址:https://github.com/185594-5-27/csdndemo/tree/master-base-tree
上一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】
下一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【八】【完善整个项目】
QQ交流群:578746866
相关文章推荐
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【一】【构建工程】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【八】【完善整个项目】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【四】【编写基础开发工具】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【九】【整合websocket】
- 一步步教你如何用疯狂.NET架构中的通用权限系统 -- (用户 - 角色 - 操作权限 - 模块菜单)之间的关联关系
- 一步步教你如何用疯狂.NET架构中的通用权限系统 -- (用户 - 角色 - 操作权限 - 模块菜单)之间的关联关系
- 一步步教你如何用疯狂.NET架构中的通用权限系统 -- (用户 - 角色 - 操作权限 - 模块菜单)之间的关联关系
- 搭建一套自己实用的.net架构(2)【日志模块-log4net】
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(十二)【权限架构生产者(菜单管理)】
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(十七)【权限架构系统(基础框架搭建)】
- 基于吉日嘎底层架构的Web端权限管理操作演示-菜单模块管理
- 一步步教你如何用疯狂.NET架构中的通用权限系统 -- (用户 - 角色 - 操作权限 - 模块菜单)之间的关联关系
- 一套网站架构完整方案
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(八)【权限架构生产者(swagger2集成)】
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(十六)【路由网关】
- MDI程序中反射生成菜单并与权限控制的结合(利用XML将模块组件装配与卸载)