ps:activiti7强依赖security,所以还需要整合security,这里就当整合成功了。
真不会整合,就看我下面这个博文
日常记录-SpringBoot整合SpringSecurity(前后分离)+JWT+Redis
org.activiti activiti-spring-boot-starter 7.1.0.M6 mybatis org.mybatis org.springframework.boot spring-boot-starter-security
spring: activiti: #自动更新数据库结构 #1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常 #2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建 #3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表) #4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎) database-schema-update: false #activiti7默认不生成历史信息表,开启历史表 db-history-used: false #记录历史等级 可配置的历史级别有none, activity, audit, full #none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。 #activity:级别高于none,保存流程实例与流程行为,其他数据不保存。 #audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。 #full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。 history-level: none # ============================= #自动检查、部署流程定义文件 check-process-definitions: false # 关闭 SpringAutoDeployment never-fail deployment-mode: never-fail # asyncExecutorActivate是指activiti在流程引擎启动就激活AsyncExecutor,异步:true-开启(默认)、false-关闭 async-executor-activate: true #流程定义文件存放目录,要具体到某个目录 # process-definition-location-prefix: classpath:/processes/holliday/ #process-definition-location-suffixes: #流程文件格式 # - **.bpmn20.xml # - **.bpmn
启动成功后就看到下面的表
activiti常用的服务
@Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService;
java代码
//使用RepositoryService进行部署 DeploymentBuilder builder = repositoryService.createDeployment(); builder.addClasspathResource("bpmn/demo1/demo1.bpmn20.xml"); builder.addClasspathResource("bpmn/demo1/demo1.png"); builder.tenantId("212121");//区分同一个流程所属系统,该值主要用于记录启动的流程实例归属于哪个系统。 builder.name("串行并行配置工作流"); Deployment deployment = builder.deploy(); //输出部署信息 System.out.println("流程部署id:" + deployment.getId()); System.out.println("流程部署名称:" + deployment.getName());
bpmn文件路径
controller代码
/** * 部署流程 * @param fileBpmn bpmn文件 * @param fileSvg svg图片 * @param name 流程名称 * @param key 流程key * @param tenantId 系统标识 -> 同一个流程可以部署多次,互不干扰,系统标识必须唯一 * @return */ @PostMapping(value="/saveDeploy") public ApiResult saveDeploy(@RequestPart(name = "fileBpmn", required = true) MultipartFile fileBpmn, @RequestPart(name = "fileSvg", required = true) MultipartFile fileSvg, @RequestParam("name") String name, @RequestParam("key") String key, @RequestParam("tenantId") String tenantId){ activitiService.saveDeploy(fileBpmn,fileSvg,name,key,tenantId); return ApiResult.ok("成功"); }
service代码
void saveDeploy(MultipartFile fileBpmn, MultipartFile fileSvg, String name, String key,String tenantId);
serviceImpl代码
@Override public void saveDeploy(MultipartFile fb, MultipartFile fg, String name, String key,String tenantId) { //1:使用File 类创建一个要操作的文件路径 //File file = new File("D:" + File.separator + bpmnZip); /* File fileBpmn = new File("D:" + File.separator + fb); File fileSvg = new File("D:" + File.separator + fg);*/ //System.out.println(file.getPath()); InputStream inputStreamBpmn = null; InputStream inputStreamSvg = null; try { inputStreamBpmn = fb.getInputStream(); inputStreamSvg = fg.getInputStream(); /* 这是压缩包部署 ZipInputStream zipInputStream = new ZipInputStream(inputStream); System.out.println(inputStream); */ // 流程部署 Deployment deployment = repositoryService.createDeployment() .name(name) .key(key) .addInputStream(fb.getOriginalFilename(),inputStreamBpmn) .addInputStream(fg.getOriginalFilename(),inputStreamSvg) //.category("vvvv") .tenantId(tenantId) //.addZipInputStream(zipInputStream) .deploy(); System.out.println("流程部署id:" + deployment.getId()); System.out.println("流程部署名称:" + deployment.getName()); }catch (Exception e){ e.printStackTrace(); }finally { try { inputStreamBpmn.close(); inputStreamSvg.close(); }catch (Exception e){ e.printStackTrace(); } } }
部署成功后,这几张表会有数据
act_ge_bytearray(二进制数据表,存储通用的流程定义和流程资源)
act_re_deployment(部署单元信息表)
act_re_procdef(已部署的流程定义)
//参数 processDefinitionKey -> act_re_procdef.KEY_ //参数 businessKey -> 一般是你业务的唯一标识,把该流程和你的业务绑定一起 //参数 Mapvariables -> 流程变量 ProcessInstance startProcessInstanceByKey(String processDefinitionKey); ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey); ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map variables); ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map variables);
//参数 processDefinitionKey -> act_re_procdef.KEY_ //参数 businessKey -> 一般是你业务的唯一标识,把该流程和你的业务绑定一起 //参数 Mapvariables -> 流程变量 //参数 tenantId -> 系统唯一标识(类似同一型号的手机有不同的串码) ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String tenantId); ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, String tenantId); ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, Map variables, String tenantId); ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, Map variables, String tenantId);
//参数 processDefinitionId-> act_re_procdef.ID_ //参数 businessKey -> 一般是你业务的唯一标识,把该流程和你的业务绑定一起 //参数 Mapvariables -> 流程变量 ProcessInstance startProcessInstanceById(String processDefinitionId); ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey); ProcessInstance startProcessInstanceById(String processDefinitionId, Map variables); ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey, Map variables);
获取processDefinitionId的java代码
//一般来说,你也不会设置key和tenantId一样的数据 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey("demo1").processDefinitionTenantId("212121").singleResult(); System.out.println("processDefinition的主键ID:"+processDefinition.getId()); //通过processDefinitionId启动流程 ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); //输出实例信息 System.out.println("流程定义id:" + processInstance.getProcessDefinitionId()); System.out.println("流程实例id:" + processInstance.getId()); System.out.println("当前活动Id:" + processInstance.getActivityId());
部署流程的时候没有配tenantId
ProcessInstance startProcessInstanceByMessage(String messageName); ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey); ProcessInstance startProcessInstanceByMessage(String messageName, MapprocessVariables); ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map processVariables);
部署流程的时候有配tenantId
ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String tenantId); ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, String tenantId); ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, MapprocessVariables, String tenantId); ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, Map processVariables, String tenantId);
实例
message 和 process 是同级的
如果start事件用了messageRef,一定要配相应的message
act_ru_event_subscr表(运行时事件),部署成功就有数据了
java代码1
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessageAndTenantId("testMessage","888888"); //输出实例信息 System.out.println("流程定义id:" + processInstance.getProcessDefinitionId()); System.out.println("流程实例id:" + processInstance.getId()); System.out.println("当前活动Id:" + processInstance.getActivityId());
java代码2
//Execution execution = runtimeService.createExecutionQuery().messageEventSubscriptionName("testMessage").singleResult(); log.info("execution = {}", execution); runtimeService.messageEventReceived("testMessage",execution.getId());
//TaskService已经封装好了,根据自己的业务查询,这里只是简单的演示 //根据流程key查询任务 Listlist = taskService.createTaskQuery() .processDefinitionKey("demo1")//act_re_procdef.KEY_ //.taskAssignee() //任务负责人 .list(); for (Task task : list) { System.out.println("流程实例id:" + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); }
// 可以拾取任务 //参数1 任务id //参数2 负责人名称 taskService.claim("41691bf7-47c9-11ee-af01-002b67defec7","负责人名称");
// 如果设置为null,归任务没有负责人 taskService.setAssignee("41691bf7-47c9-11ee-af01-002b67defec7",null);
//查询任务候选人 //参数1 任务id ListidentityLinkList = taskService.getIdentityLinksForTask("41691bf7-47c9-11ee-af01-002b67defec7"); for (IdentityLink identityLink : identityLinkList) { System.out.println(identityLink.getUserId()); }
// 查看当前用户待审核记录(任务给别人拾取也能查询) //参数1 你定义的用户名称或用户id Listlist = taskService.createTaskQuery().taskInvolvedUser("user1") .orderByTaskCreateTime().desc() .list();// 代办列表 for (Task task : list) { System.out.println("流程实例id:" + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); }
//先查询任务是否给当前用户拾取了 Task task = taskService.createTaskQuery() .taskId("任务id") .taskAssignee("负责人名称") .singleResult(); //再执行任务 if(task != null){ taskService.complete("任务id"); System.out.println("完成任务"); }
常用的服务就这三个了,基本能满足大部分需求
@Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService;