flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板實(shí)現(xiàn)demo
更新時(shí)間:2023年05月23日 11:15:21 作者:多喝灬丶燙水
這篇文章主要為大家介紹了flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板
引入Maven依賴
<dependency> <groupId>org.flowable</groupId> <artifactId>flowable-spring-boot-starter</artifactId> <version>6.6.0</version> </dependency>
動(dòng)態(tài)創(chuàng)建流程節(jié)點(diǎn)工具類
/** * 動(dòng)態(tài)創(chuàng)建流程節(jié)點(diǎn) */ @Slf4j @Component @RequiredArgsConstructor public class FlowableBpmnHandler { /** * 創(chuàng)建開始節(jié)點(diǎn)信息 * * @return */ public static FlowElement createStartFlowElement(String id, String name) { StartEvent startEvent = new StartEvent(); startEvent.setId(id); startEvent.setName(name); return startEvent; } /** * 創(chuàng)建結(jié)束節(jié)點(diǎn)信息 * * @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; } /** * 循環(huán)創(chuàng)建普通任務(wù)節(jié)點(diǎn)信息 * * @param processEntity 流程實(shí)體 * @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; } /** * 創(chuàng)建排它網(wǎng)關(guān)節(jié)點(diǎn) * * @return */ public static ExclusiveGateway createExclusiveGateway(Integer i) { ExclusiveGateway gateway = new ExclusiveGateway(); gateway.setName("getaway_name_" + i); gateway.setId("getaway_id_" + i); return gateway; } }
動(dòng)態(tài)創(chuàng)建流程模板工具類
/** * 動(dòng)態(tài)創(chuàng)建流程模板 * * @author ll * @date 2023/04/19 14:28 **/ @Slf4j @Component public class DynamicProcessDefinition { @Resource private RepositoryService repositoryService; public String createProcessDefinition(ProcessEntity processEntity) { //數(shù)據(jù)校驗(yàn):傳入的數(shù)據(jù)節(jié)點(diǎn)字段:流程配置id、節(jié)點(diǎn)id、節(jié)點(diǎn)順序、節(jié)點(diǎn)描述 List<ProcessNode> nodeList = processEntity.getProcessNodeList(); if (CollUtil.isEmpty(nodeList)) { throw new RuntimeException("流程節(jié)點(diǎn)不能少于一個(gè),請(qǐng)配置發(fā)起人節(jié)點(diǎn)和至少一個(gè)審批節(jié)點(diǎn)"); } BpmnModel bpmnModel = new BpmnModel(); Process process = new Process(); bpmnModel.addProcess(process); // 流程標(biāo)識(shí) process.setId(TypeEnum.getProcessKey(processEntity.getType())); process.setName(TypeEnum.getProcessKey(processEntity.getType())); //開始事件 FlowElement startEvent = FlowableBpmnHandler.createStartFlowElement("start", "開始"); process.addFlowElement(startEvent); //結(jié)束事件--任務(wù)正常完成 FlowElement endEvent = FlowableBpmnHandler.createEndFlowElement("end", "結(jié)束"); process.addFlowElement(endEvent); //創(chuàng)建用戶節(jié)點(diǎn)任務(wù) List<UserTask> userTaskList = FlowableBpmnHandler.createCommonUserTask(processEntity); //構(gòu)建流程模板 buildProcessTemplate(process, startEvent, endEvent, userTaskList); //該流程的流程xml字符串 //BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter(); //byte[] convertToXML = bpmnXMLConverter.convertToXML(bpmnModel); //String bytes = new String(convertToXML); //log.info("該流程的流程xml為:{}", bytes); // 創(chuàng)建一個(gè)新的部署 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(); } /** * 構(gòu)建流程模板 * * @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++) { //用戶任務(wù) UserTask userTask = userTaskList.get(i); process.addFlowElement(userTask); //創(chuàng)建排它網(wǎng)關(guān)節(jié)點(diǎn) ExclusiveGateway exclusiveGateway = FlowableBpmnHandler.createExclusiveGateway(i); process.addFlowElement(exclusiveGateway); //開始事件到第一個(gè)節(jié)點(diǎn) if (i == 0) { // 開始節(jié)點(diǎn)到第一級(jí)節(jié)點(diǎn) SequenceFlow startSequenceFlow = new SequenceFlow(startEvent.getId(), userTask.getId()); process.addFlowElement(startSequenceFlow); } //用戶任務(wù)到網(wǎng)關(guān)節(jié)點(diǎn) SequenceFlow sequenceFlow = new SequenceFlow(userTask.getId(), exclusiveGateway.getId()); sequenceFlow.setName(userTask.getName() + "_開始審批"); process.addFlowElement(sequenceFlow); //同意:取下一步用戶任務(wù)的節(jié)點(diǎn)id,可能為結(jié)束節(jié)點(diǎn)或者用戶任務(wù)節(jié)點(diǎn) 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); //不同意:回退到上一步,取上一步的節(jié)點(diǎn)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) { //業(yè)務(wù)自己定義key String businessKey = auditData.getBusinessKey(); //流程定義key String processKey = auditData.getType(); // 判斷是否啟動(dòng)流程 boolean isStartProcess = null != runtimeService.createProcessInstanceQuery() .processDefinitionKey(processKey) .processInstanceBusinessKey(businessKey) .singleResult(); if (!isStartProcess) { //記錄開啟流程的用戶 HashMap<String, Object> variable = Maps.newHashMap(); //啟動(dòng)流程 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, businessKey, variable); log.info("啟動(dòng)流程實(shí)例成功:processInstanceId={}", processInstance.getId()); } return !isStartProcess ? "流程啟動(dòng)成功" : "流程啟動(dòng)失敗"; }
以上就是flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板demo的詳細(xì)內(nèi)容,更多關(guān)于flowable動(dòng)態(tài)多級(jí)流程模板的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot返回多種格式的數(shù)據(jù)的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot返回多種格式的數(shù)據(jù)的實(shí)現(xiàn)示例,主要包括了FastJson,xml,pdf,excel,資源流,具有一定的參考價(jià)值,感興趣的可以了解一下2021-10-10Java語言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹的前中后序遍歷總結(jié)
今天小編就為大家分享一篇關(guān)于Java語言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹的前中后序遍歷總結(jié),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01教你Spring Cloud保證各個(gè)微服務(wù)之間調(diào)用安全性
在微服務(wù)的架構(gòu)下,系統(tǒng)會(huì)根據(jù)業(yè)務(wù)拆分為多個(gè)服務(wù),各自負(fù)責(zé)單一的職責(zé),在這樣的架構(gòu)下,我們需要確保各api的安全性,今天通過本文給大家分享Spring Cloud中如何保證各個(gè)微服務(wù)之間調(diào)用的安全性,需要的朋友參考下吧2021-08-08RocketMQ整合SpringBoot實(shí)現(xiàn)生產(chǎn)級(jí)二次封裝
本文主要介紹了RocketMQ整合SpringBoot實(shí)現(xiàn)生產(chǎn)級(jí)二次封裝,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06