From 46c125b0305aeb27aec326e664f7d67ffc2fc9fe Mon Sep 17 00:00:00 2001 From: Lesan <1960681385@qq.com> Date: Mon, 6 Jan 2025 17:24:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Simple=E8=AE=BE=E8=AE=A1=E5=99=A8-?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/definition/BpmListenerMapType.java | 31 ++++++++ .../vo/model/simple/BpmSimpleModelNodeVO.java | 36 +++++++++ .../flowable/core/util/SimpleModelUtils.java | 18 +++++ .../task/listener/BpmUserTaskListener.java | 76 +++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerMapType.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerMapType.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerMapType.java new file mode 100644 index 0000000000..4afd9ea3c3 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerMapType.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.bpm.enums.definition; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * BPM 任务监听器键值对类型 + * + * @author Lesan + */ +@Getter +@AllArgsConstructor +public enum BpmListenerMapType implements IntArrayValuable { + + FIXED_VALUE(1, "固定值"), + FROM_FORM(2, "表单"); + + private final Integer type; + private final String name; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmListenerMapType::getType).toArray(); + + @Override + public int[] array() { + return ARRAYS; + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java index 6a4ec2c263..45c5db3a00 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java @@ -96,6 +96,42 @@ public class BpmSimpleModelNodeVO { */ private AssignEmptyHandler assignEmptyHandler; + /** + * 创建任务监听器 + */ + private ListenerHandler createTaskListener; + + @Schema(description = "任务监听器") + @Data + public static class ListenerHandler { + + @Schema(description = "是否开启任务监听器", example = "false") + private Boolean enable; + + @Schema(description = "请求路径", example = "http://xxxxx") + private String path; + + @Schema(description = "请求头", example = "[]") + private List header; + + @Schema(description = "请求体", example = "[]") + private List body; + + @Schema(description = "任务监听器键值对") + @Data + public static class ListenerMap { + + @Schema(description = "键", example = "xxx") + private String key; + + @Schema(description = "值类型", example = "1") + private Integer type; + + @Schema(description = "值", example = "xxx") + private String value; + } + } + @Schema(description = "审批节点拒绝处理策略") @Data public static class RejectHandler { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java index f4fd8c6d9e..2f1d966f6b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.*; +import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups; @@ -15,11 +16,14 @@ import org.flowable.bpmn.BpmnAutoLayout; import org.flowable.bpmn.constants.BpmnXMLConstants; import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.*; +import org.flowable.engine.delegate.TaskListener; import java.util.*; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.*; +import static cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener.DELEGATE_EXPRESSION; +import static cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener.EXTENSION_SUFFIX; import static java.util.Arrays.asList; /** @@ -420,6 +424,20 @@ public class SimpleModelUtils { if (node.getTimeoutHandler() != null && node.getTimeoutHandler().getEnable()) { userTask.setDueDate(node.getTimeoutHandler().getTimeDuration()); } + // 设置监听器 + List flowableListeners = new ArrayList<>(3); + if (node.getCreateTaskListener().getEnable()) { + FlowableListener flowableListener = new FlowableListener(); + flowableListener.setEvent(TaskListener.EVENTNAME_CREATE); + flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); + flowableListener.setImplementation(DELEGATE_EXPRESSION); + addExtensionElement(userTask, "create" + EXTENSION_SUFFIX, + JSONUtil.toJsonStr(node.getCreateTaskListener())); + flowableListeners.add(flowableListener); + } + if (!flowableListeners.isEmpty()) { + userTask.setTaskListeners(flowableListeners); + } return userTask; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java new file mode 100644 index 0000000000..18360241ef --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.bpm.service.task.listener; + +import cn.hutool.http.HttpRequest; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmListenerMapType; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; +import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.engine.delegate.TaskListener; +import org.flowable.engine.history.HistoricProcessInstance; +import org.flowable.task.service.delegate.DelegateTask; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.parseExtensionElement; + +/** + * BPM 用户任务通用监听器 + * + * @author Lesan + */ +@Component +@Slf4j +public class BpmUserTaskListener implements TaskListener { + + public static final String DELEGATE_EXPRESSION = "${bpmUserTaskListener}"; + + public static final String EXTENSION_SUFFIX = "TaskListenerMetaInfo"; + + @Resource + private BpmModelService modelService; + + @Resource + private BpmProcessInstanceService processInstanceService; + + @Override + public void notify(DelegateTask delegateTask) { + // 1. 获取所需基础信息 + HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(delegateTask.getProcessInstanceId()); + BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(delegateTask.getProcessDefinitionId()); + FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, delegateTask.getTaskDefinitionKey()); + BpmSimpleModelNodeVO.ListenerHandler listenerHandler = JSONUtil.toBean( + parseExtensionElement(userTaskElement, delegateTask.getEventName() + EXTENSION_SUFFIX), + BpmSimpleModelNodeVO.ListenerHandler.class); + Map processVariables = processInstance.getProcessVariables(); + // 2. 获取请求头和请求体 + HashMap headers = new HashMap<>(); + HashMap body = new HashMap<>(); + listenerHandler.getHeader().forEach(item -> { + if (item.getType().equals(BpmListenerMapType.FIXED_VALUE.getType())) { + headers.put(item.getKey(), item.getValue()); + } else if (item.getType().equals(BpmListenerMapType.FROM_FORM.getType())) { + headers.put(item.getKey(), processVariables.getOrDefault(item.getValue(), "").toString()); + } + }); + listenerHandler.getBody().forEach(item -> { + if (item.getType().equals(BpmListenerMapType.FIXED_VALUE.getType())) { + body.put(item.getKey(), item.getValue()); + } else if (item.getType().equals(BpmListenerMapType.FROM_FORM.getType())) { + body.put(item.getKey(), processVariables.getOrDefault(item.getValue(), "")); + } + }); + // 3. 异步发起请求 + HttpRequest.post(listenerHandler.getPath()) + .addHeaders(headers).form(body).executeAsync(); + // 4. 是否需要后续操作? + } + +} \ No newline at end of file