spring cloud(六)系统管理之用户、角色、菜单数据库设计及实现

您所在的位置:网站首页 管理员与用户的实体联系图 spring cloud(六)系统管理之用户、角色、菜单数据库设计及实现

spring cloud(六)系统管理之用户、角色、菜单数据库设计及实现

2023-12-19 10:11| 来源: 网络整理| 查看: 265

本系列文章均参考:朝雨忆轻尘,感谢博主!

这里还有他的技术交流群:429854222,欢迎大家支持博主

若有侵权,还请告知,一定删除

一、需求说明

不同的账户登录系统看到的是不同的菜单,最高权限账户能看到所有的。

二、数据库设计

首先看张ER图:

我们看图说话:后台人员各自拥有不同的账户,分配了不同的角色,一个账号可以分配多个角色(一对多),一个角色也可以分配给不同的账户(一对多),所以账户角色是多对多的关系;同理。角色权限也是多对多,这里设计的时候把菜单和权限绑定在一起。

数据库设计如下:

账户表sys_user:

角色表sys_role:

菜单表sys_menu:

用户角色表sys_user_role:

角色菜单表sys_role_menu:

 

这样的话,根据需求的数据库就设计出来了,接下来就是代码实现了。

三、代码实现 3.1、用户

3.1.1、model

public class SysUser extends BaseModel { private String name; private String password; private String salt; private String email; private String mobile; private Byte status; private Long deptId; private String deptName; private Byte delFlag; private String roleNames; private List userRoles = new ArrayList(); public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Byte getStatus() { return status; } public void setStatus(Byte status) { this.status = status; } public Long getDeptId() { return deptId; } public void setDeptId(Long deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public Byte getDelFlag() { return delFlag; } public void setDelFlag(Byte delFlag) { this.delFlag = delFlag; } public String getRoleNames() { return roleNames; } public void setRoleNames(String roleNames) { this.roleNames = roleNames; } public List getUserRoles() { return userRoles; } public void setUserRoles(List userRoles) { this.userRoles = userRoles; } }

3.1.2、dao

public interface SysUserMapper { int deleteByPrimaryKey(Long id); int insert(SysUser record); int insertSelective(SysUser record); SysUser selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysUser record); int updateByPrimaryKey(SysUser record); List findPage(); SysUser findByName(@Param(value="name") String name); List findPageByName(@Param(value="name") String name); List findPageByNameAndEmail(@Param(value="name") String name, @Param(value="email") String email); }

3.1.3、mapper

id, name, password, salt, email, mobile, status, dept_id, create_by, create_time, last_update_by, last_update_time, del_flag select from sys_user where id = #{id,jdbcType=BIGINT} delete from sys_user where id = #{id,jdbcType=BIGINT} insert into sys_user (id, name, password, salt, email, mobile, status, dept_id, create_by, create_time, last_update_by, last_update_time, del_flag) values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT}, #{deptId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}) insert into sys_user id, name, password, salt, email, mobile, status, dept_id, create_by, create_time, last_update_by, last_update_time, del_flag, #{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT}, #{deptId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}, update sys_user name = #{name,jdbcType=VARCHAR}, password = #{password,jdbcType=VARCHAR}, salt = #{salt,jdbcType=VARCHAR}, email = #{email,jdbcType=VARCHAR}, mobile = #{mobile,jdbcType=VARCHAR}, status = #{status,jdbcType=TINYINT}, dept_id = #{deptId,jdbcType=BIGINT}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT}, where id = #{id,jdbcType=BIGINT} update sys_user set name = #{name,jdbcType=VARCHAR}, password = #{password,jdbcType=VARCHAR}, salt = #{salt,jdbcType=VARCHAR}, email = #{email,jdbcType=VARCHAR}, mobile = #{mobile,jdbcType=VARCHAR}, status = #{status,jdbcType=TINYINT}, dept_id = #{deptId,jdbcType=BIGINT}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT} where id = #{id,jdbcType=BIGINT} select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where u.name = #{name,jdbcType=VARCHAR} select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where u.name like #{pattern} select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where u.name like #{patternName} and u.email like #{patternEmail}

3.1.4、service以及impl

