¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.ubcs.flow.engine.utils; |
| | | |
| | | import com.vci.ubcs.flow.core.utils.TaskUtil; |
| | | import com.vci.ubcs.flow.core.vo.FlowTaskHisVO; |
| | | import com.vci.ubcs.flow.engine.constant.FlowEngineConstant; |
| | | import com.vci.ubcs.starter.exception.VciBaseException; |
| | | import com.vci.ubcs.starter.web.util.VciBaseUtil; |
| | | import com.vci.ubcs.system.user.cache.UserCache; |
| | | import com.vci.ubcs.system.user.entity.User; |
| | | import com.vci.ubcs.system.user.vo.UserVO; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.engine.HistoryService; |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.history.HistoricActivityInstance; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; |
| | | import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior; |
| | | import org.flowable.engine.task.Comment; |
| | | import org.flowable.variable.api.history.HistoricVariableInstance; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * @author weidy |
| | | * @date 2021/4/2 |
| | | */ |
| | | public class FlowableUtils { |
| | | /** |
| | | * æ ¹æ®èç¹ï¼è·åå
¥å£è¿çº¿ |
| | | * @param source èç¹ |
| | | * @return å
å«ç线 |
| | | */ |
| | | public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) { |
| | | List<SequenceFlow> sequenceFlows = null; |
| | | if (source instanceof Task) { |
| | | sequenceFlows = ((Task) source).getIncomingFlows(); |
| | | } else if (source instanceof Gateway) { |
| | | sequenceFlows = ((Gateway) source).getIncomingFlows(); |
| | | } else if (source instanceof SubProcess) { |
| | | sequenceFlows = ((SubProcess) source).getIncomingFlows(); |
| | | } else if (source instanceof StartEvent) { |
| | | sequenceFlows = ((StartEvent) source).getIncomingFlows(); |
| | | } else if (source instanceof EndEvent) { |
| | | sequenceFlows = ((EndEvent) source).getIncomingFlows(); |
| | | } |
| | | return sequenceFlows; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®èç¹ï¼è·ååºå£è¿çº¿ |
| | | * @param source èç¹ |
| | | * @return åºå£ç线 |
| | | */ |
| | | public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) { |
| | | List<SequenceFlow> sequenceFlows = null; |
| | | if (source instanceof Task) { |
| | | sequenceFlows = ((Task) source).getOutgoingFlows(); |
| | | } else if (source instanceof Gateway) { |
| | | sequenceFlows = ((Gateway) source).getOutgoingFlows(); |
| | | } else if (source instanceof SubProcess) { |
| | | sequenceFlows = ((SubProcess) source).getOutgoingFlows(); |
| | | } else if (source instanceof StartEvent) { |
| | | sequenceFlows = ((StartEvent) source).getOutgoingFlows(); |
| | | } else if (source instanceof EndEvent) { |
| | | sequenceFlows = ((EndEvent) source).getOutgoingFlows(); |
| | | } |
| | | return sequenceFlows; |
| | | } |
| | | |
| | | /** |
| | | * è·åå
¨é¨èç¹å表ï¼å
å«åæµç¨èç¹ |
| | | * @param flowElements èç¹ |
| | | * @param allElements ææçèç¹ |
| | | * @return èç¹çå
容 |
| | | */ |
| | | public static Collection<FlowElement> getAllElements(Collection<FlowElement> flowElements, Collection<FlowElement> allElements) { |
| | | allElements = allElements == null ? new ArrayList<>() : allElements; |
| | | |
| | | for (FlowElement flowElement : flowElements) { |
| | | allElements.add(flowElement); |
| | | if (flowElement instanceof SubProcess) { |
| | | // ç»§ç»æ·±å
¥åæµç¨ï¼è¿ä¸æ¥è·ååæµç¨ |
| | | allElements = FlowableUtils.getAllElements(((SubProcess) flowElement).getFlowElements(), allElements); |
| | | } |
| | | } |
| | | return allElements; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£è·åç¶çº§ä»»å¡èç¹å表ï¼ååæ¾ |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param userTaskList å·²æ¾å°çç¨æ·ä»»å¡èç¹ |
| | | * @return |
| | | */ |
| | | public static List<UserTask> iteratorFindParentUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) { |
| | | userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | userTaskList = iteratorFindParentUserTasks(source.getSubProcess(), hasSequenceFlow, userTaskList); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // ç±»åä¸ºç¨æ·èç¹ï¼åæ°å¢ç¶çº§èç¹ |
| | | if (sequenceFlow.getSourceFlowElement() instanceof UserTask) { |
| | | userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement()); |
| | | continue; |
| | | } |
| | | // ç±»åä¸ºåæµç¨ï¼åæ·»å åæµç¨å¼å§èç¹åºå£å¤ç¸è¿çèç¹ |
| | | if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) { |
| | | // è·ååæµç¨ç¨æ·ä»»å¡èç¹ |
| | | List<UserTask> childUserTaskList = findChildProcessUserTasks((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null); |
| | | // 妿æ¾å°èç¹ï¼å说æè¯¥çº¿è·¯æ¾å°èç¹ï¼ä¸ç»§ç»å䏿¾ï¼åä¹ç»§ç» |
| | | if (childUserTaskList != null && childUserTaskList.size() > 0) { |
| | | userTaskList.addAll(childUserTaskList); |
| | | continue; |
| | | } |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | userTaskList = iteratorFindParentUserTasks(sequenceFlow.getSourceFlowElement(), new HashSet<>(hasSequenceFlow), userTaskList); |
| | | } |
| | | } |
| | | return userTaskList; |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ£å¨è¿è¡çä»»å¡èç¹ï¼è¿ä»£è·åå级任å¡èç¹å表ï¼ååæ¾ |
| | | * @param source èµ·å§èç¹ |
| | | * @param runActiveIdList æ£å¨è¿è¡çä»»å¡ Keyï¼ç¨äºæ ¡éªä»»å¡èç¹æ¯å¦æ¯æ£å¨è¿è¡çèç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param flowElementList éè¦æ¤åçç¨æ·ä»»å¡å表 |
| | | * @return èç¹çä¿¡æ¯ |
| | | */ |
| | | public static List<FlowElement> iteratorFindChildUserTasks(FlowElement source, List<String> runActiveIdList, Set<String> hasSequenceFlow, List<FlowElement> flowElementList) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | flowElementList = flowElementList == null ? new ArrayList<>() : flowElementList; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof EndEvent && source.getSubProcess() != null) { |
| | | flowElementList = iteratorFindChildUserTasks(source.getSubProcess(), runActiveIdList, hasSequenceFlow, flowElementList); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // å¦æä¸ºç¨æ·ä»»å¡ç±»åï¼æè
为ç½å
³ |
| | | // æ´»å¨èç¹ID å¨è¿è¡çä»»å¡ä¸åå¨ï¼æ·»å |
| | | if ((sequenceFlow.getTargetFlowElement() instanceof UserTask || sequenceFlow.getTargetFlowElement() instanceof Gateway) && runActiveIdList.contains((sequenceFlow.getTargetFlowElement()).getId())) { |
| | | flowElementList.add(sequenceFlow.getTargetFlowElement()); |
| | | continue; |
| | | } |
| | | // 妿èç¹ä¸ºåæµç¨èç¹æ
åµï¼åä»èç¹ä¸ç第ä¸ä¸ªèç¹å¼å§è·å |
| | | if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { |
| | | List<FlowElement> childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runActiveIdList, hasSequenceFlow, null); |
| | | // 妿æ¾å°èç¹ï¼å说æè¯¥çº¿è·¯æ¾å°èç¹ï¼ä¸ç»§ç»å䏿¾ï¼åä¹ç»§ç» |
| | | if (childUserTaskList != null && childUserTaskList.size() > 0) { |
| | | flowElementList.addAll(childUserTaskList); |
| | | continue; |
| | | } |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | flowElementList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runActiveIdList, new HashSet<>(hasSequenceFlow), flowElementList); |
| | | } |
| | | } |
| | | return flowElementList; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£è·ååæµç¨ç¨æ·ä»»å¡èç¹ |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param userTaskList éè¦æ¤åçç¨æ·ä»»å¡å表 |
| | | * @return ä»»å¡ |
| | | */ |
| | | public static List<UserTask> findChildProcessUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // å¦æä¸ºç¨æ·ä»»å¡ç±»åï¼ä¸ä»»å¡èç¹ç Key æ£å¨è¿è¡çä»»å¡ä¸åå¨ï¼æ·»å |
| | | if (sequenceFlow.getTargetFlowElement() instanceof UserTask) { |
| | | userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement()); |
| | | continue; |
| | | } |
| | | // 妿èç¹ä¸ºåæµç¨èç¹æ
åµï¼åä»èç¹ä¸ç第ä¸ä¸ªèç¹å¼å§è·å |
| | | if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { |
| | | List<UserTask> childUserTaskList = findChildProcessUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null); |
| | | // 妿æ¾å°èç¹ï¼å说æè¯¥çº¿è·¯æ¾å°èç¹ï¼ä¸ç»§ç»å䏿¾ï¼åä¹ç»§ç» |
| | | if (childUserTaskList != null && childUserTaskList.size() > 0) { |
| | | userTaskList.addAll(childUserTaskList); |
| | | continue; |
| | | } |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | userTaskList = findChildProcessUserTasks(sequenceFlow.getTargetFlowElement(), new HashSet<>(hasSequenceFlow), userTaskList); |
| | | } |
| | | } |
| | | return userTaskList; |
| | | } |
| | | |
| | | /** |
| | | * ä»ååå寻路ï¼è·åææè线路ä¸çç¹ |
| | | * @param source èµ·å§èç¹ |
| | | * @param passRoads å·²ç»ç»è¿çç¹éå |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param targets ç®æ è线路ç»ç¹ |
| | | * @param dirtyRoads ç¡®å®ä¸ºèæ°æ®çç¹ï¼å 为ä¸éè¦éå¤ï¼å æ¤ä½¿ç¨ set åå¨ |
| | | * @return 路线 |
| | | */ |
| | | public static Set<String> iteratorFindDirtyRoads(FlowElement source, List<String> passRoads, Set<String> hasSequenceFlow, List<String> targets, Set<String> dirtyRoads) { |
| | | passRoads = passRoads == null ? new ArrayList<>() : passRoads; |
| | | dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads; |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | dirtyRoads = iteratorFindDirtyRoads(source.getSubProcess(), passRoads, hasSequenceFlow, targets, dirtyRoads); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // æ°å¢ç»è¿ç路线 |
| | | passRoads.add(sequenceFlow.getSourceFlowElement().getId()); |
| | | // 妿æ¤ç¹ä¸ºç®æ ç¹ï¼ç¡®å®ç»è¿ç路线为èçº¿è·¯ï¼æ·»å ç¹å°è线路ä¸ï¼ç¶åæ¾ä¸ä¸ªè¿çº¿ |
| | | if (targets.contains(sequenceFlow.getSourceFlowElement().getId())) { |
| | | dirtyRoads.addAll(passRoads); |
| | | continue; |
| | | } |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) { |
| | | dirtyRoads = findChildProcessAllDirtyRoad((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, dirtyRoads); |
| | | // æ¯å¦åå¨åæµç¨ä¸ï¼true æ¯ï¼false å¦ |
| | | Boolean isInChildProcess = dirtyTargetInChildProcess((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, targets, null); |
| | | if (isInChildProcess) { |
| | | // å·²å¨åæµç¨ä¸æ¾å°ï¼è¯¥è·¯çº¿ç»æ |
| | | continue; |
| | | } |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | dirtyRoads = iteratorFindDirtyRoads(sequenceFlow.getSourceFlowElement(), new ArrayList<>(passRoads), new HashSet<>(hasSequenceFlow), targets, dirtyRoads); |
| | | } |
| | | } |
| | | return dirtyRoads; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£è·ååæµç¨è路线 |
| | | * 说æï¼åå¦åéçç¹å°±æ¯åæµç¨ï¼é£ä¹ä¹è¯å®ä¼åéå°åæµç¨æåçç¨æ·ä»»å¡èç¹ï¼å æ¤åæµç¨ä¸çèç¹å
¨æ¯è路线 |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param dirtyRoads ç¡®å®ä¸ºèæ°æ®çç¹ï¼å 为ä¸éè¦éå¤ï¼å æ¤ä½¿ç¨ set åå¨ |
| | | * @return 路线 |
| | | */ |
| | | public static Set<String> findChildProcessAllDirtyRoad(FlowElement source, Set<String> hasSequenceFlow, Set<String> dirtyRoads) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // æ·»å è路线 |
| | | dirtyRoads.add(sequenceFlow.getTargetFlowElement().getId()); |
| | | // 妿èç¹ä¸ºåæµç¨èç¹æ
åµï¼åä»èç¹ä¸ç第ä¸ä¸ªèç¹å¼å§è·å |
| | | if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { |
| | | dirtyRoads = findChildProcessAllDirtyRoad((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, dirtyRoads); |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | dirtyRoads = findChildProcessAllDirtyRoad(sequenceFlow.getTargetFlowElement(), new HashSet<>(hasSequenceFlow), dirtyRoads); |
| | | } |
| | | } |
| | | return dirtyRoads; |
| | | } |
| | | |
| | | /** |
| | | * 夿èè·¯çº¿ç»æèç¹æ¯å¦å¨åæµç¨ä¸ |
| | | * @param source èµ·å§èç¹ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param targets 夿è路线èç¹æ¯å¦åå¨åæµç¨ä¸ï¼åªè¦åå¨ä¸ä¸ªï¼è¯´æè路线åªå°åæµç¨ä¸ºæ¢ |
| | | * @param inChildProcess æ¯å¦åå¨åæµç¨ä¸ï¼true æ¯ï¼false å¦ |
| | | * @return æ¯å¦ |
| | | */ |
| | | public static Boolean dirtyTargetInChildProcess(FlowElement source, Set<String> hasSequenceFlow, List<String> targets, Boolean inChildProcess) { |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | inChildProcess = inChildProcess == null ? false : inChildProcess; |
| | | |
| | | // æ ¹æ®ç±»åï¼è·ååºå£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source); |
| | | |
| | | if (sequenceFlows != null && !inChildProcess) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // 妿åç°ç®æ ç¹å¨åæµç¨ä¸åå¨ï¼è¯´æåªå°åæµç¨ä¸ºæ¢ |
| | | if (targets.contains(sequenceFlow.getTargetFlowElement().getId())) { |
| | | inChildProcess = true; |
| | | break; |
| | | } |
| | | // 妿èç¹ä¸ºåæµç¨èç¹æ
åµï¼åä»èç¹ä¸ç第ä¸ä¸ªèç¹å¼å§è·å |
| | | if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) { |
| | | inChildProcess = dirtyTargetInChildProcess((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, targets, inChildProcess); |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | inChildProcess = dirtyTargetInChildProcess(sequenceFlow.getTargetFlowElement(), new HashSet<>(hasSequenceFlow), targets, inChildProcess); |
| | | } |
| | | } |
| | | return inChildProcess; |
| | | } |
| | | |
| | | /** |
| | | * è¿ä»£ä»åååæ«æï¼å¤æç®æ èç¹ç¸å¯¹äºå½åèç¹æ¯å¦æ¯ä¸²è¡ |
| | | * ä¸åå¨ç´æ¥åéå°åæµç¨ä¸çæ
åµï¼ä½åå¨ä»åæµç¨åºå»å°ç¶æµç¨æ
åµ |
| | | * @param source èµ·å§èç¹ |
| | | * @param isSequential æ¯å¦ä¸²è¡ |
| | | * @param hasSequenceFlow å·²ç»ç»è¿çè¿çº¿ç IDï¼ç¨äºå¤æçº¿è·¯æ¯å¦éå¤ |
| | | * @param targetKsy ç®æ èç¹ |
| | | * @return æ¯å¦ |
| | | */ |
| | | public static Boolean iteratorCheckSequentialReferTarget(FlowElement source, String targetKsy, Set<String> hasSequenceFlow, Boolean isSequential) { |
| | | isSequential = isSequential == null ? true : isSequential; |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | isSequential = iteratorCheckSequentialReferTarget(source.getSubProcess(), targetKsy, hasSequenceFlow, isSequential); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null) { |
| | | // å¾ªç¯æ¾å°ç®æ å
ç´ |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // å¦æç®æ èç¹å·²è¢«å¤æä¸ºå¹¶è¡ï¼åé¢é½ä¸éè¦æ§è¡ï¼ç´æ¥è¿å |
| | | if (isSequential == false) { |
| | | break; |
| | | } |
| | | // è¿æ¡çº¿è·¯åå¨ç®æ èç¹ï¼è¿æ¡çº¿è·¯å®æï¼è¿å
¥ä¸ä¸ªçº¿è·¯ |
| | | if (targetKsy.equals(sequenceFlow.getSourceFlowElement().getId())) { |
| | | continue; |
| | | } |
| | | if (sequenceFlow.getSourceFlowElement() instanceof StartEvent) { |
| | | isSequential = false; |
| | | break; |
| | | } |
| | | // å¦å就继ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | isSequential = iteratorCheckSequentialReferTarget(sequenceFlow.getSourceFlowElement(), targetKsy, new HashSet<>(hasSequenceFlow), isSequential); |
| | | } |
| | | } |
| | | return isSequential; |
| | | } |
| | | |
| | | /** |
| | | * ä»ååå寻路ï¼è·åå°è¾¾èç¹çææè·¯çº¿ |
| | | * ä¸åå¨ç´æ¥åéå°åæµç¨ï¼ä½æ¯åå¨åéå°ç¶çº§æµç¨çæ
åµ |
| | | * @param source èµ·å§èç¹ |
| | | * @param passRoads å·²ç»ç»è¿çç¹éå |
| | | * @param roads 路线 |
| | | * @return ä»»å¡ |
| | | */ |
| | | public static List<List<UserTask>> findRoad(FlowElement source, List<UserTask> passRoads, Set<String> hasSequenceFlow, List<List<UserTask>> roads) { |
| | | passRoads = passRoads == null ? new ArrayList<>() : passRoads; |
| | | roads = roads == null ? new ArrayList<>() : roads; |
| | | hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow; |
| | | |
| | | // å¦æè¯¥èç¹ä¸ºå¼å§èç¹ï¼ä¸åå¨ä¸çº§åèç¹ï¼å顺çä¸çº§åèç¹ç»§ç»è¿ä»£ |
| | | if (source instanceof StartEvent && source.getSubProcess() != null) { |
| | | roads = findRoad(source.getSubProcess(), passRoads, hasSequenceFlow, roads); |
| | | } |
| | | |
| | | // æ ¹æ®ç±»åï¼è·åå
¥å£è¿çº¿ |
| | | List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source); |
| | | |
| | | if (sequenceFlows != null && sequenceFlows.size() != 0) { |
| | | for (SequenceFlow sequenceFlow: sequenceFlows) { |
| | | // 妿åç°è¿çº¿éå¤ï¼è¯´æå¾ªç¯äºï¼è·³è¿è¿ä¸ªå¾ªç¯ |
| | | if (hasSequenceFlow.contains(sequenceFlow.getId())) { |
| | | continue; |
| | | } |
| | | // æ·»å å·²ç»èµ°è¿çè¿çº¿ |
| | | hasSequenceFlow.add(sequenceFlow.getId()); |
| | | // æ·»å ç»è¿è·¯çº¿ |
| | | if (sequenceFlow.getSourceFlowElement() instanceof UserTask) { |
| | | passRoads.add((UserTask) sequenceFlow.getSourceFlowElement()); |
| | | } |
| | | // ç»§ç»è¿ä»£ |
| | | // 注æï¼å·²ç»ç»è¿çèç¹ä¸è¿çº¿é½åºè¯¥ç¨æµ
æ·è´åºæ¥ç对象 |
| | | // æ¯å¦åæ¯ï¼a->b->cä¸a->d->cï¼èµ°å®a->b->cåèµ°å¦ä¸ä¸ªè·¯çº¿æ¯ï¼å·²ç»ç»è¿çèç¹åºè¯¥ä¸å
å«a->b->cè·¯çº¿çæ°æ® |
| | | roads = findRoad(sequenceFlow.getSourceFlowElement(), new ArrayList<>(passRoads), new HashSet<>(hasSequenceFlow), roads); |
| | | } |
| | | } else { |
| | | // æ·»å 路线 |
| | | roads.add(passRoads); |
| | | } |
| | | return roads; |
| | | } |
| | | |
| | | /** |
| | | * åå²èç¹æ°æ®æ¸
æ´ï¼æ¸
æ´æå忻坼è´çèæ°æ® |
| | | * @param allElements å
¨é¨èç¹ä¿¡æ¯ |
| | | * @param historicActivityIdList åå²ä»»å¡å®ä¾ä¿¡æ¯ï¼æ°æ®éç¨å¼å§æ¶é´ååº |
| | | * @return å岿°æ® |
| | | */ |
| | | public static List<String> historicTaskInstanceClean(Collection<FlowElement> allElements, List<HistoricActivityInstance> historicActivityIdList) { |
| | | // ä¼ç¾èç¹æ¶é |
| | | List<String> multiTask = new ArrayList<>(); |
| | | allElements.forEach(flowElement -> { |
| | | if (flowElement instanceof UserTask) { |
| | | // å¦æè¯¥èç¹çè¡ä¸ºä¸ºä¼ç¾è¡ä¸ºï¼è¯´æè¯¥èç¹ä¸ºä¼ç¾èç¹ |
| | | if (((UserTask) flowElement).getBehavior() instanceof ParallelMultiInstanceBehavior || ((UserTask) flowElement).getBehavior() instanceof SequentialMultiInstanceBehavior) { |
| | | multiTask.add(flowElement.getId()); |
| | | } |
| | | } |
| | | }); |
| | | // å¾ªç¯æ¾å
¥æ ï¼æ LIFOï¼åè¿å
åº |
| | | Stack<HistoricActivityInstance> stack = new Stack<>(); |
| | | historicActivityIdList.forEach(item -> stack.push(item)); |
| | | // æ¸
æ´åçåå²ä»»å¡å®ä¾ |
| | | List<String> lastHistoricTaskInstanceList = new ArrayList<>(); |
| | | // ç½å
³åå¨å¯è½åªèµ°äºé¨å忝æ
åµï¼ä¸è¿åå¨è·³è½¬åºå¼æ°æ®ä»¥åå
¶ä»åæ¯æ°æ®çå¹²æ°ï¼å æ¤éè¦å¯¹åå²èç¹æ°æ®è¿è¡æ¸
æ´ |
| | | // 临æ¶ç¨æ·ä»»å¡ key |
| | | StringBuilder userTaskKey = null; |
| | | // 临æ¶è¢«å æçä»»å¡ keyï¼åå¨å¹¶è¡æ
åµ |
| | | List<String> deleteKeyList = new ArrayList<>(); |
| | | // 临æ¶èæ°æ®çº¿è·¯ |
| | | List<Set<String>> dirtyDataLineList = new ArrayList<>(); |
| | | // ç±æä¸ªç¹è·³å°ä¼ç¾ç¹,æ¤æ¶åºç°å¤ä¸ªä¼ç¾å®ä¾å¯¹åº 1 个跳转æ
åµï¼éè¦æè¿äºè¿ç»èæ°æ®é½æ¾å° |
| | | // ä¼ç¾ç¹æ®å¤ç䏿 |
| | | int multiIndex = -1; |
| | | // ä¼ç¾ç¹æ®å¤ç key |
| | | StringBuilder multiKey = null; |
| | | // ä¼ç¾ç¹æ®å¤çæä½æ è¯ |
| | | boolean multiOpera = false; |
| | | while (!stack.empty()) { |
| | | // ä»è¿éå¼å§ userTaskKey é½è¿æ¯ä¸ä¸ªæ ç key |
| | | // æ¯å¦æ¯èæ°æ®çº¿è·¯ä¸çç¹ |
| | | final boolean[] isDirtyData = {false}; |
| | | for (Set<String> oldDirtyDataLine : dirtyDataLineList) { |
| | | if (oldDirtyDataLine.contains(stack.peek().getActivityId())) { |
| | | isDirtyData[0] = true; |
| | | } |
| | | } |
| | | // å é¤åå ä¸ä¸ºç©ºï¼è¯´æä»è¿æ¡æ°æ®å¼å§åè·³æè
åéç |
| | | // MI_ENDï¼ä¼ç¾å®æåï¼å
¶ä»æªç¾å°èç¹çå é¤åå ï¼ä¸å¨å¤çèå´å
|
| | | if (stack.peek().getDeleteReason() != null && !stack.peek().getDeleteReason().equals("MI_END")) { |
| | | // å¯ä»¥ç解为èçº¿è·¯èµ·ç¹ |
| | | String dirtyPoint = ""; |
| | | if (stack.peek().getDeleteReason().indexOf("Change activity to ") >= 0) { |
| | | dirtyPoint = stack.peek().getDeleteReason().replace("Change activity to ", ""); |
| | | } |
| | | // ä¼ç¾åéå é¤åå æç¹ä¸å |
| | | if (stack.peek().getDeleteReason().indexOf("Change parent activity to ") >= 0) { |
| | | dirtyPoint = stack.peek().getDeleteReason().replace("Change parent activity to ", ""); |
| | | } |
| | | FlowElement dirtyTask = null; |
| | | // è·ååæ´èç¹ç对åºçå
¥å£å¤è¿çº¿ |
| | | // 妿æ¯ç½å
³å¹¶è¡åéæ
åµï¼ä¼åæä¸¤æ¡èæ°æ®è·¯çº¿ï¼ææä¸æ · |
| | | for (FlowElement flowElement : allElements) { |
| | | if (flowElement.getId().equals(stack.peek().getActivityId())) { |
| | | dirtyTask = flowElement; |
| | | } |
| | | } |
| | | // è·åèæ°æ®çº¿è·¯ |
| | | Set<String> dirtyDataLine = FlowableUtils.iteratorFindDirtyRoads(dirtyTask, null, null, Arrays.asList(dirtyPoint.split(",")), null); |
| | | // èªå·±æ¬èº«ä¹æ¯è线路ä¸çç¹ï¼å è¿å» |
| | | dirtyDataLine.add(stack.peek().getActivityId()); |
| | | //logger.info(stack.peek().getActivityId() + "ç¹è路线éåï¼" + dirtyDataLine); |
| | | // æ¯å
¨æ°çéè¦æ·»å çè线路 |
| | | boolean isNewDirtyData = true; |
| | | for (int i = 0; i < dirtyDataLineList.size(); i++) { |
| | | // 妿åç°ä»çä¸ä¸ªèç¹å¨è线路å
ï¼è¯´æè¿ä¸ªç¹å¯è½æ¯å¹¶è¡çèç¹ï¼æè
è¿ç»é©³å |
| | | // è¿æ¶ï¼é½ä»¥ä¹åçè线路èç¹ä¸ºæ åï¼åªéåå¹¶è线路å³å¯ï¼ä¹å°±æ¯è·¯çº¿è¡¥å
¨ |
| | | if (dirtyDataLineList.get(i).contains(userTaskKey.toString())) { |
| | | isNewDirtyData = false; |
| | | dirtyDataLineList.get(i).addAll(dirtyDataLine); |
| | | } |
| | | } |
| | | // å·²ç¡®å®æ¶å
¨æ°çè线路 |
| | | if (isNewDirtyData) { |
| | | // deleteKey åä¸è·¯çº¿é©³åå°å¹¶è¡ï¼è¿ç§åæ¶çæå¤ä¸ªæ°å®ä¾è®°å½æ
åµï¼è¿æ¶ deleteKey å
¶å®æ¯ç±å¤ä¸ªå¼ç»æ |
| | | // æç
§é»è¾ï¼åéåç«å»çæçå®ä¾è®°å½å°±æ¯åéçè®°å½ |
| | | // è³äºé©³åæçæç Keyï¼ç´æ¥ä»å é¤åå ä¸è·åï¼å 为åå¨é©³åå°å¹¶è¡çæ
åµ |
| | | deleteKeyList.add(dirtyPoint + ","); |
| | | dirtyDataLineList.add(dirtyDataLine); |
| | | } |
| | | // æ·»å åï¼ç°å¨è¿ä¸ªç¹åæè线路ä¸çç¹äº |
| | | isDirtyData[0] = true; |
| | | } |
| | | // 妿䏿¯è线路ä¸çç¹ï¼è¯´ææ¯æææ°æ®ï¼æ·»å åå²å®ä¾ Key |
| | | if (!isDirtyData[0]) { |
| | | lastHistoricTaskInstanceList.add(stack.peek().getActivityId()); |
| | | } |
| | | // æ ¡éªè线路æ¯å¦ç»æ |
| | | for (int i = 0; i < deleteKeyList.size(); i ++) { |
| | | // 妿åç°èæ°æ®å±äºä¼ç¾ï¼è®°å½ä¸ä¸æ ä¸å¯¹åº Keyï¼ä»¥å¤åç»æ¯å¯¹ï¼ä¼ç¾èæ°æ®èç´å¼å§ |
| | | if (multiKey == null && multiTask.contains(stack.peek().getActivityId()) |
| | | && deleteKeyList.get(i).contains(stack.peek().getActivityId())) { |
| | | multiIndex = i; |
| | | multiKey = new StringBuilder(stack.peek().getActivityId()); |
| | | } |
| | | // ä¼ç¾èæ°æ®å¤çï¼èç¹éåä¼ç¾æ¸
空 |
| | | // 妿å¨ä¼ç¾èæ°æ®èç´ä¸åç° Keyæ¹åï¼è¯´æä¼ç¾èæ°æ®å¨ä¸ä¸ªèç¹å°±ç»æäºï¼å¯ä»¥æä¼ç¾èæ°æ®å æ |
| | | if (multiKey != null && !multiKey.toString().equals(stack.peek().getActivityId())) { |
| | | deleteKeyList.set(multiIndex , deleteKeyList.get(multiIndex).replace(stack.peek().getActivityId() + ",", "")); |
| | | multiKey = null; |
| | | // ç»æè¿è¡ä¸æ ¡éªå é¤ |
| | | multiOpera = true; |
| | | } |
| | | // å
¶ä»èæ°æ®å¤ç |
| | | // åç°è¯¥è·¯çº¿æå䏿¡èæ°æ®ï¼è¯´æè¿æ¡èæ°æ®çº¿è·¯å¤çå®äºï¼å é¤èæ°æ®ä¿¡æ¯ |
| | | // èæ°æ®äº§ççæ°å®ä¾ä¸æ¯å¦å
å«è¿æ¡æ°æ® |
| | | if (multiKey == null && deleteKeyList.get(i).contains(stack.peek().getActivityId())) { |
| | | // å é¤å¹é
å°çé¨å |
| | | deleteKeyList.set(i , deleteKeyList.get(i).replace(stack.peek().getActivityId() + ",", "")); |
| | | } |
| | | // 妿æ¯ç»ä¸çå
ç´ é½ä»¥å¹é
è¿ï¼è¯´æèæ°æ®ç»æ |
| | | if ("".equals(deleteKeyList.get(i))) { |
| | | // åæ¶å é¤èæ°æ® |
| | | deleteKeyList.remove(i); |
| | | dirtyDataLineList.remove(i); |
| | | break; |
| | | } |
| | | } |
| | | // ä¼ç¾æ°æ®å¤çéè¦å¨å¾ªç¯å¤å¤çï¼å¦åå¯è½å¯¼è´æº¢åº |
| | | // ä¼ç¾çæ°æ®è¯å®æ¯ä¹åæ¾è¿å»çæä»¥ç论ä¸ä¸ä¼æº¢åºï¼ä½è¿æ¯æ ¡éªä¸ |
| | | if (multiOpera && deleteKeyList.size() > multiIndex && "".equals(deleteKeyList.get(multiIndex))) { |
| | | // åæ¶å é¤èæ°æ® |
| | | deleteKeyList.remove(multiIndex); |
| | | dirtyDataLineList.remove(multiIndex); |
| | | multiIndex = -1; |
| | | multiOpera = false; |
| | | } |
| | | // pop() æ¹æ³ä¸ peek() æ¹æ³ä¸åï¼å¨è¿åå¼çåæ¶ï¼ä¼æå¼ä»æ ä¸ç§»é¤ |
| | | // ä¿åæ°ç userTaskKey å¨ä¸ä¸ªå¾ªç¯ä¸ä½¿ç¨ |
| | | userTaskKey = new StringBuilder(stack.pop().getActivityId()); |
| | | } |
| | | //logger.info("æ¸
æ´åçåå²èç¹æ°æ®ï¼" + lastHistoricTaskInstanceList); |
| | | return lastHistoricTaskInstanceList; |
| | | } |
| | | |
| | | /** |
| | | * è·åç¸å
³çåå² |
| | | * @param processInstanceId æµç¨å®ä¾çä¸»é® |
| | | * @param historyService åå²æå¡ |
| | | * @param taskService ä»»å¡æå¡ |
| | | * @return åå²çä¿¡æ¯ |
| | | */ |
| | | public static List<FlowTaskHisVO> listTaskHistory(String processInstanceId, HistoryService historyService, TaskService taskService){ |
| | | HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); |
| | | if(processInstance == null || StringUtils.isBlank(processInstance.getId())){ |
| | | throw new VciBaseException("æµç¨æªæ¾å°"); |
| | | } |
| | | List<HistoricActivityInstance> hisList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).activityType("userTask").orderByHistoricActivityInstanceEndTime().desc().list(); |
| | | Map<String,FlowTaskHisVO> hisVOList = new HashMap<>(); |
| | | if(!CollectionUtils.isEmpty(hisList)){ |
| | | List<HistoricActivityInstance> allowTaskInstances = new ArrayList<>(); |
| | | Map<String,List<Comment>> taskOidCommentsMap = new HashMap<>(); |
| | | for(int i = 0 ; i < hisList.size(); i ++){ |
| | | HistoricActivityInstance his = hisList.get(i); |
| | | //æä»¬æ¾å½æ¶ç审æ¹ä¿¡æ¯ï¼è¿æ ·å¯ä»¥å¤ææ¯å¦ä¸ºä¸åæ |
| | | List<Comment> comments = taskService.getTaskComments(his.getTaskId()); |
| | | if(!CollectionUtils.isEmpty(comments)){ |
| | | taskOidCommentsMap.put(his.getId(),comments); |
| | | //æ¥è¯¢ |
| | | }//第ä¸ä¸ªå¯è½æ²¡æ |
| | | allowTaskInstances.add(his); |
| | | } |
| | | if(!CollectionUtils.isEmpty(allowTaskInstances)){ |
| | | List<HistoricVariableInstance> variableInstances = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list(); |
| | | Map<String,Object> variableMap = switchVariable(variableInstances); |
| | | Set<Long> userIds = new HashSet<>(); |
| | | Set<String> processInstanceIds = new HashSet<>(); |
| | | for(int i = 0 ; i < allowTaskInstances.size() ; i ++){ |
| | | HistoricActivityInstance activityInstance = allowTaskInstances.get(i); |
| | | if(!hisVOList.containsKey(activityInstance.getId())) { |
| | | FlowTaskHisVO hisVO = new FlowTaskHisVO(); |
| | | hisVO.setOid(activityInstance.getId()); |
| | | hisVO.setActivityId(activityInstance.getActivityId()); |
| | | hisVO.setActivityName(activityInstance.getActivityName()); |
| | | hisVO.setActivityType(activityInstance.getActivityType()); |
| | | hisVO.setProcessDefinitionId(activityInstance.getProcessDefinitionId()); |
| | | hisVO.setProcessInstanceId(activityInstance.getProcessInstanceId()); |
| | | hisVO.setExecutionId(activityInstance.getExecutionId()); |
| | | hisVO.setTaskId(activityInstance.getTaskId()); |
| | | hisVO.setCalledProcessInstanceId(activityInstance.getCalledProcessInstanceId()); |
| | | hisVO.setAssignee(activityInstance.getAssignee()); |
| | | if (StringUtils.isNotBlank(hisVO.getAssignee())) { |
| | | userIds.add(TaskUtil.getUserId(hisVO.getAssignee())); |
| | | } |
| | | hisVO.setStartTime(activityInstance.getStartTime()); |
| | | hisVO.setEndTime(activityInstance.getEndTime()); |
| | | hisVO.setDurationInMillis(activityInstance.getDurationInMillis()); |
| | | hisVO.setDeleteReason(activityInstance.getDeleteReason()); |
| | | hisVO.setTenantId(activityInstance.getTenantId()); |
| | | hisVO.setVariablesMap(variableMap); |
| | | hisVO.setBtmType(variableMap.getOrDefault(FlowEngineConstant.BTMTYPE,"").toString()); |
| | | hisVO.setLinkBusinessOids(VciBaseUtil.str2List(variableMap.getOrDefault(FlowEngineConstant.OIDS,"").toString())); |
| | | List<Comment> comments = taskOidCommentsMap.getOrDefault(activityInstance.getId(),new ArrayList<>()); |
| | | hisVO.setDescription(comments.stream().map(s->{ |
| | | String fullMsg = s.getFullMessage(); |
| | | if(StringUtils.isNotBlank(fullMsg) && fullMsg.contains(":")){ |
| | | fullMsg = fullMsg.substring(fullMsg.indexOf(":")+1); |
| | | } |
| | | return fullMsg; |
| | | }).collect(Collectors.joining(";"))); |
| | | processInstanceIds.add(activityInstance.getProcessInstanceId()); |
| | | hisVO.setProcessName(processInstance.getName()); |
| | | hisVO.setProcessDefinitionName(processInstance.getProcessDefinitionName()); |
| | | hisVOList.put(hisVO.getActivityId(), hisVO); |
| | | } |
| | | } |
| | | if(!CollectionUtils.isEmpty(userIds) && !CollectionUtils.isEmpty(hisVOList)){ |
| | | List<User> userList = new ArrayList<>(); |
| | | for(Long userId : userIds){ |
| | | userList.add(UserCache.getUser(userId)); |
| | | } |
| | | if(!CollectionUtils.isEmpty(userList)){ |
| | | Map<Long, User> userVOMap = userList.stream().collect(Collectors.toMap(s -> s.getId(), t -> t, (o1, o2) -> o1)); |
| | | hisVOList.values().forEach(history->{ |
| | | List<String> thisUserIds = VciBaseUtil.str2List(TaskUtil.getTaskUser(history.getAssignee())); |
| | | List<String> thisUserNames = new ArrayList<>(); |
| | | if(!CollectionUtils.isEmpty(thisUserIds)) { |
| | | thisUserIds.forEach(userId -> { |
| | | thisUserNames.add(userVOMap.getOrDefault(userId, new User()).getName()); |
| | | }); |
| | | } |
| | | history.setAssigneeName(thisUserNames.stream().collect(Collectors.joining(","))); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return hisVOList.values().stream().collect(Collectors.toList()); |
| | | } |
| | | |
| | | /** |
| | | * 转æ¢åé |
| | | * @param variableInstances åéçå®ä¾ |
| | | * @return åé |
| | | */ |
| | | public static Map<String,Object> switchVariable(List<HistoricVariableInstance> variableInstances){ |
| | | Map<String,Object> variableMap = new HashMap<>(); |
| | | if(!CollectionUtils.isEmpty(variableInstances)){ |
| | | variableMap = variableInstances.stream().collect(Collectors.toMap(s->s.getVariableName(),t->t.getValue() == null?"":t.getValue())); |
| | | } |
| | | return variableMap; |
| | | } |
| | | } |