使用Camunda流程引擎开发,共享任务如何实现?

momory

共 4342字,需浏览 9分钟

 ·

2022-03-06 16:03

最近在用Camunda流程引擎做业务开发时,产品经理提了一个需求:共享任务根据产品经理的描述:流程引擎首先会产生一个共享任务,然后多个人会看到此任务,如果有一个人执行了此任务之后,此任务就成已执行,其它人就不能执行,也看不到此任务了 ,流程流转到下一个节点举个栗子,有下面这样一样流程:37dbab11ef24eafb187b269a95e01d26.webp
在发起此流程后,执行完新增申请信息节点的任务后,在共享任务这个流程节点会产生一个任务,这个任务需要A、B 两人其中一个人来执行,要完成此功能先来整理下思路:

  1. 流程产生任务
  2. 记录能完成此任务的用户(如果有2个用户,2个用户都能看到此任务)
  3. 如果用户1有强迫症,看到任务提醒的红点都要点开查看,看到任务并完成后,流程流程到下一节点
思路清楚了,Camunda流程引擎是如何完成此功能的呢?在此流程中, 在完成【申请信息】节点产生的任务后,Camunda 流程引擎会帮助我们完成产生【共享任务】节点的任务重点:在完成【申请信息】的任务时,会把A、B 两人信息通过参数提交,Camunda 流程引擎会把A、B信息存储起来,并产生任务,此任务只有A、B两人都能看见那么问题来了,此信息存储在什么地方?在Camunda的库中,有ACT_HI_IDENTITYLINK这样一张表,此表记录了任务与人员的信息c8763cad792f7972470df56ac170dd0b.webp
我提交的参数分别是:demo、8,然后在此表中产生了2条数据那么问题又来了,没有写一行代码,是如何实现此功能的呢?Camunda 之所以很强大,就是在这些细节方面,现在一起来看看绘制流程图时都干了什么:a6311115c7060b2a57b3071f66de8033.webp
相信大家都注意到了图片中的红色框,配制一个 【candidateUsers】这样的参数,Camunda 就是根据此参数的值存 把任务与人的信息绑定并存储到 ACT_HI_IDENTITYLINK 表中只是查询任务的时候,去查询一下 ACT_HI_IDENTITYLINK 表就完成任务列表的功能了。
 /**         * 查询任务列表     */    @Override    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!其实还有很重要的一步需要做,那就是在完成任务的时候?这里留个疑问,大家可以结合下面的代码想一想,为什么?
@Overridepublic 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 ,大家可以一起交流!!
浏览 49
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报