public interface SysUserService extends CurdService { SysUser findByName(String username); SysUser findByToken(String token); /** * 查找用户的菜单权限标识集合 * @param userName * @return */ Set findPermissions(String userName); /** * 查找用户的角色集合 * @param userName * @return */ List findUserRoles(Long userId); int savePWD(SysUser sysUser); } @Service public class SysUserServiceImpl implements SysUserService { @Autowired private SysUserMapper sysUserMapper; @Autowired private SysMenuMapper sysMenuMapper; @Autowired private SysUserRoleMapper sysUserRoleMapper; @Autowired private SysRoleMapper sysRoleMapper; @Autowired private SysUserTokenMapper sysUserTokenMapper; @Override public int save(SysUser record) { Long id = null; if(record.getId() == null || record.getId() == 0) { // 新增用户 sysUserMapper.insertSelective(record); id = record.getId(); } else { // 更新用户信息 sysUserMapper.updateByPrimaryKeySelective(record); } // 更新用户角色 if(id != null && id == 0) { return 1; } if(id != null) { for(SysUserRole sysUserRole:record.getUserRoles()) { sysUserRole.setUserId(id); } } else { sysUserRoleMapper.deleteByUserId(record.getId()); } for(SysUserRole sysUserRole:record.getUserRoles()) { sysUserRoleMapper.insertSelective(sysUserRole); } return 1; } @Override public int savePWD(SysUser sysUser) { if(sysUser.getId() == null || sysUser.getId() == 0) { return 0; } // 更新用户信息 return sysUserMapper.updateByPrimaryKeySelective(sysUser); } @Override public int delete(SysUser record) { return sysUserMapper.deleteByPrimaryKey(record.getId()); } @Override public int delete(List records) { for(SysUser record:records) { delete(record); } return 1; } @Override public SysUser findById(Long id) { return sysUserMapper.selectByPrimaryKey(id); } @Override public SysUser findByName(String name) { return sysUserMapper.findByName(name); } @Override public PageResult findPage(PageRequest pageRequest) { PageResult pageResult = null; String name = getColumnFilterValue(pageRequest, "name"); String email = getColumnFilterValue(pageRequest, "email"); if(name != null) { if(email != null) { pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper, "findPageByNameAndEmail", name, email); } else { pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper, "findPageByName", name); } } else { pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper); } // 加载用户角色信息 findUserRoles(pageResult); return pageResult; } /** * 获取过滤字段的值 * @param filterName * @return */ public String getColumnFilterValue(PageRequest pageRequest, String filterName) { String value = null; ColumnFilter columnFilter = pageRequest.getColumnFilter(filterName); if(columnFilter != null) { value = columnFilter.getValue(); } return value; } /** * 加载用户角色 * @param pageResult */ private void findUserRoles(PageResult pageResult) { List content = pageResult.getContent(); for(Object object:content) { SysUser sysUser = (SysUser) object; List userRoles = findUserRoles(sysUser.getId()); sysUser.setUserRoles(userRoles); sysUser.setRoleNames(getRoleNames(userRoles)); } } private String getRoleNames(List userRoles) { StringBuilder sb = new StringBuilder(); for(Iterator iter=userRoles.iterator(); iter.hasNext();) { SysUserRole userRole = iter.next(); SysRole sysRole = sysRoleMapper.selectByPrimaryKey(userRole.getRoleId()); if(sysRole == null) { continue ; } sb.append(sysRole.getRemark()); if(iter.hasNext()) { sb.append(", "); } } return sb.toString(); } @Override public Set findPermissions(String userName) { Set perms = new HashSet(); List sysMenus = findByUser(userName); for(SysMenu sysMenu:sysMenus) { if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) { perms.add(sysMenu.getPerms()); } } return perms; } @Override public List findUserRoles(Long userId) { return sysUserRoleMapper.findUserRoles(userId); } private List findByUser(String userName) { if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) { return sysMenuMapper.findAll(); } return sysMenuMapper.findByUserName(userName); } @Override public SysUser findByToken(String token) { SysUserToken sysUserToken = sysUserTokenMapper.findByToken(token); return sysUserMapper.selectByPrimaryKey(sysUserToken.getUserId()); } }

代码有的地方是跟token有关的,这是因为后台API的接口都是通过token鉴权来访问的(每个用户登录一次都会生成一个token),通过token来查询更方便一点。

重点方法:findPermissions、findUserRoles

3.2、角色

3.2.1、model

public class SysRole extends BaseModel { private String name; private String remark; private Byte delFlag; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public Byte getDelFlag() { return delFlag; } public void setDelFlag(Byte delFlag) { this.delFlag = delFlag; } }

3.2.2、dao

public interface SysRoleMapper { int deleteByPrimaryKey(Long id); int insert(SysRole record); int insertSelective(SysRole record); SysRole selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysRole record); int updateByPrimaryKey(SysRole record); List findPage(); List findAll(); List findPageByName(@Param(value="name") String name); List findByName(@Param(value="name") String name); }

3.2.3、mapper

id, name, remark, create_by, create_time, last_update_by, last_update_time, del_flag select from sys_role where id = #{id,jdbcType=BIGINT} delete from sys_role where id = #{id,jdbcType=BIGINT} insert into sys_role (id, name, remark, create_by, create_time, last_update_by, last_update_time, del_flag) values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}) insert into sys_role id, name, remark, create_by, create_time, last_update_by, last_update_time, del_flag, #{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}, update sys_role name = #{name,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT}, where id = #{id,jdbcType=BIGINT} update sys_role set name = #{name,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT} where id = #{id,jdbcType=BIGINT} select from sys_role select from sys_role select from sys_role where name like #{pattern} select from sys_role where name = #{name,jdbcType=VARCHAR}

3.2.4、service以及impl

public interface SysRoleService extends CurdService { /** * 查询全部 * @return */ List findAll(); /** * 查询角色菜单集合 * @return */ List findRoleMenus(Long roleId); /** * 保存角色菜单 * @param records * @return */ int saveRoleMenus(List records); /** * 根据名称查询 * @param name * @return */ List findByName(String name); /** * 查询角色区域集合 * @return */ List findRoleAreas(Long roleId); /** * 保存角色区域 * @param records * @return */ int saveRoleAreas(List records); List findRoleByName(String name); } @Service public class SysRoleServiceImpl implements SysRoleService { @Autowired private SysRoleMapper sysRoleMapper; @Autowired private SysRoleMenuMapper sysRoleMenuMapper; @Autowired private SysRoleAreaMapper sysRoleAreaMapper; @Autowired private SysMenuMapper sysMenuMapper; @Autowired private SysAreaMapper sysAreaMapper; @Autowired private SysUserMapper sysUserMapper; @Autowired private SysUserRoleMapper sysUserRoleMapper; @Override public int save(SysRole record) { if(record.getId() == null || record.getId() == 0) { return sysRoleMapper.insertSelective(record); } return sysRoleMapper.updateByPrimaryKeySelective(record); } @Override public int delete(SysRole record) { return sysRoleMapper.deleteByPrimaryKey(record.getId()); } @Override public int delete(List records) { for(SysRole record:records) { delete(record); } return 1; } @Override public SysRole findById(Long id) { return sysRoleMapper.selectByPrimaryKey(id); } @Override public PageResult findPage(PageRequest pageRequest) { ColumnFilter columnFilter = pageRequest.getColumnFilter("name"); if(columnFilter != null && columnFilter.getValue() != null) { return MybatisPageHelper.findPage(pageRequest, sysRoleMapper, "findPageByName", columnFilter.getValue()); } return MybatisPageHelper.findPage(pageRequest, sysRoleMapper); } @Override public List findAll() { return sysRoleMapper.findAll(); } public SysRoleMapper getSysRoleMapper() { return sysRoleMapper; } public void setSysRoleMapper(SysRoleMapper sysRoleMapper) { this.sysRoleMapper = sysRoleMapper; } @Override public List findRoleMenus(Long roleId) { SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId); if(SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) { // 如果是超级管理员,返回全部 return sysMenuMapper.findAll(); } return sysMenuMapper.findRoleMenus(roleId); } @Transactional @Override public int saveRoleMenus(List records) { if(records == null || records.isEmpty()) { return 1; } Long roleId = records.get(0).getRoleId(); sysRoleMenuMapper.deleteByRoleId(roleId); for(SysRoleMenu record:records) { sysRoleMenuMapper.insertSelective(record); } return 1; } @Override public List findByName(String name) { return sysRoleMapper.findByName(name); } @Override public List findRoleAreas(Long roleId) { SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId); if(SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) { // 如果是超级管理员,返回全部 return sysAreaMapper.findAll(); } return sysAreaMapper.findRoleAreas(roleId); } @Override public int saveRoleAreas(List records) { if(records == null || records.isEmpty()) { return 1; } Long roleId = records.get(0).getRoleId(); sysRoleAreaMapper.deleteByRoleId(roleId); for(SysRoleArea record:records) { sysRoleAreaMapper.insert(record); } return 1; } @Override public List findRoleByName(String name) { SysUser user = sysUserMapper.findByName(name); List userRoles = sysUserRoleMapper.findUserRoles(user.getId()); List res = new ArrayList(); for (SysUserRole userRole : userRoles) { res.add(sysRoleMapper.selectByPrimaryKey(userRole.getRoleId())); } return res; } }

重点方法: findRoleMenus、saveRoleMenus、findRoleByName

3.3、菜单

3.3.1、model

public class SysMenu extends BaseModel { private Long parentId; private String name; private String url; private String perms; private Integer type; private String icon; private Integer orderNum; private Byte delFlag; // 非数据库字段 private String parentName; // 非数据库字段 private Integer level; // 非数据库字段 private List children; public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getPerms() { return perms; } public void setPerms(String perms) { this.perms = perms; } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public Integer getOrderNum() { return orderNum; } public void setOrderNum(Integer orderNum) { this.orderNum = orderNum; } public Byte getDelFlag() { return delFlag; } public void setDelFlag(Byte delFlag) { this.delFlag = delFlag; } public List getChildren() { return children; } public void setChildren(List children) { this.children = children; } public Integer getLevel() { return level; } public void setLevel(Integer level) { this.level = level; } public String getParentName() { return parentName; } public void setParentName(String parentName) { this.parentName = parentName; } }

3.3.2、dao

public interface SysMenuMapper { int deleteByPrimaryKey(Long id); int insert(SysMenu record); int insertSelective(SysMenu record); SysMenu selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysMenu record); int updateByPrimaryKey(SysMenu record); List findPage(); List findPageByName(@Param(value="name") String name); List findAll(); List findByUserName(@Param(value="userName") String userName); List findByName(@Param(value="name") String name); List findSimpleByName(@Param(value="name") String name); List findRoleMenus(@Param(value="roleId") Long roleId); }

3.3.3、mapper

id, parent_id, name, url, perms, type, icon, order_num, create_by, create_time, last_update_by, last_update_time, del_flag select from sys_menu where id = #{id,jdbcType=BIGINT} delete from sys_menu where id = #{id,jdbcType=BIGINT} insert into sys_menu (id, parent_id, name, url, perms, type, icon, order_num, create_by, create_time, last_update_by, last_update_time, del_flag ) values (#{id,jdbcType=BIGINT}, #{parentId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{perms,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{icon,jdbcType=VARCHAR}, #{orderNum,jdbcType=INTEGER}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT} ) insert into sys_menu id, parent_id, name, url, perms, type, icon, order_num, create_by, create_time, last_update_by, last_update_time, del_flag, #{id,jdbcType=BIGINT}, #{parentId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{url,jdbcType=VARCHAR}, #{perms,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{icon,jdbcType=VARCHAR}, #{orderNum,jdbcType=INTEGER}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}, update sys_menu parent_id = #{parentId,jdbcType=BIGINT}, name = #{name,jdbcType=VARCHAR}, url = #{url,jdbcType=VARCHAR}, perms = #{perms,jdbcType=VARCHAR}, type = #{type,jdbcType=INTEGER}, icon = #{icon,jdbcType=VARCHAR}, order_num = #{orderNum,jdbcType=INTEGER}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT}, where id = #{id,jdbcType=BIGINT} update sys_menu set parent_id = #{parentId,jdbcType=BIGINT}, name = #{name,jdbcType=VARCHAR}, url = #{url,jdbcType=VARCHAR}, perms = #{perms,jdbcType=VARCHAR}, type = #{type,jdbcType=INTEGER}, icon = #{icon,jdbcType=VARCHAR}, order_num = #{orderNum,jdbcType=INTEGER}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, del_flag = #{delFlag,jdbcType=TINYINT} where id = #{id,jdbcType=BIGINT} select from sys_menu select from sys_menu select from sys_menu where name like #{pattern} select m.* from sys_menu m, sys_user u, sys_user_role ur, sys_role_menu rm where u.name = #{userName,jdbcType=BIGINT} and u.id = ur.user_id and ur.role_id = rm.role_id and rm.menu_id = m.id select m.* from sys_menu m, sys_user u, sys_user_role ur, sys_role_menu rm where m.name = #{name,jdbcType=VARCHAR} and u.id = ur.user_id and ur.role_id = rm.role_id and rm.menu_id = m.id select m.* from sys_menu m where m.name = #{name,jdbcType=VARCHAR} select m.* from sys_menu m, sys_role_menu rm where rm.role_id = #{roleId,jdbcType=BIGINT} and m.id = rm.menu_id

3.3.4、service以及impl

public interface SysMenuService extends CurdService { /** * 查询菜单树,用户ID和用户名为空则查询全部 * @param menuType 获取菜单类型,0:获取所有菜单,包含按钮,1:获取所有菜单,不包含按钮 * @param userId * @return */ List findTree(String userName, int menuType,String name); /** * 根据用户名查找菜单列表 * @param userName * @return */ List findByUser(String userName, String name); List findByName(String name); } @Service public class SysMenuServiceImpl implements SysMenuService { @Autowired private SysMenuMapper sysMenuMapper; @Override public int save(SysMenu record) { if(record.getId() == null || record.getId() == 0) { return sysMenuMapper.insertSelective(record); } if(record.getParentId() == null) { record.setParentId(0L); } return sysMenuMapper.updateByPrimaryKeySelective(record); } @Override public int delete(SysMenu record) { return sysMenuMapper.deleteByPrimaryKey(record.getId()); } @Override public int delete(List records) { for(SysMenu record:records) { delete(record); } return 1; } @Override public SysMenu findById(Long id) { return sysMenuMapper.selectByPrimaryKey(id); } @Override public PageResult findPage(PageRequest pageRequest) { return MybatisPageHelper.findPage(pageRequest, sysMenuMapper); } @Override public List findTree(String userName, int menuType,String name) { List sysMenus = new ArrayList(); List menus = findByUser(userName,name); for (SysMenu menu : menus) { if (menu.getParentId() == null || menu.getParentId() == 0) { menu.setLevel(0); if(!exists(sysMenus, menu)) { sysMenus.add(menu); } } } sysMenus.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum())); findChildren(sysMenus, menus, menuType); return sysMenus; } @Override public List findByUser(String userName, String name) { if(!StringUtils.isBlank(name)) { return sysMenuMapper.findByName(name); } if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) { return sysMenuMapper.findAll(); } return sysMenuMapper.findByUserName(userName); } private void findChildren(List SysMenus, List menus, int menuType) { for (SysMenu SysMenu : SysMenus) { List children = new ArrayList(); for (SysMenu menu : menus) { if(menuType == 1 && menu.getType() == 2) { // 如果是获取类型不需要按钮,且菜单类型是按钮的,直接过滤掉 continue ; } if (SysMenu.getId() != null && SysMenu.getId().equals(menu.getParentId())) { menu.setParentName(SysMenu.getName()); menu.setLevel(SysMenu.getLevel() + 1); if(!exists(children, menu)) { children.add(menu); } } } SysMenu.setChildren(children); children.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum())); findChildren(children, menus, menuType); } } private boolean exists(List sysMenus, SysMenu sysMenu) { boolean exist = false; for(SysMenu menu:sysMenus) { if(menu.getId().equals(sysMenu.getId())) { exist = true; } } return exist; } @Override public List findByName(String name) { return sysMenuMapper.findSimpleByName(name); } }

