更新到Activiti6.0.0 之後,發現pvm 包整個被删掉了。。。。這樣一來就導緻之前的跟蹤流失效了。代碼連編譯都通過不了。
因為pvm包沒了,是以就不能再使用ActivityImpl 等相關類了。隻能改成用org.activiti.bpmn.model包下的FlowNode類來替代。好在他們差不多,是以代碼改動也不大。下面是完整代碼:
/**
* @Author 葛明
* @Note 讀取流程資源
* @Date 2017-1-3 15:11
* @param processDefinitionId 流程定義ID
* @param resourceName 資源名稱
*/
@RequestMapping(value = "/read-resource")
public void readResource(String processDefinitionId, String resourceName,String pProcessInstanceId, HttpServletResponse response)
throws Exception {
// 設定頁面不緩存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
ProcessDefinition pd = pdq.processDefinitionId(processDefinitionId).singleResult();
if(resourceName.endsWith(".png") && StringUtils.isEmpty(pProcessInstanceId) == false)
{
getActivitiProccessImage(pProcessInstanceId,response);
//ProcessDiagramGenerator.generateDiagram(pde, "png", getRuntimeService().getActiveActivityIds(processInstanceId));
}
else
{
// 通過接口讀取
InputStream resourceAsStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
// 輸出資源内容到相應對象
byte[] b = new byte[1024];
int len = -1;
while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
response.getOutputStream().write(b, 0, len);
}
}
}
/**
* 擷取流程圖像,已執行節點和流程線高亮顯示
*/
public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response)
{
//logger.info("[開始]-擷取流程圖圖像");
try {
// 擷取曆史流程執行個體
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(pProcessInstanceId).singleResult();
if (historicProcessInstance == null) {
//throw new BusinessException("擷取流程執行個體ID[" + pProcessInstanceId + "]對應的曆史流程執行個體失敗!");
}
else
{
// 擷取流程定義
ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
.getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
// 擷取流程曆史中已執行節點,并按照節點在流程中執行先後順序排序
List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();
// 已執行的節點ID集合
List<String> executedActivityIdList = new ArrayList<String>();
int index = 1;
//logger.info("擷取已經執行的節點ID");
for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
executedActivityIdList.add(activityInstance.getActivityId());
//logger.info("第[" + index + "]個已執行節點=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
index++;
}
BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
// 已執行的線集合
List<String> flowIds = new ArrayList<String>();
// 擷取流程走過的線 (getHighLightedFlows是下面的方法)
flowIds = getHighLightedFlows(bpmnModel,processDefinition, historicActivityInstanceList);
// 擷取流程圖圖像字元流
ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
//配置字型
InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds,"宋體","微軟雅黑","黑體",null,2.0);
response.setContentType("image/png");
OutputStream os = response.getOutputStream();
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
imageStream.close();
}
//logger.info("[完成]-擷取流程圖圖像");
} catch (Exception e) {
System.out.println(e.getMessage());
//logger.error("【異常】-擷取流程圖失敗!" + e.getMessage());
//throw new BusinessException("擷取流程圖失敗!" + e.getMessage());
}
}
public List<String> getHighLightedFlows(BpmnModel bpmnModel,ProcessDefinitionEntity processDefinitionEntity,List<HistoricActivityInstance> historicActivityInstances)
{
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小時制
List<String> highFlows = new ArrayList<String>();// 用以儲存高亮的線flowId
for (int i = 0; i < historicActivityInstances.size() - 1; i++)
{
// 對曆史流程節點進行周遊
// 得到節點定義的詳細資訊
FlowNode activityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());
List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();// 用以儲存後續開始時間相同的節點
FlowNode sameActivityImpl1 = null;
HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);// 第一個節點
HistoricActivityInstance activityImp2_ ;
for(int k = i + 1 ; k <= historicActivityInstances.size() - 1; k++)
{
activityImp2_ = historicActivityInstances.get(k);// 後續第1個節點
if ( activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime())) ) //都是usertask,且主節點與後續節點的開始時間相同,說明不是真實的後繼節點
{
}
else
{
sameActivityImpl1 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());//找到緊跟在後面的一個節點
break;
}
}
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 (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime())) )
{// 如果第一個節點和第二個節點開始時間相同儲存
FlowNode sameActivityImpl2 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
sameStartTimeNodes.add(sameActivityImpl2);
}
else
{// 有不相同跳出循環
break;
}
}
List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows() ; // 取出節點的所有出去的線
for (SequenceFlow pvmTransition : pvmTransitions)
{// 對所有的線進行周遊
FlowNode pvmActivityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement( pvmTransition.getTargetRef());// 如果取出的線的目标節點存在時間相同的節點裡,儲存該線的id,進行高亮顯示
if (sameStartTimeNodes.contains(pvmActivityImpl)) {
highFlows.add(pvmTransition.getId());
}
}
}
return highFlows;
}