|
京淘
权限管理系统
菜单管理
Day21
1. 菜单列表模块 1-2
1.1. 业务描述 1-2
1.2. 服务端设计及实现 1-3
1.2.1. 创建表sys_menus 1-3
1.2.2. DAO接口及方法定义 1-4
1.2.3. Mapper元素定义 1-4
1.2.4. Service中方法的定义 1-5
1.2.5. Controller中方法定义 1-5
1.3. 客户端设计及实现 1-5
1.3.1. 定义menu_list.html页面 1-5
1.3.2. 设置start.html页面 1-8
2. 菜单删除模块 2-9
2.1. 服务端设计及实现 2-9
2.1.1. Dao接口方法定义 2-9
2.1.2. Mapper中元素定义 2-9
2.1.3. Service接口中方法定义 2-10
2.1.4. Controller中方法定义 2-10
2.2. 客户端设计及实现 2-10
2.2.1. 删除按钮事件注册 2-10
2.2.2. 删除按钮事件处理 2-11
3. 菜单添加页面设计 3-12
3.1. 业务描述 3-12
3.2. 页面呈现 3-12
3.2.1. Controller方法定义 3-13
3.2.2. 定义添加页面 3-13
3.2.3. Js定义 3-14
4. 上级菜单操作 4-15
4.1. 服务端设计及实现 4-15
4.1.1. 定义Node对象封装树节点 4-15
4.1.2. DAO操作 4-15
4.1.3. Mapper操作 4-15
4.1.4. Service操作 4-16
4.1.5. Controller操作 4-16
4.2. 客户端设计与实现 4-16
4.2.1. 编辑页面添加DIV元素 4-17
4.2.2. 上级菜单选项注册事件 4-17
4.2.3. 上级菜单事件处理 4-18
5. 菜单数据保存 5-19
5.1. 服务端设计与实现 5-19
5.1.1. Entity类定义 5-19
5.1.2. Dao方法定义及实现 5-19
5.1.3. Service方法定义及实现 5-19
5.1.4. Controller方法定义及实现 5-20
5.2. 客户端设计与实现 5-20
5.2.1. 保存按钮事件注册 5-20
5.2.2. 保存按钮事件处理 5-20
6. 修改页面加载 6-21
6.1. 服务端实现 6-21
6.1.1. Dao方法定义 6-21
6.1.2. Mapper元素定义 6-22
6.1.3. Service方法定义 6-22
6.1.4. Controller方法定义 6-22
6.2. 客户端实现 6-23
6.2.1. 列表页面操作 6-23
6.2.2. 编辑页面操作 6-23
7. 修改页面数据保存 7-25
7.1. 服务端设计与实现 7-25
7.1.1. Dao方法定义 7-25
7.1.2. Mapper元素定义 7-25
7.1.3. Service方法定义 7-25
7.1.4. Controller方法定义 7-26
7.2. 客户端设计及实现 7-26
7.2.1. 获取表单数据异步更新 7-26
8. 总结 8-27
8.1. 重点和难点分析 8-27
8.2. 常见FAQ 8-27
菜单
点击菜单名称可展开,例如点击系统管理
服务端设计及实现
创建表sys_menus
CREATETABLE`sys_menus`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar(50)DEFAULTNULLCOMMENT''资源名称'',
`url`varchar(200)DEFAULTNULLCOMMENT''资源URL'',
`type`int(11)DEFAULTNULLCOMMENT''类型1:菜单2:按钮'',
`sort`int(11)DEFAULTNULLCOMMENT''排序'',
`note`varchar(100)DEFAULTNULLCOMMENT''备注'',
`parentId`int(11)DEFAULTNULLCOMMENT''父菜单ID,一级菜单为0'',
`permission`varchar(500)DEFAULTNULLCOMMENT''授权(如:user:create)'',
`createdTime`datetimeDEFAULTNULLCOMMENT''创建时间'',
`modifiedTime`datetimeDEFAULTNULLCOMMENT''修改时间'',
`createdUser`varchar(20)DEFAULTNULLCOMMENT''创建用户'',
`modifiedUser`varchar(20)DEFAULTNULLCOMMENT''修改用户'',
PRIMARYKEY(`id`)
)ENGINE=InnoDBAUTO_INCREMENT=141DEFAULTCHARSET=utf8;
DAO接口及方法定义
在此模块没有分页,没有查询,重点是要查询本菜单和一级.
publicinterfaceSysMenuDao{
List |
页面中添加js(第一步需要将treegrid放到项目对应目录)
/
初始化表格的列(这些列如何定义,按照treeGrid规范即可
我自己在实现时是先treeGridDemo案例,然后从拷贝
实现./
varcolunms=[
{
field:''selectItem'',
radio:true
},
{
title:''菜单ID'',
field:''id'',
visible:false,
align:''center'',
valign:''middle'',
width:''80px''
},
{
title:''菜单名称'',
field:''name'',
align:''center'',
valign:''middle'',
sortable:true,
width:''180px''
},
{
title:''上级菜单'',
field:''parentName'',
align:''center'',
valign:''middle'',
sortable:true,
width:''180px''
},
{
title:''类型'',
field:''type'',
align:''center'',
valign:''middle'',
sortable:true,
width:''100px'',
formatter:function(item,index){
if(item.type==1){
return''菜单'';
}
if(item.type==2){
return''按钮'';
}
}
},
{
title:''排序号'',
field:''sort'',
align:''center'',
valign:''middle'',
sortable:true,
width:''100px''
},
{
title:''菜单URL'',
field:''url'',
align:''center'',
valign:''middle'',
sortable:true,
width:''160px''
},
{
title:''授权标识'',
field:''permission'',
align:''center'',
valign:''middle'',
sortable:true
}];
$(function(){
doGetObjects();
});
functiondoGetObjects(){
vartableId="menuTable";
vartable=newTreeTable(tableId,"menu/doFindObjects.do",colunms);
table.setExpandColumn(2);
table.init();//底层会发起异步请求加载数据,然后初始化表格}
说明:本案例中会用到treeGrid库,需要将相应的js引入到当前页面
课后了解内容(js内容进行强化,代码是treetable.js的实现原理分析)
(function(){
vartree=function(id,name){
this.id=id;
this.name=name;
};
tree.prototype={
setId:function(id){
this.id=id;
}
setName:function(name){
this.name=name;
}
};
window.tree=tree;
}())$("#load-menu-id").click(function(){
//console.log("helloworld");
$(".container-fluid").load("menu/listUI.do",function(){
$(".container-fluid").removeData("id");
});
})
菜单删除模块
服务端设计及实现
Dao接口方法定义
SysMenuDao接口中添加如下两个方法
publicinterfaceSysMenuDao{
…
inthasChild(IntegermenuId);
intdeleteObject(Integerid);
}
从业务菜单进行删除操作时只能删除树结构中的叶子节点(子的菜单的节点).
技术角度实现,在执行操作应先查询这个下有没有菜单,
通过对子元素进行统计实现.假如统计结果为没有子元素,这样
可以对菜单进行删除操作了.查询要删除的菜单是否有子菜单
selectcount()
fromsys_menus
whereparentId=#{menuId}
删除菜单按钮
deletefromsys_menuswhereid=#{id}
@Override
publicvoiddeleteObject(IntegermenuId){
if(menuId==null)
thrownewServiceException("删除菜单,菜单id不能为空!");
intcount=menuDao.hasChild(menuId);
if(count!=0)
thrownewServiceException("请先删除子菜单或按钮!");
inti=menuDao.deleteObject(menuId);
if(i!=1)thrownewServiceException("删除菜单失败!");
}@RequestMapping("doDeleteObject")
@ResponseBody
publicJsonResultdoDeleteObject(IntegermenuId){
menuService.deleteObject(menuId);
returnnewJsonResult();
}
客户端设计及实现
删除按钮事件注册
页面加载完成,采用如下语句注册事件
$(''.input-group-btn'').on(''click'',''.btn-delete'',doDeleteObject)
删除按钮事件处理
/获得选中的id值/
functiongetSelectedId(){
//1.1获得选中的对象,默认返回值为一个对象数组
varselections=$("#menuTable")
.bootstrapTreeTable("getSelections");
if(selections.length==0){
return-1;//表示没选择任何对象
}
//1.2获得选中数组中下标为0的元素id的值
returnselections[0].id;
}
//删除菜单项
functiondoDeleteObject(){
varmenuId=getSelectedId();
if(menuId==-1){
alert("请先选择");
return;
}
varparams={''menuId'':menuId};
varurl=''menu/doDeleteObject.do'';
$.post(url,params,function(result){
if(result.state==1){
alert(''删除成功!'');
doGetObjects();
}else{
alert(result.message);
}
});
}
菜单添加页面设计
业务描述
点击菜单列表页面的添加按钮
点击上级菜单时,弹出树结构,选择具体选项
页面呈现
Controller方法定义
@RequestMapping("editUI")
publicStringeditUI(){
return"sys/menu_edit";
}
定义添加页面
在WEB-INF/pages/sys/menu_edit.html,在对应div添加如下form元素
类型
菜单
按钮
菜单名称
上级菜单
菜单URL
授权标识:
placeholder="多个用逗号分隔,如:user:list,user:create"
class="form-control">
排序号:
class="form-control">
Cancel
Save
Js定义
在sys_menu.html文件中定义,页面加载事件
$(".input-group-btn").on("click",".btn-add",doLoadEditPage)
事件处理函数
functiondoLoadEditPage(){
vartitle="添加菜单"
varurl="menu/editUI.do";
$(".container-fluid").load(url,function(){
$(".box-title").html(title);
});
}一个值对象,用于封装zTree上节点信息
publicclassNode{
privateIntegerid;
privateIntegerparentId;
privateStringname;
//set/get
}
不写这个类可以吗?可以map都可以封装
DAO操作
在SysMenuDao中定义查询节点的方法
ListfindZtreeNodes();
Mapper操作
在SysUserMapper中定义查询节点的信息
select
id,
name,
parentId
from
sys_menus
Service操作
在SysUserService接口及实现类中定义查询节点的方。
@Override
publicListfindZtreeNodes(){
//TODOAuto-generatedmethodstub
returnmenuDao.findZtreeNodes();
}
Controller操作
@RequestMapping("treeUI")
@ResponseBody
publicJsonResulttreeUI(){
Listlist=
menuService.findZtreeNodes();
returnnewJsonResult(1,"ok",list);
}
客户端设计与实现
编辑页面添加DIV元素
在编辑页面menu_edit.html添加用于呈现树结构的div元素,例如
style="z-index:59891016;width:300px;height:450px;top:100px;left:500px;display:none">
选择菜单
确定
取消
在这个页面呈现数据时bower_components这个目录下.html页面引入CSS,在当前html页面引入js。
例如:
href="bower_components/layer/skin/default/layer.css">
href="bower_components/ztree/css/metroStyle/metroStyle.css"/>
在编辑页面后面
src="bower_components/layer/layer.js">
上级菜单选项注册事件
事件注册
$(''.form-horizontal'')
.on(''click'',''.load-sys-menu'',doLoadZTreeNodes);
上级菜单事件处理
定义配置信息varzTree;
varsetting={
data:{
simpleData:{
enable:true,
idKey:"id",//节点数据中保存唯一标识的属性名称
pIdKey:"parentId",//节点数据中保存其父节点唯一标识的属性名称
rootPId:null//根节点id
}
}
}
定义事件处理函数functiondoLoadZTreeNodes(){
$(''#menuLayer'').css(''display'',''block'');
varurl=''menu/treeUI.do'';
$.getJSON(url,function(result){
if(result.state==1){
zTree=$.fn.zTree.init($("#menuTree"),setting,result.data);
}else{
alert(result.message);
}
})
}
点击ZTree确定按钮,执行
functiondoSetSelectedNode(){
varselectedNodes=zTree.getSelectedNodes();
varnode=selectedNodes[0];
$(''#menuLayer'').css(''display'',''none'');
$(''#parentId'').val(node.name);
$(''.form-horizontal'').data(''parentId'',node.id);
}
菜单数据保存
与实现
在pojo包中定义SysMenu类,用于封装数据
publicclassSysMenuimplementsSerializable{
privatestaticfinallongserialVersionUID=6880195210216766454L;
privateIntegerid;
privateStringname;
privateStringurl;
privateinttype;
privateintsort;
privateStringnote;
privateIntegerparentId;
privateStringpermission;
privateDatecreatedTime;
privateDatemodifiedTime;
privateStringcreatedUser;
privateStringmodifiedUser;
//set/get
}
Dao方法定义实现
intinsertObject(SysUserentity);
方法定义实现
SysMenuService接口及实现类中定义Object方法
@Override
publicintsaveObject(SysMenuentity){
if(entity==null)
thrownewServiceException("保存的数据不能为空");
introws=sysMenuDao.insertObject(entity);
if(rows!=1)
thrownewServiceException("数据保存失败");
returnrows;
}方法定义实现
SysMenuController中定义SaveObject方法
@RequestMapping("doSaveObject")
@ResponseBody
publicJsonResultdoSaveObject(SysMenuentity){
sysMenuService.saveObject(entity);
returnnewJsonResult(1,"saveok");
}设计与实现
按钮事件注册
$(''.form-horizontal'') .on(''click'',''.btn-save'',doSaveOrUpdate)
保存按钮事件
获取表单数据
functiongetFormData(){
varparams={
type:$("input[name=''typeId'']:checked").val(),
name:$("#nameId").val(),
parentId:$(''.form-horizontal'').data(''parentId''),
url:$("#urlId").val(),
permission:$("#permissionId").val(),
sort:$("#sortId").val()
}
returnparams;
}
提交表单数据
functiondoSaveOrUpdate(){
//1.获取表单数据
varparams=getFormData();
//2.异步提交表单数据
varurl=menu/doSaveObject.do;
$.post(url,params,function(result){
if(result.state==1){
alert(result.message);
doCancel();
}else{
alert(result.message);
}
});
}
修改页面加载
时根据选择的id查询库,然后将结果填充在表单中.
实现
方法定义
根据id查询的方法
Map
findObjectById(Integerid);
Mapper元素定义
id查询菜单信息. resultType="map">
selectm.,p.nameparentName
fromsys_menusmleftjoinsys_menusp
onm.parentId=p.id
wherem.id=#{id}
Service方法定义
id执行查询操作.@Override
publicMapfindObjectById(Integerid){
if(id==null||id<1)
thrownewServiceException("id的值无效");
Mapmap=
sysMenuDao.findObjectById(id);
returnmap;
}Controller方法定义
@RequestMapping("treeUI")
@ResponseBody
publicJsonResulttreeUI(){
Listlist=sysMenuService.findZtreeNodes();
returnnewJsonResult(1,"ok",list);
}实现
页面列表页面点击修改时编辑页面(添加一个)
按钮事件注册:
$(".input-group-btn")
.on("click",".btn-add,.btn-update",doLoadEditPage)
按钮事件处理:
functiondoLoadEditPage(){
vartitle;
if($(this).hasClass("btn-add")){
title="添加菜单";
}elseif($(this).hasClass("btn-update")){
title="修改菜单";
varid=getSelectedId();
if(id==-1){
alert("请先选择");
return;
}
$(".container-fluid").data("id",id);
}
varurl="menu/editUI.do";
$(".container-fluid").load(url,function(){
$(".box-title").html(title);
});
}
编辑页面操作页面加载完成以后根据id的值异步获取数据库
页面数据.
$(function(){
varid=$(".container-fluid").data("id");
//假如id有值说明是修改,然后根据id查找菜单信息
if(id){
doFindObjectById(id);
}
});
根据id查找functiondoFindObjectById(id){
varurl="menu/doFindObjectById.do";
varparams={"id":id};
$.getJSON(url,params,function(result){
if(result.state==1){
doInitFormData(result.data)
}else{
alert(result.message);
}
})
}
通过数据初始化表单
$(function(){
$(''.form-horizontal'')
.on(''click'',''.load-sys-menu'',doLoadZTreeNodes)
.on(''click'',''.btn-save'',doSaveOrUpdate)
$(''#menuLayer'')
.on(''click'',''.btn-confirm'',doSetSelectedNode)
.on(''click'',''.btn-cancle'',doHideTree);
varid=$(".container-fluid").data("id");
//假如id有值说明是修改,然后根据id查找菜单信息
if(id){
doFindObjectById(id);
}
});
修改页面数据保存
设计与实现
方法定义
SysMenuDao接口中定义修改数据
intupdateObject(SysMenuentity);
Mapper元素定义
SysMenuMapper中元素
updatesys_menus
set
name=#{name},type=#{type},url=#{url},
sort=#{sort},parentId=#{parentId},
permission=#{permission}
whereid=#{id}
Service方法定义
SysMenuService接口及实现类中定义修改方法
@Override
publicintupdateObject(SysMenuentity){
if(entity==null)
thrownewServiceException("更新的数据不能为空");
introws=sysMenuDao.updateObject(entity);
if(rows!=1)
thrownewServiceException("数据更新失败");
returnrows;
}
Controller方法定义
SysMenuController中定义修改方法
@RequestMapping("doUpdateObject")
@ResponseBody
publicJsonResultdoUpdateObject(SysMenuentity){
sysMenuService.updateObject(entity);
returnnewJsonResult(1,"updateok");
}
客户端设计及实现
表单数据异步更新
functiondoSaveOrUpdate(){
//1.获取表单数据
varparams=getFormData();
varid=$(".container-fluid").data("id");
if(id)params.id=id;
console.log(params);
//2.异步提交表单数据
varinsertUrl="menu/doSaveObject.do";
varupdateUrl="menu/doUpdateObject.do";
varurl=id?updateUrl:insertUrl;
$.post(url,params,function(result){
if(result.state==1){
alert(result.message);
doCancel();
}else{
alert(result.message);
}
});
}
退出时移除绑定的id
functiondoCancel(){
$(".container-fluid").load("menu/listUI.do");
$(".container-fluid").removeData("id")
}
1-2
齐雷(qilei@tedu.cn)
|
|