 这里查找树形菜单时使用了递归的方法。

重点方法:findTree、findChildren

3.4、用户角色

3.4.1、model

public class SysUserRole extends BaseModel { private Long userId; private Long roleId; public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } }

3.4.2、dao

public interface SysUserRoleMapper { int deleteByPrimaryKey(Long id); int insert(SysUserRole record); int insertSelective(SysUserRole record); SysUserRole selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysUserRole record); int updateByPrimaryKey(SysUserRole record); List findUserRoles(@Param(value="userId") Long userId); int deleteByUserId(@Param(value="userId") Long userId); }

3.4.3、mapper

id, user_id, role_id select from sys_user_role where id = #{id,jdbcType=BIGINT} delete from sys_user_role where id = #{id,jdbcType=BIGINT} insert into sys_user_role (id, user_id, role_id ) values (#{id,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT} ) insert into sys_user_role id, user_id, role_id, #{id,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}, update sys_user_role user_id = #{userId,jdbcType=BIGINT}, role_id = #{roleId,jdbcType=BIGINT}, where id = #{id,jdbcType=BIGINT} update sys_user_role set user_id = #{userId,jdbcType=BIGINT}, role_id = #{roleId,jdbcType=BIGINT} where id = #{id,jdbcType=BIGINT} select from sys_user_role where user_id = #{userId,jdbcType=BIGINT} delete from sys_user_role where user_id = #{userId,jdbcType=BIGINT}

3.4.4、service以及impl

详见SysUserService和SysRoleService

3.5、角色菜单

3.5.1、model

public class SysRoleMenu extends BaseModel { private Long roleId; private Long menuId; public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } public Long getMenuId() { return menuId; } public void setMenuId(Long menuId) { this.menuId = menuId; } }

3.5.2、dao

public interface SysRoleMenuMapper { int deleteByPrimaryKey(Long id); int insert(SysRoleMenu record); int insertSelective(SysRoleMenu record); SysRoleMenu selectByPrimaryKey(Long id); int updateByPrimaryKeySelective(SysRoleMenu record); int updateByPrimaryKey(SysRoleMenu record); List findRoleMenus(@Param(value="roleId") Long roleId); List findAll(); int deleteByRoleId(@Param(value="roleId") Long roleId); }

3.5.3、mapper

id, role_id, menu_id, create_by, create_time, last_update_by, last_update_time select from sys_role_menu where id = #{id,jdbcType=BIGINT} delete from sys_role_menu where id = #{id,jdbcType=BIGINT} insert into sys_role_menu (id, role_id, menu_id, create_by, create_time, last_update_by, last_update_time) values (#{id,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}, #{menuId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}) insert into sys_role_menu id, role_id, menu_id, create_by, create_time, last_update_by, last_update_time, #{id,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}, #{menuId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, update sys_role_menu role_id = #{roleId,jdbcType=BIGINT}, menu_id = #{menuId,jdbcType=BIGINT}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}, where id = #{id,jdbcType=BIGINT} update sys_role_menu set role_id = #{roleId,jdbcType=BIGINT}, menu_id = #{menuId,jdbcType=BIGINT}, create_by = #{createBy,jdbcType=BIGINT}, create_time = #{createTime,jdbcType=TIMESTAMP}, last_update_by = #{lastUpdateBy,jdbcType=BIGINT}, last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP} where id = #{id,jdbcType=BIGINT} select from sys_role_menu where role_id = #{roleId,jdbcType=BIGINT} select from sys_role_menu delete from sys_role_menu where role_id = #{roleId,jdbcType=BIGINT}

3.5.4、service以及impl

详见SysUserService和SysRoleService

4、controller层调用及其他相关

根据用户名查找角色:

// @RequiresPermissions("sys:user:view") @GetMapping(value="/findByName") public HttpResult findByUserName(@RequestParam String name) { return HttpResult.ok(sysRoleService.findRoleByName(name)); }

根据角色查找菜单:

@RequiresPermissions("sys:role:view") @GetMapping(value="/findRoleMenus") public HttpResult findRoleMenus(@RequestParam Long roleId) { return HttpResult.ok(sysRoleService.findRoleMenus(roleId)); }

(其实都是直接调用service方法,至于方法是干啥的,稍微懂点英文就行了吧 /笑哭/笑哭/笑哭/笑哭)

还有就是,从上面代码也能看到一个注解:@RequiresPermissions,这玩意就是权限,放在库里就是这样:

实现方式是shiro+oauth2,首先写个shiro配置:

@Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); // 自定义 OAuth2Filter 过滤器,替代默认的过滤器 Map filters = new HashMap(); filters.put("oauth2", new OAuth2Filter()); shiroFilter.setFilters(filters); // 访问路径拦截配置,"anon"表示无需验证,未登录也可访问 Map filterMap = new LinkedHashMap(); // 首页和登录页面 filterMap.put("/", "anon"); filterMap.put("/login", "anon"); // 图片 filterMap.put("/images/**", "anon"); // 其他所有路径交给OAuth2Filter处理 filterMap.put("/**", "oauth2"); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 注入 Realm 实现类,实现自己的登录逻辑 securityManager.setRealm(getShiroRealm()); return securityManager; } @Bean public Realm getShiroRealm(){ OAuth2Realm myShiroRealm = new OAuth2Realm(); return myShiroRealm; } /** * Shiro生命周期处理器 */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能 */ @Bean @DependsOn({"lifecycleBeanPostProcessor"}) public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; } }

