更多ruoyi-nbcio功能请看演示系统
gitee源代码地址
前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio
演示地址:RuoYi-Nbcio后台管理系统
更多nbcio-boot功能请看演示系统
gitee源代码地址
后端代码: https://gitee.com/nbacheng/nbcio-boot
前端代码:https://gitee.com/nbacheng/nbcio-vue.git
在线演示(包括H5) : http://218.75.87.38:9888
这个功能在已办任务里,就是用户可以通过已办任务,而且最好是发起人可以进行任务的收回,收回后可以重新进行业务流程提交。
具体的代码如下,同时在自定义业务提交的时候做一个判断,符合这种情况可以进行提交:
@Override @Transactional(rollbackFor = Exception.class) public R recallProcess(WfTaskBo bo) { // 当前任务 listtask List<Task> listtask = taskService.createTaskQuery().processInstanceId(bo.getProcInsId()).active().list(); if (listtask == null || listtask.size()==0) { throw new FlowableException("流程未启动或已执行完成,无法收回"); } if (taskService.createTaskQuery().taskId(listtask.get(0).getId()).singleResult().isSuspended()) { throw new FlowableException("任务处于挂起状态"); } List<Task> procInsId = taskService.createNativeTaskQuery().sql("select * from ACT_HI_TASKINST where PROC_INST_ID_ = #{procInsId} ORDER BY START_TIME_ desc").parameter("procInsId", bo.getProcInsId()).list(); String processInstanceId = listtask.get(0).getProcessInstanceId(); // 获取所有历史任务(按创建时间升序) List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId).orderByTaskCreateTime() .asc() .list(); if (CollectionUtil.isEmpty(hisTaskList) || hisTaskList.size() < 2) { log.error("当前流程 【{}】 审批节点 【{}】正在初始节点无法收回", processInstanceId, listtask.get(0).getName()); throw new FlowableException(String.format("当前流程 【%s】 审批节点【%s】正在初始节点无法收回", processInstanceId, listtask.get(0).getName())); } // 第一个任务 HistoricTaskInstance startTask = hisTaskList.get(0); //若操作用户不是发起人,不能收回 if(!StringUtils.equalsAnyIgnoreCase(LoginHelper.getUsername(), startTask.getAssignee())) { throw new FlowableException("操作用户不是发起人,不能收回"); } // 当前任务 HistoricTaskInstance currentTask = hisTaskList.get(hisTaskList.size() - 1); BpmnModel bpmnModel = repositoryService.getBpmnModel(listtask.get(0).getProcessDefinitionId()); // 获取第一个活动节点 FlowNode startFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(startTask.getTaskDefinitionKey()); // 获取当前活动节点 FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentTask.getTaskDefinitionKey()); // 临时保存当前活动的原始方向 List<SequenceFlow> originalSequenceFlowList = new ArrayList<>(currentFlowNode.getOutgoingFlows()); // 清理活动方向 currentFlowNode.getOutgoingFlows().clear(); // 建立新方向 SequenceFlow newSequenceFlow = new SequenceFlow(); newSequenceFlow.setId("newSequenceFlowId"); newSequenceFlow.setSourceFlowElement(currentFlowNode); newSequenceFlow.setTargetFlowElement(startFlowNode); List<SequenceFlow> newSequenceFlowList = new ArrayList<>(); newSequenceFlowList.add(newSequenceFlow); // 当前节点指向新的方向 currentFlowNode.setOutgoingFlows(newSequenceFlowList); // 完成当前任务 for(Task task : listtask) { taskService.addComment(task.getId(), listtask.get(0).getProcessInstanceId(),FlowComment.RECALL.getType(), "发起人收回"); taskService.setAssignee(task.getId(), startTask.getAssignee()); taskService.complete(task.getId()); } // 重新查询当前任务 Task nextTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); if (ObjectUtil.isNotNull(nextTask)) { taskService.setAssignee(nextTask.getId(), startTask.getAssignee()); //taskService.complete(nextTask.getId());;//跳过流程发起节点 } //自定义业务处理id String dataId = bo.getDataId(); if(StringUtils.isNotEmpty(dataId)) { WfMyBusiness business = wfMyBusinessService.getByDataId(dataId); //更新删除自定义业务任务关联表与流程历史表,以便可以重新发起流程。 if (business != null) { business.setActStatus(ActStatus.recall); business.setTodoUsers(""); business.setDoneUsers(""); business.setProposer(""); business.setTaskName(""); business.setTaskId(""); business.setTaskNameId(""); wfMyBusinessService.updateById(business); } } // 删除运行和历史的节点信息 this.deleteActivity(procInsId.get(1).getTaskDefinitionKey(), bo.getProcInsId(), dataId); // 恢复原始方向 currentFlowNode.setOutgoingFlows(originalSequenceFlowList); return R.ok("发起人收回成功"); }
try { LambdaQueryWrapper<WfMyBusiness> wfMyBusinessLambdaQueryWrapper = new LambdaQueryWrapper<>(); wfMyBusinessLambdaQueryWrapper.eq(WfMyBusiness::getDataId, dataId); WfMyBusiness business = wfMyBusinessService.getOne(wfMyBusinessLambdaQueryWrapper); if (business==null || (business != null && business.getActStatus().equals(ActStatus.stop)) || (business != null && business.getActStatus().equals(ActStatus.recall))){ if(processDefinition==null) { return R.fail("自定义表单也没关联流程定义表,流程没定义关联自定义表单"+wfCustomForm.getId()); } boolean binit = wfCommonService.initActBusiness(wfCustomForm.getBusinessName(), dataId, serviceName, processDefinition.getKey(), processDefinition.getId(), wfCustomForm.getRouteName()); if(!binit) { return R.fail("自定义表单也没关联流程定义表,流程没定义关联自定义表单"+wfCustomForm.getId()); } WfMyBusiness businessnew = wfMyBusinessService.getOne(wfMyBusinessLambdaQueryWrapper); //流程实例关联初始化结束 if (StrUtil.isNotBlank(businessnew.getProcessDefinitionId())){ return this.startProcessByDefId(businessnew.getProcessDefinitionId(),variables); } return this.startProcessByDefKey(businessnew.getProcessDefinitionKey(),variables); } else { return R.fail("已经存在这个dataid实例,不要重复申请:"+dataId); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); }