Commit b766f8d820a13ec12a25f02485570b7e50a10df2

Authored by YunaiV
1 parent 7ba084bc

fix:【BPM 工作流】子流程支持流程 title 自定义标题

yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmProcessInstanceEventListener.java
1 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener;
2 2  
  3 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
3 4 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
4 5 import com.google.common.collect.ImmutableSet;
5 6 import jakarta.annotation.Resource;
... ... @@ -37,18 +38,26 @@ public class BpmProcessInstanceEventListener extends AbstractFlowableEngineEvent
37 38  
38 39 @Override
39 40 protected void processCreated(FlowableEngineEntityEvent event) {
40   - processInstanceService.processProcessInstanceCreated((ProcessInstance)event.getEntity());
  41 + ProcessInstance processInstance = (ProcessInstance) event.getEntity();
  42 + FlowableUtils.execute(processInstance.getTenantId(),
  43 + () -> processInstanceService.processProcessInstanceCreated(processInstance));
41 44 }
42 45  
43 46 @Override
44 47 protected void processCompleted(FlowableEngineEntityEvent event) {
45   - processInstanceService.processProcessInstanceCompleted((ProcessInstance)event.getEntity());
  48 + ProcessInstance processInstance = (ProcessInstance) event.getEntity();
  49 + FlowableUtils.execute(processInstance.getTenantId(),
  50 + () -> processInstanceService.processProcessInstanceCompleted(processInstance));
46 51 }
47 52  
48   - @Override // 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法
  53 + @Override
49 54 protected void processCancelled(FlowableCancelledEvent event) {
  55 + // 特殊情况:当跳转到 EndEvent 流程实例未结束, 会执行 deleteProcessInstance 方法
50 56 ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getProcessInstanceId());
51   - processInstanceService.processProcessInstanceCompleted(processInstance);
  57 + if (processInstance != null) {
  58 + FlowableUtils.execute(processInstance.getTenantId(),
  59 + () -> processInstanceService.processProcessInstanceCompleted(processInstance));
  60 + }
52 61 }
53 62  
54 63 }
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
... ... @@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.ListUtil;
5 5 import cn.hutool.core.date.DateUtil;
6 6 import cn.hutool.core.lang.Assert;
7   -import cn.hutool.core.util.ArrayUtil;
8   -import cn.hutool.core.util.ObjUtil;
9   -import cn.hutool.core.util.ObjectUtil;
10   -import cn.hutool.core.util.StrUtil;
  7 +import cn.hutool.core.util.*;
11 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
12 9 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
13 10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
... ... @@ -61,6 +58,8 @@ import org.flowable.task.api.history.HistoricTaskInstance;
61 58 import org.springframework.context.annotation.Lazy;
62 59 import org.springframework.stereotype.Service;
63 60 import org.springframework.transaction.annotation.Transactional;
  61 +import org.springframework.transaction.support.TransactionSynchronization;
  62 +import org.springframework.transaction.support.TransactionSynchronizationManager;
64 63 import org.springframework.validation.annotation.Validated;
65 64  
66 65 import java.util.*;
... ... @@ -244,7 +243,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
244 243 if (historicProcessInstance == null) {
245 244 throw exception(ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS);
246 245 }
247   - // 1.3 校验 BpmnModel
  246 + // 1.3 校验BpmnModel
248 247 BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(task.getProcessDefinitionId());
249 248 if (bpmnModel == null) {
250 249 return null;
... ... @@ -449,7 +448,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
449 448 .setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
450 449 .setStartTime(DateUtils.of(activity.getStartTime()))
451 450 .setEndTime(DateUtils.of(activity.getEndTime()))
452   - .setProcessInstanceId(activity.getCalledProcessInstanceId());
  451 + .setProcessInstanceId(activity.getProcessInstanceId());
453 452 approvalNodes.add(callActivity);
454 453 }
455 454 });
... ... @@ -521,7 +520,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
521 520 activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
522 521 }
523 522 if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
524   - activityNode.setProcessInstanceId(firstActivity.getCalledProcessInstanceId());
  523 + activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());
