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;}
}