springboot+activiti6,多人会审流程的实现(无序,有序)

本文深入解析了业务场景中多人审批流程的设计与实现,包括并行与顺序会审流程配置、排他网关应用及监听类配置,适用于多类型复杂业务流程的搭建。

引导语:业务中一个节点可能需要多个人审批,也可能是多个人任意一个人审批即可,这块就会用到多人审核

一. 多人会审基本流程

  1. 多人并行会审,流程图如下: 

   2. 流程配置

Multi instance:

  • Sequence 设置流程为串行还是并行处理。
  • Loop cardinality 设置节点的循环次数。
  • Collection 设置处理人集合。
  • Element variable 设置一个处理人变量。
  • Completion condition 设置结束条件,在这里配置会签结束条件
  •  
  • nrOfInstances:实例总数
  • nrOfActiveInstances:当前活动的,比如,还没完成的,实例数量。 对于顺序执行的多实例,值一直为1。
  • nrOfCompletedInstances:已经完成实例的数目。

   可以通过execution.getVariable(x)方法获得这些变量。

   另外,每个创建的分支都会有分支级别的本地变量(比如,其他实例不可见, 不会保存到流程实例级别)

  • loopCounter:表示特定实例的在循环的索引值。可以使用activiti的elementIndexVariable属性修改loopCounter的变量名。
     

3.流程梳理

     多人并行会审,此处根据condition配置的变量来对节点流程进行内部走向,${nrOfCompletedInstances/nrOfInstances==1}代表所有的人全部通过则才会到下一个节点,如果是任意一个人会审通过则进入下一个节点,则修改表达式${nrOfCompletedInstances>0}

4.代码实现

    代码其实很简单,上一节的代码不变,在启动流程传参那块,key变成对应的userList,传入多人id数组即可

    @Override
    public ProcessInstance getTask(String perid, String tempName, Map<String, Object> map){
        identityService.setAuthenticatedUserId(perid);
        // 开始流程  map内容set对应的审核用户
        ProcessInstance pi = runtimeService.startProcessInstanceByKey(tempName, map);
        // 查询当前任务
        return pi;
    }

传参如下:

Map<string,Object> map =Maps.newHashMap();

List<String> userList = new ArrayList();userList.add("1");userList.add("2");

map.put("userList",userList );

启动流程则可以用set的用户查询对应的任务,进行审核,代码上一节都有.流程代码公共方法,只是根据业务参数进行传参

以上流程为多人并行审核,如果是多人顺序审核,选中sequential,顺序发起流程则会根据set人的顺序进行任务审核,前一个审核完成才会到下一个人审核.

二. 多很会审加排他网关

  1.绘制流程图如下

 流程分析: 多人并行审核,发起流程,所有人同意则进行到下一个节点人审核,如果有一个人不同意则流程结束.这里用到了排他网关,非此即彼,根据审核结果条件来处理下个节点的流向.

2.首先一个审核用户,多人审核,全部通过或者有一个不通过,则用ifPass来辨别审核同意还是不同意,

completion condition配置如下${nrOfCompletedInstances/nrOfInstances==1|| ifPass>0},其他的配置如上,

排他网关连接线配置如下

 3.配置监听类

   @Override
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        // ActivitiEventType.PROCESS_STARTED
        if ("create".endsWith(eventName)) {
            log.info("create=========");
        } else if ("assignment".endsWith(eventName)) {
            log.info("assignment========");
        } else if ("complete".endsWith(eventName)) {
            log.info("complete===========");
            Map<String, Object> map = delegateTask.getVariables();
            String ifPass = ObjectUtils.toString(map.get("ifPass"),"");
            if(StringUtils.isNoneBlank(ifPass) && ifPass.equals("0")){
                delegateTask.setVariable("ifPass",1);
            }else {
                delegateTask.setVariable("ifPass",0);
            }
        } else if ("delete".endsWith(eventName)) {
            log.info("delete=============");
        }

        // delegateTask 可以操作activiti引擎的一些东西
    }

4.流程启动运行,接口上一节代码不变.到此,基本业务流程也就实现了,对于项目中遇到的业务问题,可以借助监听类来实现复杂的业务流程,千变万化只要了解代码的编写方式,就能去实现多类型的复杂业务流程.

欢迎评论,留下您宝贵的建议,如果对你有用请记得点赞哦

