| | |
| | | import org.dromara.workflow.flowable.CustomDefaultProcessDiagramGenerator; |
| | | import org.dromara.workflow.flowable.cmd.DeleteExecutionCmd; |
| | | import org.dromara.workflow.flowable.cmd.ExecutionChildByExecutionIdCmd; |
| | | import org.dromara.workflow.flowable.strategy.FlowEventStrategy; |
| | | import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler; |
| | | import org.dromara.workflow.flowable.handler.FlowProcessEventHandler; |
| | | import org.dromara.workflow.service.IActHiProcinstService; |
| | | import org.dromara.workflow.service.IActProcessInstanceService; |
| | | import org.dromara.workflow.service.IWfNodeConfigService; |
| | |
| | | private final TaskService taskService; |
| | | private final IActHiProcinstService actHiProcinstService; |
| | | private final ManagementService managementService; |
| | | private final FlowEventStrategy flowEventStrategy; |
| | | private final IWfTaskBackNodeService iWfTaskBackNodeService; |
| | | private final IWfNodeConfigService iWfNodeConfigService; |
| | | private final IWfTaskBackNodeService wfTaskBackNodeService; |
| | | private final IWfNodeConfigService wfNodeConfigService; |
| | | private final FlowProcessEventHandler flowProcessEventHandler; |
| | | |
| | | @Value("${flowable.activity-font-name}") |
| | | private String activityFontName; |
| | |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = iWfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |
| | |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = iWfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 通过流程实例id获取历史流程图 |
| | | * 通过业务id获取历史流程图 |
| | | * |
| | | * @param processInstanceId 流程实例id |
| | | * @param businessKey 业务id |
| | | */ |
| | | @SneakyThrows |
| | | @Override |
| | | public String getHistoryImage(String processInstanceId) { |
| | | public String getHistoryImage(String businessKey) { |
| | | String processDefinitionId; |
| | | // 获取当前的流程实例 |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId).singleResult(); |
| | | ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey).singleResult(); |
| | | // 如果流程已经结束,则得到结束节点 |
| | | if (Objects.isNull(processInstance)) { |
| | | HistoricProcessInstance pi = QueryUtils.hisInstanceQuery(processInstanceId).singleResult(); |
| | | HistoricProcessInstance pi = QueryUtils.hisInstanceQuery().processInstanceBusinessKey(businessKey).singleResult(); |
| | | processDefinitionId = pi.getProcessDefinitionId(); |
| | | } else { |
| | | // 根据流程实例ID获得当前处于活动状态的ActivityId合集 |
| | | ProcessInstance pi = QueryUtils.instanceQuery(processInstanceId).singleResult(); |
| | | ProcessInstance pi = QueryUtils.instanceQuery(processInstance.getProcessInstanceId()).singleResult(); |
| | | processDefinitionId = pi.getProcessDefinitionId(); |
| | | } |
| | | |
| | | // 获得活动的节点 |
| | | List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list(); |
| | | List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstance.getProcessInstanceId()).orderByHistoricActivityInstanceStartTime().asc().list(); |
| | | |
| | | List<String> highLightedFlows = new ArrayList<>(); |
| | | List<String> highLightedNodes = new ArrayList<>(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 通过流程实例id获取历史流程图运行中,历史等节点 |
| | | * 通过业务id获取历史流程图运行中,历史等节点 |
| | | * |
| | | * @param processInstanceId 流程实例id |
| | | * @param businessKey 业务id |
| | | */ |
| | | @Override |
| | | public Map<String, Object> getHistoryList(String processInstanceId) { |
| | | public Map<String, Object> getHistoryList(String businessKey) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | List<Map<String, Object>> taskList = new ArrayList<>(); |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult(); |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult(); |
| | | String processInstanceId = historicProcessInstance.getId(); |
| | | StringBuilder xml = new StringBuilder(); |
| | | ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId()); |
| | | // 获取节点 |
| | |
| | | /** |
| | | * 获取审批记录 |
| | | * |
| | | * @param processInstanceId 流程实例id |
| | | * @param businessKey 业务id |
| | | */ |
| | | @Override |
| | | public Map<String, Object> getHistoryRecord(String processInstanceId) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | public List<ActHistoryInfoVo> getHistoryRecord(String businessKey) { |
| | | // 查询任务办理记录 |
| | | List<HistoricTaskInstance> list = QueryUtils.hisTaskInstanceQuery(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list(); |
| | | List<HistoricTaskInstance> list = QueryUtils.hisTaskBusinessKeyQuery(businessKey).orderByHistoricTaskInstanceEndTime().desc().list(); |
| | | list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo)).reversed()); |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult(); |
| | | String processInstanceId = historicProcessInstance.getId(); |
| | | List<ActHistoryInfoVo> actHistoryInfoVoList = new ArrayList<>(); |
| | | List<Comment> processInstanceComments = taskService.getProcessInstanceComments(processInstanceId); |
| | | //附件 |
| | |
| | | } |
| | | actHistoryInfoVoList.add(actHistoryInfoVo); |
| | | } |
| | | List<ActHistoryInfoVo> collect = new ArrayList<>(); |
| | | // 待办理 |
| | | List<ActHistoryInfoVo> waitingTask = StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() == null); |
| | | // 已办理 |
| | | List<ActHistoryInfoVo> finishTask = StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() != null); |
| | | collect.addAll(waitingTask); |
| | | collect.addAll(finishTask); |
| | | // 审批记录 |
| | | map.put("historyRecordList", collect); |
| | | List<ActHistoryInfoVo> nodeInfoList = new ArrayList<>(); |
| | | Map<String, List<ActHistoryInfoVo>> groupByKey = StreamUtils.groupByKey(actHistoryInfoVoList, ActHistoryInfoVo::getTaskDefinitionKey); |
| | | for (Map.Entry<String, List<ActHistoryInfoVo>> entry : groupByKey.entrySet()) { |
| | | ActHistoryInfoVo actHistoryInfoVo = BeanUtil.toBean(entry.getValue().get(0), ActHistoryInfoVo.class); |
| | |
| | | actHistoryInfoVo.setEndTime(null); |
| | | actHistoryInfoVo.setRunDuration(null); |
| | | }); |
| | | nodeInfoList.add(actHistoryInfoVo); |
| | | } |
| | | // 节点信息 |
| | | map.put("nodeListInfo", nodeInfoList); |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(list.get(0).getProcessDefinitionId()); |
| | | List<GraphicInfoVo> graphicInfoVos = new ArrayList<>(); |
| | | Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements(); |
| | | //节点图形信息 |
| | | buildGraphicInfo(flowElements, graphicInfoVos, bpmnModel); |
| | | map.put("graphicInfoVos", graphicInfoVos); |
| | | return map; |
| | | } |
| | | List<ActHistoryInfoVo> recordList = new ArrayList<>(); |
| | | // 待办理 |
| | | recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() == null)); |
| | | // 已办理 |
| | | recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() != null)); |
| | | |
| | | /** |
| | | * 构建节点图形信息 |
| | | * |
| | | * @param flowElements 节点 |
| | | */ |
| | | private static void buildGraphicInfo(Collection<FlowElement> flowElements, List<GraphicInfoVo> graphicInfoVos, BpmnModel bpmnModel) { |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof SubProcess) { |
| | | Collection<FlowElement> subFlowElements = ((SubProcess) flowElement).getFlowElements(); |
| | | buildGraphicInfo(subFlowElements, graphicInfoVos, bpmnModel); |
| | | } else { |
| | | if (flowElement instanceof UserTask) { |
| | | GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowElement.getId()); |
| | | GraphicInfoVo graphicInfoVo = BeanUtil.toBean(graphicInfo, GraphicInfoVo.class); |
| | | graphicInfoVo.setNodeId(flowElement.getId()); |
| | | graphicInfoVo.setNodeName(flowElement.getName()); |
| | | graphicInfoVos.add(graphicInfoVo); |
| | | } |
| | | } |
| | | } |
| | | return recordList; |
| | | } |
| | | |
| | | /** |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunInstance(ProcessInvalidBo processInvalidBo) { |
| | | try { |
| | | List<Task> list = QueryUtils.taskQuery(processInvalidBo.getProcessInstanceId()).list(); |
| | | List<Task> list = QueryUtils.taskQuery().processInstanceBusinessKey(processInvalidBo.getBusinessKey()).list(); |
| | | String processInstanceId = list.get(0).getProcessInstanceId(); |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | |
| | | for (Task task : StreamUtils.filter(list, e -> StringUtils.isBlank(e.getParentTaskId()))) { |
| | | taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.INVALID.getStatus(), deleteReason); |
| | | } |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInvalidBo.getProcessInstanceId()).singleResult(); |
| | | HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult(); |
| | | BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus()); |
| | | runtimeService.updateBusinessStatus(processInvalidBo.getProcessInstanceId(), BusinessStatusEnum.INVALID.getStatus()); |
| | | runtimeService.deleteProcessInstance(processInvalidBo.getProcessInstanceId(), deleteReason); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false); |
| | | } |
| | | runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.INVALID.getStatus()); |
| | | runtimeService.deleteProcessInstance(processInstanceId, deleteReason); |
| | | //流程作废监听 |
| | | flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(), |
| | | historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | /** |
| | | * 运行中的实例 删除程实例,删除历史记录,删除业务与流程关联信息 |
| | | * |
| | | * @param processInstanceIds 流程实例id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunAndHisInstance(List<String> processInstanceIds) { |
| | | try { |
| | | // 1.删除运行中流程实例 |
| | | List<Task> list = QueryUtils.taskQuery(processInstanceIds).list(); |
| | | List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId())); |
| | | if (CollUtil.isNotEmpty(subTasks)) { |
| | | subTasks.forEach(e -> taskService.deleteTask(e.getId())); |
| | | } |
| | | runtimeService.bulkDeleteProcessInstances(processInstanceIds, LoginHelper.getUserId() + "删除了当前流程申请"); |
| | | // 2.删除历史记录 |
| | | List<HistoricProcessInstance> historicProcessInstanceList = QueryUtils.hisInstanceQuery(new HashSet<>(processInstanceIds)).list(); |
| | | if (ObjectUtil.isNotEmpty(historicProcessInstanceList)) { |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | } |
| | | iWfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new ServiceException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 按照业务id删除 运行中的实例 删除程实例,删除历史记录,删除业务与流程关联信息 |
| | | * |
| | | * @param businessKeys 业务id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteRunAndHisInstanceByBusinessKeys(List<String> businessKeys) { |
| | | public boolean deleteRunAndHisInstance(List<String> businessKeys) { |
| | | try { |
| | | // 1.删除运行中流程实例 |
| | | List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys); |
| | |
| | | if (ObjectUtil.isNotEmpty(historicProcessInstanceList)) { |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | } |
| | | iWfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | /** |
| | | * 已完成的实例 删除程实例,删除历史记录,删除业务与流程关联信息 |
| | | * |
| | | * @param processInstanceIds 流程实例id |
| | | * @param businessKeys 业务id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean deleteFinishAndHisInstance(List<String> processInstanceIds) { |
| | | public boolean deleteFinishAndHisInstance(List<String> businessKeys) { |
| | | try { |
| | | List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys); |
| | | if (CollUtil.isEmpty(actHiProcinsts)) { |
| | | log.warn("当前业务ID:{}查询到流程实例为空!", businessKeys); |
| | | return false; |
| | | } |
| | | List<String> processInstanceIds = StreamUtils.toList(actHiProcinsts, ActHiProcinst::getId); |
| | | historyService.bulkDeleteHistoricProcessInstances(processInstanceIds); |
| | | iWfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | /** |
| | | * 撤销流程申请 |
| | | * |
| | | * @param processInstanceId 流程实例id |
| | | * @param businessKey 业务id |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean cancelProcessApply(String processInstanceId) { |
| | | public boolean cancelProcessApply(String businessKey) { |
| | | try { |
| | | ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId) |
| | | ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey) |
| | | .startedBy(String.valueOf(LoginHelper.getUserId())).singleResult(); |
| | | if (ObjectUtil.isNull(processInstance)) { |
| | | throw new ServiceException("您不是流程发起人,撤销失败!"); |
| | |
| | | if (processInstance.isSuspended()) { |
| | | throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED); |
| | | } |
| | | String processInstanceId = processInstance.getId(); |
| | | BusinessStatusEnum.checkCancelStatus(processInstance.getBusinessStatus()); |
| | | List<Task> taskList = QueryUtils.taskQuery(processInstanceId).list(); |
| | | for (Task task : taskList) { |
| | | taskService.setAssignee(task.getId(), null); |
| | | taskService.addComment(task.getId(), processInstanceId, TaskStatusEnum.CANCEL.getStatus(), LoginHelper.getLoginUser().getNickname() + ":撤销申请"); |
| | | } |
| | | HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery().finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0); |
| | | HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0); |
| | | List<String> nodeIds = StreamUtils.toList(taskList, Task::getTaskDefinitionKey); |
| | | runtimeService.createChangeActivityStateBuilder() |
| | | .processInstanceId(processInstanceId) |
| | |
| | | managementService.executeCommand(deleteExecutionCmd); |
| | | } |
| | | runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.CANCEL.getStatus()); |
| | | FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey()); |
| | | if (processHandler != null) { |
| | | processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false); |
| | | } |
| | | //流程作废监听 |
| | | flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), |
| | | processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | |
| | | } |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = iWfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds); |
| | | for (ProcessInstanceVo processInstanceVo : list) { |
| | | if (CollUtil.isNotEmpty(wfNodeConfigVoList)) { |
| | | wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo); |