From 3f7fe99067dcae5260f3c37341611e59ace2fba1 Mon Sep 17 00:00:00 2001 From: ye1023 <12588209+ye1023@user.noreply.gitee.com> Date: Fri, 10 Jul 2026 14:18:55 +0800 Subject: [PATCH] =?UTF-8?q?yxk-20260710=20=E5=85=9A=E5=A7=94=E4=BC=9A?= =?UTF-8?q?=E3=80=81=E6=89=80=E5=8A=A1=E4=BC=9A=E3=80=81=E6=8A=8A=E6=8A=8A?= =?UTF-8?q?=E8=84=89=EF=BC=9A=E9=83=A8=E9=97=A8=E8=B4=9F=E8=B4=A3=E4=BA=BA?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E8=8A=82=E7=82=B9=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6=E5=AE=8C=E6=88=90=EF=BC=8C?= =?UTF-8?q?=E8=8B=A5=E5=AE=8C=E6=88=90=E5=88=99=E8=BF=9B=E5=85=A5=E7=9D=A3?= =?UTF-8?q?=E5=8A=9E=E9=83=A8=E9=97=A8=E5=AE=A1=E6=89=B9=EF=BC=9B=E8=8B=A5?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90=E5=88=99=E5=9B=9E=E5=88=B0=E7=BB=8F?= =?UTF-8?q?=E5=8A=9E=E4=BA=BA=E7=BB=A7=E7=BB=AD=E5=8F=8D=E9=A6=88=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=83=85=E5=86=B5=EF=BC=8C=E7=9B=B4=E5=88=B0=E6=9C=80?= =?UTF-8?q?=E7=BB=88=E5=AE=8C=E6=88=90=E4=BB=BB=E5=8A=A1=E3=80=82=201?= =?UTF-8?q?=E3=80=81=E4=BC=98=E5=8C=96=E4=BA=86setVariableLocal=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=8F=AF=E4=BB=A5=E4=BC=A0=E5=85=A5parentLev?= =?UTF-8?q?el=202=E3=80=81=E4=BF=AE=E6=94=B9=E4=BA=86getSonProcessHqVariab?= =?UTF-8?q?leString=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpm/controller/ActProcessController.java | 4 +- .../modules/bpm/dto/ProcessVariableDTO.java | 3 + .../bpm/service/BpmVariableLocalService.java | 10 ++++ .../impl/BpmVariableLocalServiceImpl.java | 58 +++++++++++++------ .../common/expression/FlowNodeExpression.java | 23 ++++++-- 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/controller/ActProcessController.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/controller/ActProcessController.java index 9febc34..948b11a 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/controller/ActProcessController.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/controller/ActProcessController.java @@ -119,7 +119,7 @@ public class ActProcessController { } @PostMapping(value = "/setBpmVariableLocal") - @Operation(summary = "设置局部流程变量(向上追溯2层父级执行实例)") + @Operation(summary = "设置局部流程变量(默认向上追溯2层父级执行实例)") public Result setBpmVariableLocal(@RequestBody ProcessVariableDTO dto) { if (dto == null || oConvertUtils.isEmpty(dto.getTaskId())) { return Result.error("任务ID不能为空"); @@ -128,7 +128,7 @@ public class ActProcessController { return Result.error("流程变量名不能为空"); } try { - bpmVariableLocalService.setVariableLocal(dto.getTaskId(), dto.getVarField(), dto.getVarVal()); + bpmVariableLocalService.setVariableLocal(dto.getTaskId(), dto.getVarField(), dto.getVarVal(), dto.getParentLevel()); return Result.OK("保存成功"); } catch (Exception e) { log.error("设置BPM局部变量失败", e); diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/dto/ProcessVariableDTO.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/dto/ProcessVariableDTO.java index eff70be..1aeefac 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/dto/ProcessVariableDTO.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/dto/ProcessVariableDTO.java @@ -27,4 +27,7 @@ public class ProcessVariableDTO implements Serializable { @Schema(description = "Whether to save as execution local variable") private Boolean local; + + @Schema(description = "Parent execution level for local variable, default 2") + private Integer parentLevel; } diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/BpmVariableLocalService.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/BpmVariableLocalService.java index bea3c35..044b3e9 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/BpmVariableLocalService.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/BpmVariableLocalService.java @@ -10,4 +10,14 @@ public interface BpmVariableLocalService { * @param varVal 变量值 */ void setVariableLocal(String taskId, String varField, Object varVal); + + /** + * 将变量存入指定向上追溯层级的父级执行实例中。 + * + * @param taskId 当前任务ID + * @param varField 变量名 + * @param varVal 变量值 + * @param parentLevel 向上追溯层级,0为当前执行实例,1为直接父级,2为父级的父级 + */ + void setVariableLocal(String taskId, String varField, Object varVal, Integer parentLevel); } diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/impl/BpmVariableLocalServiceImpl.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/impl/BpmVariableLocalServiceImpl.java index e8c6b7b..22fb7b0 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/impl/BpmVariableLocalServiceImpl.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/bpm/service/impl/BpmVariableLocalServiceImpl.java @@ -21,39 +21,61 @@ public class BpmVariableLocalServiceImpl implements BpmVariableLocalService { @Override public void setVariableLocal(String taskId, String varField, Object varVal) { + setVariableLocal(taskId, varField, varVal, 2); + } + + @Override + public void setVariableLocal(String taskId, String varField, Object varVal, Integer parentLevel) { Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); if (task == null) { throw new IllegalArgumentException("任务ID不存在: " + taskId); } String executionId = task.getExecutionId(); + String targetId = resolveTargetExecutionId(executionId, parentLevel); + + runtimeService.setVariableLocal(targetId, varField, varVal); + log.info("BPM局部变量已存入: targetId={}, parentLevel={}, varField={}, varVal={}", + targetId, normalizeParentLevel(parentLevel), varField, varVal); + } + + private String resolveTargetExecutionId(String executionId, Integer parentLevel) { + int level = normalizeParentLevel(parentLevel); + String targetId = executionId; Execution currentExecution = runtimeService.createExecutionQuery() .executionId(executionId) .singleResult(); if (currentExecution == null) { - runtimeService.setVariableLocal(executionId, varField, varVal); - return; + return targetId; } - String parentId = currentExecution.getParentId(); - if (oConvertUtils.isEmpty(parentId)) { - runtimeService.setVariableLocal(executionId, varField, varVal); - return; + Execution current = currentExecution; + for (int i = 0; i < level; i++) { + String parentId = current.getParentId(); + if (oConvertUtils.isEmpty(parentId)) { + break; + } + // 先记录 parentId;即使父执行实例查询不到,也保持和旧逻辑一致写到该 parentId。 + targetId = parentId; + Execution parentExecution = runtimeService.createExecutionQuery() + .executionId(parentId) + .singleResult(); + if (parentExecution == null) { + break; + } + current = parentExecution; } + return targetId; + } - Execution parentExecution = runtimeService.createExecutionQuery() - .executionId(parentId) - .singleResult(); - if (parentExecution == null) { - runtimeService.setVariableLocal(parentId, varField, varVal); - return; + private int normalizeParentLevel(Integer parentLevel) { + if (parentLevel == null) { + return 2; } - - String grandParentId = parentExecution.getParentId(); - String targetId = oConvertUtils.isNotEmpty(grandParentId) ? grandParentId : parentId; - - runtimeService.setVariableLocal(targetId, varField, varVal); - log.info("BPM局部变量已存入: targetId={}, varField={}, varVal={}", targetId, varField, varVal); + if (parentLevel < 0) { + throw new IllegalArgumentException("parentLevel不能小于0"); + } + return parentLevel; } } diff --git a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java index f9a36ad..998d42a 100644 --- a/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java +++ b/jeecg-boot-platform/jeecg-boot-module-bpm-flowable/src/main/java/org/jeecg/modules/extbpm/process/common/expression/FlowNodeExpression.java @@ -400,8 +400,14 @@ public class FlowNodeExpression { return splitUsernames(execution.getVariableLocal(variableName)); } + // parentLevel=1 写入时变量挂在当前子流程父级 execution 上,网关读取前先查该作用域。 + Object parentLocalVariable = runtimeService.getVariableLocal(parentExecutionId, variableName); + if (parentLocalVariable != null) { + return splitUsernames(parentLocalVariable); + } + List executions = runtimeService.createExecutionQuery() - .processInstanceId(parentExecutionId) + .parentId(parentExecutionId) .list(); for (Execution childExecution : executions) { if (execution.getId().equals(childExecution.getId())) { @@ -444,8 +450,14 @@ public class FlowNodeExpression { return execution.getVariableLocal(variableName); } + // parentLevel=1 写入时变量挂在当前子流程父级 execution 上,网关读取前先查该作用域。 + Object parentLocalVariable = runtimeService.getVariableLocal(parentExecutionId, variableName); + if (parentLocalVariable != null) { + return parentLocalVariable; + } + List executions = runtimeService.createExecutionQuery() - .processInstanceId(parentExecutionId) + .parentId(parentExecutionId) .list(); for (Execution childExecution : executions) { if (execution.getId().equals(childExecution.getId())) { @@ -465,8 +477,11 @@ public class FlowNodeExpression { } public String getSonProcessHqVariableString(DelegateExecution execution, String variableName) { - if(execution == null || StringUtils.isBlank(variableName) || getSonProcessHqVariableList(execution, variableName).isEmpty()) return StringUtils.EMPTY; - return getSonProcessHqVariableList(execution, variableName).get(0); + List usernames = getSonProcessHqVariableList(execution, variableName); + if (CollectionUtils.isEmpty(usernames)) { + return StringUtils.EMPTY; + } + return usernames.get(0); } /** * Save current task assignee as execution local variable.