525 524 }
526 525 return activityNode;
527 526 });
... ... @@ -771,17 +770,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
771 770 processInstanceBuilder.predefineProcessInstanceId(processIdRedisDAO.generate(processIdRule));
772 771 }
773 772 // 3.2 流程名称
774   - BpmModelMetaInfoVO.TitleSetting titleSetting = processDefinitionInfo.getTitleSetting();
775   - if (titleSetting != null && Boolean.TRUE.equals(titleSetting.getEnable())) {
776   - AdminUserRespDTO user = adminUserApi.getUser(userId);
777   - Map<String, Object> cloneVariables = new HashMap<>(variables);
778   - cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());
779   - cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());
780   - cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());
781   - processInstanceBuilder.name(StrUtil.format(titleSetting.getTitle(), cloneVariables));
782   - } else {
783   - processInstanceBuilder.name(definition.getName().trim());
784   - }
  773 + processInstanceBuilder.name(generateProcessInstanceName(userId, definition, processDefinitionInfo, variables));
785 774 // 3.3 发起流程实例
786 775 ProcessInstance instance = processInstanceBuilder.start();
787 776 return instance.getId();
... ... @@ -817,6 +806,25 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
817 806 });
818 807 }
819 808  
  809 + private String generateProcessInstanceName(Long userId,
  810 + ProcessDefinition definition,
  811 + BpmProcessDefinitionInfoDO definitionInfo,
  812 + Map<String, Object> variables) {
  813 + if (definition == null || definitionInfo == null) {
  814 + return null;
  815 + }
  816 + BpmModelMetaInfoVO.TitleSetting titleSetting = definitionInfo.getTitleSetting();
  817 + if (titleSetting == null || !BooleanUtil.isTrue(titleSetting.getEnable())) {
  818 + return definition.getName();
  819 + }
  820 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  821 + Map<String, Object> cloneVariables = new HashMap<>(variables);
  822 + cloneVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, user.getNickname());
  823 + cloneVariables.put(BpmnVariableConstants.PROCESS_START_TIME, DateUtil.now());
  824 + cloneVariables.put(BpmnVariableConstants.PROCESS_DEFINITION_NAME, definition.getName().trim());
  825 + return StrUtil.format(definitionInfo.getTitleSetting().getTitle(), cloneVariables);
  826 + }
  827 +
820 828 @Override
821 829 public void cancelProcessInstanceByStartUser(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) {
822 830 // 1.1 校验流程实例存在
... ... @@ -833,7 +841,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
833 841 .getProcessDefinitionInfo(instance.getProcessDefinitionId());
834 842 Assert.notNull(processDefinitionInfo, "流程定义({})不存在", processDefinitionInfo);
835 843 if (processDefinitionInfo.getAllowCancelRunningProcess() != null // 防止未配置 AllowCancelRunningProcess , 默认为可取消
836   - && Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
  844 + && BooleanUtil.isFalse(processDefinitionInfo.getAllowCancelRunningProcess())) {
837 845 throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
838 846 }
839 847 // 1.4 子流程不允许取消
... ... @@ -900,64 +908,77 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
900 908  
901 909 @Override
902 910 public void processProcessInstanceCompleted(ProcessInstance instance) {
903   - // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
904   - FlowableUtils.execute(instance.getTenantId(), () -> {
905   - // 1.1 获取当前状态
906   - Integer status = (Integer) instance.getProcessVariables()
907   - .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
908   - String reason = (String) instance.getProcessVariables()
909   - .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
910   - // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
911   - // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
912   - if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
913   - status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
914   - runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
915   - status);
916   - }
  911 + // 1.1 获取当前状态
  912 + Integer status = (Integer) instance.getProcessVariables()
  913 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
  914 + String reason = (String) instance.getProcessVariables()
  915 + .get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON);
  916 + // 1.2 当流程状态还是审批状态中,说明审批通过了,则变更下它的状态
  917 + // 为什么这么处理?因为流程完成,并且完成了,说明审批通过了
  918 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.RUNNING.getStatus())) {
  919 + status = BpmProcessInstanceStatusEnum.APPROVE.getStatus();
  920 + runtimeService.setVariable(instance.getId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS,
  921 + status);
  922 + }
  923 +
  924 + // 2. 发送对应的消息通知
  925 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
  926 + messageService.sendMessageWhenProcessInstanceApprove(
  927 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
  928 + } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
  929 + messageService.sendMessageWhenProcessInstanceReject(
  930 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
  931 + }
  932 +
  933 + // 3. 发送流程实例的状态事件
  934 + processInstanceEventPublisher.sendProcessInstanceResultEvent(
  935 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));
  936 +
  937 + // 4. 流程后置通知
  938 + if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
  939 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
  940 + getProcessDefinitionInfo(instance.getProcessDefinitionId());
  941 + if (ObjUtil.isNotNull(processDefinitionInfo) &&
  942 + ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
  943 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
917 944  
918   - // 2. 发送对应的消息通知
919   - if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
920   - messageService.sendMessageWhenProcessInstanceApprove(
921   - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceApproveMessage(instance));
922   - } else if (Objects.equals(status, BpmProcessInstanceStatusEnum.REJECT.getStatus())) {
923   - messageService.sendMessageWhenProcessInstanceReject(
924   - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceRejectMessage(instance, reason));
  945 + BpmHttpRequestUtils.executeBpmHttpRequest(instance,
  946 + setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
925 947 }
  948 + }
  949 + }
