权限模块主要包括用户管理、部门管理、角色管理、菜单管理模块。以下主要从数据库表创建、页面、 接口主要实现点的讲述。 复制代码
部门表和菜单表都是树形结构,在项目初始化时,在这两张表中初始化一个根节点,方便之后查询树形结构(我是这么解决的,也可以用其他方法解决),例如:
insert into sys_dept(dept_id,name) values(-1,'一级部门'); insert into sys_menu(menu_id,name) values(-1,'一级菜单'); 复制代码
关联表中是有外键关联的,以便于后期修改和删除主表时,自动更新。
前端代码路径
─views
├─sys
│ ├─dept
│ ├─dict
│ ├─job
│ ├─menu
│ ├─role
│ ├─task
│ ├─test
│ └─user
复制代码 /sysuser/list /sysuser/adduser /sysuser/edit /sysuser/delete
接口访问方式:前端访问接口使用 axios 方式,后端controller中使用 @RequestBody 标签对象接收数据
@RequestMapping(value = "adduser", method = RequestMethod.POST)
public void addUser(@RequestBody SysUser sysUser, HttpServletRequest request, HttpServletResponse response){...}
复制代码 权限管理:在接口上添加 @RequiresPermissions 注解,使接口拥有指定权限的人才能使用,在改系统中用户权限配置在数据表中,权限注解代码如下:
@RequiresPermissions("userInfo:view")//拥有userInfo:view权限才能查询
@RequestMapping(value = "list", method = RequestMethod.POST)
@ResponseBody
public JSONObject findList(@RequestBody SysUser sysUser, HttpServletRequest request, HttpServletResponse response) {
List list = sysUserService.findList(sysUser);
JSONObject obj = new JSONObject();
obj.put("data", list);
obj.put("code", 20000);
obj.put("message", "success");
return obj;
}
复制代码
角色列表: /sysrole/list
角色新增: /sysrole/add
角色编辑: /sysrole/edit
部门查询: /sysdept/getTree
菜单查询: /sysmenu/getTree
菜单授权:在编辑页面中的菜单授权默认勾选项,是在前端JS中根据后端查询回来的数据处理的,代码如下:
getMenuTreeCheckedKeys: function(arr, node) {
var that = this
if (node.children.length === 0) {
arr.push(node.menuId)
return node.menuId
}
for (var index in node.children) {
that.getMenuTreeCheckedKeys(arr, node.children[index])
}
arr.push(node.menuId)
}
复制代码 数据授权:在前端JS中处理,代码如下:
getDeptTreeCheckedKeys: function(arr, node) {
var that = this
if (node.children.length === 0) {
arr.push(node.deptId)
return node.deptId
}
for (var index in node.children) {
that.getDeptTreeCheckedKeys(arr, node.children[index])
}
arr.push(node.deptId)
}
复制代码
/sysdept/getTree /sysdept/add /sysdept/edit /sysdept/delete
部门列表:因为列表是树形结构,在查询时传递树的根节点 deptId ,前端请求如下:
getTree({ deptId: '-1' }).then(response => {
that.depts = response.data.children
})
复制代码 后端代码:
@RequestMapping("getTree")
@ResponseBody
public JSONObject getTree(@RequestBody SysDept sysDept, HttpServletRequest request, HttpServletResponse response) {
JSONObject jsonObject = new JSONObject();
SysDept tree = new SysDept();
tree = sysDeptService.getMenuTree(sysDept.getDeptId());
jsonObject.put("code", 20000);
jsonObject.put("data", tree);
return jsonObject;
}
复制代码 部门删除:由于部门数据是树形结构的,如果删除的节点有孩子节点,不删除,提示信息,主要代码如下:
@RequestMapping(value = "delete", method = RequestMethod.POST)
public void delete(@RequestBody SysDept sysDeptParam, HttpServletRequest request, HttpServletResponse response) {
int flag = 0;
JSONObject jsonObject = new JSONObject();
BigInteger deptId = sysDeptParam.getDeptId();
SysDept tree = new SysDept();
tree = sysDeptService.getMenuTree(deptId);
if (tree.getChildren().size() == 0) {
SysDept sysDept = new SysDept();
sysDept.setDeptId(deptId);
sysDept.setDelFlag(-1);
flag = sysDeptService.delete(sysDept);
if (flag > 0) {
jsonObject.put("status", 200);
} else {
jsonObject.put("status", 500);
}
} else {
jsonObject.put("status", 201);
}
jsonObject.put("code", 20000);
try {
response.getWriter().print(jsonObject.toJSONString());
} catch (IOException e) {
e.printStackTrace();
}
}
复制代码
/sysmenu/getTree /sysmenu/add /sysmenu/edit /sysmenu/delete
菜单路由 和 授权标识 ,并且都可以配置多个,中间用英文 ; 间隔。
shiro 校验的标识,需要和controller方法中的注解 @RequiresPermissions 一致
MyBatis如何获取插入记录的自增长字段值
在插入方法中添加 useGeneratedKeys 和 keyProperty 属性, useGeneratedKeys 当设置为 true 时,表示如果插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回。
<insert id="insert" useGeneratedKeys="true" keyProperty="userId" parameterType="com.site.mountain.entity.SysUser">
INSERT INTO sys_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId!=null">`user_id`,</if>
<if test="username!=null">`username`,</if>
<if test="password!=null">`password`,</if>
<if test="email!=null">`email`,</if>
<if test="mobile!=null">`mobile`,</if>
<if test="status!=null">`status`,</if>
<if test="deptId!=null">`dept_id`,</if>
<if test="createTime!=null">`create_time`,</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId!=null">#{userId},</if>
<if test="username!=null">#{username},</if>
<if test="password!=null">#{password},</if>
<if test="email!=null">#{email},</if>
<if test="mobile!=null">#{mobile},</if>
<if test="status!=null">#{status},</if>
<if test="deptId!=null">#{deptId},</if>
<if test="createTime!=null">#{createTime},</if>
</trim>
</insert>
复制代码 MySQL根据外键级联删除:表存储引擎必须使用InnoDB引擎
事务失效问题:springboot和shiro框架集成时,先加载shiro,这时sysUserService还没有实例化,导致事务失效, 在sysUserService 上加载 @Lazy ,主要代码如下:
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
private SysUserService sysUserService;
......
}
复制代码 该项目我先是设计数据库表的关系,然后用自己写的小工具把数据库表转成JavaBean、xml、mapper代码,小工具请看我的 《golang 实现的mybatis代码生成器》
生成小工具 下载地址