使用Camunda流程引擎开发,共享任务如何实现?
最近在用Camunda流程引擎做业务开发时,产品经理提了一个需求:共享任务根据产品经理的描述:流程引擎首先会产生一个共享任务,然后多个人会看到此任务,如果有一个人执行了此任务之后,此任务就成已执行,其它人就不能执行,也看不到此任务了 ,流程流转到下一个节点举个栗子,有下面这样一样流程:
在发起此流程后,执行完新增申请信息节点的任务后,在共享任务这个流程节点会产生一个任务,这个任务需要A、B 两人其中一个人来执行,要完成此功能先来整理下思路:
- 流程产生任务
- 记录能完成此任务的用户(如果有2个用户,2个用户都能看到此任务)
- 如果用户1有强迫症,看到任务提醒的红点都要点开查看,看到任务并完成后,流程流程到下一节点
我提交的参数分别是:demo、8,然后在此表中产生了2条数据那么问题又来了,没有写一行代码,是如何实现此功能的呢?Camunda 之所以很强大,就是在这些细节方面,现在一起来看看绘制流程图时都干了什么:
相信大家都注意到了图片中的红色框,配制一个 【candidateUsers】这样的参数,Camunda 就是根据此参数的值存 把任务与人的信息绑定并存储到 ACT_HI_IDENTITYLINK 表中只是查询任务的时候,去查询一下 ACT_HI_IDENTITYLINK 表就完成任务列表的功能了。
/** * 查询任务列表 */ public List getTodoTaskList(WorkflowQueryDto workflowQueryDto) { QueryWrapper queryWrapper = new QueryWrapper<>(); if(ObjectUtils.isNotEmpty(workflowQueryDto.getTaskId()) && StringUtils.isNotBlank(workflowQueryDto.getTaskId())) { queryWrapper.eq("ID_", workflowQueryDto.getTaskId()); } if(ObjectUtils.isNotEmpty(workflowQueryDto.getProcessDefinitionName()) && StringUtils.isNotBlank(workflowQueryDto.getProcessDefinitionName())) { queryWrapper.eq("PROC_DEF_NAME_", workflowQueryDto.getProcessDefinitionName()); } queryWrapper.or(ObjectUtils.isNotEmpty(workflowQueryDto.getOwner()), qw -> qw.eq("OWNER_", workflowQueryDto.getOwner())); queryWrapper.or(ObjectUtils.isNotEmpty(workflowQueryDto.getAssignee()), qw -> qw.eq("ASSIGNEE_", workflowQueryDto.getAssignee())); boolean isEmpty = StringUtils.isBlank(workflowQueryDto.getCandidateUsers()) && StringUtils.isBlank(workflowQueryDto.getCandidateGroups()); if (!isEmpty){ queryWrapper.or(qw -> { if(StringUtils.isNotBlank(workflowQueryDto.getCandidateUsers())) { qw.or().exists(String.format("select ID_ from ACT_HI_IDENTITYLINK " + "where TASK_ID_ = t.ID_ and TYPE_ = 'candidate' " + "and USER_ID_ = '%s'", workflowQueryDto.getCandidateUsers())); } if (StringUtils.isNotBlank(workflowQueryDto.getCandidateGroups())) { String groupIds = StringUtils.getSqlInStringByArray(workflowQueryDto.getCandidateGroups()); qw.or().exists(String.format("select ID_ from ACT_HI_IDENTITYLINK " + "where TASK_ID_ = t.ID_ and TYPE_ = 'candidate' " + "and GROUP_ID_ in (%s)", groupIds)); } }); } queryWrapper.orderByDesc("START_TIME_"); return workflowTaskMapper.listTodoTaskByPage(queryWrapper); } // 对应 Mapper 接口里的查询方法 @Select("SELECT * from (" + " SELECT t1.*, t3.NAME_ procDefName FROM ACT_HI_TASKINST t1 " + "left JOIN ACT_RE_PROCDEF t2 on t1.PROC_DEF_ID_ = t2.ID_ " + "left join ACT_RE_DEPLOYMENT t3 on t3.ID_ = t2.DEPLOYMENT_ID_ "+ " )t ${ew.customSqlSegment}") List listCompleteTaskByPage( @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
到这里完成了参数设置、任务展示,是不是功能就完了呢?NO!其实还有很重要的一步需要做,那就是在完成任务的时候?这里留个疑问,大家可以结合下面的代码想一想,为什么?String completeTask(String taskId, WorkflowVariableDto dto) { // 获取完成前任务 Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if(ObjectUtils.isEmpty(task)){ return "没有查找到当前任务"; } // 对共享任务的处理 if(StringUtils.isBlank(task.getAssignee())){ if(StringUtils.isBlank(dto.getVariables().get("assignee").toString())){ return"当前任务为共享任务,请先设置执行人"; }else { claimTask(taskId, dto.getVariables().get("assignee").toString()); } } // 完成任务填写的备注 if(StringUtils.isNotBlank(dto.getReason()) && StringUtils.isNotBlank(task.getProcessInstanceId())){ taskService.createComment(task.getId(), task.getProcessInstanceId(), dto.getReason()); } // 完成当前任务 taskService.complete(taskId, dto.getVariables()); return null;}// taskId 任务ID// claimUser 认领用户ID@Overridepublic void claimTask(String taskId, String claimUser) { taskService.claim(taskId, claimUser);}
OK,今天就写到这里,如果你使用过或者正在使用Camunda ,大家可以一起交流!!评论