- 1.4.0-SNAPSHOT
+ 1.4.1-SNAPSHOT
2.0.0-SNAPSHOT
2.0.0-SNAPSHOT
11.8
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
index 9a3a41d7b..6c132c786 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/constant/BpmnConstants.java
@@ -107,6 +107,7 @@ public interface BpmnConstants {
String END_EVENT_ID = "endEventNode";
String BPM_MODEL_CATEGORY = "bpm_model_category";
String BPM_ALLOW_SKIP_USER_TASK = "_INTERNAL_SKIP_USER_TASK_";
+ String AUTO_APPROVAL_TYPE = "autoApprovalType";
/**
* 用于国内审批节点填写审批建议
*
@@ -157,4 +158,24 @@ public interface BpmnConstants {
*/
String MQ_OWNERSHIP_APPLICATION = "MQ_OWNERSHIP_APPLICATION";
String MQ_OWNERSHIP_PROCESS_DEFINITION_KEY = "MQ_OWNERSHIP_PROCESS_DEFINITION_KEY";
+
+ /**
+ * 审批人数量限制
+ */
+ Integer APPROVAL_ASSIGNER_LIMIT_NUMBER = 60;
+
+ /**
+ * 抄送人员数量限制
+ */
+ Integer CARBON_ASSIGNER_LIMIT_NUMBER = 100;
+
+ /**
+ * MQ消息每批次人员数量
+ */
+ Integer MQ_ASSIGNER_BATCH_SIZE = 20;
+
+ /**
+ * 加签显示人员数量
+ */
+ Integer COUNTERSIGN_ASSIGNER_SHOW_NUMBER = 2;
}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/AutoApprovalTypeEnum.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/AutoApprovalTypeEnum.java
new file mode 100644
index 000000000..91189769d
--- /dev/null
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/AutoApprovalTypeEnum.java
@@ -0,0 +1,35 @@
+package cn.axzo.workflow.common.enums;
+
+import lombok.Getter;
+import org.springframework.util.StringUtils;
+
+/**
+ * 自动过审参数
+ */
+
+@Getter
+public enum AutoApprovalTypeEnum {
+
+ NO_AUTO_APPROVAL("noAutoApproval", "不自动过审"),
+ CONTINUOUS_NODES_AUTO_APPROVAL("continuousNodesAutoApproval", "连续节点自动过审");
+
+ private final String type;
+ private final String desc;
+
+ AutoApprovalTypeEnum(String type, String desc) {
+ this.type = type;
+ this.desc = desc;
+ }
+
+ public static AutoApprovalTypeEnum fromType(String type) {
+ if (!StringUtils.hasText(type)) {
+ return null;
+ }
+ for (AutoApprovalTypeEnum typeEnum : AutoApprovalTypeEnum.values()) {
+ if (typeEnum.type.equals(type)) {
+ return typeEnum;
+ }
+ }
+ return null;
+ }
+}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
index bab520d14..abc5fe45e 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/BpmnApproveConf.java
@@ -1,5 +1,6 @@
package cn.axzo.workflow.common.model.request;
+import cn.axzo.workflow.common.enums.AutoApprovalTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -27,4 +28,10 @@ public class BpmnApproveConf {
@ApiModelProperty(value = "审批同意录入手写签名")
@Valid
private Boolean userAgreeSignature;
+
+ /**
+ * 审批自动过审配置
+ */
+ @ApiModelProperty(value = "同一审批人自动过审类型,默认不自动过审,枚举类型为'NO_AUTO_APPROVAL'")
+ private AutoApprovalTypeEnum autoApprovalType = AutoApprovalTypeEnum.NO_AUTO_APPROVAL;
}
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java
index 9337b7521..33896b0f3 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnJsonNodeProperty.java
@@ -4,6 +4,7 @@ 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.AutoApprovalTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeMode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnActivitySetAssigneeDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnActivitySetAssigneeDTO.java
index 7ddf139f7..6f5a22aff 100644
--- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnActivitySetAssigneeDTO.java
+++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnActivitySetAssigneeDTO.java
@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -53,6 +54,7 @@ public class BpmnActivitySetAssigneeDTO {
*/
@ApiModelProperty(value = "审批人集合信息", notes = "业务传参时,需要注意去重")
@Valid
+ @Size(max = 60, message = "指定审批人数量限制为60")
private List assigners;
/**
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/AsyncJobRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/AsyncJobRespCode.java
index 9dad9b374..9b8de2294 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/AsyncJobRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/AsyncJobRespCode.java
@@ -18,8 +18,8 @@ public enum AsyncJobRespCode implements IModuleRespCode {
JOB_NOT_EXISTS_PROC_INST_ID("003", "流程实例id为【{}】对应任务不存在"),
RESUME_JOB_REQUEST_PARAM_ERROR("004", "恢复任务请求参数错误,jobId 和 procInstId 不能同时为空"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -30,13 +30,4 @@ public enum AsyncJobRespCode implements IModuleRespCode {
public String getProjectCode() {
return "998";
}
-
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
index 02d029de7..471cd0e27 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnInstanceRespCode.java
@@ -27,8 +27,8 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
TASK_CANT_COMMENT_INSTANCE_NOT_EXISTS("012", "流程实例【{}】不存在, 不能评论"),
RUNNING_INSTANCE_ONLY_FORECAST("013", "仅运行中的实例可以推测"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -40,12 +40,4 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnModelRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnModelRespCode.java
index 2f5f12a2e..3deec0d1e 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnModelRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnModelRespCode.java
@@ -20,8 +20,8 @@ public enum BpmnModelRespCode implements IModuleRespCode {
BPMN_BYTES_NOT_EXISTS("005", "模型定义内容字节码不存在"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -33,13 +33,5 @@ public enum BpmnModelRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnProcessDefinitionRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnProcessDefinitionRespCode.java
index 16b038961..145712343 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnProcessDefinitionRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnProcessDefinitionRespCode.java
@@ -24,8 +24,8 @@ public enum BpmnProcessDefinitionRespCode implements IModuleRespCode {
PROCESS_DEFINITION_HAS_DIRTY_DATA("009", "流程定义KEY【{}】存在脏数据,当前模型没有流程定义内容"),
PROCESS_DEFINITION_IS_INVALID("010", "暂时无法发起,请先配置流程模型")
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -37,12 +37,4 @@ public enum BpmnProcessDefinitionRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
index e3b3b5616..3fdbeea92 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java
@@ -4,6 +4,8 @@ import cn.axzo.framework.domain.web.code.IModuleRespCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
+import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
+
/**
* 流程模型响应码
*
@@ -34,10 +36,11 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
PROCESS_INSTANCE_IS_NOT_EXIST("019", "Execution:{} 对应流程实例不存在,流程状态异常!"),
TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"),
PROCESS_CANT_SET_ASSIGNEE("021", "当前审批状态不允许设置审批人"),
+ ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT("022", String.format("人员数量超过限制,节点审批人限制数量为: %d!", APPROVAL_ASSIGNER_LIMIT_NUMBER)),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -49,13 +52,4 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/CategoryRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/CategoryRespCode.java
index cca3ac338..c3456f937 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/CategoryRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/CategoryRespCode.java
@@ -21,8 +21,8 @@ public enum CategoryRespCode implements IModuleRespCode {
CATEGORY_CONFIG_EXISTS("006", "分类【{}】的【{}】配置中已存在重复数据"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -34,13 +34,5 @@ public enum CategoryRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/ConvertorRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/ConvertorRespCode.java
index 84ea0fb9c..c961cbc02 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/ConvertorRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/ConvertorRespCode.java
@@ -23,8 +23,8 @@ public enum ConvertorRespCode implements IModuleRespCode {
CONVERTOR_OPERATION_CHECKBOX_TYPE_ERROR("008", "条件节点(复选)运算符【{}】暂不支持"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -36,13 +36,4 @@ public enum ConvertorRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java
index e82a9f833..7fbdc0886 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java
@@ -22,8 +22,8 @@ public enum FlowableEngineRespCode implements IModuleRespCode {
ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现异常, 将放弃"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -35,13 +35,4 @@ public enum FlowableEngineRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormDefinitionRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormDefinitionRespCode.java
index 4f1e9901b..8665d3154 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormDefinitionRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormDefinitionRespCode.java
@@ -17,8 +17,8 @@ public enum FormDefinitionRespCode implements IModuleRespCode {
FORM_DEFINITION_PARSER_ERROR("002", "表单定义内容解析出错"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -30,13 +30,4 @@ public enum FormDefinitionRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormModelRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormModelRespCode.java
index 4650677ee..7db2b5b6e 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormModelRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FormModelRespCode.java
@@ -17,8 +17,8 @@ public enum FormModelRespCode implements IModuleRespCode {
FORM_MODEL_ID_NOT_EXISTS("002", "表单模型ID【{}】不存在"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -30,13 +30,4 @@ public enum FormModelRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/OtherRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/OtherRespCode.java
index 9edc8db47..ae80b5003 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/OtherRespCode.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/OtherRespCode.java
@@ -21,8 +21,8 @@ public enum OtherRespCode implements IModuleRespCode {
MESSAGE_PUSH_EVENT_BUILD_ERROR("006", "不能使用 createEvent 函数创建`发送待办`的事件, 请调用 createPendingPushEvent 函数"),
;
- private String code;
- private String message;
+ private final String code;
+ private final String message;
@Override
public String getModuleCode() {
@@ -34,12 +34,4 @@ public enum OtherRespCode implements IModuleRespCode {
return "998";
}
- public void setCode(String code) {
- this.code = code;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java
index 024744e13..bb8691467 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnJsonConverterUtil.java
@@ -69,6 +69,7 @@ import java.util.UUID;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVE_SUPPORT_BATCH_OPERATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVE_USER_AGREE_SIGNATURE;
+import static cn.axzo.workflow.common.constant.BpmnConstants.AUTO_APPROVAL_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_BUTTON_META;
@@ -506,6 +507,15 @@ public final class BpmnJsonConverterUtil {
config.addAttribute(configAttribute);
approveConfigElement.addChildElement(config);
}
+ if (Objects.nonNull(approveConf.getAutoApprovalType())) {
+ ExtensionElement config = new ExtensionElement();
+ config.setName(AUTO_APPROVAL_TYPE);
+ ExtensionAttribute configAttribute = new ExtensionAttribute();
+ configAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
+ configAttribute.setValue(approveConf.getAutoApprovalType().getType());
+ config.addAttribute(configAttribute);
+ approveConfigElement.addChildElement(config);
+ }
}
public static byte[] transformBytes(BpmnModel bpmnModel) {
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java
index d10efc4e9..3cbaf4f0c 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnMetaParserHelper.java
@@ -4,6 +4,7 @@ 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.AutoApprovalTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.enums.CarbonCopyObjectType;
@@ -41,6 +42,7 @@ import java.util.Optional;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVE_SUPPORT_BATCH_OPERATION;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVE_USER_AGREE_SIGNATURE;
+import static cn.axzo.workflow.common.constant.BpmnConstants.AUTO_APPROVAL_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_EMPTY_HANDLE_TYPE;
@@ -104,6 +106,7 @@ public final class BpmnMetaParserHelper {
if (CollectionUtils.isEmpty(elements)) {
conf.setUserAgreeSignature(USER_AGREE_SIGNATURE_DEFAULT_VALUE);
conf.setSupportBatchOperation(SUPPORT_BATCH_OPERATION_DEFAULT_VALUE);
+ conf.setAutoApprovalType(AutoApprovalTypeEnum.NO_AUTO_APPROVAL);
} else {
elements.get(0).getChildElements().forEach((k, v) -> {
if (APPROVE_SUPPORT_BATCH_OPERATION.equals(k)) {
@@ -112,6 +115,10 @@ public final class BpmnMetaParserHelper {
} else if (APPROVE_USER_AGREE_SIGNATURE.equals(k)) {
String value = v.get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE);
conf.setUserAgreeSignature(Boolean.valueOf(value));
+ } else if (AUTO_APPROVAL_TYPE.equals(k)) {
+ String value = v.get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE);
+ AutoApprovalTypeEnum typeEnum = AutoApprovalTypeEnum.fromType(value);
+ conf.setAutoApprovalType(typeEnum == null ? AutoApprovalTypeEnum.NO_AUTO_APPROVAL : typeEnum);
}
});
}
@@ -377,7 +384,6 @@ public final class BpmnMetaParserHelper {
return defaultValid(userTask, CONFIG_APPROVER_EMPTY_HANDLE_TYPE).map(element -> StringUtils.hasLength(element.getElementText()) ? element.getElementText() : "[]");
}
-
private static Optional defaultValid(FlowElement flowElement, String elementName) {
if (Objects.isNull(flowElement)) {
return Optional.empty();
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java
new file mode 100644
index 000000000..86871e9d1
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java
@@ -0,0 +1,28 @@
+package cn.axzo.workflow.core.common.utils;
+
+import org.springframework.lang.Nullable;
+
+import java.util.Map;
+
+public class SpringContextUtils {
+
+ private static SpringContextUtils.SpringContext springContext;
+
+ public SpringContextUtils(SpringContextUtils.SpringContext springContext) {
+ SpringContextUtils.springContext = springContext;
+ }
+
+ public static T getBean(Class clazz) {
+ return springContext.getBean(clazz);
+ }
+
+ public static Map getBeansOfType(@Nullable Class type) {
+ return springContext.getBeansOfType(type);
+ }
+
+ public interface SpringContext {
+ T getBean(Class var1);
+
+ Map getBeansOfType(@Nullable Class type);
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java
index 2b47c563b..f44d04057 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java
@@ -1,5 +1,6 @@
package cn.axzo.workflow.core.conf;
+import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory;
import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory;
import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator;
@@ -27,14 +28,20 @@ import org.flowable.form.spring.SpringFormEngineConfiguration;
import org.flowable.job.service.JobProcessor;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.lang.Nullable;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.time.Duration;
import java.util.List;
+import java.util.Map;
import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE;
@@ -111,4 +118,30 @@ public class FlowableConfiguration {
return new CustomActivityBehaviorFactory();
}
+ @Bean
+ @Order
+ public SpringContextUtils springContextUtils(SpringContext springContext) {
+ return new SpringContextUtils(springContext);
+ }
+
+ @Configuration
+ public static class SpringContext implements SpringContextUtils.SpringContext, ApplicationContextAware {
+ private ApplicationContext applicationContext;
+
+ public SpringContext() {
+ }
+
+ public T getBean(Class clazz) {
+ return this.applicationContext.getBean(clazz);
+ }
+
+ public Map getBeansOfType(@Nullable Class type){
+ return this.applicationContext.getBeansOfType(type);
+ }
+
+ public void setApplicationContext(@Nullable ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+ }
+
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/UserTaskJsonConverter.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/UserTaskJsonConverter.java
index 3b20e789b..83613b362 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/UserTaskJsonConverter.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/UserTaskJsonConverter.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.AND_SIGN_EXPRESSION;
+import static cn.axzo.workflow.common.constant.BpmnConstants.AUTO_APPROVAL_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_EMPTY_HANDLE_TYPE;
@@ -71,8 +72,8 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter {
setApprovalExtensionElement(node, userTask);
// "权限设置"
setFieldExtensionElement(node, userTask);
- // "高级设置"
- setButtonExtensionElement(node, userTask);
+ // "高级设置",包含按钮配置,自动过审配置
+ setAdvancedExtensionElement(node, userTask);
// "待办消息模板配置"
setPendingMessageExtensionElement(node, userTask);
@@ -130,7 +131,7 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter {
}
}
- private static void setButtonExtensionElement(BpmnJsonNode node, UserTask userTask) {
+ private static void setAdvancedExtensionElement(BpmnJsonNode node, UserTask userTask) {
if (Objects.isNull(node.getProperty())) {
return;
}
@@ -146,6 +147,13 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter {
}
userTask.addExtensionElement(buttonConfigElement);
+
+ //添加自动审批配置
+ ExtensionElement autoApprovalExtensionElement = new ExtensionElement();
+ ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute();
+ pendingMessageAttribute.setName(AUTO_APPROVAL_TYPE);
+ autoApprovalExtensionElement.addAttribute(pendingMessageAttribute);
+ userTask.addExtensionElement(autoApprovalExtensionElement);
}
private static void setFieldExtensionElement(BpmnJsonNode node, UserTask userTask) {
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskCmd.java
index 2867af38e..f108311bf 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBizSpecifyAssigneeToTaskCmd.java
@@ -4,7 +4,6 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import com.alibaba.fastjson.JSON;
-import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
@@ -32,6 +31,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_BIZ_SET_ASSIGNEE_ERROR;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_CANT_SET_ASSIGNEE;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.PROCESS_CANT_SET_ASSIGNEE;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount;
/**
* 自定的业务指定审批人命令实现
@@ -57,17 +57,33 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand
return JSON.toJSONString(params);
}
+ public static Task getOperateTask(TaskService taskService, String executionId) {
+ return taskService.createTaskQuery().executionId(executionId)
+ .taskAssignee(NO_ASSIGNEE)
+ .singleResult();
+ }
+
+ /**
+ * 校验
+ *
+ * @param runtimeService
+ * @param task
+ * @param assigners
+ */
+ public static void validate(RuntimeService runtimeService, String executionId, Task task, List assigners) {
+ validTask(task, executionId);
+ //校验审批人数量是否超过限制
+ validTaskAssignerCount(runtimeService, (TaskEntity) task, assigners);
+ }
+
@Override
public Boolean execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskService();
-
- Task task = taskService.createTaskQuery().executionId(executionId)
- .taskAssignee(NO_ASSIGNEE)
- .singleResult();
-
- validTask(task);
+ Task task = getOperateTask(taskService, executionId);
+ //校验
+ validate(processEngineConfiguration.getRuntimeService(), executionId, task, addedAssigners);
validProcessInstance(commandContext, task);
@@ -124,7 +140,7 @@ public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand
CustomTaskHelper.deleteMultiTask(commandContext, (TaskEntity) task);
}
- private void validTask(Task task) {
+ private static void validTask(Task task, String executionId) {
if (Objects.isNull(task)) {
throw new WorkflowEngineException(ACTIVITY_BIZ_SET_ASSIGNEE_ERROR, executionId);
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java
index 885e332e9..0a3a4eb15 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java
@@ -35,11 +35,13 @@ import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
+import static cn.axzo.workflow.common.constant.BpmnConstants.CARBON_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getLimitedElementList;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDuplicateByPersonId;
/**
@@ -157,7 +159,7 @@ public class CustomCarbonCopyUserSelectorCmd extends AbstractCommand getApproverRelationUser(BpmnCarbonCopyConf carbon,
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java
index f347c124d..fa939ffb2 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java
@@ -4,7 +4,6 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.core.engine.job.AsyncCountersignUserTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
-import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
@@ -17,10 +16,9 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
public class CustomCountersignUserTaskAsyncCmd extends AbstractCommand implements Serializable {
@@ -50,6 +48,8 @@ public class CustomCountersignUserTaskAsyncCmd extends AbstractCommand imp
validTaskAssignerDuplicated(commandContext, (TaskEntity) task, dto.getTargetAssignerList());
+ validTaskAssignerCount(processEngineConfiguration.getRuntimeService(), (TaskEntity) task, dto.getTargetAssignerList());
+
startAsync(processEngineConfiguration, task);
return null;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
index 877cad88d..d524ad757 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java
@@ -8,7 +8,7 @@ import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
-import org.flowable.common.engine.impl.interceptor.Command;
+import org.apache.commons.lang3.math.NumberUtils;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
@@ -25,12 +25,14 @@ import java.util.List;
import java.util.Map;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
+import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ASSIGNER_SHOW_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.COUNTERSIGN;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVirtualTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
/**
@@ -90,6 +92,8 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand implemen
validTask(historicTaskInstance, (TaskEntity) task, originTaskAssignee, null);
+ validTaskAssignerCount(processEngineConfiguration.getRuntimeService(), (TaskEntity) task, targetTaskAssigneeList);
+
List taskDelegateAssigners =
validTaskAssignerDuplicated(commandContext, (TaskEntity) task, targetTaskAssigneeList);
@@ -142,7 +146,9 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand implemen
TaskService taskService, Task task) {
// 构建评论内容
StringBuilder message = new StringBuilder("添加");
- for (int i = 0; i < targetTaskAssigneeList.size(); i++) {
+ int end = NumberUtils.min(targetTaskAssigneeList.size(), COUNTERSIGN_ASSIGNER_SHOW_NUMBER);
+ //加签人员数量显示指定个数
+ for (int i = 0; i < end; i++) {
message.append(targetTaskAssigneeList.get(i).getAssignerName());
if (i < targetTaskAssigneeList.size() - 1) {
message.append("、");
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java
index a17379858..84d6a2627 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java
@@ -23,7 +23,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getLimitedElementList;
/**
* 自定义的推测用户任务的审批人的命令实现
@@ -88,7 +90,7 @@ public class CustomForecastUserTaskAssigneeCmd extends AbstractCommand validTaskAssignerCount(RuntimeService runtimeService,
+ TaskEntity taskEntity,
+ List targetAssigneeList) {
+ // 这个节点下所有审批人快照
+ String activityListSnapshot = INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey();
+ List taskAssignerListSnapshot = runtimeService.getVariable(taskEntity.getProcessInstanceId(), activityListSnapshot, List.class);
+ if (taskAssignerListSnapshot.size() + targetAssigneeList.size() > APPROVAL_ASSIGNER_LIMIT_NUMBER) {
+ throw new WorkflowEngineException(ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT);
+ }
+ return taskAssignerListSnapshot;
+ }
+
/**
* 保存附件
*
@@ -379,6 +400,22 @@ public class CustomTaskHelper {
.values());
}
+ /**
+ * 获取指定数量元素
+ *
+ * @param assigners 原始列表列表
+ * @return 截取后的列表
+ */
+ public static List getLimitedElementList(List assigners, Integer limitNumber) {
+ if (limitNumber == null || limitNumber <= 0) {
+ throw new IllegalArgumentException("limit number must be greater than 0");
+ }
+ if (CollectionUtils.isEmpty(assigners) || assigners.size() <= limitNumber) {
+ return assigners;
+ }
+ return new ArrayList<>(assigners.subList(0, limitNumber));
+ }
+
public static List getHistoryOperationUsers(CommandContext commandContext, String processInstanceId,
BpmnHistoricTaskInstanceConverter historicTaskInstanceConverter,
String serviceVersion) {
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
index 093f1d108..e48493113 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java
@@ -38,9 +38,10 @@ public class CustomRetryInterceptor extends AbstractCommandInterceptor {
try {
// try to execute the command
+ log.info("assignableFrom result: {}", AbstractCommand.class.isAssignableFrom(command.getClass()));
if (AbstractCommand.class.isAssignableFrom(command.getClass())) {
// 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行.
- log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(),
+ log.info("Executing command params: {} traceId:{} ", TraceUtil.traceId(),
((AbstractCommand) command).paramToJsonString());
}
return next.execute(config, command, commandExecutor);
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AbstractExecuteWithLockJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AbstractExecuteWithLockJobHandler.java
new file mode 100644
index 000000000..406dc44f0
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AbstractExecuteWithLockJobHandler.java
@@ -0,0 +1,45 @@
+package cn.axzo.workflow.core.engine.job;
+
+import cn.axzo.workflow.core.common.utils.SpringContextUtils;
+import cn.axzo.workflow.core.repository.entity.ExtAxProperty;
+import cn.axzo.workflow.core.service.ExtAxPropertyService;
+import org.apache.commons.lang.StringUtils;
+import org.flowable.common.engine.impl.interceptor.CommandContext;
+import org.flowable.job.service.JobHandler;
+import org.flowable.job.service.impl.persistence.entity.JobEntity;
+import org.flowable.variable.api.delegate.VariableScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DuplicateKeyException;
+
+public abstract class AbstractExecuteWithLockJobHandler extends AbstractJobHandler implements JobHandler {
+
+ private static final Logger log = LoggerFactory.getLogger(AbstractExecuteWithLockJobHandler.class);
+
+ @Override
+ public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
+ ExtAxPropertyService extAxPropertyService = SpringContextUtils.getBean(ExtAxPropertyService.class);
+ String processInstanceId = job.getProcessInstanceId(), jobId = job.getId();
+ if (StringUtils.isBlank(processInstanceId) || StringUtils.isBlank(jobId)) {
+ log.warn("processInstanceId or lockOwner is empty,cannot execute with lock,jobId:{},processInstanceId:{}", job.getId(), job.getProcessInstanceId());
+ executeInternal(job, configuration, variableScope, commandContext);
+ return;
+ }
+ //todo 处理超时时间,超过一定时间,锁还存在,删除锁
+ try {
+ ExtAxProperty extAxProperty = new ExtAxProperty();
+ extAxProperty.setName(processInstanceId);
+ extAxProperty.setValue(jobId);
+ extAxPropertyService.add(extAxProperty);
+ log.info("job acquire lock success,processInstanceId:{},jobId:{}", processInstanceId, jobId);
+ executeInternal(job, configuration, variableScope, commandContext);
+ } catch (DuplicateKeyException e) {
+ log.error("executeWithLock error,lock by another job,jobId:{},processInstanceId:{}", job.getId(), job.getProcessInstanceId(), e);
+ throw e;
+ } finally {
+ extAxPropertyService.delete(processInstanceId, jobId);
+ }
+ }
+
+ abstract void executeInternal(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext);
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncApproveTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncApproveTaskJobHandler.java
index d411172ad..557406fda 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncApproveTaskJobHandler.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncApproveTaskJobHandler.java
@@ -12,13 +12,6 @@ import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.Task;
import org.flowable.variable.api.delegate.VariableScope;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
@@ -30,7 +23,7 @@ import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
* @since 2024/4/15 22:41
*/
@Slf4j
-public class AsyncApproveTaskJobHandler extends AbstractJobHandler implements JobHandler {
+public class AsyncApproveTaskJobHandler extends AbstractExecuteWithLockJobHandler implements JobHandler {
public static final String TYPE = "async-approve-task";
@Override
@@ -39,7 +32,7 @@ public class AsyncApproveTaskJobHandler extends AbstractJobHandler implements Jo
}
@Override
- public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
+ public void executeInternal(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
log.info("AsyncApproveTaskJobHandler executing...");
log(job);
ProcessEngineConfigurationImpl processEngineConfiguration =
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncRejectTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncRejectTaskJobHandler.java
index 46363dd95..c52832ba5 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncRejectTaskJobHandler.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncRejectTaskJobHandler.java
@@ -19,7 +19,7 @@ import org.flowable.variable.api.delegate.VariableScope;
* @since 2024/4/16 11:11
*/
@Slf4j
-public class AsyncRejectTaskJobHandler extends AbstractJobHandler implements JobHandler {
+public class AsyncRejectTaskJobHandler extends AbstractExecuteWithLockJobHandler implements JobHandler {
public static final String TYPE = "async-reject-task";
private final ExtAxHiTaskInstService extAxHiTaskInstService;
@@ -33,7 +33,7 @@ public class AsyncRejectTaskJobHandler extends AbstractJobHandler implements Job
}
@Override
- public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
+ public void executeInternal(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
log.info("AsyncRejectTaskJobHandler executing...");
log(job);
ProcessEngineConfigurationImpl processEngineConfiguration =
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineCarbonCopyEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineCarbonCopyEventListener.java
index 47d9a3cae..34f4b020e 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineCarbonCopyEventListener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineCarbonCopyEventListener.java
@@ -108,7 +108,6 @@ public class EngineCarbonCopyEventListener implements JavaDelegate {
}
return conf;
}).orElse(null);
-
MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY,
carbonUsers, bpmnNoticeConf, execution.getProcessInstanceId(),
parseProcessDefinitionKey(execution.getProcessDefinitionId()),
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineExecutionStartListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineExecutionStartListener.java
index b110445a1..b1a66b45b 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineExecutionStartListener.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineExecutionStartListener.java
@@ -37,6 +37,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER_TASK;
import static cn.axzo.workflow.common.constant.BpmnConstants.DUMMY_ASSIGNEE;
import static cn.axzo.workflow.common.constant.BpmnConstants.DUMMY_ASSIGNEE_TYPE;
@@ -53,6 +54,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove
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;
+import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getLimitedElementList;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDuplicateByPersonId;
@@ -148,13 +150,13 @@ public class EngineExecutionStartListener implements ExecutionListener {
// 审批候选人为空时的兜底
emptyAssigneeHandle(assigners, userTask, execution);
-
- for (BpmnTaskDelegateAssigner user : assigners) {
+ List resultAssigners = getLimitedElementList(assigners, APPROVAL_ASSIGNER_LIMIT_NUMBER);
+ for (BpmnTaskDelegateAssigner user : resultAssigners) {
assigneeIdList.add(user.buildAssigneeId());
}
execution.setVariable(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId,
- assigners);
+ resultAssigners);
break;
}
// UserTask 多实例, 该变量用于引擎
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProperty.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProperty.java
index 9fd14518d..c0adf9e72 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProperty.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProperty.java
@@ -1,10 +1,13 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
+import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
import lombok.ToString;
/**
@@ -17,6 +20,8 @@ import lombok.ToString;
@TableName(value = "ext_ax_property", autoResultMap = true)
@Data
@ToString(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
public class ExtAxProperty extends BaseEntity {
private static final long serialVersionUID = 1L;
@@ -39,4 +44,7 @@ public class ExtAxProperty extends BaseEntity {
*/
@TableField("manageable")
private Boolean manageable;
+
+ @TableField(value = "is_delete", fill = FieldFill.INSERT)
+ private Long isDelete = 0L;
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxPropertyService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxPropertyService.java
index 289c27d0e..caf684e89 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxPropertyService.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/ExtAxPropertyService.java
@@ -3,6 +3,7 @@ package cn.axzo.workflow.core.service;
import cn.axzo.workflow.core.repository.entity.ExtAxProperty;
import java.util.Optional;
+import java.util.concurrent.TimeUnit;
/**
* 引擎服务持久配置信息表操作 Service
@@ -17,4 +18,17 @@ public interface ExtAxPropertyService {
ExtAxProperty update(ExtAxProperty property);
Optional getByName(String name);
+
+ int delete(String name, String value);
+
+ /**
+ * 删除指定时间段之前创建的数据
+ *
+ * @param name
+ * @param timeOut
+ * @param timeUnit
+ * @return
+ */
+ int deleteByNameWithDuration(String name, Long timeOut, TimeUnit timeUnit);
+
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessActivityServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessActivityServiceImpl.java
index ebe551592..ec9305755 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessActivityServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessActivityServiceImpl.java
@@ -17,6 +17,7 @@ import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.spring.SpringProcessEngineConfiguration;
+import org.flowable.task.api.Task;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -95,6 +96,10 @@ public class BpmnProcessActivityServiceImpl implements BpmnProcessActivityServic
@Override
public void setAssigneeAsync(BpmnActivitySetAssigneeDTO dto) {
+ //查询任务
+ Task task = CustomBizSpecifyAssigneeToTaskCmd.getOperateTask(processEngineConfiguration.getTaskService(), dto.getTriggerId());
+ //先校验
+ CustomBizSpecifyAssigneeToTaskCmd.validate(processEngineConfiguration.getRuntimeService(), dto.getTriggerId(), task, dto.getAssigners());
validateAndStartAsyncJob(dto.getTriggerId(), dto, JOB_ASSIGNEE_ASYNC_NAME);
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxPropertyServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxPropertyServiceImpl.java
index 7ebf4702d..4f1171f60 100644
--- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxPropertyServiceImpl.java
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxPropertyServiceImpl.java
@@ -9,10 +9,17 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.TimeUnit;
/**
* 引擎服务持久配置信息表操作 Service 实现
@@ -28,6 +35,7 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService {
@CacheEvict(value = "property", key = "#property.name")
@Override
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
public ExtAxProperty add(ExtAxProperty property) {
mapper.insert(property);
return property;
@@ -50,4 +58,30 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService {
.eq("name", name);
return Optional.ofNullable(mapper.selectOne(queryWrapper));
}
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public int delete(String name, String value) {
+ if (!StringUtils.hasText(name)) {
+ return 0;
+ }
+ Map deleteMap = new HashMap<>();
+ deleteMap.put("name", name);
+ if (StringUtils.hasText(value)) {
+ deleteMap.put("value", value);
+ }
+ return mapper.deleteByMap(deleteMap);
+ }
+
+ public int deleteByNameWithDuration(String name, Long timeOut, TimeUnit timeUnit) {
+ if (!StringUtils.hasText(name) || timeOut == null || timeUnit == null) {
+ log.error("argument not valid,name:{},timeOut:{},timeUnit:{}", name, timeOut, timeUnit);
+ throw new IllegalArgumentException("argument not valid");
+ }
+ LocalDateTime startTime = LocalDateTime.now().minus(timeUnit.toMillis(timeOut), ChronoUnit.MILLIS);
+ QueryWrapper queryWrapper = new QueryWrapper()
+ .eq("name", name)
+ .le("create_at", startTime);
+ return mapper.delete(queryWrapper);
+ }
}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java
new file mode 100644
index 000000000..a6393917d
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java
@@ -0,0 +1,53 @@
+package cn.axzo.workflow.core.version;
+
+
+import cn.axzo.workflow.core.common.utils.SpringContextUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static cn.axzo.workflow.core.version.Versioned.UNKNOWN_VERSION;
+
+public class MultiVersionBeanUtils {
+
+ /**
+ * 获取支持指定版本的bean
+ *
+ * @param clazz 类型
+ * @param version 版本号
+ * @param
+ * @return
+ */
+ public static T getSpecifiedVersionBean(Class clazz, String version) {
+ Map beans = SpringContextUtils.getBeansOfType(clazz);
+ if (CollectionUtils.isEmpty(beans)) {
+ throw new NullPointerException("no beans of type " + clazz.getName());
+ }
+ if (StringUtils.isEmpty(version)) {
+ T t = beans.values().stream().filter(bean -> bean.getVersion() == null || bean.getVersion() == UNKNOWN_VERSION).findFirst().orElse(null);
+ if (t != null) {
+ return t;
+ }
+ throw new IllegalArgumentException("no default version bean found for version: " + version);
+ }
+ //根据版本号排序
+ List sortedList = beans.values().stream().sorted((o1, o2) -> {
+ DefaultArtifactVersion version1 = o1.getVersion() == null ? UNKNOWN_VERSION : o1.getVersion();
+ DefaultArtifactVersion version2 = o2.getVersion() == null ? UNKNOWN_VERSION : o2.getVersion();
+ return version1.compareTo(version2);
+ }).collect(Collectors.toList());
+ DefaultArtifactVersion targetVersion = new DefaultArtifactVersion(version);
+ for (int i = sortedList.size() - 1; i >= 0; i--) {
+ DefaultArtifactVersion classVersion = sortedList.get(i).getVersion() == null ? UNKNOWN_VERSION : sortedList.get(i).getVersion();
+ int flag = classVersion.compareTo(targetVersion);
+ if (flag <= 0) {
+ return sortedList.get(i);
+ }
+ }
+ throw new NullPointerException("no beans of type " + clazz.getName() + " and version " + version);
+ }
+}
diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/Versioned.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/Versioned.java
new file mode 100644
index 000000000..b024b21d3
--- /dev/null
+++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/Versioned.java
@@ -0,0 +1,10 @@
+package cn.axzo.workflow.core.version;
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+
+public interface Versioned {
+
+ DefaultArtifactVersion getVersion();
+
+ DefaultArtifactVersion UNKNOWN_VERSION = new DefaultArtifactVersion("0.0.0");
+}
diff --git a/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.1.sql b/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.1.sql
new file mode 100644
index 000000000..3d304a1ab
--- /dev/null
+++ b/workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE ext_ax_property ADD UNIQUE INDEX name_unique_index (name);
+
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/aspectj/RepeatSubmitAspect.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/aspectj/RepeatSubmitAspect.java
index 259cbb313..172cf50de 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/aspectj/RepeatSubmitAspect.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/aspectj/RepeatSubmitAspect.java
@@ -1,6 +1,7 @@
package cn.axzo.workflow.server.common.aspectj;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
+import cn.axzo.workflow.core.common.utils.TraceUtil;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
import cn.axzo.workflow.server.common.config.RepeatSubmitResolver;
import cn.axzo.workflow.server.common.util.RedisUtils;
@@ -81,7 +82,7 @@ public class RepeatSubmitAspect implements Ordered {
String key = RedisUtils.getCacheObject(cacheRepeatKey);
if (key == null) {
- RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
+ RedisUtils.setCacheObject(cacheRepeatKey, TraceUtil.traceId(), Duration.ofMillis(interval));
KEY_CACHE.set(cacheRepeatKey);
} else {
log.warn("{}", repeatSubmit.message());
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/activity/RocketMqBpmActivityEventListener.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/activity/RocketMqBpmActivityEventListener.java
index f6a54b77a..b9bc8cd16 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/activity/RocketMqBpmActivityEventListener.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/activity/RocketMqBpmActivityEventListener.java
@@ -139,7 +139,7 @@ public class RocketMqBpmActivityEventListener extends AbstractBpmnEventListener<
// 这个 ID 等于 ExecutionId
dto.setTriggerId(execution.getId());
dto.setActivityId(execution.getCurrentActivityId());
- dto.setActivityName(((ExecutionEntityImpl) execution).getCurrentActivityName());
+ dto.setActivityName(execution.getCurrentFlowElement().getName());
ProcessInstance processInstance = getContext().getProcessInstance(() ->
runtimeService.createProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId())
.includeProcessVariables().singleResult());
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/notice/RocketMqMessagePushEventListener.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/notice/RocketMqMessagePushEventListener.java
index 820d255a7..49a6cafa9 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/notice/RocketMqMessagePushEventListener.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/notice/RocketMqMessagePushEventListener.java
@@ -1,5 +1,6 @@
package cn.axzo.workflow.server.controller.listener.notice;
+import cn.axzo.core.utils.converter.BeanConverter;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventProducer;
import cn.axzo.workflow.common.enums.ProcessMessagePushEventEnum;
@@ -12,6 +13,7 @@ import cn.axzo.workflow.core.common.context.NoticeOperationContext;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.engine.event.MessagePushEvent;
+import cn.axzo.workflow.core.engine.event.MessagePushEventImpl;
import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
import cn.axzo.workflow.core.listener.BpmnMessagePushEventListener;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
@@ -55,6 +57,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NE
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_PROCESS_DEFINITION_KEY;
+import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_ASSIGNER_BATCH_SIZE;
import static cn.axzo.workflow.common.constant.BpmnConstants.MULTI_INSTANCE_LOOP_COUNTER;
import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
@@ -135,9 +138,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
log.info("RocketMqMessagePushEventListener#onNotice...msgTemplateId: {}, receivePerson: {}, processInstanceId: {}",
event.getNoticeConfig().getNotice().getNoticeMessageId(), JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId());
if (Objects.nonNull(event.getNoticeConfig().getNotice())) {
- MessagePushDTO dto = build(noticeTemplateCode,
- PROCESS_PUSH_NOTICE, event, collectionVariable(event));
- sendMessageQueue(dto, PROCESS_PUSH_NOTICE);
+ getMessagePushDtoSlice(event, noticeTemplateCode, PROCESS_PUSH_NOTICE).forEach(dto -> sendMessageQueue(dto, PROCESS_PUSH_NOTICE));
}
log.info("RocketMqMessagePushEventListener#onNotice...end, msgTemplateId: {}, receivePerson: {}, processInstanceId: {}",
event.getNoticeConfig().getNotice().getNoticeMessageId(), JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId());
@@ -245,20 +246,47 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener<
|| !StringUtils.hasText(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
return;
}
- // TODO 这里的抄送人,不建议使用一个 MQ 事件来承载,而是一个人一个事件
log.info("RocketMqMessagePushEventListener#onCarbonCopy... cc' templateId: {}, receivePerson: {}, processInstanceId: {}",
event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(),
JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId());
if (Objects.nonNull(event.getNoticeConfig().getCarbonCopy())) {
- MessagePushDTO dto = build(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(),
- PROCESS_CARBON_COPY, event, collectionVariable(event));
- sendMessageQueue(dto, PROCESS_CARBON_COPY);
+ //按人员拆分为多个批次发送消息
+ getMessagePushDtoSlice(event, event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(), PROCESS_CARBON_COPY).forEach(dto -> sendMessageQueue(dto, PROCESS_CARBON_COPY));
}
log.info("RocketMqMessagePushEventListener#onCarbonCopy...end, cc' templateId: {}, receivePerson: {}, processInstanceId: {}",
event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(),
JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId());
}
+ /**
+ * 根据人员数量,拆分消息发送
+ *
+ * @param event 事件消息
+ * @return 发送mq消息列表
+ */
+ private List getMessagePushDtoSlice(MessagePushEvent event, String templateId, ProcessMessagePushEventEnum type) {
+ if (event == null) {
+ throw new NullPointerException("event不能为空");
+ }
+ List assigners = event.getAssigners();
+ if (CollectionUtils.isEmpty(assigners) || assigners.size() <= MQ_ASSIGNER_BATCH_SIZE) {
+ return Collections.singletonList(build(templateId, type, event, collectionVariable(event)));
+ }
+ List slice = new ArrayList<>();
+ Map objectMap = collectionVariable(event);
+ int startIndex = 0;
+ do {
+ List batchAssigners = assigners.subList(startIndex, Integer.min(startIndex + MQ_ASSIGNER_BATCH_SIZE, assigners.size()));
+ MessagePushEventImpl messagePushEvent = new MessagePushEventImpl(event.getType());
+ BeanConverter.convert(event, messagePushEvent);
+ messagePushEvent.setAssigner(batchAssigners);
+ MessagePushDTO dto = build(templateId, type, messagePushEvent, objectMap);
+ slice.add(dto);
+ startIndex = startIndex + MQ_ASSIGNER_BATCH_SIZE;
+ } while (startIndex < assigners.size());
+ return slice;
+ }
+
/**
* 完成抄送
*
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/AutoOperatorEvent_101_Listener.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/AutoOperatorEvent_101_Listener.java
index 1783eb0f0..a50d516ec 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/AutoOperatorEvent_101_Listener.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/AutoOperatorEvent_101_Listener.java
@@ -1,9 +1,9 @@
package cn.axzo.workflow.server.controller.listener.task;
-import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import cn.axzo.workflow.common.enums.AutoApprovalTypeEnum;
+import cn.axzo.workflow.common.model.request.BpmnApproveConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
-import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
import cn.axzo.workflow.core.common.context.TaskOperationContext;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskCmd;
@@ -11,22 +11,20 @@ import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
-import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
+import cn.axzo.workflow.core.version.MultiVersionBeanUtils;
+import cn.axzo.workflow.server.controller.listener.task.service.CheckApproverService;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
-import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
-import org.flowable.engine.impl.persistence.entity.ActivityInstanceEntity;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
@@ -37,11 +35,10 @@ import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Optional;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
@@ -53,10 +50,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
+import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
-import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
-import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED;
import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.REJECTION_AUTO_COMPLETED;
@@ -79,7 +74,6 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener processApproveConf = BpmnMetaParserHelper.getProcessApproveConf(mainProcess);
+ //自动过审配置连续节点自动过审才处理,历史数据默认不自动过审
+ if (processApproveConf.isPresent() && AutoApprovalTypeEnum.CONTINUOUS_NODES_AUTO_APPROVAL == processApproveConf.get().getAutoApprovalType()) {
+ Object versionVar = delegateTask.getVariable(WORKFLOW_ENGINE_VERSION);
+ String version = versionVar == null ? null : String.valueOf(versionVar);
+ CheckApproverService checkApproverService = MultiVersionBeanUtils.getSpecifiedVersionBean(CheckApproverService.class, version);
+ boolean exists = checkApproverService.checkApproverExists(delegateTask, userTask, mainProcess, getContext());
+ log.info("是否需要自动过程判断 exists:{},processInstId:{},taskDefinitionKey:{}", exists, delegateTask.getProcessInstanceId(), delegateTask.getTaskDefinitionKey());
+ if (exists) {
+ taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE,
+ "同一审批人,自动过审");
+ autoPass(delegateTask);
+ }
}
-
// 检测节点自身配置是否有自动操作
checkApprovalMethod(delegateTask, userTask);
@@ -140,72 +140,6 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener !Objects.equals(i.getActivityId(), userTask.getId()))
- .filter(i -> !Objects.equals(i.getActivityType(), "exclusiveGateway"))
- .filter(i -> !Objects.equals(i.getActivityType(), "sequenceFlow"))
- .max(Comparator.comparing(ActivityInstanceEntity::getStartTime))
- .ifPresent(i -> {
- // 与发起人比对
- if (Objects.equals(NODE_STARTER.getType(), i.getActivityId())) {
- BpmnTaskDelegateAssigner initiator = BpmnTaskDelegateAssigner.toObjectCompatible(delegateTask.getVariable(INTERNAL_INITIATOR));
- if (Objects.nonNull(initiator) && initiator.comparePersonIdToOther(delegateTask.getAssignee())) {
- exists.compareAndSet(false, true);
- }
- } else {
- FlowElement flowElement = mainProcess.getFlowElement(i.getActivityId());
- BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(j -> {
- if (Objects.equals(NODE_TASK, j)) {
- ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
- searchDTO.setProcessInstanceId(delegateTask.getProcessInstanceId());
- searchDTO.setTaskDefinitionKey(i.getActivityId());
- getContext().getExtAxHiTaskInsts(() -> extAxHiTaskInstService.queryList(searchDTO))
- .stream().filter(e -> Objects.equals(e.getStatus(), APPROVED.getStatus()))
- .map(ExtAxHiTaskInst::getAssignee)
- .filter(Objects::nonNull)
- .filter(StringUtils::hasText)
- .filter(k -> specialApproverComparison(k, delegateTask.getAssignee()))
- .findAny().ifPresent(k -> exists.compareAndSet(false, true));
- }
- });
- }
- });
- return exists.get();
- }
-
- /**
- * 特殊审批人字段的比对, 兼容旧迭代导致的数据格式
- *
- * @return
- */
- private boolean specialApproverComparison(String compareAssignee, String currentAssignee) {
- if (StringUtils.hasText(compareAssignee) && StringUtils.hasText(currentAssignee)) {
- String[] compareSplit = compareAssignee.split("\\|");
- String[] currentSplit = currentAssignee.split("\\|");
- if (compareSplit.length == 2 || currentSplit.length == 2) {
- return Objects.equals(compareSplit[1], currentSplit[1]);
- }
- }
- return false;
- }
-
/**
* 如果审批人为空时, 读取 approverEmptyHandleType = 自动通过或自动驳回
*
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproverService.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproverService.java
new file mode 100644
index 000000000..1039057a7
--- /dev/null
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproverService.java
@@ -0,0 +1,13 @@
+package cn.axzo.workflow.server.controller.listener.task.service;
+
+import cn.axzo.workflow.core.common.context.TaskOperationContext;
+import cn.axzo.workflow.core.version.Versioned;
+import org.flowable.bpmn.model.Process;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.task.service.delegate.DelegateTask;
+
+public interface CheckApproverService extends Versioned {
+
+ boolean checkApproverExists(DelegateTask delegateTask, UserTask userTask, Process mainProcess, TaskOperationContext taskOperationContext);
+
+}
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/impl/CheckApproverServiceImpl.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/impl/CheckApproverServiceImpl.java
new file mode 100644
index 000000000..62db9bd4a
--- /dev/null
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/impl/CheckApproverServiceImpl.java
@@ -0,0 +1,141 @@
+package cn.axzo.workflow.server.controller.listener.task.service.impl;
+
+import cn.axzo.workflow.common.enums.BpmnButtonEnum;
+import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf;
+import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
+import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
+import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
+import cn.axzo.workflow.core.common.context.TaskOperationContext;
+import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
+import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
+import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
+import cn.axzo.workflow.server.controller.listener.task.service.CheckApproverService;
+import lombok.AllArgsConstructor;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.Process;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.flowable.engine.impl.persistence.entity.ActivityInstanceEntity;
+import org.flowable.engine.impl.util.CommandContextUtil;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
+import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
+import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK;
+import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
+
+/**
+ * REQ-2596. 自动过审规则:
+ * a. 审批人=发起人/历史审批人
+ * b. 连续节点
+ * c. 当前节点有同意按钮
+ */
+@Component
+@AllArgsConstructor
+public class CheckApproverServiceImpl implements CheckApproverService {
+
+ private final ExtAxHiTaskInstService extAxHiTaskInstService;
+
+ public boolean checkApproverExists(DelegateTask delegateTask, UserTask userTask, Process mainProcess, TaskOperationContext taskOperationContext) {
+ AtomicBoolean exists = new AtomicBoolean(false);
+ FlowElement currentFlowElement = mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
+ BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(currentFlowElement).orElse(NODE_EMPTY);
+ //业务节点,指定业务审批人,或者业务设置了审批人,也要参与自动过审,node_type为NODE_BUSINESS,节点元素类型为UserTask
+ //业务节点审批人为空,或者人员未指定,此时不进行自动过审操作,需要再业务指定审批人后,再做自动过审动作
+ if (!(Objects.equals(currentNodeType, NODE_TASK) || Objects.equals(currentNodeType, NODE_BUSINESS)) ||
+ !StringUtils.hasText(delegateTask.getAssignee()) ||
+ delegateTask.getAssignee().equals(NO_ASSIGNEE)) {
+ return exists.get();
+ }
+ Optional optConfig = BpmnMetaParserHelper.getButtonConfig(mainProcess, delegateTask.getTaskDefinitionKey());
+ if (!optConfig.isPresent()) {
+ return exists.get();
+ }
+ BpmnButtonConf bpmnButtonConf = optConfig.get();
+ List currentButtons = bpmnButtonConf.getCurrent();
+ if (CollectionUtils.isEmpty(currentButtons)) {
+ return exists.get();
+ }
+ Optional agreeButton = currentButtons.stream()
+ .filter(button -> button.getType().equals("SYSTEM") //系统按钮
+ && button.getChecked() != null && button.getChecked() //选中
+ && (button.getDisabled() == null || !button.getDisabled()) //没用禁用
+ && button.getBtnKey().equals(BpmnButtonEnum.BPMN_APPROVE.getBtnKey())) //类型为同意
+ .findFirst();
+ //不存在同意按钮
+ if (!agreeButton.isPresent()) {
+ return exists.get();
+ }
+ ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
+ processEngineConfiguration.getActivityInstanceEntityManager()
+ .findActivityInstancesByProcessInstanceId(delegateTask.getProcessInstanceId(), false)
+ .stream()
+ .filter(i -> !Objects.equals(i.getActivityId(), userTask.getId()))
+ .filter(i -> !Objects.equals(i.getActivityType(), "exclusiveGateway"))
+ .filter(i -> !Objects.equals(i.getActivityType(), "sequenceFlow"))
+ .max(Comparator.comparing(ActivityInstanceEntity::getStartTime))
+ .ifPresent(i -> {
+ // 与发起人比对
+ if (Objects.equals(NODE_STARTER.getType(), i.getActivityId())) {
+ BpmnTaskDelegateAssigner initiator = BpmnTaskDelegateAssigner.toObjectCompatible(delegateTask.getVariable(INTERNAL_INITIATOR));
+ if (Objects.nonNull(initiator) && initiator.comparePersonIdToOther(delegateTask.getAssignee())) {
+ exists.compareAndSet(false, true);
+ }
+ } else {
+ FlowElement flowElement = mainProcess.getFlowElement(i.getActivityId());
+ BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(j -> {
+ //上一节点如果是业务节点,但是是人员审批,也需要加入到自动过审
+ if (Objects.equals(NODE_TASK, j) || (Objects.equals(NODE_BUSINESS, j) && flowElement.getClass().isAssignableFrom(UserTask.class))) {
+ ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
+ searchDTO.setProcessInstanceId(delegateTask.getProcessInstanceId());
+ searchDTO.setTaskDefinitionKey(i.getActivityId());
+ taskOperationContext.getExtAxHiTaskInsts(() -> extAxHiTaskInstService.queryList(searchDTO))
+ .stream().filter(e -> Objects.equals(e.getStatus(), APPROVED.getStatus()))
+ .map(ExtAxHiTaskInst::getAssignee)
+ .filter(Objects::nonNull)
+ .filter(StringUtils::hasText)
+ .filter(k -> specialApproverComparison(k, delegateTask.getAssignee()))
+ .findAny().ifPresent(k -> exists.compareAndSet(false, true));
+ }
+ });
+ }
+ });
+ return exists.get();
+ }
+
+ /**
+ * 特殊审批人字段的比对, 兼容旧迭代导致的数据格式
+ *
+ * @return
+ */
+ private boolean specialApproverComparison(String compareAssignee, String currentAssignee) {
+ if (StringUtils.hasText(compareAssignee) && StringUtils.hasText(currentAssignee)) {
+ String[] compareSplit = compareAssignee.split("\\|");
+ String[] currentSplit = currentAssignee.split("\\|");
+ if (compareSplit.length == 2 || currentSplit.length == 2) {
+ return Objects.equals(compareSplit[1], currentSplit[1]);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public DefaultArtifactVersion getVersion() {
+// return new DefaultArtifactVersion(FLOW_SERVER_VERSION_130);
+ return null;
+ }
+}
diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
index 0a87ef7e1..b50e31172 100644
--- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
+++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java
@@ -23,6 +23,7 @@ import cn.axzo.workflow.core.service.BpmnProcessTaskService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
import cn.azxo.framework.common.model.CommonResponse;
+import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
@@ -186,7 +187,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi {
@PostMapping("/countersign")
@RepeatSubmit
public CommonResponse countersignTask(@Validated @RequestBody BpmnTaskCountersignDTO countersignDTO) {
- log.info("加签任务 countersignTask===>>>参数:{}", countersignDTO);
+ log.info("加签任务 countersignTask===>>>参数:{}", JSON.toJSONString(countersignDTO));
bpmnProcessTaskService.countersignTask(countersignDTO);
return success(true);
}