Kaynağa Gözat

解决图片渲染bug

赵冬冬 3 yıl önce
ebeveyn
işleme
7398983422

+ 290 - 290
src/main/java/com/activiti6/controller/image/LeaveNewController.java

@@ -1,290 +1,290 @@
-package com.activiti6.controller.image;
-
-
-import com.activiti6.controller.ModelerController;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.activiti.bpmn.model.BpmnModel;
-import org.activiti.bpmn.model.FlowNode;
-import org.activiti.bpmn.model.SequenceFlow;
-import org.activiti.engine.HistoryService;
-import org.activiti.engine.ProcessEngine;
-import org.activiti.engine.RepositoryService;
-import org.activiti.engine.RuntimeService;
-import org.activiti.engine.history.HistoricActivityInstance;
-import org.activiti.engine.history.HistoricProcessInstance;
-import org.activiti.engine.impl.RepositoryServiceImpl;
-import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
-import org.activiti.engine.repository.ProcessDefinition;
-import org.activiti.engine.repository.ProcessDefinitionQuery;
-import org.activiti.engine.runtime.ProcessInstance;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.stream.Collectors;
-
-
-/**
- * 请假业务Controller
- *
- * @author Xianlu Tech
- * @date 2019-10-11
- */
-@RestController
-@RequestMapping("/activiti")
-public class LeaveNewController {
-
-    private static final Logger logger = LoggerFactory.getLogger(LeaveNewController.class);
-
-    @Autowired
-    private HistoryService historyService;
-
-    @Autowired
-    private RepositoryService repositoryService;
-
-    protected ObjectMapper objectMapper = new ObjectMapper();
-
-    @Autowired
-    private RuntimeService runtimeService;
-
-    @RequestMapping(value = "/process-instance/{processInstanceId}/highlights")
-    public ObjectNode readResource(@PathVariable String processInstanceId)
-            throws Exception {
-        // 设置页面不缓存
-        return showImage(processInstanceId);
-    }
-
-    private ObjectNode showImage(String processInstanceId) throws IOException {
-
-        ObjectNode responseJSON = objectMapper.createObjectNode();
-
-        responseJSON.put("processInstanceId", processInstanceId);
-
-        ArrayNode activitiesArray = objectMapper.createArrayNode();
-        ArrayNode flowsArray = objectMapper.createArrayNode();
-
-        try {
-            //  获取历史流程实例
-            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
-                    .processInstanceId(processInstanceId).singleResult();
-            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
-            responseJSON.put("processDefinitionId", historicProcessInstance.getProcessDefinitionId());
-            // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
-            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
-                    .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
-            // 已执行的节点ID集合
-            List<String> highLightedActivities = new ArrayList<String>();
-            //logger.info("获取已经执行的节点ID");
-            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
-                highLightedActivities.add(activityInstance.getActivityId());
-            }
-            // 已执行的线集合
-            List<String> flowIds = new ArrayList<>();
-            // 获取流程走过的线 (getHighLightedFlows是下面的方法)
-            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
-
-            List<String> highLightedFlows = executedFlowIdList(bpmnModel, processDefinition, historicActivityInstanceList);
-
-            for (String activityId : highLightedActivities) {
-                activitiesArray.add(activityId);
-            }
-
-            for (String flow : highLightedFlows) {
-                flowsArray.add(flow);
-            }
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        responseJSON.put("activities", activitiesArray);
-        responseJSON.put("flows", flowsArray);
-
-        return responseJSON;
-    }
-
-    private void image(String processInstanceId) {
-        //logger.info("[开始]-获取流程图图像");
-        try {
-            //  获取历史流程实例
-            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
-                    .processInstanceId(processInstanceId).singleResult();
-
-            if (historicProcessInstance == null) {
-                //throw new BusinessException("获取流程实例ID[" + processInstanceId + "]对应的历史流程实例失败!");
-            } else {
-                // 获取流程定义
-                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
-                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
-
-                // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
-                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
-                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
-                // 已执行的节点ID集合
-                List<String> executedActivityIdList = new ArrayList<String>();
-                //logger.info("获取已经执行的节点ID");
-                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
-                    executedActivityIdList.add(activityInstance.getActivityId());
-                }
-                BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
-
-                // 已执行的线集合
-                List<String> flowIds = new ArrayList<>();
-                // 获取流程走过的线 (getHighLightedFlows是下面的方法)
-                flowIds = executedFlowIdList(bpmnModel, processDefinition, historicActivityInstanceList);
-
-            }
-            //logger.info("[完成]-获取流程图图像");
-        } catch (Exception e) {
-            e.printStackTrace();
-            logger.error("【异常】-获取流程图失败!" + e.getMessage());
-            throw new RuntimeException("获取流程图失败!" + e.getMessage());
-        }
-    }
-
-
-    private static List<String> executedFlowIdList(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity,
-                                                   List<HistoricActivityInstance> historicActivityInstanceList) {
-
-        List<String> executedFlowIdList = new ArrayList<>();
-        Set<String> ids = new HashSet<>();
-        Map<String, SequenceFlow> flowHashMap = new HashMap<>();
-        List<String> activityIds = historicActivityInstanceList.stream().map(X -> X.getActivityId()).collect(Collectors.toList());
-        for (int i = 0; i < historicActivityInstanceList.size(); i++) {
-            HistoricActivityInstance hai = historicActivityInstanceList.get(i);
-            String activityId = hai.getActivityId();
-            FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId);
-            List<SequenceFlow> sequenceFlows = flowNode.getOutgoingFlows();
-            for (SequenceFlow sequenceFlow : sequenceFlows) {
-                String sourceRef = sequenceFlow.getSourceRef();
-                String targetRef = sequenceFlow.getTargetRef();
-                flowHashMap.put(targetRef, sequenceFlow);
-            }
-        }
-        for (String activityId : activityIds) {
-            for (String s : flowHashMap.keySet()) {
-                if (s.contains(activityId)) {
-                    SequenceFlow sequenceFlow = flowHashMap.get(s);
-                    ids.add(sequenceFlow.getId());
-                }
-            }
-        }
-        executedFlowIdList.addAll(ids);
-        return executedFlowIdList;
-    }
-
-
-    /**
-     * 获取流程图像,已执行节点和流程线高亮显示
-     */
-    public void getActivitiProccessImage(String processInstanceId, HttpServletResponse response) {
-        //logger.info("[开始]-获取流程图图像");
-        try {
-            //  获取历史流程实例
-            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
-                    .processInstanceId(processInstanceId).singleResult();
-
-            if (historicProcessInstance == null) {
-                //throw new BusinessException("获取流程实例ID[" + processInstanceId + "]对应的历史流程实例失败!");
-            } else {
-                // 获取流程定义
-                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
-                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
-
-                // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
-                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
-                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
-
-                // 已执行的节点ID集合
-                List<String> executedActivityIdList = new ArrayList<String>();
-                int index = 1;
-                //logger.info("获取已经执行的节点ID");
-                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
-                    executedActivityIdList.add(activityInstance.getActivityId());
-
-                    //logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
-                    index++;
-                }
-
-                BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
-
-                // 已执行的线集合
-                List<String> flowIds = new ArrayList<String>();
-                // 获取流程走过的线 (getHighLightedFlows是下面的方法)
-                flowIds = getHighLightedFlows(bpmnModel, processDefinition, historicActivityInstanceList);
-
-            }
-            //logger.info("[完成]-获取流程图图像");
-        } catch (Exception e) {
-            System.out.println(e.getMessage());
-            //logger.error("【异常】-获取流程图失败!" + e.getMessage());
-            //throw new BusinessException("获取流程图失败!" + e.getMessage());
-        }
-    }
-
-    public List<String> getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {
-        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小时制
-        List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
-
-        for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
-            // 对历史流程节点进行遍历
-            // 得到节点定义的详细信息
-            FlowNode activityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());
-
-
-            List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();// 用以保存后续开始时间相同的节点
-            FlowNode sameActivityImpl1 = null;
-
-            HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);// 第一个节点
-            HistoricActivityInstance activityImp2_;
-
-            for (int k = i + 1; k <= historicActivityInstances.size() - 1; k++) {
-                activityImp2_ = historicActivityInstances.get(k);// 后续第1个节点
-
-                if (activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
-                        df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime()))) //都是usertask,且主节点与后续节点的开始时间相同,说明不是真实的后继节点
-                {
-
-                } else {
-                    sameActivityImpl1 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());//找到紧跟在后面的一个节点
-                    break;
-                }
-
-            }
-            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 (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime()))) {// 如果第一个节点和第二个节点开始时间相同保存
-                    FlowNode sameActivityImpl2 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
-                    sameStartTimeNodes.add(sameActivityImpl2);
-                } else {// 有不相同跳出循环
-                    break;
-                }
-            }
-            List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows(); // 取出节点的所有出去的线
-
-            for (SequenceFlow pvmTransition : pvmTransitions) {// 对所有的线进行遍历
-                FlowNode pvmActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(pvmTransition.getTargetRef());// 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
-                if (sameStartTimeNodes.contains(pvmActivityImpl)) {
-                    highFlows.add(pvmTransition.getId());
-                }
-            }
-
-        }
-        return highFlows;
-
-    }
-
-}
+//package com.activiti6.controller.image;
+//
+//
+//import com.activiti6.controller.ModelerController;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fasterxml.jackson.databind.node.ArrayNode;
+//import com.fasterxml.jackson.databind.node.ObjectNode;
+//import org.activiti.bpmn.model.BpmnModel;
+//import org.activiti.bpmn.model.FlowNode;
+//import org.activiti.bpmn.model.SequenceFlow;
+//import org.activiti.engine.HistoryService;
+//import org.activiti.engine.ProcessEngine;
+//import org.activiti.engine.RepositoryService;
+//import org.activiti.engine.RuntimeService;
+//import org.activiti.engine.history.HistoricActivityInstance;
+//import org.activiti.engine.history.HistoricProcessInstance;
+//import org.activiti.engine.impl.RepositoryServiceImpl;
+//import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+//import org.activiti.engine.repository.ProcessDefinition;
+//import org.activiti.engine.repository.ProcessDefinitionQuery;
+//import org.activiti.engine.runtime.ProcessInstance;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.PathVariable;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RequestParam;
+//import org.springframework.web.bind.annotation.RestController;
+//
+//import javax.servlet.http.HttpServletResponse;
+//import java.io.IOException;
+//import java.text.SimpleDateFormat;
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+//
+///**
+// * 请假业务Controller
+// *
+// * @author Xianlu Tech
+// * @date 2019-10-11
+// */
+//@RestController
+//@RequestMapping("/activiti")
+//public class LeaveNewController {
+//
+//    private static final Logger logger = LoggerFactory.getLogger(LeaveNewController.class);
+//
+//    @Autowired
+//    private HistoryService historyService;
+//
+//    @Autowired
+//    private RepositoryService repositoryService;
+//
+//    protected ObjectMapper objectMapper = new ObjectMapper();
+//
+//    @Autowired
+//    private RuntimeService runtimeService;
+//
+//    @RequestMapping(value = "/process-instance/{processInstanceId}/highlights")
+//    public ObjectNode readResource(@PathVariable String processInstanceId)
+//            throws Exception {
+//        // 设置页面不缓存
+//        return showImage(processInstanceId);
+//    }
+//
+//    private ObjectNode showImage(String processInstanceId) throws IOException {
+//
+//        ObjectNode responseJSON = objectMapper.createObjectNode();
+//
+//        responseJSON.put("processInstanceId", processInstanceId);
+//
+//        ArrayNode activitiesArray = objectMapper.createArrayNode();
+//        ArrayNode flowsArray = objectMapper.createArrayNode();
+//
+//        try {
+//            //  获取历史流程实例
+//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+//                    .processInstanceId(processInstanceId).singleResult();
+//            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
+//            responseJSON.put("processDefinitionId", historicProcessInstance.getProcessDefinitionId());
+//            // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
+//            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
+//                    .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
+//            // 已执行的节点ID集合
+//            List<String> highLightedActivities = new ArrayList<String>();
+//            //logger.info("获取已经执行的节点ID");
+//            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
+//                highLightedActivities.add(activityInstance.getActivityId());
+//            }
+//            // 已执行的线集合
+//            List<String> flowIds = new ArrayList<>();
+//            // 获取流程走过的线 (getHighLightedFlows是下面的方法)
+//            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
+//
+//            List<String> highLightedFlows = executedFlowIdList(bpmnModel, processDefinition, historicActivityInstanceList);
+//
+//            for (String activityId : highLightedActivities) {
+//                activitiesArray.add(activityId);
+//            }
+//
+//            for (String flow : highLightedFlows) {
+//                flowsArray.add(flow);
+//            }
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//
+//        responseJSON.put("activities", activitiesArray);
+//        responseJSON.put("flows", flowsArray);
+//
+//        return responseJSON;
+//    }
+//
+//    private void image(String processInstanceId) {
+//        //logger.info("[开始]-获取流程图图像");
+//        try {
+//            //  获取历史流程实例
+//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+//                    .processInstanceId(processInstanceId).singleResult();
+//
+//            if (historicProcessInstance == null) {
+//                //throw new BusinessException("获取流程实例ID[" + processInstanceId + "]对应的历史流程实例失败!");
+//            } else {
+//                // 获取流程定义
+//                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
+//                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
+//
+//                // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
+//                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
+//                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
+//                // 已执行的节点ID集合
+//                List<String> executedActivityIdList = new ArrayList<String>();
+//                //logger.info("获取已经执行的节点ID");
+//                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
+//                    executedActivityIdList.add(activityInstance.getActivityId());
+//                }
+//                BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
+//
+//                // 已执行的线集合
+//                List<String> flowIds = new ArrayList<>();
+//                // 获取流程走过的线 (getHighLightedFlows是下面的方法)
+//                flowIds = executedFlowIdList(bpmnModel, processDefinition, historicActivityInstanceList);
+//
+//            }
+//            //logger.info("[完成]-获取流程图图像");
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            logger.error("【异常】-获取流程图失败!" + e.getMessage());
+//            throw new RuntimeException("获取流程图失败!" + e.getMessage());
+//        }
+//    }
+//
+//
+//    private static List<String> executedFlowIdList(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity,
+//                                                   List<HistoricActivityInstance> historicActivityInstanceList) {
+//
+//        List<String> executedFlowIdList = new ArrayList<>();
+//        Set<String> ids = new HashSet<>();
+//        Map<String, SequenceFlow> flowHashMap = new HashMap<>();
+//        List<String> activityIds = historicActivityInstanceList.stream().map(X -> X.getActivityId()).collect(Collectors.toList());
+//        for (int i = 0; i < historicActivityInstanceList.size(); i++) {
+//            HistoricActivityInstance hai = historicActivityInstanceList.get(i);
+//            String activityId = hai.getActivityId();
+//            FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId);
+//            List<SequenceFlow> sequenceFlows = flowNode.getOutgoingFlows();
+//            for (SequenceFlow sequenceFlow : sequenceFlows) {
+//                String sourceRef = sequenceFlow.getSourceRef();
+//                String targetRef = sequenceFlow.getTargetRef();
+//                flowHashMap.put(targetRef, sequenceFlow);
+//            }
+//        }
+//        for (String activityId : activityIds) {
+//            for (String s : flowHashMap.keySet()) {
+//                if (s.contains(activityId)) {
+//                    SequenceFlow sequenceFlow = flowHashMap.get(s);
+//                    ids.add(sequenceFlow.getId());
+//                }
+//            }
+//        }
+//        executedFlowIdList.addAll(ids);
+//        return executedFlowIdList;
+//    }
+//
+//
+//    /**
+//     * 获取流程图像,已执行节点和流程线高亮显示
+//     */
+//    public void getActivitiProccessImage(String processInstanceId, HttpServletResponse response) {
+//        //logger.info("[开始]-获取流程图图像");
+//        try {
+//            //  获取历史流程实例
+//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+//                    .processInstanceId(processInstanceId).singleResult();
+//
+//            if (historicProcessInstance == null) {
+//                //throw new BusinessException("获取流程实例ID[" + processInstanceId + "]对应的历史流程实例失败!");
+//            } else {
+//                // 获取流程定义
+//                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
+//                        .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
+//
+//                // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
+//                List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
+//                        .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
+//
+//                // 已执行的节点ID集合
+//                List<String> executedActivityIdList = new ArrayList<String>();
+//                int index = 1;
+//                //logger.info("获取已经执行的节点ID");
+//                for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
+//                    executedActivityIdList.add(activityInstance.getActivityId());
+//
+//                    //logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
+//                    index++;
+//                }
+//
+//                BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
+//
+//                // 已执行的线集合
+//                List<String> flowIds = new ArrayList<String>();
+//                // 获取流程走过的线 (getHighLightedFlows是下面的方法)
+//                flowIds = getHighLightedFlows(bpmnModel, processDefinition, historicActivityInstanceList);
+//
+//            }
+//            //logger.info("[完成]-获取流程图图像");
+//        } catch (Exception e) {
+//            System.out.println(e.getMessage());
+//            //logger.error("【异常】-获取流程图失败!" + e.getMessage());
+//            //throw new BusinessException("获取流程图失败!" + e.getMessage());
+//        }
+//    }
+//
+//    public List<String> getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {
+//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小时制
+//        List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
+//
+//        for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
+//            // 对历史流程节点进行遍历
+//            // 得到节点定义的详细信息
+//            FlowNode activityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());
+//
+//
+//            List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();// 用以保存后续开始时间相同的节点
+//            FlowNode sameActivityImpl1 = null;
+//
+//            HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);// 第一个节点
+//            HistoricActivityInstance activityImp2_;
+//
+//            for (int k = i + 1; k <= historicActivityInstances.size() - 1; k++) {
+//                activityImp2_ = historicActivityInstances.get(k);// 后续第1个节点
+//
+//                if (activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
+//                        df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime()))) //都是usertask,且主节点与后续节点的开始时间相同,说明不是真实的后继节点
+//                {
+//
+//                } else {
+//                    sameActivityImpl1 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());//找到紧跟在后面的一个节点
+//                    break;
+//                }
+//
+//            }
+//            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 (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime()))) {// 如果第一个节点和第二个节点开始时间相同保存
+//                    FlowNode sameActivityImpl2 = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
+//                    sameStartTimeNodes.add(sameActivityImpl2);
+//                } else {// 有不相同跳出循环
+//                    break;
+//                }
+//            }
+//            List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows(); // 取出节点的所有出去的线
+//
+//            for (SequenceFlow pvmTransition : pvmTransitions) {// 对所有的线进行遍历
+//                FlowNode pvmActivityImpl = (FlowNode) bpmnModel.getMainProcess().getFlowElement(pvmTransition.getTargetRef());// 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
+//                if (sameStartTimeNodes.contains(pvmActivityImpl)) {
+//                    highFlows.add(pvmTransition.getId());
+//                }
+//            }
+//
+//        }
+//        return highFlows;
+//
+//    }
+//
+//}

