场景:对已结束流程的变量进行改动
方法包含2个类
1)核心方法,flowable command类:HistoricVariablesUpdateCmd
2)执行command类:BpmProcessCommandService
然后springboot 执行方法即可: bpmProcessCommandService.executeUpdateHistoricVariables(processInstanceId, 变量集合map);
注:@AllArgsConstructor 来自 lombok 注解,其中工具类来自 hutool;这里就不做过多介绍;
实现 flowable command类
注:代码中 FlowableUtils.getProcessInstanceStatus 这里为自己定义的状态机制,用于判断流程是正在运行的;
若流程处于运行,则直接调用内置接口修改变量;你也可以删掉此实现;
package com.flowable.core.cmd;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.core.util.FlowableUtils;
import com.flowable.process.enums.task.ProcessInstanceStatusEnum;
import lombok.AllArgsConstructor;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.flowable.variable.api.types.VariableType;
import org.flowable.variable.service.VariableServiceConfiguration;
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntityImpl;
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntityManager;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntityImpl;
import java.util.Map;
/**
* 历史任务变量更新
*/
@AllArgsConstructor
public class HistoricVariablesUpdateCmd implements Command {
// 流程实例ID
protected String processInstanceId;
// 变量集合
Map variables;
@Override
public Void execute(CommandContext commandContext) {
// processInstanceId 参数不能为空
if (ObjectUtil.isNull(this.processInstanceId)) {
throw new FlowableIllegalArgumentException("流程实例编号不能为空!");
}
// variables 参数不能为空
if (CollUtil.isEmpty(variables)) {
throw new FlowableIllegalArgumentException("修改的表单内容不能为空!");
}
// 1 获取运历史服务、历史变量管理器、变量管理器
ProcessEngineConfigurationImpl procEngineConf = CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoryService historyService = procEngineConf.getHistoryService();
RuntimeService runtimeService = procEngineConf.getRuntimeService();
HistoricVariableInstanceEntityManager historicVariableInstanceEntityManager = procEngineConf.getVariableServiceConfiguration().getHistoricVariableInstanceEntityManager();
VariableServiceConfiguration variableServiceConfiguration = procEngineConf.getVariableServiceConfiguration().getVariableServiceConfiguration();
// 2 根据流程实例id,查询流程
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(this.processInstanceId)
.includeProcessVariables()
.singleResult();
// 3 如果流程是正在运行,则直接修改流程表单数据
Integer processInstanceStatus = FlowableUtils.getProcessInstanceStatus(historicProcessInstance);
if (ProcessInstanceStatusEnum.RUNNING.getCode().equals(processInstanceStatus)) {
runtimeService.setVariables(this.processInstanceId, this.variables);
return null;
}
for (Map.Entry entry : variables.entrySet()) {
String variableName = entry.getKey();
Object variableValue = entry.getValue();
// 4 查询是否存在历史变量是否存在
HistoricVariableInstance hisVariable = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(this.processInstanceId)
.excludeLocalVariables() //排除本地变量
.variableName(variableName)
.singleResult();
if (ObjectUtil.isNotNull(hisVariable)) {
// 4 根据当前变量,修改历史变量的值
HistoricVariableInstanceEntityImpl historicVariableImpl = (HistoricVariableInstanceEntityImpl) hisVariable;
VariableInstanceEntityImpl variableInstanceEntity = createVariable(historicProcessInstance, variableName, variableValue, variableServiceConfiguration);
historicVariableInstanceEntityManager.copyVariableFields(historicVariableImpl, variableInstanceEntity, DateUtil.date());
historicVariableInstanceEntityManager.update(historicVariableImpl);
} else {
// 5 新增历史变量
VariableInstanceEntityImpl variableInstanceEntity = createVariable(historicProcessInstance, variableName, variableValue, variableServiceConfiguration);
historicVariableInstanceEntityManager.createAndInsert(variableInstanceEntity, DateUtil.date());
}
}
return null;
}
/**
* 根据变量名 和变量值,构建变量
*
* @param historicProcessInstance 流程实例
* @param variableName 流程变量名
* @param variableValue 流程值
* @param variableServiceConfiguration 变量配置
* @return 流程变量
*/
private VariableInstanceEntityImpl createVariable(HistoricProcessInstance historicProcessInstance, String variableName, Object variableValue
, VariableServiceConfiguration variableServiceConfiguration) {
VariableInstanceEntityImpl variableInstanceEntity = new VariableInstanceEntityImpl();
variableInstanceEntity.setName(variableName);
variableInstanceEntity.setProcessInstanceId(historicProcessInstance.getId());
variableInstanceEntity.setExecutionId(historicProcessInstance.getId());
VariableType variableType = variableServiceConfiguration.getVariableTypes().findVariableType(variableValue);
variableInstanceEntity.setTypeName(variableType.getTypeName());
variableInstanceEntity.setType(variableType);
variableInstanceEntity.setValue(variableValue);
return variableInstanceEntity;
}
}
执行command 需要注入 ManagementService
package com.flowable.core.service;
import com.flowable.core.cmd.HistoricTaskSingleVariableUpdateCmd;
import jakarta.annotation.Resource;
import org.flowable.engine.ManagementService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BpmProcessCommandService {
@Resource
private ManagementService managementService;
/**
* 更新历史流程变量
*
* @param processInstanceId 历史流程实例id
* @param variables 表单变量
*/
public void executeUpdateHistoricVariables(String processInstanceId, Map variables) {
// 实例化 跟新历史流程变量 command 类
HistoricVariablesUpdateCmd historicVariablesUpdateCmd = new HistoricVariablesUpdateCmd(processInstanceId, variables);
// 通过 managementService 管理服务,执行 跟新历史流程变量 command 类
managementService.executeCommand(historicVariablesUpdateCmd);
}
}
然后springboot 正常调用该方法即可
bpmProcessCommandService.executeUpdateHistoricVariables(processInstanceId, 变量集合map);