|
|
@ -96,8 +96,6 @@ public class FlowService extends MybatisBaseService<FlowMapper, Flowable> { |
|
|
|
private MessageFeign messageFeign; |
|
|
|
@Autowired |
|
|
|
private SysFlowccFeign sysFlowccFeign; |
|
|
|
@Autowired |
|
|
|
private FlowTaskMapper flowTaskMapper; |
|
|
|
|
|
|
|
public ResultBean<String> getNextNodeUser(BusinessVariables bv) { |
|
|
|
ResultBean<String> rb = ResultBean.fireFail(); |
|
|
@ -747,202 +745,5 @@ public class FlowService extends MybatisBaseService<FlowMapper, Flowable> { |
|
|
|
return rb.success().setMsg("抄送" + userName.toString() + "成功!"); |
|
|
|
} |
|
|
|
|
|
|
|
public ResultBean<UpdateFlowFieldVo> revokeProcess(FlowTaskVo flowTaskVo) { |
|
|
|
ResultBean<UpdateFlowFieldVo> rb =ResultBean.fireFail(); |
|
|
|
String userSid = flowTaskVo.getUserSid(); |
|
|
|
//获取当前环节信息
|
|
|
|
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(flowTaskVo.getTaskId()).singleResult(); |
|
|
|
Execution execution = runtimeService.createExecutionQuery().executionId(historicTaskInstance.getExecutionId()).singleResult(); |
|
|
|
DelegateExecution delegateExecution = (DelegateExecution) execution; |
|
|
|
if (delegateExecution == null) { |
|
|
|
return rb.setMsg("流程已办结或终止,不能撤回"); |
|
|
|
} |
|
|
|
// 获取当前节点的activityId,即xml中每个标签的ID
|
|
|
|
String currentActivityId = delegateExecution.getCurrentActivityId(); |
|
|
|
String taskId = getTaskId(currentActivityId, historicTaskInstance.getProcessInstanceId(), historicTaskInstance.getProcessDefinitionId()); |
|
|
|
if (StringUtils.isBlank(taskId)) { |
|
|
|
return rb.setMsg("流程找不到上一环节,撤回操作失败!"); |
|
|
|
} |
|
|
|
//获取上一环节操作信息
|
|
|
|
HistoricTaskInstance historicTaskInstance1 = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult(); |
|
|
|
//上一环节操作人
|
|
|
|
String assignee = historicTaskInstance1.getAssignee(); |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private String getTaskId(String currentActivityId, String processInstanceId, String processDefinitionId) { |
|
|
|
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); |
|
|
|
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(currentActivityId); |
|
|
|
List<SequenceFlow> list=flowNode.getIncomingFlows(); |
|
|
|
if(list.size()==0){ |
|
|
|
return ""; |
|
|
|
} |
|
|
|
List<HistoricActivityInstance> list1=new ArrayList<>(); |
|
|
|
for( SequenceFlow sequenceFlow:list){ |
|
|
|
String sourceRef = sequenceFlow.getSourceRef(); |
|
|
|
list1= historyService.createHistoricActivityInstanceQuery().activityId(sourceRef) |
|
|
|
.processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list(); |
|
|
|
if(list1.size()>0){ |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
// 获取上一个节点的activityId
|
|
|
|
HistoricActivityInstance historicActivityInstance = list1.get(0); |
|
|
|
String activityType = historicActivityInstance.getActivityType(); |
|
|
|
String historicActivityInstanceActivityId = historicActivityInstance.getActivityId(); |
|
|
|
if (!"userTask".equals(activityType)) { |
|
|
|
return getTaskId(historicActivityInstanceActivityId, processInstanceId, processDefinitionId); |
|
|
|
} |
|
|
|
return historicActivityInstance.getTaskId(); |
|
|
|
} |
|
|
|
|
|
|
|
private ResultBean<List<LatestTaskVo>> revokeProcess_( String processInstanceId, |
|
|
|
String assignee ) { |
|
|
|
// 流程回退到上一个节点,审批人继续审批
|
|
|
|
// 获取流程定义信息
|
|
|
|
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); |
|
|
|
ProcessDefinition processDefinition = repositoryService |
|
|
|
.createProcessDefinitionQuery() |
|
|
|
.processDefinitionId(task.getProcessDefinitionId()).singleResult(); |
|
|
|
// 获取所有节点信息
|
|
|
|
Process process = repositoryService.getBpmnModel(processDefinition.getId()).getProcesses().get(0); |
|
|
|
// 获取全部节点列表,包含子节点
|
|
|
|
Collection<FlowElement> allElements = |
|
|
|
FlowableUtils.getAllElements(process.getFlowElements(), null); |
|
|
|
// 获取当前任务节点元素
|
|
|
|
FlowElement source = null; |
|
|
|
if (allElements != null) { |
|
|
|
for (FlowElement flowElement : allElements) { |
|
|
|
//类型为用户节点
|
|
|
|
if (flowElement.getId().equals(task.getTaskDefinitionKey())) { |
|
|
|
//获取节点信息
|
|
|
|
source = flowElement; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 目的获取所有跳转到的节点 targetIds
|
|
|
|
// 获取当前节点的所有父级用户任务节点
|
|
|
|
// 深度优先算法思想:延边迭代深入
|
|
|
|
//申请人申请后,销售经理审批同意,随后销售经理再撤回,申请人再撤回。 申请人->网关->销售经理->销售支持部经理
|
|
|
|
List<UserTask> parentUserTaskList = FlowableUtils.iteratorFindParentUserTasks(source, null, null); |
|
|
|
if (parentUserTaskList == null || parentUserTaskList.size() == 0) { |
|
|
|
// throw new CustomException("当前节点为");
|
|
|
|
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("当前节点为").setData(new ArrayList<>()); |
|
|
|
} |
|
|
|
// 如果流程已经结束,则得到结束节点
|
|
|
|
if (historyService.createHistoricProcessInstanceQuery().finished() |
|
|
|
.processInstanceId(processInstanceId).count() > 0) { |
|
|
|
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("当前已经结束不能撤回").setData(new ArrayList<>()); |
|
|
|
} |
|
|
|
// 获取活动 ID 即节点 Key
|
|
|
|
List<String> parentUserTaskKeyList = new ArrayList<>(); |
|
|
|
parentUserTaskList.forEach(item -> parentUserTaskKeyList.add(item.getId())); |
|
|
|
// 获取全部历史节点活动实例,即已经走过的节点历史,数据采用开始时间升序
|
|
|
|
List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery() |
|
|
|
.processInstanceId(processInstanceId) |
|
|
|
.orderByHistoricTaskInstanceStartTime().asc().list(); |
|
|
|
HistoricTaskInstance historicTaskInstance = historicTaskInstanceList.get(historicTaskInstanceList.size() - 1); |
|
|
|
Map<String, Object> actHiVarinstForOrgPath = flowTaskMapper.getActHiVarinstForOrgPath(historicTaskInstance.getId()); |
|
|
|
String orgPath = MapUtil.getStr(actHiVarinstForOrgPath,"TEXT_"); |
|
|
|
// 数据清洗,将回滚导致的脏数据清洗掉
|
|
|
|
List<String> lastHistoricTaskInstanceList = FlowableUtils.historicTaskInstanceClean(allElements, historicTaskInstanceList); |
|
|
|
|
|
|
|
// 此时历史任务实例为倒序,获取最后走的节点
|
|
|
|
List<String> targetIds = new ArrayList<>(); |
|
|
|
int number = 0; |
|
|
|
StringBuilder parentHistoricTaskKey = new StringBuilder(); |
|
|
|
for (String historicTaskInstanceKey : lastHistoricTaskInstanceList) { |
|
|
|
// 当会签时候会出现特殊的,连续都是同一个节点历史数据的情况,这种时候跳过
|
|
|
|
if (parentHistoricTaskKey.toString().equals(historicTaskInstanceKey)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
parentHistoricTaskKey = new StringBuilder(historicTaskInstanceKey); |
|
|
|
if (historicTaskInstanceKey.equals(task.getTaskDefinitionKey())) { |
|
|
|
number++; |
|
|
|
} |
|
|
|
// 在数据清洗后,历史节点就是唯一一条从起始到当前节点的历史记录,理论上每个点只会出现一次
|
|
|
|
// 在流程中如果出现循环,那么每次循环中间的点也只会出现一次,再出现就是下次循环
|
|
|
|
// number == 1,第一次遇到当前节点
|
|
|
|
// number == 2,第二次遇到,代表最后一次的循环范围
|
|
|
|
if (number == 2) { |
|
|
|
break; |
|
|
|
} |
|
|
|
// 如果当前历史节点,属于父级的节点,说明最后一次经过了这个点,需要退回这个点
|
|
|
|
if (parentUserTaskKeyList.contains(historicTaskInstanceKey)) { |
|
|
|
targetIds.add(historicTaskInstanceKey); |
|
|
|
} |
|
|
|
} |
|
|
|
// 目的获取所有需要被跳转的节点 currentIds
|
|
|
|
// 取其中一个父级任务,因为后续要么存在公共网关,要么就是串行公共线路
|
|
|
|
UserTask oneUserTask = parentUserTaskList.get(0); |
|
|
|
// 获取所有正常进行的任务节点 Key,这些任务不能直接使用,需要找出其中需要撤回的任务
|
|
|
|
List<Task> runTaskList = taskService.createTaskQuery() |
|
|
|
.processInstanceId(processInstanceId).list(); |
|
|
|
List<String> runTaskKeyList = new ArrayList<>(); |
|
|
|
runTaskList.forEach(item -> runTaskKeyList.add(item.getTaskDefinitionKey())); |
|
|
|
// 需驳回任务列表
|
|
|
|
List<String> currentIds = new ArrayList<>(); |
|
|
|
// 通过父级网关的出口连线,结合 runTaskList 比对,获取需要撤回的任务
|
|
|
|
List<UserTask> currentUserTaskList = FlowableUtils.iteratorFindChildUserTasks(oneUserTask, runTaskKeyList, null, null); |
|
|
|
currentUserTaskList.forEach(item -> currentIds.add(item.getId())); |
|
|
|
// 规定:并行网关之前节点必须需存在唯一用户任务节点,
|
|
|
|
// 如果出现多个任务节点,则并行网关节点默认为结束节点,原因为不考虑多对多情况
|
|
|
|
if (targetIds.size() > 1 && currentIds.size() > 1) { |
|
|
|
return new ResultBean<List<LatestTaskVo>>().fail().setMsg("任务出现多对多情况,无法撤回").setData(new ArrayList<>()); |
|
|
|
} |
|
|
|
// 循环获取那些需要被撤回的节点的ID,用来设置驳回原因
|
|
|
|
List<String> currentTaskIds = new ArrayList<>(); |
|
|
|
currentIds.forEach(currentId -> runTaskList.forEach(runTask -> { |
|
|
|
if (currentId.equals(runTask.getTaskDefinitionKey())) { |
|
|
|
currentTaskIds.add(runTask.getId()); |
|
|
|
} |
|
|
|
})); |
|
|
|
// 设置撤回意见
|
|
|
|
currentTaskIds.forEach(item -> { |
|
|
|
taskService.addComment(item, processInstanceId,FlowComment.RECALL.getType(), "撤回办理"); |
|
|
|
// 设置实际办理人
|
|
|
|
taskService.setAssignee(item, assignee); |
|
|
|
}); |
|
|
|
|
|
|
|
// 最近环节
|
|
|
|
List<LatestTaskVo> latestTaskList = new ArrayList<>(); |
|
|
|
try { |
|
|
|
// 如果父级任务多于 1 个,说明当前节点不是并行节点,原因为不考虑多对多情况
|
|
|
|
if (targetIds.size() > 1) { |
|
|
|
// 1 对 多任务跳转,currentIds 当前节点(1),targetIds 跳转到的节点(多)
|
|
|
|
runtimeService.createChangeActivityStateBuilder() |
|
|
|
.processInstanceId(processInstanceId). |
|
|
|
moveSingleActivityIdToActivityIds(currentIds.get(0), targetIds).changeState(); |
|
|
|
} |
|
|
|
// 如果父级任务只有一个,因此当前任务可能为网关中的任务
|
|
|
|
if (targetIds.size() == 1) { |
|
|
|
// 1 对 1 或 多 对 1 情况,currentIds 当前要跳转的节点列表(1或多),targetIds.get(0) 跳转到的节点(1)
|
|
|
|
runtimeService.createChangeActivityStateBuilder() |
|
|
|
.processInstanceId(processInstanceId) |
|
|
|
.moveActivityIdsToSingleActivityId(currentIds, targetIds.get(0)).changeState(); |
|
|
|
} |
|
|
|
// 最近环节
|
|
|
|
parentUserTaskList.forEach(item -> { |
|
|
|
LatestTaskVo latestTaskVo = new LatestTaskVo(); |
|
|
|
latestTaskVo.setASSIGNEE_(item.getAssignee()); |
|
|
|
latestTaskVo.setName_(item.getName()); |
|
|
|
latestTaskVo.setTask_def_key_(item.getId()); |
|
|
|
latestTaskVo.setIncomingSourceRef(item.getIncomingFlows().get(0).getSourceRef()); |
|
|
|
latestTaskVo.setOrgPath(orgPath); |
|
|
|
|
|
|
|
Map<String, Object> task_map = flowTaskMapper.getTaskByDefKey(processInstanceId, item.getId()); |
|
|
|
if(task_map!=null){ |
|
|
|
taskService.setAssignee(task_map.get("id_").toString(), assignee); |
|
|
|
latestTaskVo.setId_(task_map.get("id_").toString()); |
|
|
|
latestTaskList.add(latestTaskVo); |
|
|
|
} |
|
|
|
}); |
|
|
|
} catch (FlowableObjectNotFoundException e) { |
|
|
|
throw new CustomException("未找到流程实例,流程可能已发生变化"); |
|
|
|
} catch (FlowableException e) { |
|
|
|
throw new CustomException("无法取消或开始活动"); |
|
|
|
} |
|
|
|
return new ResultBean<List<LatestTaskVo>>().success().setData(latestTaskList); |
|
|
|
} |
|
|
|
} |
|
|
|