Activiti Task:排除候选组特定用户申领任务失败求助
解决Activiti候选组中排除特定用户的问题
我明白你的困扰——给任务设置了候选组CG1后,尝试用delegateTask.deleteCandidateUser(userId)排除某个用户却完全没效果对吧?这其实是因为你误解了这个API的作用,咱们一步步拆解解决:
为什么deleteCandidateUser()没生效?
Activiti中,当任务关联了候选组时,属于该组的所有用户都会自动获得任务的查看和申领权限,不管有没有单独把用户添加为个人候选人。而deleteCandidateUser()这个方法,只是删除用户作为个人候选人的身份记录,并不会移除用户通过候选组获得的权限。所以哪怕你调用了这个方法,目标用户依然能通过CG1组看到任务。
可行的解决方案
方案1:动态生成候选用户列表(从根源排除)
如果可以修改任务创建的逻辑,不要直接把CG1设为候选组,而是先获取CG1的所有用户,排除目标用户后,再把剩下的用户逐个添加为任务的候选用户:
// 1. 获取CG1组下的所有用户 List<User> groupUsers = identityService.createUserQuery().memberOfGroup("CG1").list(); // 2. 过滤掉要排除的用户 String excludedUserId = "你的目标用户ID"; groupUsers.removeIf(user -> excludedUserId.equals(user.getId())); // 3. 把剩余用户添加为任务候选 for (User user : groupUsers) { taskService.addCandidateUser(delegateTask.getId(), user.getId()); }
这种方式从根源上确保被排除的用户不在候选人范围内,自然看不到任务。
方案2:查询时过滤(适合无法修改任务创建逻辑的场景)
如果任务已经关联了CG1组,没法修改创建逻辑,那就在用户查询可申领任务的时候,手动过滤掉被排除的用户:
// 获取当前登录用户ID String currentUserId = SecurityContextHolder.getContext().getAuthentication().getName(); String excludedUserId = "你的目标用户ID"; // 构建任务查询 TaskQuery taskQuery = taskService.createTaskQuery() .taskCandidateGroup("CG1"); // 如果当前用户是被排除的,直接返回空结果 if (excludedUserId.equals(currentUserId)) { taskQuery = taskQuery.taskIdIn(Collections.emptyList()); } List<Task> availableTasks = taskQuery.list();
这样被排除的用户查询时就看不到这个任务了。
方案3:申领时拦截(防止用户即使看到也无法申领)
如果前面两种方式都不适用,还可以添加一个任务监听器,在用户尝试申领任务时校验身份,拒绝被排除的用户:
public class ExcludeUserClaimListener implements TaskListener { @Override public void notify(DelegateTask delegateTask) { String excludedUserId = "你的目标用户ID"; // 获取尝试申领的用户ID(可根据实际场景从上下文或变量中获取) String claimingUserId = SecurityContextHolder.getContext().getAuthentication().getName(); if (excludedUserId.equals(claimingUserId)) { throw new ActivitiException("抱歉,你没有权限申领此任务"); } } }
然后在流程定义的任务节点上,把这个监听器绑定到claim事件上,这样即使用户看到任务,点击申领也会被拒绝。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

