fix:【bpm 工作流】跨进程调用,无法回调 crm 的工作流结果的问题
parent
b46f29e45f
commit
8eea97add4
|
@ -15,6 +15,7 @@ import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigu
|
|||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -124,6 +125,7 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
|
|||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@LoadBalanced
|
||||
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
||||
return restTemplateBuilder.build();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,11 @@ public class BpmProcessInstanceStatusEvent extends ApplicationEvent {
|
|||
*/
|
||||
private String businessKey;
|
||||
|
||||
public BpmProcessInstanceStatusEvent() {
|
||||
// new Object() 保证非空
|
||||
super(new Object());
|
||||
}
|
||||
|
||||
public BpmProcessInstanceStatusEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_EXISTS = new ErrorCode(1_009_004_004, "任务({})的候选人({})不存在");
|
||||
ErrorCode PROCESS_INSTANCE_START_USER_CAN_START = new ErrorCode(1_009_004_005, "发起流程失败,你没有权限发起该流程");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_005, "流程取消失败,该流程不允许取消");
|
||||
ErrorCode PROCESS_INSTANCE_HTTP_TRIGGER_CALL_ERROR = new ErrorCode(1_009_004_006, "流程 Http 触发器请求调用失败");
|
||||
ErrorCode PROCESS_INSTANCE_HTTP_CALL_ERROR = new ErrorCode(1_009_004_006, "流程 Http 请求调用失败");
|
||||
ErrorCode PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG = new ErrorCode(1_009_004_007, "下一个任务({})的审批人未配置");
|
||||
ErrorCode PROCESS_INSTANCE_CANCEL_CHILD_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_008, "子流程取消失败,子流程不允许取消");
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.bpm.api.event;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* 回款审批的结果的监听器实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class CrmReceivableStatusListener extends BpmProcessInstanceStatusEventListener {
|
||||
|
||||
@Override
|
||||
public String getProcessDefinitionKey() {
|
||||
return "crm-receivable-audit";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(@RequestBody @Valid BpmProcessInstanceStatusEvent event) {
|
||||
BpmHttpRequestUtils.executeBpmHttpRequest(event,
|
||||
"http://crm-server/rpc-api/crm/receivable/update-audit-status");
|
||||
}
|
||||
|
||||
}
|
|
@ -6,15 +6,15 @@ import cn.iocoder.yudao.framework.common.core.KeyValue;
|
|||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmHttpRequestParamTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
|
@ -26,7 +26,7 @@ import java.util.Map;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_HTTP_TRIGGER_CALL_ERROR;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_HTTP_CALL_ERROR;
|
||||
|
||||
/**
|
||||
* 工作流发起 HTTP 请求工具类
|
||||
|
@ -42,7 +42,6 @@ public class BpmHttpRequestUtils {
|
|||
List<BpmSimpleModelNodeVO.HttpRequestParam> bodyParams,
|
||||
Boolean handleResponse,
|
||||
List<KeyValue<String, String>> response) {
|
||||
RestTemplate restTemplate = SpringUtils.getBean(RestTemplate.class);
|
||||
BpmProcessInstanceService processInstanceService = SpringUtils.getBean(BpmProcessInstanceService.class);
|
||||
|
||||
// 1.1 设置请求头
|
||||
|
@ -51,6 +50,7 @@ public class BpmHttpRequestUtils {
|
|||
MultiValueMap<String, String> body = buildHttpBody(processInstance, bodyParams);
|
||||
|
||||
// 2. 发起请求
|
||||
RestTemplate restTemplate = SpringUtils.getBean(RestTemplate.class);
|
||||
ResponseEntity<String> responseEntity = sendHttpRequest(url, headers, body, restTemplate);
|
||||
|
||||
// 3. 处理返回
|
||||
|
@ -78,27 +78,55 @@ public class BpmHttpRequestUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void executeBpmHttpRequest(BpmProcessInstanceStatusEvent event,
|
||||
String url) {
|
||||
// 1.1 设置请求头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
if (TenantContextHolder.getTenantId() != null) {
|
||||
headers.add(HEADER_TENANT_ID, String.valueOf(TenantContextHolder.getTenantId()));
|
||||
} else {
|
||||
BpmProcessInstanceService processInstanceService = SpringUtils.getBean(BpmProcessInstanceService.class);
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(event.getId());
|
||||
if (processInstance != null) {
|
||||
headers.add(HEADER_TENANT_ID, String.valueOf(TenantContextHolder.getTenantId()));
|
||||
}
|
||||
}
|
||||
// 1.2 设置请求体
|
||||
// MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
|
||||
// body.add("id", event.getId());
|
||||
// body.add("processDefinitionKey", event.getProcessDefinitionKey());
|
||||
// body.add("status", event.getStatus().toString());
|
||||
// if (StrUtil.isNotEmpty(event.getBusinessKey())) {
|
||||
// body.add("businessKey", event.getBusinessKey());
|
||||
// }
|
||||
|
||||
// 2. 发起请求
|
||||
RestTemplate restTemplate = SpringUtils.getBean(RestTemplate.class);
|
||||
sendHttpRequest(url, headers, event, restTemplate);
|
||||
}
|
||||
|
||||
public static ResponseEntity<String> sendHttpRequest(String url,
|
||||
MultiValueMap<String, String> headers,
|
||||
MultiValueMap<String, String> body,
|
||||
Object body,
|
||||
RestTemplate restTemplate) {
|
||||
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
|
||||
HttpEntity<Object> requestEntity = new HttpEntity<>(body, headers);
|
||||
ResponseEntity<String> responseEntity;
|
||||
try {
|
||||
responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
|
||||
log.info("[sendHttpRequest][HTTP 触发器,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity);
|
||||
log.info("[sendHttpRequest][HTTP 请求,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity);
|
||||
} catch (RestClientException e) {
|
||||
log.error("[sendHttpRequest][HTTP 触发器,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage());
|
||||
throw exception(PROCESS_INSTANCE_HTTP_TRIGGER_CALL_ERROR);
|
||||
log.error("[sendHttpRequest][HTTP 请求,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage());
|
||||
throw exception(PROCESS_INSTANCE_HTTP_CALL_ERROR);
|
||||
}
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
public static MultiValueMap<String, String> buildHttpHeaders(ProcessInstance processInstance,
|
||||
List<BpmSimpleModelNodeVO.HttpRequestParam> headerSettings) {
|
||||
Map<String, Object> processVariables = processInstance.getProcessVariables();
|
||||
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
headers.add(HEADER_TENANT_ID, processInstance.getTenantId());
|
||||
Map<String, Object> processVariables = processInstance.getProcessVariables();
|
||||
addHttpRequestParam(headers, headerSettings, processVariables);
|
||||
return headers;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cn.iocoder.yudao.module.bpm.framework.rpc.config;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.api.event.CrmReceivableStatusListener;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
||||
|
@ -7,11 +8,22 @@ import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
|||
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
|
||||
import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(value = "bpmRpcConfiguration", proxyBeanMethods = false)
|
||||
@EnableFeignClients(clients = {RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class,
|
||||
PermissionApi.class})
|
||||
public class RpcConfiguration {
|
||||
|
||||
// ========== 特殊:解决微 yudao-cloud 微服务场景下,跨服务(进程)无法 Listener 的问题 ==========
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "crmReceivableStatusListener")
|
||||
public CrmReceivableStatusListener crmReceivableStatusListener() {
|
||||
return new CrmReceivableStatusListener();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
package cn.iocoder.yudao.module.crm.service.receivable.listener;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
|
||||
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
|
||||
import cn.iocoder.yudao.module.crm.enums.ApiConstants;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 回款审批的结果的监听器实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
@RestController
|
||||
@Validated
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
public class CrmReceivableStatusListener extends BpmProcessInstanceStatusEventListener {
|
||||
|
||||
private static final String PREFIX = ApiConstants.PREFIX + "/receivable";
|
||||
|
||||
@Resource
|
||||
private CrmReceivableService receivableService;
|
||||
|
||||
|
@ -24,7 +34,8 @@ public class CrmReceivableStatusListener extends BpmProcessInstanceStatusEventLi
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(BpmProcessInstanceStatusEvent event) {
|
||||
@PostMapping(PREFIX + "/update-audit-status") // 目的:提供给 bpm-server rpc 调用
|
||||
public void onEvent(@RequestBody BpmProcessInstanceStatusEvent event) {
|
||||
receivableService.updateReceivableAuditStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue