Activiti学习——生成历史流程跟踪图

来源:互联网 发布:淘宝电子凭证是什么 编辑:程序博客网 时间:2024/05/19 06:15

需求说明

  1. 流程在流转或者结束后,可以查看其流转历史流程图
  2. 效果图

实现思路

  1. 获取流程图
  2. 获取指定流程的流转环节
  3. 获取每个流转环节之间的线
  4. 根据流程图,环节,线绘制流转历史流程图

实现代码

@Controller@RequestMapping(value = "/first")public class FirstController {    @Autowired    RepositoryService repositoryService;    @Autowired    ManagementService managementService;    @Autowired    protected RuntimeService runtimeService;    @Autowired    ProcessEngineConfiguration processEngineConfiguration;    @Autowired    ProcessEngineFactoryBean processEngine;    @Autowired    HistoryService historyService;    @Autowired    TaskService taskService;    /**     * 读取带跟踪的图片     */    @RequestMapping(value = "/test")    public void test(HttpServletResponse response) throws Exception {        // 部署流程,只要是符合BPMN2规范的XML文件,理论上都可以被ACTIVITI部署        repositoryService.createDeployment().addClasspathResource("com/pzr/demo/diagrams/MyProcess.bpmn").deploy();        // 开启流程,myprocess是流程的ID        System.out.println("流程【启动】,环节推动到【一次审批】环节");        runtimeService.startProcessInstanceByKey("myProcess");        // 查询历史表中的Task        List<Task> task = taskService.createTaskQuery().list();        Task task1 = task.get(task.size()-1);        //解开注释就推动到下一环节,对应的在流程图上看到        taskService.complete(task1.getId());        System.out.println("执行【一次审批】环节,流程推动到【二次审批】环节");        task1 = taskService.createTaskQuery().executionId(task1.getExecutionId()).singleResult();        //解开注释就推动到下一环节,对应的在流程图上看到        taskService.complete(task1.getId());        System.out.println("执行【二次审批】环节,流程推动到【结束】环节");        //processInstanceId        String processInstanceId = task1.getProcessInstanceId();        //获取历史流程实例        HistoricProcessInstance processInstance =  historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();        //获取流程图        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());        processEngineConfiguration = processEngine.getProcessEngineConfiguration();        Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();        ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());        List<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).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);        }        //中文显示的是口口口,设置字体就好了        InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis,highLightedFlows,"宋体","宋体",null,1.0);        //单独返回流程图,不高亮显示//        InputStream imageStream = diagramGenerator.generatePngDiagram(bpmnModel);        // 输出资源内容到相应对象        byte[] b = new byte[1024];        int len;        while ((len = imageStream.read(b, 0, 1024)) != -1) {            response.getOutputStream().write(b, 0, len);        }    }    /**     * 获取需要高亮的线     * @param processDefinitionEntity     * @param historicActivityInstances     * @return     */    private List<String> getHighLightedFlows(            ProcessDefinitionEntity processDefinitionEntity,            List<HistoricActivityInstance> historicActivityInstances) {        List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线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;    }

实现效果

浏览器地址栏输入

http://localhost:8080/ActivitiDemo4/first/test

启动流程图

一次审批执行

二次审批执行

参考资料

http://blog.csdn.net/daisy_xiu/article/details/44343653

0 0
原创粉丝点击