feat(bpm): 新增流程变量本地服务及完善 XiSpeak 流程相关功能
- 新增 BpmVariableLocalService 流程变量本地服务接口及实现 - XiSpeakFlow 完善流程变量读取逻辑 - ActProcessController 流程控制器功能增强 - FlowNodeExpression 扩展表达式能力 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -194,6 +194,25 @@ public class XiSpeakFlow {
|
|||||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplWorkerKey()).size();
|
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplWorkerKey()).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程表达式内用法: ${xiSpeakFlow.getIsEnd(execution)}
|
||||||
|
*/
|
||||||
|
public int getIsEnd(DelegateExecution execution) {
|
||||||
|
Object value = flowNodeExpression.getSonProcessHqVariable(execution, "isEnd");
|
||||||
|
if (value == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(String.valueOf(value));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("isEnd变量值无法解析为int: {}", value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程表达式内用法: ${xiSpeakFlow.getTemImplLeaderList(execution)}
|
* 流程表达式内用法: ${xiSpeakFlow.getTemImplLeaderList(execution)}
|
||||||
*/
|
*/
|
||||||
@@ -222,6 +241,13 @@ public class XiSpeakFlow {
|
|||||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemBgLeaderKey()).size();
|
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemBgLeaderKey()).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeaderListLength(execution)}
|
||||||
|
*/
|
||||||
|
public int getImplDeptLeaderIsEnd(DelegateExecution execution) {
|
||||||
|
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemBgLeaderKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeader(execution)}
|
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeader(execution)}
|
||||||
|
|||||||
+21
@@ -19,6 +19,7 @@ import org.jeecg.common.util.RedisUtil;
|
|||||||
import org.jeecg.common.util.TokenUtils;
|
import org.jeecg.common.util.TokenUtils;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
import org.jeecg.modules.bpm.dto.ProcessVariableDTO;
|
import org.jeecg.modules.bpm.dto.ProcessVariableDTO;
|
||||||
|
import org.jeecg.modules.bpm.service.BpmVariableLocalService;
|
||||||
import org.jeecg.modules.bpm.service.impl.ActProcessService;
|
import org.jeecg.modules.bpm.service.impl.ActProcessService;
|
||||||
import org.jeecg.modules.extbpm.process.service.IExtActProcessService;
|
import org.jeecg.modules.extbpm.process.service.IExtActProcessService;
|
||||||
import org.jeecg.modules.extbpm.util.CommonRandomUtil;
|
import org.jeecg.modules.extbpm.util.CommonRandomUtil;
|
||||||
@@ -57,6 +58,8 @@ public class ActProcessController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TaskService taskService;
|
private TaskService taskService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private BpmVariableLocalService bpmVariableLocalService;
|
||||||
|
@Autowired
|
||||||
private ActProcessService actProcessService;
|
private ActProcessService actProcessService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IExtActProcessService extActProcessService;
|
private IExtActProcessService extActProcessService;
|
||||||
@@ -115,6 +118,24 @@ public class ActProcessController {
|
|||||||
return Result.OK("保存成功");
|
return Result.OK("保存成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/setBpmVariableLocal")
|
||||||
|
@Operation(summary = "设置局部流程变量(向上追溯2层父级执行实例)")
|
||||||
|
public Result<String> setBpmVariableLocal(@RequestBody ProcessVariableDTO dto) {
|
||||||
|
if (dto == null || oConvertUtils.isEmpty(dto.getTaskId())) {
|
||||||
|
return Result.error("任务ID不能为空");
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(dto.getVarField())) {
|
||||||
|
return Result.error("流程变量名不能为空");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bpmVariableLocalService.setVariableLocal(dto.getTaskId(), dto.getVarField(), dto.getVarVal());
|
||||||
|
return Result.OK("保存成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("设置BPM局部变量失败", e);
|
||||||
|
return Result.error("保存失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("deploy")
|
@PostMapping("deploy")
|
||||||
@Operation(summary = "部署流程文件")
|
@Operation(summary = "部署流程文件")
|
||||||
public Result deploy(@RequestParam("processFile") MultipartFile file) throws IOException {
|
public Result deploy(@RequestParam("processFile") MultipartFile file) throws IOException {
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package org.jeecg.modules.bpm.service;
|
||||||
|
|
||||||
|
public interface BpmVariableLocalService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将变量存入向上追溯2层的父级执行实例中(与 AfterImplWorkerTemStoreListener 逻辑一致)
|
||||||
|
*
|
||||||
|
* @param taskId 当前任务ID
|
||||||
|
* @param varField 变量名
|
||||||
|
* @param varVal 变量值
|
||||||
|
*/
|
||||||
|
void setVariableLocal(String taskId, String varField, Object varVal);
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package org.jeecg.modules.bpm.service.impl;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.engine.RuntimeService;
|
||||||
|
import org.flowable.engine.TaskService;
|
||||||
|
import org.flowable.engine.runtime.Execution;
|
||||||
|
import org.flowable.task.api.Task;
|
||||||
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.bpm.service.BpmVariableLocalService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||||
|
public class BpmVariableLocalServiceImpl implements BpmVariableLocalService {
|
||||||
|
|
||||||
|
private final RuntimeService runtimeService;
|
||||||
|
private final TaskService taskService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVariableLocal(String taskId, String varField, Object varVal) {
|
||||||
|
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalArgumentException("任务ID不存在: " + taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
String executionId = task.getExecutionId();
|
||||||
|
|
||||||
|
Execution currentExecution = runtimeService.createExecutionQuery()
|
||||||
|
.executionId(executionId)
|
||||||
|
.singleResult();
|
||||||
|
if (currentExecution == null) {
|
||||||
|
runtimeService.setVariableLocal(executionId, varField, varVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parentId = currentExecution.getParentId();
|
||||||
|
if (oConvertUtils.isEmpty(parentId)) {
|
||||||
|
runtimeService.setVariableLocal(executionId, varField, varVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Execution parentExecution = runtimeService.createExecutionQuery()
|
||||||
|
.executionId(parentId)
|
||||||
|
.singleResult();
|
||||||
|
if (parentExecution == null) {
|
||||||
|
runtimeService.setVariableLocal(parentId, varField, varVal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -427,6 +427,43 @@ public class FlowNodeExpression {
|
|||||||
return this.getSonProcessHqVariableList(execution,variableName).size();
|
return this.getSonProcessHqVariableList(execution,variableName).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取子流程原始变量值(不经过 splitUsernames 逗号分割),适用于非列表类型的变量。
|
||||||
|
* 遍历逻辑与 getSonProcessHqVariableList 一致。
|
||||||
|
*/
|
||||||
|
public Object getSonProcessHqVariable(DelegateExecution execution, String variableName) {
|
||||||
|
if (execution == null || StringUtils.isBlank(variableName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String parentExecutionId = execution.getParentId();
|
||||||
|
if (StringUtils.isBlank(parentExecutionId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (execution.hasVariableLocal(variableName)) {
|
||||||
|
return execution.getVariableLocal(variableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Execution> executions = runtimeService.createExecutionQuery()
|
||||||
|
.processInstanceId(parentExecutionId)
|
||||||
|
.list();
|
||||||
|
for (Execution childExecution : executions) {
|
||||||
|
if (execution.getId().equals(childExecution.getId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object localVariable = runtimeService.getVariableLocal(childExecution.getId(), variableName);
|
||||||
|
if (localVariable != null) {
|
||||||
|
return localVariable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return execution.getVariable(variableName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("getSonProcessHqVariable failed, executionId={}, variableName={}",
|
||||||
|
execution.getId(), variableName, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getSonProcessHqVariableString(DelegateExecution execution, String variableName) {
|
public String getSonProcessHqVariableString(DelegateExecution execution, String variableName) {
|
||||||
if(execution == null || StringUtils.isBlank(variableName) || getSonProcessHqVariableList(execution, variableName).isEmpty()) return StringUtils.EMPTY;
|
if(execution == null || StringUtils.isBlank(variableName) || getSonProcessHqVariableList(execution, variableName).isEmpty()) return StringUtils.EMPTY;
|
||||||
return getSonProcessHqVariableList(execution, variableName).get(0);
|
return getSonProcessHqVariableList(execution, variableName).get(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user