| | |
| | | import com.ycl.common.core.domain.entity.SysUser; |
| | | import com.ycl.common.enums.FlowComment; |
| | | import com.ycl.common.enums.business.TaskStatusEnum; |
| | | import com.ycl.common.utils.SecurityUtils; |
| | | import com.ycl.domain.entity.SysForm; |
| | | import com.ycl.domain.vo.FormDetailVO; |
| | | import com.ycl.flow.FindNextNodeUtil; |
| | | import com.ycl.service.ISysFormService; |
| | | import com.ycl.system.service.ISysUserService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.flowable.bpmn.model.*; |
| | | import org.flowable.bpmn.model.Process; |
| | |
| | | import org.flowable.engine.TaskService; |
| | | import org.flowable.engine.history.HistoricProcessInstance; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.flowable.identitylink.api.IdentityLink; |
| | | import org.flowable.identitylink.api.IdentityLinkType; |
| | | import org.flowable.task.api.Task; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | private final RepositoryService repositoryService; |
| | | private final TaskService taskService; |
| | | private final HistoryService historyService; |
| | | private final ISysUserService sysUserService; |
| | | |
| | | /** |
| | | * 通过当前节点定义key,获取其上一个节点的信息,如果前面是并行的会返回多个(包含当前节点) |
| | | * |
| | | * @param processDefId 流程定义id |
| | | * @param currentNodeDefId 当前节点定义id |
| | | * @param sysFormService 表单服务层 |
| | | * @param processDefId 流程定义id |
| | | * @param currentNodeDefId 当前节点定义id |
| | | * @param sysFormService 表单服务层 |
| | | * @param needInitCurrentForm 是否需要初始化当前节点的表单数据,一般查询已完成的任务详情需要 |
| | | * @return |
| | | */ |
| | |
| | | throw new RuntimeException("未找到该任务的流程定义节点"); |
| | | } |
| | | |
| | | // 获取当前节点的输入 |
| | | // 获取当前节点的信息 |
| | | List<FormDetailVO> defKeys = new ArrayList<>(2); |
| | | FormDetailVO formDetailVO = new FormDetailVO(); |
| | | formDetailVO.setCurrent(Boolean.TRUE); |
| | | formDetailVO.setBeforeNodeDefId(currentElement.getId()); |
| | | formDetailVO.setBeforeNodeName(currentElement.getName()); |
| | | if (StringUtils.hasText(currentElement.getFormKey())) { |
| | | FormDetailVO formDetailVO = new FormDetailVO(); |
| | | formDetailVO.setBeforeNodeDefId(currentElement.getId()); |
| | | formDetailVO.setBeforeNodeName(currentElement.getName()); |
| | | formDetailVO.setCurrent(Boolean.TRUE); |
| | | |
| | | if (needInitCurrentForm) { |
| | | SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(currentElement.getFormKey())); |
| | |
| | | } |
| | | Map<String, Object> data = new HashMap<>(1); |
| | | data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent())); |
| | | |
| | | formDetailVO.setFormJsonObj(data); |
| | | } |
| | | |
| | | defKeys.add(formDetailVO); |
| | | } |
| | | formDetailVO.setCanJump(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_JUMP_TEXT)); |
| | | formDetailVO.setCanWait(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_WAIT_TEXT)); |
| | | formDetailVO.setCanHangup(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_HANGUP_TEXT)); |
| | | |
| | | defKeys.add(formDetailVO); |
| | | this.beforeNodeInfo(currentElement, defKeys); |
| | | |
| | | return defKeys; |
| | |
| | | private void beforeNodeInfo(FlowElement currentElement, List<FormDetailVO> defKeys) { |
| | | if (currentElement instanceof UserTask) { |
| | | UserTask userTask = (UserTask) currentElement; |
| | | if (! CollectionUtils.isEmpty(userTask.getIncomingFlows())) { |
| | | if (!CollectionUtils.isEmpty(userTask.getIncomingFlows())) { |
| | | for (SequenceFlow incomingFlow : userTask.getIncomingFlows()) { |
| | | if (incomingFlow.getSourceFlowElement() instanceof UserTask) { |
| | | FormDetailVO formDetailVO = new FormDetailVO(); |
| | | formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId()); |
| | | formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName()); |
| | | formDetailVO.setCanJump(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_JUMP_TEXT)); |
| | | formDetailVO.setCanWait(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_WAIT_TEXT)); |
| | | defKeys.add(formDetailVO); |
| | | } else { |
| | | beforeNodeInfo(incomingFlow.getSourceFlowElement(), defKeys); |
| | | } |
| | | } |
| | | } |
| | | } else if (currentElement instanceof Gateway ){ |
| | | } else if (currentElement instanceof Gateway) { |
| | | Gateway gateway = (Gateway) currentElement; |
| | | if (! CollectionUtils.isEmpty(gateway.getIncomingFlows())) { |
| | | if (!CollectionUtils.isEmpty(gateway.getIncomingFlows())) { |
| | | for (SequenceFlow incomingFlow : gateway.getIncomingFlows()) { |
| | | if (incomingFlow.getSourceFlowElement() instanceof UserTask) { |
| | | FormDetailVO formDetailVO = new FormDetailVO(); |
| | | formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId()); |
| | | formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName()); |
| | | formDetailVO.setCanJump(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_JUMP_TEXT)); |
| | | formDetailVO.setCanWait(this.checkHasExeProperty(currentElement.getExtensionElements().get("properties"), ProcessConstants.EXTENSION_PROPERTY_CAN_WAIT_TEXT)); |
| | | defKeys.add(formDetailVO); |
| | | } else { |
| | | beforeNodeInfo(incomingFlow.getSourceFlowElement(), defKeys); |
| | |
| | | /** |
| | | * 获取当前节点的上一节点id,不反悔当前节点信息,如果前面是并行,那么会返回多个 |
| | | * |
| | | * @param processDefId 流程定义id |
| | | * @param processDefId 流程定义id |
| | | * @param currentNodeDefId 当前节点定义id |
| | | * @return |
| | | */ |
| | |
| | | |
| | | |
| | | /** |
| | | * 检查任务节点是否配置了:需要审核 的扩展属性 |
| | | * 检查任务节点是否配置了某个的扩展属性 |
| | | * |
| | | * @param extensionElements 扩展列表 |
| | | * @return |
| | | */ |
| | | public Boolean checkTaskNeedAuditing(List<ExtensionElement> extensionElements) { |
| | | public Boolean checkHasExeProperty(List<ExtensionElement> extensionElements, String exePropertyName) { |
| | | if (CollectionUtils.isEmpty(extensionElements)) { |
| | | return Boolean.FALSE; |
| | | } |
| | | for (ExtensionElement extensionElement : extensionElements) { |
| | | return extensionElements.stream().anyMatch(extensionElement -> { |
| | | if (CollectionUtils.isEmpty(extensionElement.getAttributes())) { // 如果本身没有属性,则递归child |
| | | return checkTaskNeedAuditing(extensionElement.getChildElements().get("property")); |
| | | return checkHasExeProperty(extensionElement.getChildElements().get("property"), exePropertyName); |
| | | } else { |
| | | // 否则先查本身的属性有不有:需要审核 的属性,没有也是递归child |
| | | if (extensionElement.getAttributes().get("name").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_TEXT.equals(attribute.getValue())) |
| | | && extensionElement.getAttributes().get("value").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_VALUE.equals(attribute.getValue())) |
| | | // 否则先查本身的属性有不有,没有也是递归child |
| | | if (extensionElement.getAttributes().get("name").stream().anyMatch(attribute -> exePropertyName.equals(attribute.getValue())) |
| | | && extensionElement.getAttributes().get("value").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_VALUE.equals(attribute.getValue())) |
| | | ) { |
| | | return Boolean.TRUE; |
| | | } else { |
| | | return checkTaskNeedAuditing(extensionElement.getChildElements().get("property")); |
| | | return checkHasExeProperty(extensionElement.getChildElements().get("property"), exePropertyName); |
| | | } |
| | | } |
| | | } |
| | | return Boolean.FALSE; |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | * 驳回任务 |
| | | * |
| | | * @param rejectedTaskDefKey 被驳回的任务key |
| | | * @param rejectTaskDefKey 执行驳回操作所在的任务key |
| | | * @param processInsId 流程实例id |
| | | * @param taskId 当前任务id |
| | | * @param msg 审核意见 |
| | | * @param rejectTaskDefKey 执行驳回操作所在的任务key |
| | | * @param processInsId 流程实例id |
| | | * @param taskId 当前任务id |
| | | * @param msg 审核意见 |
| | | */ |
| | | @Deprecated |
| | | public void reject(String rejectedTaskDefKey, String rejectTaskDefKey, String processInsId, String taskId, String msg) { |
| | | // 驳回的核心api:runtimeService.createChangeActivityStateBuilder().moveXXX 的api,可以设置从当前节点移动到目标节点 |
| | | // 驳回的核心:需要找到当前节点、以及要流转到的目标节点。其中比较麻烦的是处理并行等比较复杂的情况 |
| | |
| | | // 设置两条评论 |
| | | 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); |
| | | taskService.addComment(taskId, processInsId, FlowComment.REJECT.getType(), msg1 + msg); |
| | | // TODO 直接使用这个api好像有问题 |
| | | runtimeService.createChangeActivityStateBuilder().processInstanceId(processInsId).moveActivityIdTo(rejectTaskDefKey, rejectedTaskDefKey).changeState(); |
| | | runtimeService.createChangeActivityStateBuilder().processInstanceId(processInsId).moveExecutionToActivityId(rejectTaskDefKey, rejectedTaskDefKey).changeState(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取当前用户的组 |
| | | * |
| | | * @return |
| | | */ |
| | | public List<String> getCurrentUserGroups() { |
| | | String deptId = "dept:" + SecurityUtils.getLoginUser().getDeptId(); |
| | | List<String> roleIds; |
| | | if (CollectionUtils.isEmpty(SecurityUtils.getLoginUser().getUser().getRoles())) { |
| | | roleIds = new ArrayList<>(1); |
| | | } else { |
| | | roleIds = SecurityUtils.getLoginUser().getUser().getRoles().stream().map(role -> role.getRoleId() + "").collect(Collectors.toList()); |
| | | } |
| | | roleIds.add(deptId); |
| | | return roleIds; |
| | | } |
| | | |
| | | } |