Activiti 添加监听获取下一节点数据

做会签功能时遇到的,想根据节点预设的候选人创建多实例

 常规操作是需要在进入会签节点之前设置好多实例参数,然后根据参数来生成多个实例。

看了很多场景都是在会签节点的上一个节点审批时,选择下一节点的处理人。

但是我想要操作简单一些,省去人工选择处理人的操作,直接在流程图中配置好处理人,自动创建多个实例。

所以就想到一个思路:在会签的前一个节点添加一个监听,获取会签节点的候选人

 

 监听类代码:

@Component
public class ApprovedCounterSignStartListener implements TaskListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void notify(DelegateTask delegateTask) {
        FlowElement resultTask = null;//定义返回值
        //流程定义Id
        String processDefId=delegateTask.getProcessDefinitionId();
        //通过流程资源部署类获取BpmnModel
        BpmnModel bpmnModel = SpringUtils.getBean(RepositoryService.class).getBpmnModel(processDefId);
        //直接使用当前task的定义key去查找模型中的节点(当前任务节点)
        FlowElement flowElement = bpmnModel.getProcesses().get(0).getFlowElement(delegateTask.getTaskDefinitionKey());
        UserTask nowUserTask = (UserTask)flowElement;//获取当前UserTask
        List<SequenceFlow> nowOutgoingFlows = nowUserTask.getOutgoingFlows();//当前任务流向节点(SequenceFlow: 连接两个节点之间的线)
        if(ObjectUtils.isNotEmpty(nowOutgoingFlows) && nowOutgoingFlows.size() == 1 ) {//如果只流向一个节点
            FlowElement nextFlowElement = nowOutgoingFlows.get(0).getTargetFlowElement();//下一节点
            if(UserTask.class.isInstance(nextFlowElement)) {//判断节点是否是UserTask
                resultTask = nextFlowElement;
            }else if(ExclusiveGateway.class.isInstance(nextFlowElement)){//判断是否是排他网关
                ExclusiveGateway exclusiveGateway = (ExclusiveGateway)nextFlowElement;
                List<SequenceFlow> exclusiveOutgoingFlows = exclusiveGateway.getOutgoingFlows();//排他网关流向节点

                if(ObjectUtils.isNotEmpty(exclusiveOutgoingFlows)
                        && exclusiveOutgoingFlows.size() == 1
                        && (UserTask.class.isInstance(exclusiveOutgoingFlows.get(0).getTargetFlowElement())
                        || EndEvent.class.isInstance(exclusiveOutgoingFlows.get(0).getTargetFlowElement()))) {   //如果排他网关只有一条线路信息并且是UserTask节点

                    resultTask = exclusiveOutgoingFlows.get(0).getTargetFlowElement();

                }else if(exclusiveOutgoingFlows.size() > 1) {   //如果排他网关有多条线路信息
                    for (SequenceFlow sequenceFlow : exclusiveOutgoingFlows) {
                        String conditionExpression = sequenceFlow.getConditionExpression();

                        if(isCondition(conditionExpression,delegateTask.getTransientVariables())) {//判断跳转条件是否成立
                            resultTask = sequenceFlow.getTargetFlowElement();//条件成立  返回节点对象
                        }
                    }
                }
            }
        }
        if(UserTask.class.isInstance(resultTask)){  //如果是人工节点
            nowUserTask = (UserTask)resultTask;
            List<String> candidateUsers = nowUserTask.getCandidateUsers();
            delegateTask.setVariable("users",candidateUsers);
        }
    }


    public boolean isCondition(String el, Map<String,Object> data) {
        ExpressionFactory expressionFactory = new ExpressionFactoryImpl();
        SimpleContext simpleContext = new SimpleContext();
        for (String dataKey : data.keySet()) {
            simpleContext.setVariable(dataKey, expressionFactory.createValueExpression(data.get(dataKey), String.class));
        }
        ValueExpression e = expressionFactory.createValueExpression(simpleContext, el, boolean.class);
        return (Boolean) e.getValue(simpleContext);
    }
}

处理的方式比较简易,只处理了上一节点出来后是排他网关的情况

然后还有一个地方不是很完善,在解析处理箭头的流条件时,只能处理简单的判断,类似于${!flag}、${num>2},稍微复杂一些就不行了,${approvedCounter == users.size()}就无法解析。

会签用这种方式感觉有些麻烦,肯定还有更好的解决方法,但是我目前只能想到这个。刚接触流程引擎,也还在研究阶段,如果有大佬看到可以指导一下,非常感谢。欢迎交流

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值