Commit 3686ef82d5d7da52ea5dd7ae681598a7e9545244

Authored by 芋道源码
Committed by Gitee
2 parents eb57b222 bd73cfdf

!1519 条件节点添加包含和不包含操作符

Merge pull request !1519 from Lesan/bugfix/bpm-202602
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormFieldVO.java
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
  5 +import java.util.List;
  6 +
5 /** 7 /**
6 * 流程表单字段 VO 8 * 流程表单字段 VO
7 */ 9 */
@@ -20,5 +22,9 @@ public class BpmFormFieldVO { @@ -20,5 +22,9 @@ public class BpmFormFieldVO {
20 * 字段标题 22 * 字段标题
21 */ 23 */
22 private String title; 24 private String title;
  25 + /**
  26 + * 子表单字段(处理布局组件)
  27 + */
  28 + private List<BpmFormFieldVO> children;
23 29
24 } 30 }
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmConditionOpCodeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.enums.definition;
  2 +
  3 +import lombok.Getter;
  4 +import lombok.RequiredArgsConstructor;
  5 +
  6 +/**
  7 + * BPM 条件表达式操作符枚举
  8 + *
  9 + * @author Lesan
  10 + */
  11 +@RequiredArgsConstructor
  12 +@Getter
  13 +public enum BpmConditionOpCodeEnum {
  14 + EQ("==", "等于", " var:getOrDefault(%s, null) == %s "),
  15 + NE("!=", "不等于", " var:getOrDefault(%s, null) != %s "),
  16 + GT(">", "大于", " var:getOrDefault(%s, null) > %s "),
  17 + GE(">=", "大于等于", " var:getOrDefault(%s, null) >= %s "),
  18 + LT("<", "小于", " var:getOrDefault(%s, null) < %s "),
  19 + LE("<=", "小于等于", " var:getOrDefault(%s, null) <= %s "),
  20 + CONTAINS("contain", "包含", " var:contains(%s, %s) "),
  21 + NOT_CONTAINS("!contain", "不包含", " !var:contains(%s, %s) ");
  22 +
  23 + private final String code;
  24 + private final String des;
  25 + private final String symbol;
  26 +
  27 + public static BpmConditionOpCodeEnum fromCode(String code) {
  28 + for (BpmConditionOpCodeEnum op : BpmConditionOpCodeEnum.values()) {
  29 + if (op.code.equalsIgnoreCase(code)) {
  30 + return op;
  31 + }
  32 + }
  33 + throw new IllegalArgumentException("未知操作符: " + code);
  34 + }
  35 +
  36 +}
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
2 2
3 import cn.hutool.core.map.MapUtil; 3 import cn.hutool.core.map.MapUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
5 import cn.hutool.extra.spring.SpringUtil; 6 import cn.hutool.extra.spring.SpringUtil;
6 import cn.iocoder.yudao.framework.common.core.KeyValue; 7 import cn.iocoder.yudao.framework.common.core.KeyValue;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@@ -247,9 +248,7 @@ public class FlowableUtils { @@ -247,9 +248,7 @@ public class FlowableUtils {
247 Map<String, BpmFormFieldVO> formFieldsMap = new HashMap<>(); 248 Map<String, BpmFormFieldVO> formFieldsMap = new HashMap<>();
248 processDefinitionInfo.getFormFields().forEach(formFieldStr -> { 249 processDefinitionInfo.getFormFields().forEach(formFieldStr -> {
249 BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class); 250 BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class);
250 - if (formField != null) {  
251 - formFieldsMap.put(formField.getField(), formField);  
252 - } 251 + parseFormField(formField, formFieldsMap);
253 }); 252 });
254 253
255 // 情况一:当自定义了摘要 254 // 情况一:当自定义了摘要
@@ -273,6 +272,30 @@ public class FlowableUtils { @@ -273,6 +272,30 @@ public class FlowableUtils {
273 .collect(Collectors.toList()); 272 .collect(Collectors.toList());
274 } 273 }
275 274
  275 + /**
  276 + * 递归解析表单字段
  277 + */
  278 + private static void parseFormField(BpmFormFieldVO formField,
  279 + Map<String, BpmFormFieldVO> formFieldsMap) {
  280 +
  281 + if (formField == null) {
  282 + return;
  283 + }
  284 +
  285 + // 如果存在 children -> 说明是布局组件
  286 + if (formField.getChildren() != null && !formField.getChildren().isEmpty()) {
  287 + for (BpmFormFieldVO child : formField.getChildren()) {
  288 + parseFormField(child, formFieldsMap);
  289 + }
  290 + return;
  291 + }
  292 +
  293 + // 真实字段才加入 map
  294 + if (StrUtil.isNotBlank(formField.getField())) {
  295 + formFieldsMap.put(formField.getField(), formField);
  296 + }
  297 + }
  298 +
276 // ========== Task 相关的工具方法 ========== 299 // ========== Task 相关的工具方法 ==========
277 300
278 /** 301 /**
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -705,12 +705,12 @@ public class SimpleModelUtils { @@ -705,12 +705,12 @@ public class SimpleModelUtils {
705 } 705 }
706 // 构造规则表达式 706 // 构造规则表达式
707 List<String> list = convertList(item.getRules(), (rule) -> { 707 List<String> list = convertList(item.getRules(), (rule) -> {
  708 + // TODO @芋艿:官方文档中无convertByType方法,https://flowable.me/blog/2025/04/02/back-end-expressions/
708 String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide() 709 String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide()
709 : "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号 710 : "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号
710 - return String.format(" vars:getOrDefault(%s, null) %s var:convertByType(%s,%s) ", 711 + return String.format(BpmConditionOpCodeEnum.fromCode(rule.getOpCode()).getSymbol(),
711 rule.getLeftSide(), // 左侧:读取变量 712 rule.getLeftSide(), // 左侧:读取变量
712 - rule.getOpCode(), // 中间:操作符,比较  
713 - rule.getLeftSide(), rightSide); // 右侧:转换变量,VariableConvertByTypeExpressionFunction 713 + rightSide); // 右侧:取值变量
714 }); 714 });
715 // 构造条件组的表达式 715 // 构造条件组的表达式
716 Boolean and = item.getAnd(); 716 Boolean and = item.getAnd();