Activiti6.0流程图跟踪,标记已执行过的节点

需求是这样的,查询一个流程,图形化显示流程,并能标识当前流程的哪个节点

流程图:

Activiti6.0流程图跟踪,标记已执行过的节点_第1张图片

子流程:

Activiti6.0流程图跟踪,标记已执行过的节点_第2张图片

代码:

public class Main {
	
	private static final Logger log = LoggerFactory.getLogger(Main.class);
	
	public static void main(String[] args) {
		//创建流程引擎
		ProcessEngine processEngine = createProcessEngine();
		//部署流程文件
		ProcessDefinition processDefinition = deployProcessDefinition(processEngine);
		//启动流程
		ProcessInstance processInstance = startProcessInstance(processEngine,processDefinition);
		//处理任务
		//dealTask(processEngine,null);
		
		Task task = processEngine.getTaskService().createTaskQuery().singleResult();
		log.info("taskName:【{}】",task.getName());
		processEngine.getTaskService().complete(task.getId());
		
		InputStream image = generateProcessDiagram(processEngine,processInstance.getId());
		try {
			FileUtils.copyInputStreamToFile(image, new File("D:/d.png"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private static InputStream generateProcessDiagram(ProcessEngine processEngine, String processInstanceId) {
		// TODO Auto-generated method stub
		//获取历史流程实例
		HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService().createHistoricProcessInstanceQuery()
		.processInstanceId(processInstanceId).singleResult();
		log.info("历史流程id:【{}】",historicProcessInstance.getId());
		//获取历史流程定义
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) 
				processEngine.getRepositoryService()).getDeployedProcessDefinition(historicProcessInstance
						.getProcessDefinitionId());
		//查询历史节点
		List historicActivityInstanceList = processEngine.getHistoryService().createHistoricActivityInstanceQuery()
		.processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
		//已执行历史节点
		List executedActivityIdList = new ArrayList();
		historicActivityInstanceList.forEach(historicActivityInstance->{executedActivityIdList.add(historicActivityInstance.getActivityId());});
		
		BpmnModel bpmnModel = processEngine.getRepositoryService().getBpmnModel(processDefinitionEntity.getId());
		//已执行flow的集和
		List executedFlowIdList = executedFlowIdList(bpmnModel,processDefinitionEntity,historicActivityInstanceList);
		
		ProcessDiagramGenerator processDiagramGenerator = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
		InputStream diagram = processDiagramGenerator.generateDiagram(bpmnModel, "png", executedActivityIdList,executedFlowIdList, "黑体","黑体","黑体",null,1.0);
		
		return diagram;
	}

	private static List executedFlowIdList(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity,
			List historicActivityInstanceList) {
		
		List executedFlowIdList = new ArrayList<>();
		
	
		for(int i=0;i sequenceFlows = flowNode.getOutgoingFlows();
			if(sequenceFlows.size()>1) {
				HistoricActivityInstance nextHai = historicActivityInstanceList.get(i+1);
				sequenceFlows.forEach(sequenceFlow->{
					if(sequenceFlow.getTargetFlowElement().getId().equals(nextHai.getActivityId())) {
						executedFlowIdList.add(sequenceFlow.getId());
					}
				});
			}else {
				executedFlowIdList.add(sequenceFlows.get(0).getId());
			}
		}
		
		return executedFlowIdList;
	}

	private static void dealTask(ProcessEngine processEngine, ProcessInstance processInstance) {
		// TODO Auto-generated method stub
		while(processInstance!=null && !processInstance.isEnded()) {
			Execution currentExecution = processEngine.getRuntimeService().createExecutionQuery()
					.processInstanceId(processInstance.getId()).onlyProcessInstanceExecutions().singleResult();
			Task currentTask = processEngine.getTaskService().createTaskQuery().processInstanceId(currentExecution.getId())
			.singleResult();
			log.info("当前任务为:【】,完成任务",currentTask.getName());
			if("User Task-2".equals(currentTask.getName())) {
				break;
			}
			processEngine.getTaskService().complete(currentTask.getId());
		}
	}

	private static ProcessInstance startProcessInstance(ProcessEngine processEngine,
			ProcessDefinition processDefinition) {
		// TODO Auto-generated method stub
		ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinition.getKey());
		log.info("processInstanceId:【{}】",processInstance.getId());
		log.info("processDefinitionKey:【{}】",processInstance.getProcessDefinitionKey());
		return processInstance;
	}

	private static ProcessDefinition deployProcessDefinition(ProcessEngine processEngine) {
		// TODO Auto-generated method stub
		InputStream bpmn = Main.class.getResourceAsStream("MyProcess.bpmn");
		InputStream Png = Main.class.getResourceAsStream("MyProcess.png");
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Deployment deployment = repositoryService.createDeployment()
		.addInputStream("MyProcess.bpmn", bpmn)
		.addInputStream("MyProcess.png", Png).deploy();
		
		InputStream subBpmn = Main.class.getResourceAsStream("SubProcess.bpmn");
		InputStream subPng = Main.class.getResourceAsStream("SubProcess.png");
		repositoryService.createDeployment()
		.addInputStream("SubProcess.bpmn", subBpmn)
		.addInputStream("SubProcess.png", subPng).deploy();
		
		log.info("deploymentId:【{}】",deployment.getId());
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
		log.info("processDefinitionId:【{}】",processDefinition.getId());
		log.info("processDefinitionName:【{}】",processDefinition.getName());
		log.info("processDefinitionKey:【{}】",processDefinition.getKey());
		return processDefinition;
	}

	@SuppressWarnings("static-access")
	private static ProcessEngine createProcessEngine() {
		// TODO Auto-generated method stub
		ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        cfg.setJdbcDriver("com.mysql.jdbc.Driver");
        cfg.setJdbcUrl("jdbc:mysql://localhost:3306/activiti-test?useUnicode=true&characterEncoding=utf8");
        cfg.setJdbcUsername("root");
        cfg.setJdbcPassword("0118");
        cfg.setHistory(HistoryLevel.FULL.getKey());
        cfg.setDatabaseSchemaUpdate("true");
        ProcessEngine processEngine = cfg.buildProcessEngine();
        String name = processEngine.getName();
        String version = processEngine.VERSION;
        log.info("引擎名称:"+name+"  引擎版本:"+version);
		return processEngine;
	}

}

效果图:

Activiti6.0流程图跟踪,标记已执行过的节点_第3张图片

这里生成流程图主要用的到是DefaultProcessDiagramGenerator的generateDiagram方法:

Activiti6.0流程图跟踪,标记已执行过的节点_第4张图片

提供了一系列重载的方法,其中参数最多的一个:

public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, List highLightedFlows, 
      String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor);

