diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java index 7c1950f8ce..24f76b3aca 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignLeaderExpression.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @@ -41,11 +42,34 @@ public class BpmTaskAssignLeaderExpression { * @param level 指定级别 * @return 指定级别的领导 */ - public Set calculateUsers(DelegateExecution execution, int level) { - Assert.isTrue(level > 0, "level 必须大于 0"); + public Set calculateUsers(ExecutionEntityImpl execution, Long level) { // 获得发起人 ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); - Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); + return calculateUsers(NumberUtils.parseLong(processInstance.getStartUserId()), level); + } + + /** + * 计算审批的候选人 + * + * @param processInstanceId 流程实例id + * @param level 指定级别 + * @return 指定级别的领导 + */ + public Set calculateUsers(String processInstanceId, Long level) { + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); + return calculateUsers(NumberUtils.parseLong(processInstance.getStartUserId()), level); + } + + + /** + * 计算审批的候选人 + * + * @param startUserId 发起人 + * @param level 指定级别 + * @return 指定级别的领导 + */ + public Set calculateUsers(Long startUserId, Long level) { + Assert.isTrue(level > 0, "level 必须大于 0"); // 获得对应 leve 的部门 DeptRespDTO dept = null; for (int i = 0; i < level; i++) { diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java index ac243c0f43..fe6bff1916 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/expression/BpmTaskAssignStartUserExpression.java @@ -33,4 +33,26 @@ public class BpmTaskAssignStartUserExpression { return SetUtils.asSet(startUserId); } + /** + * 计算审批的候选人 + * + * @param startUserId 发起人id + * @return 发起人 + */ + public Set calculateUsers(Long startUserId) { + return SetUtils.asSet(startUserId); + } + + /** + * 计算审批的候选人 + * + * @param processInstanceId 流程实例id + * @return 发起人 + */ + public Set calculateUsers(String processInstanceId) { + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); + Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); + return SetUtils.asSet(startUserId); + } + } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java index 893c4d053c..f1d3088cfd 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnVariableConstants.java @@ -96,4 +96,8 @@ public class BpmnVariableConstants { */ public static final String TASK_SIGN_PIC_URL = "TASK_SIGN_PIC_URL"; + /** + * 流程实例的变量 - 流程实例id + */ + public static final String PROCESS_INSTANCE_ID = "PROCESS_INSTANCE_ID"; } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java index 67c24bb9f4..98c3ef2803 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormFieldVO; @@ -30,6 +31,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.Callable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; @@ -355,6 +358,33 @@ public class FlowableUtils { } public static Object getExpressionValue(Map variable, String expressionString) { + // 替换方法参数中的 execution 为流程实例id或userId,因为流程预测时获取不到execution对象 + // 例如将 calculateUsers(execution, 1) 替换为 calculateUsers('xxx-xxx-xxx-xxx', 1) + Pattern pattern = Pattern.compile("\\(([^)]*)\\)"); + Matcher matcher = pattern.matcher(expressionString); + StringBuilder sb = new StringBuilder(); + while (matcher.find()) { + // 获取方法参数列表 + String args = matcher.group(1); + // 用逗号分隔参数并逐个替换精确匹配 execution 的部分 + String[] params = args.split(","); + for (int i = 0; i < params.length; i++) { + if ("execution".equals(params[i].trim())) { + // 流程已开始 + if(ObjectUtil.isNotEmpty(variable.get(BpmnVariableConstants.PROCESS_INSTANCE_ID))) { + String processInstanceId = variable.get(BpmnVariableConstants.PROCESS_INSTANCE_ID).toString(); + params[i] = "'" + processInstanceId + "'"; + } else { + //流程未开始 + params[i] = Objects.requireNonNull(SecurityFrameworkUtils.getLoginUserId()).toString(); + } + } + } + String newArgs = String.join(", ", params); + matcher.appendReplacement(sb, "(" + newArgs + ")"); + } + matcher.appendTail(sb); + expressionString = sb.toString(); VariableContainer variableContainer = new MapDelegateVariableContainer(variable, VariableContainer.empty()); return getExpressionValue(variableContainer, expressionString); } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 319f7bd8a8..9d102b4821 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -46,6 +46,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.flowable.bpmn.constants.BpmnXMLConstants; import org.flowable.bpmn.model.*; import org.flowable.engine.HistoryService; @@ -766,9 +767,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService .businessKey(businessKey) .variables(variables); // 3.1 创建流程 ID + String processInstanceId = null; BpmModelMetaInfoVO.ProcessIdRule processIdRule = processDefinitionInfo.getProcessIdRule(); if (processIdRule != null && Boolean.TRUE.equals(processIdRule.getEnable())) { - processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule)); + processInstanceId = processIdRedisDAO.generate(processIdRule); + processInstanceBuilder.predefineProcessInstanceId(processInstanceId); } // 3.2 流程名称 BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting(); @@ -784,6 +787,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService } // 3.3 发起流程实例 ProcessInstance instance = processInstanceBuilder.start(); + // 将流程实例id保存到流程变量里,用于无法获取execution时获取流程实例id + processInstanceId = StringUtils.defaultIfBlank(processInstanceId, instance.getId()); + runtimeService.setVariable(instance.getProcessInstanceId(),BpmnVariableConstants.PROCESS_INSTANCE_ID,processInstanceId); return instance.getId(); }