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

最近在用Camunda流程引擎做业务开发时,产品经理提了一个需求:共享任务

根据产品经理的描述:流程引擎首先会产生一个共享任务,然后多个人会看到此任务,如果有一个人执行了此任务之后,此任务就成已执行,其它人就不能执行,也看不到此任务了 ,流程流转到下一个节点

举个栗子,有下面这样一样流程:

 

在发起此流程后,执行完新增申请信息节点的任务后,在共享任务这个流程节点会产生一个任务,这个任务需要A、B 两人其中一个人来执行,要完成此功能

先来整理下思路:

  1. 流程产生任务

  2. 记录能完成此任务的用户(如果有2个用户,2个用户都能看到此任务)

  3. 如果用户1有强迫症,看到任务提醒的红点都要点开查看,看到任务并完成后,流程流程到下一节点

思路清楚了,Camunda流程引擎是如何完成此功能的呢?

在此流程中, 在完成【申请信息】节点产生的任务后,Camunda 流程引擎会帮助我们完成产生【共享任务】节点的任务

重点在完成【申请信息】的任务时,会把A、B 两人信息通过参数提交,Camunda 流程引擎会把A、B信息存储起来,并产生任务,此任务只有A、B两人都能看见

那么问题来了,此信息存储在什么地方?

在Camunda的库中,有ACT_HI_IDENTITYLINK这样一张表,此表记录了任务与人员的信息

 

我提交的参数分别是:demo、8,然后在此表中产生了2条数据

那么问题又来了,没有写一句代码,是如何实现此功能的呢?

Camunda 之所以很强大,就是在这些细节方面,现在一起来看看绘制流程图时都干了什么:

 

相信大家都注意到了图片中的红色框,配制一个 【candidateUsers】这样的参数,Camunda 就是根据此参数的值存 把任务与人的信息绑定并存储到 ACT_HI_IDENTITYLINK 表中

只是查询任务的时候,去查询一下 ACT_HI_IDENTITYLINK 表就完成任务列表的功能了。

  /**

        * 查询任务列表

    */

    @Override

    public List<WorkflowTaskEntity> getTodoTaskList(WorkflowQueryDto workflowQueryDto) {

        QueryWrapper<WorkflowTaskEntity> 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<WorkflowTaskEntity> listCompleteTaskByPage(

        @Param(Constants.WRAPPER) QueryWrapper<WorkflowTaskEntity> queryWrapper);

到这里完成了参数设置、任务展示,是不是功能就完了呢?

NO!

其实还有很重要的一步需要做,那就是在完成任务的时候?

这里留个疑问,大家可以结合下面的代码想一想,为什么?

@Override

public 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

@Override

public void claimTask(String taskId, String claimUser) {
    taskService.claim(taskId, claimUser);

}

OK,今天就写到这里,如果你使用过或者正在使用Camunda ,大家可以一起交流!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周的JAVA技术栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值