Activiti工作流查看流程視圖

思路

首先我們要知道Activiti工作流查看流程針對的是運行的實例, 可以看到流程流轉到那個節點。
但是大多數情況實例對業務來說是沒有意義的,那麼我就需要業務key,每個業務key對應工作流唯一的task任務。
有了這些想法我們就能構思查看流程視圖的接口了,入參肯定是業務能夠提供的,出參沒有疑問那就是圖片了,爲了方便我們直接返回圖片流InputStream

業務key轉換流程實例

  通過businessKey 查詢業務key對應的task任務
   List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).list();
  理論上來說業務businessKey也是唯一的,但是對Activiti來說只是某一列返回List,沒事我們直接加判斷,不唯一就異常出去。
   if(tasks != null && tasks.size() == 1){
      String taskId = tasks.get(0).getId();
      Task nowTask = taskService.createTaskQuery().taskId(taskId).singleResult();
       processInstanceId = nowTask.getProcessInstanceId();
       ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
       processDefinitionId = processInstance.getProcessDefinitionId();
    }else if (tasks != null && tasks.size() == 0){
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().finished().processInstanceBusinessKey(businessKey).list();
        if(list != null && list.size() == 1){
            processDefinitionId = list.get(0).getProcessDefinitionId();
            processInstanceId = list.get(0).getId();
        }
    }

有了思路不多說直接上代碼

public InputStream _$look_png(String businessKey) {
            logger.info("_$look_png---參數businessKey="+businessKey);
            InputStream inputStream= null;
            String processInstanceId = null;
            String processDefinitionId = null;
            try {
                List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).list();
                logger.info("_$look_png---任務tasks="+ tasks);
                if(tasks != null && tasks.size() == 1){
                    String taskId = tasks.get(0).getId();
                    Task nowTask = taskService.createTaskQuery().taskId(taskId).singleResult();
                    processInstanceId = nowTask.getProcessInstanceId();
                    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                    processDefinitionId = processInstance.getProcessDefinitionId();
                }else if (tasks != null && tasks.size() == 0){
                    List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().finished().processInstanceBusinessKey(businessKey).list();
                    if(list != null && list.size() == 1){
                        processDefinitionId = list.get(0).getProcessDefinitionId();
                        processInstanceId = list.get(0).getId();
                    }
                }

            if(StringUtils.isBlank(processInstanceId) || StringUtils.isBlank(processDefinitionId)){
                logger.info("_$look_png---異常,未找到或發現多個流程!businessKey="+businessKey);
                String result = "未找到或發現多個流程!businessKey="+businessKey;
                inputStream = new ByteArrayInputStream(result.getBytes());
                return inputStream;
            }
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            List<HistoricActivityInstance> activityInstances = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
            List<String> activityIds = new ArrayList<String>();
            List<String> flowIds = new ArrayList<String>();
            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
            //獲取流程走過的線
            flowIds = getHighLightedFlows(processDefinition, activityInstances);
            for (HistoricActivityInstance hai : activityInstances) {
                //獲取流程走過的節點
                activityIds.add(hai.getActivityId());
            }

            ImageIO.setCacheDirectory(new File(_PNG_PATH));
            inputStream = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator().generateDiagram(bpmnModel, "png", activityIds, flowIds,"宋體", "宋體", "宋體", null, 1.0);

        }catch (Exception e){
            e.printStackTrace();
            logger.error("_$look_png---異常:", e);
        }

        return inputStream;
    }

這裏有個注意的地方, linux注意安裝字體
linux 安裝字體
yum install -y fontconfig mkfontscale
將 宋體 丟入/usr/share/fonts/
建立字體索引信息,更新字體緩存,使用如下命令:
mkfontscale
mkfontdir
fc-cache
查看安裝字體fc-list,重啓服務

//獲取流程走過的線
    public static List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity,List<HistoricActivityInstance> haiList) throws Exception{
        //用來保存高亮的線 flowId
        List<String> highFlows = new ArrayList<String>();
        for (int i = 0; i < haiList.size() - 1; i++) {
            //對歷史流程節點進行遍歷
            //得到節點定義的詳細信息
            ActivityImpl activityImpl = processDefinitionEntity.findActivity(haiList.get(i).getActivityId());
            //用以保存後需要開始時間相同的節點
            List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();
            ActivityImpl sameActivityImpl1 = processDefinitionEntity.findActivity(haiList.get(i + 1).getActivityId());
            //講後面第一個節點放在時間相同節點的集合裏
            sameStartTimeNodes.add(sameActivityImpl1);
            for (int j = i + 1; j < haiList.size() - 1; j++) {
                HistoricActivityInstance activityImpl1 = haiList.get(j);//後續第一個節點
                HistoricActivityInstance activityImpl2 = haiList.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;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章