flowable之驳回多实例驳回并行网关驳回普通节点驳回到多实例

liuwenjun liuwenjun     2022-12-29     433

关键词:

flowable 驳回

欢迎大家学习交流,如有不对的地方,请大家多多指教,我接下来会把flowable的所有的中国式API*都写出来,也希望对大家有帮助,程序员只要静下心来,其实可以产生巨大的能量,靠任何人都没有用,唯有靠自己。学习好一门技术,还是多看看源代码,多在实际工作中用,如果想走捷径,想通过一本书或者一些视频想学好,那永远是痴心说梦。*

网上搜索了很多关于activiti的驳回方法,flowable的驳回方法,发现一个问题,基本都是在扯淡,根本无法解决商业用途,为了把这块吃透,我最近研究了一下他们的源代码,已在我们公司使用,暂时没有发现问题。其实看flowable的源代码很简单的,就是一个命令模式,仿照他们的命令模式写自己的就可以了,没有太大的难度。不得不佩服flowable的作者,用命令模式规范了自己的代码,而且把这么好的东西开源出来,从来没有找我们要过钱,这是何等的伟大,像大神致敬。闲话不多说,直接来代码比较干脆。

由于我们公司的流程有规范,所以有写地方有点特殊,如果不懂的可以随时给我留言即可,来也网络,去也网络。

  • 1. 判断该节点上一个节点是不是并行网关节点
  • 2. 如果上一个节点是提交者的话要处理一下
  • 3. 添加审批意见和修改流程状态
  • 4. 删除现有的所有任务
  • 5. 删除节点信息
  • 6. 驳回到disk节点
  • 6.1 如果当前节点是多实例节点 删除当前多实例 如果目标节点不是多实例我们就创建一个孩子实例
  • 6.2 处理并行网关的多实例

    具体代码

 public ReturnVo<String> backToStep(BackVo backVo) 
        ReturnVo<String> returnVo = new ReturnVo<>(ReturnCode.SUCCESS, "OK");
        if (backVo != null && StringUtils.isNotBlank(backVo.getTaskId())) 
            TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(backVo.getTaskId()).singleResult();
            if (taskEntity != null)
                Activity distActivity = processDefinitionUtils.findFlowElementById(taskEntity.getProcessDefinitionId(), backVo.getDistFlowElementId());
                if (taskEntity != null && distActivity != null) 
                    //1. 判断该节点上一个节点是不是并行网关节点
                    List<SequenceFlow> incomingFlows = distActivity.getIncomingFlows();
                    if (CollectionUtils.isNotEmpty(incomingFlows)) 
                        for (SequenceFlow sequenceFlow : incomingFlows) 
                            FlowElement upNode = sequenceFlow.getSourceFlowElement();
                            if (upNode != null && (upNode instanceof ParallelGateway || upNode instanceof InclusiveGateway)) 
                                returnVo = new ReturnVo<>(ReturnCode.FAIL, "并行节点无法驳回,请选择其他节点!");
                                return returnVo;
                            
                        
                    
                    //2. 如果上一个节点是提交者的话要处理一下
                    if (FlowConstant.FLOW_SUBMITTER.equals(distActivity.getName())) 
                        //查找发起人
                        ExtendHisprocinst extendHisprocinst = this.extendHisprocinstService.findExtendHisprocinstByProcessInstanceId(taskEntity.getProcessInstanceId());
                        if (extendHisprocinst != null) 
                            runtimeService.setVariable(taskEntity.getProcessInstanceId(), FlowConstant.FLOW_SUBMITTER, extendHisprocinst.getCreator());
                        
                    
                    //3. 添加审批意见和修改流程状态
                    this.addCommentAndUpdateProcessStatus(backVo);
                    //4. 删除现有的所有任务
                    managementService.executeCommand(new DeleteTaskCmd(taskEntity.getProcessInstanceId()));
                    //5. 删除节点信息
                    this.deleteHisActivities(distActivity, taskEntity.getProcessInstanceId());
                    //6. 驳回到disk节点
                    Activity currActivity = processDefinitionUtils.findFlowElementById(taskEntity.getProcessDefinitionId(), taskEntity.getTaskDefinitionKey());
                    //6.1 如果当前节点是多实例节点 删除当前多实例 如果目标节点不是多实例我们就创建一个孩子实例
                    boolean flag = false;
                    if (currActivity.getBehavior() instanceof MultiInstanceActivityBehavior)
                        ExecutionEntity executionEntity = (ExecutionEntity)runtimeService.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult();
                        managementService.executeCommand(new DeleteMultiInstanceExecutionCmd(executionEntity.getParentId(),false));
                        flag = true;
                    
                    //6.2 处理并行网关的多实例
                    List<Execution> executions = runtimeService.createExecutionQuery().parentId(taskEntity.getProcessInstanceId()).list();
                    if (CollectionUtils.isNotEmpty(executions) && executions.size() >1)
                        executions.forEach(execution -> 
                            ExecutionEntity e = (ExecutionEntity)execution;
                            managementService.executeCommand(new DeleteChildExecutionCmd(e));
                        );
                        flag = true;
                    
                    if (flag) 
                        ExecutionEntity parentExecutionEntity = (ExecutionEntity)runtimeService.createExecutionQuery().executionId(taskEntity.getProcessInstanceId()).singleResult();
                        managementService.executeCommand(new AddChildExecutionCmd(parentExecutionEntity));
                    
                    managementService.executeCommand(new JumpActivityCmd(taskEntity.getProcessInstanceId(),distActivity.getId()));
                    //TODO 7. 处理加签的数据0
                
            else 
                returnVo = new ReturnVo<>(ReturnCode.FAIL, "当前任务不存在!");
            
         else 
            returnVo = new ReturnVo<>(ReturnCode.FAIL, "请设置相关参数!");
        
        return returnVo;
    

  

  • ProcessDefinitionUtils
