feat:V3.1.1整合remi-comm到remi-cloud中

This commit is contained in:
dianjiu
2024-09-11 17:41:17 +08:00
parent e111c59a69
commit 28d62f6cf4
245 changed files with 20975 additions and 154 deletions

View File

@@ -0,0 +1,27 @@
package ai.remi.comm.feign.annotation;
import org.springframework.cloud.openfeign.EnableFeignClients;
import java.lang.annotation.*;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc 自定义feign注解,添加basePackages路径
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EnableFeignClients
public @interface EnableRemiFeignClients {
String[] value() default {};
String[] basePackages() default {"ai.remi"};
Class<?>[] basePackageClasses() default {};
Class<?>[] defaultConfiguration() default {};
Class<?>[] clients() default {};
}

View File

@@ -0,0 +1,52 @@
package ai.remi.comm.feign.aspect;
import feign.Logger;
import feign.RequestInterceptor;
import feign.codec.ErrorDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc Feign 配置注册
*/
@Configuration
public class FeignAutoConfiguration {
/**
* 自定义请求拦截器
* 传递用户信息请求头,防止丢失
* @return
*/
@Bean
public RequestInterceptor requestInterceptor() {
return new FeignRequestInterceptor();
}
/**
* 设置Feign客户端日志级别
* <p>
* 有四种日志记录级别可供选择:
* <p>
* - NONE – 不记录日志,这是默认设置
* - BASIC – 仅记录请求方法、URL 和响应状态
* - HEADERS – 将基本信息与请求和响应标头一起记录
* - FULL – 记录请求和响应的主体、标头和元数据
*/
@Bean
Logger.Level level() {
return Logger.Level.FULL;
}
/**
* Feign 的默认错误处理程序ErrorDecoder.default总是抛出FeignException。
* 种行为并不总是最有用的。因此,要自定义抛出的异常
* @return
*/
@Bean
public ErrorDecoder errorDecoder() {
return new RemiFeignErrorDecoder();
}
}

View File

@@ -0,0 +1,72 @@
package ai.remi.comm.feign.aspect;
import ai.remi.comm.core.constant.HeaderConstant;
import ai.remi.comm.core.enums.IdentityTypeEnum;
import ai.remi.comm.core.enums.PermissionScopeEnum;
import ai.remi.comm.util.auth.AuthInfoUtils;
import ai.remi.comm.util.http.ServletUtils;
import ai.remi.comm.util.ip.IpAddrUtils;
import ai.remi.comm.util.string.StringUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Optional;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc Feign 请求拦截器
*/
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
private Logger log = LoggerFactory.getLogger(FeignRequestInterceptor.class);
@Override
public void apply(RequestTemplate requestTemplate) {
HttpServletRequest httpServletRequest = ServletUtils.getRequest();
Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);
// 传递用户信息请求头,防止丢失
//String userId = headers.get(HeaderConstant.X_UNIQUE_ID);
if (StringUtils.isNotNull(httpServletRequest)) {
// 传递服务类型请求头,防止丢失
log.info("FeignHeaderRequestInterceptor X_SERVICE_TYPE:{}", AuthInfoUtils.getServiceTypeCode());
requestTemplate.header(HeaderConstant.X_SERVICE_TYPE, AuthInfoUtils.getServiceTypeCode());
// 传递部门租户请求头,防止丢失
requestTemplate.header(HeaderConstant.X_DEPT_TENANT_ID, AuthInfoUtils.getDeptTenantId());
// 传递公司租户请求头,防止丢失
requestTemplate.header(HeaderConstant.X_COMPANY_TENANT_ID, AuthInfoUtils.getCompanyTenantId());
// 传递用户信息请求头,防止丢失
requestTemplate.header(HeaderConstant.X_UNIQUE_ID, AuthInfoUtils.getUniqueId());
// 传递系统语言请求头,防止丢失
requestTemplate.header(HeaderConstant.X_USER_LANGUAGE, AuthInfoUtils.getUserLanguage());
// 传递用户设备请求头,防止丢失
requestTemplate.header(HeaderConstant.X_DISTINCT_ID, headers.get(HeaderConstant.X_DISTINCT_ID));
// 传递鉴权信息请求头,防止丢失
requestTemplate.header(HeaderConstant.X_ACCESS_TOKEN, headers.get(HeaderConstant.X_ACCESS_TOKEN));
// 判断用户类型是否为集团公司,是的话进一步判断是否为集团权限,是集团权限需要传递集团下属公司IDs
IdentityTypeEnum identityTypeEnum = AuthInfoUtils.getIdentityTypeEnum();
//集团公司的用户
if (identityTypeEnum == IdentityTypeEnum.COMPANY) {
//权限范围
String permissionScope = Optional.ofNullable(AuthInfoUtils.getPermissionScopeEnum())
.map(PermissionScopeEnum::getCode).orElse("");
requestTemplate.header(HeaderConstant.X_PERMISSION_SCOPE, permissionScope);
//当权限范围为集团时,为这个用户管理公司的id
requestTemplate.header(HeaderConstant.X_COMPANY_IDS, AuthInfoUtils.getHasPermissionCompanyIds());
//当权限范围为公司时,为这个用户管理部门的id
requestTemplate.header(HeaderConstant.X_COMPANY_IDS, AuthInfoUtils.getHasPermissionCompanyIds());
} else if (identityTypeEnum == IdentityTypeEnum.VISITOR) {
//访客体验的用户 do anything
}
// 传递请求来源请求头,防止丢失
requestTemplate.header("X-Forwarded-For", IpAddrUtils.getIpAddr(ServletUtils.getRequest()));
}
}
}

