您的位置:首页 > 其它

Activiti学习——生成历史流程跟踪图

2016-07-13 11:41 211 查看

需求说明

流程在流转或者结束后,可以查看其流转历史流程图

效果图



实现思路

获取流程图

获取指定流程的流转环节

获取每个流转环节之间的线

根据流程图,环节,线绘制流转历史流程图

实现代码

@Controller
@RequestMapping(value = "/first")
public class FirstController {

@Autowired
RepositoryService repositoryService;
@Autowired
ManagementService managementService;
@Autowired
protected RuntimeService runtimeService;
@Autowired
ProcessEngineConfiguration processEngineConfiguration;
@Autowired
ProcessEngineFactoryBean processEngine;
@Autowired
HistoryService historyService;
@Autowired
TaskService taskService;

/**
* 读取带跟踪的图片
*/
@RequestMapping(value = "/test")
public void test(HttpServletResponse response) throws Exception {
// 部署流程,只要是符合BPMN2规范的XML文件,理论上都可以被ACTIVITI部署
repositoryService.createDeployment().addClasspathResource("com/pzr/demo/diagrams/MyProcess.bpmn").deploy();
// 开启流程,myprocess是流程的ID
System.out.println("流程【启动】,环节推动到【一次审批】环节");
runtimeService.startProcessInstanceByKey("myProcess");
// 查询历史表中的Task
List<Task> task = taskService.createTaskQuery().list();
Task task1 = task.get(task.size()-1);
//解开注释就推动到下一环节,对应的在流程图上看到
taskService.complete(task1.getId());
System.out.println("执行【一次审批】环节,流程推动到【二次审批】环节");
task1 = taskService.createTaskQuery().executionId(task1.getExecutionId()).singleResult();

//解开注释就推动到下一环节,对应的在流程图上看到
taskService.complete(task1.getId());
System.out.println("执行【二次审批】环节,流程推动到【结束】环节");

//processInstanceId
String processInstanceId = task1.getProcessInstanceId();
//获取历史流程实例
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<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
//高亮环节id集合
List<String> highLightedActivitis = new ArrayList<String>();
//高亮线路id集合
List<String> 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);
//单独返回流程图,不高亮显示
//        InputStream imageStream = diagramGenerator.generatePngDiagram(bpmnModel);
// 输出资源内容到相应对象
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<String> getHighLightedFlows(
ProcessDefinitionEntity processDefinitionEntity,
List<HistoricActivityInstance> historicActivityInstances) {
List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历
ActivityImpl activityImpl = processDefinitionEntity
.findActivity(historicActivityInstances.get(i)
.getActivityId());// 得到节点定义的详细信息
List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
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<PvmTransition> 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:8080/ActivitiDemo4/first/test


启动流程图



一次审批执行



二次审批执行



参考资料

http://blog.csdn.net/daisy_xiu/article/details/44343653
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息