 然后是oauth2三个类:

public class OAuth2Filter extends AuthenticatingFilter { @Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { // 获取请求token String token = getRequestToken((HttpServletRequest) request); if(StringUtils.isBlank(token)){ return null; } return new OAuth2Token(token); } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { return false; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpRequest = (HttpServletRequest) request; if("OPTIONS".equals(httpRequest.getMethod())) { // 如果是跨域中复杂请求的预检请求(OPTIONS类型),因为预检请求不带token, 所以不需要验证token return true; } // 获取请求token,如果token不存在,直接返回401 String token = getRequestToken(httpRequest); if(StringUtils.isBlank(token)){ HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json; charset=utf-8"); HttpResult result = HttpResult.error(HttpStatus.SC_UNAUTHORIZED, "invalid token"); String json = JSONObject.toJSONString(result); httpResponse.getWriter().print(json); return false; } return executeLogin(request, response); } @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json; charset=utf-8"); try { // 处理登录失败的异常 Throwable throwable = e.getCause() == null ? e : e.getCause(); HttpResult result = HttpResult.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); String json = JSONObject.toJSONString(result); httpResponse.getWriter().print(json); } catch (IOException e1) { } return false; } /** * 获取请求的token */ private String getRequestToken(HttpServletRequest httpRequest){ // 从header中获取token String token = httpRequest.getHeader("token"); // 如果header中不存在token,则从参数中获取token if(StringUtils.isBlank(token)){ token = httpRequest.getParameter("token"); } return token; } }

 

@Component public class OAuth2Realm extends AuthorizingRealm { @Autowired SysUserMapper sysUserMapper; @Autowired SysMenuMapper sysMenuMapper; @Autowired SysUserTokenMapper sysUserTokenMapper; @Override public boolean supports(AuthenticationToken token) { return token instanceof OAuth2Token; } /** * 授权(接口保护,验证接口调用权限时调用) */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SysUser user = (SysUser)principals.getPrimaryPrincipal(); // 用户权限列表,根据用户拥有的权限标识与如 @permission标注的接口对比,决定是否可以调用接口 Set permsSet = findPermissions(user.getName()); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; } /** * 认证(登录时调用) */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String token = (String) authenticationToken.getPrincipal(); // 根据accessToken,查询用户token信息 SysUserToken sysUserToken = sysUserTokenMapper.findByToken(token); if(sysUserToken == null || sysUserToken.getExpireTime().getTime() < System.currentTimeMillis()){ // token已经失效 throw new IncorrectCredentialsException("token失效,请重新登录"); } // 查询用户信息 SysUser user = sysUserMapper.selectByPrimaryKey(sysUserToken.getUserId()); // 账号被锁定 if(user.getStatus() == 0){ throw new LockedAccountException("账号已被锁定,请联系管理员"); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, token, getName()); return info; } private Set findPermissions(String userName) { Set perms = new HashSet(); List sysMenus = findByUser(userName); for(SysMenu sysMenu:sysMenus) { if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) { perms.add(sysMenu.getPerms()); } } return perms; } private List findByUser(String userName) { if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) { return sysMenuMapper.findAll(); } return sysMenuMapper.findByUserName(userName); } }

 

public class OAuth2Token implements AuthenticationToken { private static final long serialVersionUID = 1L; private String token; public OAuth2Token(String token){ this.token = token; } @Override public String getPrincipal() { return token; } @Override public Object getCredentials() { return token; } }

 到这,基本上就算完工了,告辞!

附:

public class BaseModel { private Long id; private String createBy; private Date createTime; private String lastUpdateBy; private Date lastUpdateTime; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getLastUpdateBy() { return lastUpdateBy; } public void setLastUpdateBy(String lastUpdateBy) { this.lastUpdateBy = lastUpdateBy; } public Date getLastUpdateTime() { return lastUpdateTime; } public void setLastUpdateTime(Date lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } }

 

public interface CurdService { /** * 保存操作 * @param record * @return */ int save(T record); /** * 删除操作 * @param record * @return */ int delete(T record); /** * 批量删除操作 * @param entities */ int delete(List records); /** * 根据ID查询 * @param id * @return */ T findById(Long id); /** * 分页查询 * 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象 * 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会 * 影响服务层以上的分页接口,起到了解耦的作用 * @param pageRequest 自定义,统一分页查询请求 * @return PageResult 自定义,统一分页查询结果 */ PageResult findPage(PageRequest pageRequest); }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3