View File

@@ -0,0 +1,19 @@
package ai.remi.comm.feign.aspect;
import ai.remi.comm.feign.exception.BadRequestException;
import ai.remi.comm.feign.exception.NotFoundException;
import ai.remi.comm.feign.exception.OpenFeignException;
import feign.Response;
import feign.codec.ErrorDecoder;
public class RemiFeignErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
return switch (response.status()) {
case 400 -> new BadRequestException();
case 404 -> new NotFoundException("Remi Feign ");
default -> new OpenFeignException("Remi Feign error");
};
}
}

View File

@@ -0,0 +1,17 @@
package ai.remi.comm.feign.exception;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc BadRequestException
*/
@Data
@NoArgsConstructor
public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,33 @@
package ai.remi.comm.feign.exception;
import ai.remi.comm.core.constant.Constants;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc NotFoundException
*/
@Data
@NoArgsConstructor
public class NotFoundException extends Exception {
private static final long serialVersionUID = 1L;
@Getter
@Setter
private String code;
@Getter
@Setter
private String message;
public NotFoundException(String msg) {
super(msg);
this.code = Constants.ERROR;
}
public NotFoundException(String msg, Exception e) {
super(msg + " not found,because of" + e.getMessage());
}
}

View File

@@ -0,0 +1,63 @@
package ai.remi.comm.feign.exception;
import ai.remi.comm.core.constant.Constants;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* @author Remi
* @email remi@dianjiu.cc
* @desc OpenFeignException
*/
@Data
@NoArgsConstructor
public class OpenFeignException extends RuntimeException {
@Getter
@Setter
private String code;
@Getter
@Setter
private String message;
@Getter
@Setter
private Object data;
public OpenFeignException(Throwable cause) {
super(cause);
}
public OpenFeignException(String message) {
super(message);
this.code = Constants.ERROR;
this.message = message;
}
public OpenFeignException(String code, String message) {
super(message);
this.code = code;
this.message = message;
}
public OpenFeignException(String code, Throwable cause) {
super(cause);
this.code = code;
this.message = cause.getMessage();
}
public OpenFeignException(String code, String message, Throwable cause) {
super(message, cause);
this.code = code;
this.message = message;
}
public OpenFeignException(String code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
this.code = code;
this.message = message;
}
}