Activiti6.0.0 跟蹤流程執行情況用紅色框在流程圖上標識路線跟節點
阿新 • • 發佈:2019-01-01
升級到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; }