@Component
public class ProcessDefinitionUtils 

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 获取end节点
     *
     * @param processDefId
     * @return FlowElement
     */
    public FlowElement findEndFlowElement(String processDefId) 
        Process process = repositoryService.getBpmnModel(processDefId).getMainProcess();
        Collection<FlowElement> list = process.getFlowElements();
        for (FlowElement f : list) 
            if (f instanceof EndEvent) 
                return f;
            
        
        return null;
    

    /**
     * 获取指定节点的节点信息
     *
     * @param processDefId
     * @param flowElementId
     * @return FlowElement
     */
    public Activity findFlowElementById(String processDefId, String flowElementId) 
        Process process = repositoryService.getBpmnModel(processDefId).getMainProcess();
        return (Activity) process.getFlowElement(flowElementId);
    


  

addCommentAndUpdateProcessStatus 这个方法是添加审批意见和更新流程状态,由于流程状态没有,我这里扩展了一张表,状态主要有审批中,驳回,暂存,转办,撤回,终止等等状态

/**
     * 添加审批意见和修改流程状态
     * @param baseProcessVo 基本流程任务参数
     */
    protected void addCommentAndUpdateProcessStatus(BaseProcessVo baseProcessVo) 
        //兼容处理
        if (StringUtils.isBlank(baseProcessVo.getProcessInstanceId()))
            Task task = taskService.createTaskQuery().taskId(baseProcessVo.getTaskId()).singleResult();
            if (task != null) 
                baseProcessVo.setProcessInstanceId(task.getProcessInstanceId());
            
        
        //1.添加审批意见
        FlowCommentVo flowCommentVo = new FlowCommentVo(baseProcessVo.getTaskId(), baseProcessVo.getUserCode(),
                baseProcessVo.getProcessInstanceId(), baseProcessVo.getMessage(), baseProcessVo.getCommentTypeEnum().toString());
        this.addFlowComment(flowCommentVo);
        //2.修改流程实例的状态
        ExtendHisprocinst extendHisprocinst = new ExtendHisprocinst(baseProcessVo.getProcessInstanceId(), baseProcessVo.getProcessStatusEnum().toString());
        extendHisprocinstService.updateStatusByProcessInstanceId(extendHisprocinst);
        //3.TODO 生成索引
    

    /**
     * 添加审批意见
     * @param flowCommentVo
     */
    private void addFlowComment(FlowCommentVo flowCommentVo) 
        FlowCommentCmd cmd = new FlowCommentCmd(flowCommentVo.getTaskId(), flowCommentVo.getUserId(),
                flowCommentVo.getProcessInstanceId(), flowCommentVo.getType(), flowCommentVo.getMessage());
        managementService.executeCommand(cmd);
    

 DeleteTaskCmd 删除任务命令

