后台管理模块相关总结
做这个是一个系统的后台管理,进行系统级别操作,登陆时可用来验证什么角色,拥有什么角色,显示什么内容。
一、五个表,user ,user_role,role,role_menu,menu 。分别是 用户表,用户角色表,角色表,用户菜单表,菜单表
需求:
用户这块:
1.展示所有用户,并展示相应用户角色信息。(可以模糊查询,相应中心和相应部门查询,分页,10条一页)
这里相应中心和部门也是一个接口,可以List<Map>中的Map再放一个List来作为部门。
2.给批量用户添加一个角色,也就是对用户多选框后,进行添加角色。
3.给用户批量重置密码,主要给忘密码的人,重新重置。
4.用户功能导出(excel,有excel模板用excel模板导出)
5.能对某个用户角色进行操作,比如给某个用户批量增加角色,减少角色等。
角色这块:
1.新增角色。
2.删除角色。
3.角色功能导出。
4.权限编辑(也就是给角色添加权限,删除权限等,也是批量的,就用上多选框)
菜单这块(权限): ---最需要思考部分
表设计:
1.展示出所有菜单,并且是树状结构,父子级关系,无限层级。
2.对某个节点进行新增子级。
3.编辑某个节点。
4.删除该节点,并删除该节点下所有子节点。
菜单1和4需要比较难。
思路,1.方法:因为无限,思考着用递归来做。2方法:本人用的mybatis框架,可以用mybatis框架中的resultMap返回类型,来做。
递归:1.自己调用自己,2.有个递归出口
有一个根节点,是一定有的,不然无法查找
Menu实体类中加有如下
1需求代码:
0作为pid,根节点。
/**
* 查询权限树
* @return
*/
@Override
public List<SysMenu> returnTree() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("pid", "0");
params.put("delSign", BasicConstants.DEL_SIGN_ON);
List<SysMenu>list1 = menuDao.selectMenu(params);
log.info("pid:"+list1.get(0).getPid()+",size:"+list1.size());
List<SysMenu> lists = treeDigui(list1);
return lists;
}
//递归
public List<SysMenu> treeDigui(List<SysMenu>list){
List<SysMenu> returnList = list;
log.info("sizes:"+list.size());
if(list.size()==0){
return null;
}else{
for(int i=0; i<returnList.size();i++){
int size = returnList.size();
Map<String, Object> map = new HashMap<>();
map.put("pid", returnList.get(i).getId()+"");
map.put("delSign", BasicConstants.DEL_SIGN_ON);
List<SysMenu>lists = menuDao.selectMenu(map);//再去查是否有子集
returnList.get(i).setListMenu(lists); //都再加进去
treeDigui(lists); //递归实现树结构
}
}
return returnList;
}
2方法查找:比如(复制别人的)这样也会形成树结构,只要传一个根节点(一定存在不被删除的)pid 比如 0或者-1
注意:collection 中还用了一个select查找语句,才可以一直无限查询的,比第一种好,第一种一直去连接数据库,太耗费资源了。
<resultMap id="BaseResultMap" type="org.javaboy.vhr.model.Department">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="parentId" property="parentId" jdbcType="INTEGER"/>
<result column="depPath" property="depPath" jdbcType="VARCHAR"/>
<result column="enabled" property="enabled" jdbcType="BIT"/>
<result column="isParent" property="isParent" jdbcType="BIT"/>
</resultMap>
<resultMap id="DepartmentWithChildren" type="org.javaboy.vhr.model.Department" extends="BaseResultMap">
<collection property="children" ofType="org.javaboy.vhr.model.Department"
select="org.javaboy.vhr.mapper.DepartmentMapper.getAllDepartmentsByParentId" column="id"/>
</resultMap>
<select id="getAllDepartmentsByParentId" resultMap="DepartmentWithChildren">
select * from department where parentId=#{pid};
</select>
2需求,删除
/**
* 新增,修改,删除一个菜单
*/
@Override
public int saveSysMenu(SysMenuDTO sysMenuDTO) {
String flag = sysMenuDTO.getFlag();
SysMenu sysMenu = sysMenuDTO.getSysMenu();
Date date=null;
try {
date = dateTimeUtil.dateTimeNow();
} catch (ParseException e) {
e.printStackTrace();
}
int result =0;
if(flag != null && flag.equals(flag) ){
if("1".equals(flag)){
//新增
sysMenu.setCreateDate(date);//创建时间
sysMenu.setPid(sysMenu.getId());
result = menuDao.saveSysMenu(sysMenu);
if(result>0){
result = 1;
}else{
result = -1;
}
}
if("2".equals(flag)){
//编辑
sysMenu.setModifyDate(date);
result = menuDao.updateSysMenu(sysMenu);
if(result >0){
result = 2;
}else{
result =-2;
}
}
if("3".equals(flag)){
//删除
List<SysMenu> listMap = new ArrayList<>();
listMap.add(sysMenu);
result = delDigui(listMap);
if(result >0){
result = 3;
}else{
result = -3;
}
}
}
return result;
}
/**
* 递归
* 条件
* 1.自己调用自己
* 2.有个递归出口
* @param list
* @return
*/
public Integer delDigui(List<SysMenu> list){
List<SysMenu> returnList = list;
log.info("sizes:"+list.size());
int result = 0;
if (returnList.size()==0){
return null;
}else{
for(int i=0; i<returnList.size();i++){
Map<String, Object> map = new HashMap<>();
map.put("pid", returnList.get(i).getId()+"");
map.put("delSign", BasicConstants.DEL_SIGN_ON);
List<SysMenu>lists = menuDao.selectMenu(map);//再去查是否有子集
log.info("进来id:"+returnList.get(i).getId());
Map<String, Object> params = new HashMap<>();
params.put("id", returnList.get(i).getId());
params.put("delSign", BasicConstants.DEL_SIGN_OFF);//删除标志
result = menuDao.delSysMenus(params);
log.info("出来id:"+returnList.get(i).getId());
delDigui(lists); //递归实现树结构
}
}
return result ;
}
追加:
一、登陆时,通过用户id或者工号啥的去找到相应权限
<mapper namespace="com.lyh.beacon.dao.SysUserRoleDao">
<!-- 1.这里多去理解,这个jdbcType必须都大写,不然报错
2. Collection 用ofType 集合
3. assciation 用javaType 对象
4. column 数据库列参数 property 映射的实体类参数
5. id标签是唯一列 result标签其他列
-->
<resultMap type="com.lyh.beacon.model.sys.SysMenu" id="loginMenu">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column = "name" property="name" jdbcType="VARCHAR"/>
<result column = "pid" property="pid" jdbcType="INTEGER"/>
<result column = "code" property="code" jdbcType="VARCHAR"/>
<result column ="levels" property="levels" jdbcType="INTEGER"/>
<result column = "front_url" property = "frontUrl" jdbcType="VARCHAR"/>
<result column = "back_url" property="backUrl" jdbcType="VARCHAR"/>
<collection property="listMenu" ofType="com.lyh.beacon.model.sys.SysMenu" >
<id column="id2" property="id" jdbcType="INTEGER"/>
<result column = "name2" property="name" jdbcType="VARCHAR"/>
<result column = "pid2" property="pid" jdbcType="INTEGER"/>
<result column = "code2" property="code" jdbcType="VARCHAR"/>
<result column ="levels2" property="levels" jdbcType="INTEGER"/>
<result column = "front_url2" property = "frontUrl" jdbcType="VARCHAR"/>
<result column = "back_url2" property="backUrl" jdbcType="VARCHAR"/>
</collection>
</resultMap>
<!-- 这个可以做成登陆时返回相应模块给前端去展示 ,利用resultMap很强大,那种递归,都可以用resultMap来做,好的很-->
<select id="loginViewMenu" parameterType="java.lang.String" resultMap="loginMenu">
select m1.*,m2.id id2,m2.name name2,m2.pid pid2,m2.code code2,m2.levels levels2,m2.front_url frontUrl2,m2.back_url backUrl2
from sys_menu m1,sys_menu m2,sys_user_role ur ,sys_role_menu rm
where m1.id = m2.pid and ur.user_id = #{userId} and ur.role_id = rm.role_id and rm.menu_id = m2.id
</select>
结果如 这种层级结构
[
{
"id": 1,
"name": "项目管理系统",
"code": "",
"pid": 0,
"pcode": null,
"pcodes": null,
"levels": 0,
"frontUrl": null,
"backUrl": null,
"sequence": 0,
"ismenu": 0,
"icon": null,
"status": 0,
"createId": null,
"createDate": null,
"modifyId": null,
"modifyDate": null,
"delSign": 0,
"tips": null,
"listMenu": [
{
"id": 2,
"name": "项目管理",
"code": "01",
"pid": 1,
"pcode": null,
"pcodes": null,
"levels": 1,
"frontUrl": null,
"backUrl": null,
"sequence": 0,
"ismenu": 0,
"icon": null,
"status": 0,
"createId": null,
"createDate": null,
"modifyId": null,
"modifyDate": null,
"delSign": 0,
"tips": null,
"listMenu": null
},
{
"id": 6,
"name": "任务管理",
"code": "02",
"pid": 1,
"pcode": null,
"pcodes": null,
"levels": 1,
"frontUrl": null,
"backUrl": null,
"sequence": 0,
"ismenu": 0,
"icon": null,
"status": 0,
"createId": null,
"createDate": null,
"modifyId": null,
"modifyDate": null,
"delSign": 0,
"tips": null,
"listMenu": null
}
]
}
]
二、
用户和角色这块某个需求思考解决:
2.给批量用户添加一个角色,也就是对用户多选框后,进行添加角色。
* 对单个用户进行角色操作
* 批量新增和删除
*
* 多选框
*可以这么解决,
* 通过工号把该工号所有角色删掉,然后再重新加入进去这些多选框的角色
* {
* userId:"05748"工号
* list:[
* {roleId:"2",createId:""},
* {roleId:"3",createId:""},
* {roleId:"4",createId:""},
* ]
* }
4.权限编辑(也就是给角色添加权限,删除权限等,也是批量的,就用上多选框)
类似上面一样解决方案。
扩展:多选框应该都可以这样用。