diff --git a/README.md b/README.md index 7bc856947..7cc8efc94 100644 --- a/README.md +++ b/README.md @@ -342,9 +342,9 @@ API: API: -**(添加评论)**: cn.axzo.workflow.core.service.BpmnTaskService.commentTask +**(添加评论)**: cn.axzo.workflow.core.service.BpmnProcessTaskService.commentTask -**(添加附件)**: cn.axzo.workflow.core.service.BpmnTaskService.attachmentTask +**(添加附件)**: cn.axzo.workflow.core.service.BpmnProcessTaskService.attachmentTask 操作的库表: diff --git a/pom.xml b/pom.xml index 309348023..eeae2cd55 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,11 @@ workflow-engine-server ${project.version} + + cn.axzo.maokai + maokai-api + ${axzo-dependencies.version} + mysql mysql-connector-java diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessActivityApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessActivityApi.java new file mode 100644 index 000000000..a5a9bdd01 --- /dev/null +++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessActivityApi.java @@ -0,0 +1,25 @@ +package cn.axzo.workflow.client.feign.bpmn; + +import cn.azxo.framework.common.model.CommonResponse; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.validation.constraints.NotBlank; + +/** + * 流程活动的 API + * + * @author wangli + * @since 2023/11/17 16:28 + */ +@FeignClient(name = "workflow-engine", url = "${axzo.service.workflow-engine:http://workflow-engine:8080}") +public interface ProcessActivityApi { + + /** + * 业务节点唤醒 + */ + @GetMapping("/api/process/activity/trigger") + CommonResponse trigger(@NotBlank(message = "活动 ID 不能为空") @RequestParam String processActivityId); + +} diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonMetaInfo.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonMetaInfo.java index cf963c9e4..231de12c8 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonMetaInfo.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/BpmnButtonMetaInfo.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.experimental.Accessors; /** - * TODO + * 按钮元数据 * * @author wangli * @since 2023/11/14 23:53 diff --git a/workflow-engine-core/pom.xml b/workflow-engine-core/pom.xml index 49b1645c3..1f866e9ef 100644 --- a/workflow-engine-core/pom.xml +++ b/workflow-engine-core/pom.xml @@ -84,5 +84,9 @@ cn.axzo.workflow workflow-engine-common + + cn.axzo.maokai + maokai-api + 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 f094dca69..a062b8b2e 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 @@ -389,7 +389,7 @@ public final class BpmnJsonConverterUtil { mainProcess.addFlowElement(flowElement); if (Lists.newArrayList(preNodeIds).isEmpty()) { - // first time entrance, nothing to do. + // first time entrance, do nothing. } else if (Lists.newArrayList(preNodeIds).size() == 1 && !NODE_CONDITION.equals(bpmnJsonNode.getType())) { mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess)); } else { diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AbstractBpmnTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AbstractBpmnTaskAssigneeSelector.java new file mode 100644 index 000000000..19c693cd3 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AbstractBpmnTaskAssigneeSelector.java @@ -0,0 +1,64 @@ +package cn.axzo.workflow.core.deletage; + +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.maokai.api.client.OrganizationalNodeUserApi; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; +import cn.axzo.maokai.api.vo.response.FlowTaskAssigner; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.http.HttpStatus; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.UserTask; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; + +/** + * 抽象的流程任务审批人选择器 + * + * @author wangli + * @since 2023/11/17 11:35 + */ +@Slf4j +public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssigneeSelector { + @Resource + private OrganizationalNodeUserApi nodeUserApi; + + protected abstract FlowTaskAssignerReq buildQuery(UserTask userTask); + + @Override + public final List select(UserTask userTask) { + FlowTaskAssignerReq query = buildQuery(userTask); + List flowTaskAssigners = null; + try { + flowTaskAssigners = parseApiResult(() -> + nodeUserApi.listFlowTaskAssigner(query), "根据配置查询审批候选人", query); + } catch (Exception e) { + throw new WorkflowEngineException("调用 API 查询审批候选人出现异常: " + e.getMessage()); + } + + if (CollectionUtils.isEmpty(flowTaskAssigners)) { + return Collections.emptyList(); + } + return BeanUtil.copyToList(flowTaskAssigners, BpmnTaskDelegateAssigner.class); + } + + private T parseApiResult(Supplier> supplier, String operatorDesc, Object... param) { + log.info(operatorDesc + "-Param: " + JSONUtil.toJsonStr(param)); + ApiResult result = supplier.get(); + log.info(operatorDesc + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throw new WorkflowEngineException(result.getMsg()); + } + return result.getData(); + } + +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AdminTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AdminTaskAssigneeSelector.java index 5cc8b2a44..988eb8816 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AdminTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/AdminTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 基于"转交给管理员"查询审批人 * @@ -14,14 +12,16 @@ import java.util.List; * @since 2023/11/16 11:44 */ @Component -public class AdminTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class AdminTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { + + @Override public boolean support(String param) { return ApproverEmptyHandleTypeEnum.transferToAdmin.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/CheckDueDateDelegate.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/CheckDueDateDelegate.java deleted file mode 100644 index a79678b2e..000000000 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/CheckDueDateDelegate.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.axzo.workflow.core.deletage; - -import lombok.extern.slf4j.Slf4j; -import org.flowable.engine.delegate.DelegateExecution; -import org.flowable.engine.delegate.JavaDelegate; -import org.springframework.stereotype.Component; - -/** - * TODO - * - * @author wangli - * @since 2023/7/31 20:20 - */ -@Component -@Slf4j -public class CheckDueDateDelegate implements JavaDelegate { - @Override - public void execute(DelegateExecution execution) { - log.info("cycle exec..."); - } -} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/IdentityTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/IdentityTaskAssigneeSelector.java index 2e7e93474..764616def 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/IdentityTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/IdentityTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 基于"身份"查询审批人 * @@ -14,14 +12,15 @@ import java.util.List; * @since 2023/11/16 11:38 */ @Component -public class IdentityTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class IdentityTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { @Override public boolean support(String param) { return ApproverSpecifyEnum.identity.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderRecursionTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderRecursionTaskAssigneeSelector.java index bb62c9185..9db2db7f3 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderRecursionTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderRecursionTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 给予"发起人多级主管"查询审批人 * @@ -14,14 +12,15 @@ import java.util.List; * @since 2023/11/16 11:42 */ @Component -public class InitiatorLeaderRecursionTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class InitiatorLeaderRecursionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { @Override public boolean support(String param) { return ApproverSpecifyEnum.initiatorLeaderRecursion.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderTaskAssigneeSelector.java index d0e0cc036..8752c4bee 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/InitiatorLeaderTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 基于"发起人多级主管"查询审批人 * @@ -14,14 +12,14 @@ import java.util.List; * @since 2023/11/16 11:41 */ @Component -public class InitiatorLeaderTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class InitiatorLeaderTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { @Override public boolean support(String param) { return ApproverSpecifyEnum.initiatorLeader.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/MockTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/MockTaskAssigneeSelector.java new file mode 100644 index 000000000..59787b6ec --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/MockTaskAssigneeSelector.java @@ -0,0 +1,27 @@ +package cn.axzo.workflow.core.deletage; + +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import org.flowable.bpmn.model.UserTask; + +import java.util.ArrayList; +import java.util.List; + +/** + * 开发阶段的模拟审批人查询 + * + * @author wangli + * @since 2023/11/17 13:40 + */ +public class MockTaskAssigneeSelector implements BpmnTaskAssigneeSelector { + + @Override + public boolean support(String param) { + return true; + } + + @Override + public List select(UserTask userTask) { + List users = new ArrayList<>(); + return users; + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/PositionTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/PositionTaskAssigneeSelector.java index 9e2e80339..61479d566 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/PositionTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/PositionTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 基于"岗位"查询审批人 * @@ -14,14 +12,14 @@ import java.util.List; * @since 2023/11/16 11:35 */ @Component -public class PositionTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class PositionTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { @Override public boolean support(String param) { return ApproverSpecifyEnum.position.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/RoleTaskAssigneeSelector.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/RoleTaskAssigneeSelector.java index 475e181ea..61497a846 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/RoleTaskAssigneeSelector.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/deletage/RoleTaskAssigneeSelector.java @@ -1,12 +1,10 @@ package cn.axzo.workflow.core.deletage; +import cn.axzo.maokai.api.vo.request.FlowTaskAssignerReq; import cn.axzo.workflow.common.enums.ApproverSpecifyEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import org.flowable.bpmn.model.UserTask; import org.springframework.stereotype.Component; -import java.util.List; - /** * 基于"角色"查询审批人 * @@ -14,14 +12,14 @@ import java.util.List; * @since 2023/11/16 11:37 */ @Component -public class RoleTaskAssigneeSelector implements BpmnTaskAssigneeSelector { +public class RoleTaskAssigneeSelector extends AbstractBpmnTaskAssigneeSelector { @Override public boolean support(String param) { return ApproverSpecifyEnum.role.getType().equals(param); } @Override - public List select(UserTask userTask) { + protected FlowTaskAssignerReq buildQuery(UserTask userTask) { return null; } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomUserTaskActivityBehavior.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomUserTaskActivityBehavior.java index cee9910df..1421552bd 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomUserTaskActivityBehavior.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/behavior/CustomUserTaskActivityBehavior.java @@ -32,7 +32,7 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.util.List; /** - * TODO + * 自定义的用户审批任务节点行为处理器 * * @author wangli * @since 2023/7/29 01:11 diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineActivityEventListener.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineActivityEventListener.java index fe26b5e44..e1089df46 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineActivityEventListener.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/listener/EngineActivityEventListener.java @@ -4,9 +4,17 @@ import cn.axzo.framework.jackson.utility.JSON; import cn.axzo.workflow.core.listener.BpmnActivityEventListener; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; -import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener; import org.flowable.common.engine.api.delegate.event.FlowableEvent; import org.flowable.common.engine.api.delegate.event.FlowableEventType; +import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; +import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent; +import org.flowable.engine.delegate.event.FlowableActivityEvent; +import org.flowable.engine.delegate.event.FlowableErrorEvent; +import org.flowable.engine.delegate.event.FlowableMessageEvent; +import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCancelledEvent; +import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCompletedEvent; +import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityEvent; +import org.flowable.engine.delegate.event.FlowableSignalEvent; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Component; @@ -15,10 +23,20 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_CANCELLED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPENSATE; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_COMPLETED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_ERROR_RECEIVED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_CANCELLED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_RECEIVED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_MESSAGE_WAITING; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_SIGNALED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_SIGNAL_WAITING; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.ACTIVITY_STARTED; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_CANCELLED; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED; import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION; +import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventType.MULTI_INSTANCE_ACTIVITY_STARTED; /** * 活动节点完成事件 @@ -28,7 +46,7 @@ import static org.flowable.common.engine.api.delegate.event.FlowableEngineEventT */ @Slf4j @Component -public class EngineActivityEventListener extends AbstractFlowableEventListener { +public class EngineActivityEventListener extends AbstractFlowableEngineEventListener { @Resource ObjectProvider> activityListeners; @@ -37,12 +55,97 @@ public class EngineActivityEventListener extends AbstractFlowableEventListener { public Collection getTypes() { return Lists.newArrayList(ACTIVITY_STARTED, ACTIVITY_COMPLETED, + ACTIVITY_CANCELLED, + MULTI_INSTANCE_ACTIVITY_STARTED, MULTI_INSTANCE_ACTIVITY_COMPLETED, - MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION); + MULTI_INSTANCE_ACTIVITY_COMPLETED_WITH_CONDITION, + MULTI_INSTANCE_ACTIVITY_CANCELLED, + ACTIVITY_SIGNAL_WAITING, + ACTIVITY_SIGNALED, + ACTIVITY_COMPENSATE, + ACTIVITY_MESSAGE_WAITING, + ACTIVITY_MESSAGE_RECEIVED, + ACTIVITY_MESSAGE_CANCELLED, + ACTIVITY_ERROR_RECEIVED); + } + + @Override + protected void activityStarted(FlowableActivityEvent event) { + // TODO 业务节点通过发送这个事件给业务, 必须要传输 activity instance id, 业务则通过这个 id 来推动工作流继续流转 + super.activityStarted(event); + } + + @Override + protected void activityCompleted(FlowableActivityEvent event) { + // TODO 以前老的 TaskListener 事件实际上都是不标准的, 因为一个任务节点可能有多个人审批, 而多人审批就会有会签/或签模型, + // 让业务监听任务的完成状态本身就有问题, 统一替换成 Activity 相关的事件 + super.activityCompleted(event); + } + + @Override + protected void activityCancelled(FlowableActivityCancelledEvent event) { + super.activityCancelled(event); + } + + @Override + protected void multiInstanceActivityStarted(FlowableMultiInstanceActivityEvent event) { + super.multiInstanceActivityStarted(event); + } + + @Override + protected void multiInstanceActivityCompleted(FlowableMultiInstanceActivityCompletedEvent event) { + super.multiInstanceActivityCompleted(event); + } + + @Override + protected void multiInstanceActivityCompletedWithCondition(FlowableMultiInstanceActivityCompletedEvent event) { + super.multiInstanceActivityCompletedWithCondition(event); + } + + @Override + protected void multiInstanceActivityCancelled(FlowableMultiInstanceActivityCancelledEvent event) { + super.multiInstanceActivityCancelled(event); + } + + @Override + protected void activitySignalWaiting(FlowableSignalEvent event) { + super.activitySignalWaiting(event); + } + + @Override + protected void activitySignaled(FlowableSignalEvent event) { + super.activitySignaled(event); + } + + @Override + protected void activityCompensate(FlowableActivityEvent event) { + super.activityCompensate(event); + } + + + @Override + protected void activityMessageWaiting(FlowableMessageEvent event) { + super.activityMessageWaiting(event); + } + + @Override + protected void activityMessageReceived(FlowableMessageEvent event) { + super.activityMessageReceived(event); + } + + @Override + protected void activityMessageCancelled(FlowableMessageEvent event) { + super.activityMessageCancelled(event); + } + + @Override + protected void activityErrorReceived(FlowableErrorEvent event) { + super.activityErrorReceived(event); } @Override public void onEvent(FlowableEvent event) { + super.onEvent(event); getOrderedListeners().forEach(i -> i.onEvent(event)); } 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 d4faa709d..1376f9dc7 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 @@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector; import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO; import cn.axzo.workflow.core.deletage.BpmnTaskDelegate; +import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.Process; @@ -30,6 +31,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.BPM_ALLOW_SKIP_USER import static cn.axzo.workflow.common.constant.BpmnConstants.FLOW_SERVER_VERSION_121; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS; import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType; @@ -52,14 +54,15 @@ public class EngineExecutionStartListener implements ExecutionListener { private ObjectProvider bpmTaskDelegate; @Resource private List selectors; + @Resource + private ObjectProvider objectProvider; @Override public void notify(DelegateExecution execution) { log.info("execution Start: {}", JSON.toJSONString(execution)); String currentActivityId = execution.getCurrentActivityId(); String assigneeListVariableName = INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + currentActivityId; - List assigneeList = (List) execution.getVariable(assigneeListVariableName); - if (!CollectionUtils.isEmpty(assigneeList)) { + if (execution.hasVariable(assigneeListVariableName)) { return; } @@ -67,17 +70,19 @@ public class EngineExecutionStartListener implements ExecutionListener { UserTask userTask = (UserTask) mainProcess.getFlowElement(currentActivityId); // 从 version=1.2.1-SNAPSHOT 开始,才给 process 节点增加了 serverVersion 属性 - getProcessServerVersion(mainProcess).ifPresent(version -> { + + Optional processServerVersion = getProcessServerVersion(mainProcess); + if (processServerVersion.isPresent()) { Optional nodeType = getNodeType(userTask); - if (Objects.equals(FLOW_SERVER_VERSION_121, version) + if (Objects.equals(FLOW_SERVER_VERSION_121, processServerVersion.get()) && nodeType.isPresent() - && Objects.equals(NODE_TASK, nodeType.get())) { + && (Objects.equals(NODE_TASK, nodeType.get()) || Objects.equals(NODE_BUSINESS, nodeType.get()))) { getApprovalMethod(userTask).ifPresent(method -> { - List assigneeIdList = new ArrayList<>(); + switch (method) { case autoPassed: case autoRejection: - // nothing to do + // Do nothing // TODO 不要调用查询审批人的接口,只需要保证该节点在实际运行过程中,能自动通过和拒绝即可 // 通过的功能可以参考下面枢智的方法,拒绝还需研究(可以结合 task 相关的事件去处理) break; @@ -91,17 +96,23 @@ public class EngineExecutionStartListener implements ExecutionListener { // 查询审批候选人 emptyAssigneeHandle(assigners, userTask, execution); + List assigneeIdList = new ArrayList<>(); + for (BpmnTaskDelegateAssigner user : assigners) { + assigneeIdList.add(user.buildAssigneeId()); + } // UserTask 多实例, 该变量用于引擎 execution.setVariable(assigneeListVariableName, assigneeIdList); + execution.setVariableLocal(INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId, assigners); break; } }); } - }); + } else { + defaultCalcTaskAssigner(execution, userTask, currentActivityId, assigneeListVariableName); + } - defaultCalcTaskAssigner(execution, userTask, currentActivityId, assigneeListVariableName); } private void emptyAssigneeHandle(List assigners, UserTask userTask, @@ -137,11 +148,15 @@ public class EngineExecutionStartListener implements ExecutionListener { */ private List approverSelect(String type, UserTask userTask) { List assigners = new ArrayList<>(); - selectors.forEach(select -> { - if (select.support(type)) { - assigners.addAll(select.select(userTask)); - } - }); + if (Objects.nonNull(objectProvider.getIfAvailable())) { + objectProvider.ifAvailable(selector -> assigners.addAll(selector.select(userTask))); + } else { + selectors.forEach(select -> { + if (select.support(type)) { + assigners.addAll(select.select(userTask)); + } + }); + } return assigners; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessActivityService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessActivityService.java new file mode 100644 index 000000000..56d92d8b4 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessActivityService.java @@ -0,0 +1,17 @@ +package cn.axzo.workflow.core.service; + +/** + * 流程活动的 Service + * + * @author wangli + * @since 2023/11/17 16:37 + */ +public interface BpmnProcessActivityService { + + /** + * 唤醒业务节点 + * + * @param processActivityId 活动 ID + */ + void trigger(String processActivityId); +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnTaskService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java similarity index 82% rename from workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnTaskService.java rename to workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java index b0ab88ee4..51f95ceaa 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnTaskService.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java @@ -1,6 +1,11 @@ package cn.axzo.workflow.core.service; -import cn.axzo.workflow.common.model.request.bpmn.task.*; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO; @@ -11,7 +16,7 @@ import org.flowable.form.api.FormInfo; import java.util.List; -public interface BpmnTaskService { +public interface BpmnProcessTaskService { /** * 待审核列表 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 new file mode 100644 index 000000000..6a4094082 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessActivityServiceImpl.java @@ -0,0 +1,29 @@ +package cn.axzo.workflow.core.service.impl; + +import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.axzo.workflow.core.service.BpmnProcessActivityService; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.runtime.ActivityInstance; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Objects; + +@Service +@Slf4j +public class BpmnProcessActivityServiceImpl implements BpmnProcessActivityService { + + @Resource + private RuntimeService runtimeService; + + @Override + public void trigger(String processActivityId) { + ActivityInstance activityInstance = + runtimeService.createActivityInstanceQuery().activityInstanceId(processActivityId).singleResult(); + if (Objects.isNull(activityInstance)) { + throw new WorkflowEngineException(""); + } + runtimeService.trigger(activityInstance.getExecutionId()); + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java similarity index 90% rename from workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java rename to workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index d2d269f96..105619c3f 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -3,13 +3,27 @@ package cn.axzo.workflow.core.service.impl; import cn.axzo.framework.core.util.StringUtil; import cn.axzo.workflow.common.enums.BpmnCountersignType; import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum; -import cn.axzo.workflow.common.model.request.bpmn.task.*; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAssigneeDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; -import cn.axzo.workflow.common.model.response.bpmn.task.*; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.id.TimeBasedIdGenerator; -import cn.axzo.workflow.core.service.BpmnTaskService; -import cn.axzo.workflow.core.service.converter.*; +import cn.axzo.workflow.core.service.BpmnProcessTaskService; +import cn.axzo.workflow.core.service.converter.BpmnHistoricCommentConverter; +import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskDonePageItemConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskTodoPageItemConverter; import cn.hutool.core.collection.CollUtil; import cn.hutool.json.JSONUtil; import com.google.common.collect.Lists; @@ -19,7 +33,11 @@ import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.UserTask; import org.flowable.common.engine.impl.identity.Authentication; -import org.flowable.engine.*; +import org.flowable.engine.HistoryService; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; @@ -41,13 +59,43 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.workflow.common.constant.BpmnConstants.*; -import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.*; -import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.*; +import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ENDS_AUTOMATICALLY; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; +import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_ORIGIN_ASSIGNER; +import static cn.axzo.workflow.common.constant.BpmnConstants.COUNTERSIGN_REMAIN_ASSIGNER_LIST; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_ID; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_NAME; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_SPECIFY_NEXT_APPROVER; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT; +import static cn.axzo.workflow.common.constant.BpmnConstants.MULTI_INSTANCE_LOOP_COUNTER; +import static cn.axzo.workflow.common.constant.BpmnConstants.NUMBER_OF_INSTANCES; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.CANCELLED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.valueOfStatus; +import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.PROCESS_INSTANCE_ID_NOT_EXISTS; +import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.PROCESS_INSTANCE_NOT_EXISTS; +import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_APOSTILLE_NOT_SUPPORT; +import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF; +import static cn.axzo.workflow.core.common.enums.BpmnErrorCode.TASK_COMPLETE_FAIL_NOT_EXISTS; import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet; import static cn.axzo.workflow.core.common.utils.BpmnNativeQueryUtil.countSql; import static cn.axzo.workflow.core.common.utils.BpmnNativeQueryUtil.sqlConnectors; @@ -55,7 +103,7 @@ import static org.flowable.engine.impl.persistence.entity.CommentEntity.TYPE_COM @Service @Slf4j -public class BpmnTaskServiceImpl implements BpmnTaskService { +public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { @Resource private TaskService taskService; @@ -573,8 +621,7 @@ public class BpmnTaskServiceImpl implements BpmnTaskService { * @param taskId 任务ID */ private Task checkTask(String tenantId, String assignee, String taskId) { - - Task task = getTask(taskId, assignee, tenantId); + Task task = getTask(taskId, null, null); if (Objects.nonNull(task) && !Objects.equals(assignee, task.getAssignee())) { throw new WorkflowEngineException(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/FlowNodeForecastService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/FlowNodeForecastService.java index 9039081fc..2d77db5b9 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/FlowNodeForecastService.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/FlowNodeForecastService.java @@ -110,7 +110,7 @@ public class FlowNodeForecastService implements InitializingBean { public List performProcessForecasting(@Nullable String processInstanceId, @Nullable ProcessInstance instance) { if (Objects.nonNull(instance)) { - // nothing to do + // Do nothing } else if (!StringUtils.hasLength(processInstanceId)) { throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS); } else { diff --git a/workflow-engine-core/src/main/resources/test.bpmn20.xml b/workflow-engine-core/src/main/resources/test.bpmn20.xml deleted file mode 100644 index b8e5d06b8..000000000 --- a/workflow-engine-core/src/main/resources/test.bpmn20.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/WorkflowEnginApplication.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/WorkflowEnginApplication.java index a5fb0d160..131f005b9 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/WorkflowEnginApplication.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/WorkflowEnginApplication.java @@ -9,7 +9,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @MapperScan({"cn.axzo.workflow.core.**.mapper"}) -@ComponentScan({"cn.axzo.workflow"}) +@ComponentScan({"cn.axzo.workflow", "cn.axzo.maokai"}) @SpringBootApplication(exclude = RabbitAutoConfiguration.class) @EnableTransactionManagement public class WorkflowEnginApplication { diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/conf/WorkflowEngineConfiguration.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/conf/WorkflowEngineConfiguration.java new file mode 100644 index 000000000..848f00a99 --- /dev/null +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/conf/WorkflowEngineConfiguration.java @@ -0,0 +1,22 @@ +package cn.axzo.workflow.server.conf; + +import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Workflow Engine Application Global Configuration + * + * @author wangli + * @since 2023/11/17 14:27 + */ +@Configuration(proxyBeanMethods = false) +public class WorkflowEngineConfiguration { + + @Bean + @ConditionalOnProperty(prefix = "workflow", name = "mock", havingValue = "true") + public MockTaskAssigneeSelector mockTaskAssigneeSelector() { + return new MockTaskAssigneeSelector(); + } +} diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessActivityController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessActivityController.java new file mode 100644 index 000000000..e48a4b835 --- /dev/null +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessActivityController.java @@ -0,0 +1,37 @@ +package cn.axzo.workflow.server.controller.web.bpmn; + +import cn.axzo.workflow.client.feign.bpmn.ProcessActivityApi; +import cn.axzo.workflow.core.service.BpmnProcessActivityService; +import cn.azxo.framework.common.model.CommonResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.constraints.NotBlank; + +/** + * 流程活动相关控制器 + * + * @author wangli + * @since 2023/11/17 16:33 + */ +@Slf4j +@RequestMapping({"/web/v1/api/process/activity", "/api/process/activity"}) +@RestController +@Validated +public class BpmnProcessActivityController implements ProcessActivityApi { + + @Resource + private BpmnProcessActivityService bpmnProcessActivityService; + + @GetMapping("/trigger") + @Override + public CommonResponse trigger(@NotBlank(message = "活动 ID 不能为空") @RequestParam String processActivityId) { + bpmnProcessActivityService.trigger(processActivityId); + return CommonResponse.success(true); + } +} diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java similarity index 85% rename from workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnTaskController.java rename to workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java index 03881f3a4..8da3a29b8 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnTaskController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java @@ -14,7 +14,7 @@ import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO; import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO; import cn.axzo.workflow.common.valid.group.ValidGroup; -import cn.axzo.workflow.core.service.BpmnTaskService; +import cn.axzo.workflow.core.service.BpmnProcessTaskService; import cn.azxo.framework.common.model.CommonResponse; import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; @@ -39,10 +39,10 @@ import static cn.azxo.framework.common.model.CommonResponse.success; @RequestMapping({"/web/v1/api/process/task", "/api/process/task"}) @RestController @Validated -public class BpmnTaskController implements ProcessTaskApi { +public class BpmnProcessTaskController implements ProcessTaskApi { @Resource - private BpmnTaskService bpmnTaskService; + private BpmnProcessTaskService bpmnProcessTaskService; /** @@ -52,7 +52,7 @@ public class BpmnTaskController implements ProcessTaskApi { @Override public CommonResponse> getTodoTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) { log.info("待审核列表 getTodoTaskPage===>>>参数:{}", dto); - return success(bpmnTaskService.getTodoTaskPage(dto)); + return success(bpmnProcessTaskService.getTodoTaskPage(dto)); } /** @@ -62,7 +62,7 @@ public class BpmnTaskController implements ProcessTaskApi { @Override public CommonResponse> getDoneTaskPage(@Validated @RequestBody BpmnTaskPageSearchDTO dto) { log.info("已完成的审批列表 getDoneTaskPage===>>>参数:{}", dto); - return success(bpmnTaskService.getDoneTaskPage(dto)); + return success(bpmnProcessTaskService.getDoneTaskPage(dto)); } @@ -73,7 +73,7 @@ public class BpmnTaskController implements ProcessTaskApi { @Override public CommonResponse approveTask(@Validated(ValidGroup.Insert.class) @RequestBody BpmnTaskAuditDTO dto) { log.info("同意 approveTask===>>>参数:{}", dto); - bpmnTaskService.approveTask(dto); + bpmnProcessTaskService.approveTask(dto); return success(true); } @@ -84,7 +84,7 @@ public class BpmnTaskController implements ProcessTaskApi { @Override public CommonResponse rejectTask(@Validated(ValidGroup.Update.class) @RequestBody BpmnTaskAuditDTO dto) { log.info("拒绝 rejectTask===>>>参数:{}", dto); - bpmnTaskService.rejectTask(dto); + bpmnProcessTaskService.rejectTask(dto); return success(true); } @@ -95,7 +95,7 @@ public class BpmnTaskController implements ProcessTaskApi { @PutMapping("/assignee") @Override public CommonResponse assigneeTask(@Validated @RequestBody BpmnTaskAssigneeDTO dto) { - bpmnTaskService.assigneeTask(dto); + bpmnProcessTaskService.assigneeTask(dto); return success(true); } @@ -104,7 +104,7 @@ public class BpmnTaskController implements ProcessTaskApi { */ @Override public CommonResponse commentTask(BpmnTaskCommentDTO commentDTO) { - bpmnTaskService.commentTask(commentDTO); + bpmnProcessTaskService.commentTask(commentDTO); return success(true); } @@ -115,7 +115,7 @@ public class BpmnTaskController implements ProcessTaskApi { @Override @PutMapping("/countersign") public CommonResponse countersignTask(BpmnTaskCountersignDTO countersignDTO) { - bpmnTaskService.countersignTask(countersignDTO); + bpmnProcessTaskService.countersignTask(countersignDTO); return success(true); } @@ -151,7 +151,7 @@ public class BpmnTaskController implements ProcessTaskApi { @NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId) { log.info("获取历史已审批的列表详情 getTaskListFlatByProcessInstanceId===>>>参数:{}", processInstanceId); - return success(bpmnTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId)); + return success(bpmnProcessTaskService.getHistoricTaskListByProcessInstanceId(processInstanceId, tenantId)); } /** @@ -165,7 +165,7 @@ public class BpmnTaskController implements ProcessTaskApi { @NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable @RequestParam(required = false) String tenantId) { log.info("获取历史已审批的列表详情 getTaskListGroupByProcessInstanceId===>>>参数:{}", processInstanceId); - return success(bpmnTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId)); + return success(bpmnProcessTaskService.getHistoricTaskListGroupByProcessInstanceId(processInstanceId, tenantId)); } /** @@ -177,18 +177,18 @@ public class BpmnTaskController implements ProcessTaskApi { @NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId) { log.info(" 获取实例正在审核的人列表 getActiveTasksByProcessInstanceId===>>>参数:{}", processInstanceId); - return success(bpmnTaskService.getActiveTasksByProcessInstanceId(processInstanceId, tenantId)); + return success(bpmnProcessTaskService.getActiveTasksByProcessInstanceId(processInstanceId, tenantId)); } @GetMapping("/form") public CommonResponse getTaskForm(@NotBlank(message = "任务 ID 不能为空") @RequestParam String taskId, @NotBlank(message = "租户不能为空") @RequestParam String tenantId) { - return success(bpmnTaskService.getTaskFormModel(taskId, tenantId)); + return success(bpmnProcessTaskService.getTaskFormModel(taskId, tenantId)); } @PostMapping("/attachment/add") public CommonResponse addAttachment(@Validated @RequestBody BpmnTaskAttachmentDTO dto) { - bpmnTaskService.attachmentTask(dto); + bpmnProcessTaskService.attachmentTask(dto); return success(); } diff --git a/workflow-engine-server/src/main/resources/test-all.json b/workflow-engine-server/src/main/resources/test-all.json index 886318301..e00e88eb2 100644 --- a/workflow-engine-server/src/main/resources/test-all.json +++ b/workflow-engine-server/src/main/resources/test-all.json @@ -606,7 +606,7 @@ ], "isMultiTask": "true", "multiMode": "AND", - "approverEmptyHandleType": "autoPassed", + "approverEmptyHandleType": "transferToAdmin", "fieldPermission": null, "buttonPermission": { "initiator": [ diff --git a/workflow-engine-server/src/main/resources/test.bpmn20.xml b/workflow-engine-server/src/main/resources/test.bpmn20.xml index 8a2c5a76b..d6e4da2b9 100644 --- a/workflow-engine-server/src/main/resources/test.bpmn20.xml +++ b/workflow-engine-server/src/main/resources/test.bpmn20.xml @@ -1,13 +1,14 @@ - - - remark + targetNamespace="customCategory"> + + 极引非东活已运王点越组油门展总想立。年深江亲联热制者条济它部即月。号线信平和者京两马何标这。 + @@ -79,10 +80,9 @@ - - + @@ -92,7 +92,7 @@ - + @@ -138,18 +138,20 @@ - + ${nrOfInstances == nrOfCompletedInstances} - + - - + default="SequenceFlowId_e4c8e59f118b4dc1847a992033836746"> + + + + @@ -221,8 +223,11 @@ - - + + + + + @@ -253,7 +258,7 @@ ${nrOfInstances == nrOfCompletedInstances} - + ${nrOfInstances == nrOfCompletedInstances} - - + + @@ -285,120 +290,122 @@ - - + + - - - + + - + - + - + - + - + - + - + - + - + - + - + - - - - - + + + + + - - - + + + + + - - - - - - - - - - - + - - - - - + + + + + - - - - - + + + - - - + + + + + - - - - - + + + - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + +