Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into pay_extension

This commit is contained in:
YunaiV
2021-10-12 21:25:03 +08:00
328 changed files with 7295 additions and 2691 deletions

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.framework.common.util.http;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.TableMap;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.ReferenceUtil;
import cn.hutool.core.util.ReflectUtil;
import java.nio.charset.Charset;
/**
* HTTP 工具类
*
* @author 芋道源码
*/
public class HttpUtils {
@SuppressWarnings("unchecked")
public static String replaceUrlQuery(String url, String key, String value) {
UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
// 先移除
TableMap<CharSequence, CharSequence> query = (TableMap<CharSequence, CharSequence>)
ReflectUtil.getFieldValue(builder.getQuery(), "query");
query.remove(key);
// 后添加
builder.addQuery(key, value);
return builder.build();
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.IOException;
import java.util.ArrayList;
@ -19,6 +20,10 @@ public class JsonUtils {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
/**
* 初始化 objectMapper 属性
* <p>

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.framework.common.util.validation;
import cn.hutool.core.util.StrUtil;
import org.springframework.util.StringUtils;
import java.util.regex.Pattern;
/**
* 校验工具类
*
* @author 芋道源码
*/
public class ValidationUtils {
private static Pattern PATTERN_URL = Pattern.compile("^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
public static boolean isMobile(String mobile) {
if (StrUtil.length(mobile) != 11) {
return false;
}
// TODO 芋艿,后面完善手机校验
return true;
}
public static boolean isURL(String url) {
return StringUtils.hasText(url)
&& PATTERN_URL.matcher(url).matches();
}
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.framework.common.validation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = MobileValidator.class
)
public @interface Mobile {
String message() default "手机号格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.framework.common.validation;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class MobileValidator implements ConstraintValidator<Mobile, String> {
@Override
public void initialize(Mobile annotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 如果手机号为空,默认不校验,即校验通过
if (StrUtil.isEmpty(value)) {
return true;
}
// 校验手机
return ValidationUtils.isMobile(value);
}
}

View File

@ -39,7 +39,7 @@ public class ExcelUtils {
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
public static <T> List<T> raed(MultipartFile file, Class<T> head) throws IOException {
public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
return EasyExcel.read(file.getInputStream(), head, null)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.doReadAllSync();

View File

@ -41,6 +41,10 @@
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
@ -53,10 +57,6 @@
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-opentracing</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>

View File

@ -1,13 +1,9 @@
package cn.iocoder.yudao.framework.tracer.config;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.tracer.core.aop.BizTraceAspect;
import cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;
import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
@ -25,24 +21,25 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true)
public class YudaoTracerAutoConfiguration {
@Bean
public TracerProperties bizTracerProperties() {
return new TracerProperties();
}
@Bean
public BizTraceAspect bizTracingAop() {
return new BizTraceAspect(tracer());
}
@Bean
public Tracer tracer() {
// 创建 SkywalkingTracer 对象
SkywalkingTracer tracer = new SkywalkingTracer();
// 设置为 GlobalTracer 的追踪器
GlobalTracer.register(tracer);
return tracer;
}
// TODO @芋艿:重要。目前 opentracing 版本存在冲突,要么保证 skywalking要么保证阿里云短信 sdk
// @Bean
// public TracerProperties bizTracerProperties() {
// return new TracerProperties();
// }
//
// @Bean
// public BizTraceAspect bizTracingAop() {
// return new BizTraceAspect(tracer());
// }
//
// @Bean
// public Tracer tracer() {
// // 创建 SkywalkingTracer 对象
// SkywalkingTracer tracer = new SkywalkingTracer();
// // 设置为 GlobalTracer 的追踪器
// GlobalTracer.register(tracer);
// return tracer;
// }
/**
* 创建 TraceFilter 过滤器,响应 header 设置 traceId

View File

@ -15,7 +15,7 @@ import org.springframework.context.annotation.Configuration;
* @author 芋道源码
*/
@Configuration
@MapperScan(value = "${yudao.info.base-package}", annotationClass = Mapper.class,
@MapperScan(value = {"${yudao.info.base-package}", "${yudao.core-service.base-package}"}, annotationClass = Mapper.class,
lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
public class YudaoMybatisAutoConfiguration {

View File

@ -36,4 +36,8 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
return selectList(new QueryWrapper<>());
}
default List<T> selectList(String field, Object value) {
return selectList(new QueryWrapper<T>().eq(field, value));
}
}

View File

@ -19,7 +19,12 @@
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
<version>${revision}</version>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Web 相关 -->

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.security.config;
import cn.iocoder.yudao.framework.security.core.filter.JwtAuthenticationTokenFilter;
import cn.iocoder.yudao.framework.security.core.aop.PreAuthenticatedAspect;
import cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter;
import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl;
import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl;
import cn.iocoder.yudao.framework.security.core.handler.LogoutSuccessHandlerImpl;
@ -32,6 +33,14 @@ public class YudaoSecurityAutoConfiguration {
@Resource
private SecurityProperties securityProperties;
/**
* 处理用户未登录拦截的切面的 Bean
*/
@Bean
public PreAuthenticatedAspect preAuthenticatedAspect() {
return new PreAuthenticatedAspect();
}
/**
* 认证失败处理类 Bean
*/
@ -71,9 +80,9 @@ public class YudaoSecurityAutoConfiguration {
* Token 认证过滤器 Bean
*/
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilter(SecurityAuthFrameworkService securityFrameworkService,
public JWTAuthenticationTokenFilter authenticationTokenFilter(SecurityAuthFrameworkService securityFrameworkService,
GlobalExceptionHandler globalExceptionHandler) {
return new JwtAuthenticationTokenFilter(securityProperties, securityFrameworkService, globalExceptionHandler);
return new JWTAuthenticationTokenFilter(securityProperties, securityFrameworkService, globalExceptionHandler);
}
}

View File

@ -1,26 +1,20 @@
package cn.iocoder.yudao.framework.security.config;
import cn.iocoder.yudao.framework.security.core.filter.JwtAuthenticationTokenFilter;
import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl;
import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl;
import cn.iocoder.yudao.framework.security.core.handler.LogoutSuccessHandlerImpl;
import cn.iocoder.yudao.framework.security.core.filter.JWTAuthenticationTokenFilter;
import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService;
import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
@ -41,14 +35,11 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
@Resource
private WebProperties webProperties;
@Value("${spring.boot.admin.context-path:''}")
private String adminSeverContextPath;
/**
* 自定义用户【认证】逻辑
*/
@Resource
private UserDetailsService userDetailsService;
private SecurityAuthFrameworkService userDetailsService;
/**
* Spring Security 加密器
*/
@ -73,7 +64,14 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
* Token 认证过滤器 Bean
*/
@Resource
private JwtAuthenticationTokenFilter authenticationTokenFilter;
private JWTAuthenticationTokenFilter authenticationTokenFilter;
/**
* 自定义的权限映射 Bean
*
* @see #configure(HttpSecurity)
*/
@Resource
private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer;
/**
* 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入
@ -121,15 +119,16 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
.csrf().disable()
// 基于 token 机制,所以不需要 Session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.headers().frameOptions().disable().and()
// 一堆自定义的 Spring Security 处理器
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler).and()
// 设置每个请求的权限
.authorizeRequests()
// 登陆的接口,可匿名访问
.logout().logoutUrl(api("/logout")).logoutSuccessHandler(logoutSuccessHandler); // 登出
// 设置每个请求的权限 ①:全局共享规则
httpSecurity.authorizeRequests()
// 登录的接口,可匿名访问
.antMatchers(api("/login")).anonymous()
// 通用的接口,可匿名访问 TODO 芋艿:需要抽象出去
.antMatchers(api("/system/captcha/**")).anonymous()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 文件的获取接口,可匿名访问
@ -139,21 +138,20 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap
.antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous()
// Spring Boot Admin Server 的安全配置 TODO 芋艿:需要抽象出去
.antMatchers(adminSeverContextPath).anonymous()
.antMatchers(adminSeverContextPath + "/**").anonymous()
// Spring Boot Actuator 的安全配置
.antMatchers("/actuator").anonymous()
.antMatchers("/actuator/**").anonymous()
// Druid 监控 TODO 芋艿:需要抽象出去
// Druid 监控 TODO 芋艿:等对接了 druid admin 后,在调整下。
.antMatchers("/druid/**").anonymous()
// 短信回调 API TODO 芋艿:需要抽象出去
.antMatchers(api("/system/sms/callback/**")).anonymous()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable();
httpSecurity.logout().logoutUrl(api("/logout")).logoutSuccessHandler(logoutSuccessHandler);
// oAuth2 auth2/login/gitee
.antMatchers(api("/auth2/login/**")).anonymous()
.antMatchers(api("/auth2/authorization/**")).anonymous()
.antMatchers("/api/callback/**").anonymous()
// 设置每个请求的权限 ②:每个项目的自定义规则
.and().authorizeRequests(authorizeRequestsCustomizer)
// 设置每个请求的权限 ③:兜底规则,必须认证
.authorizeRequests().anyRequest().authenticated()
;
// 添加 JWT Filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.security.core;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
@ -8,10 +9,11 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
* 登用户信息
* 登用户信息
*
* @author 芋道源码
*/
@ -23,7 +25,13 @@ public class LoginUser implements UserDetails {
*/
private Long id;
/**
* 科室编号
* 用户类型
*
* 关联 {@link UserTypeEnum}
*/
private Integer userType;
/**
* 部门编号
*/
private Long deptId;
/**
@ -48,6 +56,8 @@ public class LoginUser implements UserDetails {
*/
private Integer status;
// TODO @芋艿:怎么去掉 deptId
@Override
@JsonIgnore// 避免序列化
public String getPassword() {
@ -69,7 +79,7 @@ public class LoginUser implements UserDetails {
@Override
@JsonIgnore// 避免序列化
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
return new HashSet<>();
}
@Override

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.framework.security.core.annotations;
import java.lang.annotation.*;
/**
* 声明用户需要登录
*
* 为什么不使用 {@link org.springframework.security.access.prepost.PreAuthorize} 注解,原因是不通过时,抛出的是认证不通过,而不是未登录
*
* @author 芋道源码
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PreAuthenticated {
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.framework.security.core.aop;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@Aspect
@Slf4j
public class PreAuthenticatedAspect {
@Around("@annotation(preAuthenticated)")
public Object around(ProceedingJoinPoint joinPoint, PreAuthenticated preAuthenticated) throws Throwable {
if (SecurityFrameworkUtils.getLoginUser() == null) {
throw exception(UNAUTHORIZED);
}
return joinPoint.proceed();
}
}

View File

@ -23,10 +23,10 @@ import java.io.IOException;
* JWT 过滤器验证 token 的有效性
* 验证通过后获得 {@link LoginUser} 信息并加入到 Spring Security 上下文
*
* @author ruoyi
* @author 芋道源码
*/
@AllArgsConstructor
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
public class JWTAuthenticationTokenFilter extends OncePerRequestFilter {
private final SecurityProperties securityProperties;
@ -63,7 +63,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
}
/**
* 模拟登用户方便日常开发调试
* 模拟登用户方便日常开发调试
*
* 注意在线上环境下一定要关闭该功能
*

View File

@ -0,0 +1,53 @@
/*
* MIT License
* Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package cn.iocoder.yudao.framework.security.core.handler;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author weir
*/
public class AbstractSignUpUrlAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
if (requestCache.getRequest(request, response) != null) {
requestCache.getRequest(request, response);
}
super.onAuthenticationSuccess(request,response,authentication);
}
@Override
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}

View File

@ -84,7 +84,7 @@ public class SecurityFrameworkUtils {
/**
* 设置当前用户
*
* @param loginUser 登用户
* @param loginUser 登用户
* @param request 请求
*/
public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
@ -97,6 +97,7 @@ public class SecurityFrameworkUtils {
// 额外设置到 request 中,用于 ApiAccessLogFilter 可以获取到用户编号;
// 原因是Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
}
}

View File

@ -81,7 +81,7 @@ public class ApiAccessLogFilter extends OncePerRequestFilter {
Map<String, String> queryString, String requestBody, Exception ex) {
// 处理用户信息
accessLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
accessLog.setUserType(WebFrameworkUtils.getUserType(request));
accessLog.setUserType(WebFrameworkUtils.getLoginUserType(request));
// 设置访问结果
CommonResult<?> result = WebFrameworkUtils.getCommonResult(request);
if (result != null) {

View File

@ -16,8 +16,7 @@ public interface ApiAccessLogFrameworkService {
* 创建 API 访问日志
*
* @param createDTO 创建信息
* @return 是否创建成功
*/
Future<Boolean> createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO);
void createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO);
}

View File

@ -16,8 +16,7 @@ public interface ApiErrorLogFrameworkService {
* 创建 API 错误日志
*
* @param createDTO 创建信息
* @return 是否创建成功
*/
Future<Boolean> createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO);
void createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO);
}

View File

@ -23,7 +23,7 @@ public class DemoFilter extends OncePerRequestFilter {
protected boolean shouldNotFilter(HttpServletRequest request) {
String method = request.getMethod();
return !StrUtil.equalsAnyIgnoreCase(method, "POST", "PUT", "DELETE") // 写操作时,不进行过滤率
|| WebFrameworkUtils.getLoginUserId(request) == null; // 非登用户时,不进行过滤
|| WebFrameworkUtils.getLoginUserId(request) == null; // 非登用户时,不进行过滤
}
@Override

View File

@ -245,7 +245,7 @@ public class GlobalExceptionHandler {
private void initExceptionLog(ApiErrorLogCreateDTO errorLog, HttpServletRequest request, Throwable e) {
// 处理用户信息
errorLog.setUserId(WebFrameworkUtils.getLoginUserId(request));
errorLog.setUserType(WebFrameworkUtils.getUserType(request));
errorLog.setUserType(WebFrameworkUtils.getLoginUserType(request));
// 设置异常字段
errorLog.setExceptionName(e.getClass().getName());
errorLog.setExceptionMessage(ExceptionUtil.getMessage(e));

View File

@ -17,6 +17,7 @@ import javax.servlet.http.HttpServletRequest;
public class WebFrameworkUtils {
private static final String REQUEST_ATTRIBUTE_LOGIN_USER_ID = "login_user_id";
private static final String REQUEST_ATTRIBUTE_LOGIN_USER_TYPE = "login_user_type";
private static final String REQUEST_ATTRIBUTE_COMMON_RESULT = "common_result";
@ -24,6 +25,10 @@ public class WebFrameworkUtils {
request.setAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID, userId);
}
public static void setLoginUserType(ServletRequest request, Integer userType) {
request.setAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_TYPE, userType);
}
/**
* 获得当前用户的编号,从请求中
*
@ -37,15 +42,24 @@ public class WebFrameworkUtils {
return (Long) request.getAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_ID);
}
/**
* 获得当前用户的类型,从请求中
*
* @param request 请求
* @return 用户编号
*/
public static Integer getLoginUserType(HttpServletRequest request) {
if (request == null) {
return null;
}
return (Integer) request.getAttribute(REQUEST_ATTRIBUTE_LOGIN_USER_TYPE);
}
public static Long getLoginUserId() {
HttpServletRequest request = getRequest();
return getLoginUserId(request);
}
public static Integer getUserType(HttpServletRequest request) {
return UserTypeEnum.ADMIN.getValue(); // TODO 芋艿:等后续优化
}
public static void setCommonResult(ServletRequest request, CommonResult<?> result) {
request.setAttribute(REQUEST_ATTRIBUTE_COMMON_RESULT, result);
}