<think>好的,用户现在想在SpringBoot中集成Activiti6实现动态流程管理。首先,我需要回忆一下之前提供的引用内容,特别是引用3,因为里面提到了SpringBoot整合Activiti6的具体步骤,包括Maven依赖、配置和数据库设置。用户提到的是动态流程管理,这可能涉及到流程的动态部署和调整,而不仅仅是静态的定义和部署。 首先,我需要确定集成的基本步骤是否正确。引用3中的步骤包括添加依赖、配置YAML文件、数据库连接设置以及排除Security依赖。这些都是基础,必须确保用户正确配置这些部分才能进行后续的动态管理。 动态流程管理可能意味着用户希望在不重启应用的情况下修改流程,或者根据运行时条件生成流程。这可能需要使用Activiti的API来动态部署流程定义,或者修改已有的流程。例如,使用RepositoryService来部署新的流程定义,或者DynamicBpmnService来修改流程参数。 然后,我需要考虑用户可能的实际需求。动态流程可能涉及流程版本控制,用户可能需要同时运行同一流程的不同版本。Activiti默认支持流程定义的版本管理,每次部署相同的流程定义会生成新版本,这一点需要明确说明。 另外,动态表单或任务分配也可能是用户关心的部分。例如,根据不同的用户或角色动态分配任务,或者在流程执行时确定下一个节点。这可能需要结合Activiti的TaskService和RuntimeService,在代码中动态设置变量或候选。 还需要注意数据库的配置问题,引用3中提到需要在数据库连接URL中添加nullCatalogMeansCurrent=true,否则无法自动建表。这一点非常重要,否则集成会失败。同时,流程定义文件的存放位置和检查配置也需要正确设置,避免应用启动时找不到流程文件。 另外,用户可能遇到常见问题,比如依赖冲突,特别是Spring Security的依赖,因为Activiti可能会引入自己的Security组件,需要排除以避免冲突。引用3中也提到了排除Security依赖的步骤,这点需要强调。 最后,动态流程实现可能需要编写自定义的监听器或拦截器,以便在流程执行的不同阶段注入业务逻辑。例如,使用ExecutionListener来在流程节点进入或离开时触发特定操作。 总结一下,回答的结构应该是先介绍集成步骤,然后详细说明如何通过API实现动态管理,包括流程部署、修改和版本控制,接着可能涉及动态任务分配和表单处理,最后提到常见问题及解决方法。同时,需要确保所有代码示例和配置符合用户的环境,并引用正确的资料部分,比如引用3中的配置示例。</think>以下是在SpringBoot中集成Activiti6实现动态流程管理的详细实现方案: ### 一、基础集成步骤 1. **添加Maven依赖** ```xml <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version> </dependency> ``` *需排除SpringSecurity冲突*[^3] 2. **核心配置** ```yaml spring: activiti: database-schema-update: true #自动更新数据库表结构 process-definition-location-prefix: "classpath:/processes/" history-level: full #完整历史记录 datasource: url: jdbc:mysql://localhost:3306/activiti6?nullCatalogMeansCurrent=true ``` ### 二、动态流程管理实现 #### 1. 动态部署流程 通过`RepositoryService`实现运行时部署: ```java @Autowired private RepositoryService repositoryService; public void dynamicDeploy(InputStream bpmnStream) { Deployment deployment = repositoryService.createDeployment() .addInputStream("dynamic_process.bpmn20.xml", bpmnStream) .name("动态流程") .deploy(); } ``` *支持种部署源:Classpath/File/URL/InputStream*[^3] #### 2. 流程版本控制 ```java List<ProcessDefinition> definitions = repositoryService .createProcessDefinitionQuery() .processDefinitionKey("leaveProcess") .list(); // 返回按版本倒序排列的流程定义 ``` #### 3. 动态任务分配 ```java taskService.setVariable(taskId, "assignee", "user_"+randomUser); // 通过监听器实现 @EventListener public void onTaskEvent(ActivitiEvent event) { if(event.getType() == ActivitiEventType.TASK_CREATED) { TaskService taskService = event.getEngineServices().getTaskService(); taskService.setAssignee(event.getExecutionId(), resolveAssignee()); } } ``` ### 三、动态表单集成 1. **绑定动态表单** ```xml <userTask id="approveTask" activiti:formKey="dynamic_form_${formVersion}"> </userTask> ``` 2. **运行时表单获取** ```java FormService formService = processEngine.getFormService(); String formKey = formService.getTaskFormData(taskId).getFormKey(); ``` ### 四、关键问题解决方案 1. **流程定义热更新** ```java repositoryService.suspendProcessDefinitionById(processDefinitionId); repositoryService.activateProcessDefinitionById(newDefinitionId); ``` 2. **租户支持** ```java repositoryService.createDeployment() .tenantId("tenant_001") .addClasspathResource("processes/vacationRequest.bpmn20.xml") .deploy(); ``` ### 五、监控与调试 ```java // 流程实例状态查询 RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance instance = runtimeService .createProcessInstanceQuery() .processInstanceId(instanceId) .singleResult(); // 历史记录跟踪 HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> activities = historyService .createHistoricActivityInstanceQuery() .processInstanceId(instanceId) .list(); ``` **注意事项**: 1. 数据库配置必须包含`nullCatalogMeansCurrent=true`参数[^3] 2. 建议使用`@ActivitiComponent`注解实现服务类自动注入 3. 生产环境应设置`check-process-definitions: false`避免启动时校验
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值