yangys
2025-08-29 b7af95d487f49490de16f9636147e5a40911e157
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package org.springblade.mdm.flow.service;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.List;
import java.util.Map;
@Service
public class FlowableBackWithAssigneeService {
    @Autowired
    private RuntimeService runtimeService;
 
    @Autowired
    private TaskService taskService;
 
    @Autowired
    private HistoryService historyService;
 
    /**
     * 将流程退回到指定任务节点并指定新的处理人
     * @param currentTaskId 当前任务ID
     * @param targetActivityId 目标活动节点ID
     * @param newAssignee 新的处理人
     * @param comment 退回意见
     * @param variables 流程变量
     */
    @Transactional
    public void backToTaskWithNewAssignee(String currentTaskId,
                                          String targetActivityId,
                                          String newAssignee,
                                          String comment,
                                          Map<String, Object> variables) {
        // 获取当前任务
        Task currentTask = taskService.createTaskQuery()
            .taskId(currentTaskId)
            .singleResult();
 
        if (currentTask == null) {
            throw new RuntimeException("当前任务不存在");
        }
 
        String processInstanceId = currentTask.getProcessInstanceId();
 
        // 添加评论
        if (comment != null && !comment.trim().isEmpty()) {
            taskService.addComment(currentTaskId, processInstanceId, comment);
        }
 
        // 验证目标节点是否存在
        validateTargetActivity(processInstanceId, targetActivityId);
 
        // 使用运行时服务跳转到目标节点
        runtimeService.createChangeActivityStateBuilder()
            .processInstanceId(processInstanceId)
            .moveActivityIdTo(currentTask.getTaskDefinitionKey(), targetActivityId)
            .changeState();
 
        // 获取新创建的任务(退回后产生的任务)
        Task newTask = taskService.createTaskQuery()
            .processInstanceId(processInstanceId)
            .taskDefinitionKey(targetActivityId)
            .singleResult();
 
        if (newTask != null) {
            // 设置新的处理人
            if (newAssignee != null && !newAssignee.trim().isEmpty()) {
                taskService.setAssignee(newTask.getId(), newAssignee);
            }
 
            // 设置流程变量
            if (variables != null && !variables.isEmpty()) {
                taskService.setVariables(newTask.getId(), variables);
            }
        }
 
        // 删除当前任务
        taskService.deleteTask(currentTaskId, "退回流程并指定新处理人: " + newAssignee);
    }
 
    /**
     * 退回并保留原处理人信息(记录历史)
     */
    @Transactional
    public void backToTaskWithOriginalAssignee(String currentTaskId,
                                               String targetActivityId,
                                               String comment) {
        Task currentTask = taskService.createTaskQuery()
            .taskId(currentTaskId)
            .singleResult();
 
        if (currentTask == null) {
            throw new RuntimeException("当前任务不存在");
        }
 
        String processInstanceId = currentTask.getProcessInstanceId();
 
        // 获取目标节点的历史任务信息
        HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
            .processInstanceId(processInstanceId)
            .taskDefinitionKey(targetActivityId)
            .orderByHistoricTaskInstanceEndTime().desc()
            .list()
            .stream()
            .findFirst()
            .orElse(null);
 
        String originalAssignee = historicTask != null ? historicTask.getAssignee() : null;
 
        // 执行退回操作
        backToTaskWithNewAssignee(currentTaskId, targetActivityId, originalAssignee, comment, null);
    }
 
    /**
     * 验证目标活动节点是否存在
     */
    private void validateTargetActivity(String processInstanceId, String targetActivityId) {
        List<HistoricActivityInstance> targetActivities = historyService
            .createHistoricActivityInstanceQuery()
            .processInstanceId(processInstanceId)
            .activityId(targetActivityId)
            .list();
 
        if (targetActivities.isEmpty()) {
            throw new RuntimeException("目标节点不存在于流程实例中");
        }
    }
 
    /**
     * 获取可退回的节点列表(用户任务节点)
     */
    public List<HistoricActivityInstance> getBackableUserTasks(String processInstanceId) {
        return historyService.createHistoricActivityInstanceQuery()
            .processInstanceId(processInstanceId)
            .activityType("userTask")
            .orderByHistoricActivityInstanceStartTime().desc()
            .list();
    }
 
    /**
     * 获取指定节点的历史处理人
     */
    public String getHistoricAssignee(String processInstanceId, String activityId) {
        HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
            .processInstanceId(processInstanceId)
            .taskDefinitionKey(activityId)
            .orderByHistoricTaskInstanceEndTime().desc()
            .list()
            .stream()
            .findFirst()
            .orElse(null);
 
        return historicTask != null ? historicTask.getAssignee() : null;
    }
}