聲明版本:activiti 5.22.0 一、BPMN文件部署流程app
/** * 保存流程信息 * @param startType * @param file * @param projectId * @param processType * @param productId * @return * @throws IOException */ public String saveProcess(Integer startType, MultipartFile file, Long projectId, String processType, Long productId) throws IOException { String fileName = file.getOriginalFilename(); InputStream fileInputStream = file.getInputStream(); Deployment deployment = null; String extension = FilenameUtils.getExtension(fileName); try { if (extension.equals("zip") || extension.equals("bar")) { ZipInputStream zip = new ZipInputStream(fileInputStream); deployment = repositoryService.createDeployment().addZipInputStream(zip).deploy(); } else { deployment = repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy(); } } catch (XMLException e1) { throw new BizException("流程定義文件存在錯誤,請修改後從新部署!"); } //保存流程定義-項目配置表 processDefinitionProjectRelService.saveProcessDefinitionProject(deployment.getId(), startType, projectId, processType, productId); //保存流程定義-業務狀態配置表 processStatusService.saveOrUpdateBatch(projectId, deployment.getId()); return deployment.getId(); }
二、流程定義轉換爲模板code
public String convertToModel(Long projectId, String processDefinitionId) throws UnsupportedEncodingException, XMLStreamException { ProcessDefinitionVo processDefinition = getProcessDefinition(processDefinitionId); InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName()); XMLInputFactory xif = XMLInputFactory.newInstance(); InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8"); XMLStreamReader xtr = xif.createXMLStreamReader(in); BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr); BpmnJsonConverter converter = new BpmnJsonConverter(); ObjectNode modelNode = converter.convertToJson(bpmnModel); org.activiti.engine.repository.Model modelData = repositoryService.newModel(); modelData.setKey(processDefinition.getKey()); modelData.setName(processDefinition.getName()); modelData.setCategory(processDefinition.getDeploymentId()); modelData.setDeploymentId(processDefinition.getDeploymentId()); ObjectNode modelObjectNode = new ObjectMapper().createObjectNode(); modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName()); modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1); modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription()); modelData.setMetaInfo(modelObjectNode.toString()); repositoryService.saveModel(modelData); repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8")); // 保存項目-模板關聯關係 ModelProjectRel modelProjectRel = new ModelProjectRel(); modelProjectRel.setFkModelId(modelData.getId()); modelProjectRel.setFkProjectId(projectId); ProcdefProjectRel processDefinitionProjectRel = processDefinitionProjectRelService .findByProjectIdAndKey(projectId, processDefinition.getKey()); if (null != processDefinitionProjectRel) { modelProjectRel.setProcessType(processDefinitionProjectRel.getProcessType()); modelProjectRel.setFkProductId(processDefinitionProjectRel.getFkProductId()); } else { throw new BizException("未知流程類型"); } modelProjectRelService.save(modelProjectRel); return modelData.getId(); }
三、讀取流程定義的靜態流程圖對象
public void readProcessDefinitionResource(String processDefinitionId, String resourceType, HttpServletResponse response) throws IOException { ProcessDefinitionVo processDefinition = getProcessDefinition(processDefinitionId); String resourceName = ""; if (WorkflowConstants.READ_IMAGE.equals(resourceType)) { resourceName = processDefinition.getDiagramResourceName(); } else if (WorkflowConstants.READ_XML.equals(resourceType)) { resourceName = processDefinition.getResourceName(); } InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName); byte[] b = new byte[1024]; int len = -1; while ((len = resourceAsStream.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } }
四、讀取流程實例的動態流程圖ip
public void readProcessImg(String processInstanceId, HttpServletResponse response) throws IOException { if (StringUtils.isBlank(processInstanceId)) { logger.error("參數爲空"); } HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery() .processInstanceId(processInstanceId).singleResult(); BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService .getProcessDefinition(processInstance.getProcessDefinitionId()); List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().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); } CustomProcessDiagramGeneratorI diagramGenerator = (CustomProcessDiagramGeneratorI) processEngineConfiguration .getProcessDiagramGenerator(); InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis, highLightedFlows, "宋體", "宋體", "宋體", null, 1.0, new Color[] { new Color(0, 205, 0), Color.red }); // 輸出資源內容到相應對象 byte[] b = new byte[1024]; int len; while ((len = imageStream.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } }
其中,CustomProcessDiagramGeneratorI是筆者爲了自定義流程圖高亮顏色所實現的自定義類,若是讀者沒有這個需求,可用ProcessDiagramGenerator代替。 其中獲取高亮線的方法以下:utf-8
/** * 獲取須要高亮的線 * * @param processDefinitionEntity * @param historicActivityInstances * @return */ private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) { List<String> highFlows = new ArrayList<>();// 用以保存高亮的線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; }
五、獲取流程實例當前運行節點的入口連線資源
/** * 獲取流程當前節點前連線 * @param processInstanceId * @return */ public String getIncomingFlow(String processInstanceId) { String flowId = null; HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery() .processInstanceId(processInstanceId).singleResult(); ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity) repositoryService .getProcessDefinition(processInstance.getProcessDefinitionId()); List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list(); // 高亮線路id集合 List<String> highLightedFlows = getHighLightedFlows(definitionEntity, highLightedActivitList); if(CollectionUtils.isNotEmpty(highLightedFlows)) { flowId = highLightedFlows.get(highLightedFlows.size()-1); } return flowId; }