Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	pig-common/pig-common-feign/src/main/java/org/springframework/cloud/openfeign/PigFeignClientsRegistrar.java
This commit is contained in:
冷冷 2024-04-19 21:24:28 +08:00
commit 5bd49b3be5
15 changed files with 732 additions and 744 deletions

View File

@ -42,14 +42,14 @@ public class WebSecurityConfiguration {
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests(authorizeRequests -> authorizeRequests.antMatchers("/token/*")
.permitAll()// 开放自定义的部分端点
.anyRequest()
.authenticated())
.headers()
.frameOptions()
.sameOrigin()// 避免iframe同源无法登录
.and()
.apply(new FormIdentityLoginConfigurer()); // 表单登录个性化
.permitAll()// 开放自定义的部分端点
.anyRequest()
.authenticated())
.headers()
.frameOptions()
.sameOrigin()// 避免iframe同源无法登录
.and()
.apply(new FormIdentityLoginConfigurer()); // 表单登录个性化
// 处理 UsernamePasswordAuthenticationToken
http.authenticationProvider(new PigDaoAuthenticationProvider());
return http.build();
@ -67,13 +67,13 @@ public class WebSecurityConfiguration {
@Order(0)
SecurityFilterChain resources(HttpSecurity http) throws Exception {
http.requestMatchers((matchers) -> matchers.antMatchers("/actuator/**", "/code/image", "/css/**", "/error"))
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
.requestCache()
.disable()
.securityContext()
.disable()
.sessionManagement()
.disable();
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
.requestCache()
.disable()
.securityContext()
.disable()
.sessionManagement()
.disable();
return http.build();
}

View File

@ -24,25 +24,25 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
public class ImageCodeEndpoint {
private static final Integer DEFAULT_IMAGE_WIDTH = 100;
private static final Integer DEFAULT_IMAGE_WIDTH = 100;
private static final Integer DEFAULT_IMAGE_HEIGHT = 40;
private static final Integer DEFAULT_IMAGE_HEIGHT = 40;
private final StringRedisTemplate redisTemplate;
private final StringRedisTemplate redisTemplate;
/**
* 创建图形验证码
*/
@SneakyThrows
@GetMapping("/image")
public void image(String randomStr, HttpServletResponse response) {
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
/**
* 创建图形验证码
*/
@SneakyThrows
@GetMapping("/image")
public void image(String randomStr, HttpServletResponse response) {
ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
String result = captcha.text();
redisTemplate.opsForValue()
.set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
// 转换流信息写出
captcha.out(response.getOutputStream());
String result = captcha.text();
redisTemplate.opsForValue()
.set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result, SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
// 转换流信息写出
captcha.out(response.getOutputStream());
}
}

View File

@ -47,46 +47,46 @@ import java.util.Map;
@RequiredArgsConstructor
public class PasswordDecoderFilter extends OncePerRequestFilter {
private final AuthSecurityConfigProperties authSecurityConfigProperties;
private final AuthSecurityConfigProperties authSecurityConfigProperties;
private static final String PASSWORD = "password";
private static final String PASSWORD = "password";
private static final String KEY_ALGORITHM = "AES";
private static final String KEY_ALGORITHM = "AES";
static {
// 关闭hutool 强制关闭Bouncy Castle库的依赖
SecureUtil.disableBouncyCastle();
}
static {
// 关闭hutool 强制关闭Bouncy Castle库的依赖
SecureUtil.disableBouncyCastle();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
// 不是登录请求直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)) {
chain.doFilter(request, response);
return;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
// 不是登录请求直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getRequestURI(), SecurityConstants.OAUTH_TOKEN_URL)) {
chain.doFilter(request, response);
return;
}
// 将请求流转换为可多次读取的请求流
RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request);
Map<String, String[]> parameterMap = requestWrapper.getParameterMap();
// 将请求流转换为可多次读取的请求流
RepeatBodyRequestWrapper requestWrapper = new RepeatBodyRequestWrapper(request);
Map<String, String[]> parameterMap = requestWrapper.getParameterMap();
// 构建前端对应解密AES 因子
AES aes = new AES(Mode.CFB, Padding.NoPadding,
new SecretKeySpec(authSecurityConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM),
new IvParameterSpec(authSecurityConfigProperties.getEncodeKey().getBytes()));
// 构建前端对应解密AES 因子
AES aes = new AES(Mode.CFB, Padding.NoPadding,
new SecretKeySpec(authSecurityConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM),
new IvParameterSpec(authSecurityConfigProperties.getEncodeKey().getBytes()));
parameterMap.forEach((k, v) -> {
String[] values = parameterMap.get(k);
if (!PASSWORD.equals(k) || ArrayUtil.isEmpty(values)) {
return;
}
parameterMap.forEach((k, v) -> {
String[] values = parameterMap.get(k);
if (!PASSWORD.equals(k) || ArrayUtil.isEmpty(values)) {
return;
}
// 解密密码
String decryptPassword = aes.decryptStr(values[0]);
parameterMap.put(k, new String[]{decryptPassword});
});
chain.doFilter(requestWrapper, response);
}
// 解密密码
String decryptPassword = aes.decryptStr(values[0]);
parameterMap.put(k, new String[] { decryptPassword });
});
chain.doFilter(requestWrapper, response);
}
}

View File

