add - 新增节点运行时查询审批候选人的逻辑框架, 未对具体的查询审批人做实现.

This commit is contained in:
wangli 2023-11-16 15:55:56 +08:00
parent e445f4a245
commit d4b4f97f17
18 changed files with 514 additions and 35 deletions

View File

@ -0,0 +1,40 @@
package cn.axzo.workflow.common.enums;
/**
* 审批方式枚举
*
* @author wangli
* @since 2023/11/16 10:10
*/
public enum ApprovalMethodEnum {
human("human", "人工审批"),
autoPassed("autoPassed", "自动通过"),
autoRejection("autoRejection", "自动拒绝"),
nobody("nobody", "不审批[仅业务节点可能有该值]"),
;
private String type;
private String desc;
ApprovalMethodEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.workflow.common.enums;
/**
* 审批人为空时的处理方式枚举
*
* @author wangli
* @since 2023/11/16 10:22
*/
public enum ApproverEmptyHandleTypeEnum {
autoPassed("autoPassed", "自动通过"),
autoSkipped("autoSkipped", "自动跳过"),
transferToAdmin("transferToAdmin", "转交给管理员"),
;
private String type;
private String desc;
ApproverEmptyHandleTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.workflow.common.enums;
/**
* 审批人所在范围枚举
*
* @author wangli
* @since 2023/11/16 10:14
*/
public enum ApproverScopeEnum {
entWorkspace("entWorkspace", "企业工作台"),
projectWorkspace("projectWorkspace", "项目工作台"),
preTaskUser("preTaskUser", "上节点审批人所在单位"),
;
private String type;
private String desc;
ApproverScopeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@ -0,0 +1,41 @@
package cn.axzo.workflow.common.enums;
/**
* 审批人指定枚举
*
* @author wangli
* @since 2023/11/16 10:16
*/
public enum ApproverSpecifyEnum {
position("position", "指定职位"),
role("role", "指定角色"),
identity("identity", "指定身份"),
initiatorLeader("initiatorLeader", "发起人主管"),
initiatorLeaderRecursion("initiatorLeaderRecursion", "发起人多级主管"),
fixedPerson("fixedPerson", "固定人员"),
;
private String type;
private String desc;
ApproverSpecifyEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@ -1,5 +1,9 @@
package cn.axzo.workflow.common.model.request.bpmn;
import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
import cn.axzo.workflow.common.enums.ApproverScopeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -23,7 +27,7 @@ public class BpmnJsonNodeProperty {
@ApiModelProperty(value = "任务节点: 审批方式", notes = "human: 人工审批, autoPassed: 自动通过, autoRejection: 自动拒绝, nobody: " +
"不审批[仅业务节点可能有该值]")
@NotBlank(message = "审批方式不能为空")
private String approvalMethod;
private ApprovalMethodEnum approvalMethod;
//************* 审批方式End **************//
@ -33,18 +37,19 @@ public class BpmnJsonNodeProperty {
*/
@ApiModelProperty(value = "任务节点: 审批人所在范围", notes = "entWorkspace: 企业工作台, projectWorkspace: 项目工作台, preTaskUser:" +
" 上节点审批人所在单位")
private String approverScope;
private ApproverScopeEnum approverScope;
//************* 审批人所在范围End **************//
//************* 审批人指定Start **************//
/**
* 审批人指定: position(指定岗位), role(指定角色), identity(指定身份), initiatorLeader(发起人主管)
* 审批人指定: position(指定岗位), role(指定角色), identity(指定身份), initiatorLeader(发起人主管), initiatorLeaderRecursion(发起人多级主管),
* fixedPerson(固定人员)
*/
@ApiModelProperty(value = "任务节点: 审批人指定", notes = "position: 指定岗位, role: 指定角色, identity: 指定身份, initiatorLeader: " +
"发起人主管")
"发起人主管, initiatorLeaderRecursion: 发起人多级主管, fixedPerson: 固定人员")
@NotBlank(message = "审批人指定不能为空")
private String approverSpecify;
private ApproverSpecifyEnum approverSpecify;
/**
* 具体的配置值
@ -76,7 +81,7 @@ public class BpmnJsonNodeProperty {
*/
@ApiModelProperty(value = "任务节点: 审批人为空处理方式", notes = "autoPassed: 自动通过, autoSkipped: 自动跳过, transferToAdmin: 转交给管理员")
@NotBlank(message = "审批人为空处理方式不能为空")
private String approverEmptyHandleType;
private ApproverEmptyHandleTypeEnum approverEmptyHandleType;
//************* 审批人为空时的策略End **************//

View File

@ -1,17 +1,26 @@
package cn.axzo.workflow.core.common.utils;
import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import com.google.common.collect.Lists;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_EMPTY_HANDLE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_SPECIFY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NODE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION;
@ -30,13 +39,36 @@ public final class BpmnMetaParserHelper {
}
public static Optional<BpmnFlowNodeType> getNodeType(FlowElement flowElement) {
return defaultValid(flowElement, CONFIG_NODE_TYPE)
.map(element -> BpmnFlowNodeType.valueOfType(element.getElementText()));
if (flowElement instanceof UserTask
|| flowElement instanceof ServiceTask
|| flowElement instanceof ReceiveTask) {
return defaultValid(flowElement, CONFIG_NODE_TYPE)
.map(element -> BpmnFlowNodeType.valueOf(element.getElementText()));
}
return Optional.empty();
}
public static Optional<String> getApprovalMethod(UserTask userTask) {
public static Optional<ApprovalMethodEnum> getApprovalMethod(UserTask userTask) {
return defaultValid(userTask, CONFIG_APPROVAL_METHOD)
.map(element -> element.getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE));
.map(element -> ApprovalMethodEnum.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE)));
}
public static Optional<ApproverSpecifyEnum> getApproverSpecify(UserTask userTask) {
return defaultValid(userTask, CONFIG_APPROVER_SPECIFY)
.map(element -> ApproverSpecifyEnum.valueOf(element.getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE)));
}
public static Optional<List<String>> getApproverSpecifyValue(UserTask userTask) {
return defaultValid(userTask, CONFIG_APPROVER_SPECIFY)
.map(element -> StringUtils.hasLength(element.getElementText())
? Lists.newArrayList(StringUtils.commaDelimitedListToStringArray(element.getElementText()))
: Collections.emptyList());
}
public static Optional<ApproverEmptyHandleTypeEnum> getApproverEmptyHandleType(UserTask userTask) {
return defaultValid(userTask, CONFIG_APPROVER_EMPTY_HANDLE_TYPE)
.map(element -> ApproverEmptyHandleTypeEnum.valueOf(element.getAttributeValue(null,
ELEMENT_ATTRIBUTE_VALUE)));
}
private static Optional<ExtensionElement> defaultValid(FlowElement flowElement, String elementName) {

View File

@ -6,7 +6,9 @@ import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_NODE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_NODE_JSON;
@ -24,19 +26,24 @@ public abstract class AbstractBpmnJsonConverter<T extends FlowElement> {
}
public final void addNodeTypeAttribute(T flowElement, BpmnJsonNode jsonNode) {
ExtensionElement nodeTypeElement = new ExtensionElement();
nodeTypeElement.setName(CONFIG_NODE_TYPE);
nodeTypeElement.setElementText(jsonNode.getType().getType());
flowElement.addExtensionElement(nodeTypeElement);
if (flowElement instanceof UserTask
|| flowElement instanceof ServiceTask
|| flowElement instanceof ReceiveTask) {
ExtensionElement nodeTypeElement = new ExtensionElement();
nodeTypeElement.setName(CONFIG_NODE_TYPE);
nodeTypeElement.setElementText(jsonNode.getType().getType());
flowElement.addExtensionElement(nodeTypeElement);
}
}
public final void addJsonValueAttribute(T flowElement, BpmnJsonNode jsonNode) {
if (flowElement instanceof SequenceFlow) {
return;
if (flowElement instanceof UserTask
|| flowElement instanceof ServiceTask
|| flowElement instanceof ReceiveTask) {
ExtensionElement jsonValueElement = new ExtensionElement();
jsonValueElement.setName(FLOW_NODE_JSON);
jsonValueElement.setElementText(JSON.toJSONString(jsonNode));
flowElement.addExtensionElement(jsonValueElement);
}
ExtensionElement jsonValueElement = new ExtensionElement();
jsonValueElement.setName(FLOW_NODE_JSON);
jsonValueElement.setElementText(JSON.toJSONString(jsonNode));
flowElement.addExtensionElement(jsonValueElement);
}
}

View File

@ -24,6 +24,20 @@ public class SequenceFlowJsonConverter extends AbstractBpmnJsonConverter<Sequenc
sequenceFlow.setId(id(SEQUENCE_FLOW_ID));
sequenceFlow.setSourceRef(incoming.get(0));
sequenceFlow.setTargetRef(node.getId());
// 设置条件表达式
setConditionExpression(node, sequenceFlow);
return sequenceFlow;
}
/**
* 设置条件表达式
*
* @param node
* @param sequenceFlow
*/
private void setConditionExpression(BpmnJsonNode node, SequenceFlow sequenceFlow) {
// TODO 解析条件组及条件, 转换成引擎能识别的表达式
}
}

View File

@ -1,6 +1,8 @@
package cn.axzo.workflow.core.converter.json;
import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty;
@ -35,6 +37,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_D
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.OR_SIGN_EXPRESSION;
import static cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum.autoPassed;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
import static cn.axzo.workflow.core.common.utils.BpmnJsonConverterUtil.buildMetaButton;
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
@ -55,7 +58,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
userTask.setName(node.getName());
// 设置审批人为空时,允许自动通过
setAutoCompleted(node, userTask);
setAutoPassed(node, userTask);
// 设置会签或签
setMultiInstance(node, userTask);
// 设置全局任务监听器
@ -76,9 +79,9 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
return userTask;
}
private static void setAutoCompleted(BpmnJsonNode node, UserTask userTask) {
private static void setAutoPassed(BpmnJsonNode node, UserTask userTask) {
if (Objects.nonNull(node.getProperty()) &&
Objects.equals(node.getProperty().getApproverEmptyHandleType(), "autoPassed")) {
Objects.equals(node.getProperty().getApproverEmptyHandleType(), autoPassed)) {
userTask.setSkipExpression("${" + BPM_ALLOW_SKIP_USER_TASK + "}");
}
}
@ -147,23 +150,26 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute();
approvalMethodValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approvalMethodValueAttribute.setValue(property.getApprovalMethod());
approvalMethodValueAttribute.setValue(property.getApprovalMethod().getType());
approvalMethodElement.addAttribute(approvalMethodValueAttribute);
ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute();
approvalMethodDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
approvalMethodDescAttribute.setValue("审批方式");
approvalMethodElement.addAttribute(approvalMethodDescAttribute);
userTask.addExtensionElement(approvalMethodElement);
if (BpmnFlowNodeType.NODE_BUSINESS.equals(node.getType()) && ApprovalMethodEnum.nobody.equals(property.getApprovalMethod())) {
// 业务节点有一种不设置审批人的选项, "审批方式"外都是空配置, 所以在此直接中断后端的扩展属性配置
return;
}
// 审批人所在范围
ExtensionElement approverScopeElement = new ExtensionElement();
approverScopeElement.setName(CONFIG_APPROVER_SCOPE);
ExtensionAttribute approverScopeValueAttribute = new ExtensionAttribute();
approverScopeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverScopeValueAttribute.setValue(property.getApproverScope());
approverScopeValueAttribute.setValue(property.getApproverScope().getType());
approverScopeElement.addAttribute(approverScopeValueAttribute);
ExtensionAttribute approverScopeDescAttribute = new ExtensionAttribute();
@ -178,7 +184,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute();
approverSpecifyValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverSpecifyValueAttribute.setValue(property.getApproverSpecify());
approverSpecifyValueAttribute.setValue(property.getApproverSpecify().getType());
approverSpecifyElement.addAttribute(approverSpecifyValueAttribute);
ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute();
@ -209,7 +215,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
approverEmptyHandleTypeElement.setName(CONFIG_APPROVER_EMPTY_HANDLE_TYPE);
ExtensionAttribute approverEmptyHandleTypeValueAttribute = new ExtensionAttribute();
approverEmptyHandleTypeValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
approverEmptyHandleTypeValueAttribute.setValue(property.getApproverEmptyHandleType());
approverEmptyHandleTypeValueAttribute.setValue(property.getApproverEmptyHandleType().getType());
approverEmptyHandleTypeElement.addAttribute(approverEmptyHandleTypeValueAttribute);
ExtensionAttribute approverEmptyHandleTypeDescAttribute = new ExtensionAttribute();

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"转交给管理员"查询审批人
*
* @author wangli
* @since 2023/11/16 11:44
*/
@Component
public class AdminTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverEmptyHandleTypeEnum.transferToAdmin.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,32 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import java.util.List;
/**
* 任务节点的审批人查询器接口
*
* @author wangli
* @since 2023/11/16 10:43
*/
public interface BpmnTaskAssigneeSelector {
/**
* 判断是否支持当前审批指定类型
*
* @param param
* @return
*/
boolean support(String param);
/**
* 查询具体审批人
*
* @param userTask
* @return
*/
List<BpmnTaskDelegateAssigner> select(UserTask userTask);
}

View File

@ -5,6 +5,12 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import java.util.List;
/**
* 该接口适用于枢智版本, 后续新版本都使用 {@link BpmnTaskAssigneeSelector}
*
* @deprecated 1.2.1-SNAPSHOT
*/
@Deprecated
public interface BpmnTaskDelegate {
List<BpmnTaskDelegateAssigner> calculateAssignerAtExecution(BpmnTaskCalculateDTO delegateTask);
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"身份"查询审批人
*
* @author wangli
* @since 2023/11/16 11:38
*/
@Component
public class IdentityTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.identity.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 给予"发起人多级主管"查询审批人
*
* @author wangli
* @since 2023/11/16 11:42
*/
@Component
public class InitiatorLeaderRecursionTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.initiatorLeaderRecursion.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"发起人多级主管"查询审批人
*
* @author wangli
* @since 2023/11/16 11:41
*/
@Component
public class InitiatorLeaderTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.initiatorLeader.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"岗位"查询审批人
*
* @author wangli
* @since 2023/11/16 11:35
*/
@Component
public class PositionTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.position.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.workflow.core.deletage;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import org.flowable.bpmn.model.UserTask;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 基于"角色"查询审批人
*
* @author wangli
* @since 2023/11/16 11:37
*/
@Component
public class RoleTaskAssigneeSelector implements BpmnTaskAssigneeSelector {
@Override
public boolean support(String param) {
return ApproverSpecifyEnum.role.getType().equals(param);
}
@Override
public List<BpmnTaskDelegateAssigner> select(UserTask userTask) {
return null;
}
}

View File

@ -1,8 +1,11 @@
package cn.axzo.workflow.core.engine.listener;
import cn.axzo.workflow.common.constant.BpmnConstants;
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
import com.alibaba.fastjson.JSON;
@ -29,6 +32,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELAT
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getNodeType;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getProcessServerVersion;
@ -45,6 +50,8 @@ public class EngineExecutionStartListener implements ExecutionListener {
private RepositoryService repositoryService;
@Resource
private ObjectProvider<BpmnTaskDelegate> bpmTaskDelegate;
@Resource
private List<BpmnTaskAssigneeSelector> selectors;
@Override
public void notify(DelegateExecution execution) {
@ -66,26 +73,78 @@ public class EngineExecutionStartListener implements ExecutionListener {
&& nodeType.isPresent()
&& Objects.equals(NODE_TASK, nodeType.get())) {
getApprovalMethod(userTask).ifPresent(method -> {
List<String> assigneeIdList = new ArrayList<>();
switch (method) {
case "autoPassed":
case "autoRejection":
// nothing to do
// TODO 不要调用查询审批人的接口 只需要保证该节点在实际运行过程中能自动通过和拒绝即可
case autoPassed:
case autoRejection:
// nothing to do
// TODO 不要调用查询审批人的接口只需要保证该节点在实际运行过程中能自动通过和拒绝即可
// 通过的功能可以参考下面枢智的方法拒绝还需研究可以结合 task 相关的事件去处理
break;
default:
// 这里只会是 human 这一种情况 因为 nobody 在转 BPMN 协议时Activity 直接变成了 ReceiveTask 节点了
// TODO 结合不同配置开始执行查询审批人的逻辑
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
getApproverSpecify(userTask).ifPresent(specify -> {
assigners.addAll(approverSelect(specify.getType(), userTask));
});
// 查询审批候选人
emptyAssigneeHandle(assigners, userTask, execution);
// UserTask 多实例, 该变量用于引擎
execution.setVariable(assigneeListVariableName, assigneeIdList);
execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
assigners);
break;
}
});
}
});
defaultCalcTaskAssigner(execution, userTask, currentActivityId, assigneeListVariableName);
}
private void emptyAssigneeHandle(List<BpmnTaskDelegateAssigner> assigners, UserTask userTask,
DelegateExecution execution) {
// 审批人为空并且当前节点设置了自动跳过条件
if (!CollectionUtils.isEmpty(assigners)) {
return;
}
Optional<ApproverEmptyHandleTypeEnum> approverEmptyHandleType = getApproverEmptyHandleType(userTask);
approverEmptyHandleType.ifPresent(type -> {
switch (type) {
case autoPassed:
// 自动通过的默认引擎参数必须设置为 true
execution.setTransientVariable(BpmnConstants.FLOWABLE_SKIP_EXPRESSION_ENABLE, true);
// 设置当前 UserTask 使用的 skip 表达式
execution.setTransientVariable(BPM_ALLOW_SKIP_USER_TASK, true);
break;
case transferToAdmin:
approverSelect(ApproverEmptyHandleTypeEnum.transferToAdmin.getType(), userTask);
break;
default:
break;
}
});
}
/**
* 根据审批人指定类型查询审批人
*
* @param type "审批人指定"方式 {@link ApproverSpecifyEnum}
* @param userTask 当前节点, 这个对象会包含配置元数据, 可以在该方法中或者基于 BpmnTaskAssigneeSelector 建一个抽象类, 做解析元数据公共方法
* @return
*/
private List<BpmnTaskDelegateAssigner> approverSelect(String type, UserTask userTask) {
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
selectors.forEach(select -> {
if (select.support(type)) {
assigners.addAll(select.select(userTask));
}
});
return assigners;
}
/**
* 枢智版本的逻辑, 不太兼容了暂时先放在这里
*
@ -123,6 +182,7 @@ public class EngineExecutionStartListener implements ExecutionListener {
execution.setTransientVariable(BPM_ALLOW_SKIP_USER_TASK, true);
}
// UserTask 非多实例
if (!userTask.hasMultiInstanceLoopCharacteristics()) {
if (!CollectionUtils.isEmpty(assigneeIdList)) {