diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmConstants.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmConstants.java index 9a8a24bce..7fb16200f 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmConstants.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmConstants.java @@ -47,6 +47,16 @@ public interface BpmConstants { String NUMBER_OF_INSTANCES = "nrOfInstances"; String MULTI_INSTANCE_LOOP_COUNTER = "loopCounter"; + /** + * 会签表达式 + */ + String AND_SIGN_EXPRESSION = "${nrOfInstances == nrOfCompletedInstances}"; + + /** + * 或签表达式 + */ + String OR_SIGN_EXPRESSION = "${nrOfCompletedInstances > 0}"; + /** * 全局的启用/上架等状态描述 */ diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/ProcessNodeDetailVO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/ProcessNodeDetailVO.java index 716da6488..2a5d588c7 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/ProcessNodeDetailVO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/response/bpmn/process/ProcessNodeDetailVO.java @@ -1,5 +1,6 @@ package cn.axzo.workflow.common.model.response.bpmn.process; +import cn.axzo.workflow.common.enums.BpmnFlowNodeMode; import lombok.Data; import lombok.experimental.Accessors; @@ -13,5 +14,24 @@ import lombok.experimental.Accessors; @Accessors(chain = true) public class ProcessNodeDetailVO { + /** + * 节点标识 + */ + private String id; + + /** + * 节点名称 + */ + private String name; + + /** + * 节点类型 + */ + private BpmnFlowNodeMode nodeMode; + + /** + * 关联的表单 Key + */ + private String formKey; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmTransformUtil.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmTransformUtil.java index cb0eda428..97bf6edb1 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmTransformUtil.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmTransformUtil.java @@ -35,8 +35,10 @@ import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmConstants.AND_SIGN_EXPRESSION; import static cn.axzo.workflow.common.constant.BpmConstants.BPM_ALLOW_SKIP_USER_TASK; import static cn.axzo.workflow.common.constant.BpmConstants.END_EVENT_ID; +import static cn.axzo.workflow.common.constant.BpmConstants.OR_SIGN_EXPRESSION; import static cn.axzo.workflow.core.common.enums.BpmErrorCode.CONVERTOR_META_DATA_FORMAT_ERROR; import static cn.axzo.workflow.core.common.enums.BpmErrorCode.CONVERTOR_UNKNOW_NODE_TYPE; import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION; @@ -380,10 +382,9 @@ public class BpmTransformUtil { // 设置多实例属性 userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics); if (BpmnFlowNodeMode.OR.getType().equals(mode.getType())) { - multiInstanceLoopCharacteristics.setCompletionCondition("${nrOfCompletedInstances > 0}"); + multiInstanceLoopCharacteristics.setCompletionCondition(OR_SIGN_EXPRESSION); } else if (BpmnFlowNodeMode.AND.getType().equals(mode.getType())) { - multiInstanceLoopCharacteristics.setCompletionCondition("${nrOfInstances == " + - "nrOfCompletedInstances}"); + multiInstanceLoopCharacteristics.setCompletionCondition(AND_SIGN_EXPRESSION); } } // 设置审批人为空时,允许自动通过 diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java index 3707f7b0e..4b1a8398b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessInstanceServiceImpl.java @@ -1,6 +1,7 @@ package cn.axzo.workflow.core.service.impl; import cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum; +import cn.axzo.workflow.common.enums.BpmnFlowNodeMode; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO; import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO; @@ -48,6 +49,7 @@ import org.flowable.bpmn.model.SignalEventDefinition; import org.flowable.bpmn.model.SubProcess; import org.flowable.bpmn.model.TextAnnotation; import org.flowable.bpmn.model.TimerEventDefinition; +import org.flowable.bpmn.model.UserTask; import org.flowable.bpmn.model.VariableListenerEventDefinition; import org.flowable.common.engine.impl.db.SuspensionState; import org.flowable.common.engine.impl.identity.Authentication; @@ -59,6 +61,8 @@ import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.history.NativeHistoricProcessInstanceQuery; +import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior; +import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.form.api.FormInfo; @@ -79,6 +83,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmConstants.AND_SIGN_EXPRESSION; import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_DELETE_PROCESS_FLAG; import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_TENANT_ID; import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_USER_ID; @@ -86,6 +91,8 @@ import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_USER_NA import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_INITIATOR; import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_PROCESS_TYPE_CANCEL; import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_SPECIFY_NEXT_APPROVER; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.AND; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeMode.OR; import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_ID_NOT_EXISTS; import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_IS_SUSPENDED; import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_DEFINITION_KEY_NOT_EXISTS; @@ -551,8 +558,23 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic throw new WorkflowEngineException(PROCESS_INSTANCE_ID_NOT_EXISTS, processInstanceId); } BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId()); - bpmnModel.getMainProcess().getFlowElements(); - return null; + List flowElements = + bpmnModel.getMainProcess().getFlowElements().stream().filter(UserTask.class::isInstance).collect(Collectors.toList()); + List resultList = new ArrayList<>(flowElements.size()); + flowElements.forEach(i -> { + UserTask userTask = (UserTask) i; + ProcessNodeDetailVO node = new ProcessNodeDetailVO().setId(userTask.getId()) + .setName(userTask.getName()) + .setFormKey(userTask.getFormKey()); + if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) { + MultiInstanceActivityBehavior behavior = (MultiInstanceActivityBehavior) userTask.getBehavior(); + node.setNodeMode(Objects.equals(AND_SIGN_EXPRESSION, behavior.getCompletionCondition()) ? AND : OR); + } else if (userTask.getBehavior() instanceof UserTaskActivityBehavior) { + node.setNodeMode(BpmnFlowNodeMode.GENERAL); + } + resultList.add(node); + }); + return resultList; } private List gatherCompletedFlows(Set completedActivityInstances, diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java index a4f47ea95..2749a0d19 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java @@ -1,12 +1,24 @@ package cn.axzo.workflow.core.service.impl; import cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.*; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; -import cn.axzo.workflow.common.model.response.bpmn.task.*; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.service.BpmnTaskService; -import cn.axzo.workflow.core.service.converter.*; +import cn.axzo.workflow.core.service.converter.BpmnHistoricCommentConverter; +import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskDonePageItemConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskTodoPageItemConverter; import cn.hutool.core.collection.CollUtil; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.Activity; @@ -14,7 +26,11 @@ import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.UserTask; import org.flowable.common.engine.impl.identity.Authentication; -import org.flowable.engine.*; +import org.flowable.engine.HistoryService; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; @@ -34,13 +50,40 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.workflow.common.constant.BpmConstants.*; -import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.*; -import static cn.axzo.workflow.core.common.enums.BpmErrorCode.*; +import static cn.axzo.workflow.common.constant.BpmConstants.APPROVAL_ENDS_AUTOMATICALLY; +import static cn.axzo.workflow.common.constant.BpmConstants.COMMENT_TYPE_ADVICE; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_DELETE_PROCESS_FLAG; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_TENANT_ID; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_USER_ID; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_END_USER_NAME; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_PROCESS_TYPE_REJECT; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_SPECIFY_NEXT_APPROVER; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO; +import static cn.axzo.workflow.common.constant.BpmConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT; +import static cn.axzo.workflow.common.constant.BpmConstants.MULTI_INSTANCE_LOOP_COUNTER; +import static cn.axzo.workflow.common.constant.BpmConstants.NUMBER_OF_INSTANCES; +import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.APPROVED; +import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.CANCELLED; +import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.PROCESSING; +import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.REJECTED; +import static cn.axzo.workflow.common.enums.BpmProcessInstanceResultEnum.valueOfStatus; +import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_INSTANCE_ID_NOT_EXISTS; +import static cn.axzo.workflow.core.common.enums.BpmErrorCode.PROCESS_INSTANCE_NOT_EXISTS; +import static cn.axzo.workflow.core.common.enums.BpmErrorCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF; +import static cn.axzo.workflow.core.common.enums.BpmErrorCode.TASK_COMPLETE_FAIL_NOT_EXISTS; import static cn.axzo.workflow.core.common.utils.BpmCollectionUtils.convertSet; import static cn.axzo.workflow.core.service.impl.BpmnProcessInstanceServiceImpl.countSql; import static cn.axzo.workflow.core.service.impl.BpmnProcessInstanceServiceImpl.sqlConnectors; @@ -383,8 +426,11 @@ public class BpmnTaskServiceImpl implements BpmnTaskService { HistoricVariableInstance assgineeSnapshot = variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskDefinitionKey() , null); - vo.setAssigneeSnapshot(Objects.nonNull(assgineeSnapshot) ? - (BpmnTaskDelegateAssigner) assgineeSnapshot.getValue() : null); + + BpmnTaskDelegateAssigner assigner = Objects.nonNull(assgineeSnapshot) ? + (BpmnTaskDelegateAssigner) assgineeSnapshot.getValue() : null; + vo.setAssignee(Objects.isNull(assigner) ? "" : assigner.getAssignee()); + vo.setAssigneeSnapshot(assigner); count++; } return vos; @@ -416,7 +462,7 @@ public class BpmnTaskServiceImpl implements BpmnTaskService { } else if (entry.getValue().stream().anyMatch(i -> Objects.equals(PROCESSING, i.getResult()))) { groupVO.setResult(PROCESSING); } else if (entry.getValue().stream().anyMatch(i -> Objects.equals(REJECTED, i.getResult()))) { - // FIXME 明显存在问题 + // FIXME 等版本迭代进行逻辑修复 groupVO.setResult(REJECTED); } }