Browse Source

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

jason 1 year ago
parent
commit
f85ca1f88f

+ 2 - 1
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;
 @AllArgsConstructor
 public enum BpmSimpleModeConditionType {
 
-    CUSTOM_EXPRESSION(1, "自定义条件表达式");
+    EXPRESSION(1, "条件表达式"),
+    RULE(2, "条件规则");
 
     private final Integer type;
     private final String name;

+ 4 - 0
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
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.event.BpmProcessInstanceEventPublisher;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import org.flowable.common.engine.api.delegate.FlowableFunctionDelegate;
 import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
 import org.flowable.spring.SpringProcessEngineConfiguration;
 import org.flowable.spring.boot.EngineConfigurationConfigurer;
@@ -56,12 +57,15 @@ public class BpmFlowableConfiguration {
     @Bean
     public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer(
             ObjectProvider<FlowableEventListener> listeners,
+            ObjectProvider<FlowableFunctionDelegate> customFlowableFunctionDelegates,
             BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
         return configuration -> {
             // 注册监听器,例如说 BpmActivityEventListener
             configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
             // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
             configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
+            // 设置自定义的函数
+            configuration.setCustomFlowableFunctionDelegates(ListUtil.toList(customFlowableFunctionDelegates.stream().iterator()));
         };
     }
 

+ 29 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/el/VariableConvertByTypeExpressionFunction.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.bpm.framework.flowable.core.el;
+
+import org.flowable.common.engine.api.variable.VariableContainer;
+import org.flowable.common.engine.impl.el.function.AbstractFlowableVariableExpressionFunction;
+import org.springframework.stereotype.Component;
+
+/**
+ * 根据流程变量 variable 的类型, 转换参数的值
+ *
+ * @author jason
+ */
+@Component
+public class VariableConvertByTypeExpressionFunction extends AbstractFlowableVariableExpressionFunction {
+
+    public VariableConvertByTypeExpressionFunction() {
+        super("convertByType");
+    }
+
+    public static Object convertByType(VariableContainer variableContainer, String variableName, Object parmaValue) {
+        Object variable = variableContainer.getVariable(variableName);
+        if (variable != null && parmaValue != null) {
+            // 如果值不是字符串类型, 流程变量的类型是字符串。 把值转成字符串
+            if (!(parmaValue instanceof String) && variable instanceof String ) {
+                return parmaValue.toString();
+            }
+        }
+        return parmaValue;
+    }
+}

+ 5 - 0
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 {
      */
     String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression";
 
+    /**
+     * 条件规则的条件组属性
+     */
+    String CONDITION_GROUPS_ATTRIBUTE = "conditionGroups";
+
 }

+ 63 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/simple/SimpleModelConditionGroups.java

@@ -0,0 +1,63 @@
+package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 仿钉钉流程设计器条件节点的条件组 Model
+ *
+ * @author jason
+ */
+@Data
+public class SimpleModelConditionGroups {
+
+    /**
+     * 条件组的逻辑关系是否为与的关系
+     */
+    private Boolean and;
+
+    /**
+     * 条件组下的条件
+     */
+    private List<SimpleModelCondition> conditions;
+
+    @Data
+    public static class SimpleModelCondition {
+
+        /**
+         * 条件下面多个规则的逻辑关系是否为与的关系
+         */
+        private Boolean and;
+
+
+        /**
+         * 条件下的规则
+         */
+        private List<ConditionRule> rules;
+    }
+
+    @Data
+    public static class ConditionRule {
+
+        /**
+         * 类型. TODO  暂时未定义, 未想好
+         */
+        private Integer type;
+
+        /**
+         * 运行符号. 例如 == <
+         */
+        private String opCode;
+
+        /**
+         * 运算符左边的值
+         */
+        private String leftSide;
+
+        /**
+         * 运算符右边的值
+         */
+        private String rightSide;
+    }
+}

+ 28 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java

@@ -1,18 +1,22 @@
 package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.lang.TypeReference;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.BooleanUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModeConditionType;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.simple.SimpleModelConditionGroups;
 import org.flowable.bpmn.BpmnAutoLayout;
 import org.flowable.bpmn.model.Process;
 import org.flowable.bpmn.model.*;
@@ -143,12 +147,34 @@ public class SimpleModelUtils {
         Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE);
         BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType);
         String conditionExpression = null;
-        if (conditionTypeEnum == BpmSimpleModeConditionType.CUSTOM_EXPRESSION) {
+        if (conditionTypeEnum == BpmSimpleModeConditionType.EXPRESSION) {
             conditionExpression = MapUtil.getStr(conditionNode.getAttributes(), CONDITION_EXPRESSION_ATTRIBUTE);
         }
+        if (conditionTypeEnum == BpmSimpleModeConditionType.RULE) {
+            SimpleModelConditionGroups conditionGroups = BeanUtil.toBean(MapUtil.get(conditionNode.getAttributes(),
+                            CONDITION_GROUPS_ATTRIBUTE, new TypeReference<Map<String, Object>>() {
+                            }),
+                    SimpleModelConditionGroups.class);
+            if (conditionGroups != null && CollUtil.isNotEmpty(conditionGroups.getConditions())) {
+                List<String> strConditionGroups = conditionGroups.getConditions().stream().map(item -> {
+                    if (CollUtil.isNotEmpty(item.getRules())) {
+                        Boolean and = item.getAnd();
+                        List<String> list = CollectionUtils.convertList(item.getRules(), (rule) -> {
+                            // 如果非数值类型加引号
+                            String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() : "\"" + rule.getRightSide() + "\"";
+                            return String.format(" %s %s var:convertByType(%s,%s)", rule.getLeftSide(), rule.getOpCode(), rule.getLeftSide(), rightSide);
+                        });
+                        return "(" + CollUtil.join(list, and ? " && " : " || ") + ")";
+                    } else {
+                        return "";
+                    }
+                }).toList();
+                conditionExpression = String.format("${%s}", CollUtil.join(strConditionGroups, conditionGroups.getAnd() ? " && " : " || "));
+            }
+
+        }
         // TODO 待增加其它类型
         return conditionExpression;
-
     }
 
     private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) {