activiti7---自定義流程圖(springboot專案)
之前的文章中我們繪製流程圖時,都是需要依賴IDEA的activiti7外掛,不靈活。
本篇文章的目的是通過特定的資料結構,能實現前端頁面自定義配置流程圖。
1.yml檔案
spring:
datasource:
url: jdbc:mysql://ip:3306/activiti7?useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&characterEncoding=utf8&serverTimezone=GMT%2B8
username : root
password : root
driver-class-name: com.mysql.jdbc.Driver
activiti:
#Activiti記錄歷史任務資料級別,full是最全的,方便日後查詢使用
history-level: full
#建立資料庫歷史資料表
db-history-used: true
2.pom檔案(主要依賴)
<!-- activiti-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.0.0.SR1</version>
</dependency>
<!--畫圖 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-image-generator</artifactId>
<version>5.22.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>6.0.0.RC1</version>
</dependency>
3.安全配置類
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
@Order(1)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
/**
* aciviti7預設整合springSecurity,這裡全部放行
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().anyRequest().permitAll();
}
}
4.流程圖基本資訊類
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WorkFlow {
private Integer id;
private String name;
private String content;
}
5.流程圖步驟類
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class Step {
private Integer id;
private Integer workFlowId;
private String name;
private Integer type;
private Integer orderId;
//接下要執行的步驟,用於連線
private List<Integer> chlidOrderIds;
private String conditionExpression;
private String assignee;
//0為人工任務,1為服務於任務
//private Integer taskType;
}
6.流程的定義與部署
其它的查詢任務,執行任務與之前的邏輯一致。
import com.example.springactiviti.entity.Step;
import com.example.springactiviti.entity.WorkFlow;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class ProcessController3 {
@Autowired
private RepositoryService repositoryService; //流程定義和流程部署相關功能
@Autowired
private ProcessEngine processEngine; //流程引擎
/**
* 動態流程例項並輸出png和xml
*
* @throws IOException
*/
@GetMapping("/createDeployment3")
public String createDeployment3() throws IOException {
//模擬前端頁面資料
WorkFlow workFlow = new WorkFlow(1, "test", "流程測試");
List<Step> stepList = new ArrayList<>();
List<Integer> childList1 = new ArrayList<>();
childList1.add(2);
Step s1 = new Step(1, workFlow.getId(), "start", 1, 1, childList1, null, null);
List<Integer> childList2 = new ArrayList<>();
childList2.add(3);
childList2.add(4);
Step s2 = new Step(2, workFlow.getId(), "parallelGateway-fork", 2, 2, childList2, null, "a");
List<Integer> childList3 = new ArrayList<>();
childList3.add(6);
Step s3 = new Step(3, workFlow.getId(), "task1", 0, 3, childList3, null, "a");
List<Integer> childList4 = new ArrayList<>();
childList4.add(5);
Step s4 = new Step(4, workFlow.getId(), "task2", 0, 4, childList4, null, "a");
List<Integer> childList5 = new ArrayList<>();
childList5.add(6);
Step s5 = new Step(5, workFlow.getId(), "task22", 0, 5, childList5, null, "a");
List<Integer> childList6 = new ArrayList<>();
childList6.add(7);
Step s6 = new Step(6, workFlow.getId(), "parallelGateway-join", 3, 6, childList6, null, "a");
List<Integer> childList7 = new ArrayList<>();
childList7.add(8);
childList7.add(9);
Step s7 = new Step(7, workFlow.getId(), "exclusiveGate", 4, 7, childList7, null, "a");
List<Integer> childList8 = new ArrayList<>();
childList8.add(10);
Step s8 = new Step(8, workFlow.getId(), "task3", 0, 8, childList8, "${flag=='true'}", "a");
List<Integer> childList9 = new ArrayList<>();
childList9.add(10);
Step s9 = new Step(9, workFlow.getId(), "task4", 0, 9, childList9, "${flag=='false'}", "a");
List<Integer> childList10 = new ArrayList<>();
childList10.add(11);
Step s10 = new Step(10, workFlow.getId(), "receiveTask", 6, 10, childList10, null, "a");
Step s11 = new Step(11, workFlow.getId(), "end", 5, 11, new ArrayList<>(), null, "a");
stepList.add(s1);
stepList.add(s2);
stepList.add(s3);
stepList.add(s4);
stepList.add(s5);
stepList.add(s6);
stepList.add(s7);
stepList.add(s8);
stepList.add(s9);
stepList.add(s10);
stepList.add(s11);
//建立ProcessEngine物件
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//得到RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 1. 建立模型
BpmnModel model = new BpmnModel();
Process process = new Process();
model.addProcess(process);
process.setId(workFlow.getName());
process.setName(workFlow.getName());
stepList.forEach(step -> {
if (step.getType() == 1) {
process.addFlowElement(createStartEvent());
} else if (step.getType() == 5) {
process.addFlowElement(createEndEvent());
} else if (step.getType() == 2 || step.getType() == 3) {
process.addFlowElement(createParallelGateway(step.getName(), step.getName()));
} else if (step.getType() == 4) {
process.addFlowElement(createExclusiveGateway(step.getName(), step.getName()));
} else if (step.getType() == 6) {
process.addFlowElement(createReceiveTask(step.getName(), step.getName()));
} else {
process.addFlowElement(createUserTask(step.getName(), step.getName(), step.getAssignee()));
}
});
//連線
stepList.forEach(step -> {
List<Integer> childList = step.getChlidOrderIds();
childList.forEach(child -> {
stepList.forEach(step1 -> {
if (step1.getOrderId() == child) {
if (step.getType() == 4) {
process.addFlowElement(createSequenceFlow(step.getName(), step1.getName(), step1.getConditionExpression()));
} else {
process.addFlowElement(createSequenceFlow(step.getName(), step1.getName(), null));
}
}
});
});
});
//定義並設定流程變數
Map<String, Object> variables = new HashMap<>();
variables.put("flag", 1 == 2);
//deploy
Deployment deployment = repositoryService.createDeployment().addBpmnModel("process/dynamic-model.bpmn", model).name("Dynamic process deployment").deploy();
System.out.println("deploymentId:"+deployment.getId());
//start
ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(workFlow.getName(), variables);
System.out.println("processInstanceId:" + processInstance.getId());
System.out.println("getProcessDefinitionId:"+processInstance.getProcessDefinitionId());
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
//save as png
new BpmnAutoLayout(bpmnModel).execute();
List<String> highLightedActivities = processEngine.getRuntimeService().getActiveActivityIds(processInstance.getId());// 高亮節點
List<String> highLightedFlows = new ArrayList<>(); // 高亮連線線
ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows, "宋體", "宋體", "宋體", null, 1.0);
FileUtils.copyInputStreamToFile(inputStream, new File("C:\\Users\\Administrator\\Desktop\\process.png"));
//save sa xml
InputStream inputStreamXml = processEngine.getRepositoryService().getResourceAsStream(deployment.getId(), "process/dynamic-model.bpmn");
FileUtils.copyInputStreamToFile(inputStreamXml, new File("C:\\Users\\Administrator\\Desktop\\process.bpmn.xml"));
return processInstance.getId();
}
/**
* 開始事件
*
* @return
*/
StartEvent createStartEvent() {
StartEvent startEvent = new StartEvent();
startEvent.setId("start");
return startEvent;
}
/**
* 結束事件
*
* @return
*/
EndEvent createEndEvent() {
EndEvent endEvent = new EndEvent();
endEvent.setId("end");
return endEvent;
}
/**
* 建立使用者任務
*
* @param id
* @param name
* @param assignee
* @return
*/
UserTask createUserTask(String id, String name, String assignee) {
UserTask userTask = new UserTask();
userTask.setName(name);
userTask.setId(id);
userTask.setAssignee(assignee);
return userTask;
}
/**
* 建立接收任務
*
* @param id
* @param name
* @return
*/
ReceiveTask createReceiveTask(String id, String name) {
ReceiveTask receiveTask = new ReceiveTask();
receiveTask.setId(id);
receiveTask.setName(name);
return receiveTask;
}
/**
* 連線
*
* @param from
* @param to
* @return
*/
SequenceFlow createSequenceFlow(String from, String to, String conditionExpression) {
SequenceFlow sequenceFlow = new SequenceFlow();
sequenceFlow.setSourceRef(from);
sequenceFlow.setTargetRef(to);
if (StringUtils.isNotBlank(conditionExpression)) {
sequenceFlow.setConditionExpression(conditionExpression);
}
return sequenceFlow;
}
/**
* 排他閘道器
*
* @param id
* @param name
* @return
*/
ExclusiveGateway createExclusiveGateway(String id, String name) {
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId(id);
exclusiveGateway.setName(name);
return exclusiveGateway;
}
/**
* 並行閘道器
*
* @return
*/
ParallelGateway createParallelGateway(String id, String name) {
ParallelGateway parallelGateway = new ParallelGateway();
parallelGateway.setId(id);
parallelGateway.setName(name);
return parallelGateway;
}
}
7.效果圖
相關文章
- 聊聊springboot專案如何實現自定義actuator端點Spring Boot
- SpringBoot專案建立流程--SpringMVCSpring BootSpringMVC
- SpringBoot專案實戰(7):自定義異常處理介面Spring Boot
- SpringBoot讀取自定義配置檔案Spring Boot
- springboot如何使用自定義配置檔案Spring Boot
- 建立自定義專案模板
- springboot專案打war包流程Spring Boot
- SpringBoot 自定義 starterSpring Boot
- SpringBoot自定義StarterSpring Boot
- springboot 自定義errorSpring BootError
- SpringBoot專案使用AOP及自定義註解儲存操作日誌Spring Boot
- .NET Core - 自定義專案模板
- AUTOCAD——新增自定義填充圖案
- Spring Boot - 自定義 Banner 圖案Spring Boot
- springboot讀取自定義配置檔案節點Spring Boot
- SpringBoot自定義classloader加密保護class檔案Spring Boot加密
- springboot自定義異常Spring Boot
- 自定義Vue-cli專案模板Vue
- 五、自定義Zabbix監控專案
- VS2019 自定義專案模板
- _008_SpringBoot_自定義配置Spring Boot
- 自定義springboot啟動器Spring Boot
- 專案需求討論-自定義滾輪
- flutter 用 CustomPaint 繪製自定義圖案FlutterAI
- 採購專案管理:定義和流程專案管理
- 基於函式計算自定義執行時快速部署一個 springboot 專案函式Spring Boot
- 實戰|如何自定義SpringBoot Starter?Spring Boot
- Springboot中自定義監聽器Spring Boot
- SpringBoot自定義校驗註解Spring Boot
- springBoot自定義註解的使用Spring Boot
- SpringBoot自定義註解@YmlPropertySource載入yml或者yaml檔案Spring BootYAML
- 使用函式計算自定義執行時快速部署一個 SpringBoot 專案 | 文末有禮函式Spring Boot
- 使用joinjs繪製流程圖(六)-自定義節點成html元素JS流程圖HTML
- SpringBoot專案部署到阿里雲伺服器全流程Spring Boot阿里伺服器
- Swift 專案總結 03 自定義 CollectionView 佈局SwiftView
- SpringBoot應用篇(一):自定義starterSpring Boot
- SpringBoot自定義控制層引數解析Spring Boot
- SpringBoot自動裝配-自定義StartSpring Boot