public class DeleteTaskCmd implements Command<Void> 

    private String processInstanceId;

    public DeleteTaskCmd(String processInstanceId) 
        this.processInstanceId = processInstanceId;
    

    @Override
    public Void execute(CommandContext commandContext) 
        TaskEntityManager taskEntityManager = CommandContextUtil.getTaskEntityManager(commandContext);
        ExecutionEntityManager executionEntityManager = org.flowable.engine.impl.util.CommandContextUtil.getExecutionEntityManager(commandContext);
        List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
        executionEntities.forEach(executionEntity -> taskEntityManager.deleteTasksByExecutionId(executionEntity.getId()));
        return null;
    

 AddChildExecutionCmd 添加一个流程实例下面的执行实例

public class AddChildExecutionCmd implements Command<Void> 

    private ExecutionEntity parentExecutionEntity;

    public AddChildExecutionCmd(ExecutionEntity parentExecutionEntity) 
        this.parentExecutionEntity = parentExecutionEntity;
    

    @Override
    public Void execute(CommandContext commandContext) 
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        executionEntityManager.createChildExecution(parentExecutionEntity);
        return null;
    

  DeleteChildExecutionCmd 删除执行实例

public class DeleteChildExecutionCmd implements Command<Void> 

    private ExecutionEntity child;

    public DeleteChildExecutionCmd(ExecutionEntity child) 
        this.child = child;
    

    @Override
    public Void execute(CommandContext commandContext) 
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        executionEntityManager.delete(child,true);
        return null;
    

  JumpActivityCmd 执行跳转

public class JumpActivityCmd implements Command<Void> 

    private String target;
    private String processInstanceId;

    public JumpActivityCmd(String processInstanceId, String target) 
        this.processInstanceId = processInstanceId;
        this.target = target;
    

    @Override
    public Void execute(CommandContext commandContext) 
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByParentExecutionId(processInstanceId);
        Process process = ProcessDefinitionUtil.getProcess(executionEntities.get(0).getProcessDefinitionId());
        FlowNode targetFlowElement = (FlowNode) process.getFlowElement(target);
        FlowableEngineAgenda agenda = CommandContextUtil.getAgenda();
        executionEntities.forEach(execution -> 
            execution.setCurrentFlowElement(targetFlowElement);
            agenda.planContinueProcessInCompensation(execution);
        );
        return null;
    

  

activiti5.22.0之自由驳回任务实现(亲测)

...,我们完成一个任务SKIP的实现,说好要给各位看官带来驳回实现的现在,就奉上具体实现和讲解。(其实我感觉我的注释写的已经非常清楚了,哈哈)?依旧是,先说我们的需求和思路。PS:?从6.0.0降到5.22.0版本的原因因为项目中... 查看详情

工作流引擎驳回设计

1.1关于驳回驳回,在有的应用中叫“回退”。驳回是中国特色的一种方式,驳回在流程图上也没有迁移线的表达经常也是隐性的,比如申请经费可能由于资料不足被驳回来补充资料,像这样的例子有非常多,也很常见。驳... 查看详情

ctiviti7工作流引擎:进阶篇驳回(拒绝)(代码片段)

驳回或者拒绝就是某个审批人不同意你的申请,此时流程就直接结束了。我们可以增加分支条件或者排它网关来完成驳回功能。此方法适用于节点较少的情况。1.bpmn文件同意:$result==1驳回:$result==1有一个正常结束事件,有一个... 查看详情

商标驳回和不予受理区别是啥?

  1.拒绝的原因不同  商标驳回是因为商标不符合在先申请或者在先注册原则而被驳回注册的;但因申请人提交的商标申请文件或者违反禁止注册规定,才会不予受理。  2.审查的阶段和对象不同  商标不予受理仍处于... 查看详情

activiti工作流几种驳回方式的实现与比较

最近公司做的一个项目要实现工作流程的收回,驳回等操作,而采用的工作流引擎并不支持驳回功能,这个项目恰好就我和一个实习生一块做,所以这个问题就落到我的头上来解决了。。。客户提出的要求是驳回时要记录日志,... 查看详情

activiti7工作流引擎:进阶篇驳回(拒绝)(代码片段)

也不知道张世豪厉害,还是李华强厉害。驳回或者拒绝就是某个审批人不同意你的申请,此时流程就直接结束了。我们可以增加分支条件或者排它网关来完成驳回功能。此方法适用于节点较少的情况。1.bpmn文件同意:... 查看详情

我如何使用驳回传递数据?

