全部开发者教程

企业级在线办公系统

上个小节我们实现了新增角色这个功能,那么按照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);
    }
}