声明版本: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; }