本系列文章均参考:朝雨忆轻尘,感谢博主!
这里还有他的技术交流群: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<SysUserRole> 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<SysUserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(List<SysUserRole> 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<SysUser> findPage();
SysUser findByName(@Param(value="name") String name);
List<SysUser> findPageByName(@Param(value="name") String name);
List<SysUser> findPageByNameAndEmail(@Param(value="name") String name, @Param(value="email") String email);
}
3.1.3、mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.dao.SysUserMapper">
<resultMap id="BaseResultMap" type="com.***.model.SysUser">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="salt" jdbcType="VARCHAR" property="salt" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="mobile" jdbcType="VARCHAR" property="mobile" />
<result column="status" jdbcType="TINYINT" property="status" />
<result column="dept_id" jdbcType="BIGINT" property="deptId" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
<result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
<result column="del_flag" jdbcType="TINYINT" property="delFlag" />
</resultMap>
<sql id="Base_Column_List">
id, name, password, salt, email, mobile, status, dept_id, create_by, create_time,
last_update_by, last_update_time, del_flag
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_user
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from sys_user
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.***.model.SysUser">
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>
<insert id="insertSelective" parameterType="com.***.model.SysUser">
insert into sys_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
<if test="password != null">
password,
</if>
<if test="salt != null">
salt,
</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="createBy != null">
create_by,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="lastUpdateBy != null">
last_update_by,
</if>
<if test="lastUpdateTime != null">
last_update_time,
</if>
<if test="delFlag != null">
del_flag,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="password != null">
#{password,jdbcType=VARCHAR},
</if>
<if test="salt != null">
#{salt,jdbcType=VARCHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="mobile != null">
#{mobile,jdbcType=VARCHAR},
</if>
<if test="status != null">
#{status,jdbcType=TINYINT},
</if>
<if test="deptId != null">
#{deptId,jdbcType=BIGINT},
</if>
<if test="createBy != null">
#{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
#{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
#{delFlag,jdbcType=TINYINT},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysUser">
update sys_user
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="salt != null">
salt = #{salt,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="mobile != null">
mobile = #{mobile,jdbcType=VARCHAR},
</if>
<if test="status != null">
status = #{status,jdbcType=TINYINT},
</if>
<if test="deptId != null">
dept_id = #{deptId,jdbcType=BIGINT},
</if>
<if test="createBy != null">
create_by = #{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
del_flag = #{delFlag,jdbcType=TINYINT},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.***.model.SysUser">
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}
</update>
<select id="findPage" resultMap="BaseResultMap">
select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where
</select>
<select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
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>
<select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
<bind name="pattern" value="'%' + _parameter.name + '%'" />
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>
<select id="findPageByNameAndEmail" parameterType="java.lang.String" resultMap="BaseResultMap">
<bind name="patternName" value="'%' + _parameter.name + '%'" />
<bind name="patternEmail" value="'%' + _parameter.email + '%'" />
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}
</select>
</mapper>
3.1.4、service以及impl
public interface SysUserService extends CurdService<SysUser> {
SysUser findByName(String username);
SysUser findByToken(String token);
/**
* 查找用户的菜单权限标识集合
* @param userName
* @return
*/
Set<String> findPermissions(String userName);
/**
* 查找用户的角色集合
* @param userName
* @return
*/
List<SysUserRole> 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<SysUser> 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<SysUserRole> userRoles = findUserRoles(sysUser.getId());
sysUser.setUserRoles(userRoles);
sysUser.setRoleNames(getRoleNames(userRoles));
}
}
private String getRoleNames(List<SysUserRole> userRoles) {
StringBuilder sb = new StringBuilder();
for(Iterator<SysUserRole> 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<String> findPermissions(String userName) {
Set<String> perms = new HashSet<>();
List<SysMenu> sysMenus = findByUser(userName);
for(SysMenu sysMenu:sysMenus) {
if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) {
perms.add(sysMenu.getPerms());
}
}
return perms;
}
@Override
public List<SysUserRole> findUserRoles(Long userId) {
return sysUserRoleMapper.findUserRoles(userId);
}
private List<SysMenu> 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<SysRole> findPage();
List<SysRole> findAll();
List<SysRole> findPageByName(@Param(value="name") String name);
List<SysRole> findByName(@Param(value="name") String name);
}
3.2.3、mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.dao.SysRoleMapper">
<resultMap id="BaseResultMap" type="com.***.model.SysRole">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="remark" jdbcType="VARCHAR" property="remark" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
<result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
<result column="del_flag" jdbcType="TINYINT" property="delFlag" />
</resultMap>
<sql id="Base_Column_List">
id, name, remark, create_by, create_time, last_update_by, last_update_time,
del_flag
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from sys_role
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.***.model.SysRole">
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>
<insert id="insertSelective" parameterType="com.***.model.SysRole">
insert into sys_role
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
<if test="remark != null">
remark,
</if>
<if test="createBy != null">
create_by,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="lastUpdateBy != null">
last_update_by,
</if>
<if test="lastUpdateTime != null">
last_update_time,
</if>
<if test="delFlag != null">
del_flag,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="remark != null">
#{remark,jdbcType=VARCHAR},
</if>
<if test="createBy != null">
#{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
#{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
#{delFlag,jdbcType=TINYINT},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysRole">
update sys_role
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="remark != null">
remark = #{remark,jdbcType=VARCHAR},
</if>
<if test="createBy != null">
create_by = #{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
del_flag = #{delFlag,jdbcType=TINYINT},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.***.model.SysRole">
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}
</update>
<select id="findPage" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role
</select>
<select id="findAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role
</select>
<select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
<bind name="pattern" value="'%' + _parameter.name + '%'" />
select
<include refid="Base_Column_List" />
from sys_role
where name like #{pattern}
</select>
<select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role
where name = #{name,jdbcType=VARCHAR}
</select>
</mapper>
3.2.4、service以及impl
public interface SysRoleService extends CurdService<SysRole> {
/**
* 查询全部
* @return
*/
List<SysRole> findAll();
/**
* 查询角色菜单集合
* @return
*/
List<SysMenu> findRoleMenus(Long roleId);
/**
* 保存角色菜单
* @param records
* @return
*/
int saveRoleMenus(List<SysRoleMenu> records);
/**
* 根据名称查询
* @param name
* @return
*/
List<SysRole> findByName(String name);
/**
* 查询角色区域集合
* @return
*/
List<SysArea> findRoleAreas(Long roleId);
/**
* 保存角色区域
* @param records
* @return
*/
int saveRoleAreas(List<SysRoleArea> records);
List<SysRole> 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<SysRole> 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<SysRole> findAll() {
return sysRoleMapper.findAll();
}
public SysRoleMapper getSysRoleMapper() {
return sysRoleMapper;
}
public void setSysRoleMapper(SysRoleMapper sysRoleMapper) {
this.sysRoleMapper = sysRoleMapper;
}
@Override
public List<SysMenu> 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<SysRoleMenu> 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<SysRole> findByName(String name) {
return sysRoleMapper.findByName(name);
}
@Override
public List<SysArea> 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<SysRoleArea> 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<SysRole> findRoleByName(String name) {
SysUser user = sysUserMapper.findByName(name);
List<SysUserRole> userRoles = sysUserRoleMapper.findUserRoles(user.getId());
List<SysRole> 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<SysMenu> 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<SysMenu> getChildren() {
return children;
}
public void setChildren(List<SysMenu> 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<SysMenu> findPage();
List<SysMenu> findPageByName(@Param(value="name") String name);
List<SysMenu> findAll();
List<SysMenu> findByUserName(@Param(value="userName") String userName);
List<SysMenu> findByName(@Param(value="name") String name);
List<SysMenu> findSimpleByName(@Param(value="name") String name);
List<SysMenu> findRoleMenus(@Param(value="roleId") Long roleId);
}
3.3.3、mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.dao.SysMenuMapper">
<resultMap id="BaseResultMap" type="com.***.model.SysMenu">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="parent_id" jdbcType="BIGINT" property="parentId" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="url" jdbcType="VARCHAR" property="url" />
<result column="perms" jdbcType="VARCHAR" property="perms" />
<result column="type" jdbcType="INTEGER" property="type" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="order_num" jdbcType="INTEGER" property="orderNum" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
<result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
<result column="del_flag" jdbcType="TINYINT" property="delFlag" />
</resultMap>
<sql id="Base_Column_List">
id, parent_id, name, url, perms, type, icon, order_num, create_by, create_time,
last_update_by, last_update_time, del_flag
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_menu
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from sys_menu
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.***.model.SysMenu">
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>
<insert id="insertSelective" parameterType="com.***.model.SysMenu">
insert into sys_menu
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="parentId != null">
parent_id,
</if>
<if test="name != null">
name,
</if>
<if test="url != null">
url,
</if>
<if test="perms != null">
perms,
</if>
<if test="type != null">
type,
</if>
<if test="icon != null">
icon,
</if>
<if test="orderNum != null">
order_num,
</if>
<if test="createBy != null">
create_by,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="lastUpdateBy != null">
last_update_by,
</if>
<if test="lastUpdateTime != null">
last_update_time,
</if>
<if test="delFlag != null">
del_flag,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="parentId != null">
#{parentId,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="url != null">
#{url,jdbcType=VARCHAR},
</if>
<if test="perms != null">
#{perms,jdbcType=VARCHAR},
</if>
<if test="type != null">
#{type,jdbcType=INTEGER},
</if>
<if test="icon != null">
#{icon,jdbcType=VARCHAR},
</if>
<if test="orderNum != null">
#{orderNum,jdbcType=INTEGER},
</if>
<if test="createBy != null">
#{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
#{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
#{delFlag,jdbcType=TINYINT},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysMenu">
update sys_menu
<set>
<if test="parentId != null">
parent_id = #{parentId,jdbcType=BIGINT},
</if>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="url != null">
url = #{url,jdbcType=VARCHAR},
</if>
<if test="perms != null">
perms = #{perms,jdbcType=VARCHAR},
</if>
<if test="type != null">
type = #{type,jdbcType=INTEGER},
</if>
<if test="icon != null">
icon = #{icon,jdbcType=VARCHAR},
</if>
<if test="orderNum != null">
order_num = #{orderNum,jdbcType=INTEGER},
</if>
<if test="createBy != null">
create_by = #{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
<if test="delFlag != null">
del_flag = #{delFlag,jdbcType=TINYINT},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.***.model.SysMenu">
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}
</update>
<select id="findAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_menu
</select>
<select id="findPage" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_menu
</select>
<select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
<bind name="pattern" value="'%' + _parameter.name + '%'" />
select
<include refid="Base_Column_List" />
from sys_menu
where name like #{pattern}
</select>
<select id="findByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">
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>
<select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
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>
<select id="findSimpleByName" parameterType="java.lang.String" resultMap="BaseResultMap">
select m.* from sys_menu m
where m.name = #{name,jdbcType=VARCHAR}
</select>
<select id="findRoleMenus" parameterType="java.lang.Long" resultMap="BaseResultMap">
select m.* from sys_menu m, sys_role_menu rm
where rm.role_id = #{roleId,jdbcType=BIGINT}
and m.id = rm.menu_id
</select>
</mapper>
3.3.4、service以及impl
public interface SysMenuService extends CurdService<SysMenu> {
/**
* 查询菜单树,用户ID和用户名为空则查询全部
* @param menuType 获取菜单类型,0:获取所有菜单,包含按钮,1:获取所有菜单,不包含按钮
* @param userId
* @return
*/
List<SysMenu> findTree(String userName, int menuType,String name);
/**
* 根据用户名查找菜单列表
* @param userName
* @return
*/
List<SysMenu> findByUser(String userName, String name);
List<SysMenu> 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<SysMenu> 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<SysMenu> findTree(String userName, int menuType,String name) {
List<SysMenu> sysMenus = new ArrayList<>();
List<SysMenu> 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<SysMenu> 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<SysMenu> SysMenus, List<SysMenu> menus, int menuType) {
for (SysMenu SysMenu : SysMenus) {
List<SysMenu> 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<SysMenu> sysMenus, SysMenu sysMenu) {
boolean exist = false;
for(SysMenu menu:sysMenus) {
if(menu.getId().equals(sysMenu.getId())) {
exist = true;
}
}
return exist;
}
@Override
public List<SysMenu> 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<SysUserRole> findUserRoles(@Param(value="userId") Long userId);
int deleteByUserId(@Param(value="userId") Long userId);
}
3.4.3、mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.dao.SysUserRoleMapper">
<resultMap id="BaseResultMap" type="com.***.model.SysUserRole">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="user_id" jdbcType="BIGINT" property="userId" />
<result column="role_id" jdbcType="BIGINT" property="roleId" />
</resultMap>
<sql id="Base_Column_List">
id, user_id, role_id
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_user_role
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from sys_user_role
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.***.model.SysUserRole">
insert into sys_user_role (id, user_id, role_id
)
values (#{id,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}
)
</insert>
<insert id="insertSelective" parameterType="com.***.model.SysUserRole">
insert into sys_user_role
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="userId != null">
user_id,
</if>
<if test="roleId != null">
role_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="userId != null">
#{userId,jdbcType=BIGINT},
</if>
<if test="roleId != null">
#{roleId,jdbcType=BIGINT},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysUserRole">
update sys_user_role
<set>
<if test="userId != null">
user_id = #{userId,jdbcType=BIGINT},
</if>
<if test="roleId != null">
role_id = #{roleId,jdbcType=BIGINT},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.***.model.SysUserRole">
update sys_user_role
set user_id = #{userId,jdbcType=BIGINT},
role_id = #{roleId,jdbcType=BIGINT}
where id = #{id,jdbcType=BIGINT}
</update>
<select id="findUserRoles" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_user_role
where user_id = #{userId,jdbcType=BIGINT}
</select>
<delete id="deleteByUserId" parameterType="java.lang.Long">
delete from sys_user_role
where user_id = #{userId,jdbcType=BIGINT}
</delete>
</mapper>
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<SysRoleMenu> findRoleMenus(@Param(value="roleId") Long roleId);
List<SysRoleMenu> findAll();
int deleteByRoleId(@Param(value="roleId") Long roleId);
}
3.5.3、mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.***.dao.SysRoleMenuMapper">
<resultMap id="BaseResultMap" type="com.***.model.SysRoleMenu">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="role_id" jdbcType="BIGINT" property="roleId" />
<result column="menu_id" jdbcType="BIGINT" property="menuId" />
<result column="create_by" jdbcType="BIGINT" property="createBy" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
<result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
</resultMap>
<sql id="Base_Column_List">
id, role_id, menu_id, create_by, create_time, last_update_by, last_update_time
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role_menu
where id = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from sys_role_menu
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="com.***.model.SysRoleMenu">
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>
<insert id="insertSelective" parameterType="com.***.model.SysRoleMenu">
insert into sys_role_menu
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="roleId != null">
role_id,
</if>
<if test="menuId != null">
menu_id,
</if>
<if test="createBy != null">
create_by,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="lastUpdateBy != null">
last_update_by,
</if>
<if test="lastUpdateTime != null">
last_update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="roleId != null">
#{roleId,jdbcType=BIGINT},
</if>
<if test="menuId != null">
#{menuId,jdbcType=BIGINT},
</if>
<if test="createBy != null">
#{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
#{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
#{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysRoleMenu">
update sys_role_menu
<set>
<if test="roleId != null">
role_id = #{roleId,jdbcType=BIGINT},
</if>
<if test="menuId != null">
menu_id = #{menuId,jdbcType=BIGINT},
</if>
<if test="createBy != null">
create_by = #{createBy,jdbcType=BIGINT},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="lastUpdateBy != null">
last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
</if>
<if test="lastUpdateTime != null">
last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.***.model.SysRoleMenu">
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}
</update>
<select id="findRoleMenus" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role_menu
where role_id = #{roleId,jdbcType=BIGINT}
</select>
<select id="findAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_role_menu
</select>
<delete id="deleteByRoleId" parameterType="java.lang.Long">
delete from sys_role_menu
where role_id = #{roleId,jdbcType=BIGINT}
</delete>
</mapper>
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<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new OAuth2Filter());
shiroFilter.setFilters(filters);
// 访问路径拦截配置,"anon"表示无需验证,未登录也可访问
Map<String, String> 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<String> 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<String> findPermissions(String userName) {
Set<String> perms = new HashSet<>();
List<SysMenu> sysMenus = findByUser(userName);
for(SysMenu sysMenu:sysMenus) {
if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) {
perms.add(sysMenu.getPerms());
}
}
return perms;
}
private List<SysMenu> 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<T> {
/**
* 保存操作
* @param record
* @return
*/
int save(T record);
/**
* 删除操作
* @param record
* @return
*/
int delete(T record);
/**
* 批量删除操作
* @param entities
*/
int delete(List<T> records);
/**
* 根据ID查询
* @param id
* @return
*/
T findById(Long id);
/**
* 分页查询
* 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象
* 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会
* 影响服务层以上的分页接口,起到了解耦的作用
* @param pageRequest 自定义,统一分页查询请求
* @return PageResult 自定义,统一分页查询结果
*/
PageResult findPage(PageRequest pageRequest);
}