参数:

bpmnModel:bpmnModel对象

imageType:生成的图像格式,我用的是png

highLightedActivities:要高亮显示的活动的节点

highLightedFlows:高亮显示的连线

activityFontName:activity字体,默认字体是Arial,如果你的流程图中使用了中文,那么会显示乱码

labelFontName:label字体,同时

annotationFontName:annotation字体,同上

customClassLoader:提供一个自定义类加载器来检索图标图像

scaleFactor:比例因子,试着改了一下,会改变连线箭头的大小,一般设置为1.0

DefaultProcessDiagramGenerator生成图片最后调用的是DefaultProcessDiagramCanvas类,这个类中定义了生成流程的的各种信息,可以进行跟多定制化的操作(官网给的方法并没有太多api去定制化流程图):

定制化流程图方法:

新建一个类MyProcessDiagramCanvas继承DefaultProcessDiagramCanvas:

public class MyProcessDiagramCanvas extends DefaultProcessDiagramCanvas{


	public MyProcessDiagramCanvas(int i, int j, int minX, int minY, String imageType, String activityFontName,
			String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
		// TODO Auto-generated constructor stub
		super(i, j, minX, minY, imageType,"黑体","黑体","黑体",customClassLoader);
		this.HIGHLIGHT_COLOR = Color.green;
	}
}

这里将字体和高亮的颜色修改了一下,接下来就是调用这个类了,但是通过观察DefaultProcessDiagramGenerator这个类,虽然提供了initProcessDiagramCanvas这个方法用来执行图片生成类,但是这个类是静态的,没法进行重写,所以没办法只好新建一个MyProcessDiagramGenerator类,实现ProcessDiagramGenerator接口,其他的部分原原本本的从DefaultProcessDiagramGenerator类拷贝,需要修改的部分initProcessDiagramCanvas方法:

return new MyProcessDiagramCanvas((int) maxX + 10,(int) maxY + 10, (int) minX, (int) minY, 
	        imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);

将返回值换成自己的图片生成类MyProcessDiagramCanvas

准备工作都做好后就是使用了:

ProcessEngineConfiguration cfg = processEngine.getProcessEngineConfiguration();
MyProcessDiagramGenerator processDiagramGenerator = new MyProcessDiagramGenerator();
cfg.setProcessDiagramGenerator(processDiagramGenerator);
ProcessDiagramGenerator processDiagramGenerator = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();

这样就可以对生成的流程图进行随意的改造了

 

你可能感兴趣的:(activiti,Java)