flowable 动态创建多级流程
-
引入 Maven 依赖
<dependency> <groupId>org.flowable</groupId> <artifactId>flowable-spring-boot-starter</artifactId> <version>6.6.0</version> </dependency>
-
动态创建流程节点工具类
/** * 动态创建流程节点 */ @Slf4j @Component @RequiredArgsConstructor public class FlowableBpmnHandler { /** * 创立开始节点信息 * * @return */ public static FlowElement createStartFlowElement(String id, String name) {StartEvent startEvent = new StartEvent(); startEvent.setId(id); startEvent.setName(name); return startEvent; } /** * 创立完结节点信息 * * @param id * @param name * @return */ public static FlowElement createEndFlowElement(String id, String name) {EndEvent endEvent = new EndEvent(); endEvent.setId(id); endEvent.setName(name); return endEvent; } /** * 循环创立一般工作节点信息 * * @param processEntity 流程实体 * @return */ public static List<UserTask> createCommonUserTask(ProcessEntity processEntity) {List<ProcessNode> processNodes = processEntity.getProcessNodeList(); List<UserTask> userTaskList = Lists.newLinkedList(); for (int i = 0; i < processNodes.size(); i++) {ProcessNode node = processNodes.get(i); node.setNodeId(UUIDHelper.randomUUID()); node.setNodeLevel(i + 1); UserTask userTask = new UserTask(); userTask.setId(TypeEnum.getProcessKey(processEntity.getType()) + "_task_" + node.getNodeId()); userTask.setCategory(String.valueOf(i + 1)); userTask.setDocumentation(i == processNodes.size() - 1 ? "true" : "false"); userTask.setName(node.getNodeName()); userTaskList.add(userTask); } return userTaskList; } /** * 创立排它网关节点 * * @return */ public static ExclusiveGateway createExclusiveGateway(Integer i) {ExclusiveGateway gateway = new ExclusiveGateway(); gateway.setName("getaway_name_" + i); gateway.setId("getaway_id_" + i); return gateway; } }
-
动态创建流程模板工具类
/** * 动态创建流程模板 * * @author ll * @date 2023/04/19 14:28 **/ @Slf4j @Component public class DynamicProcessDefinition { @Resource private RepositoryService repositoryService; public String createProcessDefinition(ProcessEntity processEntity) { // 数据校验:传入的数据节点字段:流程配置 id、节点 id、节点程序、节点形容 List<ProcessNode> nodeList = processEntity.getProcessNodeList(); if (CollUtil.isEmpty(nodeList)) {throw new RuntimeException("流程节点不能少于一个,请配置发起人节点和至多一个审批节点"); } BpmnModel bpmnModel = new BpmnModel(); Process process = new Process(); bpmnModel.addProcess(process); // 流程标识 process.setId(TypeEnum.getProcessKey(processEntity.getType())); process.setName(TypeEnum.getProcessKey(processEntity.getType())); // 开始事件 FlowElement startEvent = FlowableBpmnHandler.createStartFlowElement("start", "开始"); process.addFlowElement(startEvent); // 完结事件 -- 工作失常实现 FlowElement endEvent = FlowableBpmnHandler.createEndFlowElement("end", "完结"); process.addFlowElement(endEvent); // 创立用户节点工作 List<UserTask> userTaskList = FlowableBpmnHandler.createCommonUserTask(processEntity); // 构建流程模板 buildProcessTemplate(process, startEvent, endEvent, userTaskList); // 该流程的流程 xml 字符串 //BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter(); //byte[] convertToXML = bpmnXMLConverter.convertToXML(bpmnModel); //String bytes = new String(convertToXML); //log.info("该流程的流程 xml 为:{}", bytes); // 创立一个新的部署 Deployment deploy = repositoryService.createDeployment().key(TypeEnum.getProcessKey(processEntity.getType())) .name(TypeEnum.getProcessKey(processEntity.getType())) .addBpmnModel(TypeEnum.getProcessKey(processEntity.getType()) + ".bpmn", bpmnModel) .deploy(); log.info("部署 id:{}", deploy.getId()); return deploy.getId();} /** * 构建流程模板 * * @param process * @param startEvent * @param endEvent * @param userTaskList * @return void * @author ll * @date 2023/04/24 08:53 */ private void buildProcessTemplate(Process process, FlowElement startEvent, FlowElement endEvent, List<UserTask> userTaskList) {for (int i = 0; i < userTaskList.size(); i++) { // 用户工作 UserTask userTask = userTaskList.get(i); process.addFlowElement(userTask); // 创立排它网关节点 ExclusiveGateway exclusiveGateway = FlowableBpmnHandler.createExclusiveGateway(i); process.addFlowElement(exclusiveGateway); // 开始事件到第一个节点 if (i == 0) { // 开始节点到第一级节点 SequenceFlow startSequenceFlow = new SequenceFlow(startEvent.getId(), userTask.getId()); process.addFlowElement(startSequenceFlow); } // 用户工作到网关节点 SequenceFlow sequenceFlow = new SequenceFlow(userTask.getId(), exclusiveGateway.getId()); sequenceFlow.setName(userTask.getName() + "_开始审批"); process.addFlowElement(sequenceFlow); // 批准:取下一步用户工作的节点 id,可能为完结节点或者用户工作节点 String nextUserTaskId = endEvent.getId(); if (userTaskList.size() - i > 1) {nextUserTaskId = userTaskList.get(i + 1).getId();} SequenceFlow sequenceFlowAgree = new SequenceFlow(exclusiveGateway.getId(), nextUserTaskId); sequenceFlowAgree.setConditionExpression("${auditResult}"); sequenceFlowAgree.setName("批准"); process.addFlowElement(sequenceFlowAgree); // 不批准:回退到上一步, 取上一步的节点 id String preUserTaskId = userTaskList.get(0).getId(); if (i != 0) {preUserTaskId = userTaskList.get(i - 1).getId();} SequenceFlow sequenceFlowRefuse = new SequenceFlow(exclusiveGateway.getId(), preUserTaskId); sequenceFlowRefuse.setConditionExpression("${!auditResult}"); sequenceFlowRefuse.setName("回绝"); process.addFlowElement(sequenceFlowRefuse); } } }
-
保留流程配置模板的接口
@Resource private DynamicProcessDefinition dynamicProcessDefinition; @RequestMapping("/save") public Result<String> save(@RequestBody ProcessEntity processEntity) {return dynamicProcessDefinition.createProcessDefinition(processEntity);; }
-
开启流程接口
@RequestMapping("/start") public String start(@RequestBody AuditData auditData) { // 业务本人定义 key String businessKey = auditData.getBusinessKey(); // 流程定义 key String processKey = auditData.getType(); // 判断是否启动流程 boolean isStartProcess = null != runtimeService.createProcessInstanceQuery() .processDefinitionKey(processKey) .processInstanceBusinessKey(businessKey) .singleResult(); if (!isStartProcess) { // 记录开启流程的用户 HashMap<String, Object> variable = Maps.newHashMap(); // 启动流程 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, businessKey, variable); log.info("启动流程实例胜利:processInstanceId={}", processInstance.getId()); } return !isStartProcess ? "流程启动胜利" : "流程启动失败"; }