@ -40,86 +40,87 @@ import java.util.Optional;
@RequiredArgsConstructor
public class ValidateCodeFilter extends OncePerRequestFilter {
private final AuthSecurityConfigProperties authSecurityConfigProperties;
private final AuthSecurityConfigProperties authSecurityConfigProperties;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestUrl = request.getServletPath();
String requestUrl = request.getServletPath();
// 不是登录URL 请求直接跳过
if (!SecurityConstants.OAUTH_TOKEN_URL.equals(requestUrl)) {
filterChain.doFilter(request, response);
return;
}
// 不是登录URL 请求直接跳过
if (!SecurityConstants.OAUTH_TOKEN_URL.equals(requestUrl)) {
filterChain.doFilter(request, response);
return;
}
// 如果登录URL 但是刷新token的请求直接向下执行
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
filterChain.doFilter(request, response);
return;
}
// 如果登录URL 但是刷新token的请求直接向下执行
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
filterChain.doFilter(request, response);
return;
}
// 客户端配置跳过验证码
boolean isIgnoreClient = authSecurityConfigProperties.getIgnoreClients().contains(WebUtils.getClientId());
if (isIgnoreClient) {
filterChain.doFilter(request, response);
return;
}
// 客户端配置跳过验证码
boolean isIgnoreClient = authSecurityConfigProperties.getIgnoreClients().contains(WebUtils.getClientId());
if (isIgnoreClient) {
filterChain.doFilter(request, response);
return;
}
// 校验验证码 1. 客户端开启验证码 2. 短信模式
try {
checkCode();
filterChain.doFilter(request, response);
} catch (ValidateCodeException validateCodeException) {
throw new OAuth2AuthenticationException(validateCodeException.getMessage());
}
}
// 校验验证码 1. 客户端开启验证码 2. 短信模式
try {
checkCode();
filterChain.doFilter(request, response);
}
catch (ValidateCodeException validateCodeException) {
throw new OAuth2AuthenticationException(validateCodeException.getMessage());
}
}
/**
* 校验验证码
*/
private void checkCode() throws ValidateCodeException {
Optional<HttpServletRequest> request = WebUtils.getRequest();
String code = request.get().getParameter("code");
/**
* 校验验证码
*/
private void checkCode() throws ValidateCodeException {
Optional<HttpServletRequest> request = WebUtils.getRequest();
String code = request.get().getParameter("code");
if (StrUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
}
if (StrUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
}
String randomStr = request.get().getParameter("randomStr");
String randomStr = request.get().getParameter("randomStr");
// https://gitee.com/log4j/pig/issues/IWA0D
String mobile = request.get().getParameter("mobile");
if (StrUtil.isNotBlank(mobile)) {
randomStr = mobile;
}
// https://gitee.com/log4j/pig/issues/IWA0D
String mobile = request.get().getParameter("mobile");
if (StrUtil.isNotBlank(mobile)) {
randomStr = mobile;
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
RedisTemplate<String, String> redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
if (Boolean.FALSE.equals(redisTemplate.hasKey(key))) {
throw new ValidateCodeException("验证码不合法");
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
RedisTemplate<String, String> redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
if (Boolean.FALSE.equals(redisTemplate.hasKey(key))) {
throw new ValidateCodeException("验证码不合法");
}
Object codeObj = redisTemplate.opsForValue().get(key);
Object codeObj = redisTemplate.opsForValue().get(key);
if (codeObj == null) {
throw new ValidateCodeException("验证码不合法");
}
if (codeObj == null) {
throw new ValidateCodeException("验证码不合法");
}
String saveCode = codeObj.toString();
if (StrUtil.isBlank(saveCode)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
String saveCode = codeObj.toString();
if (StrUtil.isBlank(saveCode)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
if (!StrUtil.equals(saveCode, code)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
if (!StrUtil.equals(saveCode, code)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
redisTemplate.delete(key);
redisTemplate.delete(key);
}
}

View File

@ -59,91 +59,91 @@ import java.util.stream.Collectors;
@RequiredArgsConstructor
public class PigBootSecurityServerConfiguration {
private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
private final ResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;
private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;
private final OpaqueTokenIntrospector customOpaqueTokenIntrospector;
private final AuthenticationConverter accessTokenRequestConverter;
private final AuthenticationConverter accessTokenRequestConverter;
private final OAuth2AuthorizationService authorizationService;
private final OAuth2AuthorizationService authorizationService;
private final PigBearerTokenExtractor pigBearerTokenExtractor;
private final PigBearerTokenExtractor pigBearerTokenExtractor;
private final PasswordDecoderFilter passwordDecoderFilter;
private final PasswordDecoderFilter passwordDecoderFilter;
private final OAuth2TokenGenerator oAuth2TokenGenerator;
private final OAuth2TokenGenerator oAuth2TokenGenerator;
private final ValidateCodeFilter validateCodeFilter;
private final ValidateCodeFilter validateCodeFilter;
private final PermitAllUrlProperties permitAllUrl;
private final PermitAllUrlProperties permitAllUrl;
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
http.addFilterAfter(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
http.apply(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter
.accessTokenResponseHandler(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器
.errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)))
.authorizationService(authorizationService)
.authorizationServerSettings(
AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build());
http.addFilterAfter(passwordDecoderFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
http.apply(authorizationServerConfigurer.tokenEndpoint((tokenEndpoint) -> {// 个性化认证授权端点
tokenEndpoint.accessTokenRequestConverter(accessTokenRequestConverter) // 注入自定义的授权认证Converter
.accessTokenResponseHandler(new PigAuthenticationSuccessEventHandler()) // 登录成功处理器
.errorResponseHandler(new PigAuthenticationFailureEventHandler());// 登录失败处理器
}).clientAuthentication(oAuth2ClientAuthenticationConfigurer -> // 个性化客户端认证
oAuth2ClientAuthenticationConfigurer.errorResponseHandler(new PigAuthenticationFailureEventHandler()))// 处理客户端认证异常
.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint// 授权码端点个性化confirm页面
.consentPage(SecurityConstants.CUSTOM_CONSENT_PAGE_URI)))
.authorizationService(authorizationService)
.authorizationServerSettings(
AuthorizationServerSettings.builder().issuer(SecurityConstants.PROJECT_LICENSE).build());
AntPathRequestMatcher[] requestMatchers = permitAllUrl.getUrls()
.stream()
.map(AntPathRequestMatcher::new)
.collect(Collectors.toList())
.toArray(new AntPathRequestMatcher[]{});
AntPathRequestMatcher[] requestMatchers = permitAllUrl.getUrls()
.stream()
.map(AntPathRequestMatcher::new)
.collect(Collectors.toList())
.toArray(new AntPathRequestMatcher[] {});
http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers(requestMatchers)
.permitAll()
.anyRequest()
.authenticated())
.oauth2ResourceServer(
oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
.authenticationEntryPoint(resourceAuthExceptionEntryPoint)
.bearerTokenResolver(pigBearerTokenExtractor))
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(resourceAuthExceptionEntryPoint))
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.csrf(AbstractHttpConfigurer::disable);
http.authorizeHttpRequests(authorizeRequests -> authorizeRequests.requestMatchers(requestMatchers)
.permitAll()
.anyRequest()
.authenticated())
.oauth2ResourceServer(
oauth2 -> oauth2.opaqueToken(token -> token.introspector(customOpaqueTokenIntrospector))
.authenticationEntryPoint(resourceAuthExceptionEntryPoint)
.bearerTokenResolver(pigBearerTokenExtractor))
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(resourceAuthExceptionEntryPoint))
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
.csrf(AbstractHttpConfigurer::disable);
DefaultSecurityFilterChain securityFilterChain = http.build();
DefaultSecurityFilterChain securityFilterChain = http.build();
// 注入自定义授权模式实现
addCustomOAuth2GrantAuthenticationProvider(http);
return securityFilterChain;
}
// 注入自定义授权模式实现
addCustomOAuth2GrantAuthenticationProvider(http);
return securityFilterChain;
}
/**
* 注入授权模式实现提供方
* <p>
* 1. 密码模式 </br>
* 2. 短信登录 </br>
*/
@SuppressWarnings("unchecked")
private void addCustomOAuth2GrantAuthenticationProvider(HttpSecurity http) {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
/**
* 注入授权模式实现提供方
* <p>
* 1. 密码模式 </br>
* 2. 短信登录 </br>
*/
@SuppressWarnings("unchecked")
private void addCustomOAuth2GrantAuthenticationProvider(HttpSecurity http) {
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
OAuth2AuthorizationService authorizationService = http.getSharedObject(OAuth2AuthorizationService.class);
OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider = new OAuth2ResourceOwnerPasswordAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
OAuth2ResourceOwnerPasswordAuthenticationProvider resourceOwnerPasswordAuthenticationProvider = new OAuth2ResourceOwnerPasswordAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
OAuth2ResourceOwnerSmsAuthenticationProvider resourceOwnerSmsAuthenticationProvider = new OAuth2ResourceOwnerSmsAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
OAuth2ResourceOwnerSmsAuthenticationProvider resourceOwnerSmsAuthenticationProvider = new OAuth2ResourceOwnerSmsAuthenticationProvider(
authenticationManager, authorizationService, oAuth2TokenGenerator);
// 处理 UsernamePasswordAuthenticationToken
http.authenticationProvider(new PigDaoAuthenticationProvider());
// 处理 OAuth2ResourceOwnerPasswordAuthenticationToken
http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);
// 处理 OAuth2ResourceOwnerSmsAuthenticationToken
http.authenticationProvider(resourceOwnerSmsAuthenticationProvider);
// 处理 UsernamePasswordAuthenticationToken
http.authenticationProvider(new PigDaoAuthenticationProvider());
// 处理 OAuth2ResourceOwnerPasswordAuthenticationToken
http.authenticationProvider(resourceOwnerPasswordAuthenticationProvider);
// 处理 OAuth2ResourceOwnerSmsAuthenticationToken
http.authenticationProvider(resourceOwnerSmsAuthenticationProvider);
}
}

View File

@ -38,66 +38,66 @@ import java.util.Map;
@Slf4j
public class RepeatBodyRequestWrapper extends HttpServletRequestWrapper {
private final byte[] bodyByteArray;
private final byte[] bodyByteArray;
private final Map<String, String[]> parameterMap;
private final Map<String, String[]> parameterMap;
public RepeatBodyRequestWrapper(HttpServletRequest request) {
super(request);
this.bodyByteArray = getByteBody(request);
this.parameterMap = super.getParameterMap();
}
public RepeatBodyRequestWrapper(HttpServletRequest request) {
super(request);
this.bodyByteArray = getByteBody(request);
this.parameterMap = super.getParameterMap();
}
@Override
public BufferedReader getReader() {
return ObjectUtils.isEmpty(this.bodyByteArray) ? null
: new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public BufferedReader getReader() {
return ObjectUtils.isEmpty(this.bodyByteArray) ? null
: new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.bodyByteArray);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.bodyByteArray);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
// doNoting
}
@Override
public void setReadListener(ReadListener readListener) {
// doNoting
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
private static byte[] getByteBody(HttpServletRequest request) {
byte[] body = new byte[0];
try {
body = StreamUtils.copyToByteArray(request.getInputStream());
} catch (IOException e) {
log.error("解析流中数据异常", e);
}
return body;
}
private static byte[] getByteBody(HttpServletRequest request) {
byte[] body = new byte[0];
try {
body = StreamUtils.copyToByteArray(request.getInputStream());
}
catch (IOException e) {
log.error("解析流中数据异常", e);
}
return body;
}
/**
* 重写 getParameterMap() 方法 解决 undertow 中流被读取后会进行标记从而导致无法正确获取 body 中的表单数据的问题
*
* @return Map<String, String [ ]> parameterMap
*/
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
/**
* 重写 getParameterMap() 方法 解决 undertow 中流被读取后会进行标记从而导致无法正确获取 body 中的表单数据的问题
* @return Map<String, String [ ]> parameterMap
*/
@Override
public Map<String, String[]> getParameterMap() {
return this.parameterMap;
}
}

View File

@ -24,14 +24,14 @@ public class RedisUtils {
/**
* 指定缓存失效时间
* @param key
* @param key
* @param time 时间()
*/
public boolean expire(String key, long time) {
RedisTemplate<Object, Object> redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
Optional.ofNullable(redisTemplate)
.filter(template -> time > 0)
.ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS));
.filter(template -> time > 0)
.ifPresent(template -> template.expire(key, time, TimeUnit.SECONDS));
return true;
}
@ -43,8 +43,8 @@ public class RedisUtils {
public long getExpire(Object key) {
RedisTemplate<Object, Object> redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
return Optional.ofNullable(redisTemplate)
.map(template -> template.getExpire(key, TimeUnit.SECONDS))
.orElse(-1L);
.map(template -> template.getExpire(key, TimeUnit.SECONDS))
.orElse(-1L);
}
/**
@ -71,8 +71,8 @@ public class RedisUtils {
/**
* 分页查询 key
* @param patternKey key
* @param page 页码
* @param size 每页数目
* @param page 页码
* @param size 每页数目
* @return /
*/
public List<String> findKeysForPage(String patternKey, int page, int size) {
@ -125,22 +125,22 @@ public class RedisUtils {
/**
* 获取锁
* @param lockKey 锁key
* @param value value
* @param lockKey 锁key
* @param value value
* @param expireTime单位-
* @return boolean
*/
public boolean getLock(String lockKey, String value, int expireTime) {
RedisTemplate<Object, Object> redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
return Optional.ofNullable(redisTemplate)
.map(template -> template.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS))
.orElse(false);
.map(template -> template.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS))
.orElse(false);
}
/**
* 释放锁
* @param lockKey 锁key
* @param value value
* @param value value
* @return boolean
*/
public boolean releaseLock(String lockKey, String value) {
@ -148,9 +148,9 @@ public class RedisUtils {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
return Optional.ofNullable(redisTemplate.execute(redisScript, Collections.singletonList(lockKey), value))
.map(Convert::toLong)
.filter(SUCCESS::equals)
.isPresent();
.map(Convert::toLong)
.filter(SUCCESS::equals)
.isPresent();
}
// ============================String=============================
@ -177,7 +177,7 @@ public class RedisUtils {
/**
* 普通缓存放入
* @param key
* @param key
* @param value
* @return true成功 false失败
*/
@ -192,9 +192,9 @@ public class RedisUtils {
/**
* 普通缓存放入并设置时间
* @param key
* @param key
* @param value
* @param time 时间() time要大于0 如果time小于等于0 将设置无限期
* @param time 时间() time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
@ -202,7 +202,8 @@ public class RedisUtils {
return Optional.ofNullable(redisTemplate).map(template -> {
if (time > 0) {
template.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
}
else {
template.opsForValue().set(key, value);
}
return true;
@ -211,9 +212,9 @@ public class RedisUtils {
/**
* 普通缓存放入并设置时间
* @param key
* @param value
* @param time 时间
* @param key
* @param value
* @param time 时间
* @param timeUnit 类型
* @return true成功 false 失败
*/
@ -222,7 +223,8 @@ public class RedisUtils {
Optional.ofNullable(redisTemplate).map(template -> {
if (time > 0) {
template.opsForValue().set(key, value, time, timeUnit);
} else {
}
else {
template.opsForValue().set(key, value);
}
return true;
@ -234,7 +236,7 @@ public class RedisUtils {
/**
* HashGet
* @param key 不能为null
* @param key 不能为null
* @param hashKey 不能为null
* @return
*/
@ -270,8 +272,8 @@ public class RedisUtils {
/**
* HashSet 并设置时间
* @param key
* @param map 对应多个键值
* @param key
* @param map 对应多个键值
* @param time 时间()
* @return true成功 false失败
*/
@ -304,10 +306,10 @@ public class RedisUtils {
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key
* @param item
* @param key
* @param item
* @param value
* @param time 时间() 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @param time 时间() 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
@ -323,7 +325,7 @@ public class RedisUtils {
/**
* 删除hash表中的值
* @param key 不能为null
* @param key 不能为null
* @param item 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
@ -333,7 +335,7 @@ public class RedisUtils {
/**
* 判断hash表中是否有该项的值
* @param key 不能为null
* @param key 不能为null
* @param item 不能为null
* @return true 存在 false不存在
*/
@ -344,9 +346,9 @@ public class RedisUtils {
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key
* @param key
* @param item
* @param by 要增加几(大于0)
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
@ -356,9 +358,9 @@ public class RedisUtils {
/**
* hash递减
* @param key
* @param key
* @param item
* @param by 要减少记(小于0)
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
@ -391,7 +393,7 @@ public class RedisUtils {
/**
* 将数据放入set缓存
* @param key
* @param key
* @param values 可以是多个
* @return 成功个数
*/
@ -452,9 +454,9 @@ public class RedisUtils {
/**
* 获取list缓存的内容
* @param key
* @param key
* @param start 开始
* @param end 结束 0 -1代表所有值
* @param end 结束 0 -1代表所有值
* @return
*/
public <T> List<T> lGet(String key, long start, long end) {
@ -474,7 +476,7 @@ public class RedisUtils {
/**
* 通过索引 获取list中的值
* @param key
* @param key
* @param index 索引 index>=0时 0 表头1 第二个元素依次类推index<0时-1表尾-2倒数第二个元素依次类推
* @return
*/
@ -485,7 +487,7 @@ public class RedisUtils {
/**
* 将list放入缓存
* @param key
* @param key
* @param value
* @return
*/
@ -513,7 +515,7 @@ public class RedisUtils {
/**
* 将list放入缓存
* @param key
* @param key
* @param value
* @return
*/
@ -525,9 +527,9 @@ public class RedisUtils {
/**
* 将list放入缓存
* @param key
* @param key
* @param value
* @param time 时间()
* @param time 时间()
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
@ -541,7 +543,7 @@ public class RedisUtils {
/**
* 根据索引修改list中的某条数据
* @param key
* @param key
* @param index 索引
* @param value
* @return /
@ -554,7 +556,7 @@ public class RedisUtils {
/**
* 移除N个值为value
* @param key
* @param key
* @param count 移除多少个
* @param value
* @return 移除的个数

View File

@ -11,14 +11,13 @@ import org.springframework.http.HttpHeaders;
*/
public class PigFeignRequestCloseInterceptor implements RequestInterceptor {
/**
* set connection close
*
* @param template
*/
@Override
public void apply(feign.RequestTemplate template) {
template.header(HttpHeaders.CONNECTION, "close");
}
/**
* set connection close
* @param template
*/
@Override
public void apply(feign.RequestTemplate template) {
template.header(HttpHeaders.CONNECTION, "close");
}
}

View File

@ -45,56 +45,55 @@ import java.util.stream.Collectors;
@Slf4j
public class SqlFilterArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 判断Controller是否包含page 参数
*
* @param parameter 参数
* @return 是否过滤
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(Page.class);
}
/**
* 判断Controller是否包含page 参数
* @param parameter 参数
* @return 是否过滤
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(Page.class);
}
/**
* @param parameter 入参集合
* @param mavContainer model view
* @param webRequest web相关
* @param binderFactory 入参解析
* @return 检查后新的page对象
* <p>
* page 只支持查询 GET .如需解析POST获取请求报文体处理
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
/**
* @param parameter 入参集合
* @param mavContainer model view
* @param webRequest web相关
* @param binderFactory 入参解析
* @return 检查后新的page对象
* <p>
* page 只支持查询 GET .如需解析POST获取请求报文体处理
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String[] ascs = request.getParameterValues("ascs");
String[] descs = request.getParameterValues("descs");
String current = request.getParameter("current");
String size = request.getParameter("size");
String[] ascs = request.getParameterValues("ascs");
String[] descs = request.getParameterValues("descs");
String current = request.getParameter("current");
String size = request.getParameter("size");
Page<?> page = new Page<>();
if (StrUtil.isNotBlank(current)) {
page.setCurrent(Long.parseLong(current));
}
Page<?> page = new Page<>();
if (StrUtil.isNotBlank(current)) {
page.setCurrent(Long.parseLong(current));
}
if (StrUtil.isNotBlank(size)) {
page.setSize(Long.parseLong(size));
}
if (StrUtil.isNotBlank(size)) {
page.setSize(Long.parseLong(size));
}
List<OrderItem> orderItemList = new ArrayList<>();
Optional.ofNullable(ascs)
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
.filter(asc -> !SqlInjectionUtils.check(asc))
.map(OrderItem::asc)
.collect(Collectors.toList())));
Optional.ofNullable(descs)
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
.filter(desc -> !SqlInjectionUtils.check(desc))
.map(OrderItem::desc)
List<OrderItem> orderItemList = new ArrayList<>();
Optional.ofNullable(ascs)
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
.filter(asc -> !SqlInjectionUtils.check(asc))
.map(OrderItem::asc)
.collect(Collectors.toList())));
Optional.ofNullable(descs)
.ifPresent(s -> orderItemList.addAll(Arrays.stream(s)
.filter(desc -> !SqlInjectionUtils.check(desc))
.map(OrderItem::desc)
.collect(Collectors.toList())));
page.addOrder(orderItemList);

View File

@ -20,11 +20,11 @@ public class OpenAPIMetadataConfiguration implements InitializingBean, Applicati
@Override
public void afterPropertiesSet() throws Exception {
String[] beanNamesForType = applicationContext.getBeanNamesForType(ServiceInstance.class);
String[] beanNamesForType = applicationContext.getBeanNamesForType(ServiceInstance.class);
if (beanNamesForType.length == 0) {
return;
}
if (beanNamesForType.length == 0) {
return;
}
ServiceInstance serviceInstance = applicationContext.getBean(ServiceInstance.class);
serviceInstance.getMetadata().put("spring-doc", path);

View File

@ -53,53 +53,49 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysLogController {
private final SysLogService sysLogService;
private final SysLogService sysLogService;
/**
* 简单分页查询
*
* @param page 分页对象
* @param sysLog 系统日志
* @return
*/
@GetMapping("/page")
public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
return R.ok(sysLogService.getLogByPage(page, sysLog));
}
/**
* 简单分页查询
* @param page 分页对象
* @param sysLog 系统日志
* @return
*/
@GetMapping("/page")
public R getLogPage(@ParameterObject Page page, @ParameterObject SysLogDTO sysLog) {
return R.ok(sysLogService.getLogByPage(page, sysLog));
}
/**
* 批量删除日志
*
* @param ids ID
* @return success/false
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_log_del')")
public R removeByIds(@RequestBody Long[] ids) {
return R.ok(sysLogService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 批量删除日志
* @param ids ID
* @return success/false
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('sys_log_del')")
public R removeByIds(@RequestBody Long[] ids) {
return R.ok(sysLogService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 插入日志
*
* @param sysLog 日志实体
* @return success/false
*/
@Inner
@PostMapping("/save")
public R save(@Valid @RequestBody SysLog sysLog) {
return R.ok(sysLogService.saveLog(sysLog));
}
/**
* 插入日志
* @param sysLog 日志实体
* @return success/false
*/
@Inner
@PostMapping("/save")
public R save(@Valid @RequestBody SysLog sysLog) {
return R.ok(sysLogService.saveLog(sysLog));
}
/**
* 导出excel 表格
*
* @param sysLog 查询条件
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_log_export')")
/**
* 导出excel 表格
* @param sysLog 查询条件
* @return
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('sys_log_export')")
public List<SysLog> export(SysLogDTO sysLog) {
return sysLogService.getList(sysLog);
}

View File

@ -36,26 +36,24 @@ import java.util.List;
*/
public interface SysLogService extends IService<SysLog> {
/**
* 分页查询日志
*
* @param page
* @param sysLog
* @return
*/
Page getLogByPage(Page page, SysLogDTO sysLog);
/**
* 分页查询日志
* @param page
* @param sysLog
* @return
*/
Page getLogByPage(Page page, SysLogDTO sysLog);
/**
* 插入日志
*
* @param sysLog 日志对象
* @return true/false
*/
Boolean saveLog(SysLog sysLog);
/**
* 插入日志
* @param sysLog 日志对象
* @return true/false
*/
Boolean saveLog(SysLog sysLog);
/**
* 查询日志列表
* @param sysLog 查询条件
/**
* 查询日志列表
* @param sysLog 查询条件
* @return List<SysLog>
*/
List<SysLog> getList(SysLogDTO sysLog);

View File

@ -85,7 +85,7 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
if (ArrayUtil.isNotEmpty(sysLog.getCreateTime())) {
wrapper.ge(SysLog::getCreateTime, sysLog.getCreateTime()[0])
.le(SysLog::getCreateTime, sysLog.getCreateTime()[1]);
.le(SysLog::getCreateTime, sysLog.getCreateTime()[1]);
}
return wrapper;

View File

@ -69,382 +69,374 @@ import java.util.stream.Collectors;
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private final SysMenuService sysMenuService;
private final SysMenuService sysMenuService;
private final SysRoleService sysRoleService;
private final SysRoleService sysRoleService;
private final SysPostService sysPostService;
private final SysPostService sysPostService;
private final SysDeptService sysDeptService;
private final SysDeptService sysDeptService;
private final SysUserRoleMapper sysUserRoleMapper;
private final SysUserRoleMapper sysUserRoleMapper;
private final SysUserPostMapper sysUserPostMapper;
private final SysUserPostMapper sysUserPostMapper;
private final CacheManager cacheManager;
private final CacheManager cacheManager;
/**
* 保存用户信息
*
* @param userDto DTO 对象
* @return success/fail
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
sysUser.setCreateBy(userDto.getUsername());
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
baseMapper.insert(sysUser);
// 保存用户岗位信息
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> {
posts.stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(sysUserPostMapper::insert);
});
/**
* 保存用户信息
* @param userDto DTO 对象
* @return success/fail
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
sysUser.setCreateBy(userDto.getUsername());
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
baseMapper.insert(sysUser);
// 保存用户岗位信息
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> {
posts.stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(sysUserPostMapper::insert);
});
// 如果角色为空赋默认角色
if (CollUtil.isEmpty(userDto.getRole())) {
// 获取默认角色编码
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
// 默认角色
SysRole sysRole = sysRoleService
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
}
// 如果角色为空赋默认角色
if (CollUtil.isEmpty(userDto.getRole())) {
// 获取默认角色编码
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
// 默认角色
SysRole sysRole = sysRoleService
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
}
// 插入用户角色关系表
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(sysUserRoleMapper::insert);
return Boolean.TRUE;
}
// 插入用户角色关系表
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(sysUserRoleMapper::insert);
return Boolean.TRUE;
}
/**
* 通过查用户的全部信息
*
* @param sysUser 用户
* @return
*/
@Override
public UserInfo findUserInfo(SysUser sysUser) {
UserInfo userInfo = new UserInfo();
userInfo.setSysUser(sysUser);
// 设置角色列表 ID
List<Long> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId())
.stream()
.map(SysRole::getRoleId)
.collect(Collectors.toList());
userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class));
/**
* 通过查用户的全部信息
* @param sysUser 用户
* @return
*/
@Override
public UserInfo findUserInfo(SysUser sysUser) {
UserInfo userInfo = new UserInfo();
userInfo.setSysUser(sysUser);
// 设置角色列表 ID
List<Long> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId())
.stream()
.map(SysRole::getRoleId)
.collect(Collectors.toList());
userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class));
// 设置权限列表menu.permission
Set<String> permissions = new HashSet<>();
roleIds.forEach(roleId -> {
List<String> permissionList = sysMenuService.findMenuByRoleId(roleId)
.stream()
.filter(menu -> StrUtil.isNotEmpty(menu.getPermission()))
.map(SysMenu::getPermission)
.collect(Collectors.toList());
permissions.addAll(permissionList);
});
userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class));
return userInfo;
}
// 设置权限列表menu.permission
Set<String> permissions = new HashSet<>();
roleIds.forEach(roleId -> {
List<String> permissionList = sysMenuService.findMenuByRoleId(roleId)
.stream()
.filter(menu -> StrUtil.isNotEmpty(menu.getPermission()))
.map(SysMenu::getPermission)
.collect(Collectors.toList());
permissions.addAll(permissionList);
});
userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class));
return userInfo;
}
/**
* 分页查询用户信息含有角色信息
*
* @param page 分页对象
* @param userDTO 参数列表
* @return
*/
@Override
public IPage getUsersWithRolePage(Page page, UserDTO userDTO) {
return baseMapper.getUserVosPage(page, userDTO);
}
/**
* 分页查询用户信息含有角色信息
* @param page 分页对象
* @param userDTO 参数列表
* @return
*/
@Override
public IPage getUsersWithRolePage(Page page, UserDTO userDTO) {
return baseMapper.getUserVosPage(page, userDTO);
}
/**
* 通过ID查询用户信息
*
* @param id 用户ID
* @return 用户信息
*/
@Override
public UserVO selectUserVoById(Long id) {
return baseMapper.getUserVoById(id);
}
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
@Override
public UserVO selectUserVoById(Long id) {
return baseMapper.getUserVoById(id);
}
/**
* 删除用户
*
* @param ids 用户ID 列表
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteUserByIds(Long[] ids) {
// 删除 spring cache
List<SysUser> userList = baseMapper.selectBatchIds(CollUtil.toList(ids));
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
for (SysUser sysUser : userList) {
// 立即删除
cache.evictIfPresent(sysUser.getUsername());
}
/**
* 删除用户
* @param ids 用户ID 列表
* @return Boolean
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteUserByIds(Long[] ids) {
// 删除 spring cache
List<SysUser> userList = baseMapper.selectBatchIds(CollUtil.toList(ids));
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
for (SysUser sysUser : userList) {
// 立即删除
cache.evictIfPresent(sysUser.getUsername());
}
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, CollUtil.toList(ids)));
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, CollUtil.toList(ids)));
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> updateUserInfo(UserDTO userDto) {
SysUser sysUser = new SysUser();
sysUser.setPhone(userDto.getPhone());
sysUser.setUserId(SecurityUtils.getUser().getId());
sysUser.setAvatar(userDto.getAvatar());
sysUser.setNickname(userDto.getNickname());
sysUser.setName(userDto.getName());
sysUser.setEmail(userDto.getEmail());
return R.ok(this.updateById(sysUser));
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> updateUserInfo(UserDTO userDto) {
SysUser sysUser = new SysUser();
sysUser.setPhone(userDto.getPhone());
sysUser.setUserId(SecurityUtils.getUser().getId());
sysUser.setAvatar(userDto.getAvatar());
sysUser.setNickname(userDto.getNickname());
sysUser.setName(userDto.getName());
sysUser.setEmail(userDto.getEmail());
return R.ok(this.updateById(sysUser));
}
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) {
// 更新用户表信息
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setUpdateTime(LocalDateTime.now());
if (StrUtil.isNotBlank(userDto.getPassword())) {
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
}
this.updateById(sysUser);
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public Boolean updateUser(UserDTO userDto) {
// 更新用户表信息
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUser.setUpdateTime(LocalDateTime.now());
if (StrUtil.isNotBlank(userDto.getPassword())) {
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
}
this.updateById(sysUser);
// 更新用户角色表
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId()));
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(SysUserRole::insert);
// 更新用户角色表
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId()));
userDto.getRole().stream().map(roleId -> {
SysUserRole userRole = new SysUserRole();
userRole.setUserId(sysUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).forEach(SysUserRole::insert);
// 更新用户岗位表
sysUserPostMapper.delete(Wrappers.<SysUserPost>lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId()));
userDto.getPost().stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(SysUserPost::insert);
return Boolean.TRUE;
}
// 更新用户岗位表
sysUserPostMapper.delete(Wrappers.<SysUserPost>lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId()));
userDto.getPost().stream().map(postId -> {
SysUserPost userPost = new SysUserPost();
userPost.setUserId(sysUser.getUserId());
userPost.setPostId(postId);
return userPost;
}).forEach(SysUserPost::insert);
return Boolean.TRUE;
}
/**
* 查询全部的用户
*
* @param userDTO 查询条件
* @return list
*/
@Override
public List<UserExcelVO> listUser(UserDTO userDTO) {
// 根据数据权限查询全部的用户信息
List<UserVO> voList = baseMapper.selectVoList(userDTO);
// 转换成execl 对象输出
return voList.stream().map(userVO -> {
UserExcelVO excelVO = new UserExcelVO();
BeanUtils.copyProperties(userVO, excelVO);
String roleNameList = userVO.getRoleList()
.stream()
.map(SysRole::getRoleName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setRoleNameList(roleNameList);
String postNameList = userVO.getPostList()
.stream()
.map(SysPost::getPostName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setPostNameList(postNameList);
return excelVO;
}).collect(Collectors.toList());
}
/**
* 查询全部的用户
* @param userDTO 查询条件
* @return list
*/
@Override
public List<UserExcelVO> listUser(UserDTO userDTO) {
// 根据数据权限查询全部的用户信息
List<UserVO> voList = baseMapper.selectVoList(userDTO);
// 转换成execl 对象输出
return voList.stream().map(userVO -> {
UserExcelVO excelVO = new UserExcelVO();
BeanUtils.copyProperties(userVO, excelVO);
String roleNameList = userVO.getRoleList()
.stream()
.map(SysRole::getRoleName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setRoleNameList(roleNameList);
String postNameList = userVO.getPostList()
.stream()
.map(SysPost::getPostName)
.collect(Collectors.joining(StrUtil.COMMA));
excelVO.setPostNameList(postNameList);
return excelVO;
}).collect(Collectors.toList());
}
/**
* excel 导入用户, 插入正确的 错误的提示行号
*
* @param excelVOList excel 列表数据
* @param bindingResult 错误数据
* @return ok fail
*/
@Override
public R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = sysDeptService.list();
List<SysRole> roleList = sysRoleService.list();
List<SysPost> postList = sysPostService.list();
/**
* excel 导入用户, 插入正确的 错误的提示行号
* @param excelVOList excel 列表数据
* @param bindingResult 错误数据
* @return ok fail
*/
@Override
public R importUser(List<UserExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = sysDeptService.list();
List<SysRole> roleList = sysRoleService.list();
List<SysPost> postList = sysPostService.list();
// 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) {
// 个性化校验逻辑
List<SysUser> userList = this.list();
// 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) {
// 个性化校验逻辑
List<SysUser> userList = this.list();
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在
boolean exsitUserName = userList.stream()
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在
boolean exsitUserName = userList.stream()
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
// 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptName().equals(dept.getName()))
.findFirst();
if (!deptOptional.isPresent()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName()));
}
// 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptName().equals(dept.getName()))
.findFirst();
if (!deptOptional.isPresent()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptName()));
}
// 判断输入的角色名称列表是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<SysRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.collect(Collectors.toList());
// 判断输入的角色名称列表是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<SysRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.collect(Collectors.toList());
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
// 判断输入的部门名称列表是否合法
List<String> postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA);
List<SysPost> postCollList = postList.stream()
.filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name)))
.collect(Collectors.toList());
// 判断输入的部门名称列表是否合法
List<String> postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA);
List<SysPost> postCollList = postList.stream()
.filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name)))
.collect(Collectors.toList());
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, deptOptional, roleCollList, postCollList);
} else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, deptOptional, roleCollList, postCollList);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 插入excel User
*/
private void insertExcelUser(UserExcelVO excel, Optional<SysDept> deptOptional, List<SysRole> roleCollList,
List<SysPost> postCollList) {
UserDTO userDTO = new UserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入初始密码为手机号
userDTO.setPassword(userDTO.getPhone());
// 根据部门名称查询部门ID
userDTO.setDeptId(deptOptional.get().getDeptId());
// 插入岗位名称
List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).collect(Collectors.toList());
userDTO.setPost(postIdList);
// 根据角色名称查询角色ID
List<Long> roleIdList = roleCollList.stream().map(SysRole::getRoleId).collect(Collectors.toList());
userDTO.setRole(roleIdList);
// 插入用户
this.saveUser(userDTO);
}
/**
* 插入excel User
*/
private void insertExcelUser(UserExcelVO excel, Optional<SysDept> deptOptional, List<SysRole> roleCollList,
List<SysPost> postCollList) {
UserDTO userDTO = new UserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入初始密码为手机号
userDTO.setPassword(userDTO.getPhone());
// 根据部门名称查询部门ID
userDTO.setDeptId(deptOptional.get().getDeptId());
// 插入岗位名称
List<Long> postIdList = postCollList.stream().map(SysPost::getPostId).collect(Collectors.toList());
userDTO.setPost(postIdList);
// 根据角色名称查询角色ID
List<Long> roleIdList = roleCollList.stream().map(SysRole::getRoleId).collect(Collectors.toList());
userDTO.setRole(roleIdList);
// 插入用户
this.saveUser(userDTO);
}
/**
* 注册用户 赋予用户默认角色
*
* @param userDto 用户信息
* @return success/false
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> registerUser(UserDTO userDto) {
// 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (sysUser != null) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
return R.ok(saveUser(userDto));
}
/**
* 注册用户 赋予用户默认角色
* @param userDto 用户信息
* @return success/false
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R<Boolean> registerUser(UserDTO userDto) {
// 判断用户名是否存在
SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()));
if (sysUser != null) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
return R.ok(saveUser(userDto));
}
/**
* 锁定用户
*
* @param username 用户名
* @return
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username")
public R<Boolean> lockUser(String username) {
SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
/**
* 锁定用户
* @param username 用户名
* @return
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username")
public R<Boolean> lockUser(String username) {
SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
if (Objects.nonNull(sysUser)) {
sysUser.setLockFlag(CommonConstants.STATUS_LOCK);
baseMapper.updateById(sysUser);
}
return R.ok();
}
if (Objects.nonNull(sysUser)) {
sysUser.setLockFlag(CommonConstants.STATUS_LOCK);
baseMapper.updateById(sysUser);
}
return R.ok();
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R changePassword(UserDTO userDto) {
SysUser sysUser = baseMapper.selectById(SecurityUtils.getUser().getId());
if (Objects.isNull(sysUser)) {
return R.failed("用户不存在");
}
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R changePassword(UserDTO userDto) {
SysUser sysUser = baseMapper.selectById(SecurityUtils.getUser().getId());
if (Objects.isNull(sysUser)) {
return R.failed("用户不存在");
}
if (StrUtil.isEmpty(userDto.getPassword())) {
return R.failed("原密码不能为空");
}
if (StrUtil.isEmpty(userDto.getPassword())) {
return R.failed("原密码不能为空");
}
if (!ENCODER.matches(userDto.getPassword(), sysUser.getPassword())) {
log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
}
if (!ENCODER.matches(userDto.getPassword(), sysUser.getPassword())) {
log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
}
if (StrUtil.isEmpty(userDto.getNewpassword1())) {
return R.failed("新密码不能为空");
}
String password = ENCODER.encode(userDto.getNewpassword1());
if (StrUtil.isEmpty(userDto.getNewpassword1())) {
return R.failed("新密码不能为空");
}
String password = ENCODER.encode(userDto.getNewpassword1());
this.update(Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getPassword, password)
.eq(SysUser::getUserId, sysUser.getUserId()));
return R.ok();
}
this.update(Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getPassword, password)
.eq(SysUser::getUserId, sysUser.getUserId()));
return R.ok();
}
@Override
public R checkPassword(String password) {
String username = SecurityUtils.getUser().getUsername();
@Override
public R checkPassword(String password) {
String username = SecurityUtils.getUser().getUsername();
SysUser condition = new SysUser();
condition.setUsername(username);
SysUser sysUser = this.getOne(new QueryWrapper<>(condition));

View File

@ -64,7 +64,8 @@ public class JavaClassTaskInvok implements ITaskInvok {
catch (ClassNotFoundException e) {
log.error("定时任务java反射类没有找到,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射类没有找到,执行任务:" + sysJob.getClassName());
} catch (IllegalAccessException | InstantiationException e) {
}
catch (IllegalAccessException | InstantiationException e) {
log.error("定时任务java反射类异常,执行任务:{}", sysJob.getClassName());
throw new TaskException("定时任务java反射类异常,执行任务:" + sysJob.getClassName());
}