Browse Source

BPM:新增 flowable expression 表达式,替代现有 BpmTaskAssignScript,更加灵活

YunaiV 1 year ago
parent
commit
797fddfb3d
12 changed files with 59 additions and 90 deletions
  1. 2 0
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
  2. 2 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java
  3. 1 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java
  4. 1 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
  5. 1 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
  6. 1 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
  7. 0 76
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java
  8. 4 3
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
  9. 26 1
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
  10. 0 5
      yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java
  11. 16 0
      yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java
  12. 5 5
      yudao-server/pom.xml

+ 2 - 0
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java

@@ -18,7 +18,9 @@ public enum BpmTaskAssignRuleTypeEnum {
     POST(22, "岗位"),
     USER(30, "用户"),
     USER_GROUP(40, "用户组"),
+    @Deprecated
     SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
+    EXPRESS(60, "流程表达式"), // 表达式 ExpressionManager
     ;
 
     /**

+ 2 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/BpmTaskAssignScript.java

@@ -14,6 +14,7 @@ import java.util.Set;
  *
  * @author 芋道源码
  */
+@Deprecated
 public interface BpmTaskAssignScript {
 
     /**
@@ -30,5 +31,6 @@ public interface BpmTaskAssignScript {
      * @return 枚举值
      */
     BpmTaskRuleScriptEnum getEnum();
+
 }
 

+ 1 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java

@@ -24,6 +24,7 @@ import static java.util.Collections.emptySet;
  *
  * @author 芋道源码
  */
+@Deprecated
 public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
 
     @Resource

+ 1 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java

@@ -11,6 +11,7 @@ import java.util.Set;
  *
  * @author 芋道源码
  */
+@Deprecated
 @Component
 public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
 

+ 1 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java

@@ -11,6 +11,7 @@ import java.util.Set;
  *
  * @author 芋道源码
  */
+@Deprecated
 @Component
 public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
 

+ 1 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java

@@ -18,6 +18,7 @@ import java.util.Set;
  *
  * @author 芋道源码
  */
+@Deprecated
 @Component
 public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
 

+ 0 - 76
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java

@@ -1,76 +0,0 @@
-package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
-import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
-import jakarta.annotation.Resource;
-import lombok.AllArgsConstructor;
-import org.flowable.bpmn.model.FlowElement;
-import org.flowable.bpmn.model.UserTask;
-import org.flowable.engine.delegate.DelegateExecution;
-import org.springframework.stereotype.Component;
-
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-
-// TODO @芋艿:bpmn 分配人融合时,需要搞下这块;
-/**
- * 多实例处理类
- */
-@AllArgsConstructor
-@Component("multiInstanceHandler")
-public class MultiInstanceHandler {
-
-    @Resource
-    private AdminUserApi userApi;
-
-    @Resource
-    private PermissionApi permissionApi;
-
-    /**
-     * 流程发起人那种情况不需要处理,
-     * 由 flowable 完成
-     *
-     * @param execution flowable的执行对象
-     * @return 用户ID
-     */
-    public Set<String> getUserIds(DelegateExecution execution) {
-        Set<String> candidateUserIds = new LinkedHashSet<>();
-        FlowElement flowElement = execution.getCurrentFlowElement();
-        if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) {
-            String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE);
-            if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
-                // 添加候选用户id
-                candidateUserIds.addAll(userTask.getCandidateUsers());
-            } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
-                // 获取组的ID,角色ID集合或部门ID集合
-                List<Long> groups = userTask.getCandidateGroups().stream()
-                        // 例如部门DEPT100,100才是部门id
-                        .map(item -> Long.parseLong(item.substring(4)))
-                        .collect(Collectors.toList());
-                List<Long> userIds = new ArrayList<>();
-                if ("ROLES".equals(dataType)) {
-                    // 通过角色id,获取所有用户id集合
-                    Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups);
-                    userIds = new ArrayList<>(userRoleIdListByRoleIds);
-                } else if ("DEPTS".equals(dataType)) {
-                    // 通过部门id,获取所有用户id集合
-                    List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups);
-                    userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId);
-                }
-                // 添加候选用户id
-                userIds.forEach(id -> candidateUserIds.add(String.valueOf(id)));
-            }
-        }
-        return candidateUserIds;
-    }
-
-}

+ 4 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java

@@ -171,9 +171,10 @@ public class BpmModelServiceImpl implements BpmModelService {
         // 1.5 校验模型是否发生修改。如果未修改,则不允许创建
         BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form)
                 .setBpmnBytes(bpmnBytes);
