上个小节我们实现了新增角色这个功能,那么按照CRUD的顺序,本小节我们要做修改角色信息的功能。
一、熟悉数据表
在tb_role
数据表里面有两个字段我要特殊说明一下,permissions
字段是JSON格式的,用来记录角色关联了哪些权限。由于有些角色是系统内置的,它包含初始的一些权限,这些初始权限保存在default_permissions
字段里面。
大家请看下面的修改角色弹窗,在穿梭框的右侧是该角色拥有的权限。如果该角色是系统内置角色,那么该角色默认的权限是无法取消的,我们只能在此基础之上为该角色关联其他的新权限。default_permissions
字段的作用现在凸显出来了。在前端页面在渲染穿梭框的时候,我们告诉穿梭框哪些选中的权限不能被取消。
大家可以去看TbRoleDao.xml
文件中的查询语句,根据角色ID查询角色的信息,default_permissions
字段返回给了前端。相关的DAO、Service和Controller代码大家可以去看一眼。
<select id="searchById" parameterType="int" resultType="HashMap">
SELECT id,
role_name AS roleName,
permissions,
`desc`,
default_permissions AS defaultPermissions
FROM tb_role
WHERE id = #{id}
</select>
二、编写持久层代码
在TbRoleDao.xml
文件中,定义SQL语句。searchUserIdByRoleId
这个SQL语句用来查询某个角色关联的用户,因为要把用户踢下线,所以要把这些用户查询出来。另外,因为超级管理员的id=0,所以update
这个SQL语句的WHERE id=#{id} AND id!=0
这句话的意思是不能修改超级管理员记录。
<select id="searchUserIdByRoleId" parameterType="int" resultType="int">
SELECT u.id
FROM tb_role r
JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE r.id=#{id}
</select>
<update id="update" parameterType="com.example.emos.api.db.pojo.TbRole">
UPDATE tb_role
SET role_name=#{roleName},
`desc`=#{desc},
permissions=#{permissions}
WHERE id=#{id} AND id!=0
</update>
在TbRoleDao.java
接口中,定义抽象DAO方法。
public interface TbRoleDao {
……
public ArrayList<Integer> searchUserIdByRoleId(int roleId);
public int update(TbRole role);
}
三、编写业务层代码
在RoleService.java
接口中,定义抽象方法。
public interface RoleService {
……
public ArrayList<Integer> searchUserIdByRoleId(int roleId);
public int update(TbRole role);
}
在RoleServiceImpl.java
类中,实现抽象方法。
public class RoleServiceImpl implements RoleService {
……
@Override
public ArrayList<Integer> searchUserIdByRoleId(int roleId) {
ArrayList<Integer> list = roleDao.searchUserIdByRoleId(roleId);
return list;
}
@Override
public int update(TbRole role) {
int rows = roleDao.update(role);
return rows;
}
}
四、编写Web层代码
创建UpdateRoleForm.java
类,封装Ajax提交的数据。
@Schema(description = "更新角色表单")
@Data
public class UpdateRoleForm {
@NotNull(message = "id不能为空")
@Schema(description = "角色ID")
private Integer id;
@NotBlank(message = "roleName不能为空")
@Pattern(regexp = "^[a-zA-Z0-9\\u4e00-\\u9fa5]{2,10}", message = "roleName内容不正确")
@Schema(description = "角色名称")
private String roleName;
@NotEmpty(message = "permissions不能为空")
@Schema(description = "权限")
private Integer[] permissions;
@Length(max = 20, message = "desc不能超过20个字符")
@Schema(description = "简介")
private String desc;
@NotNull(message = "changed不能为空")
@Schema(description = "权限是否改动了")
private Boolean changed;
}
在RoleController.java
类中,定义Web方法,然后就可以用Swagger测试这个Web方法了。
public class RoleController {
……
@PostMapping("/update")
@Operation(summary = "更新角色")
@SaCheckPermission(value = {"ROOT", "ROLE:UPDATE"}, mode = SaMode.OR)
public R update(@Valid @RequestBody UpdateRoleForm form) {
TbRole role = new TbRole();
role.setId(form.getId());
role.setRoleName(form.getRoleName());
role.setPermissions(JSONUtil.parseArray(form.getPermissions()).toString());
role.setDesc(form.getDesc());
int rows = roleService.update(role);
//如果用户修改成功,并且用户修改了该角色的关联权限
if (rows == 1 && form.getChanged()) {
//把该角色关联的用户踢下线
ArrayList<Integer> list = roleService.searchUserIdByRoleId(form.getId());
list.forEach(userId -> {
StpUtil.logoutByLoginId(userId);
});
}
return R.ok().put("rows", rows);
}
}