Commit 797fddfb3d495303378a4798d7934086cdedc9ae
1 parent
cdbcd4d6
BPM:新增 flowable expression 表达式,替代现有 BpmTaskAssignScript,更加灵活
Showing
12 changed files
with
59 additions
and
90 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTaskAssignRuleTypeEnum.java
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; |
| 14 | 14 | * |
| 15 | 15 | * @author 芋道源码 |
| 16 | 16 | */ |
| 17 | +@Deprecated | |
| 17 | 18 | public interface BpmTaskAssignScript { |
| 18 | 19 | |
| 19 | 20 | /** |
| ... | ... | @@ -30,5 +31,6 @@ public interface BpmTaskAssignScript { |
| 30 | 31 | * @return 枚举值 |
| 31 | 32 | */ |
| 32 | 33 | BpmTaskRuleScriptEnum getEnum(); |
| 34 | + | |
| 33 | 35 | } |
| 34 | 36 | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderAbstractScript.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX1Script.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignLeaderX2Script.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/script/impl/BpmTaskAssignStartUserScript.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/handler/MultiInstanceHandler.java deleted
| 1 | -package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler; | |
| 2 | - | |
| 3 | -import cn.hutool.core.collection.CollUtil; | |
| 4 | -import cn.hutool.core.util.ObjectUtil; | |
| 5 | -import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants; | |
| 6 | -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 7 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 8 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 9 | -import jakarta.annotation.Resource; | |
| 10 | -import lombok.AllArgsConstructor; | |
| 11 | -import org.flowable.bpmn.model.FlowElement; | |
| 12 | -import org.flowable.bpmn.model.UserTask; | |
| 13 | -import org.flowable.engine.delegate.DelegateExecution; | |
| 14 | -import org.springframework.stereotype.Component; | |
| 15 | - | |
| 16 | -import java.util.ArrayList; | |
| 17 | -import java.util.LinkedHashSet; | |
| 18 | -import java.util.List; | |
| 19 | -import java.util.Set; | |
| 20 | -import java.util.stream.Collectors; | |
| 21 | - | |
| 22 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 23 | - | |
| 24 | -// TODO @芋艿:bpmn 分配人融合时,需要搞下这块; | |
| 25 | -/** | |
| 26 | - * 多实例处理类 | |
| 27 | - */ | |
| 28 | -@AllArgsConstructor | |
| 29 | -@Component("multiInstanceHandler") | |
| 30 | -public class MultiInstanceHandler { | |
| 31 | - | |
| 32 | - @Resource | |
| 33 | - private AdminUserApi userApi; | |
| 34 | - | |
| 35 | - @Resource | |
| 36 | - private PermissionApi permissionApi; | |
| 37 | - | |
| 38 | - /** | |
| 39 | - * 流程发起人那种情况不需要处理, | |
| 40 | - * 由 flowable 完成 | |
| 41 | - * | |
| 42 | - * @param execution flowable的执行对象 | |
| 43 | - * @return 用户ID | |
| 44 | - */ | |
| 45 | - public Set<String> getUserIds(DelegateExecution execution) { | |
| 46 | - Set<String> candidateUserIds = new LinkedHashSet<>(); | |
| 47 | - FlowElement flowElement = execution.getCurrentFlowElement(); | |
| 48 | - if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) { | |
| 49 | - String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE); | |
| 50 | - if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) { | |
| 51 | - // 添加候选用户id | |
| 52 | - candidateUserIds.addAll(userTask.getCandidateUsers()); | |
| 53 | - } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) { | |
| 54 | - // 获取组的ID,角色ID集合或部门ID集合 | |
| 55 | - List<Long> groups = userTask.getCandidateGroups().stream() | |
| 56 | - // 例如部门DEPT100,100才是部门id | |
| 57 | - .map(item -> Long.parseLong(item.substring(4))) | |
| 58 | - .collect(Collectors.toList()); | |
| 59 | - List<Long> userIds = new ArrayList<>(); | |
| 60 | - if ("ROLES".equals(dataType)) { | |
| 61 | - // 通过角色id,获取所有用户id集合 | |
| 62 | - Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups); | |
| 63 | - userIds = new ArrayList<>(userRoleIdListByRoleIds); | |
| 64 | - } else if ("DEPTS".equals(dataType)) { | |
| 65 | - // 通过部门id,获取所有用户id集合 | |
| 66 | - List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups); | |
| 67 | - userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId); | |
| 68 | - } | |
| 69 | - // 添加候选用户id | |
| 70 | - userIds.forEach(id -> candidateUserIds.add(String.valueOf(id))); | |
| 71 | - } | |
| 72 | - } | |
| 73 | - return candidateUserIds; | |
| 74 | - } | |
| 75 | - | |
| 76 | -} |
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 { |
| 171 | 171 | // 1.5 校验模型是否发生修改。如果未修改,则不允许创建 |
| 172 | 172 | BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form) |
| 173 | 173 | .setBpmnBytes(bpmnBytes); |
| 174 | - if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 | |
| 175 | - throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); | |
| 176 | - } | |
| 174 | + // TODO @芋艿:这里比较可能有点问题 | |
| 175 | +// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等 | |
| 176 | +// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS); | |
| 177 | +// } | |
| 177 | 178 | |
| 178 | 179 | // 2.1 创建流程定义 |
| 179 | 180 | String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO); | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.bpm.service.definition; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | 5 | import cn.hutool.core.util.StrUtil; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| ... | ... | @@ -10,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils; |
| 10 | 11 | import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; |
| 11 | 12 | import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants; |
| 12 | 13 | import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils; |
| 14 | +import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; | |
| 13 | 15 | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; |
| 14 | 16 | import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; |
| 15 | 17 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; |
| ... | ... | @@ -26,6 +28,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 26 | 28 | import com.google.common.annotations.VisibleForTesting; |
| 27 | 29 | import jakarta.annotation.Resource; |
| 28 | 30 | import lombok.extern.slf4j.Slf4j; |
| 31 | +import org.dromara.hutool.core.convert.Convert; | |
| 29 | 32 | import org.flowable.bpmn.model.BpmnModel; |
| 30 | 33 | import org.flowable.bpmn.model.FlowElement; |
| 31 | 34 | import org.flowable.bpmn.model.UserTask; |
| ... | ... | @@ -57,6 +60,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 57 | 60 | @Lazy // 解决循环依赖 |
| 58 | 61 | private BpmProcessInstanceService processInstanceService; |
| 59 | 62 | |
| 63 | +// @Resource | |
| 64 | +// private ExpressionManager expressionManager; | |
| 65 | + | |
| 60 | 66 | @Resource |
| 61 | 67 | private RoleApi roleApi; |
| 62 | 68 | @Resource |
| ... | ... | @@ -93,6 +99,10 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 93 | 99 | if (type == null || StrUtil.isBlank(options)) { |
| 94 | 100 | throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, userTask.getName()); |
| 95 | 101 | } |
| 102 | + // TODO 芋艿:校验 options | |
| 103 | + if (ObjectUtil.equal(type, BpmTaskAssignRuleTypeEnum.EXPRESS.getType())) { | |
| 104 | + return; | |
| 105 | + } | |
| 96 | 106 | validTaskAssignRuleOptions(type, StrUtils.splitToLong(options, ",")); |
| 97 | 107 | }); |
| 98 | 108 | } |
| ... | ... | @@ -117,6 +127,14 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 117 | 127 | } |
| 118 | 128 | } |
| 119 | 129 | |
| 130 | + public Long test(DelegateExecution execution) { | |
| 131 | + return 1L; | |
| 132 | + } | |
| 133 | + | |
| 134 | + public Long test2(DelegateExecution execution, Long id) { | |
| 135 | + return id; | |
| 136 | + } | |
| 137 | + | |
| 120 | 138 | @Override |
| 121 | 139 | @DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题 |
| 122 | 140 | public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) { |
| ... | ... | @@ -137,7 +155,11 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 137 | 155 | // TODO 芋艿:assignType/assignOptions/, 枚举 |
| 138 | 156 | FlowElement flowElement = execution.getCurrentFlowElement(); |
| 139 | 157 | Integer type = NumberUtils.parseInt(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType")); |
| 140 | - Set<Long> options = StrUtils.splitToLongSet(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions"), ","); | |
| 158 | + String optionStr = flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions"); | |
| 159 | + Set<Long> options = null; | |
| 160 | + if (ObjectUtil.notEqual(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) { | |
| 161 | + options = StrUtils.splitToLongSet(optionStr, ","); | |
| 162 | + } | |
| 141 | 163 | |
| 142 | 164 | // 计算审批人 |
| 143 | 165 | Set<Long> assigneeUserIds = null; |
| ... | ... | @@ -155,6 +177,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { |
| 155 | 177 | assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options); |
| 156 | 178 | } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) { |
| 157 | 179 | assigneeUserIds = calculateTaskCandidateUsersByScript(execution, options); |
| 180 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) { | |
| 181 | + Object result = FlowableUtils.getExpressionValue(execution, optionStr); | |
| 182 | + assigneeUserIds = Convert.toSet(Long.class, result); | |
| 158 | 183 | } |
| 159 | 184 | |
| 160 | 185 | // 移除被禁用的用户 | ... | ... |
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/enums/BpmnModelConstants.java
yudao-module-bpm/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/core/util/FlowableUtils.java
| 1 | 1 | package cn.iocoder.yudao.framework.flowable.core.util; |
| 2 | 2 | |
| 3 | +import org.flowable.common.engine.api.delegate.Expression; | |
| 4 | +import org.flowable.common.engine.api.variable.VariableContainer; | |
| 5 | +import org.flowable.common.engine.impl.el.ExpressionManager; | |
| 3 | 6 | import org.flowable.common.engine.impl.identity.Authentication; |
| 7 | +import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; | |
| 8 | +import org.flowable.engine.impl.util.CommandContextUtil; | |
| 4 | 9 | |
| 5 | 10 | /** |
| 6 | 11 | * Flowable 相关的工具方法 |
| ... | ... | @@ -29,4 +34,15 @@ public class FlowableUtils { |
| 29 | 34 | return activityId + "_assignee"; |
| 30 | 35 | } |
| 31 | 36 | |
| 37 | + // ========== Expression 相关的工具方法 ========== | |
| 38 | + | |
| 39 | + public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) { | |
| 40 | + ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(); | |
| 41 | + assert processEngineConfiguration != null; | |
| 42 | + ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager(); | |
| 43 | + assert expressionManager != null; | |
| 44 | + Expression expression = expressionManager.createExpression(expressionString); | |
| 45 | + return expression.getValue(variableContainer); | |
| 46 | + } | |
| 47 | + | |
| 32 | 48 | } | ... | ... |
yudao-server/pom.xml
| ... | ... | @@ -46,11 +46,11 @@ |
| 46 | 46 | <!-- <version>${revision}</version>--> |
| 47 | 47 | <!-- </dependency>--> |
| 48 | 48 | <!-- 工作流。默认注释,保证编译速度 --> |
| 49 | -<!-- <dependency>--> | |
| 50 | -<!-- <groupId>cn.iocoder.boot</groupId>--> | |
| 51 | -<!-- <artifactId>yudao-module-bpm-biz</artifactId>--> | |
| 52 | -<!-- <version>${revision}</version>--> | |
| 53 | -<!-- </dependency>--> | |
| 49 | + <dependency> | |
| 50 | + <groupId>cn.iocoder.boot</groupId> | |
| 51 | + <artifactId>yudao-module-bpm-biz</artifactId> | |
| 52 | + <version>${revision}</version> | |
| 53 | + </dependency> | |
| 54 | 54 | <!-- 支付服务。默认注释,保证编译速度 --> |
| 55 | 55 | <!-- <dependency>--> |
| 56 | 56 | <!-- <groupId>cn.iocoder.boot</groupId>--> | ... | ... |