工作流Acticity7入门

中间件 / 2022-06-21

一、背景

最近工作上有审批需求场景要用到工作流,最终选型还是选择了activity7版本,话不多说,进入主题

二、如何画流程图

1.1 进入activity官网 https://www.activiti.org/get-started
1.2 下载

image-1667907029093

1.3下载后解压,在war目录下会有3个war包,然后将activiti-app.war 拷贝到我们自己的tomcat的webapp目录下,并启动tomcat

1.4 启动成功,浏览器输入 http://localhost:8080/activiti-app 进入到登录页

默认用户名:admin

默认密码:test

1.5页面默认是英文版,网上搜了下汉化资料,最终效果还可以,如有需要请私信留邮箱。
image-1667907043926

1.6 新建自己的流程,画好后将流程图进行导出保存在本地,放在项目classpath下,新建processes文件夹xx.bpmn20.xml

三、整合SpringBoot

因为工作流框架自己业务表有23个表,因此,在架构设计的时候考虑将工作流项目与业务系统解耦抽象出来,封装成微服务,其他微服务通过feign来调用工作流接口。

引入依赖:

		<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-spring-boot-starter</artifactId>
			<version>7.1.0.M6</version>
		</dependency>

配置文件:

spring:
  activiti:
    database-schema-update: true //如果表不存在,则Activiti会自动创建
    history-level: full //保存历史数据级别设置为full最高级别
    db-history-used: true //检测历史表是否存在
单元测试一 部署流程
@Test
public void deployProcess() throws IOException {
   String name = "school_apply";
   // 1、创建ProcessEngine
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
   // 2、获取RepositoryService
   RepositoryService repositoryService = processEngine.getRepositoryService();
   //指定clapath路径资源
   ClassPathResource classPathResource = new ClassPathResource("processes/school_apply.bpmn20.xml");
   InputStream inputStream = classPathResource.getInputStream();
   Deployment deployment = repositoryService.createDeployment()
         .name(name)
         .key(name)
         .addInputStream("school_apply.bpmn20.xml",inputStream)
         .deploy();
   String deploymentId = deployment.getId();
   log.info("新文件部署成功:详情 == "+ JSON.toJSONString(deployment.toString()));
}
单元测试二 启动一个流程
@Test
public void testStartProcess() {
   // 1、创建ProcessEngine
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
   // 2、获取RunTimeService
   RuntimeService runtimeService = processEngine.getRuntimeService();
   // 3、根据流程定义的id启动流程
   //设置流程变量,流程变量可以用于设置审核人或者审核部门,或者通过变量判断网关从而控制流程走向
   Map<String,Object> map = new HashMap<>();
   map.put("cityBoardEduDept","10");
   ProcessInstance instance = runtimeService.startProcessInstanceByKey(key,"业务唯一编号",map);

   // 4、输出内容
   System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
   System.out.println("流程实例ID:" + instance.getId());
   System.out.println("当前活动的ID:" + instance.getActivityId());
   //流程定义ID:school_apply:5:76f2b410-dd67-11ec-82b8-52eb71925941
   //流程实例ID:df87517b-dd67-11ec-8a94-52eb71925941
   //建议启动一个流程后,业务侧也保存一下流程的定义id以及流程实例id
}
单元测试三 查询我的待办
@Test
public void testFindTaskListByProcessId() {
   // 1、获取流程引擎
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
   // 2、获取taskService
   TaskService taskService = processEngine.getTaskService();
   //根据候选组查询
   List<Task> taskList = taskService.createTaskQuery()
         .taskCandidateGroup("10").list();
   //根据候选人或者分配人去查询待办
   List<Task> taskList = taskService.createTaskQuery()
				.taskCandidateOrAssigned("1").list();
  }

tips: 业务侧可能会需要支持查询条件,并结合工作流数据返回用户当前待办,我在开发时候是这样的思路:

首先根据查询条件去分页查询业务数据库,查询出来的数据组合流程实例id集合,去工作流中过滤查询

单元测试四 处理我的待办
@Test
public void testTaskAssignCityBoardEdu(){
   // 1、获取流程引擎
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
   // 2、获取taskService
   TaskService taskService = processEngine.getTaskService();

   Task task = taskService.createTaskQuery().
         processInstanceId("b43e2736-e08f-11ec-92fa-fa163eb5b637")
         .taskCandidateOrAssigned("1")
         .singleResult();
   Map<String,Object> map = new HashMap<>();
   map.put("cityPass",1);
   map.put("areaBoardEduDeptUserIds","1");
   taskService.addComment(task.getId(),"b43e2736-e08f-11ec-92fa-fa163eb5b637","我这边审批就算过了");//添加审批备注
   taskService.claim(task.getId(),"1");//认领当前任务
   taskService.complete(task.getId(),map);//完成当前任务,并且设置task的环境变量,可以设置下一个task环境的审核人员id或者部门id
}
单元测试五 根据taskId获取审批备注comment
private String getCommentStrByTaskId(String id) {
   List<Comment> comments = taskService.getTaskComments(id);
   if(CollectionUtil.isNotEmpty(comments)){
      return comments.stream().map(t-				  >t.getFullMessage()).collect(Collectors.joining(";"));
   }
   }
单元测试六 根据taskId获取task的环境变量
HistoricVariableInstance nextDeptInstance = historyService.createHistoricVariableInstanceQuery().taskId(t.getId()).variableName("nextDept").singleResult();
String value =  (String)nextDeptInstance.getValue());