Merge branch 'feature/REQ-1309' into dev

This commit is contained in:
wangli 2023-10-07 17:23:11 +08:00
commit 9905c959a3
5 changed files with 115 additions and 16 deletions

View File

@ -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}";
/**
* 全局的启用/上架等状态描述
*/

View File

@ -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;
}

View File

@ -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);
}
}
// 设置审批人为空时,允许自动通过

View File

@ -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<FlowElement> flowElements =
bpmnModel.getMainProcess().getFlowElements().stream().filter(UserTask.class::isInstance).collect(Collectors.toList());
List<ProcessNodeDetailVO> 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<String> gatherCompletedFlows(Set<String> completedActivityInstances,

View File

@ -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);
}
}