首頁>技術>

本篇內容:實時檢視當前流程進度。

HolidayService類中新增兩個方法:
/**	 *  <p>查詢歷史資訊</p>	 *  <p>時間:2021年1月24日-上午10:42:02</p>	 * @author baba	 * @param instanceId 例項ID	 * @return HistoricProcessInstance	 */	public HistoricProcessInstance queryHistory(String instanceId) {		return historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult() ;	}		/**	 *  <p>根據例項ID獲取歷史活動示例查詢器</p>	 *  <p>時間:2021年1月24日-上午10:45:46</p>	 * @author baba	 * @param instanceId 例項ID	 * @return HistoricActivityInstanceQuery	 */	public HistoricActivityInstanceQuery getHistoryActivity(String instanceId) {		return historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId) ; 	}
配置流程圖生成Bean
@Configurationpublic class ActivitiConfig {		@Bean	@ConditionalOnMissingBean	public ProcessDiagramGenerator processDiagramGenerator() {		return new DefaultProcessDiagramGenerator() ;	}	}
獲取各個節點資訊(執行過的)
public class ActivitiUtils {		/**	 *  <p>	 *  	獲取流程走過的線	 *  </p>	 *  <p>時間:2021年1月24日-上午10:52:01</p>	 * @author baba	 * @param bpmnModel 流程物件模型	 * @param processDefinitionEntity 流程定義物件	 * @param historicActivityInstances 歷史流程已經執行的節點,並已經按執行的先後順序排序	 * @return List<String> 流程走過的線	 */	public static List<String> getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {		// 用以儲存高亮的線flowId		List<String> highFlows = new ArrayList<String>();		if(historicActivityInstances == null || historicActivityInstances.size() == 0) return highFlows;		// 遍歷歷史節點		for (int i = 0; i < historicActivityInstances.size() - 1; i++) {			// 取出已執行的節點			HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);			// 用以儲存後續開始時間相同的節點			List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();			// 獲取下一個節點(用於連線)			FlowNode sameActivityImpl = getNextFlowNode(bpmnModel, historicActivityInstances, i, activityImpl_);			// 將後面第一個節點放在時間相同節點的集合裡			if(sameActivityImpl != null) sameStartTimeNodes.add(sameActivityImpl);			// 迴圈後面節點,看是否有與此後繼節點開始時間相同的節點,有則新增到後繼節點集合			for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {				HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 後續第一個節點				HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 後續第二個節點				if (activityImpl1.getStartTime().getTime() != activityImpl2.getStartTime().getTime()) break;								// 如果第一個節點和第二個節點開始時間相同儲存				FlowNode sameActivityImpl2 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());				sameStartTimeNodes.add(sameActivityImpl2);			}			// 得到節點定義的詳細資訊			FlowNode activityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());			// 取出節點的所有出去的線,對所有的線進行遍歷			List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows();			for (SequenceFlow pvmTransition : pvmTransitions) {				// 獲取節點				FlowNode pvmActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(pvmTransition.getTargetRef());				// 不是後繼節點				if(!sameStartTimeNodes.contains(pvmActivityImpl)) continue;				// 如果取出的線的目標節點存在時間相同的節點裡,儲存該線的id,進行高亮顯示				highFlows.add(pvmTransition.getId());			}		}		//返回高亮的線		return highFlows;	}	/**	 *  <p>	 *  	獲取下一個節點資訊	 *  </p>	 *  <p>時間:2021年1月24日-上午10:52:46</p>	 * @author baba	 * @param bpmnModel 流程模型	 * @param historicActivityInstances 歷史節點	 * @param i 當前已經遍歷到的歷史節點索引(找下一個節點從此節點後)	 * @param activityImpl_ 當前遍歷到的歷史節點例項	 * @return FlowNode 下一個節點資訊	 */	private static FlowNode getNextFlowNode(BpmnModel bpmnModel, List<HistoricActivityInstance> historicActivityInstances, int i, HistoricActivityInstance activityImpl_) {		// 儲存後一個節點		FlowNode sameActivityImpl = null;		// 如果當前節點不是使用者任務節點,則取排序的下一個節點為後續節點		if(!"userTask".equals(activityImpl_.getActivityType())) {			// 是最後一個節點,沒有下一個節點			if(i == historicActivityInstances.size()) return sameActivityImpl;			// 不是最後一個節點,取下一個節點為後繼節點			sameActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i + 1).getActivityId());// 找到緊跟在後面的一個節點			// 返回			return sameActivityImpl;		}		// 遍歷後續節點,獲取當前節點後續節點		for (int k = i + 1; k <= historicActivityInstances.size() - 1; k++) {			// 後續節點			HistoricActivityInstance activityImp2_ = historicActivityInstances.get(k);			// 都是userTask,且主節點與後續節點的開始時間相同,說明不是真實的後繼節點			if("userTask".equals(activityImp2_.getActivityType()) && activityImpl_.getStartTime().getTime() == activityImp2_.getStartTime().getTime()) continue;			// 找到緊跟在後面的一個節點			sameActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());			break;		}		return sameActivityImpl;	}}
測試Controller
@RestController@RequestMapping("/view")public class ProcessViewController {		private static Logger logger = LoggerFactory.getLogger(ProcessViewController.class) ; 		@Resource	private HolidayService holidayService ;	@Resource	private RepositoryService repositoryService ;	@Resource	private ProcessDiagramGenerator processDiagramGenerator ;		@ResponseBody	@GetMapping("/image")	public void showImg(String instanceId, HttpServletResponse response) throws Exception {		response.setContentType("text/html;charset=utf-8") ;		if (StringUtils.isEmpty(instanceId)) {			PrintWriter out = response.getWriter() ;			out.write("error") ;			out.close() ;			return ;		}		// 獲取流程例項		HistoricProcessInstance processInstance = holidayService.queryHistory(instanceId) ;		if(processInstance == null) {			logger.error("流程例項ID:{}沒查詢到流程例項!", instanceId);			PrintWriter out = response.getWriter() ;			out.write("error instance not exists") ;			out.close() ;			return;		}		// 根據流程物件獲取流程物件模型		BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());		// 構造歷史流程查詢		HistoricActivityInstanceQuery historyInstanceQuery = holidayService.getHistoryActivity(instanceId) ;		// 檢視已執行的節點集合,獲取流程歷史中已執行節點,並按照節點在流程中執行先後順序排序		List<HistoricActivityInstance> historicActivityInstanceList = historyInstanceQuery.orderByHistoricActivityInstanceStartTime().asc().list();		if(historicActivityInstanceList == null || historicActivityInstanceList.isEmpty()) {			logger.error("流程例項ID: {}, 沒有歷史節點資訊!", instanceId) ;			outputImg(response, bpmnModel, null, null) ;			return ;		}		// 已執行的節點ID集合(將historicActivityInstanceList中元素的activityId欄位取出封裝到executedActivityIdList)		List<String> executedActivityIdList = historicActivityInstanceList.stream().map(item -> item.getActivityId()).collect(Collectors.toList());		// 獲取流程定義		ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processInstance.getProcessDefinitionId());		List<String> flowIds = ActivitiUtils.getHighLightedFlows(bpmnModel, processDefinition, historicActivityInstanceList);		// 輸出影象,並設定高亮		outputImg(response, bpmnModel, flowIds, executedActivityIdList);	}	/**	 *  <p>	 *  	輸出影象	 *  </p>	 *  <p>時間:2021年1月24日-上午10:49:42</p>	 * @author baba	 * @param response	 * @param bpmnModel 影象物件	 * @param flowIds 已執行的線集合	 * @param executedActivityIdList 已執行的節點ID集合	 * @return void	 */	private void outputImg(HttpServletResponse response, BpmnModel bpmnModel, List<String> flowIds, List<String> executedActivityIdList) {		InputStream imageStream = null;		try {			imageStream = processDiagramGenerator.generateDiagram(bpmnModel, executedActivityIdList, flowIds, "宋體", "微軟雅黑", "黑體", true, "png");			// 輸出資源內容到相應物件			byte[] b = new byte[10 * 1024] ;			int len = -1 ;			while ((len = imageStream.read(b)) != -1) {				response.getOutputStream().write(b, 0, len);			}			response.getOutputStream().flush();		}catch(Exception e) {			logger.error("流程圖輸出異常!", e);		} finally {			if (imageStream != null) {				try {					imageStream.close() ;				} catch (IOException e) {					e.printStackTrace();				}			}		}	}	}

測試:

生成一個新的請假流程呼叫介面:/holidays/start?processDefinitionId=holiday:1:0a012ce6-5df2-11eb-afe9-00d861e5b732&userId=10000檢視當前使用者的任務列表(找出剛啟動流程的例項id)呼叫介面:/holidays/tasks?userId=10000檢視當前流程圖呼叫介面:/view/image?instanceId=341ee217-5df2-11eb-afe9-00d861e5b732繼續執行下一步流程呼叫介面:/holidays/apply?days=3&mgr=10001&explain=生病&instanceId=341ee217-5df2-11eb-afe9-00d861e5b732檢視當前流程圖呼叫介面:/view/image?instanceId=341ee217-5df2-11eb-afe9-00d861e5b732

到此完畢!!!

16
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 淺談專項測試之弱網路測試