工作流Acticity7

一、背景

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

二、如何画流程图

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

image.png

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

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

默认用户名:admin

默认密码:test

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


image.png

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());
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容