fix:【BPM 工作流】子流程支持流程 title 自定义标题
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -37,18 +38,26 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processCreated(FlowableEngineEntityEvent event) {
|
protected void processCreated(FlowableEngineEntityEvent event) {
|
||||||
processInstanceService.processProcessInstanceCreated((ProcessInstance)event.getEntity());
|
ProcessInstance processInstance = (ProcessInstance) event.getEntity();
|
||||||
|
FlowableUtils.execute(processInstance.getTenantId(),
|
||||||
|
() -> processInstanceService.processProcessInstanceCreated(processInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processCompleted(FlowableEngineEntityEvent event) {
|
protected void processCompleted(FlowableEngineEntityEvent event) {
|
||||||
processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
|
ProcessInstance processInstance = (ProcessInstance) event.getEntity();
|
||||||
|
FlowableUtils.execute(processInstance.getTenantId(),
|
||||||
|
() -> processInstanceService.processProcessInstanceCompleted(processInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法
|
@Override
|
||||||
protected void processCancelled(FlowableCancelledEvent event) {
|
protected void processCancelled(FlowableCancelledEvent event) {
|
||||||
|
// 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法
|
||||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getProcessInstanceId());
|
ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getProcessInstanceId());
|
||||||
processInstanceService.processProcessInstanceCompleted(processInstance);
|
if (processInstance != null) {
|
||||||
|
FlowableUtils.execute(processInstance.getTenantId(),
|
||||||
|
() -> processInstanceService.processProcessInstanceCompleted(processInstance));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.*;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
@@ -61,6 +58,8 @@ import org.flowable.task.api.history.HistoricTaskInstance;
|
|||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -449,7 +448,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
.setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
|
.setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
|
||||||
.setStartTime(DateUtils.of(activity.getStartTime()))
|
.setStartTime(DateUtils.of(activity.getStartTime()))
|
||||||
.setEndTime(DateUtils.of(activity.getEndTime()))
|
.setEndTime(DateUtils.of(activity.getEndTime()))
|
||||||
.setProcessInstanceId(activity.getCalledProcessInstanceId());
|
.setProcessInstanceId(activity.getProcessInstanceId());
|
||||||
approvalNodes.add(callActivity);
|
approvalNodes.add(callActivity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -521,7 +520,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
|
activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
|
||||||
}
|
}
|
||||||
if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
|
if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
|
||||||
activityNode.setProcessInstanceId(firstActivity.getCalledProcessInstanceId());
|
activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());
|
||||||
}
|
}
|
||||||
return activityNode;
|
return activityNode;
|
||||||
});
|
});
|
||||||
@@ -771,17 +770,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));
|
processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));
|
||||||
}
|
}
|
||||||
// 3.2 流程名称
|
// 3.2 流程名称
|
||||||
BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting();
|
processInstanceBuilder.name(generateProcessInstanceName(userId, definition, processDefinitionInfo, variables));
|
||||||
if (titleSetting != null && Boolean.TRUE.equals(titleSetting.getEnable())) {
|
|
||||||
AdminUserRespDTO user = adminUserApi.getUser(userId);
|
|
||||||
Map<String, Object> cloneVariables = new HashMap<>(variables);
|
|
||||||
cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());
|
|
||||||
cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());
|
|
||||||
cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());
|
|
||||||
processInstanceBuilder.name(StrUtil.format(titleSetting.getTitle(), cloneVariables));
|
|
||||||
} else {
|
|
||||||
processInstanceBuilder.name(definition.getName().trim());
|
|
||||||
}
|
|
||||||
// 3.3 发起流程实例
|
// 3.3 发起流程实例
|
||||||
ProcessInstance instance = processInstanceBuilder.start();
|
ProcessInstance instance = processInstanceBuilder.start();
|
||||||
return instance.getId();
|
return instance.getId();
|
||||||
@@ -817,6 +806,25 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String generateProcessInstanceName(Long userId,
|
||||||
|
ProcessDefinition definition,
|
||||||
|
BpmProcessDefinitionInfoDO definitionInfo,
|
||||||
|
Map<String, Object> variables) {
|
||||||
|
if (definition == null || definitionInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BpmModelMetaInfoVO.TitleSetting titleSetting = definitionInfo.getTitleSetting();
|
||||||
|
if (titleSetting == null || !BooleanUtil.isTrue(titleSetting.getEnable())) {
|
||||||
|
return definition.getName();
|
||||||
|
}
|
||||||
|
AdminUserRespDTO user = adminUserApi.getUser(userId);
|
||||||
|
Map<String, Object> cloneVariables = new HashMap<>(variables);
|
||||||
|
cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());
|
||||||
|
cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());
|
||||||
|
cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());
|
||||||
|
return StrUtil.format(definitionInfo.getTitleSetting().getTitle(), cloneVariables);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
|
public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
|
||||||
// 1.1 校验流程实例存在
|
// 1.1 校验流程实例存在
|
||||||
@@ -833,7 +841,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
.getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
.getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
||||||
Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
|
Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
|
||||||
if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
|
if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
|
||||||
&& Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
|
&& BooleanUtil.isFalse(processDefinitionInfo.getAllowCancelRunningProcess())) {
|
||||||
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
|
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
|
||||||
}
|
}
|
||||||
// 1.4 子流程不允许取消
|
// 1.4 子流程不允许取消
|
||||||
@@ -900,8 +908,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processProcessInstanceCompleted(ProcessInstance instance) {
|
public void processProcessInstanceCompleted(ProcessInstance instance) {
|
||||||
// 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
|
|
||||||
FlowableUtils.execute(instance.getTenantId(), () -> {
|
|
||||||
// 1.1 获取当前状态
|
// 1.1 获取当前状态
|
||||||
Integer status = (Integer) instance.getProcessVariables()
|
Integer status = (Integer) instance.getProcessVariables()
|
||||||
.get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
.get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
||||||
@@ -940,24 +946,39 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|||||||
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processProcessInstanceCreated(ProcessInstance instance) {
|
public void processProcessInstanceCreated(ProcessInstance instance) {
|
||||||
// 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
|
|
||||||
FlowableUtils.execute(instance.getTenantId(), () -> {
|
|
||||||
// 流程前置通知
|
|
||||||
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
||||||
getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
||||||
if (ObjUtil.isNull(processDefinitionInfo) ||
|
ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(instance.getProcessDefinitionId());
|
||||||
ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
|
if (processDefinition == null || processDefinitionInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义标题。目的:主要处理子流程的标题无法处理
|
||||||
|
// 注意:必须使用 TransactionSynchronizationManager 事务提交后,否则不生效!!!
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
String name = generateProcessInstanceName(Long.valueOf(instance.getStartUserId()),
|
||||||
|
processDefinition, processDefinitionInfo, instance.getProcessVariables());
|
||||||
|
if (ObjUtil.notEqual(instance.getName(), name)) {
|
||||||
|
runtimeService.setProcessInstanceName(instance.getProcessInstanceId(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 流程前置通知
|
||||||
|
if (ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
|
BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
|
||||||
BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
||||||
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user