使用Camunda流程引擎开发,产品提出根据流程节点筛选数据需求,...

在用Camunda流程引擎做业务开发,遇到了各种各样的需求,我扣掉了十根头发,看了很多的星星。今天产品经理不知道吃了什么大米,来到的的位置,说:周周同学,我发现了一个很棒的需求,你要不要听一听?
看着产品经理一脸坏笑,正要拒绝,产品经理继续说道:在流程列表页面,增加一个根据流程节点的筛选条件,这样用户查询的时候是不是更加精准了,我们的系统是不是又完美了很多。我刚要张嘴,产品经理电话响了,是客户的电话。我在一旁就听产品经理吧啦吧啦,大约10分钟过后。产品经理说:刚刚给客户介绍了这个需求,客户非常满意,你今天做好,明天测试,后天就更新到客户系统。说完拍拍我的肩膀,头也不回地走了。看着产品经理越来越小的背影,感觉脑后吹过一阵凉风。我是谁,我在哪里,我要做什么……经过一番思绪整理,不就是增加一个流程节点的列表接口吗?我做还不行嘛,就这样我又……思路整理:
- 根据流程实例ID,获取流程实例 根据流程实例ID,取到定义流程的XML
- 解析流程实例 把XML中的userTask节点解析
- 返回列表数据 把解析出来的节点信息(节点ID,节点名字)组装到LIST返给前端

翻看了 Camunda 源码,发现真的可以优化,接着有了下面的代码:
返回给前端的节点数据实体:
package com.bpm.camunda.vo;import lombok.Data;public class ActivityNodeVO {// 节点IDprivate String activityId;// 节点名字private String activityName;}
接口层:
public ResponseStatusDto> getActivityNodeList(String procId){
if(StringUtils.isBlank(procId)){return ResponseStatusDto.failure("流程实例ID不能为空");}return ResponseStatusDto.success(workflowTaskService.getActivityNodeList(procId));}
服务层:
public ListgetActivityNodeList(String procId) { ListactivityNodeVOList = new ArrayList<>(); if(StringUtils.isBlank(procId)){return activityNodeVOList;}HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();if(ObjectUtils.isEmpty(historicProcessInstance)){return activityNodeVOList;}BpmnModelInstance bpmnModelInstance = repositoryService.getBpmnModelInstance(historicProcessInstance.getProcessDefinitionId());if(ObjectUtils.isEmpty(bpmnModelInstance)){return activityNodeVOList;}ListdomElementList = bpmnModelInstance.getDocument().getRootElement().getChildElements(); if(ObjectUtils.isEmpty(domElementList)){return activityNodeVOList;}DomElement domElement = domElementList.stream().filter(it -> "process".equals(it.getLocalName())).findFirst().orElse(null);if(ObjectUtils.isEmpty(domElement)){return activityNodeVOList;}activityNodeVOList.addAll(ActivityNodeUtils.createActivityNodeBySubProcessElement(domElement));return activityNodeVOList;}
涉及到的工具类:
package com.bpm.utils;import com.bpm.camunda.vo.ActivityNodeVO;import org.camunda.bpm.engine.runtime.ActivityInstance;import org.camunda.bpm.model.xml.instance.DomElement;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;public class ActivityNodeUtils {protected static ActivityNodeVO createActivityNodeByTaskElement(DomElement e){ActivityNodeVO activityNodeVO = new ActivityNodeVO();activityNodeVO.setActivityId(e.getAttribute("id"));activityNodeVO.setActivityName(e.getAttribute("name"));return activityNodeVO;}protected static SetgetNodeByActivityInstance(ActivityInstance activityInstance) {if(activityInstance == null){return new HashSet<>();}SetactivityNodeVOSet = new HashSet<>(); ActivityNodeVO activityNodeVO = new ActivityNodeVO();activityNodeVO.setActivityId(activityInstance.getActivityId());activityNodeVO.setActivityName(activityInstance.getActivityName());activityNodeVOSet.add(activityNodeVO);if(ObjectUtils.isNotEmpty(activityInstance.getChildActivityInstances())){for (ActivityInstance instance : activityInstance.getChildActivityInstances()){getNodeByActivityInstance(instance);}}return activityNodeVOSet;}public static ListcreateActivityNodeBySubProcessElement(DomElement e) {ListactivityNodeVOList = new ArrayList<>(); e.getChildElements().stream().filter(it -> "userTask".equals(it.getLocalName()) || "subProcess".equals(it.getLocalName())).forEach(item ->{switch (item.getLocalName()){case "userTask":activityNodeVOList.add(createActivityNodeByTaskElement(item));break;case "subProcess":activityNodeVOList.addAll(createActivityNodeBySubProcessElement(item));break;}});return activityNodeVOList;}}
完成后,调用接口测试:

完成功能,下班回家。本来加班应该有点沮丧,但不知道为什么心里还是有点窃喜,可能这就是做为一名程序的快乐吧!
评论