926 950  
927   - // 3. 发送流程实例的状态事件
928   - processInstanceEventPublisher.sendProcessInstanceResultEvent(
929   - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status));
  951 + @Override
  952 + public void processProcessInstanceCreated(ProcessInstance instance) {
  953 + BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
  954 + getProcessDefinitionInfo(instance.getProcessDefinitionId());
  955 + ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(instance.getProcessDefinitionId());
  956 + if (processDefinition == null || processDefinitionInfo == null) {
  957 + return;
  958 + }
930 959  
931   - // 4. 流程后置通知
932   - if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
933   - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
934   - getProcessDefinitionInfo(instance.getProcessDefinitionId());
935   - if (ObjUtil.isNotNull(processDefinitionInfo) &&
936   - ObjUtil.isNotNull(processDefinitionInfo.getProcessAfterTriggerSetting())) {
937   - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessAfterTriggerSetting();
  960 + // 自定义标题。目的:主要处理子流程的标题无法处理
  961 + // 注意:必须使用 TransactionSynchronizationManager 事务提交后,否则不生效!!!
  962 + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
938 963  
939   - BpmHttpRequestUtils.executeBpmHttpRequest(instance,
940   - setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
  964 + @Override
  965 + public void afterCommit() {
  966 + String name = generateProcessInstanceName(Long.valueOf(instance.getStartUserId()),
  967 + processDefinition, processDefinitionInfo, instance.getProcessVariables());
  968 + if (ObjUtil.notEqual(instance.getName(), name)) {
  969 + runtimeService.setProcessInstanceName(instance.getProcessInstanceId(), name);
941 970 }
942 971 }
943   - });
944   - }
945 972  
946   - @Override
947   - public void processProcessInstanceCreated(ProcessInstance instance) {
948   - // 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
949   - FlowableUtils.execute(instance.getTenantId(), () -> {
950   - // 流程前置通知
951   - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.
952   - getProcessDefinitionInfo(instance.getProcessDefinitionId());
953   - if (ObjUtil.isNull(processDefinitionInfo) ||
954   - ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
955   - return;
956   - }
957   - BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
958   - BpmHttpRequestUtils.executeBpmHttpRequest(instance,
959   - setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
960 973 });
  974 +
  975 + // 流程前置通知
  976 + if (ObjUtil.isNull(processDefinitionInfo.getProcessBeforeTriggerSetting())) {
  977 + return;
  978 + }
  979 + BpmModelMetaInfoVO.HttpRequestSetting setting = processDefinitionInfo.getProcessBeforeTriggerSetting();
  980 + BpmHttpRequestUtils.executeBpmHttpRequest(instance,
  981 + setting.getUrl(), setting.getHeader(), setting.getBody(), true, setting.getResponse());
961 982 }
962 983  
963 984 }
... ...