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

This commit is contained in:
jason 2024-05-13 14:27:01 +08:00
parent f9c7795efb
commit f85ca1f88f
6 changed files with 131 additions and 3 deletions

View File

@ -13,7 +13,8 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum BpmSimpleModeConditionType { public enum BpmSimpleModeConditionType {
CUSTOM_EXPRESSION(1, "自定义条件表达式"); EXPRESSION(1, "条件表达式"),
RULE(2, "条件规则");
private final Integer type; private final Integer type;
private final String name; private final String name;

View File

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

View File

@ -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;
}
}

View File

@ -30,4 +30,9 @@ public interface SimpleModelConstants {
*/ */
String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression"; String CONDITION_EXPRESSION_ATTRIBUTE = "conditionExpression";
/**
* 条件规则的条件组属性
*/
String CONDITION_GROUPS_ATTRIBUTE = "conditionGroups";
} }

View File

@ -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;
}
}

View File

@ -1,18 +1,22 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; 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.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.TypeReference; import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil; 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.controller.admin.definition.vo.simple.BpmSimpleModelNodeVO;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; 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.BpmSimpleModeConditionType;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType; 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.BpmnModelConstants;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.SimpleModelConstants; 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.BpmnAutoLayout;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*; import org.flowable.bpmn.model.*;
@ -143,12 +147,34 @@ public class SimpleModelUtils {
Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE); Integer conditionType = MapUtil.getInt(conditionNode.getAttributes(), CONDITION_TYPE_ATTRIBUTE);
BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType); BpmSimpleModeConditionType conditionTypeEnum = BpmSimpleModeConditionType.valueOf(conditionType);
String conditionExpression = null; String conditionExpression = null;
if (conditionTypeEnum == BpmSimpleModeConditionType.CUSTOM_EXPRESSION) { if (conditionTypeEnum == BpmSimpleModeConditionType.EXPRESSION) {
conditionExpression = MapUtil.getStr(conditionNode.getAttributes(), CONDITION_EXPRESSION_ATTRIBUTE); 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 待增加其它类型 // TODO 待增加其它类型
return conditionExpression; return conditionExpression;
} }
private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) { private static SequenceFlow buildBpmnSequenceFlow(String sourceId, String targetId, String seqFlowId, String seqName, String conditionExpression) {