From 21c4541a708da24d8773900f90a48907790cdaa5 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 28 Jun 2024 18:56:06 +0800 Subject: [PATCH 01/42] =?UTF-8?q?REQ-2596-=E8=87=AA=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E5=AE=A1=E9=85=8D=E7=BD=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/BpmnConstants.java | 1 + .../request/bpmn/BpmnJsonNodeProperty.java | 3 +++ .../common/utils/BpmnMetaParserHelper.java | 4 ++++ .../converter/json/UserTaskJsonConverter.java | 15 ++++++++++++--- .../task/AutoOperatorEvent_101_Listener.java | 18 +++++++++++------- 5 files changed, 31 insertions(+), 10 deletions(-) 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 69865ff76..4df84c4ff 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 @@ -106,6 +106,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 = "autoApproval"; /** * 用于国内审批节点填写审批建议 *

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..72862309f 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 @@ -146,4 +146,7 @@ public class BpmnJsonNodeProperty { */ @ApiModelProperty(value = "发起时使用的表单 key") private String formKey; + + @ApiModelProperty(value = "同一审批人自动过审,默认为false") + private Boolean autoApproval = false; } 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..f3ccfc989 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 @@ -41,6 +41,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; 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; @@ -377,6 +378,9 @@ public final class BpmnMetaParserHelper { return defaultValid(userTask, CONFIG_APPROVER_EMPTY_HANDLE_TYPE).map(element -> StringUtils.hasLength(element.getElementText()) ? element.getElementText() : "[]"); } + public static Optional getAutoApprovalValue(UserTask userTask) { + return defaultValid(userTask, AUTO_APPROVAL).map(element -> Boolean.valueOf(element.getElementText())); + } private static Optional defaultValid(FlowElement flowElement, String elementName) { if (Objects.isNull(flowElement)) { 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..cb2d3a861 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; 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,14 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter { } userTask.addExtensionElement(buttonConfigElement); + + //添加自动审批配置 + ExtensionElement autoApprovalExtensionElement = new ExtensionElement(); + ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute(); + pendingMessageAttribute.setName(AUTO_APPROVAL); + pendingMessageAttribute.setValue(String.valueOf(node.getProperty().getAutoApproval())); + autoApprovalExtensionElement.addAttribute(pendingMessageAttribute); + userTask.addExtensionElement(autoApprovalExtensionElement); } private static void setFieldExtensionElement(BpmnJsonNode node, UserTask userTask) { 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..5c6dc9f1a 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 @@ -41,6 +41,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; @@ -94,14 +95,17 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener autoApprovalOpt = BpmnMetaParserHelper.getAutoApprovalValue(userTask); + //自动过审配置为true才执行这段代码,默认为false,老数据默认不跳过审批 + if (autoApprovalOpt.orElse(false)) { + boolean exists = checkApproverExists(delegateTask, userTask, mainProcess); + log.info("是否需要自动过程判断 exists:{}", exists); + if (exists) { + taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE, + "同一审批人,自动过审"); + autoPass(delegateTask); + } } - // 检测节点自身配置是否有自动操作 checkApprovalMethod(delegateTask, userTask); From 872b84f1aeb25772323cb559a27b37e91d69beb0 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 2 Jul 2024 16:04:06 +0800 Subject: [PATCH 02/42] =?UTF-8?q?REQ-2596,=E8=87=AA=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E5=AE=A1=E6=94=AF=E6=8C=81=E4=B8=8D=E5=90=8C=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=89=88=E6=9C=AC=E6=89=A7=E8=A1=8C=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E4=B8=9A=E5=8A=A1=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/utils/SpringContentUtils.java | 28 +++++ .../core/conf/FlowableConfiguration.java | 29 +++++ .../version/GetSpecifiedVersionBeanUtils.java | 33 ++++++ .../axzo/workflow/core/version/Versioned.java | 8 ++ .../task/AutoOperatorEvent_101_Listener.java | 88 ++------------- .../task/service/CheckApproveService.java | 11 ++ .../impl/CheckApproverServiceImpl.java | 103 ++++++++++++++++++ 7 files changed, 220 insertions(+), 80 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/Versioned.java create mode 100644 workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java create mode 100644 workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/impl/CheckApproverServiceImpl.java diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java new file mode 100644 index 000000000..202663f32 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java @@ -0,0 +1,28 @@ +package cn.axzo.workflow.core.common.utils; + +import org.springframework.lang.Nullable; + +import java.util.Map; + +public class SpringContentUtils { + + private static SpringContentUtils.SpringContext springContext; + + public SpringContentUtils(SpringContentUtils.SpringContext springContext) { + SpringContentUtils.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 15302a561..11c6b1aeb 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.SpringContentUtils; import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory; import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory; import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator; @@ -20,19 +21,26 @@ import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.NacosServiceManager; import com.google.common.collect.Lists; +import org.apache.ibatis.session.SqlSessionFactory; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.common.engine.impl.history.HistoryLevel; 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.boot.autoconfigure.condition.ConditionalOnBean; +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.lang.Nullable; import java.time.Duration; import java.util.List; +import java.util.Map; import static org.flowable.common.engine.impl.AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE; @@ -105,4 +113,25 @@ public class FlowableConfiguration { return new CustomActivityBehaviorFactory(); } + @Configuration + @ConditionalOnBean({SqlSessionFactory.class}) + public static class SpringContext implements SpringContentUtils.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/version/GetSpecifiedVersionBeanUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java new file mode 100644 index 000000000..e2c938430 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java @@ -0,0 +1,33 @@ +package cn.axzo.workflow.core.version; + + +import cn.axzo.workflow.core.common.utils.SpringContentUtils; +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; + +public class GetSpecifiedVersionBeanUtils { + public static T getSpecialVersionBean(Class clazz, String version) { + Map beans = SpringContentUtils.getBeansOfType(clazz); + if (CollectionUtils.isEmpty(beans)) { + throw new NullPointerException("no beans of type " + clazz.getName()); + } + if (StringUtils.isEmpty(version)) { + //todo 版本为空,需要一个默认处理类?? + } + //根据版本号排序 + List sortedList = beans.values().stream().sorted().collect(Collectors.toList()); + DefaultArtifactVersion targetVersion = new DefaultArtifactVersion(version); + for (int i = sortedList.size() - 1; i >= 0; i--) { + int flag = sortedList.get(i).getVersion().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..be73a4aa6 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/Versioned.java @@ -0,0 +1,8 @@ +package cn.axzo.workflow.core.version; + +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; + +public interface Versioned { + + DefaultArtifactVersion getVersion(); +} 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 5c6dc9f1a..a8c3d8746 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,7 @@ package cn.axzo.workflow.server.controller.listener.task; -import cn.axzo.workflow.common.enums.BpmnFlowNodeType; 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 +9,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.GetSpecifiedVersionBeanUtils; +import cn.axzo.workflow.server.controller.listener.task.service.CheckApproveService; 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,12 +33,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.Optional; -import java.util.concurrent.atomic.AtomicBoolean; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; @@ -54,10 +48,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; @@ -80,7 +72,6 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener autoApprovalOpt = BpmnMetaParserHelper.getAutoApprovalValue(userTask); - //自动过审配置为true才执行这段代码,默认为false,老数据默认不跳过审批 + //自动过审配置为true才执行这段代码,默认为false,老数据默认不自动过审 if (autoApprovalOpt.orElse(false)) { - boolean exists = checkApproverExists(delegateTask, userTask, mainProcess); + Object versionVar = delegateTask.getVariable(WORKFLOW_ENGINE_VERSION); + String version = versionVar == null ? null : String.valueOf(versionVar); + CheckApproveService checkApproveService = GetSpecifiedVersionBeanUtils.getSpecialVersionBean(CheckApproveService.class, version); + boolean exists = checkApproveService.checkApproverExists(delegateTask, userTask, mainProcess, getContext()); log.info("是否需要自动过程判断 exists:{}", exists); if (exists) { taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE, @@ -144,72 +138,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/CheckApproveService.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java new file mode 100644 index 000000000..9610f0b9c --- /dev/null +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java @@ -0,0 +1,11 @@ +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 CheckApproveService 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..4dcd2224b --- /dev/null +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/impl/CheckApproverServiceImpl.java @@ -0,0 +1,103 @@ +package cn.axzo.workflow.server.controller.listener.task.service.impl; + +import cn.axzo.workflow.common.enums.BpmnFlowNodeType; +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.CheckApproveService; +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.StringUtils; + +import java.util.Comparator; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; + +import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_130; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR; +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; + +@Component +@AllArgsConstructor +public class CheckApproverServiceImpl implements CheckApproveService { + + 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); + if (!Objects.equals(currentNodeType, NODE_TASK)) { + 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)) { + 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); + } +} From b2315dfbe06fce19c99b8aa9ee8b74897e884e77 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 2 Jul 2024 17:29:55 +0800 Subject: [PATCH 03/42] =?UTF-8?q?REQ-2596,=E8=87=AA=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E5=AE=A1=E9=85=8D=E7=BD=AE=E8=B0=83=E6=95=B4=E4=B8=BA=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/BpmnConstants.java | 2 +- .../common/enums/AutoApprovalTypeEnum.java | 23 ++++++++++++++ .../request/bpmn/BpmnJsonNodeProperty.java | 5 +-- .../common/utils/BpmnMetaParserHelper.java | 7 +++-- .../converter/json/UserTaskJsonConverter.java | 6 ++-- .../task/AutoOperatorEvent_101_Listener.java | 9 +++--- .../task/service/CheckApproveService.java | 2 ++ .../impl/CheckApproverServiceImpl.java | 31 +++++++++++++++++++ 8 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/AutoApprovalTypeEnum.java 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 4df84c4ff..c5e3c7be3 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 @@ -106,7 +106,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 = "autoApproval"; + String AUTO_APPROVAL_TYPE = "autoApprovalType"; /** * 用于国内审批节点填写审批建议 *

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..5c1c46bc1 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/enums/AutoApprovalTypeEnum.java @@ -0,0 +1,23 @@ +package cn.axzo.workflow.common.enums; + +import lombok.Getter; + +/** + * 自动过审参数 + */ + +@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; + } + +} 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 72862309f..0b1bd2115 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; @@ -147,6 +148,6 @@ public class BpmnJsonNodeProperty { @ApiModelProperty(value = "发起时使用的表单 key") private String formKey; - @ApiModelProperty(value = "同一审批人自动过审,默认为false") - private Boolean autoApproval = false; + @ApiModelProperty(value = "同一审批人自动过审类型,默认不自动过审") + private AutoApprovalTypeEnum autoApproval = AutoApprovalTypeEnum.NO_AUTO_APPROVAL; } 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 f3ccfc989..8131cb4ac 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,7 +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; +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; @@ -378,8 +379,8 @@ public final class BpmnMetaParserHelper { return defaultValid(userTask, CONFIG_APPROVER_EMPTY_HANDLE_TYPE).map(element -> StringUtils.hasLength(element.getElementText()) ? element.getElementText() : "[]"); } - public static Optional getAutoApprovalValue(UserTask userTask) { - return defaultValid(userTask, AUTO_APPROVAL).map(element -> Boolean.valueOf(element.getElementText())); + public static Optional getAutoApprovalValue(UserTask userTask) { + return defaultValid(userTask, AUTO_APPROVAL_TYPE).map(element -> AutoApprovalTypeEnum.valueOf(element.getElementText())); } private static Optional defaultValid(FlowElement flowElement, String elementName) { 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 cb2d3a861..f3c4276f7 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,7 +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; +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; @@ -151,8 +151,8 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter { //添加自动审批配置 ExtensionElement autoApprovalExtensionElement = new ExtensionElement(); ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute(); - pendingMessageAttribute.setName(AUTO_APPROVAL); - pendingMessageAttribute.setValue(String.valueOf(node.getProperty().getAutoApproval())); + pendingMessageAttribute.setName(AUTO_APPROVAL_TYPE); + pendingMessageAttribute.setValue(node.getProperty().getAutoApproval().getType()); autoApprovalExtensionElement.addAttribute(pendingMessageAttribute); userTask.addExtensionElement(autoApprovalExtensionElement); } 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 a8c3d8746..91afe0f68 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,5 +1,6 @@ package cn.axzo.workflow.server.controller.listener.task; +import cn.axzo.workflow.common.enums.AutoApprovalTypeEnum; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.context.TaskOperationContext; @@ -86,14 +87,14 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener autoApprovalOpt = BpmnMetaParserHelper.getAutoApprovalValue(userTask); - //自动过审配置为true才执行这段代码,默认为false,老数据默认不自动过审 - if (autoApprovalOpt.orElse(false)) { + Optional approvalTypeEnumOpt = BpmnMetaParserHelper.getAutoApprovalValue(userTask); + //自动过审配置连续节点自动过审才处理,历史数据默认不自动过审 + if (approvalTypeEnumOpt.isPresent() && approvalTypeEnumOpt.get() == AutoApprovalTypeEnum.CONTINUOUS_NODES_AUTO_APPROVAL) { Object versionVar = delegateTask.getVariable(WORKFLOW_ENGINE_VERSION); String version = versionVar == null ? null : String.valueOf(versionVar); CheckApproveService checkApproveService = GetSpecifiedVersionBeanUtils.getSpecialVersionBean(CheckApproveService.class, version); boolean exists = checkApproveService.checkApproverExists(delegateTask, userTask, mainProcess, getContext()); - log.info("是否需要自动过程判断 exists:{}", exists); + log.info("是否需要自动过程判断 exists:{},processInstId:{},taskDefinitionKey:{}", exists, delegateTask.getProcessInstanceId(), delegateTask.getTaskDefinitionKey()); if (exists) { taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE, "同一审批人,自动过审"); diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java index 9610f0b9c..e0c6a0562 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/CheckApproveService.java @@ -7,5 +7,7 @@ import org.flowable.bpmn.model.UserTask; import org.flowable.task.service.delegate.DelegateTask; public interface CheckApproveService 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 index 4dcd2224b..17d2a52b7 100644 --- 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 @@ -1,6 +1,9 @@ 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; @@ -18,10 +21,13 @@ 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.FLOW_SERVER_VERSION_130; @@ -31,6 +37,12 @@ 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 CheckApproveService { @@ -44,6 +56,25 @@ public class CheckApproverServiceImpl implements CheckApproveService { if (!Objects.equals(currentNodeType, NODE_TASK)) { 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) From 196d9e61cd93a13d7ffbf03dadc81ec143002d86 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 3 Jul 2024 14:22:54 +0800 Subject: [PATCH 04/42] =?UTF-8?q?REQ-2596,=E4=BF=AE=E6=94=B9=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E4=B8=BA1.4.1-SNAPSHOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 319b2cfec..29a8aa30b 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ workflow-engine - 1.3.3-SNAPSHOT + 1.4.1-SNAPSHOT 2.0.0-SNAPSHOT 2.0.0-SNAPSHOT 11.8 From 136297e9e1d5f7398325fa53d33e136e1a5cc149 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 14:40:12 +0800 Subject: [PATCH 05/42] =?UTF-8?q?update=20-=20=E9=87=8D=E5=A4=8D=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E7=9A=84=20Value=20=E4=BF=AE=E6=94=B9=E4=B8=BA=20Trac?= =?UTF-8?q?eId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/server/common/aspectj/RepeatSubmitAspect.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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()); From 545ce0496f380d05a37c933636aa55634d1eae8c Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 15:07:07 +0800 Subject: [PATCH 06/42] =?UTF-8?q?update=20-=20Sonar=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/common/code/AsyncJobRespCode.java | 13 ++----------- .../core/common/code/BpmnInstanceRespCode.java | 12 ++---------- .../core/common/code/BpmnModelRespCode.java | 12 ++---------- .../common/code/BpmnProcessDefinitionRespCode.java | 12 ++---------- .../workflow/core/common/code/BpmnTaskRespCode.java | 13 ++----------- .../workflow/core/common/code/CategoryRespCode.java | 12 ++---------- .../core/common/code/ConvertorRespCode.java | 13 ++----------- .../core/common/code/FlowableEngineRespCode.java | 13 ++----------- .../core/common/code/FormDefinitionRespCode.java | 13 ++----------- .../core/common/code/FormModelRespCode.java | 13 ++----------- .../workflow/core/common/code/OtherRespCode.java | 12 ++---------- 11 files changed, 22 insertions(+), 116 deletions(-) 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 cd2775b32..413370c01 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 @@ -35,8 +35,8 @@ public enum BpmnTaskRespCode implements IModuleRespCode { TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"), ; - private String code; - private String message; + private final String code; + private final String message; @Override public String getModuleCode() { @@ -48,13 +48,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; - } - } From 970e7e58ab130fbbb85a291b0e987bb2012d94cd Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 4 Jul 2024 16:22:31 +0800 Subject: [PATCH 07/42] =?UTF-8?q?REQ-2596-=E8=8A=82=E7=82=B9=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E4=BA=BA=E5=A4=A7=E4=BA=8E=E6=8C=87=E5=AE=9A=E4=BA=BA?= =?UTF-8?q?=E6=95=B0,=E6=8C=89=E6=8C=87=E5=AE=9A=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E6=88=AA=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/common/constant/BpmnConstants.java | 5 +++++ .../AbstractBpmnTaskAssigneeSelector.java | 16 +++++++++++++++- .../BasedFixedPersonTaskAssigneeSelector.java | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) 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 c5e3c7be3..ef594a474 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 @@ -156,4 +156,9 @@ public interface BpmnConstants { * 用于 MQ 的 Header, 记录当前事件的归属应用 */ String MQ_OWNERSHIP_APP = "MQ_OWNERSHIP_APPLICATION"; + + /** + * 审批人数量限制 + */ + Integer ASSIGNER_LIMIT_NUMBER = 60; } diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java index 0d32c68cf..0e296d4e9 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.CALC_TASK_ASSIGNEE_ERROR; import static cn.axzo.workflow.core.common.code.ConvertorRespCode.CONVERTOR_META_DATA_FORMAT_ERROR; import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_USER_TASK_CALC_ERROR; @@ -72,7 +73,7 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign ApproverScopeEnum processor = ((NoticeFlowElement) flowElement).getProcessor(); assigners.addAll(privateSelector(processor, flowElement, execution, throwException)); } - return assigners.stream().filter(i -> StringUtils.hasText(i.getPersonId())).collect(Collectors.toList()); + return getLimitedAssignerList(assigners.stream().filter(i -> StringUtils.hasText(i.getPersonId())).collect(Collectors.toList())); } private List privateSelector(ApproverScopeEnum processorType, FlowElement flowElement, @@ -174,6 +175,19 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign } } + /** + * 获取指定数量审批人 + * + * @param assigners 原始的审批人列表 + * @return 截取后的审批人列表 + */ + protected List getLimitedAssignerList(List assigners) { + if (CollectionUtils.isEmpty(assigners) || assigners.size() <= ASSIGNER_LIMIT_NUMBER) { + return assigners; + } + return assigners.subList(0, ASSIGNER_LIMIT_NUMBER); + } + @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.applicationContext = context; diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java index 1934a672e..706553795 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java @@ -39,7 +39,7 @@ public class BasedFixedPersonTaskAssigneeSelector extends AbstractBpmnTaskAssign } BpmnMetaParserHelper.getApproverSpecifyValue((UserTask) flowElement) .ifPresent(s -> assigners.addAll(JSON.parseArray(s, BpmnTaskDelegateAssigner.class))); - return assigners; + return getLimitedAssignerList(assigners); } } From b3b1be05de6c12946b5072166ff9f1f4f363cddf Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 4 Jul 2024 18:58:34 +0800 Subject: [PATCH 08/42] =?UTF-8?q?REQ-2596-=E6=8A=84=E9=80=81=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8C=89=E4=BA=BA=E5=91=98=E6=95=B0=E9=87=8F=E5=88=86?= =?UTF-8?q?=E6=89=B9=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/common/constant/BpmnConstants.java | 5 +++++ .../listener/EngineCarbonCopyEventListener.java | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) 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 ef594a474..565af1d35 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 @@ -161,4 +161,9 @@ public interface BpmnConstants { * 审批人数量限制 */ Integer ASSIGNER_LIMIT_NUMBER = 60; + + /** + * 抄送MQ消息每批次人员数量 + */ + Integer CARBON_ASSIGNER_BATCH_SIZE = 20; } 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 c9f26d948..52050f161 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 @@ -36,6 +36,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import static cn.axzo.workflow.common.constant.BpmnConstants.CARBON_ASSIGNER_BATCH_SIZE; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCarbonCopyConfigs; @@ -107,11 +108,17 @@ public class EngineCarbonCopyEventListener implements JavaDelegate { } return conf; }).orElse(null); - - MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY, - carbonUsers, bpmnNoticeConf, execution.getProcessInstanceId(), - execution.getTenantId(), getCarbonTaskId(execution)); - eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey()); + //按人员批次发送消息 + int startIndex = 0, endIndex = Integer.min(startIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonUsers.size()); + do { + List bpmnTaskDelegateAssigners = carbonUsers.subList(startIndex, endIndex); + MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY, + bpmnTaskDelegateAssigners, bpmnNoticeConf, execution.getProcessInstanceId(), + execution.getTenantId(), getCarbonTaskId(execution)); + eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey()); + startIndex = endIndex; + endIndex = Integer.min(endIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonUsers.size()); + } while (startIndex < carbonUsers.size()); } private String getCarbonTaskId(DelegateExecution execution) { From a486798683a8198334180d7cecebb3546e27fa1e Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 5 Jul 2024 09:44:47 +0800 Subject: [PATCH 09/42] =?UTF-8?q?REQ-2596-=E8=B0=83=E6=95=B4=E6=8A=84?= =?UTF-8?q?=E9=80=81mq=E6=B6=88=E6=81=AF=E6=8C=89=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E5=88=86=E6=89=B9=E6=AC=A1=E6=8B=86=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/EngineCarbonCopyEventListener.java | 15 ++++----------- .../RocketMqMessagePushEventListener.java | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 14 deletions(-) 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 52050f161..e234836ca 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,17 +108,10 @@ public class EngineCarbonCopyEventListener implements JavaDelegate { } return conf; }).orElse(null); - //按人员批次发送消息 - int startIndex = 0, endIndex = Integer.min(startIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonUsers.size()); - do { - List bpmnTaskDelegateAssigners = carbonUsers.subList(startIndex, endIndex); - MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY, - bpmnTaskDelegateAssigners, bpmnNoticeConf, execution.getProcessInstanceId(), - execution.getTenantId(), getCarbonTaskId(execution)); - eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey()); - startIndex = endIndex; - endIndex = Integer.min(endIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonUsers.size()); - } while (startIndex < carbonUsers.size()); + MessagePushEventImpl event = MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY, + carbonUsers, bpmnNoticeConf, execution.getProcessInstanceId(), + execution.getTenantId(), getCarbonTaskId(execution)); + eventDispatcher.dispatchEvent(event, processEngineConfiguration.getEngineCfgKey()); } private String getCarbonTaskId(DelegateExecution execution) { 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 42d5e652a..6a7837071 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; @@ -43,6 +45,7 @@ import java.util.Objects; import java.util.stream.Collectors; import static cn.axzo.workflow.common.constant.BpmnConstants.BIZ_ORG_RELATION; +import static cn.axzo.workflow.common.constant.BpmnConstants.CARBON_ASSIGNER_BATCH_SIZE; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID; @@ -248,9 +251,17 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener< 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); + List carbonAssigners = event.getAssigners(); + //按人员拆分为多个批次发送消息 + int startIndex = 0; + do { + List batchAssigners = carbonAssigners.subList(startIndex, Integer.min(startIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonAssigners.size())); + MessagePushEventImpl messagePushEvent = BeanConverter.convert(event, MessagePushEventImpl.class); + messagePushEvent.setAssigner(batchAssigners); + MessagePushDTO dto = build(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(), PROCESS_CARBON_COPY, messagePushEvent, collectionVariable(event)); + sendMessageQueue(dto, PROCESS_CARBON_COPY); + startIndex = startIndex + CARBON_ASSIGNER_BATCH_SIZE; + } while (startIndex < carbonAssigners.size()); } log.info("RocketMqMessagePushEventListener#onCarbonCopy...end, cc' templateId: {}, receivePerson: {}, processInstanceId: {}", event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(), From 9e4d81504eafd1821efffe31e05e424b58b9fa36 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 5 Jul 2024 16:54:11 +0800 Subject: [PATCH 10/42] =?UTF-8?q?REQ-2596-=E4=B8=9A=E5=8A=A1=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E5=AE=A1=E6=89=B9=E4=BA=BA=EF=BC=8C=E5=8A=A0=E7=AD=BE?= =?UTF-8?q?=E4=BA=BA=E5=91=98=E6=95=B0=E9=87=8F=E9=97=B2=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?60?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/request/bpmn/task/BpmnActivitySetAssigneeDTO.java | 2 ++ .../common/model/request/bpmn/task/BpmnTaskCountersignDTO.java | 2 ++ 2 files changed, 4 insertions(+) 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 32dd5fec4..4ca903486 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 @@ -6,6 +6,7 @@ import lombok.Data; import javax.validation.Valid; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; import java.util.List; /** @@ -47,6 +48,7 @@ public class BpmnActivitySetAssigneeDTO { */ @ApiModelProperty(value = "审批人集合信息", notes = "业务传参时,需要注意去重") @Valid + @Size(max = 60, message = "指定审批人数量限制为60") private List assigners; /** diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java index 537d25e15..4b622bc22 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java @@ -8,6 +8,7 @@ import lombok.experimental.Accessors; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import java.io.Serializable; import java.util.List; @@ -59,6 +60,7 @@ public class BpmnTaskCountersignDTO implements Serializable { */ @ApiModelProperty(value = "加签任务转发给谁") @NotEmpty(message = "加签任务接收人不能为空") + @Size(max = 60, min = 1, message = "加签人数量最小为:{min},最大为:{max}") private List targetAssignerList; /** From c94b7e0377938fd5b750631537340ff07e491505 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 5 Jul 2024 16:59:28 +0800 Subject: [PATCH 11/42] =?UTF-8?q?REQ-2596-=E8=B0=83=E6=95=B4=E5=8A=A0?= =?UTF-8?q?=E7=AD=BE=E4=BA=BA=E6=95=B0=E9=87=8F=E9=99=90=E5=88=B6=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/model/request/bpmn/task/BpmnTaskCountersignDTO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java index 4b622bc22..e59bd4301 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java @@ -60,7 +60,7 @@ public class BpmnTaskCountersignDTO implements Serializable { */ @ApiModelProperty(value = "加签任务转发给谁") @NotEmpty(message = "加签任务接收人不能为空") - @Size(max = 60, min = 1, message = "加签人数量最小为:{min},最大为:{max}") + @Size(max = 60, min = 1, message = "加签任务接收人数量最小为:{min},最大为:{max}") private List targetAssignerList; /** From d3a3364cfcaa59e061070edd41174085037635e0 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 9 Jul 2024 09:53:37 +0800 Subject: [PATCH 12/42] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPROCESS=5FACTIVITY=5FEN?= =?UTF-8?q?D=E4=BA=8B=E4=BB=B6,activityName=E5=80=BC=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/activity/RocketMqBpmActivityEventListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1da62614e..07ef0997c 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 @@ -135,7 +135,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()); From cf394d91200b728f110efa25c9944716ddcdb183 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 9 Jul 2024 15:50:33 +0800 Subject: [PATCH 13/42] =?UTF-8?q?REQ-2596-=E8=B0=83=E6=95=B4=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=BF=87=E5=AE=A1=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nUtils.java => MultiVersionBeanUtils.java} | 27 ++++++++++++++++--- .../axzo/workflow/core/version/Versioned.java | 2 ++ .../task/AutoOperatorEvent_101_Listener.java | 8 +++--- ...Service.java => CheckApproverService.java} | 2 +- .../impl/CheckApproverServiceImpl.java | 8 +++--- 5 files changed, 34 insertions(+), 13 deletions(-) rename workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/{GetSpecifiedVersionBeanUtils.java => MultiVersionBeanUtils.java} (51%) rename workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/task/service/{CheckApproveService.java => CheckApproverService.java} (88%) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java similarity index 51% rename from workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java rename to workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java index e2c938430..69e0de189 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/GetSpecifiedVersionBeanUtils.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/version/MultiVersionBeanUtils.java @@ -10,17 +10,36 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -public class GetSpecifiedVersionBeanUtils { - public static T getSpecialVersionBean(Class clazz, String version) { +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 = SpringContentUtils.getBeansOfType(clazz); if (CollectionUtils.isEmpty(beans)) { throw new NullPointerException("no beans of type " + clazz.getName()); } if (StringUtils.isEmpty(version)) { - //todo 版本为空,需要一个默认处理类?? + T t = beans.values().stream().filter(bean -> bean.getVersion() == null).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().collect(Collectors.toList()); + 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--) { int flag = sortedList.get(i).getVersion().compareTo(targetVersion); 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 index be73a4aa6..b024b21d3 100644 --- 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 @@ -5,4 +5,6 @@ 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-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 91afe0f68..0396802a1 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 @@ -11,8 +11,8 @@ 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.service.ExtAxHiTaskInstService; -import cn.axzo.workflow.core.version.GetSpecifiedVersionBeanUtils; -import cn.axzo.workflow.server.controller.listener.task.service.CheckApproveService; +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; @@ -92,8 +92,8 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener Date: Tue, 9 Jul 2024 18:26:21 +0800 Subject: [PATCH 14/42] =?UTF-8?q?REQ-2596-=E4=BA=BA=E5=91=98=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=B7=BB=E5=8A=A0=E6=9F=A5=E8=AF=A2=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/request/bpmn/task/BpmnTaskDelegateAssigner.java | 6 ++++++ .../delegate/AbstractBpmnTaskAssigneeSelector.java | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java index 899584415..97901fdbf 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java @@ -1,5 +1,6 @@ package cn.axzo.workflow.common.model.request.bpmn.task; +import cn.axzo.workflow.common.enums.ApproverScopeEnum; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; @@ -96,6 +97,11 @@ public class BpmnTaskDelegateAssigner implements Serializable { */ private String avatar; + /** + * 人员查询对应的组织范围 + */ + private ApproverScopeEnum approverScopeEnum; + public final String buildAssigneeId_1_2_1() { if (StringUtils.hasLength(assigneeType)) { return tenantId + "|" + assignee + "|" + assigneeType; diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java index 0e296d4e9..292fcb43d 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java @@ -89,7 +89,12 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign } } try { - return invokeService(flowElement, execution, scopeDto); + List bpmnTaskDelegateAssigners = invokeService(flowElement, execution, scopeDto); + //设置查询组织范围 + if (!CollectionUtils.isEmpty(bpmnTaskDelegateAssigners)) { + bpmnTaskDelegateAssigners.forEach(assigner -> assigner.setApproverScopeEnum(processorType)); + } + return bpmnTaskDelegateAssigners; } catch (Throwable t) { if (throwException) { if (!(t instanceof WorkflowEngineException)) { From f0d31e071506fa7cbdfd70819675b57cc2005a64 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 10 Jul 2024 10:21:23 +0800 Subject: [PATCH 15/42] =?UTF-8?q?update=20-=20=E5=A2=9E=E5=8A=A0=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/interceptor/CustomRetryInterceptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); From c4dab46b746a564e0b858854e226f73a02953678 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 10 Jul 2024 14:34:28 +0800 Subject: [PATCH 16/42] =?UTF-8?q?Revert=20"REQ-2596-=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=B7=BB=E5=8A=A0=E6=9F=A5=E8=AF=A2=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E8=8C=83=E5=9B=B4=E5=AD=97=E6=AE=B5"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 81a7ebe5c49e26a2cf935e8200f7f51c42fa14c3. --- .../model/request/bpmn/task/BpmnTaskDelegateAssigner.java | 6 ------ .../delegate/AbstractBpmnTaskAssigneeSelector.java | 7 +------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java index 97901fdbf..899584415 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskDelegateAssigner.java @@ -1,6 +1,5 @@ package cn.axzo.workflow.common.model.request.bpmn.task; -import cn.axzo.workflow.common.enums.ApproverScopeEnum; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; @@ -97,11 +96,6 @@ public class BpmnTaskDelegateAssigner implements Serializable { */ private String avatar; - /** - * 人员查询对应的组织范围 - */ - private ApproverScopeEnum approverScopeEnum; - public final String buildAssigneeId_1_2_1() { if (StringUtils.hasLength(assigneeType)) { return tenantId + "|" + assignee + "|" + assigneeType; diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java index 292fcb43d..0e296d4e9 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java @@ -89,12 +89,7 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign } } try { - List bpmnTaskDelegateAssigners = invokeService(flowElement, execution, scopeDto); - //设置查询组织范围 - if (!CollectionUtils.isEmpty(bpmnTaskDelegateAssigners)) { - bpmnTaskDelegateAssigners.forEach(assigner -> assigner.setApproverScopeEnum(processorType)); - } - return bpmnTaskDelegateAssigners; + return invokeService(flowElement, execution, scopeDto); } catch (Throwable t) { if (throwException) { if (!(t instanceof WorkflowEngineException)) { From da29cbd5e09878202dcb1d5e75f5a7d3900c2f35 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 10 Jul 2024 18:05:02 +0800 Subject: [PATCH 17/42] =?UTF-8?q?REQ-2516-=E8=B0=83=E6=95=B4=E4=BA=BA?= =?UTF-8?q?=E5=91=98=E6=95=B0=E6=8D=AE=E6=88=AA=E5=8F=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/cmd/helper/CustomTaskHelper.java | 16 ++++++++++++++++ .../listener/EngineExecutionStartListener.java | 12 +++++++----- .../AbstractBpmnTaskAssigneeSelector.java | 15 +-------------- .../BasedFixedPersonTaskAssigneeSelector.java | 2 +- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java index 85e63eb32..bbd438a49 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java @@ -379,6 +379,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 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/listener/EngineExecutionStartListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineExecutionStartListener.java index b110445a1..3c8689c7c 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.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, 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 多实例, 该变量用于引擎 @@ -249,8 +251,8 @@ public class EngineExecutionStartListener implements ExecutionListener { }); } - // 按 personId 去重 - return removeDuplicateByPersonId(assigners); + // 按 personId 去重,再截取指定个数 + return getLimitedElementList(removeDuplicateByPersonId(assigners), ASSIGNER_LIMIT_NUMBER); } /** diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java index 0e296d4e9..7b30457d5 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java @@ -73,7 +73,7 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign ApproverScopeEnum processor = ((NoticeFlowElement) flowElement).getProcessor(); assigners.addAll(privateSelector(processor, flowElement, execution, throwException)); } - return getLimitedAssignerList(assigners.stream().filter(i -> StringUtils.hasText(i.getPersonId())).collect(Collectors.toList())); + return assigners.stream().filter(i -> StringUtils.hasText(i.getPersonId())).collect(Collectors.toList()); } private List privateSelector(ApproverScopeEnum processorType, FlowElement flowElement, @@ -175,19 +175,6 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign } } - /** - * 获取指定数量审批人 - * - * @param assigners 原始的审批人列表 - * @return 截取后的审批人列表 - */ - protected List getLimitedAssignerList(List assigners) { - if (CollectionUtils.isEmpty(assigners) || assigners.size() <= ASSIGNER_LIMIT_NUMBER) { - return assigners; - } - return assigners.subList(0, ASSIGNER_LIMIT_NUMBER); - } - @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.applicationContext = context; diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java index 706553795..1934a672e 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/BasedFixedPersonTaskAssigneeSelector.java @@ -39,7 +39,7 @@ public class BasedFixedPersonTaskAssigneeSelector extends AbstractBpmnTaskAssign } BpmnMetaParserHelper.getApproverSpecifyValue((UserTask) flowElement) .ifPresent(s -> assigners.addAll(JSON.parseArray(s, BpmnTaskDelegateAssigner.class))); - return getLimitedAssignerList(assigners); + return assigners; } } From 6a7d6bfacde1037c26574180422b44357592f388 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 10 Jul 2024 20:21:31 +0800 Subject: [PATCH 18/42] =?UTF-8?q?REQ-2516-=E9=80=9A=E7=9F=A5mq=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8C=89=E4=BA=BA=E6=95=B0=E5=88=86=E6=89=B9=E5=8F=91?= =?UTF-8?q?=E9=80=81,=E8=B0=83=E6=95=B4=E4=BA=BA=E5=91=98=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=88=AA=E5=8F=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/BpmnConstants.java | 4 +- .../cmd/CustomCarbonCopyUserSelectorCmd.java | 4 +- .../CustomForecastUserTaskAssigneeCmd.java | 4 +- .../EngineCarbonCopyEventListener.java | 1 - .../EngineExecutionStartListener.java | 4 +- .../RocketMqMessagePushEventListener.java | 42 ++++++++++++------- 6 files changed, 38 insertions(+), 21 deletions(-) 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 565af1d35..512abf740 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 @@ -163,7 +163,7 @@ public interface BpmnConstants { Integer ASSIGNER_LIMIT_NUMBER = 60; /** - * 抄送MQ消息每批次人员数量 + * MQ消息每批次人员数量 */ - Integer CARBON_ASSIGNER_BATCH_SIZE = 20; + Integer MQ_ASSIGNER_BATCH_SIZE = 20; } 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 f43a8bb8b..f57612ec6 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 @@ -33,10 +33,12 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; 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; /** @@ -127,7 +129,7 @@ public class CustomCarbonCopyUserSelectorCmd implements Command getApproverRelationUser(BpmnCarbonCopyConf carbon, 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 bb6070b5c..63757de1f 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 @@ -21,7 +21,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify; +import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getLimitedElementList; /** * 自定义的推测用户任务的审批人的命令实现 @@ -79,6 +81,6 @@ public class CustomForecastUserTaskAssigneeCmd implements Command sendMessageQueue(dto, PROCESS_PUSH_NOTICE)); } log.info("RocketMqMessagePushEventListener#onNotice...end, msgTemplateId: {}, receivePerson: {}, processInstanceId: {}", event.getNoticeConfig().getNotice().getNoticeMessageId(), JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId()); @@ -251,23 +249,39 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener< event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(), JSONUtil.toJsonStr(event.getAssigners()), event.getProcessInstanceId()); if (Objects.nonNull(event.getNoticeConfig().getCarbonCopy())) { - List carbonAssigners = event.getAssigners(); //按人员拆分为多个批次发送消息 - int startIndex = 0; - do { - List batchAssigners = carbonAssigners.subList(startIndex, Integer.min(startIndex + CARBON_ASSIGNER_BATCH_SIZE, carbonAssigners.size())); - MessagePushEventImpl messagePushEvent = BeanConverter.convert(event, MessagePushEventImpl.class); - messagePushEvent.setAssigner(batchAssigners); - MessagePushDTO dto = build(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId(), PROCESS_CARBON_COPY, messagePushEvent, collectionVariable(event)); - sendMessageQueue(dto, PROCESS_CARBON_COPY); - startIndex = startIndex + CARBON_ASSIGNER_BATCH_SIZE; - } while (startIndex < carbonAssigners.size()); + 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(); + 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 = BeanConverter.convert(event, MessagePushEventImpl.class); + 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; + } + /** * 完成抄送 * From 300ff3c2b8795fe0aa0883a0768e036053374b1c Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 11 Jul 2024 10:40:34 +0800 Subject: [PATCH 19/42] =?UTF-8?q?REQ-2516-=E8=87=AA=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E5=AE=A1=E9=85=8D=E7=BD=AE=E8=AE=BE=E7=BD=AE=E5=88=B0=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E9=AB=98=E7=BA=A7=E9=85=8D=E7=BD=AE=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/common/model/request/BpmnApproveConf.java | 7 +++++++ .../model/request/bpmn/BpmnJsonNodeProperty.java | 3 --- .../core/common/utils/BpmnJsonConverterUtil.java | 10 ++++++++++ .../core/common/utils/BpmnMetaParserHelper.java | 4 ---- .../core/converter/json/UserTaskJsonConverter.java | 1 - .../listener/task/AutoOperatorEvent_101_Listener.java | 5 +++-- 6 files changed, 20 insertions(+), 10 deletions(-) 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 0b1bd2115..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 @@ -147,7 +147,4 @@ public class BpmnJsonNodeProperty { */ @ApiModelProperty(value = "发起时使用的表单 key") private String formKey; - - @ApiModelProperty(value = "同一审批人自动过审类型,默认不自动过审") - private AutoApprovalTypeEnum autoApproval = AutoApprovalTypeEnum.NO_AUTO_APPROVAL; } 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 8131cb4ac..880d1911b 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 @@ -379,10 +379,6 @@ public final class BpmnMetaParserHelper { return defaultValid(userTask, CONFIG_APPROVER_EMPTY_HANDLE_TYPE).map(element -> StringUtils.hasLength(element.getElementText()) ? element.getElementText() : "[]"); } - public static Optional getAutoApprovalValue(UserTask userTask) { - return defaultValid(userTask, AUTO_APPROVAL_TYPE).map(element -> AutoApprovalTypeEnum.valueOf(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/converter/json/UserTaskJsonConverter.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/converter/json/UserTaskJsonConverter.java index f3c4276f7..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 @@ -152,7 +152,6 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter { ExtensionElement autoApprovalExtensionElement = new ExtensionElement(); ExtensionAttribute pendingMessageAttribute = new ExtensionAttribute(); pendingMessageAttribute.setName(AUTO_APPROVAL_TYPE); - pendingMessageAttribute.setValue(node.getProperty().getAutoApproval().getType()); autoApprovalExtensionElement.addAttribute(pendingMessageAttribute); userTask.addExtensionElement(autoApprovalExtensionElement); } 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 0396802a1..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,6 +1,7 @@ package cn.axzo.workflow.server.controller.listener.task; 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.core.common.context.TaskOperationContext; @@ -87,9 +88,9 @@ public class AutoOperatorEvent_101_Listener extends AbstractBpmnEventListener approvalTypeEnumOpt = BpmnMetaParserHelper.getAutoApprovalValue(userTask); + Optional processApproveConf = BpmnMetaParserHelper.getProcessApproveConf(mainProcess); //自动过审配置连续节点自动过审才处理,历史数据默认不自动过审 - if (approvalTypeEnumOpt.isPresent() && approvalTypeEnumOpt.get() == AutoApprovalTypeEnum.CONTINUOUS_NODES_AUTO_APPROVAL) { + 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); From ffe4bfa527c097d5a5d5afd4aa447667908a926d Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 11 Jul 2024 13:44:18 +0800 Subject: [PATCH 20/42] =?UTF-8?q?REQ-2516-=E8=B0=83=E6=95=B4=E6=8A=84?= =?UTF-8?q?=E9=80=81=E4=BA=BA=E5=91=98=E6=95=B0=E9=87=8F=E9=99=90=E5=88=B6?= =?UTF-8?q?=E4=B8=BA100?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/workflow/common/constant/BpmnConstants.java | 7 ++++++- .../core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java | 4 ++-- .../core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java | 4 ++-- .../core/engine/listener/EngineExecutionStartListener.java | 4 ++-- .../delegate/AbstractBpmnTaskAssigneeSelector.java | 1 - 5 files changed, 12 insertions(+), 8 deletions(-) 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 512abf740..39afb3e03 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 @@ -160,7 +160,12 @@ public interface BpmnConstants { /** * 审批人数量限制 */ - Integer ASSIGNER_LIMIT_NUMBER = 60; + Integer APPROVAL_ASSIGNER_LIMIT_NUMBER = 60; + + /** + * 抄送人员数量限制 + */ + Integer CARBON_ASSIGNER_LIMIT_NUMBER = 100; /** * MQ消息每批次人员数量 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 f57612ec6..884eab272 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 @@ -33,7 +33,7 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; +import static cn.axzo.workflow.common.constant.BpmnConstants.CARBON_ASSIGNER_LIMIT_NUMBER; 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; @@ -129,7 +129,7 @@ public class CustomCarbonCopyUserSelectorCmd implements Command getApproverRelationUser(BpmnCarbonCopyConf carbon, 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 63757de1f..ba6b61fed 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 @@ -21,7 +21,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; +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; @@ -81,6 +81,6 @@ public class CustomForecastUserTaskAssigneeCmd implements Command resultAssigners = getLimitedElementList(assigners, ASSIGNER_LIMIT_NUMBER); + List resultAssigners = getLimitedElementList(assigners, APPROVAL_ASSIGNER_LIMIT_NUMBER); for (BpmnTaskDelegateAssigner user : resultAssigners) { assigneeIdList.add(user.buildAssigneeId()); } diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java index 7b30457d5..0d32c68cf 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/delegate/AbstractBpmnTaskAssigneeSelector.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; -import static cn.axzo.workflow.common.constant.BpmnConstants.ASSIGNER_LIMIT_NUMBER; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.CALC_TASK_ASSIGNEE_ERROR; import static cn.axzo.workflow.core.common.code.ConvertorRespCode.CONVERTOR_META_DATA_FORMAT_ERROR; import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_USER_TASK_CALC_ERROR; From a67dd3ddfc7ef5089a7dff5020b61f722882baa3 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 11 Jul 2024 18:25:43 +0800 Subject: [PATCH 21/42] =?UTF-8?q?REQ-2516-=E8=B0=83=E6=95=B4=E6=8A=84?= =?UTF-8?q?=E9=80=81=E4=BA=BA=E5=91=98=E6=95=B0=E9=87=8F=E9=99=90=E5=88=B6?= =?UTF-8?q?,=E6=A0=B9=E6=8D=AE=E5=BD=93=E5=89=8D=E5=B7=B2=E6=9C=89?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E4=BA=BA=E5=AE=9E=E6=97=B6=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpmn/task/BpmnTaskCountersignDTO.java | 2 -- .../core/common/code/BpmnTaskRespCode.java | 3 ++ .../CustomBizSpecifyAssigneeToTaskCmd.java | 32 ++++++++++++++----- .../CustomCountersignUserTaskAsyncCmd.java | 6 ++-- .../cmd/CustomCountersignUserTaskCmd.java | 4 ++- .../engine/cmd/helper/CustomTaskHelper.java | 25 +++++++++++++-- .../impl/BpmnProcessActivityServiceImpl.java | 5 +++ 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java index e59bd4301..537d25e15 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnTaskCountersignDTO.java @@ -8,7 +8,6 @@ import lombok.experimental.Accessors; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.io.Serializable; import java.util.List; @@ -60,7 +59,6 @@ public class BpmnTaskCountersignDTO implements Serializable { */ @ApiModelProperty(value = "加签任务转发给谁") @NotEmpty(message = "加签任务接收人不能为空") - @Size(max = 60, min = 1, message = "加签任务接收人数量最小为:{min},最大为:{max}") private List targetAssignerList; /** 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 413370c01..4ed05bf5b 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; + /** * 流程模型响应码 * @@ -33,6 +35,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode { FIND_TASK_BY_PERSON_ID_ERROR("018", "流程实例中:【{}】未查找指定自然人:【{}】的待处理的流程任务!"), PROCESS_INSTANCE_IS_NOT_EXIST("019", "Execution:{} 对应流程实例不存在,流程状态异常!"), TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"), + ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT("021", String.format("人员数量超过限制,节点审批人限制数量为: %d!", APPROVAL_ASSIGNER_LIMIT_NUMBER)), ; private final String code; 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 bdbe80e61..256888d8a 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.RuntimeService; import org.flowable.engine.TaskService; @@ -27,6 +26,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERA import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETED; 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.engine.cmd.helper.CustomTaskHelper.validTaskAssignerCount; /** * 自定的业务指定审批人命令实现 @@ -52,17 +52,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); changeAssigneeSnapshot(commandContext, task); @@ -105,7 +121,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/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..95206dfa3 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,6 @@ 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.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -31,6 +30,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addCommen 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 +90,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); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java index bbd438a49..a22800f82 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java @@ -49,6 +49,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO; @@ -58,10 +59,10 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERA import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY; import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ASSIGNEE_HAS_BEEN_EXISTS; +import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE; -import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH; import static org.flowable.task.api.Task.DEFAULT_PRIORITY; /** @@ -153,7 +154,7 @@ public class CustomTaskHelper { //不包含对应的任务 if (!nodeTypes.contains(nodeType)) { // log.warn(TASK_TYPE_MISMATCH.getMessage(), nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); - throw new WorkflowEngineException(TASK_TYPE_MISMATCH, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); + throw new WorkflowEngineException(ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); } } } @@ -193,6 +194,26 @@ public class CustomTaskHelper { return taskAssignerListSnapshot; } + /** + * 校验人员数量是否超过限制 + * + * @param runtimeService + * @param taskEntity + * @param targetAssigneeList + * @return + */ + public static List 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; + } + /** * 保存附件 * 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); } From eee3f4f882fc337a393e53b71faac3d96606f5fb Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 09:51:18 +0800 Subject: [PATCH 22/42] =?UTF-8?q?REQ-2516-=E8=B0=83=E6=95=B4=E5=88=86?= =?UTF-8?q?=E6=89=B9=E6=AC=A1=E5=8F=91=E9=80=81mq=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/notice/RocketMqMessagePushEventListener.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 952d7a748..a0bdb86cb 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 @@ -268,12 +268,16 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener< 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 = BeanConverter.convert(event, MessagePushEventImpl.class); + MessagePushEventImpl messagePushEvent = new MessagePushEventImpl(event.getType()); + BeanConverter.convert(event, messagePushEvent); messagePushEvent.setAssigner(batchAssigners); MessagePushDTO dto = build(templateId, type, messagePushEvent, objectMap); slice.add(dto); From 14e1895fc0ba4a6157040779610f110b25f31bf0 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 15:22:39 +0800 Subject: [PATCH 23/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8D=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E6=B5=81=E7=A8=8B=E9=85=8D=E7=BD=AE=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=BF=87=E5=AE=A1=E9=85=8D=E7=BD=AE=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/workflow/core/common/utils/BpmnMetaParserHelper.java | 4 ++++ 1 file changed, 4 insertions(+) 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 880d1911b..c89da5fc6 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 @@ -106,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)) { @@ -114,6 +115,9 @@ 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); + conf.setAutoApprovalType(AutoApprovalTypeEnum.valueOf(value)); } }); } From af553bb7304fc991bb55bc11d7b4fcc3218b3e29 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 15:44:05 +0800 Subject: [PATCH 24/42] =?UTF-8?q?REQ-2596-=E5=A4=84=E7=90=86=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=B5=81=E7=A8=8B=E6=A8=A1=E5=9E=8B=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/common/enums/AutoApprovalTypeEnum.java | 12 ++++++++++++ .../core/common/utils/BpmnMetaParserHelper.java | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) 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 index 5c1c46bc1..91189769d 100644 --- 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 @@ -1,6 +1,7 @@ package cn.axzo.workflow.common.enums; import lombok.Getter; +import org.springframework.util.StringUtils; /** * 自动过审参数 @@ -20,4 +21,15 @@ public enum AutoApprovalTypeEnum { 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-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 c89da5fc6..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 @@ -117,7 +117,8 @@ public final class BpmnMetaParserHelper { conf.setUserAgreeSignature(Boolean.valueOf(value)); } else if (AUTO_APPROVAL_TYPE.equals(k)) { String value = v.get(0).getAttributeValue(null, ELEMENT_ATTRIBUTE_VALUE); - conf.setAutoApprovalType(AutoApprovalTypeEnum.valueOf(value)); + AutoApprovalTypeEnum typeEnum = AutoApprovalTypeEnum.fromType(value); + conf.setAutoApprovalType(typeEnum == null ? AutoApprovalTypeEnum.NO_AUTO_APPROVAL : typeEnum); } }); } From af26c4bb6db6a834f0870aee1c4df2c27414d29c Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 16:58:16 +0800 Subject: [PATCH 25/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8Dbean=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E8=8E=B7=E5=8F=96bean=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ngContentUtils.java => SpringContextUtils.java} | 8 ++++---- .../workflow/core/conf/FlowableConfiguration.java | 14 +++++++++----- .../core/version/MultiVersionBeanUtils.java | 4 ++-- 3 files changed, 15 insertions(+), 11 deletions(-) rename workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/{SpringContentUtils.java => SpringContextUtils.java} (70%) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java similarity index 70% rename from workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java rename to workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java index 202663f32..86871e9d1 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContentUtils.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/SpringContextUtils.java @@ -4,12 +4,12 @@ import org.springframework.lang.Nullable; import java.util.Map; -public class SpringContentUtils { +public class SpringContextUtils { - private static SpringContentUtils.SpringContext springContext; + private static SpringContextUtils.SpringContext springContext; - public SpringContentUtils(SpringContentUtils.SpringContext springContext) { - SpringContentUtils.springContext = springContext; + public SpringContextUtils(SpringContextUtils.SpringContext springContext) { + SpringContextUtils.springContext = springContext; } public static T getBean(Class clazz) { 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 753700560..2a0c0c3c3 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,6 +1,6 @@ package cn.axzo.workflow.core.conf; -import cn.axzo.workflow.core.common.utils.SpringContentUtils; +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; @@ -22,7 +22,6 @@ import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import com.alibaba.cloud.nacos.NacosDiscoveryProperties; import com.alibaba.cloud.nacos.NacosServiceManager; import com.google.common.collect.Lists; -import org.apache.ibatis.session.SqlSessionFactory; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.common.engine.impl.history.HistoryLevel; import org.flowable.form.spring.SpringFormEngineConfiguration; @@ -32,11 +31,11 @@ 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.boot.autoconfigure.condition.ConditionalOnBean; 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; @@ -119,9 +118,14 @@ public class FlowableConfiguration { return new CustomActivityBehaviorFactory(); } + @Bean + @Order + public SpringContextUtils springContextUtils(SpringContext springContext) { + return new SpringContextUtils(springContext); + } + @Configuration - @ConditionalOnBean({SqlSessionFactory.class}) - public static class SpringContext implements SpringContentUtils.SpringContext, ApplicationContextAware { + public static class SpringContext implements SpringContextUtils.SpringContext, ApplicationContextAware { private ApplicationContext applicationContext; public SpringContext() { 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 index 69e0de189..294de8973 100644 --- 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 @@ -1,7 +1,7 @@ package cn.axzo.workflow.core.version; -import cn.axzo.workflow.core.common.utils.SpringContentUtils; +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; @@ -23,7 +23,7 @@ public class MultiVersionBeanUtils { * @return */ public static T getSpecifiedVersionBean(Class clazz, String version) { - Map beans = SpringContentUtils.getBeansOfType(clazz); + Map beans = SpringContextUtils.getBeansOfType(clazz); if (CollectionUtils.isEmpty(beans)) { throw new NullPointerException("no beans of type " + clazz.getName()); } From 7c1b5b1a482834f3343790dfbff1ba3f87584c65 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 17:14:32 +0800 Subject: [PATCH 26/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8DNPE=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/workflow/core/version/MultiVersionBeanUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 index 294de8973..a6393917d 100644 --- 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 @@ -28,7 +28,7 @@ public class MultiVersionBeanUtils { throw new NullPointerException("no beans of type " + clazz.getName()); } if (StringUtils.isEmpty(version)) { - T t = beans.values().stream().filter(bean -> bean.getVersion() == null).findFirst().orElse(null); + T t = beans.values().stream().filter(bean -> bean.getVersion() == null || bean.getVersion() == UNKNOWN_VERSION).findFirst().orElse(null); if (t != null) { return t; } @@ -42,7 +42,8 @@ public class MultiVersionBeanUtils { }).collect(Collectors.toList()); DefaultArtifactVersion targetVersion = new DefaultArtifactVersion(version); for (int i = sortedList.size() - 1; i >= 0; i--) { - int flag = sortedList.get(i).getVersion().compareTo(targetVersion); + 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); } From e5b40bcf871b5be493f59cb7cd9c01ce75c8bdb1 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 12 Jul 2024 17:27:58 +0800 Subject: [PATCH 27/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8subList=E6=96=B9=E6=B3=95=E6=88=AA=E5=8F=96list?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=E4=B8=8D=E8=83=BD=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java index a22800f82..efad5b23b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java @@ -413,7 +413,7 @@ public class CustomTaskHelper { if (CollectionUtils.isEmpty(assigners) || assigners.size() <= limitNumber) { return assigners; } - return assigners.subList(0, limitNumber); + return new ArrayList<>(assigners.subList(0, limitNumber)); } public static List getHistoryOperationUsers(CommandContext commandContext, String processInstanceId, From a155b2422cfb9080fc12b2f683ae098129e572bd Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 15 Jul 2024 10:47:44 +0800 Subject: [PATCH 28/42] =?UTF-8?q?REQ-2596-=E4=B8=9A=E5=8A=A1=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=8F=82=E4=B8=8E=E8=87=AA=E5=8A=A8=E8=BF=87=E5=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/task/service/impl/CheckApproverServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index e9a9190d6..0c3c75b3f 100644 --- 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 @@ -31,6 +31,7 @@ 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.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; @@ -52,7 +53,8 @@ public class CheckApproverServiceImpl implements CheckApproverService { AtomicBoolean exists = new AtomicBoolean(false); FlowElement currentFlowElement = mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey()); BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(currentFlowElement).orElse(NODE_EMPTY); - if (!Objects.equals(currentNodeType, NODE_TASK)) { + //业务节点,指定业务审批人,或者业务设置了审批人,也要参与自动过审,node_type为NODE_BUSINESS,节点元素类型为UserTask + if (!Objects.equals(currentNodeType, NODE_TASK) && !Objects.equals(currentNodeType, NODE_BUSINESS)) { return exists.get(); } Optional optConfig = BpmnMetaParserHelper.getButtonConfig(mainProcess, delegateTask.getTaskDefinitionKey()); From 6ea8b4b95bb918207b2f94e421ea98455f8a8fa3 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 15 Jul 2024 13:54:27 +0800 Subject: [PATCH 29/42] =?UTF-8?q?REQ-2596-=E8=87=AA=E5=8A=A8=E8=BF=87?= =?UTF-8?q?=E5=AE=A1=E5=88=A4=E6=96=AD,=E4=B8=8A=E4=B8=80=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=A6=82=E6=9E=9C=E6=98=AF=E4=B8=9A=E5=8A=A1=E8=8A=82?= =?UTF-8?q?=E7=82=B9,=E4=BD=86=E6=98=AF=E6=98=AF=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E5=AE=A1=E6=89=B9,=E4=B9=9F=E9=9C=80=E8=A6=81=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E5=88=B0=E8=87=AA=E5=8A=A8=E8=BF=87=E5=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/task/service/impl/CheckApproverServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 0c3c75b3f..6c1a0009a 100644 --- 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 @@ -94,7 +94,8 @@ public class CheckApproverServiceImpl implements CheckApproverService { } else { FlowElement flowElement = mainProcess.getFlowElement(i.getActivityId()); BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(j -> { - if (Objects.equals(NODE_TASK, 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()); From ada988a158ece409a09292e93abd4d30c521e488 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 15 Jul 2024 14:35:52 +0800 Subject: [PATCH 30/42] =?UTF-8?q?REQ-2596-=E4=B8=9A=E5=8A=A1=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=AE=BE=E7=BD=AE=E4=B8=BA=E6=8C=87=E5=AE=9A=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E4=BA=BA,=E8=BF=98=E6=9C=AA=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E4=BA=BA=E6=97=B6,=E4=B8=8D=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E8=87=AA=E5=8A=A8=E8=BF=87=E5=AE=A1=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/task/service/impl/CheckApproverServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index 6c1a0009a..e3e5cb77e 100644 --- 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 @@ -31,6 +31,7 @@ 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; @@ -54,7 +55,8 @@ public class CheckApproverServiceImpl implements CheckApproverService { 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)) { + //业务节点审批人为空,或者人员未指定,此时不进行自动过审操作,需要再业务指定审批人后,再做自动过审动作 + 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()); From 9b55b354e6cf271a9f168b2a346e7c7bfa003abb Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 15 Jul 2024 15:06:45 +0800 Subject: [PATCH 31/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8D=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=BF=87=E5=AE=A1=E6=9D=A1=E4=BB=B6=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/task/service/impl/CheckApproverServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index e3e5cb77e..62db9bd4a 100644 --- 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 @@ -56,7 +56,9 @@ public class CheckApproverServiceImpl implements CheckApproverService { 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)) { + 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()); From 73913fc98043eea94f4bcd185f6f51a86eb008d4 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 19 Jul 2024 16:36:09 +0800 Subject: [PATCH 32/42] =?UTF-8?q?REQ-2596-=E5=BC=82=E6=AD=A5=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E6=89=A7=E8=A1=8Cjob=E6=B7=BB=E5=8A=A0=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractExecuteWithLockJobHandler.java | 44 +++++++++++++++++++ .../job/AsyncApproveTaskJobHandler.java | 11 +---- .../engine/job/AsyncRejectTaskJobHandler.java | 4 +- .../core/repository/entity/ExtAxProperty.java | 4 ++ .../core/service/ExtAxPropertyService.java | 14 ++++++ .../impl/ExtAxPropertyServiceImpl.java | 30 +++++++++++++ .../main/resources/sql/upgrade_to_1.4.1.sql | 2 + 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AbstractExecuteWithLockJobHandler.java create mode 100644 workflow-engine-core/src/main/resources/sql/upgrade_to_1.4.1.sql 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..8aec1d2e5 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AbstractExecuteWithLockJobHandler.java @@ -0,0 +1,44 @@ +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); + 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/repository/entity/ExtAxProperty.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/repository/entity/ExtAxProperty.java index 79272e41d..f9cb34980 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 @@ -3,8 +3,10 @@ package cn.axzo.workflow.core.repository.entity; import cn.axzo.framework.data.mybatisplus.model.BaseEntity; 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 +19,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; 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/ExtAxPropertyServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/ExtAxPropertyServiceImpl.java index f496a7208..efbd273f4 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,7 +9,12 @@ import org.springframework.stereotype.Service; 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 实现 @@ -44,4 +49,29 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService { .eq("name", name); return Optional.ofNullable(mapper.selectOne(queryWrapper)); } + + @Override + 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/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); + From 5356549e48ee7dbc472a92680c4ecee8339e8ee0 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 19 Jul 2024 17:52:34 +0800 Subject: [PATCH 33/42] =?UTF-8?q?REQ-2596-ExtAxProperty=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE,=E6=96=B0=E5=BC=80?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/service/impl/ExtAxPropertyServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) 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 efbd273f4..77d677909 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 @@ -6,6 +6,8 @@ import cn.axzo.workflow.core.service.ExtAxPropertyService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; 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; @@ -29,6 +31,7 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService { private ExtAxPropertyMapper mapper; @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) public ExtAxProperty add(ExtAxProperty property) { mapper.insert(property); return property; @@ -51,6 +54,7 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService { } @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) public int delete(String name, String value) { if (!StringUtils.hasText(name)) { return 0; From aedfec0f312d70a57d995132c36dbdc9f6febda4 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Fri, 19 Jul 2024 23:31:07 +0800 Subject: [PATCH 34/42] =?UTF-8?q?REQ-2596-=E8=B0=83=E6=95=B4ExtAxProperty?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=B9=E5=BC=8F=E4=B8=BA=E7=89=A9=E7=90=86?= =?UTF-8?q?=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/job/AbstractExecuteWithLockJobHandler.java | 1 + .../axzo/workflow/core/repository/entity/ExtAxProperty.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) 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 index 8aec1d2e5..406dc44f0 100644 --- 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 @@ -31,6 +31,7 @@ public abstract class AbstractExecuteWithLockJobHandler extends AbstractJobHandl 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); 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 f9cb34980..57caa83cd 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,6 +1,7 @@ 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; @@ -38,5 +39,6 @@ public class ExtAxProperty extends BaseEntity { @TableField("value") private String value; - + @TableField(value = "is_delete", fill = FieldFill.INSERT) + private Long isDelete = 0L; } From a7782de83f7f4830bd18d74ae06f05f38f794f78 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 22 Jul 2024 11:56:53 +0800 Subject: [PATCH 35/42] =?UTF-8?q?REQ-2596-=E4=BF=AE=E5=A4=8DBUG-14296,?= =?UTF-8?q?=E5=8A=A0=E7=AD=BE=E4=BA=BA=E5=91=98=E6=98=BE=E7=A4=BA=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E5=81=9A=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/workflow/common/constant/BpmnConstants.java | 5 +++++ .../core/engine/cmd/CustomCountersignUserTaskCmd.java | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) 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 39afb3e03..a26560127 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 @@ -171,4 +171,9 @@ public interface BpmnConstants { * MQ消息每批次人员数量 */ Integer MQ_ASSIGNER_BATCH_SIZE = 20; + + /** + * 加签显示人员数量 + */ + Integer COUNTERSIGN_ASSIGNER_SHOW_NUMBER = 2; } 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 95206dfa3..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,6 +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.apache.commons.lang3.math.NumberUtils; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -24,6 +25,7 @@ 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; @@ -144,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("、"); From 4f12272526db04df8b59f61db8f386da28c81f69 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 24 Jul 2024 11:33:36 +0800 Subject: [PATCH 36/42] =?UTF-8?q?REQ-2596-=E5=8A=A0=E7=AD=BE=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BAjson=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/web/bpmn/BpmnProcessTaskController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 37c1eba57..ac2f5b490 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); } From 76ee6c0f92b831fee1a951ad79b018ceb7dd3859 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Thu, 25 Jul 2024 17:38:30 +0800 Subject: [PATCH 37/42] update(REQ-2596) - review code --- .../cmd/CustomCountersignUserTaskCmd.java | 3 +-- .../web/bpmn/BpmnProcessTaskController.java | 22 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) 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 d524ad757..7d5f7c2bb 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,6 @@ import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; -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; @@ -146,7 +145,7 @@ public class CustomCountersignUserTaskCmd extends AbstractCommand implemen TaskService taskService, Task task) { // 构建评论内容 StringBuilder message = new StringBuilder("添加"); - int end = NumberUtils.min(targetTaskAssigneeList.size(), COUNTERSIGN_ASSIGNER_SHOW_NUMBER); + int end = Math.min(targetTaskAssigneeList.size(), COUNTERSIGN_ASSIGNER_SHOW_NUMBER); //加签人员数量显示指定个数 for (int i = 0; i < end; i++) { message.append(targetTaskAssigneeList.get(i).getAssignerName()); 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 ac2f5b490..aaf1cf811 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 @@ -68,7 +68,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @GetMapping("/page/todo") @Override public CommonResponse> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) { - log.info("待审核列表 getTodoTaskPage===>>>参数:{}", dto); + log.info("待审核列表 getTodoTaskPage===>>>参数:{}", JSON.toJSONString(dto)); return success(bpmnProcessTaskService.getTodoTaskPage(dto)); } @@ -79,7 +79,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @GetMapping("/page/done") @Override public CommonResponse> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) { - log.info("已完成的审批列表 getDoneTaskPage===>>>参数:{}", dto); + log.info("已完成的审批列表 getDoneTaskPage===>>>参数:{}", JSON.toJSONString(dto)); return success(bpmnProcessTaskService.getDoneTaskPage(dto)); } @@ -92,7 +92,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse approveTask(@Validated @RequestBody BpmnTaskAuditDTO dto) { - log.info("同意 approveTask===>>>参数:{}", dto); + log.info("同意 approveTask===>>>参数:{}", JSON.toJSONString(dto)); List tempAttachments = ListUtils.defaultIfNull(dto.getAttachmentList(), new ArrayList<>()); if (StringUtils.hasText(dto.getSignatureUrl())) { AttachmentDTO signature = new AttachmentDTO(); @@ -114,7 +114,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse batchApproveTask(@Validated @RequestBody List dtos) { - log.info("批量同意 approveTaskList===>>>参数:{}", dtos); + log.info("批量同意 approveTaskList===>>>参数:{}", JSON.toJSONString(dtos)); return success(bpmnProcessTaskService.batchApproveTask(dtos)); } @@ -126,7 +126,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse rejectTask(@Validated @RequestBody BpmnTaskAuditDTO dto) { - log.info("驳回 rejectTask===>>>参数:{}", dto); + log.info("驳回 rejectTask===>>>参数:{}", JSON.toJSONString(dto)); bpmnProcessTaskService.rejectTask(dto); return success(true); } @@ -139,7 +139,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse batchRejectTask(@Validated @RequestBody List dtos) { - log.info("批量驳回 batchRejectTask===>>>参数:{}", dtos); + log.info("批量驳回 batchRejectTask===>>>参数:{}", JSON.toJSONString(dtos)); return success(bpmnProcessTaskService.batchRejectTask(dtos)); } @@ -151,7 +151,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse transferTask(@Validated @RequestBody BpmnTaskTransferDTO dto) { - log.info("转交任务 transferTask===>>>参数:{}", dto); + log.info("转交任务 transferTask===>>>参数:{}", JSON.toJSONString(dto)); bpmnProcessTaskService.transferTask(dto); return success(true); } @@ -161,7 +161,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse batchTransferTask(@Validated @RequestBody List dtos) { - log.info("批量转交任务 batchTransferTask===>>>参数:{}", dtos); + log.info("批量转交任务 batchTransferTask===>>>参数:{}", JSON.toJSONString(dtos)); return success(bpmnProcessTaskService.batchTransferTask(dtos)); } @@ -203,7 +203,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse remindTask(@Validated @RequestBody BpmnTaskRemindDTO dto) { - log.info("催办任务 remindTask===>>>参数:{}", dto); + log.info("催办任务 remindTask===>>>参数:{}", JSON.toJSONString(dto)); bpmnProcessTaskService.remindTask(dto); return success(true); } @@ -219,7 +219,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse createRobotTask(@Validated @RequestBody BpmnRobotTaskCreateDTO dto) { - log.info("创建机器人节点, 暂停流程任务 createRobotTask===>>>参数:{}", dto); + log.info("创建机器人节点, 暂停流程任务 createRobotTask===>>>参数:{}", JSON.toJSONString(dto)); return success(bpmnProcessTaskService.createRobotTask(dto)); } @@ -234,7 +234,7 @@ public class BpmnProcessTaskController implements ProcessTaskApi { @Override @RepeatSubmit public CommonResponse completeRobotTask(@Validated @RequestBody BpmnRobotTaskCompleteDTO dto) { - log.info("完成机器人节点, 继续流程任务 completeRobotTask===>>>参数:{}", dto); + log.info("完成机器人节点, 继续流程任务 completeRobotTask===>>>参数:{}", JSON.toJSONString(dto)); bpmnProcessTaskService.completeRobotTask(dto); return success(true); } From 505d369e806438ef11a019d7cfcfa5a3a895579c Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Fri, 26 Jul 2024 14:10:24 +0800 Subject: [PATCH 38/42] =?UTF-8?q?update=20-=20=E6=B7=BB=E5=8A=A0=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handle/CustomWorkflowEngineExceptionHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java index 80ef948ed..5a95b335f 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java @@ -28,7 +28,9 @@ public class CustomWorkflowEngineExceptionHandler implements AsyncRunnableExecut // } // } log.warn("Async Runnable Execution Exception: {}", rootCause.getMessage(), e); - return WorkflowEngineException.class.isAssignableFrom(rootCause.getClass()); + boolean assignableFrom = WorkflowEngineException.class.isAssignableFrom(rootCause.getClass()); + log.info("CustomWorkflowEngineExceptionHandler result : {}" , assignableFrom); + return assignableFrom; } private Throwable getRootCause(Throwable throwable) { From 78151d27af5f986a6d47edaffe31827cb5bd8093 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Fri, 26 Jul 2024 14:36:59 +0800 Subject: [PATCH 39/42] =?UTF-8?q?remove=20-=20=E7=A7=BB=E9=99=A4=20Workflo?= =?UTF-8?q?wEngineException=20handler=20=E5=A4=84=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/workflow/core/conf/FlowableConfiguration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 2a0c0c3c3..ee15217a7 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 @@ -15,7 +15,6 @@ import cn.axzo.workflow.core.engine.job.AsyncRejectTaskJobHandler; import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler; import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncJobLogClearTraceExceptionHandler; import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncRunnableExceptionExceptionHandler; -import cn.axzo.workflow.core.engine.job.exception.handle.CustomWorkflowEngineExceptionHandler; import cn.axzo.workflow.core.engine.persistence.CustomMybatisHistoricProcessInstanceDataManager; import cn.axzo.workflow.core.service.BpmnProcessActivityService; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; @@ -36,8 +35,8 @@ 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 org.springframework.lang.Nullable; import java.time.Duration; import java.util.List; @@ -99,7 +98,8 @@ public class FlowableConfiguration { configuration.setEnableVerboseExecutionTreeLogging(enableVerboseExecutionTreeLogging); configuration.setCustomAsyncRunnableExecutionExceptionHandlers(Lists.newArrayList( new CustomAsyncJobLogClearTraceExceptionHandler(), - new CustomWorkflowEngineExceptionHandler(), + // 移除掉该异常处理器,避免因为 job 抛出 WorkflowEngineException 时,不会重试的问题 +// new CustomWorkflowEngineExceptionHandler(), new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( From 24c06f3f8c8c9d163ac0db8ddb9cd1a03ff8a455 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 29 Jul 2024 11:56:20 +0800 Subject: [PATCH 40/42] =?UTF-8?q?REQ-2596-job=E6=89=A7=E8=A1=8C=E5=8A=A0?= =?UTF-8?q?=E9=94=81=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=87=8D=E8=AF=95=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E8=8E=B7=E5=8F=96=E9=94=81=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=EF=BC=8C=E6=89=A7=E8=A1=8C=E5=88=A0=E9=99=A4=E8=BF=87=E6=9C=9F?= =?UTF-8?q?=E9=94=81=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractExecuteWithLockJobHandler.java | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) 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 index 406dc44f0..053136453 100644 --- 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 @@ -3,6 +3,7 @@ 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 com.alibaba.nacos.common.utils.ThreadUtils; import org.apache.commons.lang.StringUtils; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.job.service.JobHandler; @@ -12,34 +13,56 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; +import java.util.concurrent.TimeUnit; + 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; + if (acquireLock(processInstanceId, jobId)) { + log.info("job acquire lock success,processInstanceId:{},jobId:{}", processInstanceId, jobId); + executeInternal(job, configuration, variableScope, commandContext); + } } finally { - extAxPropertyService.delete(processInstanceId, jobId); + releaseLock(processInstanceId, jobId); } } + private boolean acquireLock(String processInstanceId, String jobId) { + int attemptNo = 3, acquireCount = 0; + ExtAxPropertyService extAxPropertyService = SpringContextUtils.getBean(ExtAxPropertyService.class); + do { + try { + ExtAxProperty extAxProperty = new ExtAxProperty(); + extAxProperty.setName(processInstanceId); + extAxProperty.setValue(jobId); + extAxPropertyService.add(extAxProperty); + return true; + } catch (DuplicateKeyException e) { + //删除15分钟前的数据,相当于超时时间是15分钟 + extAxPropertyService.deleteByNameWithDuration(processInstanceId, 15L, TimeUnit.MINUTES); + //睡眠2秒 + ThreadUtils.sleep(2 * 1000); + acquireCount++; + log.error("acquireLock error,processInstanceId:{},jobId:{},acquireCount:{}", processInstanceId, jobId, acquireCount); + } + } while (acquireCount < attemptNo); + return false; + } + + private void releaseLock(String processInstanceId, String jobId) { + ExtAxPropertyService extAxPropertyService = SpringContextUtils.getBean(ExtAxPropertyService.class); + extAxPropertyService.delete(processInstanceId, jobId); + } + abstract void executeInternal(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext); } From 6fc64d7c6969d674ff3426914f1c28fa9792361d Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 30 Jul 2024 10:07:59 +0800 Subject: [PATCH 41/42] =?UTF-8?q?REQ-2596-=E8=8E=B7=E5=8F=96=E9=94=81?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5,=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/job/AbstractExecuteWithLockJobHandler.java | 4 ++++ 1 file changed, 4 insertions(+) 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 index 053136453..aee47ba0d 100644 --- 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 @@ -1,5 +1,6 @@ package cn.axzo.workflow.core.engine.job; +import cn.axzo.framework.domain.ServiceException; import cn.axzo.workflow.core.common.utils.SpringContextUtils; import cn.axzo.workflow.core.repository.entity.ExtAxProperty; import cn.axzo.workflow.core.service.ExtAxPropertyService; @@ -31,6 +32,9 @@ public abstract class AbstractExecuteWithLockJobHandler extends AbstractJobHandl if (acquireLock(processInstanceId, jobId)) { log.info("job acquire lock success,processInstanceId:{},jobId:{}", processInstanceId, jobId); executeInternal(job, configuration, variableScope, commandContext); + } else { + log.error("get lock failed,processInstanceId:{},jobId:{}", processInstanceId, jobId); + throw new ServiceException("acquire lock failed"); } } finally { releaseLock(processInstanceId, jobId); From e37ae47d6dab5148d0adcd548856aa1d5f623115 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 30 Jul 2024 10:42:21 +0800 Subject: [PATCH 42/42] =?UTF-8?q?REQ-2596-=E5=88=A0=E9=99=A4=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E9=94=81=E6=96=B0=E5=BC=80=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/service/impl/ExtAxPropertyServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) 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 77d677909..3bd26e4a7 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 @@ -67,6 +67,8 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService { return mapper.deleteByMap(deleteMap); } + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) 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);