由于客户需求,添加撤回到已审批的任意节点功能,所以这边记录一下.
效果如下图:
/**
* 根据任务id查询已经执行的任务节点信息
*/
@Override
public DynamicFormConf getRunNodes(String taskId) {
DynamicFormConf dynamicFormConf = new DynamicFormConf();
// 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(taskId)
.activityType("userTask") //用户任务
.finished() //已经执行的任务节点
.orderByHistoricActivityInstanceEndTime()
.asc()
.list();
// 已执行的节点ID集合
if(StringUtils.isNotEmpty(historicActivityInstanceList)){
Map<String,String> map= new LinkedHashMap<String,String>();
// map = historicActivityInstanceList.stream().collect(Collectors.toMap(HistoricActivityInstance::getActivityId,HistoricActivityInstance::getActivityName,(k1,k2)->k1));
for (HistoricActivityInstance historicActivityInstance:historicActivityInstanceList){
if(!map.containsKey(historicActivityInstance.getActivityId())){
map.put(historicActivityInstance.getActivityId(),historicActivityInstance.getActivityName());
}
}
dynamicFormConf.setRunNodes(map);
}
return dynamicFormConf;
}
/**
* 驳回到指定节点
* @param approvalOpinionVO //申请流程 审批信息
* @param task //任务信息
* @param map
* @return
*/
@Override
public boolean runNodes(ApprovalOpinionVO approvalOpinionVO, Task task, Map<String, Object> map) {
String myTaskId = null;
//判断当前用户是否为该节点处理人
if (UserUtils.getUserId().equals(task.getAssignee())) {
myTaskId = task.getId();
}
//如果当前节点处理人不是该用户,就无法进行驳回操作
if (null == myTaskId) {
throw new CustomException("当前用户无法驳回");
}
//获取当前节点
String currActivityId = task.getTaskDefinitionKey();
String processDefinitionId = task.getProcessDefinitionId();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowNode currFlow = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currActivityId);
if (null == currFlow) {
List<SubProcess> subProcessList = bpmnModel.getMainProcess().findFlowElementsOfType(SubProcess.class, true);
for (SubProcess subProcess : subProcessList) {
FlowElement flowElement = subProcess.getFlowElement(currActivityId);
if (flowElement != null) {
currFlow = (FlowNode) flowElement;
break;
}
}
}
//获取目标节点
FlowNode targetFlow = (FlowNode) bpmnModel.getFlowElement(approvalOpinionVO.getRunNodeId());
//如果不是同一个流程(子流程)不能驳回
if (!(currFlow.getParentContainer().equals(targetFlow.getParentContainer()))) {
throw new CustomException("此处无法进行驳回操作");
}
//记录原活动方向
List<SequenceFlow> oriSequenceFlows = Lists.newArrayList();
oriSequenceFlows.addAll(currFlow.getOutgoingFlows());
//清理活动方向
currFlow.getOutgoingFlows().clear();
//建立新的方向
List<SequenceFlow> newSequenceFlows = Lists.newArrayList();
SequenceFlow newSequenceFlow = new SequenceFlow();
String uuid = UUID.randomUUID().toString().replace("-", "");
newSequenceFlow.setId(uuid);
newSequenceFlow.setSourceFlowElement(currFlow); //原节点
newSequenceFlow.setTargetFlowElement(targetFlow); //目标节点
newSequenceFlows.add(newSequenceFlow);
currFlow.setOutgoingFlows(newSequenceFlows);
//审批意见叠加
//variables 审批意见 act_ru_variable 变量表
Map<String, Object> variables = task.getProcessVariables();
//拒绝,通过,驳回 驳回指定节点
List<ApprovalOpinionDTO> approvalOpinionDTOs = new ArrayList<>();
//获取工作流审批记录
Object options = variables.get(Constant.ACT_APPLY_OPINION_LIST);
if (null != options) {
approvalOpinionDTOs = JSONObject.parseArray(options.toString(), ApprovalOpinionDTO.class);
}
//添加审批过后的返回提升信息
ApprovalOpinionDTO applyOpinionDTO = ApprovalOpinionConverter.INSTANCE.vo2dto(approvalOpinionVO);
applyOpinionDTO.setFlagStr(applyOpinionDTO.getTaskNodeName()+"撤回到"+targetFlow.getName());
approvalOpinionDTOs.add(applyOpinionDTO);
map.put(Constant.ACT_APPLY_OPINION_LIST, JSONObject.toJSONString(approvalOpinionDTOs));
//完成节点任务
taskService.complete(task.getId(), map);
//恢复原方向
currFlow.setOutgoingFlows(oriSequenceFlows);
return true;
}
/*补充知识点
*complete(String taskId, Map<String,Object> variables)
*参数:taskId(对应act_ru_task中的id_),variables(下一次任务所需要的参数)
*作用:完成这一次任务,并且下一步任务需要流程变量的
*/
/**
* 审批处理
*
* @param approvalOpinionVO
* @return
*/
@Override
public boolean handleApproval(ApprovalOpinionVO approvalOpinionVO) {
Task task = taskService.createTaskQuery()
.taskTenantId(UserUtils.getTenantId()) //租户
.taskId(approvalOpinionVO.getTaskId())
.includeProcessVariables() //节点审批信息
.singleResult();
if (task == null) {
throw new CustomException("流程未启动或已执行完成");
}
if (StringUtils.isNotEmpty(task.getAssignee()) && !UserUtils.getUserId().equals(task.getAssignee())) {
throw new CustomException("当前用户不是审核人,无法进行审核");
}
//task.getAssignee() 获取审批人
if (StringUtils.isEmpty(task.getAssignee())) {
Set<String> candidates = getCandiates(task.getId());
if (candidates.isEmpty()) {
throw new CustomException("当前用户不是审核人,无法进行审核");
}
if (candidates.contains(UserUtils.getUserId())) {
taskService.claim(task.getId(), UserUtils.getUserId());
}
}
//获取流程变量
Map<String, Object> processVariables = task.getProcessVariables();
approvalOpinionVO.setCreateTime(new Date());
approvalOpinionVO.setOpId(UserUtils.getUserId());
approvalOpinionVO.setOpName(SystemUtil.getCurrUserDto().getName());
approvalOpinionVO.setTaskNodeName(task.getName());
Map<String, Object> map = Maps.newHashMap();
map.put(Constant.ACT_TASK_FLAG, approvalOpinionVO.getFlag()); //审批操作 结果
//驳回操作
if (DictEnum.APPLY_APPROVAL_OPINION_REJECT.getKey().equals(approvalOpinionVO.getFlag())) {
return rejected(approvalOpinionVO, task, map);
}
//驳回到指定步骤
if(DictEnum.APPLY_APPROVAL_OPINION_ASSIGN.getKey().equals(approvalOpinionVO.getFlag())){
return runNodes(approvalOpinionVO, task, map);
}
// 审批信息叠加
List<ApprovalOpinionDTO> opinionDTOS = new ArrayList<>();
Object options = processVariables.get(Constant.ACT_APPLY_OPINION_LIST);
if (options != null) {
opinionDTOS = JSONObject.parseArray(options.toString(), ApprovalOpinionDTO.class);
}
ApprovalOpinionDTO applyOpinionDTO = ApprovalOpinionConverter.INSTANCE.vo2dto(approvalOpinionVO);
opinionDTOS.add(applyOpinionDTO);
map.put(Constant.ACT_APPLY_OPINION_LIST, JSONObject.toJSONString(opinionDTOS));
taskService.complete(applyOpinionDTO.getTaskId(), map);
return true;
}
欢迎大家留言讨论
如有转载请标明出处