1. springBoot和activiti整合
- pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version><relativePath/></parent><groupId>com.activiti7</groupId><artifactId>activiti7</artifactId><version>0.0.1-SNAPSHOT</version><name>activiti7</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- Mysql驅動包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- activiti --><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.1.0.M6</version></dependency><!-- 注意:activiti需要引入springSecurity包 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
- 數據庫的Config文件
@Configuration
public class DruidConfig {@Value("${spring.datasource.url}")private String url;@Value("${spring.datasource.username}")private String username;@Value("${spring.datasource.password}")private String password;@Value("${spring.datasource.driver-class-name}")private String driverClassName;@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);dataSource.setDriverClassName(driverClassName);// 其他 Druid 相關配置,如最大連接數、初始連接數等return dataSource;}@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}
}
- activiti的config配置類
@Configuration
public class ActivitiConfiguration {@Autowiredprivate DataSource dataSource;@Autowiredprivate PlatformTransactionManager platformTransactionManager;public ActivitiConfiguration() {}//通過@Bean注解將SpringProcessEngineConfiguration實例聲明為Spring Bean,使其可供其他組件注入和使用@Beanpublic SpringProcessEngineConfiguration springProcessEngineConfiguration() {SpringProcessEngineConfiguration spec = new SpringProcessEngineConfiguration();//設置數據源,將注入的數據源設置到SpringProcessEngineConfiguration實例中spec.setDataSource(this.dataSource);//設置事務管理器將注入的事務管理器設置到SpringProcessEngineConfiguration實例中spec.setTransactionManager(this.platformTransactionManager);//設置數據庫模式更新策略 true表示在啟動時自動創建或更新Activiti引擎所需的數據庫表結構spec.setDatabaseSchemaUpdate("true");// 這里我在部署項目的時候自己加載了bpmn文件,所以把這的掃面關掉了。
// Resource[] resources = null;
// //配置流程部署資源
// //使用PathMatchingResourcePatternResolver從classpath中的bpmn目錄下加載所有以.bpmn為擴展名的文件作為流程定義資源,
// // 并將它們設置到SpringProcessEngineConfiguration實例中。
// try {
// resources = (new PathMatchingResourcePatternResolver()).getResources("classpath*:bpmn/*.bpmn");
// } catch (IOException var4) {
// var4.printStackTrace();
// }
// spec.setDeploymentResources(resources);return spec;}
}
- yaml文件
spring:datasource:driverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://123.57.27.43:3306/activiti?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=trueusername: rootpassword: newpwd
注意:啟動項目前需要提前創建好需要用到的數據庫
配置完成后啟動項目,啟動完成后activiti數據庫會自動創建25張activiti相關的表
2. activiti基礎
@SpringBootTest
class Activiti7Base {/*部署流程1.只提供了一種類目錄加載的方式,還有流、zip等方式。2.act_re_deployment表和act_re_procdef表3.注意:act_re_deployment表有一個系統自帶的流程每次啟動項目都會升級版本(暫時沒研究)*/@Testvoid contextLoads() {// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 得到repositoryService實例RepositoryService repositoryService = processEngine.getRepositoryService();// 使用repositoryService進行部署Deployment deployment = repositoryService.createDeployment().addClasspathResource("bpmn/diagram6.bpmn").addClasspathResource("bpmn/diagram6.svg").name("請假申請流程-10").deploy();System.out.println("流程部署id:"+deployment.getId());System.out.println("流程部署名稱:"+deployment.getName());}/*啟動流程*/@Testvoid startProcess(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取runtimeService實例RuntimeService runtimeService = processEngine.getRuntimeService();// 根據流程定義Id啟動流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("java110_752023081032120386");System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());System.out.println("流程實例Id:"+processInstance.getId());System.out.println("當前活動Id:"+processInstance.getActivityId());}/*查詢用戶任務1.act_ru_task表*/@Testvoid queryUserTask(){// 負責人
// String assignee = "mps1";
// String assignee = "mps2";// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 創建taskServiceTaskService taskService = processEngine.getTaskService();// 根據流程key 和 任務負責人 查詢任務List<Task> list = taskService.createTaskQuery().processDefinitionKey("java110_752023081032120386")
// .taskAssignee(assignee).list();for(Task task : list){System.out.println("-------------------------");System.out.println("流程實例id:"+task.getProcessInstanceId());System.out.println("任務id:"+task.getId());System.out.println("任務負責人:"+task.getAssignee());System.out.println("任務名稱:"+task.getName());}}/*用戶完成任務*/@Testvoid finishTask(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 創建taskServiceTaskService taskService = processEngine.getTaskService();// 根據流程key 和 任務負責人 查詢任務Task task = taskService.createTaskQuery().processDefinitionKey("java110_752023081032120386").processInstanceId("2502") //流程實例id.taskAssignee("mps8").singleResult(); //singleResult()只返回一個任務,如果查詢結果有零個或多個任務會拋異常// 完成任務, 參數任務idtaskService.complete(task.getId());}/*查詢流程定義*/@Testvoid queryProcess(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 獲取processDefinitionQuery對象ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();// 查詢當前所有的流程定義List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("java110_752023081032120386").orderByProcessDefinitionVersion().desc().list();for(ProcessDefinition processDefinition : definitionList){System.out.println("流程定義 id="+processDefinition.getId());System.out.println("流程定義 name="+processDefinition.getName());System.out.println("流程定義 key="+processDefinition.getKey());System.out.println("流程定義 Version="+processDefinition.getVersion());System.out.println("流程部署ID="+processDefinition.getDeploymentId());}}/*查詢當前流程實例*/@Testvoid queryProcessInstance(){// 流程定義keyString processDefinitionKey = "java110_752023081032120386";// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取runtimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(processDefinitionKey).list();for(ProcessInstance processInstance : list){System.out.println("---------------------------");System.out.println("流程實例id:"+processInstance.getProcessInstanceId());System.out.println("所屬流程定義id:"+processInstance.getProcessDefinitionId());System.out.println("是否執行完成:"+processInstance.isEnded());System.out.println("是否暫停:"+processInstance.isSuspended());System.out.println("當前活動標識:"+processInstance.getActivityId());System.out.println("業務關鍵字:"+processInstance.getBusinessKey());}}/*下載流程bpmn 和 圖片*/@Testvoid download() throws IOException {// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 得到processDefinition,設置查詢條件,得到想要的流程定義ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("java110_752023081032120386").singleResult();// 通過流程定義信息,得到部署IDString deploymentId = processDefinition.getDeploymentId();// 讀取圖片和bpmnInputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());// 構造流File file_png = new File("D:/idea/work/activiti7/src/main/resources/download/aaa.svg");File file_bpmn = new File("D:/idea/work/activiti7/src/main/resources/download/aaa.bpmn");FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);FileOutputStream pngOut = new FileOutputStream(file_png);// 輸出IOUtils.copy(pngInput,pngOut);IOUtils.copy(bpmnInput,bpmnOut);// 關閉流pngOut.close();bpmnOut.close();pngInput.close();bpmnInput.close();}/*查詢歷史記錄1.act_hi_actinst表*/@Testvoid queryHistoryInfo(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取historyServiceHistoryService historyService = processEngine.getHistoryService();// 獲取act_hi_actinst表的查詢對象HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();// 設置條件instanceQuery.processInstanceId("5002");// 根據開始時間升序instanceQuery.orderByHistoricActivityInstanceStartTime().asc();// 查詢所有內容List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();for(HistoricActivityInstance hi : activityInstanceList){System.out.println(hi.getActivityId());System.out.println(hi.getActivityName());System.out.println(hi.getProcessDefinitionId());System.out.println(hi.getProcessInstanceId());System.out.println("<================================>");}}/*流程定義與流程實例1.流程定義ProcessDefinition和流程實例ProcessInstance是Activti中非常重要的兩個概念。他們的關系其實類似于JAVA中類和對象的概念。2.流程定義ProcessDefinition是以BPMN文件定義的一個工作流程,是一組工作規范。例如我們之前定義的請假流程。流程實例ProcessInstance則是指一個具體的業務流程。例如某個員工發起-一次請假,就會實例化一一個請假的流程實例,并且每個不同的流程實例之間是互不影響的。3.在后臺的表結構中,有很多張表都包含了流程定義ProcessDefinetion和流程實例rocsslnstance的字段。流程定義的字段通常是PROC_DEF_ID,而流程實例的字段通常是PROC_INST_ID。ProcessEngine對象1.processEngine.getRepositoryService() //流程定義對象2.processEngine.getRuntimeService() //運行時的對象(實例對象)3.processEngine.getHistoryService() //歷史記錄對象4.processEngine.getTaskService() //任務對象*/
}
3. activiti進階
@SpringBootTest
public class Activiti7Progress {/*啟動任務時,添加業務key*/@Testvoid addBusinessKey(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取runtimeService實例RuntimeService runtimeService = processEngine.getRuntimeService();// 根據流程定義Id啟動流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("java110_752023081032120386","1001");System.out.println("businessKey:"+processInstance.getBusinessKey());}/*整個流程的掛起和激活 ,掛起就是讓改流程停止服務*/@Testvoid suspendAllProcessInstance(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();// 得到processDefinition,設置查詢條件,得到想要的流程定義ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("java110_752023081032120386").singleResult();// 獲取當前流程是否是掛起狀態boolean suspended = processDefinition.isSuspended();// 獲取流程定義的idString definitionId = processDefinition.getId();// 如果是掛起狀態,改為激活狀態 否在掛起if(suspended){repositoryService.activateProcessDefinitionById(definitionId,true,null);System.out.println("流程定義id:"+definitionId+",已激活");}else {repositoryService.suspendProcessDefinitionById(definitionId,true,null);System.out.println("流程定義id:"+definitionId+",已掛起");}}/*掛起單個流程實例*/@Testvoid suspendSingleProcessInstance(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 獲取runtimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();// 得到runtimeService,設置查詢條件,得到想要的流程定義ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId("30002").singleResult();// 獲取當前流程是否是掛起狀態boolean suspended = instance.isSuspended();// 獲取流程定義的idString definitionId = instance.getId();// 如果是掛起狀態,改為激活狀態 否在掛起if(suspended){runtimeService.activateProcessInstanceById(definitionId);System.out.println("流程定義id:"+definitionId+",已激活");}else {runtimeService.suspendProcessInstanceById(definitionId);System.out.println("流程定義id:"+definitionId+",已掛起");}}/*啟動流程,帶流程map變量1.涉及到的bpmn文件和網關圖片放在下面*/@Testvoid startProcessM(){// 創建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 流程定義的keyString key = "java110_752023081032120386";// 流程變量mapHashMap<String, Object> variables = new HashMap<>();// 設置流程變量Evection evection = new Evection();// 設置請假日期evection.setNum(4d);// 把流程變量放入mapvariables.put("evection",evection);// 設置任務負責人
// variables.put("assignee0","李四1");
// variables.put("assignee1","王經理1");
// variables.put("assignee2","楊總經理1");
// variables.put("assignee3","張財務1");// 獲取runtimeService實例RuntimeService runtimeService = processEngine.getRuntimeService();// 根據流程定義Id啟動流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,variables);System.out.println("流程定義Id:"+processInstance.getProcessDefinitionId());System.out.println("流程實例Id:"+processInstance.getId());System.out.println("當前活動Id:"+processInstance.getActivityId());}/*查詢候選用戶*/@Testvoid queryUsers(){//得到ProcessEngine對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//得到TaskService對象TaskService taskService = processEngine.getTaskService();//設置一些參數,流程定義的key,候選用戶String key = "java110_752023081032120386";String candidateUsers = "mps8";//4.執行查詢List<Task> list = taskService.createTaskQuery().processDefinitionKey(key).taskCandidateUser(candidateUsers)//設置候選用戶.list();for (Task task : list) {System.out.println(task.getProcessInstanceId());System.out.println(task.getId());System.out.println(task.getName());System.out.println(task.getAssignee());//為null,說明當前的mps7只是一個候選人,并不是任務的執行人(需要拾取任務)}}/*查詢候選用戶組*/@Testvoid queryGroup(){// 得到ProcessEngine對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 得到TaskService對象TaskService taskService = processEngine.getTaskService();// 設置一些參數,流程定義的key,候選用戶String key = "java110_752023081032120386";String candidateUsers = "mps8";List<Task> list = taskService.createTaskQuery().processDefinitionKey(key).taskCandidateGroup(candidateUsers)// 設置候選用戶.list();for (Task task : list) {System.out.println(task.getProcessInstanceId());System.out.println(task.getId());System.out.println(task.getName());System.out.println(task.getAssignee());//為null,說明當前的mps7只是一個候選人,并不是任務的執行人(需要拾取任務)}}/*候選用戶拾取任務*/@Testvoid claimTask(){// 得到ProcessEngine對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 得到TaskService對象TaskService taskService = processEngine.getTaskService();// 設置一些參數,流程定義的key,候選用戶String key = "java110_752023081032120386";String candidateUsers = "mps8";Task task = taskService.createTaskQuery().processDefinitionKey(key)
// .taskCandidateUser(candidateUsers)// 設置候選用戶(候選用戶方式).taskCandidateGroup(candidateUsers)// 設置候選用戶(候選用戶組方式).singleResult();if (task != null) {taskService.claim(task.getId(), candidateUsers);// 第一個參數任務ID,第二個參數為具體的候選用戶名 此處可以try catch下,如果該任務已經被其他人拾取,會報異常,此時可以給前端展示任務已被拾取System.out.println("任務拾取完畢!"); // 拾取完之后就可以正常的進行辦理了}}/*任務的退還 和 交接*/@Testvoid connectTask(){// 得到ProcessEngine對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 得到TaskService對象TaskService taskService = processEngine.getTaskService();// 設置一些參數,流程定義的key,用戶String key = "java110_752023081032120386";String assignee = "mps7";// 執行查詢Task task = taskService.createTaskQuery().processDefinitionKey(key).taskAssignee(assignee) // 設置任務的負責人.singleResult();// 判斷是否有這個任務if (task != null) {// 退還 如果設置為null,歸還組任務,該任務沒有負責人taskService.setAssignee(task.getId(), null);// 交接 交接任務為mps8 ,交接任務就是一個候選人拾取用戶的過程 // 注意:activiti沒有幫我們限制一定是候選組里面的人,可以交接給任意人
// taskService.setAssignee(task.getId(), "lisi");
// System.out.println("交接任務完成~!");}}/*任務委派*/@Testvoid delegateTask(){String key = "java110_752023081032120386";String assignee = "mps3";// 得到ProcessEngine對象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 得到TaskService對象TaskService taskService = processEngine.getTaskService();// 執行查詢Task task = taskService.createTaskQuery().processDefinitionKey(key).taskAssignee(assignee) // 設置任務的負責人.singleResult();// 判斷是否有這個任務if (task != null) {taskService.delegateTask(task.getId(),"mps2");}}/*1.claim() 和 setAssignee() 區別taskService.claim(String taskId,String userId);taskService.setAssignee(String taskId, String userId);都可以實現對任務的認領。兩個方法的區別在于執行 claim 方法時會檢查該任務是否已被簽收,如果已被簽收,則會拋出 ActivitiTaskAlreadyClaimedException 異常,其他方面兩個方法效果一致。2. 委派在act_ru_task表中OWNER_(委托人),ASSIGNEE_(辦理人)兩個字段。任務委托一定是任務的代理人assignee如mps3將自己的任務委托給用戶mps2原來表中:ASSIGNEE_=mps3 OWNER_=null委托后:ASSIGNEE_=mps2 OWNER_=mps3務必理解:OWNER_是委托前的辦理人3. 候選用戶 和 候選組候選用戶和候選組都需要先拾取任何,然后在辦理任務。沒有用戶拾取任務時代辦人(Assignee)為空。候選組有更加規范的使用方式,參考:https://blog.csdn.net/qq_41466440/article/details/130592801。*/
}
候選用戶,候選用戶組,代辦人
/*查詢用候選用戶,候選用戶組*/@Testvoid queryUsersTask(){List<IdentityLink> forTask = taskService.getIdentityLinksForTask(task.getId());for(IdentityLink identityLink : forTask){System.out.println("<------------------候選組用戶>");System.out.println("GroupId:"+identityLink.getGroupId());System.out.println("ProcessDefinitionId:"+identityLink.getProcessDefinitionId());System.out.println("TaskId:"+identityLink.getTaskId());System.out.println("UserId:"+identityLink.getUserId());System.out.println("Type:"+identityLink.getType());System.out.println("ProcessInstanceId:"+identityLink.getProcessInstanceId());}}
查詢候選用戶結果:
<------------------候dai選組用戶>
GroupId:null
ProcessDefinitionId:null
TaskId:12503
UserId:mps7
Type:candidate
ProcessInstanceId:null
<------------------候選組用戶>
GroupId:null
ProcessDefinitionId:null
TaskId:12503
UserId:mps8
Type:candidate
ProcessInstanceId:null查詢代辦用戶結果:
GroupId:null
ProcessDefinitionId:null
TaskId:20003
UserId:mps8
Type:assignee
ProcessInstanceId:null查詢候選用戶組的結果:
<------------------候選組用戶>
GroupId:mps7
ProcessDefinitionId:null
TaskId:20003
UserId:null
Type:candidate
ProcessInstanceId:null
<------------------候選組用戶>
GroupId:mps8
ProcessDefinitionId:null
TaskId:20003
UserId:null
Type:candidate
ProcessInstanceId:null注意:
- 返回結果的Type來區分:candidate候選用戶,assignee代辦用戶
- 候選組用戶這樣查詢,正常使用。
- 候選組有更加規范的使用方式,參考:https://blog.csdn.net/qq_41466440/article/details/130592801
- 流程變量
流程變量的作用域
- 全局流程變量:在整個流程執行期間,這個流程變量都是有效的。
- 本地流程變量:這個只針對流程中某一個具體的 Task(任務)有效,這個任務執行完畢后,這個流程變量就失效了。
- 臨時流程變量:顧名思義就是臨時的,這個不會存入到數據庫中(略)。
全局變量
- 啟動流程時設置變量
@Test
void test01() {Map<String, Object> variables = new HashMap<>();variables.put("days", 10);variables.put("reason", "休息一下");variables.put("startTime", new Date());ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo01", variables);
}
儲存在ACT_RU_VARIABLE
表和ACT_HI_VARINST
表里面,每一個流程變量都有對應的流程實例 ID,這就說明這些流程變量是屬于某一個流程實例的。
@Test
void test01() {List<Execution> list = runtimeService.createExecutionQuery().list();for (Execution execution : list) {Object reason = runtimeService.getVariable(execution.getId(), "reason");}
}
/* sql
: ==> select * from ACT_RU_VARIABLE WHERE EXECUTION_ID_ = ? AND TASK_ID_ is null AND NAME_ = ?
: ==> 6fdd2007-4c3a-11ed-aa7e-acde48001122(String), reason(String)
: <== Total: 1
*/
查詢某一個流程的所有變量
@Test
void test02() {List<Execution> list = runtimeService.createExecutionQuery().list();for (Execution execution : list) {Map<String,Object> variables = runtimeService.getVariables(execution.getId());}
}
/* sql
: ==> select * from ACT_RU_VARIABLE WHERE EXECUTION_ID_ = ? AND TASK_ID_ is null: ==> 6fdd2007-4c3a-11ed-aa7e-acde48001122(String): <== Total: 3*/
- 通過 Task 設置
@Test
void test03() {Task task = taskService.createTaskQuery().singleResult();taskService.setVariable(task.getId(), "days", 10); // 逐個設置Map<String, Object> variables = new HashMap<>();variables.put("reason", "休息一下");variables.put("startTime", new Date());taskService.setVariables(task.getId(),variables); // 直接設置一個 Map
}
- 完成任務時設置
@Test
void test04() {Task task = taskService.createTaskQuery().singleResult();Map<String, Object> variables = new HashMap<>();variables.put("reason", "休息一下");variables.put("startTime", new Date());variables.put("days", 10);taskService.complete(task.getId(),variables);
}
- 通過流程設置
@Test
void test05() {Execution execution = runtimeService.createExecutionQuery().singleResult();runtimeService.setVariable(execution.getId(), "days", 10); // 逐個設置Map<String, Object> variables = new HashMap<>();variables.put("reason", "休息一下");variables.put("startTime", new Date());runtimeService.setVariables(execution.getId(), variables); // 直接設置一個 Map
}
本地變量
- 通過 Task 設置
@Test
void test03() {Task task = taskService.createTaskQuery().singleResult();taskService.setVariableLocal(task.getId(), "days", 10); // 逐個設置Map<String, Object> variables = new HashMap<>();variables.put("reason", "休息一下");variables.put("startTime", new Date());taskService.setVariableLocal(task.getId(),variables); // 直接設置一個 Map
}
ACT_RU_VARIABLE
表的里的TASK_ID_ 有值字段就要值了。
通過taskService.complete(task.getId());執行完任務后就在ACT_RU_VARIABLE
表里面查不到該變量了,需要在歷史表里面查詢。
@Test
void test07() {ProcessInstance pi = runtimeService.createProcessInstanceQuery().singleResult();List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().processInstanceId(pi.getId()).list();for (HistoricVariableInstance hvi : list) {logger.info("name:{},type:{},value:{}", hvi.getVariableName(), hvi.getVariableTypeName(), hvi.getValue());}
}
- 完成任務時設置
@Test
void test04() {Task task = taskService.createTaskQuery().singleResult();Map<String, Object> variables = new HashMap<>();variables.put("reason", "休息一下");variables.put("startTime", new Date());variables.put("days", 10);taskService.complete(task.getId(),variables,true);
}
/*
complete(java.lang.String, java.util.Map<java.lang.String,java.lang.Object>, boolean):在完成一個 Task 的時候,如果傳遞了變量,則可以通過第三個參數來控制這個變量是全局的還是本地的,true 表示這個變量是本地的。
*/
后續加的設置變量的方法
- 設置方法變量
- ${da.e(qingjiakaishishijian)>da.e(‘2023-08-21’)} 需要這樣的e()方法來轉換字符串
// 定義一個類
public class Da implements Serializable {public long e(String date) {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");try {return format.parse(date).getTime();} catch (ParseException e) {e.printStackTrace();}return 1;}
}// 設置變量HashMap<String, Object> variables = new HashMap<>();Da da = new Da();variables.put("qingjiakaishishijian","2023-08-22");variables.put("da",da);
// 設置到流程當中(也可以用其它方式設置,本例只寫啟動時設置)ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,variables);
啟動流程,帶流程map變量時用到的文件
- bpmn文件(文件局部內容)
<bpmn2:process id="java110_752023081032120386" name="請假流程-10" isExecutable="true"><bpmn2:startEvent id="StartEvent_1" name="開始"><bpmn2:outgoing>Flow_0gx4dj0</bpmn2:outgoing></bpmn2:startEvent><bpmn2:sequenceFlow id="Flow_0gx4dj0" sourceRef="StartEvent_1" targetRef="Activity_1jdu4q4" /><bpmn2:sequenceFlow id="Flow_01hxak9" sourceRef="Activity_1jdu4q4" targetRef="Activity_0uxetgk" /><bpmn2:sequenceFlow id="Flow_0196722" name="大于等于3天" sourceRef="Activity_0uxetgk" targetRef="Activity_0wbgvlh"><bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${evection.num>=3}</bpmn2:conditionExpression></bpmn2:sequenceFlow><bpmn2:userTask id="Activity_1jdu4q4" name="提交者" activiti:assignee="${assignee0}"><bpmn2:incoming>Flow_0gx4dj0</bpmn2:incoming><bpmn2:outgoing>Flow_01hxak9</bpmn2:outgoing></bpmn2:userTask><bpmn2:userTask id="Activity_0uxetgk" name="部門經理" activiti:assignee="${assignee1}"><bpmn2:incoming>Flow_01hxak9</bpmn2:incoming><bpmn2:outgoing>Flow_0196722</bpmn2:outgoing><bpmn2:outgoing>Flow_05s60lc</bpmn2:outgoing></bpmn2:userTask><bpmn2:userTask id="Activity_0wbgvlh" name="總經理" activiti:assignee="${assignee2}"><bpmn2:incoming>Flow_0196722</bpmn2:incoming><bpmn2:outgoing>Flow_142455r</bpmn2:outgoing></bpmn2:userTask><bpmn2:sequenceFlow id="Flow_142455r" sourceRef="Activity_0wbgvlh" targetRef="Activity_0su91aq" /><bpmn2:userTask id="Activity_0su91aq" name="財務" activiti:assignee="${assignee3}"><bpmn2:incoming>Flow_142455r</bpmn2:incoming><bpmn2:incoming>Flow_05s60lc</bpmn2:incoming><bpmn2:outgoing>Flow_075zn6w</bpmn2:outgoing></bpmn2:userTask><bpmn2:sequenceFlow id="Flow_05s60lc" name="小于3天" sourceRef="Activity_0uxetgk" targetRef="Activity_0su91aq"><bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">${evection.num<3}</bpmn2:conditionExpression></bpmn2:sequenceFlow><bpmn2:endEvent id="Event_0zvcra4"><bpmn2:incoming>Flow_075zn6w</bpmn2:incoming></bpmn2:endEvent><bpmn2:sequenceFlow id="Flow_075zn6w" sourceRef="Activity_0su91aq" targetRef="Event_0zvcra4" /></bpmn2:process>
- 圖片
候選用戶和候選組的bpmn文件
- 候選組bpmn(文件局部內容)
<bpmn2:userTask id="Activity_1js1e5x" name="總經理" activiti:candidateGroups="mps7,mps8"><bpmn2:incoming>Flow_0o5ixaf</bpmn2:incoming><bpmn2:outgoing>Flow_192t89v</bpmn2:outgoing>
</bpmn2:userTask>
- 候選用戶bpmn(文件局部內容)
<bpmn2:userTask id="Activity_1js1e5x" name="總經理" activiti:candidateUsers="mps7,mps8"><bpmn2:incoming>Flow_0o5ixaf</bpmn2:incoming><bpmn2:outgoing>Flow_192t89v</bpmn2:outgoing>
</bpmn2:userTask>
排他網關
- 設置天數就用帶流程map變量的啟動流程就行
- 也可以在流程當中設置流程變量(參考Global和Local)
- 圖片
并行網關
- 設置天數就用帶流程map變量的啟動流程就行
- 也可以在流程當中設置流程變量(參考Global和Local)
- 并行網關的條件不會執行
- 并行網關一般都是兩個一個分開一個聚合,并行網關兩個或多個都執行完成才合并然后往下走
包含網關
- 設置天數就用帶流程map變量的啟動流程就行
- 也可以在流程當中設置流程變量(參考Global和Local)
- 包含網關相當于并行和排他的結合體,符合條件的都執行完才會合并然后往下走
- 設置天數用到的javaBean類(注意:一定到實現序列化接口)
public class Evection implements Serializable {private double num;public double getNum() {return num;}public void setNum(double num) {this.num = num;}
}