使用Camunda流程引擎開發(fā),共享任務(wù)如何實現(xiàn)?
最近在用Camunda流程引擎做業(yè)務(wù)開發(fā)時,產(chǎn)品經(jīng)理提了一個需求:共享任務(wù)根據(jù)產(chǎn)品經(jīng)理的描述:流程引擎首先會產(chǎn)生一個共享任務(wù),然后多個人會看到此任務(wù),如果有一個人執(zhí)行了此任務(wù)之后,此任務(wù)就成已執(zhí)行,其它人就不能執(zhí)行,也看不到此任務(wù)了 ,流程流轉(zhuǎn)到下一個節(jié)點舉個栗子,有下面這樣一樣流程:
在發(fā)起此流程后,執(zhí)行完新增申請信息節(jié)點的任務(wù)后,在共享任務(wù)這個流程節(jié)點會產(chǎn)生一個任務(wù),這個任務(wù)需要A、B 兩人其中一個人來執(zhí)行,要完成此功能先來整理下思路:
- 流程產(chǎn)生任務(wù)
- 記錄能完成此任務(wù)的用戶(如果有2個用戶,2個用戶都能看到此任務(wù))
- 如果用戶1有強迫癥,看到任務(wù)提醒的紅點都要點開查看,看到任務(wù)并完成后,流程流程到下一節(jié)點

我提交的參數(shù)分別是:demo、8,然后在此表中產(chǎn)生了2條數(shù)據(jù)那么問題又來了,沒有寫一行代碼,是如何實現(xiàn)此功能的呢?Camunda 之所以很強大,就是在這些細節(jié)方面,現(xiàn)在一起來看看繪制流程圖時都干了什么:

相信大家都注意到了圖片中的紅色框,配制一個 【candidateUsers】這樣的參數(shù),Camunda 就是根據(jù)此參數(shù)的值存 把任務(wù)與人的信息綁定并存儲到 ACT_HI_IDENTITYLINK 表中只是查詢?nèi)蝿?wù)的時候,去查詢一下 ACT_HI_IDENTITYLINK 表就完成任務(wù)列表的功能了。
/** * 查詢?nèi)蝿?wù)列表 */ 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); 到這里完成了參數(shù)設(shè)置、任務(wù)展示,是不是功能就完了呢?NO!其實還有很重要的一步需要做,那就是在完成任務(wù)的時候?這里留個疑問,大家可以結(jié)合下面的代碼想一想,為什么? String completeTask(String taskId, WorkflowVariableDto dto) { // 獲取完成前任務(wù) Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if(ObjectUtils.isEmpty(task)){ return "沒有查找到當前任務(wù)"; } // 對共享任務(wù)的處理 if(StringUtils.isBlank(task.getAssignee())){ if(StringUtils.isBlank(dto.getVariables().get("assignee").toString())){ return"當前任務(wù)為共享任務(wù),請先設(shè)置執(zhí)行人"; }else { claimTask(taskId, dto.getVariables().get("assignee").toString()); } } // 完成任務(wù)填寫的備注 if(StringUtils.isNotBlank(dto.getReason()) && StringUtils.isNotBlank(task.getProcessInstanceId())){ taskService.createComment(task.getId(), task.getProcessInstanceId(), dto.getReason()); } // 完成當前任務(wù) taskService.complete(taskId, dto.getVariables()); return null;}// taskId 任務(wù)ID// claimUser 認領(lǐng)用戶ID@Overridepublic void claimTask(String taskId, String claimUser) { taskService.claim(taskId, claimUser);}OK,今天就寫到這里,如果你使用過或者正在使用Camunda ,大家可以一起交流!!評論
圖片
表情
