Activiti工作流实时显示步骤节点动态图

@RequestMapping(value = "/img/{procInsId}", method = RequestMethod.GET)
public void img(@PathVariable String procInsId, HttpServletResponse response) {
    try {
        String picName = "流程图";
        // 获取历史流程实例
        HistoricProcessInstance historicProcessInstance = historyService
                .createHistoricProcessInstanceQuery()
                .processInstanceId(procInsId).singleResult();
        // 获取流程中已经执行的节点,按照执行先后顺序排序
        List<HistoricActivityInstance> historicActivityInstances = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(procInsId)
                .orderByHistoricActivityInstanceId()
                .asc().list();

        // 高亮已经执行流程节点ID集合
        List<String> highLightedActivitiIds = new ArrayList<>();
        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
            highLightedActivitiIds.add(historicActivityInstance.getActivityId());
        }
        ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        // 高亮流程已发生流转的线id集合
        List<String> highLightedFlowIds = highLightedFlows(bpmnModel, historicActivityInstances);

        // 使用默认配置获得流程图表生成器,并生成追踪图片字符流
        InputStream imageStream = processDiagramGenerator.generateDiagram(bpmnModel, "png",
                highLightedActivitiIds, highLightedFlowIds, "宋体", "微软雅黑", "黑体", null, 1.0);

        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(picName, "UTF-8"));
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
        response.flushBuffer();
    } catch (Exception e) {
        log.error("[img] ######### 生成流程图失败 ########  异常:", e);
        throw new AudaqueException(e.getMessage());
    }

}

 

/**
 * 获取已经流转的线
 *
 * @param bpmnModel
 * @param historicActivityInstances
 * @return
 */
public static List<String> highLightedFlows(BpmnModel bpmnModel, List<HistoricActivityInstance> historicActivityInstances) {
    // 高亮流程已发生流转的线id集合
    List<String> highLightedFlowIds = new ArrayList<>();
    // 全部活动节点
    List<FlowNode> historicActivityNodes = new ArrayList<>();
    // 已完成的历史活动节点
    List<HistoricActivityInstance> finishedActivityInstances = new ArrayList<>();

    for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId());
        historicActivityNodes.add(flowNode);
        if (historicActivityInstance.getEndTime() != null) {
            finishedActivityInstances.add(historicActivityInstance);
        }
    }

    FlowNode currentFlowNode = null;
    FlowNode targetFlowNode = null;
    // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
    for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
        // 获得当前活动对应的节点信息及outgoingFlows信息
        currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId());
        List<SequenceFlow> sequenceFlows = currentFlowNode.getOutgoingFlows();

        /**
         * 遍历outgoingFlows并找到已已流转的 满足如下条件认为已已流转:
         * 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
         * 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
         */
        if ("parallelGateway".equals(currentActivityInstance.getActivityType())
                || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
            // 遍历历史活动节点,找到匹配流程目标节点的
            for (SequenceFlow sequenceFlow : sequenceFlows) {
                targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef());
                if (historicActivityNodes.contains(targetFlowNode)) {
                    highLightedFlowIds.add(targetFlowNode.getId());
                }
            }
        } else {
            List<Map<String, Object>> tempMapList = new ArrayList<>();
            for (SequenceFlow sequenceFlow : sequenceFlows) {
                for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
                    if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
                        Map<String, Object> map = new HashMap<>(16);
                        map.put("highLightedFlowId", sequenceFlow.getId());
                        map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
                        tempMapList.add(map);
                    }
                }
            }

            if (!CollectionUtils.isEmpty(tempMapList)) {
                // 遍历匹配的集合,取得开始时间最早的一个
                long earliestStamp = 0L;
                String highLightedFlowId = null;
                for (Map<String, Object> map : tempMapList) {
                    long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
                    if (earliestStamp == 0 || earliestStamp >= highLightedFlowStartTime) {
                        highLightedFlowId = map.get("highLightedFlowId").toString();
                        earliestStamp = highLightedFlowStartTime;
                    }
                }

                highLightedFlowIds.add(highLightedFlowId);
            }

        }

    }
    return highLightedFlowIds;
}

 

 

 

第二种方式 差不多

  /**
     * 读取流程资源
     */
    @RequestMapping(value = "trace/data/auto/{executionId}")
    public void readResource(@PathVariable("executionId") String executionId, HttpServletResponse response)
            throws Exception {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(executionId).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
        List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstance.getId());
        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
        //InputStream imageStream =diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds, highLightedFlows);
        String activityFontName=processEngineConfiguration.getActivityFontName();
        String labelFontName=processEngineConfiguration.getLabelFontName();
        InputStream imageStream =diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds, highLightedFlows,activityFontName,labelFontName,null, null, 1.0);

        // 输出资源内容到相应对象

    response.setContentType("application/octet-stream;charset=UTF-8");
        byte[] b = new byte[1024];
        int len;
        while ((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
        List<String> highLightedFlows = new ArrayList<String>();
        List<HistoricActivityInstance> historicActivityInstances = historyService
                .createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceStartTime().asc().list();

        List<String> historicActivityInstanceList = new ArrayList<String>();
        for (HistoricActivityInstance hai : historicActivityInstances) {
            historicActivityInstanceList.add(hai.getActivityId());
        }

        // add current activities to list
        List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
        historicActivityInstanceList.addAll(highLightedActivities);

        // activities and their sequence-flows
        for (ActivityImpl activity : processDefinition.getActivities()) {
            int index = historicActivityInstanceList.indexOf(activity.getId());

            if (index >= 0 && index + 1 < historicActivityInstanceList.size()) {
                List<PvmTransition> pvmTransitionList = activity
                        .getOutgoingTransitions();
                for (PvmTransition pvmTransition : pvmTransitionList) {
                    String destinationFlowId = pvmTransition.getDestination().getId();
                    if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1))) {
                        highLightedFlows.add(pvmTransition.getId());
                    }
                }
            }
        }
        return highLightedFlows;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值