-        if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
-            throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
-        }
+        // TODO @芋艿:这里比较可能有点问题
+//        if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
+//            throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
+//        }
 
         // 2.1 创建流程定义
         String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);

+ 26 - 1
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.bpm.service.definition;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -10,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils;
 import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
 import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
 import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
+import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
 import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
@@ -26,6 +28,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import com.google.common.annotations.VisibleForTesting;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.hutool.core.convert.Convert;
 import org.flowable.bpmn.model.BpmnModel;
 import org.flowable.bpmn.model.FlowElement;
 import org.flowable.bpmn.model.UserTask;
@@ -57,6 +60,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
     @Lazy // 解决循环依赖
     private BpmProcessInstanceService processInstanceService;
 
+//    @Resource
+//    private ExpressionManager expressionManager;
+
     @Resource
     private RoleApi roleApi;
     @Resource
@@ -93,6 +99,10 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
             if (type == null || StrUtil.isBlank(options)) {
                 throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, userTask.getName());
             }
+            // TODO 芋艿:校验 options
+            if (ObjectUtil.equal(type, BpmTaskAssignRuleTypeEnum.EXPRESS.getType())) {
+                return;
+            }
             validTaskAssignRuleOptions(type, StrUtils.splitToLong(options, ","));
         });
     }
@@ -117,6 +127,14 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
         }
     }
 
+    public Long test(DelegateExecution execution) {
+        return 1L;
+    }
+
+    public Long test2(DelegateExecution execution, Long id) {
+        return id;
+    }
+
     @Override
     @DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
     public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
@@ -137,7 +155,11 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
         // TODO 芋艿:assignType/assignOptions/, 枚举
         FlowElement flowElement = execution.getCurrentFlowElement();
         Integer type = NumberUtils.parseInt(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType"));
-        Set<Long> options = StrUtils.splitToLongSet(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions"), ",");
+        String optionStr = flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions");
+        Set<Long> options = null;
+        if (ObjectUtil.notEqual(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) {
+            options = StrUtils.splitToLongSet(optionStr, ",");
+        }
 
         // 计算审批人
         Set<Long> assigneeUserIds = null;
@@ -155,6 +177,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
             assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options);
         } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) {
             assigneeUserIds = calculateTaskCandidateUsersByScript(execution, options);
+        } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) {
+           Object result = FlowableUtils.getExpressionValue(execution, optionStr);
+           assigneeUserIds = Convert.toSet(Long.class, result);
         }
 
         // 移除被禁用的用户

+ 0 - 5
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java

@@ -14,9 +14,4 @@ public interface BpmnModelConstants {
      */
     String NAMESPACE = "http://flowable.org/bpmn";
 
-    /**
-     * 自定义属性 dataType
-     */
-    String PROCESS_CUSTOM_DATA_TYPE = "dataType";
-
 }

+ 16 - 0
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java

@@ -1,6 +1,11 @@
 package cn.iocoder.yudao.framework.flowable.core.util;
 
+import org.flowable.common.engine.api.delegate.Expression;
+import org.flowable.common.engine.api.variable.VariableContainer;
+import org.flowable.common.engine.impl.el.ExpressionManager;
 import org.flowable.common.engine.impl.identity.Authentication;
+import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
+import org.flowable.engine.impl.util.CommandContextUtil;
 
 /**
  * Flowable 相关的工具方法
@@ -29,4 +34,15 @@ public class FlowableUtils {
         return activityId + "_assignee";
     }
 
+    // ========== Expression 相关的工具方法 ==========
+
+    public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {
+        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
+        assert processEngineConfiguration != null;
+        ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
+        assert expressionManager != null;
+        Expression expression = expressionManager.createExpression(expressionString);
+        return expression.getValue(variableContainer);
+    }
+
 }

+ 5 - 5
yudao-server/pom.xml

@@ -46,11 +46,11 @@
 <!--            <version>${revision}</version>-->
 <!--        </dependency>-->
         <!-- 工作流。默认注释,保证编译速度 -->
-<!--        <dependency>-->
-<!--            <groupId>cn.iocoder.boot</groupId>-->
-<!--            <artifactId>yudao-module-bpm-biz</artifactId>-->
-<!--            <version>${revision}</version>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-bpm-biz</artifactId>
+            <version>${revision}</version>
+        </dependency>
         <!-- 支付服务。默认注释,保证编译速度 -->
 <!--        <dependency>-->
 <!--            <groupId>cn.iocoder.boot</groupId>-->