|
|
@@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.collection.ListUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.lang.Assert;
|
|
|
-import cn.hutool.core.util.ArrayUtil;
|
|
|
-import cn.hutool.core.util.ObjUtil;
|
|
|
-import cn.hutool.core.util.ObjectUtil;
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.core.util.*;
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
|
|
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.stereotype.Service;
|
|
|
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 java.util.*;
|
|
|
@@ -244,7 +243,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
if (historicProcessInstance == null) {
|
|
|
throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
|
|
|
}
|
|
|
- // 1.3 校验 BpmnModel
|
|
|
+ // 1.3 校验BpmnModel
|
|
|
BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());
|
|
|
if (bpmnModel == null) {
|
|
|
return null;
|
|
|
@@ -449,7 +448,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
.setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
|
|
|
.setStartTime(DateUtils.of(activity.getStartTime()))
|
|
|
.setEndTime(DateUtils.of(activity.getEndTime()))
|
|
|
- .setProcessInstanceId(activity.getCalledProcessInstanceId());
|
|
|
+ .setProcessInstanceId(activity.getProcessInstanceId());
|
|
|
approvalNodes.add(callActivity);
|
|
|
}
|
|
|
});
|
|
|
@@ -521,7 +520,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
|
|
|
}
|
|
|
if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
|
|
|
- activityNode.setProcessInstanceId(firstActivity.getCalledProcessInstanceId());
|
|
|
+ activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());
|
|
|
}
|
|
|
return activityNode;
|
|
|
});
|
|
|
@@ -771,17 +770,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));
|
|
|
}
|
|
|
// 3.2 流程名称
|
|
|
- BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting();
|
|
|
- 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());
|
|
|
- }
|
|
|
+ processInstanceBuilder.name(generateProcessInstanceName(userId, definition, processDefinitionInfo, variables));
|
|
|
// 3.3 发起流程实例
|
|
|
ProcessInstance instance = processInstanceBuilder.start();
|
|
|
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
|
|
|
public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
|
|
|
// 1.1 校验流程实例存在
|
|
|
@@ -833,7 +841,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
.getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
|
|
Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
|
|
|
if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
|
|
|
- && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
|
|
|
+ && BooleanUtil.isFalse(processDefinitionInfo.getAllowCancelRunningProcess())) {
|
|
|
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
|
|
|
}
|
|
|
// 1.4 子流程不允许取消
|
|
|
@@ -900,64 +908,77 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
|
|
|
|
|
@Override
|
|
|
public void processProcessInstanceCompleted(ProcessInstance instance) {
|
|
|
- // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
|
|
|
- FlowableUtils.execute(instance.getTenantId(), () -> {
|
|
|
- // 1.1 获取当前状态
|
|
|
- Integer status = (Integer) instance.getProcessVariables()
|
|
|
- .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
|
|
- String reason = (String) instance.getProcessVariables()
|
|
|
- .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
|
|
|
- // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
|
|
|
- // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
|
|
|
- if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
|
|
|
- status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
|
|
|
- runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
|
|
|
- status);
|
|
|
- }
|
|
|
+ // 1.1 获取当前状态
|
|
|
+ Integer status = (Integer) instance.getProcessVariables()
|
|
|
+ .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
|
|
+ String reason = (String) instance.getProcessVariables()
|
|
|
+ .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
|
|
|
+ // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
|
|
|
+ // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
|
|
|
+ if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
|
|
|
+ status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
|
|
|
+ runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
|
|
|
+ status);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 发送对应的消息通知
|
|
|
+ if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
|
|
|
+ messageService.sendMessageWhenProcessInstanceApprove(
|
|
|
+ BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
|
|
|
+ } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
|
|
|
+ messageService.sendMessageWhenProcessInstanceReject(
|
|
|
+ BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 发送流程实例的状态事件
|
|
|
+ processInstanceEventPublisher.sendProcessInstanceResultEvent(
|
|
|
+ BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));
|
|
|
+
|
|
|
+ // 4. 流程后置通知
|
|
|
+ if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
|
|
|
+ BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
|
|
+ getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
|
|
+ if (ObjUtil.isNotNull(processDefinitionInfo) &&
|
|
|
+ ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
|
|
|
+ BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
|
|
|
|
|
|
- // 2. 发送对应的消息通知
|
|
|
- if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
|
|
|
- messageService.sendMessageWhenProcessInstanceApprove(
|
|
|
- BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
|
|
|
- } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
|
|
|
- messageService.sendMessageWhenProcessInstanceReject(
|
|
|
- BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
|
|
|
+ BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
|
|
+ setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 3. 发送流程实例的状态事件
|
|
|
- processInstanceEventPublisher.sendProcessInstanceResultEvent(
|
|
|
- BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));
|
|
|
+ @Override
|
|
|
+ public void processProcessInstanceCreated(ProcessInstance instance) {
|
|
|
+ BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
|
|
+ getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
|
|
+ ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(instance.getProcessDefinitionId());
|
|
|
+ if (processDefinition == null || processDefinitionInfo == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // 4. 流程后置通知
|
|
|
- if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
|
|
|
- BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
|
|
- getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
|
|
- if (ObjUtil.isNotNull(processDefinitionInfo) &&
|
|
|
- ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
|
|
|
- BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
|
|
|
+ // 自定义标题。目的:主要处理子流程的标题无法处理
|
|
|
+ // 注意:必须使用 TransactionSynchronizationManager 事务提交后,否则不生效!!!
|
|
|
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
|
|
|
- BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
|
|
- setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
|
|
+ @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);
|
|
|
}
|
|
|
}
|
|
|
- });
|
|
|
- }
|
|
|
|
|
|
- @Override
|
|
|
- public void processProcessInstanceCreated(ProcessInstance instance) {
|
|
|
- // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
|
|
|
- FlowableUtils.execute(instance.getTenantId(), () -> {
|
|
|
- // 流程前置通知
|
|
|
- BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
|
|
|
- getProcessDefinitionInfo(instance.getProcessDefinitionId());
|
|
|
- if (ObjUtil.isNull(processDefinitionInfo) ||
|
|
|
- ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
|
|
|
- BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
|
|
- setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
|
|
});
|
|
|
+
|
|
|
+ // 流程前置通知
|
|
|
+ if (ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
|
|
|
+ BpmHttpRequestUtils.executeBpmHttpRequest(instance,
|
|
|
+ setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
|
|
|
}
|
|
|
|
|
|
}
|