Commit 8a8dc67d72c95ad1bc0d411e319e48014fe3a5d7
1 parent
ca1d9e68
【功能新增】新增Simple 设计器触发器节点
Showing
11 changed files
with
354 additions
and
65 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmListenerParamTypeEnum.java renamed to yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmHttpRequestParamSettingType.java
| @@ -7,13 +7,13 @@ import lombok.Getter; | @@ -7,13 +7,13 @@ import lombok.Getter; | ||
| 7 | import java.util.Arrays; | 7 | import java.util.Arrays; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | - * BPM 任务监听器键值对类型 | 10 | + * BPM HTTP 请求参数设置类型。用于 Simple 设计器任务监听器和触发器配置。 |
| 11 | * | 11 | * |
| 12 | * @author Lesan | 12 | * @author Lesan |
| 13 | */ | 13 | */ |
| 14 | @Getter | 14 | @Getter |
| 15 | @AllArgsConstructor | 15 | @AllArgsConstructor |
| 16 | -public enum BpmListenerParamTypeEnum implements IntArrayValuable { | 16 | +public enum BpmHttpRequestParamSettingType implements IntArrayValuable { |
| 17 | 17 | ||
| 18 | FIXED_VALUE(1, "固定值"), | 18 | FIXED_VALUE(1, "固定值"), |
| 19 | FROM_FORM(2, "表单"); | 19 | FROM_FORM(2, "表单"); |
| @@ -21,7 +21,7 @@ public enum BpmListenerParamTypeEnum implements IntArrayValuable { | @@ -21,7 +21,7 @@ public enum BpmListenerParamTypeEnum implements IntArrayValuable { | ||
| 21 | private final Integer type; | 21 | private final Integer type; |
| 22 | private final String name; | 22 | private final String name; |
| 23 | 23 | ||
| 24 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmListenerParamTypeEnum::getType).toArray(); | 24 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmHttpRequestParamSettingType::getType).toArray(); |
| 25 | 25 | ||
| 26 | @Override | 26 | @Override |
| 27 | public int[] array() { | 27 | public int[] array() { |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java
| @@ -27,6 +27,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { | @@ -27,6 +27,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable { | ||
| 27 | COPY_NODE(12, "抄送人", "serviceTask"), | 27 | COPY_NODE(12, "抄送人", "serviceTask"), |
| 28 | 28 | ||
| 29 | DELAY_TIMER_NODE(14, "延迟器", "receiveTask"), | 29 | DELAY_TIMER_NODE(14, "延迟器", "receiveTask"), |
| 30 | + TRIGGER_NODE(15, "触发器", "serviceTask"), | ||
| 30 | 31 | ||
| 31 | // 50 ~ 条件分支 | 32 | // 50 ~ 条件分支 |
| 32 | CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式 | 33 | CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式 |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTriggerType.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.enums.definition; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.ArrayUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||
| 5 | +import lombok.AllArgsConstructor; | ||
| 6 | +import lombok.Getter; | ||
| 7 | + | ||
| 8 | +import java.util.Arrays; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * BPM Simple 触发器类型枚举 | ||
| 12 | + * | ||
| 13 | + * @author jason | ||
| 14 | + */ | ||
| 15 | +@Getter | ||
| 16 | +@AllArgsConstructor | ||
| 17 | +public enum BpmTriggerType implements IntArrayValuable { | ||
| 18 | + | ||
| 19 | + HTTP_REQUEST(1, "发起 HTTP 请求"); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 触发器执行动作类型 | ||
| 23 | + */ | ||
| 24 | + private final Integer type; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 触发器执行动作描述 | ||
| 28 | + */ | ||
| 29 | + private final String desc; | ||
| 30 | + | ||
| 31 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmTriggerType::getType).toArray(); | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public int[] array() { | ||
| 35 | + return ARRAYS; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public static BpmTriggerType typeOf(Integer type) { | ||
| 39 | + return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); | ||
| 40 | + } | ||
| 41 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
| @@ -9,6 +9,7 @@ import jakarta.validation.Valid; | @@ -9,6 +9,7 @@ import jakarta.validation.Valid; | ||
| 9 | import jakarta.validation.constraints.NotEmpty; | 9 | import jakarta.validation.constraints.NotEmpty; |
| 10 | import jakarta.validation.constraints.NotNull; | 10 | import jakarta.validation.constraints.NotNull; |
| 11 | import lombok.Data; | 11 | import lombok.Data; |
| 12 | +import org.hibernate.validator.constraints.URL; | ||
| 12 | 13 | ||
| 13 | import java.util.List; | 14 | import java.util.List; |
| 14 | import java.util.Map; | 15 | import java.util.Map; |
| @@ -115,6 +116,11 @@ public class BpmSimpleModelNodeVO { | @@ -115,6 +116,11 @@ public class BpmSimpleModelNodeVO { | ||
| 115 | @Schema(description = "路由分支默认分支 ID", example = "Flow_xxx", hidden = true) // 由后端生成,所以 hidden = true | 116 | @Schema(description = "路由分支默认分支 ID", example = "Flow_xxx", hidden = true) // 由后端生成,所以 hidden = true |
| 116 | private String routerDefaultFlowId; // 仅用于路由分支节点 BpmSimpleModelNodeType.ROUTER_BRANCH_NODE | 117 | private String routerDefaultFlowId; // 仅用于路由分支节点 BpmSimpleModelNodeType.ROUTER_BRANCH_NODE |
| 117 | 118 | ||
| 119 | + /** | ||
| 120 | + * 触发器节点设置 | ||
| 121 | + */ | ||
| 122 | + private TriggerSetting triggerSetting; | ||
| 123 | + | ||
| 118 | @Schema(description = "任务监听器") | 124 | @Schema(description = "任务监听器") |
| 119 | @Valid | 125 | @Valid |
| 120 | @Data | 126 | @Data |
| @@ -128,27 +134,28 @@ public class BpmSimpleModelNodeVO { | @@ -128,27 +134,28 @@ public class BpmSimpleModelNodeVO { | ||
| 128 | private String path; | 134 | private String path; |
| 129 | 135 | ||
| 130 | @Schema(description = "请求头", example = "[]") | 136 | @Schema(description = "请求头", example = "[]") |
| 131 | - private List<ListenerParam> header; | 137 | + private List<HttpRequestParamSetting> header; |
| 132 | 138 | ||
| 133 | @Schema(description = "请求体", example = "[]") | 139 | @Schema(description = "请求体", example = "[]") |
| 134 | - private List<ListenerParam> body; | ||
| 135 | - | ||
| 136 | - // TODO @芋艿:这里后续要不要复用; | 140 | + private List<HttpRequestParamSetting> body; |
| 141 | + } | ||
| 137 | 142 | ||
| 138 | - @Schema(description = "任务监听器键值对") | ||
| 139 | - @Data | ||
| 140 | - public static class ListenerParam { | 143 | + @Schema(description = "HTTP 请求参数设置") |
| 144 | + @Data | ||
| 145 | + public static class HttpRequestParamSetting { | ||
| 141 | 146 | ||
| 142 | - @Schema(description = "值类型", example = "1") | ||
| 143 | - @InEnum(BpmListenerParamTypeEnum.class) | ||
| 144 | - private Integer type; | 147 | + @Schema(description = "值类型", example = "1") |
| 148 | + @InEnum(BpmHttpRequestParamSettingType.class) | ||
| 149 | + @NotNull(message = "值类型不能为空") | ||
| 150 | + private Integer type; | ||
| 145 | 151 | ||
| 146 | - @Schema(description = "键", example = "xxx") | ||
| 147 | - private String key; | 152 | + @Schema(description = "键", example = "xxx") |
| 153 | + @NotEmpty(message = "键不能为空") | ||
| 154 | + private String key; | ||
| 148 | 155 | ||
| 149 | - @Schema(description = "值", example = "xxx") | ||
| 150 | - private String value; | ||
| 151 | - } | 156 | + @Schema(description = "值", example = "xxx") |
| 157 | + @NotEmpty(message = "值不能为空") | ||
| 158 | + private String value; | ||
| 152 | } | 159 | } |
| 153 | 160 | ||
| 154 | @Schema(description = "审批节点拒绝处理策略") | 161 | @Schema(description = "审批节点拒绝处理策略") |
| @@ -318,4 +325,39 @@ public class BpmSimpleModelNodeVO { | @@ -318,4 +325,39 @@ public class BpmSimpleModelNodeVO { | ||
| 318 | @Schema(description = "条件组", example = "{}") | 325 | @Schema(description = "条件组", example = "{}") |
| 319 | private ConditionGroups conditionGroups; | 326 | private ConditionGroups conditionGroups; |
| 320 | } | 327 | } |
| 328 | + | ||
| 329 | + @Schema(description = "触发器节点配置") | ||
| 330 | + @Data | ||
| 331 | + @Valid | ||
| 332 | + public static class TriggerSetting { | ||
| 333 | + | ||
| 334 | + @Schema(description = "触发器类型", example = "1") | ||
| 335 | + @InEnum(BpmTriggerType.class) | ||
| 336 | + @NotNull(message = "触发器类型不能为空") | ||
| 337 | + private Integer type; | ||
| 338 | + | ||
| 339 | + /** | ||
| 340 | + * http 请求触发器设置 | ||
| 341 | + */ | ||
| 342 | + @Valid | ||
| 343 | + private HttpRequestTriggerSetting httpRequestSetting; | ||
| 344 | + | ||
| 345 | + @Schema(description = "http 请求触发器设置", example = "{}") | ||
| 346 | + @Data | ||
| 347 | + public static class HttpRequestTriggerSetting { | ||
| 348 | + | ||
| 349 | + @Schema(description = "请求路径", example = "http://127.0.0.1") | ||
| 350 | + @NotEmpty(message = "请求 URL 不能为空") | ||
| 351 | + @URL(message = "请求 URL 格式不正确") | ||
| 352 | + private String url; | ||
| 353 | + | ||
| 354 | + @Schema(description = "请求头参数设置", example = "[]") | ||
| 355 | + @Valid | ||
| 356 | + private List<HttpRequestParamSetting> header; | ||
| 357 | + | ||
| 358 | + @Schema(description = "请求头参数设置", example = "[]") | ||
| 359 | + @Valid | ||
| 360 | + private List<HttpRequestParamSetting> body; | ||
| 361 | + } | ||
| 362 | + } | ||
| 321 | } | 363 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnModelConstants.java
| @@ -101,6 +101,16 @@ public interface BpmnModelConstants { | @@ -101,6 +101,16 @@ public interface BpmnModelConstants { | ||
| 101 | String BUTTON_SETTING_ELEMENT_ENABLE_ATTRIBUTE = "enable"; | 101 | String BUTTON_SETTING_ELEMENT_ENABLE_ATTRIBUTE = "enable"; |
| 102 | 102 | ||
| 103 | /** | 103 | /** |
| 104 | + * BPMN ExtensionElement 的扩展属性,用于标记触发器的类型 | ||
| 105 | + */ | ||
| 106 | + String TRIGGER_TYPE = "triggerType"; | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * BPMN ExtensionElement 的扩展属性,用于标记触发器参数 | ||
| 110 | + */ | ||
| 111 | + String TRIGGER_PARAM = "triggerParam"; | ||
| 112 | + | ||
| 113 | + /** | ||
| 104 | * BPMN Start Event Node Id | 114 | * BPMN Start Event Node Id |
| 105 | */ | 115 | */ |
| 106 | String START_EVENT_NODE_ID = "StartEvent"; | 116 | String START_EVENT_NODE_ID = "StartEvent"; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTriggerTaskDelegate.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerType; | ||
| 4 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; | ||
| 5 | +import cn.iocoder.yudao.module.bpm.service.task.trigger.BpmTrigger; | ||
| 6 | +import jakarta.annotation.PostConstruct; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import lombok.extern.slf4j.Slf4j; | ||
| 9 | +import org.flowable.bpmn.model.FlowElement; | ||
| 10 | +import org.flowable.engine.delegate.DelegateExecution; | ||
| 11 | +import org.flowable.engine.delegate.JavaDelegate; | ||
| 12 | +import org.springframework.stereotype.Component; | ||
| 13 | + | ||
| 14 | +import java.util.EnumMap; | ||
| 15 | +import java.util.List; | ||
| 16 | + | ||
| 17 | +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmTriggerTaskDelegate.BEAN_NAME; | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * 处理触发器任务 {@link JavaDelegate} 的实现类 | ||
| 22 | + * <p> | ||
| 23 | + * 目前只有 Simple 设计器【触发器节点】使用 | ||
| 24 | + * | ||
| 25 | + * @author jason | ||
| 26 | + */ | ||
| 27 | +@Component(BEAN_NAME) | ||
| 28 | +@Slf4j | ||
| 29 | +public class BpmTriggerTaskDelegate implements JavaDelegate { | ||
| 30 | + | ||
| 31 | + public static final String BEAN_NAME = "bpmTriggerTaskDelegate"; | ||
| 32 | + | ||
| 33 | + @Resource | ||
| 34 | + private List<BpmTrigger> triggers; | ||
| 35 | + | ||
| 36 | + private final EnumMap<BpmTriggerType, BpmTrigger> triggerMap = new EnumMap<>(BpmTriggerType.class); | ||
| 37 | + | ||
| 38 | + @PostConstruct | ||
| 39 | + private void init() { | ||
| 40 | + triggers.forEach(trigger -> triggerMap.put(trigger.getType(), trigger)); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public void execute(DelegateExecution execution) { | ||
| 45 | + FlowElement flowElement = execution.getCurrentFlowElement(); | ||
| 46 | + BpmTriggerType bpmTriggerType = BpmnModelUtils.parserTriggerType(flowElement); | ||
| 47 | + BpmTrigger bpmTrigger = triggerMap.get(bpmTriggerType); | ||
| 48 | + if (bpmTrigger == null) { | ||
| 49 | + log.error("[execute], FlowElement[{}], {} 找不到匹配的 BpmTrigger", execution.getCurrentActivityId(), flowElement); | ||
| 50 | + return; | ||
| 51 | + } | ||
| 52 | + bpmTrigger.execute(execution.getProcessInstanceId(), BpmnModelUtils.parserTriggerParam(flowElement)); | ||
| 53 | + } | ||
| 54 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
| @@ -4,17 +4,16 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,17 +4,16 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.convert.Convert; | 4 | import cn.hutool.core.convert.Convert; |
| 5 | import cn.hutool.core.lang.Assert; | 5 | import cn.hutool.core.lang.Assert; |
| 6 | import cn.hutool.core.map.MapUtil; | 6 | import cn.hutool.core.map.MapUtil; |
| 7 | -import cn.hutool.core.util.*; | 7 | +import cn.hutool.core.util.ArrayUtil; |
| 8 | +import cn.hutool.core.util.ObjUtil; | ||
| 9 | +import cn.hutool.core.util.StrUtil; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 10 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 9 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 11 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 10 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 12 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 11 | import cn.iocoder.yudao.framework.common.util.string.StrUtils; | 13 | import cn.iocoder.yudao.framework.common.util.string.StrUtils; |
| 12 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | 14 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 13 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; | 15 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; |
| 14 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskApproveTypeEnum; | ||
| 15 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum; | ||
| 16 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignStartUserHandlerTypeEnum; | ||
| 17 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | 16 | +import cn.iocoder.yudao.module.bpm.enums.definition.*; |
| 18 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | 17 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; |
| 19 | import com.google.common.collect.Maps; | 18 | import com.google.common.collect.Maps; |
| 20 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
| @@ -395,6 +394,15 @@ public class BpmnModelUtils { | @@ -395,6 +394,15 @@ public class BpmnModelUtils { | ||
| 395 | return JsonUtils.parseObject(expressionText, BpmSimpleModelNodeVO.ListenerHandler.class); | 394 | return JsonUtils.parseObject(expressionText, BpmSimpleModelNodeVO.ListenerHandler.class); |
| 396 | } | 395 | } |
| 397 | 396 | ||
| 397 | + public static BpmTriggerType parserTriggerType(FlowElement flowElement) { | ||
| 398 | + Integer triggerType = NumberUtils.parseInt(parseExtensionElement(flowElement, TRIGGER_TYPE)); | ||
| 399 | + return BpmTriggerType.typeOf(triggerType); | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + public static String parserTriggerParam(FlowElement flowElement) { | ||
| 403 | + return parseExtensionElement(flowElement, TRIGGER_PARAM); | ||
| 404 | + } | ||
| 405 | + | ||
| 398 | // ========== BPM 简单查找相关的方法 ========== | 406 | // ========== BPM 简单查找相关的方法 ========== |
| 399 | 407 | ||
| 400 | /** | 408 | /** |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| @@ -5,17 +5,20 @@ import cn.hutool.core.lang.Assert; | @@ -5,17 +5,20 @@ import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.hutool.core.map.MapUtil; | 5 | import cn.hutool.core.map.MapUtil; |
| 6 | import cn.hutool.core.util.*; | 6 | import cn.hutool.core.util.*; |
| 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 8 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 8 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | 9 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 9 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups; | 10 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.ConditionGroups; |
| 10 | import cn.iocoder.yudao.module.bpm.enums.definition.*; | 11 | import cn.iocoder.yudao.module.bpm.enums.definition.*; |
| 11 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; | 12 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; |
| 12 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; | 13 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; |
| 13 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmCopyTaskDelegate; | 14 | import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmCopyTaskDelegate; |
| 15 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.BpmTriggerTaskDelegate; | ||
| 14 | import org.flowable.bpmn.BpmnAutoLayout; | 16 | import org.flowable.bpmn.BpmnAutoLayout; |
| 15 | import org.flowable.bpmn.constants.BpmnXMLConstants; | 17 | import org.flowable.bpmn.constants.BpmnXMLConstants; |
| 16 | import org.flowable.bpmn.model.Process; | 18 | import org.flowable.bpmn.model.Process; |
| 17 | import org.flowable.bpmn.model.*; | 19 | import org.flowable.bpmn.model.*; |
| 18 | import org.flowable.engine.delegate.TaskListener; | 20 | import org.flowable.engine.delegate.TaskListener; |
| 21 | +import org.springframework.util.MultiValueMap; | ||
| 19 | 22 | ||
| 20 | import java.util.*; | 23 | import java.util.*; |
| 21 | 24 | ||
| @@ -39,7 +42,7 @@ public class SimpleModelUtils { | @@ -39,7 +42,7 @@ public class SimpleModelUtils { | ||
| 39 | static { | 42 | static { |
| 40 | List<NodeConvert> converts = asList(new StartNodeConvert(), new EndNodeConvert(), | 43 | List<NodeConvert> converts = asList(new StartNodeConvert(), new EndNodeConvert(), |
| 41 | new StartUserNodeConvert(), new ApproveNodeConvert(), new CopyNodeConvert(), | 44 | new StartUserNodeConvert(), new ApproveNodeConvert(), new CopyNodeConvert(), |
| 42 | - new DelayTimerNodeConvert(), | 45 | + new DelayTimerNodeConvert(), new TriggerNodeConvert(), |
| 43 | new ConditionBranchNodeConvert(), new ParallelBranchNodeConvert(), new InclusiveBranchNodeConvert(), new RouteBranchNodeConvert()); | 46 | new ConditionBranchNodeConvert(), new ParallelBranchNodeConvert(), new InclusiveBranchNodeConvert(), new RouteBranchNodeConvert()); |
| 44 | converts.forEach(convert -> NODE_CONVERTS.put(convert.getType(), convert)); | 47 | converts.forEach(convert -> NODE_CONVERTS.put(convert.getType(), convert)); |
| 45 | } | 48 | } |
| @@ -93,7 +96,7 @@ public class SimpleModelUtils { | @@ -93,7 +96,7 @@ public class SimpleModelUtils { | ||
| 93 | /** | 96 | /** |
| 94 | * 遍历节点,构建 FlowNode 元素 | 97 | * 遍历节点,构建 FlowNode 元素 |
| 95 | * | 98 | * |
| 96 | - * @param node SIMPLE 节点 | 99 | + * @param node SIMPLE 节点 |
| 97 | * @param process BPMN 流程 | 100 | * @param process BPMN 流程 |
| 98 | */ | 101 | */ |
| 99 | private static void traverseNodeToBuildFlowNode(BpmSimpleModelNodeVO node, Process process) { | 102 | private static void traverseNodeToBuildFlowNode(BpmSimpleModelNodeVO node, Process process) { |
| @@ -124,8 +127,8 @@ public class SimpleModelUtils { | @@ -124,8 +127,8 @@ public class SimpleModelUtils { | ||
| 124 | /** | 127 | /** |
| 125 | * 遍历节点,构建 SequenceFlow 元素 | 128 | * 遍历节点,构建 SequenceFlow 元素 |
| 126 | * | 129 | * |
| 127 | - * @param process Bpmn 流程 | ||
| 128 | - * @param node 当前节点 | 130 | + * @param process Bpmn 流程 |
| 131 | + * @param node 当前节点 | ||
| 129 | * @param targetNodeId 目标节点 ID | 132 | * @param targetNodeId 目标节点 ID |
| 130 | */ | 133 | */ |
| 131 | private static void traverseNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { | 134 | private static void traverseNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { |
| @@ -152,8 +155,8 @@ public class SimpleModelUtils { | @@ -152,8 +155,8 @@ public class SimpleModelUtils { | ||
| 152 | /** | 155 | /** |
| 153 | * 遍历普通(非条件)节点,构建 SequenceFlow 元素 | 156 | * 遍历普通(非条件)节点,构建 SequenceFlow 元素 |
| 154 | * | 157 | * |
| 155 | - * @param process Bpmn 流程 | ||
| 156 | - * @param node 当前节点 | 158 | + * @param process Bpmn 流程 |
| 159 | + * @param node 当前节点 | ||
| 157 | * @param targetNodeId 目标节点 ID | 160 | * @param targetNodeId 目标节点 ID |
| 158 | */ | 161 | */ |
| 159 | private static void traverseNormalNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { | 162 | private static void traverseNormalNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { |
| @@ -161,7 +164,7 @@ public class SimpleModelUtils { | @@ -161,7 +164,7 @@ public class SimpleModelUtils { | ||
| 161 | boolean isChildNodeValid = isValidNode(childNode); | 164 | boolean isChildNodeValid = isValidNode(childNode); |
| 162 | // 情况一:有“子”节点,则建立连线 | 165 | // 情况一:有“子”节点,则建立连线 |
| 163 | // 情况二:没有“子节点”,则直接跟 targetNodeId 建立连线。例如说,结束节点、条件分支(分支节点的孩子节点或聚合节点)的最后一个节点 | 166 | // 情况二:没有“子节点”,则直接跟 targetNodeId 建立连线。例如说,结束节点、条件分支(分支节点的孩子节点或聚合节点)的最后一个节点 |
| 164 | - String finalTargetNodeId = isChildNodeValid? childNode.getId() : targetNodeId; | 167 | + String finalTargetNodeId = isChildNodeValid ? childNode.getId() : targetNodeId; |
| 165 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), finalTargetNodeId); | 168 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), finalTargetNodeId); |
| 166 | process.addFlowElement(sequenceFlow); | 169 | process.addFlowElement(sequenceFlow); |
| 167 | 170 | ||
| @@ -174,8 +177,8 @@ public class SimpleModelUtils { | @@ -174,8 +177,8 @@ public class SimpleModelUtils { | ||
| 174 | /** | 177 | /** |
| 175 | * 遍历条件节点,构建 SequenceFlow 元素 | 178 | * 遍历条件节点,构建 SequenceFlow 元素 |
| 176 | * | 179 | * |
| 177 | - * @param process Bpmn 流程 | ||
| 178 | - * @param node 当前节点 | 180 | + * @param process Bpmn 流程 |
| 181 | + * @param node 当前节点 | ||
| 179 | * @param targetNodeId 目标节点 ID | 182 | * @param targetNodeId 目标节点 ID |
| 180 | */ | 183 | */ |
| 181 | private static void traverseBranchNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { | 184 | private static void traverseBranchNodeToBuildSequenceFlow(Process process, BpmSimpleModelNodeVO node, String targetNodeId) { |
| @@ -231,7 +234,7 @@ public class SimpleModelUtils { | @@ -231,7 +234,7 @@ public class SimpleModelUtils { | ||
| 231 | String nextNodeId = isValidNode(childNode) ? childNode.getId() : targetNodeId; | 234 | String nextNodeId = isValidNode(childNode) ? childNode.getId() : targetNodeId; |
| 232 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(branchEndNodeId, nextNodeId); | 235 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(branchEndNodeId, nextNodeId); |
| 233 | process.addFlowElement(sequenceFlow); | 236 | process.addFlowElement(sequenceFlow); |
| 234 | - // 4.2 如果是路由分支,需要连接后续节点为默认路由 | 237 | + // 4.2 如果是路由分支,需要连接后续节点为默认路由 |
| 235 | } else if (nodeType == BpmSimpleModelNodeType.ROUTER_BRANCH_NODE) { | 238 | } else if (nodeType == BpmSimpleModelNodeType.ROUTER_BRANCH_NODE) { |
| 236 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), branchEndNodeId, node.getRouterDefaultFlowId(), | 239 | SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), branchEndNodeId, node.getRouterDefaultFlowId(), |
| 237 | null, null); | 240 | null, null); |
| @@ -449,7 +452,7 @@ public class SimpleModelUtils { | @@ -449,7 +452,7 @@ public class SimpleModelUtils { | ||
| 449 | private void addUserTaskListener(BpmSimpleModelNodeVO node, UserTask userTask) { | 452 | private void addUserTaskListener(BpmSimpleModelNodeVO node, UserTask userTask) { |
| 450 | List<FlowableListener> flowableListeners = new ArrayList<>(3); | 453 | List<FlowableListener> flowableListeners = new ArrayList<>(3); |
| 451 | if (node.getTaskCreateListener() != null | 454 | if (node.getTaskCreateListener() != null |
| 452 | - && Boolean.TRUE.equals(node.getTaskCreateListener().getEnable())) { | 455 | + && Boolean.TRUE.equals(node.getTaskCreateListener().getEnable())) { |
| 453 | FlowableListener flowableListener = new FlowableListener(); | 456 | FlowableListener flowableListener = new FlowableListener(); |
| 454 | flowableListener.setEvent(TaskListener.EVENTNAME_CREATE); | 457 | flowableListener.setEvent(TaskListener.EVENTNAME_CREATE); |
| 455 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 458 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
| @@ -458,7 +461,7 @@ public class SimpleModelUtils { | @@ -458,7 +461,7 @@ public class SimpleModelUtils { | ||
| 458 | flowableListeners.add(flowableListener); | 461 | flowableListeners.add(flowableListener); |
| 459 | } | 462 | } |
| 460 | if (node.getTaskAssignListener() != null | 463 | if (node.getTaskAssignListener() != null |
| 461 | - && Boolean.TRUE.equals(node.getTaskAssignListener().getEnable())) { | 464 | + && Boolean.TRUE.equals(node.getTaskAssignListener().getEnable())) { |
| 462 | FlowableListener flowableListener = new FlowableListener(); | 465 | FlowableListener flowableListener = new FlowableListener(); |
| 463 | flowableListener.setEvent(TaskListener.EVENTNAME_ASSIGNMENT); | 466 | flowableListener.setEvent(TaskListener.EVENTNAME_ASSIGNMENT); |
| 464 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 467 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
| @@ -467,7 +470,7 @@ public class SimpleModelUtils { | @@ -467,7 +470,7 @@ public class SimpleModelUtils { | ||
| 467 | flowableListeners.add(flowableListener); | 470 | flowableListeners.add(flowableListener); |
| 468 | } | 471 | } |
| 469 | if (node.getTaskCompleteListener() != null | 472 | if (node.getTaskCompleteListener() != null |
| 470 | - && Boolean.TRUE.equals(node.getTaskCompleteListener().getEnable())) { | 473 | + && Boolean.TRUE.equals(node.getTaskCompleteListener().getEnable())) { |
| 471 | FlowableListener flowableListener = new FlowableListener(); | 474 | FlowableListener flowableListener = new FlowableListener(); |
| 472 | flowableListener.setEvent(TaskListener.EVENTNAME_COMPLETE); | 475 | flowableListener.setEvent(TaskListener.EVENTNAME_COMPLETE); |
| 473 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | 476 | flowableListener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); |
| @@ -693,9 +696,9 @@ public class SimpleModelUtils { | @@ -693,9 +696,9 @@ public class SimpleModelUtils { | ||
| 693 | boundaryEvent.setAttachedToRef(receiveTask); | 696 | boundaryEvent.setAttachedToRef(receiveTask); |
| 694 | // 2.2 定义超时时间 | 697 | // 2.2 定义超时时间 |
| 695 | TimerEventDefinition eventDefinition = new TimerEventDefinition(); | 698 | TimerEventDefinition eventDefinition = new TimerEventDefinition(); |
| 696 | - if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_DATE_TIME.getType())){ | 699 | + if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_DATE_TIME.getType())) { |
| 697 | eventDefinition.setTimeDuration(node.getDelaySetting().getDelayTime()); | 700 | eventDefinition.setTimeDuration(node.getDelaySetting().getDelayTime()); |
| 698 | - } else if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_TIME_DURATION.getType())){ | 701 | + } else if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_TIME_DURATION.getType())) { |
| 699 | eventDefinition.setTimeDate(node.getDelaySetting().getDelayTime()); | 702 | eventDefinition.setTimeDate(node.getDelaySetting().getDelayTime()); |
| 700 | } | 703 | } |
| 701 | boundaryEvent.addEventDefinition(eventDefinition); | 704 | boundaryEvent.addEventDefinition(eventDefinition); |
| @@ -711,6 +714,32 @@ public class SimpleModelUtils { | @@ -711,6 +714,32 @@ public class SimpleModelUtils { | ||
| 711 | } | 714 | } |
| 712 | } | 715 | } |
| 713 | 716 | ||
| 717 | + public static class TriggerNodeConvert implements NodeConvert { | ||
| 718 | + | ||
| 719 | + @Override | ||
| 720 | + public ServiceTask convert(BpmSimpleModelNodeVO node) { | ||
| 721 | + // 触发器使用 ServiceTask 来实现 | ||
| 722 | + ServiceTask serviceTask = new ServiceTask(); | ||
| 723 | + serviceTask.setId(node.getId()); | ||
| 724 | + serviceTask.setName(node.getName()); | ||
| 725 | + serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); | ||
| 726 | + serviceTask.setImplementation("${" + BpmTriggerTaskDelegate.BEAN_NAME + "}"); | ||
| 727 | + if (node.getTriggerSetting() != null) { | ||
| 728 | + addExtensionElement(serviceTask, TRIGGER_TYPE, node.getTriggerSetting().getType()); | ||
| 729 | + if (node.getTriggerSetting().getHttpRequestSetting() != null) { | ||
| 730 | + addExtensionElement(serviceTask, TRIGGER_PARAM, | ||
| 731 | + JsonUtils.toJsonString(node.getTriggerSetting().getHttpRequestSetting())); | ||
| 732 | + } | ||
| 733 | + } | ||
| 734 | + return serviceTask; | ||
| 735 | + } | ||
| 736 | + | ||
| 737 | + @Override | ||
| 738 | + public BpmSimpleModelNodeType getType() { | ||
| 739 | + return BpmSimpleModelNodeType.TRIGGER_NODE; | ||
| 740 | + } | ||
| 741 | + } | ||
| 742 | + | ||
| 714 | public static class RouteBranchNodeConvert implements NodeConvert { | 743 | public static class RouteBranchNodeConvert implements NodeConvert { |
| 715 | 744 | ||
| 716 | @Override | 745 | @Override |
| @@ -751,7 +780,7 @@ public class SimpleModelUtils { | @@ -751,7 +780,7 @@ public class SimpleModelUtils { | ||
| 751 | } | 780 | } |
| 752 | 781 | ||
| 753 | private static void simulateNextNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables, | 782 | private static void simulateNextNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables, |
| 754 | - List<BpmSimpleModelNodeVO> resultNodes) { | 783 | + List<BpmSimpleModelNodeVO> resultNodes) { |
| 755 | // 如果不合法(包括为空),则直接结束 | 784 | // 如果不合法(包括为空),则直接结束 |
| 756 | if (!isValidNode(currentNode)) { | 785 | if (!isValidNode(currentNode)) { |
| 757 | return; | 786 | return; |
| @@ -761,10 +790,10 @@ public class SimpleModelUtils { | @@ -761,10 +790,10 @@ public class SimpleModelUtils { | ||
| 761 | 790 | ||
| 762 | // 情况:START_NODE/START_USER_NODE/APPROVE_NODE/COPY_NODE/END_NODE | 791 | // 情况:START_NODE/START_USER_NODE/APPROVE_NODE/COPY_NODE/END_NODE |
| 763 | if (nodeType == BpmSimpleModelNodeType.START_NODE | 792 | if (nodeType == BpmSimpleModelNodeType.START_NODE |
| 764 | - || nodeType == BpmSimpleModelNodeType.START_USER_NODE | ||
| 765 | - || nodeType == BpmSimpleModelNodeType.APPROVE_NODE | ||
| 766 | - || nodeType == BpmSimpleModelNodeType.COPY_NODE | ||
| 767 | - || nodeType == BpmSimpleModelNodeType.END_NODE) { | 793 | + || nodeType == BpmSimpleModelNodeType.START_USER_NODE |
| 794 | + || nodeType == BpmSimpleModelNodeType.APPROVE_NODE | ||
| 795 | + || nodeType == BpmSimpleModelNodeType.COPY_NODE | ||
| 796 | + || nodeType == BpmSimpleModelNodeType.END_NODE) { | ||
| 768 | // 添加元素 | 797 | // 添加元素 |
| 769 | resultNodes.add(currentNode); | 798 | resultNodes.add(currentNode); |
| 770 | } | 799 | } |
| @@ -774,7 +803,7 @@ public class SimpleModelUtils { | @@ -774,7 +803,7 @@ public class SimpleModelUtils { | ||
| 774 | // 查找满足条件的 BpmSimpleModelNodeVO 节点 | 803 | // 查找满足条件的 BpmSimpleModelNodeVO 节点 |
| 775 | BpmSimpleModelNodeVO matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), | 804 | BpmSimpleModelNodeVO matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), |
| 776 | conditionNode -> !BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow()) | 805 | conditionNode -> !BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow()) |
| 777 | - && evalConditionExpress(variables, conditionNode)); | 806 | + && evalConditionExpress(variables, conditionNode)); |
| 778 | if (matchConditionNode == null) { | 807 | if (matchConditionNode == null) { |
| 779 | matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), | 808 | matchConditionNode = CollUtil.findOne(currentNode.getConditionNodes(), |
| 780 | conditionNode -> BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow())); | 809 | conditionNode -> BooleanUtil.isTrue(conditionNode.getConditionSetting().getDefaultFlow())); |
| @@ -815,4 +844,25 @@ public class SimpleModelUtils { | @@ -815,4 +844,25 @@ public class SimpleModelUtils { | ||
| 815 | return BpmnModelUtils.evalConditionExpress(variables, ConditionNodeConvert.buildConditionExpression(conditionNode)); | 844 | return BpmnModelUtils.evalConditionExpress(variables, ConditionNodeConvert.buildConditionExpression(conditionNode)); |
| 816 | } | 845 | } |
| 817 | 846 | ||
| 847 | + /** | ||
| 848 | + * 添加 HTTP 请求参数。请求头或者请求体 | ||
| 849 | + * | ||
| 850 | + * @param params HTTP 请求参数 | ||
| 851 | + * @param paramSettings HTTP 请求参数设置 | ||
| 852 | + * @param processVariables 流程变量 | ||
| 853 | + */ | ||
| 854 | + public static void addHttpRequestParam(MultiValueMap<String, String> params, | ||
| 855 | + List<BpmSimpleModelNodeVO.HttpRequestParamSetting> paramSettings, | ||
| 856 | + Map<String, Object> processVariables) { | ||
| 857 | + if (CollUtil.isEmpty(paramSettings)) { | ||
| 858 | + return; | ||
| 859 | + } | ||
| 860 | + paramSettings.forEach(item -> { | ||
| 861 | + if (item.getType().equals(BpmHttpRequestParamSettingType.FIXED_VALUE.getType())) { | ||
| 862 | + params.add(item.getKey(), item.getValue()); | ||
| 863 | + } else if (item.getType().equals(BpmHttpRequestParamSettingType.FROM_FORM.getType())) { | ||
| 864 | + params.add(item.getKey(), processVariables.get(item.getValue()).toString()); | ||
| 865 | + } | ||
| 866 | + }); | ||
| 867 | + } | ||
| 818 | } | 868 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/listener/BpmUserTaskListener.java
| 1 | package cn.iocoder.yudao.module.bpm.service.task.listener; | 1 | package cn.iocoder.yudao.module.bpm.service.task.listener; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 5 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; | 4 | import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| 6 | -import cn.iocoder.yudao.module.bpm.enums.definition.BpmListenerParamTypeEnum; | 5 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils; |
| 7 | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | 6 | import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; |
| 8 | import jakarta.annotation.Resource; | 7 | import jakarta.annotation.Resource; |
| 9 | import lombok.Setter; | 8 | import lombok.Setter; |
| @@ -22,7 +21,6 @@ import org.springframework.util.MultiValueMap; | @@ -22,7 +21,6 @@ import org.springframework.util.MultiValueMap; | ||
| 22 | import org.springframework.web.client.RestClientException; | 21 | import org.springframework.web.client.RestClientException; |
| 23 | import org.springframework.web.client.RestTemplate; | 22 | import org.springframework.web.client.RestTemplate; |
| 24 | 23 | ||
| 25 | -import java.util.List; | ||
| 26 | import java.util.Map; | 24 | import java.util.Map; |
| 27 | 25 | ||
| 28 | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | 26 | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; |
| @@ -59,8 +57,8 @@ public class BpmUserTaskListener implements TaskListener { | @@ -59,8 +57,8 @@ public class BpmUserTaskListener implements TaskListener { | ||
| 59 | Map<String, Object> processVariables = processInstance.getProcessVariables(); | 57 | Map<String, Object> processVariables = processInstance.getProcessVariables(); |
| 60 | MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); | 58 | MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); |
| 61 | MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | 59 | MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); |
| 62 | - parseListenerParam(listenerHandler.getHeader(), processVariables, headers); | ||
| 63 | - parseListenerParam(listenerHandler.getBody(), processVariables, body); | 60 | + SimpleModelUtils.addHttpRequestParam(headers, listenerHandler.getHeader(), processVariables); |
| 61 | + SimpleModelUtils.addHttpRequestParam(body, listenerHandler.getBody(), processVariables); | ||
| 64 | // 2.1 请求头默认参数 | 62 | // 2.1 请求头默认参数 |
| 65 | if (StrUtil.isNotEmpty(delegateTask.getTenantId())) { | 63 | if (StrUtil.isNotEmpty(delegateTask.getTenantId())) { |
| 66 | headers.add(HEADER_TENANT_ID, delegateTask.getTenantId()); | 64 | headers.add(HEADER_TENANT_ID, delegateTask.getTenantId()); |
| @@ -94,20 +92,4 @@ public class BpmUserTaskListener implements TaskListener { | @@ -94,20 +92,4 @@ public class BpmUserTaskListener implements TaskListener { | ||
| 94 | } | 92 | } |
| 95 | // 4. 是否需要后续操作?TODO 芋艿:待定! | 93 | // 4. 是否需要后续操作?TODO 芋艿:待定! |
| 96 | } | 94 | } |
| 97 | - | ||
| 98 | - private void parseListenerParam(List<BpmSimpleModelNodeVO.ListenerHandler.ListenerParam> list, | ||
| 99 | - Map<String, Object> processVariables, | ||
| 100 | - MultiValueMap<String, String> to) { | ||
| 101 | - if (CollUtil.isEmpty(list)) { | ||
| 102 | - return; | ||
| 103 | - } | ||
| 104 | - list.forEach(item -> { | ||
| 105 | - if (item.getType().equals(BpmListenerParamTypeEnum.FIXED_VALUE.getType())) { | ||
| 106 | - to.add(item.getKey(), item.getValue()); | ||
| 107 | - } else if (item.getType().equals(BpmListenerParamTypeEnum.FROM_FORM.getType())) { | ||
| 108 | - to.add(item.getKey(), processVariables.get(item.getValue()).toString()); | ||
| 109 | - } | ||
| 110 | - }); | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | } | 95 | } |
| 114 | \ No newline at end of file | 96 | \ No newline at end of file |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmHttpRequestTrigger.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task.trigger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting; | ||
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerType; | ||
| 6 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils; | ||
| 7 | +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; | ||
| 8 | +import jakarta.annotation.Resource; | ||
| 9 | +import lombok.extern.slf4j.Slf4j; | ||
| 10 | +import org.flowable.engine.runtime.ProcessInstance; | ||
| 11 | +import org.springframework.http.HttpEntity; | ||
| 12 | +import org.springframework.http.HttpMethod; | ||
| 13 | +import org.springframework.http.ResponseEntity; | ||
| 14 | +import org.springframework.stereotype.Component; | ||
| 15 | +import org.springframework.util.LinkedMultiValueMap; | ||
| 16 | +import org.springframework.util.MultiValueMap; | ||
| 17 | +import org.springframework.web.client.RestClientException; | ||
| 18 | +import org.springframework.web.client.RestTemplate; | ||
| 19 | + | ||
| 20 | +import java.util.Map; | ||
| 21 | + | ||
| 22 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * BPM 发送 HTTP 请求触发器 | ||
| 26 | + * | ||
| 27 | + * @author jason | ||
| 28 | + */ | ||
| 29 | +@Component | ||
| 30 | +@Slf4j | ||
| 31 | +public class BpmHttpRequestTrigger implements BpmTrigger { | ||
| 32 | + | ||
| 33 | + @Resource | ||
| 34 | + private BpmProcessInstanceService processInstanceService; | ||
| 35 | + | ||
| 36 | + @Resource | ||
| 37 | + private RestTemplate restTemplate; | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public BpmTriggerType getType() { | ||
| 41 | + return BpmTriggerType.HTTP_REQUEST; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + @Override | ||
| 45 | + public void execute(String processInstanceId, String param) { | ||
| 46 | + // 1. 解析 http 请求配置 | ||
| 47 | + HttpRequestTriggerSetting httpRequestSetting = JsonUtils.parseObject(param, HttpRequestTriggerSetting.class); | ||
| 48 | + if (httpRequestSetting == null) { | ||
| 49 | + log.error("[execute] HTTP 触发器请求配置为空"); | ||
| 50 | + return; | ||
| 51 | + } | ||
| 52 | + // 2.1 设置请求头 | ||
| 53 | + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); | ||
| 54 | + Map<String, Object> processVariables = processInstance.getProcessVariables(); | ||
| 55 | + MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); | ||
| 56 | + headers.add(HEADER_TENANT_ID, processInstance.getTenantId()); | ||
| 57 | + SimpleModelUtils.addHttpRequestParam(headers, httpRequestSetting.getHeader(), processVariables); | ||
| 58 | + // 2.2 设置请求体 | ||
| 59 | + MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | ||
| 60 | + SimpleModelUtils.addHttpRequestParam(body, httpRequestSetting.getBody(), processVariables); | ||
| 61 | + body.add("processInstanceId", processInstanceId); | ||
| 62 | + | ||
| 63 | + // 3. 发起请求 | ||
| 64 | + HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers); | ||
| 65 | + try { | ||
| 66 | + ResponseEntity<String> responseEntity = restTemplate.exchange(httpRequestSetting.getUrl(), HttpMethod.POST, | ||
| 67 | + requestEntity, String.class); | ||
| 68 | + log.info("[execute][HTTP 触发器,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity); | ||
| 69 | + } catch (RestClientException e) { | ||
| 70 | + log.error("[execute][HTTP 触发器,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage()); | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmTrigger.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.task.trigger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerType; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * BPM 触发器接口 | ||
| 7 | + * <p> | ||
| 8 | + * 处理不同的动作 | ||
| 9 | + * | ||
| 10 | + * @author jason | ||
| 11 | + */ | ||
| 12 | +public interface BpmTrigger { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 对应触发器类型 | ||
| 16 | + * | ||
| 17 | + * @return 触发器类型 | ||
| 18 | + */ | ||
| 19 | + BpmTriggerType getType(); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 触发器执行 | ||
| 23 | + * | ||
| 24 | + * @param processInstanceId 流程实例编号 | ||
| 25 | + * @param param 触发器参数 | ||
| 26 | + */ | ||
| 27 | + void execute(String processInstanceId, String param); | ||
| 28 | +} |