刘光辉
13 小时以前 34981c30a78e8bbd7791131059a9210f9928b62c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package jnpf.workflow.flowable.cmd;
 
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.HistoricActivityInstanceQueryImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.HistoricTaskService;
import org.flowable.task.service.impl.HistoricTaskInstanceQueryImpl;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.flowable.variable.service.VariableService;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity;
 
import cn.hutool.core.collection.CollectionUtil;
 
/**
 * 自定义节点跳转命令:删除源节点执行流(含变量、历史任务标记),
 * 在目标节点重建子执行流并恢复变量,然后继续推进流程。
 * 由黑盒 jar 反编译逐行保真还原,勿做"顺手优化"。
 */
public class JumpCmd implements Command<Void> {
 
    private final String processInstanceId;
    private final List<String> sourceTaskDefIdList;
    private final List<String> targetFlowNodeIdList;
    private final String deleteReason;
    private final BpmnModel bpmnModel;
    private final RuntimeService runtimeService;
    private final Map<String, List<VariableInstanceEntity>> varMap = new ConcurrentHashMap<>();
 
    public JumpCmd(String processInstanceId, List<String> sourceTaskDefIdList, List<String> targetFlowNodeIdList,
                   String deleteReason, BpmnModel bpmnModel, RuntimeService runtimeService) {
        this.processInstanceId = processInstanceId;
        this.sourceTaskDefIdList = sourceTaskDefIdList;
        this.deleteReason = deleteReason;
        this.targetFlowNodeIdList = targetFlowNodeIdList;
        this.bpmnModel = bpmnModel;
        this.runtimeService = runtimeService;
    }
 
    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
        handleExecution(commandContext);
        handleActInst(commandContext);
        targetFlowNodeIdList.forEach(targetId -> {
            FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(targetId);
            ExecutionEntity processExecution = executionEntityManager.findById(processInstanceId);
            ExecutionEntity childExecution = executionEntityManager.createChildExecution(processExecution);
            childExecution.setCurrentFlowElement(flowNode);
            VariableService variableService = CommandContextUtil.getVariableService();
            List<VariableInstanceEntity> variableInstanceEntities = varMap.get(flowNode.getId());
            if (CollectionUtil.isNotEmpty(variableInstanceEntities)) {
                variableInstanceEntities.forEach(var -> {
                    var.setExecutionId(childExecution.getId());
                    variableService.insertVariableInstance(var);
                });
            }
            executionEntityManager.insert(childExecution);
            CommandContextUtil.getAgenda().planContinueProcessOperation(childExecution);
        });
        return null;
    }
 
    private void handleActInst(CommandContext commandContext) {
        for (String str : sourceTaskDefIdList) {
            HistoricActivityInstanceQueryImpl query = (HistoricActivityInstanceQueryImpl) new HistoricActivityInstanceQueryImpl()
                    .activityId(str).processInstanceId(processInstanceId).unfinished();
            List<HistoricActivityInstance> activityInstances =
                    CommandContextUtil.getHistoricActivityInstanceEntityManager().findHistoricActivityInstancesByQueryCriteria(query);
            for (HistoricActivityInstance activity : activityInstances) {
                HistoricActivityInstanceEntity activityEntity = (HistoricActivityInstanceEntity) activity;
                activityEntity.setDeleted(true);
                activityEntity.setDeleteReason(deleteReason);
                CommandContextUtil.getHistoricActivityInstanceEntityManager().update(activityEntity);
            }
        }
    }
 
    private void handleExecution(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
        HistoricTaskService historicTaskService = CommandContextUtil.getHistoricTaskService();
        VariableService variableService = CommandContextUtil.getVariableService();
        for (String str : sourceTaskDefIdList) {
            List<Execution> executionEntities = runtimeService.createExecutionQuery()
                    .processInstanceId(processInstanceId).activityId(str).list();
            for (Execution parentExecution : executionEntities) {
                List<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(parentExecution.getId());
                for (ExecutionEntity childExecution : childExecutions) {
                    List<VariableInstanceEntity> variableInstances = variableService.findVariableInstancesByExecutionId(childExecution.getId());
                    varMap.put(parentExecution.getActivityId(), variableInstances);
                    variableInstances.forEach(variableService::deleteVariableInstance);
                    executionEntityManager.deleteExecutionAndRelatedData(childExecution, deleteReason, false);
                    HistoricTaskInstanceQueryImpl query = (HistoricTaskInstanceQueryImpl) new HistoricTaskInstanceQueryImpl()
                            .executionId(childExecution.getId()).processInstanceId(processInstanceId);
                    List<HistoricTaskInstance> historicTaskInstances = historicTaskService.findHistoricTaskInstancesByQueryCriteria(query);
                    if (!CollectionUtil.isNotEmpty(historicTaskInstances)) {
                        continue;
                    }
                    for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                        HistoricTaskInstanceEntity entity = (HistoricTaskInstanceEntity) historicTaskInstance;
                        entity.setDeleteReason(deleteReason);
                        historicTaskService.updateHistoricTask(entity, true);
                    }
                }
                List<VariableInstanceEntity> variableInstances = variableService.findVariableInstancesByExecutionId(parentExecution.getId());
                varMap.put(parentExecution.getActivityId(), variableInstances);
                variableInstances.forEach(variableService::deleteVariableInstance);
                ExecutionEntity parentExecutionEntity = (ExecutionEntity) parentExecution;
                executionEntityManager.deleteExecutionAndRelatedData(parentExecutionEntity, deleteReason, false);
            }
        }
    }
}