Commit f85ca1f88ff62b8e12ef355de9e7d87df01b13df

Authored by jason
1 parent f9c7795e

仿钉钉流程设计- 条件节点新增条件规则

yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModeConditionType.java
@@ -13,7 +13,8 @@ import lombok.Getter; @@ -13,7 +13,8 @@ import lombok.Getter;
13 @AllArgsConstructor 13 @AllArgsConstructor
14 public enum BpmSimpleModeConditionType { 14 public enum BpmSimpleModeConditionType {
15 15
16 - CUSTOM_EXPRESSION(1, "自定义条件表达式"); 16 + EXPRESSION(1, "条件表达式"),
  17 + RULE(2, "条件规则");
17 18
18 private final Integer type; 19 private final Integer type;
19 private final String name; 20 private final String name;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCand @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCand
6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
7 import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher; 7 import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher;
8 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 8 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  9 +import org.flowable.common.engine.api.delegate.FlowableFunctionDelegate;
9 import org.flowable.common.engine.api.delegate.event.FlowableEventListener; 10 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
10 import org.flowable.spring.SpringProcessEngineConfiguration; 11 import org.flowable.spring.SpringProcessEngineConfiguration;
11 import org.flowable.spring.boot.EngineConfigurationConfigurer; 12 import org.flowable.spring.boot.EngineConfigurationConfigurer;
@@ -56,12 +57,15 @@ public class BpmFlowableConfiguration { @@ -56,12 +57,15 @@ public class BpmFlowableConfiguration {
56 @Bean 57 @Bean
57 public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer( 58 public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer(
58 ObjectProvider<FlowableEventListener> listeners, 59 ObjectProvider<FlowableEventListener> listeners,
  60 + ObjectProvider<FlowableFunctionDelegate> customFlowableFunctionDelegates,
59 BpmActivityBehaviorFactory bpmActivityBehaviorFactory) { 61 BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
60 return configuration -> { 62 return configuration -> {
61 // 注册监听器,例如说 BpmActivityEventListener 63 // 注册监听器,例如说 BpmActivityEventListener
62 configuration.setEventListeners(ListUtil.toList(listeners.iterator())); 64 configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
63 // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义 65 // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
64 configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory); 66 configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
  67 + // 设置自定义的函数
  68 + configuration.setCustomFlowableFunctionDelegates(ListUtil.toList(customFlowableFunctionDelegates.stream().iterator()));
65 }; 69 };
66 } 70 }
67 71
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/el/VariableConvertByTypeExpressionFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.el;
  2 +
  3 +import org.flowable.common.engine.api.variable.VariableContainer;
  4 +import org.flowable.common.engine.impl.el.function.AbstractFlowableVariableExpressionFunction;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +/**
  8 + * 根据流程变量 variable 的类型, 转换参数的值
  9 + *
  10 + * @author jason
  11 + */
  12 +@Component
  13 +public class VariableConvertByTypeExpressionFunction extends AbstractFlowableVariableExpressionFunction {
  14 +
  15 + public VariableConvertByTypeExpressionFunction() {
  16 + super("convertByType");
  17 + }
  18 +
  19 + public static Object convertByType(VariableContainer variableContainer, String variableName, Object parmaValue) {
  20 + Object variable = variableContainer.getVariable(variableName);
  21 + if (variable != null && parmaValue != null) {
  22 + // 如果值不是字符串类型, 流程变量的类型是字符串。 把值转成字符串
  23 + if (!(parmaValue instanceof String) && variable instanceof String ) {
  24 + return parmaValue.toString();
  25 + }
  26 + }
  27 + return parmaValue;
  28 + }
  29 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/SimpleModelConstants.java
@@ -30,4 +30,9 @@ public interface SimpleModelConstants { @@ -30,4 +30,9 @@ public interface SimpleModelConstants {
30 */ 30 */
31 String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression"; 31 String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression";
32 32
  33 + /**
  34 + * 条件规则的条件组属性
  35 + */
  36 + String CONDITION_GROUPS_ATTRIBUTE = "conditionGroups";
  37 +
33 } 38 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/simple/SimpleModelConditionGroups.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * 仿钉钉流程设计器条件节点的条件组 Model
  9 + *
  10 + * @author jason
  11 + */
  12 +@Data
  13 +public class SimpleModelConditionGroups {
  14 +
  15 + /**
  16 + * 条件组的逻辑关系是否为与的关系
  17 + */
  18 + private Boolean and;
  19 +
  20 + /**
  21 + * 条件组下的条件
  22 + */
  23 + private List<SimpleModelCondition> conditions;
  24 +
  25 + @Data
  26 + public static class SimpleModelCondition {
  27 +
  28 + /**
  29 + * 条件下面多个规则的逻辑关系是否为与的关系
  30 + */
  31 + private Boolean and;
  32 +
  33 +
  34 + /**
  35 + * 条件下的规则
  36 + */
  37 + private List<ConditionRule> rules;
  38 + }
  39 +
  40 + @Data
  41 + public static class ConditionRule {
  42 +
  43 + /**
  44 + * 类型. TODO 暂时未定义, 未想好
  45 + */
  46 + private Integer type;
  47 +
  48 + /**
  49 + * 运行符号. 例如 == <
  50 + */
  51 + private String opCode;
  52 +
  53 + /**
  54 + * 运算符左边的值
  55 + */
  56 + private String leftSide;
  57 +
  58 + /**
  59 + * 运算符右边的值
  60 + */
  61 + private String rightSide;
  62 + }
  63 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
2 2
  3 +import cn.hutool.core.bean.BeanUtil;
3 import cn.hutool.core.collection.CollUtil; 4 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert; 5 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.lang.TypeReference; 6 import cn.hutool.core.lang.TypeReference;
6 import cn.hutool.core.map.MapUtil; 7 import cn.hutool.core.map.MapUtil;
7 import cn.hutool.core.util.ArrayUtil; 8 import cn.hutool.core.util.ArrayUtil;
8 import cn.hutool.core.util.BooleanUtil; 9 import cn.hutool.core.util.BooleanUtil;
  10 +import cn.hutool.core.util.NumberUtil;
9 import cn.hutool.core.util.StrUtil; 11 import cn.hutool.core.util.StrUtil;
  12 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
10 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO; 13 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
11 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; 14 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
12 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType; 15 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType;
13 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; 16 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
14 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants; 17 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
15 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants; 18 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
  19 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.simple.SimpleModelConditionGroups;
16 import org.flowable.bpmn.BpmnAutoLayout; 20 import org.flowable.bpmn.BpmnAutoLayout;
17 import org.flowable.bpmn.model.Process; 21 import org.flowable.bpmn.model.Process;
18 import org.flowable.bpmn.model.*; 22 import org.flowable.bpmn.model.*;
@@ -143,12 +147,34 @@ public class SimpleModelUtils { @@ -143,12 +147,34 @@ public class SimpleModelUtils {
143 Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE); 147 Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE);
144 BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType); 148 BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType);
145 String conditionExpression = null; 149 String conditionExpression = null;
146 - if (conditionTypeEnum == BpmSimpleModeConditionType.CUSTOM_EXPRESSION) { 150 + if (conditionTypeEnum == BpmSimpleModeConditionType.EXPRESSION) {
147 conditionExpression = MapUtil.getStr(conditionNode.getAttributes(), CONDITION_EXPRESSION_ATTRIBUTE); 151 conditionExpression = MapUtil.getStr(conditionNode.getAttributes(), CONDITION_EXPRESSION_ATTRIBUTE);
148 } 152 }
  153 + if (conditionTypeEnum == BpmSimpleModeConditionType.RULE) {
  154 + SimpleModelConditionGroups conditionGroups = BeanUtil.toBean(MapUtil.get(conditionNode.getAttributes(),
  155 + CONDITION_GROUPS_ATTRIBUTE, new TypeReference<Map<String, Object>>() {
  156 + }),
  157 + SimpleModelConditionGroups.class);
  158 + if (conditionGroups != null && CollUtil.isNotEmpty(conditionGroups.getConditions())) {
  159 + List<String> strConditionGroups = conditionGroups.getConditions().stream().map(item -> {
  160 + if (CollUtil.isNotEmpty(item.getRules())) {
  161 + Boolean and = item.getAnd();
  162 + List<String> list = CollectionUtils.convertList(item.getRules(), (rule) -> {
  163 + // 如果非数值类型加引号
  164 + String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() : "\"" + rule.getRightSide() + "\"";
  165 + return String.format(" %s %s var:convertByType(%s,%s)", rule.getLeftSide(), rule.getOpCode(), rule.getLeftSide(), rightSide);
  166 + });
  167 + return "(" + CollUtil.join(list, and ? " && " : " || ") + ")";
  168 + } else {
  169 + return "";
  170 + }
  171 + }).toList();
  172 + conditionExpression = String.format("${%s}", CollUtil.join(strConditionGroups, conditionGroups.getAnd() ? " && " : " || "));
  173 + }
  174 +
  175 + }
149 // TODO 待增加其它类型 176 // TODO 待增加其它类型
150 return conditionExpression; 177 return conditionExpression;
151 -  
152 } 178 }
153 179
154 private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) { 180 private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) {