目录
前言:
功能(1) 高亮显示流程执行情况
功能(2) 挂起一个工作流实例
功能(3) 激活工作流实例
在这之前,小编写了俩篇文章,一个是Activiti是什么(入门篇) ,这个入门篇在19年底我就写了,我当时给过自己一个目标,一定要出一篇Activiti 工作流的文章,当时还没有完全把工作流吃透,20200327 我写了 Activiti 实战篇 ,我很开心,因为这是一篇完整的blog,这篇文章我想补充一些上篇文章没有说到的内容。
我懂得并非很多,但是我一直在学习的路上。
1.1 首先先画一个简单的流程图
1.2 生成一个工作流实例
/**
* 1.创建一个流程实例
*/
@GetMapping(value = "/createLeaveFlow")
public void createLeaveFlow() throws IOException {
//1.举个例子,soup_tang 需要请假 ,我在页面上添加请假申请,任务申请人是soup_tang,
// 我选择审核人为汤总,请汤总给我审核这个请假流程。
String checkPeople = "汤总";
activitiService.createLeaveWorkFlow(checkPeople);
}
@Override
public void createLeaveWorkFlow(String checkPeople) throws IOException {
//先判断这个流程文件有没有部署(只需部署一次)
Model modelData = repositoryService.getModel("1");
ObjectNode modelNode = (ObjectNode) new ObjectMapper()
.readTree(repositoryService.getModelEditorSource(modelData.getId()));
byte[] bpmnBytes = null;
BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
String processName = modelData.getName() + ".bpmn20.xml";
Deployment deployment = repositoryService.createDeployment()
.name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8"))
.deploy();
//获取流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
//启动流程定义,返回流程实例
Map map = new HashMap<>();
map.put("checkPeople",checkPeople);
ProcessInstance pi = runtimeService.startProcessInstanceById(processDefinition.getId(),map);
System.out.println("流程定义的ID:" + pi.getProcessDefinitionId());
System.out.println("流程实例的ID:" + pi.getId());
}
得到流程实例id
1.3 高亮图显示流程图执行状态
ActivitiController
@Autowired
private HistoryService historyService;
@Autowired
ProcessEngineConfiguration processEngineConfiguration;
@Autowired
ProcessEngineFactoryBean processEngine;
/**
* 查询流程实例 已高亮的形式流程执行状态
* @param response
* @throws Exception
*/
@GetMapping("/queryActivitiByProcessInstanceId")
public void queryProPlan(HttpServletResponse response) throws Exception {
//实例id
String processInstanceId = "10";
//获取历史流程实例
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
processEngineConfiguration = processEngine.getProcessEngineConfiguration();
Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);
ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
List highLightedActivitList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
//高亮环节id集合
List highLightedActivitis = new ArrayList();
//高亮线路id集合
List highLightedFlows = getHighLightedFlows(definitionEntity, highLightedActivitList);
for (HistoricActivityInstance tempActivity : highLightedActivitList) {
String activityId = tempActivity.getActivityId();
highLightedActivitis.add(activityId);
}
//中文显示的是口口口,设置字体就好了
InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis, highLightedFlows, "", "宋体", "宋体", null, 1.0);
//单独返回流程图,不高亮显示
byte[] b = new byte[1024];
int len;
while ((len = imageStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
}
/**
* 获取需要高亮的线
*
* @param processDefinitionEntity
* @param historicActivityInstances
* @return
*/
private List getHighLightedFlows(
ProcessDefinitionEntity processDefinitionEntity,
List historicActivityInstances) {
// 用以保存高亮的线flowId
List highFlows = new ArrayList();
// 对历史流程节点进行遍历
for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
ActivityImpl activityImpl = processDefinitionEntity
.findActivity(historicActivityInstances.get(i)
.getActivityId());// 得到节点定义的详细信息
// 用以保存后需开始时间相同的节点
List sameStartTimeNodes = new ArrayList();
ActivityImpl sameActivityImpl1 = processDefinitionEntity
.findActivity(historicActivityInstances.get(i + 1)
.getActivityId());
// 将后面第一个节点放在时间相同节点的集合里
sameStartTimeNodes.add(sameActivityImpl1);
for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
// 后续第一个节点
HistoricActivityInstance activityImpl1 = historicActivityInstances
.get(j);
// 后续第二个节点
HistoricActivityInstance activityImpl2 = historicActivityInstances
.get(j + 1);
if (activityImpl1.getStartTime().equals(
activityImpl2.getStartTime())) {
// 如果第一个节点和第二个节点开始时间相同保存
ActivityImpl sameActivityImpl2 = processDefinitionEntity
.findActivity(activityImpl2.getActivityId());
sameStartTimeNodes.add(sameActivityImpl2);
} else {
// 有不相同跳出循环
break;
}
}
List pvmTransitions = activityImpl
.getOutgoingTransitions();// 取出节点的所有出去的线
for (PvmTransition pvmTransition : pvmTransitions) {
// 对所有的线进行遍历
ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition
.getDestination();
// 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
if (sameStartTimeNodes.contains(pvmActivityImpl)) {
highFlows.add(pvmTransition.getId());
}
}
}
return highFlows;
}
在浏览上访问这个接口: http://localhost:8005/queryActivitiByProcessInstanceId
可以得到下面这张图,这张图也可以显示在页面上,这个就需要自己去定义了。
正常情况下 工作流实例会按照一定的规则执行完成,有时候需要中止流程,这个时候就可以用到 下面这俩个方法。
正常流程点击中止以后,流程会停止执行,只有激活流程,流程才会继续执行。
@Autowired
private RuntimeService runtimeService;
/**
* 挂起工作流
* @return
*/
@GetMapping(value = "/hangUpBusinessWorkFlow")
public void hangUpBusinessWorkFlow() {
//挂起一个流程
String processInstanceId = "10";
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(processInstance!=null) {
runtimeService.suspendProcessInstanceById(processInstanceId);
}
}
@Autowired
private RuntimeService runtimeService;
/**
* 激活工作流
*/
@GetMapping(value = "/activateBusinessWorkFlow")
public void activateBusinessWorkFlow() {
//激活一个流程
String processInstanceId = "10";
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(processInstance!=null) {
runtimeService.activateProcessInstanceById(processInstanceId);
}
}
这篇文章就到这里啦,如果觉得小编写的不错的话,不妨给小编一个赞喔,欢迎评论区交流留言,一起加油!