全部开发者教程

企业级在线办公系统

上个小节我们调通了修改角色信息的功能,那么这节课我们来写删除角色记录的后端Java代码。注意,系统内置角色是不能删除的,一旦删除会影响到工作流程序。比如说员工请假需要部门经理审批,如果你把部门经理角色删除了,那么谁来审批员工请假呢?所以我们只能删除非内置的角色,而且是那种没有关联任何用户的角色才能被删除,关联了用户的角色是不能删除的。

一、编写持久层代码

TbRoleDao.xml文件中,定义两个SQL语句。

<select id="searchCanDelete" resultType="boolean">
    SELECT IF( SUM( temp.users ) > 0, FALSE, TRUE ) AS result FROM (
        SELECT COUNT( u.id ) AS users
        FROM tb_role r
        JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
        WHERE r.id IN
        <foreach collection="array" open="(" separator="," close=")" item="one">
            #{one}
        </foreach>
        GROUP BY r.id
    ) temp
</select>
<delete id="deleteRoleByIds">
    DELETE FROM tb_role
    WHERE id IN
    <foreach collection="array" open="(" separator="," close=")" item="one">
        #{one}
    </foreach>
    AND systemic=FALSE
</delete>

我先来说一下searchCanDelete这个SQL语句,这个SQL语句很不好理解没关系,我告诉你他的原理是什么。我用几个简单的SQL语句,来告诉你复杂的SQL语句是怎么进化来的。例如下面的SQL语句是分组查询每种角色的用户数量。

SELECT COUNT( u.id ) AS users
FROM tb_role r
JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
WHERE r.id IN (1,2,4)
GROUP BY r.id;

SQL语句运行结果如下:

如果我们把上面的SQL语句查询的结果当做一张临时表,统计求和是否大于零。如果大于零,说明你要删除的这些角色中,有关联用户的角色。大家仔细想想,用户在前端页面勾选了若干角色,想要删除这些角色。后端只要盘判定出这些角色,无论哪一个只要存在关联的用户,那么这些要删除的角色一律不许删除。除非我们统计求和的结果是零,说明这些要删除的角色都没有关联用户,这些角色允许删除。

SELECT IF( SUM( temp.users ) > 0, FALSE, TRUE ) AS result FROM (
    SELECT COUNT( u.id ) AS users
    FROM tb_role r
    JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) )
    WHERE r.id IN (1,2,4)
    GROUP BY r.id
 ) temp;

SQL运行的结果如下:

由于MySQL中的FALSE用数字零表示,所以SQL语句查询出来我想要删除的3个角色存在关联的用户。现在大家再去看看searchCanDelete这个SQL语句,估计就能看懂了。另外,deleteRoleByIds这个SQL语句中WHERE子句的条件写的很清楚,只能删除非内置的角色。

TbRoleDao.java接口中,定义DAO方法。

public interface TbRoleDao {
    ……
    public boolean searchCanDelete(Integer[] ids);
    public int deleteRoleByIds(Integer[] ids);
}

二、编写业务层代码

RoleService.java接口中,定义抽象方法。

public interface RoleService {
    ……
    public int deleteRoleByIds(Integer[] ids);
}

RoleServiceImpl.java类中,实现抽象方法,其中就有判定角色是否能删除。

public class RoleServiceImpl implements RoleService {
    ……
    @Override
    public int deleteRoleByIds(Integer[] ids) {
        if (!roleDao.searchCanDelete(ids)) {
            throw new EmosException("无法删除关联用户的角色");
        }
        int rows = roleDao.deleteRoleByIds(ids);
        return rows;
    }
}

三、编写Web层代码

创建DeleteRoleByIdsForm.java类,封装Ajax提交的数据。

@Data
@Schema(description = "删除角色表单")
public class DeleteRoleByIdsForm {

    @NotEmpty(message = "ids不能为空")
    @Schema(description = "角色ID")
    private Integer[] ids;
}

RoleController.java类中,声明Web方法,然后大家可以用Swagger测试一下。

public class RoleController {
    ……
    @PostMapping("/deleteRoleByIds")
    @Operation(summary = "删除角色记录")
    @SaCheckPermission(value = {"ROOT", "ROLE:DELETE"}, mode = SaMode.OR)
    public R deleteRoleByIds(@Valid @RequestBody DeleteRoleByIdsForm form) {
        int rows = roleService.deleteRoleByIds(form.getIds());
        return R.ok().put("rows", rows);
    }
}