】我如何使用驳回传递数据?【英文标题】:howcanipassdatausingdismiss?【发布时间】:2021-02-2516:22:58【问题描述】:我有两个viewControllersAB我使用performegue从A到B并使用prepare()将A传递给B。segue类型是Show。ifsegue.identifier=="toWrite"letvc=segu... 查看详情

bpm实例分享:领导不通过某流程时,如何即可结束流程并告知发起人驳回通知

...审批单时,如何实现即刻结束流程并告知发起人该审批被驳回的通知? 鉴于近期有H3BPM 10.0的用户向小编咨询这个问题,且一些业务场景中一般都会涉及此流程,小编特此整理此文并与大家共同分享! 系统版本:H3BPM&... 查看详情

bpm实例分享:领导不通过某流程时,如何即可结束流程并告知发起人驳回通知

...审批单时,如何实现即刻结束流程并告知发起人该审批被驳回的通知? 鉴于近期有H3BPM 10.0的用户向小编咨询这个问题,且一些业务场景中一般都会涉及此流程,小编特此整理此文并与大家共同分享! 系统版本:H3BPM&... 查看详情

单元测试视图在 XCTestCase 中被驳回

】单元测试视图在XCTestCase中被驳回【英文标题】:UnitTestingaviewwasdismissedinXCTestCase【发布时间】:2019-10-0714:10:19【问题描述】:我有一个使用VIPER模式的应用。我的LoginViewController出现了,一些动作发生并且视图被关闭。我想断言... 查看详情

华为申请注册鲁班商标被驳回

...为技术有限公司申请注册的“鲁班”商标流程状态更新为驳回通知发文,该商标申请日期为2021年5月,国际分类为科学仪器。据悉,2021年1月份,华为曾与《王者荣耀》联名推出nova8Pro“鲁班8号”定制款手机。 查看详情

退回和驳回的区别。退回和移送的区别。

退回和驳回的区别:前者不符合接受的要件,可以在补足后再次提交;后者是受理后,结果审查认定提交的事项不符合法律规定而予以“返回”的。退回和移送的区别:前者以上说明过了;后者是不属于被提交单位受理的范畴,... 查看详情

华为应用上架被驳回,原因是错误:28:将hmssdkassets目录拷贝到应用工程根目录,怎么解决?

华为上架应用一直被驳回,驳回原因每次都是错误:28:将HMSSDKassets目录拷贝到应用工程根目录,问了客服就只会说此审核意见是系统自动检测的,请开发者自行整改,谢谢。太难了,这个怎么解决应该是把HMSSDK放在你的主工程的as... 查看详情

第十五篇camunda系列-任务回退驳回回退(代码片段)

Camunda任务回退/驳回专题  任务回退驳回撤销相关的操作在实际的开发中还是会经常遇到的,我们来看看Camunda中针对这些情况是如何处理的。1.串行的回退  我们先从最简单的串行流程来分析,案例如下  上面的流程就是... 查看详情

第十五篇camunda系列-任务回退驳回回退(代码片段)

Camunda任务回退/驳回专题  任务回退驳回撤销相关的操作在实际的开发中还是会经常遇到的,我们来看看Camunda中针对这些情况是如何处理的。1.串行的回退  我们先从最简单的串行流程来分析,案例如下  上面的流程就是... 查看详情

多线程如何并发访问sqlite数据库

...外部进行读写锁控制,否则SQLite会返回SQLITE_BUSY错误,以驳回相关请求。返回SQLITE_BUSY主要有以下几种情况:1。当有写操作时,其他读操作会被驳回2。当有写操作时,其他写操作会被驳回3。当开启事务时,在提交事务之前,其... 查看详情

到底是怎么回事,小米提议禁止安卓手机提取apk文件,遭谷歌驳回

...题:小米提议禁止安卓手机提取APK文件,遭谷歌驳回。事情是这样的:MishaalRahman在Twitter上分享的信息显示,小米开发者已向Android开源项目AOSP提交了一份代码,拟阻止Android设备所有者通过adbshell提取data下的APK... 查看详情

twitter被裁员工的集体诉讼遭法官驳回!

这一年,裁员频繁成为头条新闻,就业市场到底怎么了?作者|何苗   出品|CSDN(ID:CSDNnews)去年 11月初,Twitter解雇了大约3,700名员工,这是马斯克接手后削减成本的一种方法。也因此,Twitter... 查看详情