+ 225 - 217
src/main/java/com/activiti6/controller/image/MyProcessInstanceHighlightsResource.java

@@ -24,221 +24,229 @@ import java.util.*;
 @RequestMapping("/activiti")
 public class MyProcessInstanceHighlightsResource {
 
-//    @Autowired
-//    private RuntimeService runtimeService;
-//
-//    @Autowired
-//    private RepositoryService repositoryService;
-//
-//    @Autowired
-//    private HistoryService historyService;
-//
-//    protected ObjectMapper objectMapper = new ObjectMapper();
-//
-//    @RequestMapping(value = "/process-instance/{processInstanceId}/highlights", method = RequestMethod.GET, produces = "application/json")
-//    public ObjectNode getHighlighted(@PathVariable String processInstanceId) {
-//
-//        ObjectNode responseJSON = objectMapper.createObjectNode();
-//
-//        responseJSON.put("processInstanceId", processInstanceId);
-//
-//        ArrayNode activitiesArray = objectMapper.createArrayNode();
-//        ArrayNode flowsArray = objectMapper.createArrayNode();
-//
-//        try {
-//            //  获取历史流程实例
-//            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
-//                    .processInstanceId(processInstanceId).singleResult();
-//            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
-//            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
-//
-//            responseJSON.put("processDefinitionId", processInstance.getProcessDefinitionId());
-//
-//            List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
-//            List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstanceId);
-//
-//            for (String activityId : highLightedActivities) {
-//                activitiesArray.add(activityId);
-//            }
-//
-//            for (String flow : highLightedFlows) {
-//                flowsArray.add(flow);
-//            }
-//
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//        }
-//
-//        responseJSON.put("activities", activitiesArray);
-//        responseJSON.put("flows", flowsArray);
-//
-//        return responseJSON;
-//    }
-//
-//
-//    /**
-//     * getHighLightedFlows
-//     *
-//     * @param processDefinition
-//     * @param processInstanceId
-//     * @return
-//     */
-//    private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
-//
-//        List<String> highLightedFlows = new ArrayList<String>();
-//
-//        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
-//                .processInstanceId(processInstanceId)
-//                //order by startime asc is not correct. use default order is correct.
-//                //.orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
-//                .list();
-//
-//        LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
-//        hisActInstList.addAll(historicActivityInstances);
-//
-//        getHighlightedFlows(processDefinition.getActivities(), hisActInstList, highLightedFlows);
-//
-//        return highLightedFlows;
-//    }
-//
-//    /**
-//     * getHighlightedFlows
-//     * <p>
-//     * code logic:
-//     * 1. Loop all activities by id asc order;
-//     * 2. Check each activity's outgoing transitions and eventBoundery outgoing transitions, if outgoing transitions's destination.id is in other executed activityIds, add this transition to highLightedFlows List;
-//     * 3. But if activity is not a parallelGateway or inclusiveGateway, only choose the earliest flow.
-//     *
-//     * @param activityList
-//     * @param hisActInstList
-//     * @param highLightedFlows
-//     */
-//    private void getHighlightedFlows(List<ActivityImpl> activityList, LinkedList<HistoricActivityInstance> hisActInstList, List<String> highLightedFlows) {
-//
-//        //check out startEvents in activityList
-//        List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
-//        Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(activityList.size());
-//        for (ActivityImpl activity : activityList) {
-//
-//            activityMap.put(activity.getId(), activity);
-//
-//            String actType = (String) activity.getProperty("type");
-//            if (actType != null && actType.toLowerCase().indexOf("startevent") >= 0) {
-//                startEventActList.add(activity);
-//            }
-//        }
-//
-//        //These codes is used to avoid a bug:
-//        //ACT-1728 If the process instance was started by a callActivity, it will be not have the startEvent activity in ACT_HI_ACTINST table
-//        //Code logic:
-//        //Check the first activity if it is a startEvent, if not check out the startEvent's highlight outgoing flow.
-//        HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
-//        String firstActType = (String) firstHistActInst.getActivityType();
-//        if (firstActType != null && firstActType.toLowerCase().indexOf("startevent") < 0) {
-//            PvmTransition startTrans = getStartTransaction(startEventActList, firstHistActInst);
-//            if (startTrans != null) {
-//                highLightedFlows.add(startTrans.getId());
-//            }
-//        }
-//
-//        while (!hisActInstList.isEmpty()) {
-//            HistoricActivityInstance histActInst = hisActInstList.removeFirst();
-//            ActivityImpl activity = activityMap.get(histActInst.getActivityId());
-//            if (activity != null) {
-//                boolean isParallel = false;
-//                String type = histActInst.getActivityType();
-//                if ("parallelGateway".equals(type) || "inclusiveGateway".equals(type)) {
-//                    isParallel = true;
-//                } else if ("subProcess".equals(histActInst.getActivityType())) {
-//                    getHighlightedFlows(activity.getActivities(), hisActInstList, highLightedFlows);
-//                }
-//
-//                List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
-//                allOutgoingTrans.addAll(activity.getOutgoingTransitions());
-//                allOutgoingTrans.addAll(getBoundaryEventOutgoingTransitions(activity));
-//                List<String> activityHighLightedFlowIds = getHighlightedFlows(allOutgoingTrans, hisActInstList, isParallel);
-//                highLightedFlows.addAll(activityHighLightedFlowIds);
-//            }
-//        }
-//    }
-//
-//    /**
-//     * Check out the outgoing transition connected to firstActInst from startEventActList
-//     *
-//     * @param startEventActList
-//     * @param firstActInst
-//     * @return
-//     */
-//    private PvmTransition getStartTransaction(List<ActivityImpl> startEventActList, HistoricActivityInstance firstActInst) {
-//        for (ActivityImpl startEventAct : startEventActList) {
-//            for (PvmTransition trans : startEventAct.getOutgoingTransitions()) {
-//                if (trans.getDestination().getId().equals(firstActInst.getActivityId())) {
-//                    return trans;
-//                }
-//            }
-//        }
-//        return null;
-//    }
-//
-//    /**
-//     * getBoundaryEventOutgoingTransitions
-//     *
-//     * @param activity
-//     * @return
-//     */
-//    private List<PvmTransition> getBoundaryEventOutgoingTransitions(ActivityImpl activity) {
-//        List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
-//        for (ActivityImpl subActivity : activity.getActivities()) {
-//            String type = (String) subActivity.getProperty("type");
-//            if (type != null && type.toLowerCase().indexOf("boundary") >= 0) {
-//                boundaryTrans.addAll(subActivity.getOutgoingTransitions());
-//            }
-//        }
-//        return boundaryTrans;
-//    }
-//
-//    /**
-//     * find out single activity's highlighted flowIds
-//     *
-//     * @param activity
-//     * @param hisActInstList
-//     * @param isExclusive    if true only return one flowId(Such as exclusiveGateway, BoundaryEvent On Task)
-//     * @return
-//     */
-//    private List<String> getHighlightedFlows(List<PvmTransition> pvmTransitionList, LinkedList<HistoricActivityInstance> hisActInstList, boolean isParallel) {
-//
-//        List<String> highLightedFlowIds = new ArrayList<String>();
-//
-//        PvmTransition earliestTrans = null;
-//        HistoricActivityInstance earliestHisActInst = null;
-//
-//        for (PvmTransition pvmTransition : pvmTransitionList) {
-//
-//            String destActId = pvmTransition.getDestination().getId();
-//            HistoricActivityInstance destHisActInst = findHisActInst(hisActInstList, destActId);
-//            if (destHisActInst != null) {
-//                if (isParallel) {
-//                    highLightedFlowIds.add(pvmTransition.getId());
-//                } else if (earliestHisActInst == null || (earliestHisActInst.getId().compareTo(destHisActInst.getId()) > 0)) {
-//                    earliestTrans = pvmTransition;
-//                    earliestHisActInst = destHisActInst;
-//                }
-//            }
-//        }
-//
-//        if ((!isParallel) && earliestTrans != null) {
-//            highLightedFlowIds.add(earliestTrans.getId());
-//        }
-//
-//        return highLightedFlowIds;
-//    }
-//
-//    private HistoricActivityInstance findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList, String actId) {
-//        for (HistoricActivityInstance hisActInst : hisActInstList) {
-//            if (hisActInst.getActivityId().equals(actId)) {
-//                return hisActInst;
-//            }
-//        }
-//        return null;
-//    }
+    @Autowired
+    private RuntimeService runtimeService;
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    @Autowired
+    private HistoryService historyService;
+
+    protected ObjectMapper objectMapper = new ObjectMapper();
+
+    @RequestMapping(value = "/process-instance/{processInstanceId}/highlights", method = RequestMethod.GET, produces = "application/json")
+    public ObjectNode getHighlighted(@PathVariable String processInstanceId) {
+
+        ObjectNode responseJSON = objectMapper.createObjectNode();
+
+        responseJSON.put("processInstanceId", processInstanceId);
+
+        ArrayNode activitiesArray = objectMapper.createArrayNode();
+        ArrayNode flowsArray = objectMapper.createArrayNode();
+
+        try {
+            //  获取历史流程实例
+            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
+                    .processInstanceId(processInstanceId).singleResult();
+            //ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
+            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
+
+            responseJSON.put("processDefinitionId", processInstance.getProcessDefinitionId());
+            // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
+            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
+                    .processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
+            // 已执行的节点ID集合
+            List<String> highLightedActivities = new ArrayList<String>();
+            //logger.info("获取已经执行的节点ID");
+            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
+                highLightedActivities.add(activityInstance.getActivityId());
+            }
+            //List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
+            List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstanceId);
+
+            for (String activityId : highLightedActivities) {
+                activitiesArray.add(activityId);
+            }
+
+            for (String flow : highLightedFlows) {
+                flowsArray.add(flow);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        responseJSON.put("activities", activitiesArray);
+        responseJSON.put("flows", flowsArray);
+
+        return responseJSON;
+    }
+
+
+    /**
+     * getHighLightedFlows
+     *
+     * @param processDefinition
+     * @param processInstanceId
+     * @return
+     */
+    private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId) {
+
+        List<String> highLightedFlows = new ArrayList<String>();
+
+        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
+                .processInstanceId(processInstanceId)
+                //order by startime asc is not correct. use default order is correct.
+                //.orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
+                .list();
+
+        LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
+        hisActInstList.addAll(historicActivityInstances);
+
+        getHighlightedFlows(processDefinition.getActivities(), hisActInstList, highLightedFlows);
+
+        return highLightedFlows;
+    }
+
+    /**
+     * getHighlightedFlows
+     * <p>
+     * code logic:
+     * 1. Loop all activities by id asc order;
+     * 2. Check each activity's outgoing transitions and eventBoundery outgoing transitions, if outgoing transitions's destination.id is in other executed activityIds, add this transition to highLightedFlows List;
+     * 3. But if activity is not a parallelGateway or inclusiveGateway, only choose the earliest flow.
+     *
+     * @param activityList
+     * @param hisActInstList
+     * @param highLightedFlows
+     */
+    private void getHighlightedFlows(List<ActivityImpl> activityList, LinkedList<HistoricActivityInstance> hisActInstList, List<String> highLightedFlows) {
+
+        //check out startEvents in activityList
+        List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
+        Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(activityList.size());
+        for (ActivityImpl activity : activityList) {
+
+            activityMap.put(activity.getId(), activity);
+
+            String actType = (String) activity.getProperty("type");
+            if (actType != null && actType.toLowerCase().indexOf("startevent") >= 0) {
+                startEventActList.add(activity);
+            }
+        }
+
+        //These codes is used to avoid a bug:
+        //ACT-1728 If the process instance was started by a callActivity, it will be not have the startEvent activity in ACT_HI_ACTINST table
+        //Code logic:
+        //Check the first activity if it is a startEvent, if not check out the startEvent's highlight outgoing flow.
+        HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
+        String firstActType = (String) firstHistActInst.getActivityType();
+        if (firstActType != null && firstActType.toLowerCase().indexOf("startevent") < 0) {
+            PvmTransition startTrans = getStartTransaction(startEventActList, firstHistActInst);
+            if (startTrans != null) {
+                highLightedFlows.add(startTrans.getId());
+            }
+        }
+
+        while (!hisActInstList.isEmpty()) {
+            HistoricActivityInstance histActInst = hisActInstList.removeFirst();
+            ActivityImpl activity = activityMap.get(histActInst.getActivityId());
+            if (activity != null) {
+                boolean isParallel = false;
+                String type = histActInst.getActivityType();
+                if ("parallelGateway".equals(type) || "inclusiveGateway".equals(type)) {
+                    isParallel = true;
+                } else if ("subProcess".equals(histActInst.getActivityType())) {
+                    getHighlightedFlows(activity.getActivities(), hisActInstList, highLightedFlows);
+                }
+
+                List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
+                allOutgoingTrans.addAll(activity.getOutgoingTransitions());
+                allOutgoingTrans.addAll(getBoundaryEventOutgoingTransitions(activity));
+                List<String> activityHighLightedFlowIds = getHighlightedFlows(allOutgoingTrans, hisActInstList, isParallel);
+                highLightedFlows.addAll(activityHighLightedFlowIds);
+            }
+        }
+    }
+
+    /**
+     * Check out the outgoing transition connected to firstActInst from startEventActList
+     *
+     * @param startEventActList
+     * @param firstActInst
+     * @return
+     */
+    private PvmTransition getStartTransaction(List<ActivityImpl> startEventActList, HistoricActivityInstance firstActInst) {
+        for (ActivityImpl startEventAct : startEventActList) {
+            for (PvmTransition trans : startEventAct.getOutgoingTransitions()) {
+                if (trans.getDestination().getId().equals(firstActInst.getActivityId())) {
+                    return trans;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * getBoundaryEventOutgoingTransitions
+     *
+     * @param activity
+     * @return
+     */
+    private List<PvmTransition> getBoundaryEventOutgoingTransitions(ActivityImpl activity) {
+        List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
+        for (ActivityImpl subActivity : activity.getActivities()) {
+            String type = (String) subActivity.getProperty("type");
+            if (type != null && type.toLowerCase().indexOf("boundary") >= 0) {
+                boundaryTrans.addAll(subActivity.getOutgoingTransitions());
+            }
+        }
+        return boundaryTrans;
+    }
+
+    /**
+     * find out single activity's highlighted flowIds
+     *
+     * @param activity
+     * @param hisActInstList
+     * @param isExclusive    if true only return one flowId(Such as exclusiveGateway, BoundaryEvent On Task)
+     * @return
+     */
+    private List<String> getHighlightedFlows(List<PvmTransition> pvmTransitionList, LinkedList<HistoricActivityInstance> hisActInstList, boolean isParallel) {
+
+        List<String> highLightedFlowIds = new ArrayList<String>();
+
+        PvmTransition earliestTrans = null;
+        HistoricActivityInstance earliestHisActInst = null;
+
+        for (PvmTransition pvmTransition : pvmTransitionList) {
+
+            String destActId = pvmTransition.getDestination().getId();
+            HistoricActivityInstance destHisActInst = findHisActInst(hisActInstList, destActId);
+            if (destHisActInst != null) {
+                if (isParallel) {
+                    highLightedFlowIds.add(pvmTransition.getId());
+                } else if (earliestHisActInst == null || (earliestHisActInst.getId().compareTo(destHisActInst.getId()) > 0)) {
+                    earliestTrans = pvmTransition;
+                    earliestHisActInst = destHisActInst;
+                }
+            }
+        }
+
+        if ((!isParallel) && earliestTrans != null) {
+            highLightedFlowIds.add(earliestTrans.getId());
+        }
+
+        return highLightedFlowIds;
+    }
+
+    private HistoricActivityInstance findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList, String actId) {
+        for (HistoricActivityInstance hisActInst : hisActInstList) {
+            if (hisActInst.getActivityId().equals(actId)) {
+                return hisActInst;
+            }
+        }
+        return null;
+    }
 }