flowable動(dòng)態(tài)創(chuàng)建多級(jí)流程模板實(shí)現(xiàn)demo
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)建開(kāi)始節(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()));
//開(kāi)始事件
FlowElement startEvent = FlowableBpmnHandler.createStartFlowElement("start", "開(kāi)始");
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);
//開(kāi)始事件到第一個(gè)節(jié)點(diǎn)
if (i == 0) {
// 開(kāi)始節(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() + "_開(kāi)始審批");
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);;
}開(kāi)啟流程接口
@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) {
//記錄開(kāi)啟流程的用戶
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-10
Java語(yǔ)言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹(shù)的前中后序遍歷總結(jié)
今天小編就為大家分享一篇關(guān)于Java語(yǔ)言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹(shù)的前中后序遍歷總結(jié),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧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的安全性,今天通過(guò)本文給大家分享Spring Cloud中如何保證各個(gè)微服務(wù)之間調(diào)用的安全性,需要的朋友參考下吧2021-08-08
Java利用VLC開(kāi)發(fā)簡(jiǎn)易視屏播放器功能
這篇文章主要介紹了Java利用VLC開(kāi)發(fā)簡(jiǎn)易視屏播放器,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
RocketMQ整合SpringBoot實(shí)現(xiàn)生產(chǎn)級(jí)二次封裝
本文主要介紹了RocketMQ整合SpringBoot實(shí)現(xiàn)生產(chǎn)級(jí)二次封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06

