关于在IDEA中SpringBoot项目中activiti工作流的使用详解
记录一下工作流的在Springboot中的使用,,顺便写个demo,概念,什么东西的我就不解释了,如有问题欢迎各位大佬指导一下。
1.创建springboot项目后导入依赖
org.activiti activiti-spring-boot-starter-basic 6.0.0
添加配置之后再springboot启动类后面加上一行代码否则启动时会报错
@SpringBootApplication(exclude=SecurityAutoConfiguration.class)
添加数据源以及activiti的配置
spring: activiti: database-schema-update:drop‐create //默认为false,activiti在启动的时候会对比数据库中的表中保存的版本,如果不一样会抛出异常 //trueactiviti会对数据库中的表进行更新操作,如果表不存在,则自动创建 //create_drop在activiti启动的时候创建表,关闭时删除表,必须手动关闭 //drop-create在启动的时候先删除表后再创建新的表 check-process-definitions:false datasource: driver-class-name:com.mysql.cj.jdbc.Driver url:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC username:root password:root
2.初始化activiti表
这里一共有3种方式去创建
第一种
@Test publicvoidinitTables(){ //创建数据源 //DriverManagerDataSourcedataSource=newDriverManagerDataSource(); //dataSource.setDriverClassName("com.mysql.jdbc.Driver"); //dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test"); //dataSource.setUsername("root"); //dataSource.setPassword("root"); //创建流程引擎的配置 ProcessEngineConfigurationconfiguration=ProcessEngineConfiguration .createStandaloneProcessEngineConfiguration(); configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver"); configuration.setJdbcUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&nullCatalogMeansCurrent=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC"); configuration.setJdbcUsername("root"); configuration.setJdbcPassword("root"); // configuration.setDataSource(dataSource); /** *ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE如果数据库里面没有activit的表,也不会创建 *ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP创建表,使用完之后删除 *ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE如果数据库里面没有表,就创建 * *dorp-create代表如果数据库里面有表,那么先删除再创建 * */ //配置表的初始化的方式 configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //得到流程引擎 ProcessEngineprocessEngine=configuration.buildProcessEngine(); System.out.println(processEngine); }
第二种配置activiti.cfg.xml
然后写一个测试类
@Test publicvoidintiTables2(){ ProcessEngineConfigurationconfiguration=ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); //得到流程引擎 ProcessEngineprocessEngine=configuration.buildProcessEngine(); System.out.println(processEngine); }
第三种方法
@Test publicvoidintiTables3(){ //必须创建activiti.cfg.xml并配置好数据库的信息 ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine(); System.out.println(processEngine); }
3.打开数据库查看
我们打开数据库查看数据库,会发现activiti已自动帮我们创建了28张表(有的好像也只有24张表,有兴趣的可以研究一下)
这里为大家解释一下各张表的含义:Activiti的后台是有数据库的支持,所有的表都以ACT_开头。第二部分是表示表的用途的两个字母标识。
ACT_RE_*:'RE'表示repository。这个前缀的表包含了流程定义和流程静态资源(图片,规则,等等)。
ACT_RU_*:'RU'表示runtime。这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。Activiti只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。这样运行时表可以一直很小速度很快。
ACT_ID_*:'ID'表示identity。这些表包含身份信息,比如用户,组等等。
ACT_HI_*:'HI'表示history。这些表包含历史数据,比如历史流程实例,变量,任务等等。
ACT_GE_*:通用数据,用于不同场景下,如存放资源文件。
#RepositoryService Select*fromact_ge_bytearray;二进制文件夹表 Select*fromact_re_deployment;流程部署表 Select*fromact_re_procdef;流程定义表 Select*fromact_ge_property;属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录 #RuntimeServiceTaskService运行时数据库表 Select*fromact_ru_excution;流程启动一次只要没有执行完就会有一条数据 Select*fromact_ru_task;可能有多条数据 Select*fromact_ru_variable;记录流程运行时的流程变量 Select*fromact_ru_identitylink;存放流程办理人的信息 #HistoryService历史数据库表 Select*fromact_hi_procinst;历史流程实例 Select*fromact_hi_taskinst;历史任务实例 Select*fromact_hi_actinst;历史节点表 Select*fromact_hi_attachment;历史附件表 Select*fromact_hicomment;历史意见表 Select*fromact_hi_identitylink;历史流程人员表 Select*fromact_hi_detail;历史详情表提供历史变量查询 Select*fromact_hi_procinst;历史流程实例表 Select*fromact_hi_taskinst;历史任务实例表 Select*fromact_hi_varinst;历史变量表 #IdentityService这四张表尽量使用自己的一套,难以满足需求 Select*fromact_id_group;用户组信息表 Select*fromact_id_info;用户拓展信息表 Select*fromact_id_menbership;用户与用户组对应表 Select*fromact_id_user;用户信息表
4.接下来开始画请假流程图(需要先安装插件),新建一个bpm文件开始编辑
Assignee相当于办理人的意思我这里是zhang提出申请,主管yuan审核。
5.部署流程流程
//得到流程引擎 privateProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine(); @Test publicvoiddeployProcess01(){ //得到流程部署的service RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); Deploymentdeploy=repositoryService.createDeployment().name("请假流程").addClasspathResource("activitiTest.bpmn").deploy(); System.out.println("部署成功:流程部署ID:"+deploy.getId()); }
6.启动流程(这里的key与第五部第一张途中对应)
/** *启动流程 */ @Test publicvoidstartProcess(){ RuntimeServiceruntimeService=this.processEngine.getRuntimeService(); //StringprocessDefinitionId="HelloWorld:1:4"; // runtimeService.startProcessInstanceById(processDefinitionId); StringprocessDefinitionKey="mytest"; runtimeService.startProcessInstanceByKey(processDefinitionKey); System.out.println("流程启动成功"); }
7.根据用户查询任务(这里使用流程图中的assignee字段)
@Test publicvoidqueryTask(){ TaskServicetaskService=this.processEngine.getTaskService(); Stringassignee="chen"; Listlist=taskService.createTaskQuery().taskAssignee(assignee).list(); if(null!=list&&list.size()>0){ for(Tasktask:list){ System.out.println("任务ID:"+task.getId()); System.out.println("流程实例ID:"+task.getProcessInstanceId()); System.out.println("执行实例ID:"+task.getExecutionId()); System.out.println("流程定义ID:"+task.getProcessDefinitionId()); System.out.println("任务名称:"+task.getName()); System.out.println("任务办理人:"+task.getAssignee()); System.out.println("################################"); } } }
8.办理任务(配合步骤8查询出taskid然后进行办理任务)
@Test publicvoidcompleteTask(){ TaskServicetaskService=this.processEngine.getTaskService(); StringtaskId="5005";//步骤8中查询出来的taskId taskService.complete(taskId); System.out.println("任务完成"); }
重复7、8两个步骤,自此一个完整的请假流程就完成了。
那么肯定会有人问了,如果我想查看一我们流程定义的信息,流程图,删除流程定义等怎么办呢,话不多说直接上代码
packagecom.example; importorg.activiti.engine.ProcessEngine; importorg.activiti.engine.ProcessEngines; importorg.activiti.engine.RepositoryService; importorg.activiti.engine.RuntimeService; importorg.activiti.engine.repository.Deployment; importorg.activiti.engine.repository.ProcessDefinition; importorg.junit.jupiter.api.Test; importjava.io.BufferedOutputStream; importjava.io.File; importjava.io.FileOutputStream; importjava.io.InputStream; importjava.util.Collection; importjava.util.HashMap; importjava.util.List; importjava.util.Map; importjava.util.zip.ZipInputStream; publicclassTestProcessProdef{ //得到流程引擎 privateProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine(); /** *部署流程使用classpath */ @Test publicvoiddeployProcess01(){ //得到流程部署的service RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); Deploymentdeploy=repositoryService.createDeployment().name("请假流程2").addClasspathResource("activiti.bpmn").deploy(); System.out.println("部署成功:流程部署ID:"+deploy.getId()); } /** *查询流程部署信息act_re_deployment */ @Test publicvoidqueryProcessDeploy(){ RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); //创建部署信息的查询 StringdeploymentId="1"; // Deploymentdeploy=repositoryService.createDeploymentQuery() Listlist=repositoryService.createDeploymentQuery() //条件 //.deploymentId(deploymentId)//根据部署ID去查询 //.deploymentName(name)//根据部署名称去查询 //.deploymentTenantId(tenantId)//根据tenantId去查询 // .deploymentNameLike(nameLike)//根据部署名称模糊查询 //.deploymentTenantIdLike(tenantIdLike)//根据tenantId模糊查询 //排序 // .orderByDeploymentId().asc()//根据部署ID升序 //.orderByDeploymenTime().desc()//根据部署时间降序 //.orderByDeploymentName()//根据部署名称升序 //结果集 .list();//查询返回list集合 // .listPage(firstResult,maxResults)分页查询返回list集合 //.singleResult();//返回单个对象 // .count(); /* *System.out.println("部署ID:"+deploy.getId()); *System.out.println("部署名称:"+deploy.getName()); *System.out.println("部署时间:"+deploy.getDeploymentTime()); */ // System.out.println(count); for(Deploymentdeployment:list){ System.out.println("部署ID:"+deployment.getId()); System.out.println("部署名称:"+deployment.getName()); System.out.println("部署时间:"+deployment.getDeploymentTime()); System.out.println("########################"); } } /** *查询流程定义 */ @Test publicvoidqueryProcDef(){ RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); List list=repositoryService.createProcessDefinitionQuery() //条件 // .deploymentId(deploymentId)根据部署ID查询 // .deploymentIds(deploymentIds)根据部署ID的集合查询Set deploymentIds // .processDefinitionId(processDefinitionId)//根据流程定义IDHelloWorld:1:4 // .processDefinitionIds(processDefinitionIds)//根据流程定义的IDS查询 // .processDefinitionKey(processDefinitionKey)//根据流程定义的的key查询 // .processDefinitionKeyLike(processDefinitionKeyLike)//根据流程定义的的key模糊查询 // .processDefinitionName(processDefinitionName)//根据流程定义的名称查询 // .processDefinitionNameLike(processDefinitionNameLike)//根据流程定义的名称模糊查询 // .processDefinitionResourceName(resourceName)//根据流程图的BPMN文件名查询 // .processDefinitionResourceNameLike(resourceNameLike)//根据流程图的BPMN文件名模糊查询 // .processDefinitionVersion(processDefinitionVersion)//根据流程定义的版本查询 // .processDefinitionVersionGreaterThan(processDefinitionVersion)//version>num // .processDefinitionVersionGreaterThanOrEquals(processDefinitionVersion)//version>=num // .processDefinitionVersionLowerThan(processDefinitionVersion)//version 0){ for(ProcessDefinitionpd:list){ System.out.println("流程定义ID:"+pd.getId()); System.out.println("流程部署ID:"+pd.getDeploymentId()); System.out.println("流程定义KEY:"+pd.getKey()); System.out.println("流程定义的名称:"+pd.getName()); System.out.println("流程定义的bpmn文件名:"+pd.getResourceName());//bpmn的name System.out.println("流程图片名:"+pd.getDiagramResourceName());//png的name System.out.println("流程定义的版本号:"+pd.getVersion()); System.out.println("##################"); } } } /** *启动流程 */ @Test publicvoidstartProcess(){ RuntimeServiceruntimeService=this.processEngine.getRuntimeService(); StringprocessDefinitionKey="mytest"; runtimeService.startProcessInstanceByKey(processDefinitionKey); System.out.println("流程启动成功"); } /** *删除流程定义 */ @Test publicvoiddeleteProcessDef(){ RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); StringdeploymentId="2501"; //根据流程部署id删除流程定义如果当前id的流程正在执行,那么会报错 //repositoryService.deleteDeployment(deploymentId); //根据流程部署id删除删除流程定义如果当前id的流程正在执行,会把正在执行的流程数据删除act_ru_*和act_hi_*表里面的数据 repositoryService.deleteDeployment(deploymentId,true); // repositoryService.deleteDeploymentCascade(deploymentId);==repositoryService.deleteDeployment(deploymentId,true); System.out.println("删除成功"); } /** *查询流程图根据流程定义ID */ @Test publicvoidviewProcessImg(){ RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); StringprocessDefinitionId="mytest:2:2504"; InputStreaminputStream=repositoryService.getProcessDiagram(processDefinitionId); Filefile=newFile("d:/mytest.png"); try{ BufferedOutputStreamoutputStream=newBufferedOutputStream(newFileOutputStream(file)); intlen=0; byte[]b=newbyte[1024]; while((len=inputStream.read(b))!=-1){ outputStream.write(b,0,len); outputStream.flush(); } outputStream.close(); inputStream.close(); System.out.println("查询成功"); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } /** *查询流程图根据流流程部署ID */ @Test publicvoidviewProcessImg2(){ RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); //根据流程部署ID查询流程定义对象 StringdeploymentId="1"; ProcessDefinitionprocessDefinition=repositoryService.createProcessDefinitionQuery() .deploymentId(deploymentId).singleResult(); //从流程定义对象里面查询出流程定义ID StringprocessDefinitionId=processDefinition.getId(); InputStreaminputStream=repositoryService.getProcessDiagram(processDefinitionId); Filefile=newFile("d:/"+processDefinition.getDiagramResourceName()); try{ BufferedOutputStreamoutputStream=newBufferedOutputStream(newFileOutputStream(file)); intlen=0; byte[]b=newbyte[1024]; while((len=inputStream.read(b))!=-1){ outputStream.write(b,0,len); outputStream.flush(); } outputStream.close(); inputStream.close(); System.out.println("查询成功"); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } /** *查询最新的流程定义 */ @Test publicvoidqueryNewProcessDef(){ Map map=newHashMap<>(); //查询所有的流程定义根据版本号升序 RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); List list=repositoryService.createProcessDefinitionQuery() .orderByProcessDefinitionVersion().asc().list(); if(null!=list&&list.size()>0){ for(ProcessDefinitionpd:list){ map.put(pd.getKey(),pd); } } //循环map集合 Collection values=map.values(); for(ProcessDefinitionpd:values){ System.out.println("流程定义ID:"+pd.getId()); System.out.println("流程部署ID:"+pd.getDeploymentId()); System.out.println("流程定义KEY:"+pd.getKey()); System.out.println("流程定义的名称:"+pd.getName()); System.out.println("流程定义的bpmn文件名:"+pd.getResourceName());//bpmn的name System.out.println("流程图片名:"+pd.getDiagramResourceName());//png的name System.out.println("流程定义的版本号:"+pd.getVersion()); System.out.println("##################"); } } /** *已知key附加功能:删除流程定义(删除key相同的所有不同版本的流程定义) */ publicvoiddeleteAllSameVersion(){ StringprocessDefinitionKey="mytest"; RepositoryServicerepositoryService=this.processEngine.getRepositoryService(); //根据流程定义的key查询流程集合 List list=repositoryService.createProcessDefinitionQuery() .processDefinitionKey(processDefinitionKey).list(); if(null!=list&&list.size()>0){ for(ProcessDefinitionpd:list){ repositoryService.deleteDeployment(pd.getDeploymentId(),true); } } } }
肯定还有人会问,上面的请假流程是走完了,但是没有写请假理由,请假天数,如果是报销单的话还需要上传报销单据等,那么这个怎么解决呢?这个时候就需要activiti提供给我们的流程变量了,那么什么是流程变量呢?
流程变量在整个工作流中扮演很重要的作用。例如:请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不相互影响的。流程实例结束完成以后流程变量还保存在数据库中(存放到流程变量的历史表中)。图中红框的信息就是流程变量。
那么我们怎么设置流程变量呢,我们启动流程的时候就可以设置流程变量了,见代码:
/** *启动流程 */ @Test publicvoidstartProcess(){ RuntimeServiceruntimeService=this.processEngine.getRuntimeService(); StringprocessDefinitionKey="mytest"; // ProcessInstanceprocessInstance=runtimeService.startProcessInstanceByKey(processDefinitionKey); //创建流程变量对象 Mapvariables=newHashMap<>(); variables.put("请假天数",30);//int variables.put("请假原因","结婚"); variables.put("请假时间",newDate()); ProcessInstanceprocessInstance=runtimeService.startProcessInstanceByKey(processDefinitionKey,variables); System.out.println("流程启动成功:"+processInstance.getId()+""+processInstance.getProcessDefinitionId()+"" +processInstance.getProcessInstanceId()); }
说明:
1)流程变量的作用域就是流程实例,所以只要设置就行了,不用管在哪个阶段设置
2)基本类型设置流程变量,在taskService中使用任务ID,定义流程变量的名称,设置流程变量的值。
3)Javabean类型设置获取流程变量,除了需要这个javabean实现了Serializable接口外,还要求流程变量对象的属性不能发生变化,否则抛出异常。解决方案,固定序列化ID
4)设置流程变量的时候,向act_ru_variable这个表添加数据
RuntimeService对象可以设置流程变量和获取流程变量 TaskService对象可以设置流程变量和获取流程变量
Map集合的key表示流程变量的名称 Map集合的value表示流程变量的值
查询流程变量以及查询历史流程变量:
/** *获取流程变量 */ @Test publicvoidgetVariables(){ RuntimeServiceruntimeService=this.processEngine.getRuntimeService(); StringexecutionId="2501"; Integerdays=(Integer)runtimeService.getVariable(executionId,"请假天数"); Datedate=(Date)runtimeService.getVariable(executionId,"请假时间"); Useruser=(User)runtimeService.getVariable(executionId,"用户对象"); System.out.println(days); System.out.println(date.toLocaleString()); System.out.println(user.getId()+""+user.getName()); } /** *7:查询历史的流程变量 */ @Test publicvoidgetHistoryVariables(){ HistoryServicehistoryService=this.processEngine.getHistoryService(); /*HistoricVariableInstancesingleResult=historyService.createHistoricVariableInstanceQuery().id("2503").singleResult();; System.out.println(singleResult.getId()); System.out.println(singleResult.getValue()); System.out.println(singleResult.getVariableName()); System.out.println(singleResult.getVariableTypeName());*/ StringprocessInstanceId="2501"; Listlist=historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list(); for(HistoricVariableInstancehvs:list){ System.out.println("ID"+hvs.getId()); System.out.println("变量值"+hvs.getValue()); System.out.println("变量名"+hvs.getVariableName()); System.out.println("变量类型"+hvs.getVariableTypeName()); System.out.println("#####################"); } }
查询历史流程实例、查询历史活动以及查询历史任务
publicclassTestHistoryQuery{ privateProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine(); HistoryServicehistoryService=this.processEngine.getHistoryService(); /*1,查询历史流程实例*/ @Test publicvoidhistoryProcessInstince(){ Listlist=historyService.createHistoricProcessInstanceQuery() //条件 // .processDefinitionId(processDefinitionId) // .processDefinitionKey(processDefinitionKey) // .processDefinitionKeyIn(processDefinitionKeys) // .processDefinitionName(processDefinitionName) // .processDefinitionVersion(processDefinitionVersion) // .processInstanceBusinessKey(processInstanceBusinessKey) // .processInstanceId(processInstanceId) // .processInstanceIds(processInstanceIds) //排序 // .orderByProcessDefinitionId() // .orderByProcessInstanceBusinessKey() // .orderByProcessInstanceDuration() // .orderByProcessInstanceStartTime() // .orderByProcessInstanceId() //结果集 .list(); // .listPage(firstResult,maxResults) // .count() // .singleResult(); if(null!=list&&list.size()>0){ for(HistoricProcessInstancehpi:list){ System.out.println("历史流程实例ID:"+hpi.getId()); System.out.println("流程定义ID:"+hpi.getProcessDefinitionId()); System.out.println("历史流程实例的业务ID:"+hpi.getBusinessKey()); System.out.println("流程部署ID:"+hpi.getDeploymentId()); System.out.println("流程定义KEY:"+hpi.getProcessDefinitionKey()); System.out.println("开始活动ID:"+hpi.getStartActivityId()); System.out.println("结束活动ID:"+hpi.getEndActivityId()); System.out.println("########################"); } } } /*2,查询历史活动*/ @Test publicvoidqueryHistoryAct(){ List list=this.historyService.createHistoricActivityInstanceQuery() //条件 // .activityId(activityId) // .activityInstanceId(activityInstanceId) // .activityName(activityName) //排序 // .orderByActivityId() // .orderByActivityName() //结果集 .list(); if(null!=list&&list.size()>0) { for(HistoricActivityInstancehai:list){ System.out.println("ID:"+hai.getId()); System.out.println("流程定义ID:"+hai.getProcessDefinitionId()); System.out.println("流程实例ID:"+hai.getProcessInstanceId()); System.out.println("执行实例ID:"+hai.getExecutionId()); System.out.println("活动ID:"+hai.getActivityId()); System.out.println("任务ID:"+hai.getTaskId()); System.out.println("活动名称:"+hai.getActivityName()); System.out.println("活动类型:"+hai.getActivityType()); System.out.println("任务办理人:"+hai.getAssignee()); System.out.println("开始时间:"+hai.getStartTime()); System.out.println("结束时间:"+hai.getEndTime()); System.out.println("持续时间:"+hai.getDurationInMillis()); System.out.println("#######################################"); } } } /*3,查询历史任务act_hi_taskinst*/ @Test publicvoidqueryHistoryTask(){ List list=this.historyService.createHistoricTaskInstanceQuery() //条件 // .deploymentId(deploymentId) // .deploymentIdIn(deploymentIds) // .executionId(executionId) // .processDefinitionId(processDefinitionId) // .processDefinitionKey(processDefinitionKey) // .processDefinitionKeyIn(processDefinitionKeys) // .processDefinitionKeyLike(processDefinitionKeyLike)processDefinitionKeyLike="%Hello%" // .processDefinitionName(processDefinitionName) // .processDefinitionNameLike(processDefinitionNameLike) //排序 // .orderByTaskDefinitionKey() //结果集 .list(); // .listPage(firstResult,maxResults) // .count() // .singleResult() if(null!=list&&list.size()>0) { for(HistoricTaskInstancetask:list){ System.out.println("任务ID:"+task.getId()); System.out.println("任务办理人:"+task.getAssignee()); System.out.println("执行实例ID:"+task.getExecutionId()); System.out.println("任务名称:"+task.getName()); System.out.println("流程定义ID:"+task.getProcessDefinitionId()); System.out.println("流程实例ID:"+task.getProcessInstanceId()); System.out.println("任务创建时间:"+task.getCreateTime()); System.out.println("任务结束时间:"+task.getEndTime()); System.out.println("#######################################"); } } } }
最近我发现上面的代码不能完全在开发中应用,比如上面的用户申请是在画流程图的时候写死的,在实际开发中肯定是根据当前登录的用户来提出申请,另外还没有分支的情况,所以我特地修改了一下流程图。
这个流程图中没有设置用户,在Condition中传入参数#{UserId},后面的重要与不重要分支同样加上Condition条件${message=='重要'}和${message=='不重要'},然后主管审核和总经理的assignee可以设置成固定的值也可以像用户一样根据传参设置。接下来直接上代码
1.启动流程
/**启动流程实例*/ @Test publicvoidstartProcessInstance(){ StringprocessDefinitionKey="myProcess_1"; /**启动流程实例的同时,设置流程变量,使用流程变量用来指定任务的办理人,对应task.pbmn文件中#{userID}*/ Mapvariables=newHashMap (); variables.put("userID","袁志豪"); ProcessInstancepi=processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service .startProcessInstanceByKey(processDefinitionKey,variables);//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动 System.out.println("流程实例ID:"+pi.getId());//流程实例ID101 System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID }
用户完成申请提交,主管在流成图中没有设置固定值
@Test publicvoidcompleteTask(){ TaskServicetaskService=this.processEngine.getTaskService(); StringtaskId="2508"; //根据任务ID去完成任务 //taskService.complete(taskId); //根据任务ID去完成任务并指定流程变量 Mapvariable=newHashMap<>(); Stringshenheren="张三";//实际开发中可在前台选择主管传入后台 variable.put("zhuguan","张三");//这里的zhuguan和activiti.bpmn中的#{zhuguan}保持一致,既可以设置下一级审核主管 taskService.complete(taskId,variables); System.out.println("任务完成"); }
主管审核
@Test publicvoidcomplateTask2(){ TaskServicetaskService=this.processEngine.getTaskService(); StringtaskId2="5002"; Mapvariable=newHashMap<>(); /***这里的message是流程图中分支条件message,根据传入的参数判断走那一条线***/ variable.put("message","重要"); //variable.put("message","不重要"); taskService.complete(taskId2,variable); }
经理审核
@Test publicvoidcomplateTask3(){ TaskServicetaskService=this.processEngine.getTaskService(); StringtaskId2="7503"; Mapvariable=newHashMap<>(); variable.put("审核意见","好好休假注意身体");//领导审核意见 taskService.complete(taskId2,variable); }
另外我在开发中发现在流程图画完之后将bpmn后缀改为xml方式生成图片之后,再次改为bpmn的时候,发现之前写的Condition中变成了\n,如图
我们再次将后缀改为xml之后查看我们的条件:
解决方式:
将condition前面后面的空格删掉即可;
到此这篇关于关于在IDEA中SpringBoot项目中activiti工作流的使用详解的文章就介绍到这了,更多相关IDEASpringBootactiviti工作流内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。