| | |
| | | |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.ycl.common.constant.ProcessConstants; |
| | | import com.ycl.common.enums.FlowComment; |
| | | import com.ycl.domain.entity.SysForm; |
| | | import com.ycl.domain.vo.FormDetailVO; |
| | | import com.ycl.flow.FindNextNodeUtil; |
| | |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.bpmn.model.Process; |
| | | import org.flowable.engine.HistoryService; |
| | | import org.flowable.engine.RepositoryService; |
| | | import org.flowable.engine.RuntimeService; |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.StringUtils; |
| | |
| | | |
| | | private final RuntimeService runtimeService; |
| | | private final RepositoryService repositoryService; |
| | | private final TaskService taskService; |
| | | private final HistoryService historyService; |
| | | |
| | | /** |
| | | * 通过当前节点定义key,获取其上一个节点以及当前节点的信息,如果前面是并行的会返回多个 |
| | | * 通过当前节点定义key,获取其上一个节点的信息,如果前面是并行的会返回多个(包含当前节点) |
| | | * |
| | | * @param processDefId 流程定义id |
| | | * @param currentNodeDefId 当前节点定义id |
| | |
| | | |
| | | defKeys.add(formDetailVO); |
| | | } |
| | | this.beforeNodeInfo(currentElement, defKeys); |
| | | |
| | | return defKeys; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取当前节点的前置节点,不包含当前节点 |
| | | * |
| | | * @param processDefId |
| | | * @param currentNodeDefId |
| | | * @return |
| | | */ |
| | | public List<FormDetailVO> getBeforeNodeList(String processDefId, String currentNodeDefId) { |
| | | // 获取流程定义 |
| | | ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() |
| | | .processDefinitionId(processDefId) |
| | | .singleResult(); |
| | | |
| | | // 获取流程模型 |
| | | BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId); |
| | | if (bpmnModel == null) { |
| | | throw new RuntimeException("BpmnModel not found for processDefinitionId: " + processDefId); |
| | | } |
| | | |
| | | // 获取流程对象 |
| | | Process process = bpmnModel.getProcessById(processDefinition.getKey()); |
| | | if (process == null) { |
| | | throw new RuntimeException("Process not found for processDefinitionId: " + processDefId); |
| | | } |
| | | |
| | | // 遍历流程元素,找到对应的任务节点 |
| | | Collection<FlowElement> flowElements = process.getFlowElements(); |
| | | UserTask currentElement = null; |
| | | for (FlowElement flowElement : flowElements) { |
| | | if (flowElement instanceof UserTask && flowElement.getId().equals(currentNodeDefId)) { |
| | | currentElement = (UserTask) flowElement; |
| | | break; |
| | | } |
| | | } |
| | | if (Objects.isNull(currentElement)) { |
| | | throw new RuntimeException("未找到该任务的流程定义节点"); |
| | | } |
| | | |
| | | List<FormDetailVO> defKeys = new ArrayList<>(2); |
| | | |
| | | this.beforeNodeInfo(currentElement, defKeys); |
| | | |
| | | return defKeys; |
| | |
| | | return Boolean.FALSE; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 驳回任务 |
| | | * |
| | | * @param rejectedTaskDefKey 被驳回的任务key |
| | | * @param rejectTaskDefKey 执行驳回操作所在的任务key |
| | | * @param processInsId 流程实例id |
| | | * @param taskId 当前任务id |
| | | * @param msg 审核意见 |
| | | */ |
| | | public void reject(String rejectedTaskDefKey, String rejectTaskDefKey, String processInsId, String taskId, String msg) { |
| | | // 驳回的核心api:runtimeService.createChangeActivityStateBuilder().moveXXX 的api,可以设置从当前节点移动到目标节点 |
| | | // 驳回的核心:需要找到当前节点、以及要流转到的目标节点。其中比较麻烦的是处理并行等比较复杂的情况 |
| | | /** |
| | | * 驳回的情况分为以下三种: |
| | | * |
| | | * 1. 如果执行驳回操作的任务是在并行结束的后一个节点,那么被驳回的任务属于并行中的某个分支的结束节点 |
| | | * 2. 如果执行驳回操作的节点是并行开始后的某一分支的开始节点,那么该节点和被驳回节点实际上属于串行, 只不过需要同时把其它并行分支也驳回了(这里并不需要手动处理) |
| | | * 3. 如果 被驳回节点和驳回节点属于串行,则直接驳回无需考虑其它 |
| | | */ |
| | | // 所以重要的是判断两个任务之间是否存在特殊节点,目前只先考虑并行网关 |
| | | |
| | | // 设置两条评论 |
| | | List<HistoricTaskInstance> rejectedTaskList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInsId).taskDefinitionKey(rejectedTaskDefKey).orderByHistoricTaskInstanceStartTime().desc().list(); |
| | | String msg1 = "驳回了:【" + rejectedTaskList.get(0).getName() + "】,驳回原因:"; |
| | | taskService.addComment(taskId, processInsId, FlowComment.REJECT.getType(), msg1 + msg); |
| | | // TODO 直接使用这个api好像有问题 |
| | | runtimeService.createChangeActivityStateBuilder().processInstanceId(processInsId).moveActivityIdTo(rejectTaskDefKey, rejectedTaskDefKey).changeState(); |
| | | } |
| | | |
| | | } |