From ed715490d75ffc988e28fe89faf3d93f1f7e3c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=96=E9=87=91=E9=BE=99?= <46640269+JinlongLiao@users.noreply.github.com> Date: Sat, 20 Jun 2020 13:25:16 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=BC=93=E5=AD=98=20(#411)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit warn: 用户登录缓存 ,待验证”用户及角色“更新时的用户缓存更新,不推荐本地IP 查询,三方库可能存在bug 1、用户登录缓存,前后端交互时 数据库的访问次数 2、修复 本地IP 查询的空指针异常 * # 1、完善用户登录缓存 * # 1、redis清空时 ,用户登录缓存清空 * # # 代码合并 --- .../main/java/me/zhengjie/utils/CacheKey.java | 56 ++++++ .../main/java/me/zhengjie/utils/DateUtil.java | 169 ++++++++++++++++++ .../java/me/zhengjie/utils/RedisUtils.java | 22 +-- .../java/me/zhengjie/utils/StringUtils.java | 15 +- .../java/me/zhengjie/utils/DateUtilsTest.java | 26 +++ .../main/java/me/zhengjie/annotation/Log.java | 13 +- .../annotation/type/LogActionType.java | 45 +++++ .../modules/quartz/config/JobRunner.java | 12 +- .../security/config/SecurityConfig.java | 11 +- .../security/config/bean/LoginProperties.java | 14 ++ .../security/security/TokenConfigurer.java | 8 +- .../security/security/TokenFilter.java | 107 +++++++---- .../security/security/TokenProvider.java | 148 ++++++++------- .../security/service/UserCacheClean.java | 50 ++++++ .../service/UserDetailsServiceImpl.java | 59 ++++-- .../system/service/impl/RoleServiceImpl.java | 84 ++++++--- .../system/service/impl/UserServiceImpl.java | 71 +++++--- .../main/resources/config/application-dev.yml | 2 + .../resources/config/application-prod.yml | 4 +- .../test/java/me/zhengjie/LoginCacheTest.java | 34 ++++ 20 files changed, 753 insertions(+), 197 deletions(-) create mode 100644 eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java create mode 100644 eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java create mode 100644 eladmin-common/src/test/java/me/zhengjie/utils/DateUtilsTest.java create mode 100644 eladmin-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java create mode 100644 eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java new file mode 100644 index 00000000..b2f9aa35 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java @@ -0,0 +1,56 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.utils; + + +/** + * @author: liaojinlong + * @date: 2020/6/11 15:49 + * @apiNote: 关于缓存的Key 集合 + */ +public interface CacheKey { + /** + * 内置 用户、岗位、应用、菜单、角色 相关key + */ + String USER_MODIFY_TIME_KEY = "user:modify:time:key:"; + String APP_MODIFY_TIME_KEY = "app:modify:time:key:"; + String JOB_MODIFY_TIME_KEY = "job:modify:time:key:"; + String MENU_MODIFY_TIME_KEY = "menu:modify:time:key:"; + String ROLE_MODIFY_TIME_KEY = "role:modify:time:key:"; + String DEPT_MODIFY_TIME_KEY = "dept:modify:time:key:"; + + /** + * 用户 + */ + String USER_ID = "user::id:"; + String USER_NAME = "user::username:"; + /** + * s数据 + */ + + String DATE_USER = "data::user:"; + /** + * 菜单 + */ + String MENU_USER = "menu::user:"; + /** + * 角色授权 + */ + String ROLE_AUTH = "role::auth:"; + + String ROLE_ID = "role::id:"; +} diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java b/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java new file mode 100644 index 00000000..812f5639 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java @@ -0,0 +1,169 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.utils; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * @author: liaojinlong + * @date: 2020/6/11 16:28 + * @apiNote: JDK 8 新日期类 格式化与字符串转换 工具类 + */ +public class DateUtil { + public static final DateTimeFormatter dfyMdHms = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + public static final DateTimeFormatter dfyMd = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + /** + * LocalDateTime 转时间戳 + * + * @param localDateTime + * @return/ + */ + public static Long getTimeStamp(LocalDateTime localDateTime) { + return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond(); + } + + /** + * 时间戳转LocalDateTime + * + * @param timeStamp + * @return/ + */ + public static LocalDateTime fromTimeStamp(Long timeStamp) { + return LocalDateTime.ofEpochSecond(timeStamp, 0, OffsetDateTime.now().getOffset()); + } + + /** + * LocalDateTime 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDateTime + * @return/ + */ + public static Date toDate(LocalDateTime localDateTime) { + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + + /** + * LocalDate 转 Date + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param localDate + * @return/ + */ + public static Date toDate(LocalDate localDate) { + return toDate(localDate.atTime(LocalTime.now(ZoneId.systemDefault()))); + } + + + /** + * Date转 LocalDateTime + * Jdk8 后 不推荐使用 {@link Date} Date + * + * @param date + * @return/ + */ + public static LocalDateTime toLocalDateTime(Date date) { + return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + } + + /** + * 日期 格式化 + * + * @param localDateTime + * @param patten + * @return/ + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(patten); + return df.format(localDateTime); + } + + /** + * 日期 格式化 + * + * @param localDateTime + * @param df + * @return/ + */ + public static String localDateTimeFormat(LocalDateTime localDateTime, DateTimeFormatter df) { + return df.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime + * @return/ + */ + public static String localDateTimeFormatyMdHms(LocalDateTime localDateTime) { + return dfyMdHms.format(localDateTime); + } + + /** + * 日期格式化 yyyy-MM-dd + * + * @param localDateTime + * @return/ + */ + public String localDateTimeFormatyMd(LocalDateTime localDateTime) { + return dfyMd.format(localDateTime); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime + * @return/ + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, String pattern) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime + * @return/ + */ + public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, DateTimeFormatter dateTimeFormatter) { + return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd + * + * @param localDateTime + * @return/ + */ + public static LocalDateTime parseLocalDateTimeFormatyMd(String localDateTime) { + return LocalDateTime.from(dfyMd.parse(localDateTime)); + } + + /** + * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd HH:mm:ss + * + * @param localDateTime + * @return/ + */ + public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) { + return LocalDateTime.from(dfyMdHms.parse(localDateTime)); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java index 5004eb84..649b7e2c 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/RedisUtils.java @@ -174,19 +174,19 @@ public class RedisUtils { if (keys != null && keys.length > 0) { if (keys.length == 1) { boolean result = redisTemplate.delete(keys[0]); - System.out.println("--------------------------------------------"); - System.out.println(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result)); - System.out.println("--------------------------------------------"); + log.debug("--------------------------------------------"); + log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString()); + log.debug("--------------------------------------------"); } else { Set keySet = new HashSet<>(); for (String key : keys) { keySet.addAll(redisTemplate.keys(key)); } long count = redisTemplate.delete(keySet); - System.out.println("--------------------------------------------"); - System.out.println("成功删除缓存:" + keySet.toString()); - System.out.println("缓存删除数量:" + count + "个"); - System.out.println("--------------------------------------------"); + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keySet.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); } } } @@ -697,9 +697,9 @@ public class RedisUtils { } long count = redisTemplate.delete(keys); // 此处提示可自行删除 - System.out.println("--------------------------------------------"); - System.out.println("成功删除缓存:" + keys.toString()); - System.out.println("缓存删除数量:" + count + "个"); - System.out.println("--------------------------------------------"); + log.debug("--------------------------------------------"); + log.debug("成功删除缓存:" + keys.toString()); + log.debug("缓存删除数量:" + count + "个"); + log.debug("--------------------------------------------"); } } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java index 4c27c136..f0f31003 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java @@ -26,6 +26,7 @@ import org.lionsoul.ip2region.DbSearcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; + import javax.servlet.http.HttpServletRequest; import java.io.File; import java.net.InetAddress; @@ -41,7 +42,8 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { private static final Logger log = LoggerFactory.getLogger(StringUtils.class); private static boolean ipLocal = false; - private static DbSearcher searcher = null; + private static File file = null; + private static DbConfig config; private static final char SEPARATOR = '_'; private static final String UNKNOWN = "unknown"; @@ -54,11 +56,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { */ String path = "ip2region/ip2region.db"; String name = "ip2region.db"; - DbConfig config; try { config = new DbConfig(); - File file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name); - searcher = new DbSearcher(config, file.getPath()); + file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name); } catch (Exception e) { log.error(e.getMessage(), e); } @@ -206,9 +206,10 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { */ public static String getLocalCityInfo(String ip) { try { - DataBlock dataBlock; - dataBlock = searcher.binarySearch(ip); - String address = dataBlock.getRegion().replace("0|", ""); + DataBlock dataBlock = new DbSearcher(config, file.getPath()) + .binarySearch(ip); + String region = dataBlock.getRegion(); + String address = region.replace("0|", ""); char symbol = '|'; if (address.charAt(address.length() - 1) == symbol) { address = address.substring(0, address.length() - 1); diff --git a/eladmin-common/src/test/java/me/zhengjie/utils/DateUtilsTest.java b/eladmin-common/src/test/java/me/zhengjie/utils/DateUtilsTest.java new file mode 100644 index 00000000..a2d464cc --- /dev/null +++ b/eladmin-common/src/test/java/me/zhengjie/utils/DateUtilsTest.java @@ -0,0 +1,26 @@ +package me.zhengjie.utils; + +import org.junit.Test; + +import java.time.LocalDateTime; +import java.util.Date; + +public class DateUtilsTest { + @Test + public void test1() { + long l = System.currentTimeMillis() / 1000; + LocalDateTime localDateTime = DateUtil.fromTimeStamp(l); + System.out.printf(DateUtil.localDateTimeFormatyMdHms(localDateTime)); + } + + @Test + public void test2() { + LocalDateTime now = LocalDateTime.now(); + System.out.println(DateUtil.localDateTimeFormatyMdHms(now)); + Date date = DateUtil.toDate(now); + LocalDateTime localDateTime = DateUtil.toLocalDateTime(date); + System.out.println(DateUtil.localDateTimeFormatyMdHms(localDateTime)); + LocalDateTime localDateTime1 = DateUtil.fromTimeStamp(date.getTime() / 1000); + System.out.println(DateUtil.localDateTimeFormatyMdHms(localDateTime1)); + } +} diff --git a/eladmin-logging/src/main/java/me/zhengjie/annotation/Log.java b/eladmin-logging/src/main/java/me/zhengjie/annotation/Log.java index 1aa33a56..a050187d 100644 --- a/eladmin-logging/src/main/java/me/zhengjie/annotation/Log.java +++ b/eladmin-logging/src/main/java/me/zhengjie/annotation/Log.java @@ -15,6 +15,8 @@ */ package me.zhengjie.annotation; +import me.zhengjie.annotation.type.LogActionType; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,5 +29,14 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Log { - String value() default ""; + String value() default ""; + + /** + * 是否启用 + * + * @return + */ + boolean enable() default true; + + LogActionType type() default LogActionType.SELECT; } diff --git a/eladmin-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java b/eladmin-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java new file mode 100644 index 00000000..26549177 --- /dev/null +++ b/eladmin-logging/src/main/java/me/zhengjie/annotation/type/LogActionType.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.annotation.type; + +/** + * @author: liaojinlong + * @date: 2020/6/11 19:47 + * @apiNote: 日志类型 + */ + +public enum LogActionType { + /** + * 增删改查 + */ + ADD("新增"), + SELECT("查询"), + UPDATE("更新"), + DELETE("删除"); + private String value; + + LogActionType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java index e770570c..65d7e235 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/config/JobRunner.java @@ -19,9 +19,12 @@ import lombok.RequiredArgsConstructor; import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.repository.QuartzJobRepository; import me.zhengjie.modules.quartz.utils.QuartzManage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; + import java.util.List; /** @@ -31,19 +34,20 @@ import java.util.List; @Component @RequiredArgsConstructor public class JobRunner implements ApplicationRunner { - + private static final Logger log = LoggerFactory.getLogger(JobRunner.class); private final QuartzJobRepository quartzJobRepository; private final QuartzManage quartzManage; /** * 项目启动时重新激活启用的定时任务 + * * @param applicationArguments / */ @Override - public void run(ApplicationArguments applicationArguments){ - System.out.println("--------------------注入定时任务---------------------"); + public void run(ApplicationArguments applicationArguments) { + log.info("--------------------注入定时任务---------------------"); List quartzJobs = quartzJobRepository.findByIsPauseIsFalse(); quartzJobs.forEach(quartzManage::addJob); - System.out.println("--------------------定时任务注入完成---------------------"); + log.info("--------------------定时任务注入完成---------------------"); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java index 2f110398..07dc2724 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -17,7 +17,10 @@ package me.zhengjie.modules.security.config; import lombok.RequiredArgsConstructor; import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.modules.security.security.*; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; import me.zhengjie.utils.enums.RequestMethodEnum; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -37,6 +40,7 @@ import org.springframework.web.filter.CorsFilter; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + import java.util.*; /** @@ -53,6 +57,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private final JwtAuthenticationEntryPoint authenticationErrorHandler; private final JwtAccessDeniedHandler jwtAccessDeniedHandler; private final ApplicationContext applicationContext; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; @Bean GrantedAuthorityDefaults grantedAuthorityDefaults() { @@ -144,7 +151,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { if (null != anonymousAccess) { List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); - switch (Objects.requireNonNull(request)){ + switch (Objects.requireNonNull(request)) { case GET: get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); break; @@ -176,6 +183,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } private TokenConfigurer securityConfigurerAdapter() { - return new TokenConfigurer(tokenProvider); + return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheClean); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java index 7d948ed0..35ebcb1f 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java @@ -19,10 +19,12 @@ package me.zhengjie.modules.security.config.bean; import com.wf.captcha.*; import com.wf.captcha.base.Captcha; import me.zhengjie.exception.BadConfigurationException; + import java.util.Objects; /** * 配置文件读取 + * * @author liaojinlong * @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6 */ @@ -34,6 +36,10 @@ public class LoginProperties { private boolean singleLogin = false; private LoginCode loginCode; + /** + * 用户登录信息缓存 + */ + private boolean cacheEnable; public boolean isSingleLogin() { return singleLogin; @@ -51,6 +57,14 @@ public class LoginProperties { this.loginCode = loginCode; } + public boolean isCacheEnable() { + return cacheEnable; + } + + public void setCacheEnable(boolean cacheEnable) { + this.cacheEnable = cacheEnable; + } + /** * 获取验证码生产类 * diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java index 32a3beb6..94e25477 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenConfigurer.java @@ -16,6 +16,9 @@ package me.zhengjie.modules.security.security; import lombok.RequiredArgsConstructor; +import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.service.OnlineUserService; +import me.zhengjie.modules.security.service.UserCacheClean; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.DefaultSecurityFilterChain; @@ -28,10 +31,13 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic public class TokenConfigurer extends SecurityConfigurerAdapter { private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; @Override public void configure(HttpSecurity http) { - TokenFilter customFilter = new TokenFilter(tokenProvider); + TokenFilter customFilter = new TokenFilter(tokenProvider, properties, onlineUserService, userCacheClean); http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java index 84723b7d..7b278bc1 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java @@ -17,64 +17,93 @@ package me.zhengjie.modules.security.security; import cn.hutool.core.util.StrUtil; import io.jsonwebtoken.ExpiredJwtException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import me.zhengjie.modules.security.config.bean.SecurityProperties; +import me.zhengjie.modules.security.service.UserCacheClean; import me.zhengjie.modules.security.service.dto.OnlineUserDto; import me.zhengjie.modules.security.service.OnlineUserService; -import me.zhengjie.utils.SpringContextHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.StringUtils; import org.springframework.web.filter.GenericFilterBean; + import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.IOException; +import java.util.Objects; /** * @author / */ -@Slf4j -@RequiredArgsConstructor public class TokenFilter extends GenericFilterBean { + private static final Logger log = LoggerFactory.getLogger(TokenFilter.class); - private final TokenProvider tokenProvider; - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) - throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; - String token = resolveToken(httpServletRequest); - // 对于 Token 为空的不需要去查 Redis - if(StrUtil.isNotBlank(token)){ - OnlineUserDto onlineUserDto = null; - SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class); - try { - OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class); - onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token); - } catch (ExpiredJwtException e) { - log.error(e.getMessage()); - } - if (onlineUserDto != null && StringUtils.hasText(token)) { - Authentication authentication = tokenProvider.getAuthentication(token); - SecurityContextHolder.getContext().setAuthentication(authentication); - // Token 续期 - tokenProvider.checkRenewal(token); - } - } - filterChain.doFilter(servletRequest, servletResponse); - } + private final TokenProvider tokenProvider; + private final SecurityProperties properties; + private final OnlineUserService onlineUserService; + private final UserCacheClean userCacheClean; - private String resolveToken(HttpServletRequest request) { - SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class); - String bearerToken = request.getHeader(properties.getHeader()); - if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) { - // 去掉令牌前缀 - return bearerToken.replace(properties.getTokenStartWith(),""); - } - return null; - } + /** + * @param tokenProvider Token + * @param properties JWT + * @param onlineUserService 用户在线 + * @param userCacheClean 用户缓存清理工具 + */ + public TokenFilter(TokenProvider tokenProvider, SecurityProperties properties, OnlineUserService onlineUserService, UserCacheClean userCacheClean) { + this.properties = properties; + this.onlineUserService = onlineUserService; + this.tokenProvider = tokenProvider; + this.userCacheClean = userCacheClean; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + String token = resolveToken(httpServletRequest); + // 对于 Token 为空的不需要去查 Redis + if (StrUtil.isNotBlank(token)) { + OnlineUserDto onlineUserDto = null; + boolean cleanUserCache = false; + try { + onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token); + } catch (ExpiredJwtException e) { + log.error(e.getMessage()); + cleanUserCache = true; + } finally { + if (cleanUserCache || Objects.isNull(onlineUserDto)) { + userCacheClean.cleanUserCache(String.valueOf(tokenProvider.getClaims(token).get(TokenProvider.AUTHORITIES_KEY))); + } + } + if (onlineUserDto != null && StringUtils.hasText(token)) { + Authentication authentication = tokenProvider.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + // Token 续期 + tokenProvider.checkRenewal(token); + } + } + filterChain.doFilter(servletRequest, servletResponse); + } + + /** + * 初步检测Token + * + * @param request + * @return + */ + private String resolveToken(HttpServletRequest request) { + String bearerToken = request.getHeader(properties.getHeader()); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) { + // 去掉令牌前缀 + return bearerToken.replace(properties.getTokenStartWith(), ""); + } else { + log.debug("非法Token:{}", bearerToken); + } + return null; + } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java index 91439056..df294967 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java @@ -22,7 +22,6 @@ import cn.hutool.core.util.ObjectUtil; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.utils.RedisUtils; @@ -33,6 +32,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; + import javax.servlet.http.HttpServletRequest; import java.security.Key; import java.util.Arrays; @@ -47,75 +47,101 @@ import java.util.stream.Collectors; */ @Slf4j @Component -@RequiredArgsConstructor public class TokenProvider implements InitializingBean { - private final SecurityProperties properties; - private final RedisUtils redisUtils; - private static final String AUTHORITIES_KEY = "auth"; - private Key key; + private final SecurityProperties properties; + private final RedisUtils redisUtils; + public static final String AUTHORITIES_KEY = "auth"; + private Key key; + private JwtParser jwtParser; + private JwtBuilder jwtBuilder; - @Override - public void afterPropertiesSet() { - byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); - this.key = Keys.hmacShaKeyFor(keyBytes); - } + public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) { + this.properties = properties; + this.redisUtils = redisUtils; + } - public String createToken(Authentication authentication) { - String authorities = authentication.getAuthorities().stream() - .map(GrantedAuthority::getAuthority) - .collect(Collectors.joining(",")); + @Override + public void afterPropertiesSet() { + byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); + this.key = Keys.hmacShaKeyFor(keyBytes); + jwtParser = Jwts.parserBuilder() + .setSigningKey(key) + .build(); + jwtBuilder = Jwts.builder() + .signWith(key, SignatureAlgorithm.HS512); + } - return Jwts.builder() - .setSubject(authentication.getName()) - .claim(AUTHORITIES_KEY, authorities) - .signWith(key, SignatureAlgorithm.HS512) - // 加入ID确保生成的 Token 都不一致 - .setId(IdUtil.simpleUUID()) - .compact(); - } + /** + * 创建Token 设置永不过期, + * Token 的时间有效性转到Redis 维护 + * + * @param authentication + * @return + */ + public String createToken(Authentication authentication) { + /** + * 获取权限列表 + */ + String authorities = authentication.getAuthorities().stream() + .map(GrantedAuthority::getAuthority) + .collect(Collectors.joining(",")); - Authentication getAuthentication(String token) { - Claims claims = Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(token) - .getBody(); + return jwtBuilder + // 加入ID确保生成的 Token 都不一致 + .setId(IdUtil.simpleUUID()) + .claim(AUTHORITIES_KEY, authorities) + .setSubject(authentication.getName()) + .compact(); + } - // fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException - Object authoritiesStr = claims.get(AUTHORITIES_KEY); - Collection authorities = - ObjectUtil.isNotEmpty(authoritiesStr) ? - Arrays.stream(authoritiesStr.toString().split(",")) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()) : Collections.emptyList(); + /** + * 依据Token 获取鉴权信息 + * + * @param token + * @return + */ + Authentication getAuthentication(String token) { + Claims claims = getClaims(token); - User principal = new User(claims.getSubject(), "", authorities); + // fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException + Object authoritiesStr = claims.get(AUTHORITIES_KEY); + Collection authorities = + ObjectUtil.isNotEmpty(authoritiesStr) ? + Arrays.stream(authoritiesStr.toString().split(",")) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()) : Collections.emptyList(); + User principal = new User(claims.getSubject(), "******", authorities); + return new UsernamePasswordAuthenticationToken(principal, token, authorities); + } - return new UsernamePasswordAuthenticationToken(principal, token, authorities); - } + public Claims getClaims(String token) { + return jwtParser + .parseClaimsJws(token) + .getBody(); + } - /** - * @param token 需要检查的token - */ - public void checkRenewal(String token){ - // 判断是否续期token,计算token的过期时间 - long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000; - Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time); - // 判断当前时间与过期时间的时间差 - long differ = expireDate.getTime() - System.currentTimeMillis(); - // 如果在续期检查的范围内,则续期 - if(differ <= properties.getDetect()){ - long renew = time + properties.getRenew(); - redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS); - } - } + /** + * @param token 需要检查的token + */ + public void checkRenewal(String token) { + // 判断是否续期token,计算token的过期时间 + long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000; + Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time); + // 判断当前时间与过期时间的时间差 + long differ = expireDate.getTime() - System.currentTimeMillis(); + // 如果在续期检查的范围内,则续期 + if (differ <= properties.getDetect()) { + long renew = time + properties.getRenew(); + redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS); + } + } - public String getToken(HttpServletRequest request){ - final String requestHeader = request.getHeader(properties.getHeader()); - if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) { - return requestHeader.substring(7); - } - return null; - } + public String getToken(HttpServletRequest request) { + final String requestHeader = request.getHeader(properties.getHeader()); + if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) { + return requestHeader.substring(7); + } + return null; + } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java new file mode 100644 index 00000000..fbd7093b --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java @@ -0,0 +1,50 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.zhengjie.modules.security.service; + +import me.zhengjie.utils.StringUtils; +import org.springframework.stereotype.Component; + +/** + * @author: liaojinlong + * @date: 2020/6/11 18:01 + * @apiNote: 用于清理 用户登录信息缓存,为防止Spring循环依赖与安全考虑 ,单独构成工具类 + */ +@Component +public class UserCacheClean { + + + /** + * 清理特定用户缓存信息
+ * 用户信息变更时 + * + * @param userName + */ + public void cleanUserCache(String userName) { + if (StringUtils.isNotEmpty(userName)) { + UserDetailsServiceImpl.userDtoCache.remove(userName); + } + } + + /** + * 清理所有用户的缓存信息
+ * ,如发生角色授权信息变化,可以简便的全部失效缓存 + */ + public void cleanAll() { + UserDetailsServiceImpl.userDtoCache.clear(); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java index 71f263e1..857bf021 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java @@ -18,6 +18,7 @@ package me.zhengjie.modules.security.service; import lombok.RequiredArgsConstructor; import me.zhengjie.exception.BadRequestException; import me.zhengjie.exception.EntityNotFoundException; +import me.zhengjie.modules.security.config.bean.LoginProperties; import me.zhengjie.modules.security.service.dto.JwtUserDto; import me.zhengjie.modules.system.service.DataService; import me.zhengjie.modules.system.service.RoleService; @@ -27,6 +28,9 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * @author Zheng Jie * @date 2018-11-22 @@ -34,31 +38,52 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor @Service("userDetailsService") public class UserDetailsServiceImpl implements UserDetailsService { - private final UserService userService; private final RoleService roleService; private final DataService dataService; + private final LoginProperties loginProperties; + + public void setEnableCache(boolean enableCache) { + this.loginProperties.setCacheEnable(enableCache); + } + + /** + * 用户信息缓存 + * + * @see {@link UserCacheClean} + */ + static Map userDtoCache = new ConcurrentHashMap<>(); @Override public JwtUserDto loadUserByUsername(String username) { - UserDto user; - try { - user = userService.findByName(username); - } catch (EntityNotFoundException e) { - // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException - throw new UsernameNotFoundException("", e); + boolean searchDb = true; + JwtUserDto jwtUserDto = null; + if (loginProperties.isCacheEnable() && userDtoCache.containsKey(username)) { + jwtUserDto = userDtoCache.get(username); + searchDb = false; } - if (user == null) { - throw new UsernameNotFoundException(""); - } else { - if (!user.getEnabled()) { - throw new BadRequestException("账号未激活"); + if (searchDb) { + UserDto user; + try { + user = userService.findByName(username); + } catch (EntityNotFoundException e) { + // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException + throw new UsernameNotFoundException("", e); + } + if (user == null) { + throw new UsernameNotFoundException(""); + } else { + if (!user.getEnabled()) { + throw new BadRequestException("账号未激活"); + } + jwtUserDto = new JwtUserDto( + user, + dataService.getDeptIds(user), + roleService.mapToGrantedAuthorities(user) + ); + userDtoCache.put(username, jwtUserDto); } - return new JwtUserDto( - user, - dataService.getDeptIds(user), - roleService.mapToGrantedAuthorities(user) - ); } + return jwtUserDto; } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java index c680d35d..d694334c 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java @@ -15,8 +15,10 @@ */ package me.zhengjie.modules.system.service.impl; +import cn.hutool.core.collection.CollectionUtil; import lombok.RequiredArgsConstructor; import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.security.service.UserCacheClean; import me.zhengjie.modules.system.domain.Menu; import me.zhengjie.modules.system.domain.Role; import me.zhengjie.exception.EntityExistException; @@ -40,6 +42,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; @@ -59,6 +62,7 @@ public class RoleServiceImpl implements RoleService { private final RoleSmallMapper roleSmallMapper; private final RedisUtils redisUtils; private final UserRepository userRepository; + private final UserCacheClean userCacheClean; @Override public List queryAll() { @@ -68,12 +72,12 @@ public class RoleServiceImpl implements RoleService { @Override public List queryAll(RoleQueryCriteria criteria) { - return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder))); + return roleMapper.toDto(roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); } @Override public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) { - Page page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + Page page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); return PageUtil.toPage(page.map(roleMapper::toDto)); } @@ -82,15 +86,15 @@ public class RoleServiceImpl implements RoleService { @Transactional(rollbackFor = Exception.class) public RoleDto findById(long id) { Role role = roleRepository.findById(id).orElseGet(Role::new); - ValidationUtil.isNull(role.getId(),"Role","id",id); + ValidationUtil.isNull(role.getId(), "Role", "id", id); return roleMapper.toDto(role); } @Override @Transactional(rollbackFor = Exception.class) public void create(Role resources) { - if(roleRepository.findByName(resources.getName()) != null){ - throw new EntityExistException(Role.class,"username",resources.getName()); + if (roleRepository.findByName(resources.getName()) != null) { + throw new EntityExistException(Role.class, "username", resources.getName()); } roleRepository.save(resources); } @@ -99,12 +103,12 @@ public class RoleServiceImpl implements RoleService { @Transactional(rollbackFor = Exception.class) public void update(Role resources) { Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new); - ValidationUtil.isNull(role.getId(),"Role","id",resources.getId()); + ValidationUtil.isNull(role.getId(), "Role", "id", resources.getId()); Role role1 = roleRepository.findByName(resources.getName()); - if(role1 != null && !role1.getId().equals(role.getId())){ - throw new EntityExistException(Role.class,"username",resources.getName()); + if (role1 != null && !role1.getId().equals(role.getId())) { + throw new EntityExistException(Role.class, "username", resources.getName()); } role.setName(resources.getName()); role.setDescription(resources.getDescription()); @@ -120,16 +124,13 @@ public class RoleServiceImpl implements RoleService { public void updateMenu(Role resources, RoleDto roleDTO) { Role role = roleMapper.toEntity(roleDTO); List users = userRepository.findByRoleId(role.getId()); - Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); // 更新菜单 role.setMenus(resources.getMenus()); - // 清理缓存 - redisUtils.delByKeys("menu::user:",userIds); - redisUtils.delByKeys("role::auth:",userIds); - redisUtils.del("role::id:" + resources.getId()); + cleanCache(resources, users); roleRepository.save(role); } + @Override @Transactional(rollbackFor = Exception.class) public void untiedMenu(Long menuId) { @@ -166,7 +167,7 @@ public class RoleServiceImpl implements RoleService { public List mapToGrantedAuthorities(UserDto user) { Set permissions = new HashSet<>(); // 如果是管理员直接返回 - if(user.getIsAdmin()){ + if (user.getIsAdmin()) { permissions.add("admin"); return permissions.stream().map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); @@ -183,7 +184,7 @@ public class RoleServiceImpl implements RoleService { public void download(List roles, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); for (RoleDto role : roles) { - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); map.put("角色名称", role.getName()); map.put("角色级别", role.getLevel()); map.put("描述", role.getDescription()); @@ -193,21 +194,9 @@ public class RoleServiceImpl implements RoleService { FileUtil.downloadExcel(list, response); } - /** - * 清理缓存 - * @param id / - */ - public void delCaches(Long id){ - List users = userRepository.findByRoleId(id); - Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); - redisUtils.delByKeys("data::user:",userIds); - redisUtils.delByKeys("menu::user:",userIds); - redisUtils.delByKeys("role::auth:",userIds); - } - @Override public void verification(Set ids) { - if(userRepository.countByRoles(ids) > 0){ + if (userRepository.countByRoles(ids) > 0) { throw new BadRequestException("所选角色存在用户关联,请解除关联再试!"); } } @@ -216,4 +205,43 @@ public class RoleServiceImpl implements RoleService { public List findInMenuId(List menuIds) { return roleRepository.findInMenuId(menuIds); } + + /** + * 清理缓存 + * + * @param id / + */ + public void delCaches(Long id) { + List users = userRepository.findByRoleId(id); + if (CollectionUtil.isNotEmpty(users)) { + users.stream().forEach(item -> { + userCacheClean.cleanUserCache(item.getUsername()); + }); + Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); + redisUtils.delByKeys(CacheKey.DATE_USER, userIds); + redisUtils.delByKeys(CacheKey.MENU_USER, userIds); + redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + } + + } + + /** + * 清理缓存 + * + * @param resources + * @param users + */ + private void cleanCache(Role resources, List users) { + // 清理缓存 + if (CollectionUtil.isNotEmpty(users)) { + users.stream().forEach(item -> { + userCacheClean.cleanUserCache(item.getUsername()); + }); + Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); + redisUtils.delByKeys(CacheKey.MENU_USER, userIds); + redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + redisUtils.del(CacheKey.ROLE_ID + resources.getId()); + } + } + } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java index 5c1e5ae9..7f788e8c 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java @@ -17,6 +17,7 @@ package me.zhengjie.modules.system.service.impl; import lombok.RequiredArgsConstructor; import me.zhengjie.config.FileProperties; +import me.zhengjie.modules.security.service.UserCacheClean; import me.zhengjie.modules.system.domain.User; import me.zhengjie.exception.EntityExistException; import me.zhengjie.exception.EntityNotFoundException; @@ -35,7 +36,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; + import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotBlank; import java.io.File; import java.io.IOException; import java.util.*; @@ -54,16 +57,17 @@ public class UserServiceImpl implements UserService { private final UserMapper userMapper; private final FileProperties properties; private final RedisUtils redisUtils; + private final UserCacheClean userCacheClean; @Override public Object queryAll(UserQueryCriteria criteria, Pageable pageable) { - Page page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable); + Page page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); return PageUtil.toPage(page.map(userMapper::toDto)); } @Override public List queryAll(UserQueryCriteria criteria) { - List users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); + List users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)); return userMapper.toDto(users); } @@ -72,18 +76,18 @@ public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) public UserDto findById(long id) { User user = userRepository.findById(id).orElseGet(User::new); - ValidationUtil.isNull(user.getId(),"User","id",id); + ValidationUtil.isNull(user.getId(), "User", "id", id); return userMapper.toDto(user); } @Override @Transactional(rollbackFor = Exception.class) public void create(User resources) { - if(userRepository.findByUsername(resources.getUsername())!=null){ - throw new EntityExistException(User.class,"username",resources.getUsername()); + if (userRepository.findByUsername(resources.getUsername()) != null) { + throw new EntityExistException(User.class, "username", resources.getUsername()); } - if(userRepository.findByEmail(resources.getEmail())!=null){ - throw new EntityExistException(User.class,"email",resources.getEmail()); + if (userRepository.findByEmail(resources.getEmail()) != null) { + throw new EntityExistException(User.class, "email", resources.getEmail()); } userRepository.save(resources); } @@ -92,22 +96,22 @@ public class UserServiceImpl implements UserService { @Transactional(rollbackFor = Exception.class) public void update(User resources) { User user = userRepository.findById(resources.getId()).orElseGet(User::new); - ValidationUtil.isNull(user.getId(),"User","id",resources.getId()); + ValidationUtil.isNull(user.getId(), "User", "id", resources.getId()); User user1 = userRepository.findByUsername(resources.getUsername()); User user2 = userRepository.findByEmail(resources.getEmail()); - if(user1 !=null&&!user.getId().equals(user1.getId())){ - throw new EntityExistException(User.class,"username",resources.getUsername()); + if (user1 != null && !user.getId().equals(user1.getId())) { + throw new EntityExistException(User.class, "username", resources.getUsername()); } - if(user2!=null&&!user.getId().equals(user2.getId())){ - throw new EntityExistException(User.class,"email",resources.getEmail()); + if (user2 != null && !user.getId().equals(user2.getId())) { + throw new EntityExistException(User.class, "email", resources.getEmail()); } // 如果用户的角色改变 if (!resources.getRoles().equals(user.getRoles())) { - redisUtils.del("data::user:" + resources.getId()); - redisUtils.del("menu::user:" + resources.getId()); - redisUtils.del("role::auth:" + resources.getId()); + redisUtils.del(CacheKey.DATE_USER + resources.getId()); + redisUtils.del(CacheKey.MENU_USER + resources.getId()); + redisUtils.del(CacheKey.ROLE_AUTH + resources.getId()); } // 如果用户名称修改 if(!resources.getUsername().equals(user.getUsername())){ @@ -164,8 +168,9 @@ public class UserServiceImpl implements UserService { @Override @Transactional(rollbackFor = Exception.class) public void updatePass(String username, String pass) { - userRepository.updatePass(username,pass,new Date()); + userRepository.updatePass(username, pass, new Date()); redisUtils.del("user::username:" + username); + flushCache(username); } @Override @@ -177,18 +182,23 @@ public class UserServiceImpl implements UserService { user.setAvatarPath(Objects.requireNonNull(file).getPath()); user.setAvatarName(file.getName()); userRepository.save(user); - if(StringUtils.isNotBlank(oldPath)){ + if (StringUtils.isNotBlank(oldPath)) { FileUtil.del(oldPath); } - redisUtils.del("user::username:" + user.getUsername()); - return new HashMap(1){{put("avatar",file.getName());}}; + @NotBlank String username = user.getUsername(); + redisUtils.del(CacheKey.USER_NAME + username); + flushCache(username); + return new HashMap(1) {{ + put("avatar", file.getName()); + }}; } @Override @Transactional(rollbackFor = Exception.class) public void updateEmail(String username, String email) { - userRepository.updateEmail(username,email); - redisUtils.del("user::username:" + username); + userRepository.updateEmail(username, email); + redisUtils.del(CacheKey.USER_NAME + username); + flushCache(username); } @Override @@ -196,7 +206,7 @@ public class UserServiceImpl implements UserService { List> list = new ArrayList<>(); for (UserDto userDTO : queryAll) { List roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList()); - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); map.put("用户名", userDTO.getUsername()); map.put("角色", roles); map.put("部门", userDTO.getDept().getName()); @@ -213,10 +223,21 @@ public class UserServiceImpl implements UserService { /** * 清理缓存 + * * @param id / */ - public void delCaches(Long id, String username){ - redisUtils.del("user::id:" + id); - redisUtils.del("user::username:" + username); + public void delCaches(Long id, String username) { + redisUtils.del(CacheKey.USER_ID + id); + redisUtils.del(CacheKey.USER_NAME + username); + flushCache(username); + } + + /** + * 清理 登陆时 用户缓存信息 + * + * @param username + */ + private void flushCache(String username) { + userCacheClean.cleanUserCache(username); } } diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 0811295c..d9a67418 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -46,6 +46,8 @@ spring: # 登录相关配置 login: + # 登录缓存 + cache-enable: true # 是否限制单用户登录 single: false # 验证码 diff --git a/eladmin-system/src/main/resources/config/application-prod.yml b/eladmin-system/src/main/resources/config/application-prod.yml index cd26ca0f..a4122c28 100644 --- a/eladmin-system/src/main/resources/config/application-prod.yml +++ b/eladmin-system/src/main/resources/config/application-prod.yml @@ -48,6 +48,8 @@ spring: # 登录相关配置 login: + # 登录缓存 + cache-enable: true # 是否限制单用户登录 single: false # 验证码 @@ -83,7 +85,7 @@ jwt: # IP 本地解析 ip: - local-parsing: true + local-parsing: false #是否允许生成代码,生产环境设置为false generator: diff --git a/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java b/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java new file mode 100644 index 00000000..008f61a8 --- /dev/null +++ b/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java @@ -0,0 +1,34 @@ +package me.zhengjie; + +import me.zhengjie.modules.security.service.UserDetailsServiceImpl; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class LoginCacheTest { + @Resource(name = "userDetailsService") + private UserDetailsServiceImpl userDetailsService; + private int size = 10000; + + @Test + public void testCache() { + long start1 = System.currentTimeMillis(); + for (int i = 0; i < size; i++) { + userDetailsService.loadUserByUsername("admin"); + } + long end1 = System.currentTimeMillis(); + //关闭缓存 + userDetailsService.setEnableCache(false); + long start2 = System.currentTimeMillis(); + for (int i = 0; i < size; i++) { + userDetailsService.loadUserByUsername("admin"); + } + long end2 = System.currentTimeMillis(); + System.out.printf("使用缓存:" + (end1 - start1) + "毫秒\n 不使用缓存:" + (end2 - start2) + "毫秒"); + } +} From 157373eb8bed1cea2d20224997c5a658d547e736 Mon Sep 17 00:00:00 2001 From: lj-zhu <54331324@qq.com> Date: Sun, 21 Jun 2020 13:27:09 +0800 Subject: [PATCH 2/9] Update ExecutionJob.java (#416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 不是子任务时,uuid是空的,需要加个判断。 --- .../me/zhengjie/modules/quartz/utils/ExecutionJob.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java index e79193f8..380f5cf9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java @@ -54,6 +54,8 @@ public class ExecutionJob extends QuartzJobBean { QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class); QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class); RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class); + + String uuid = quartzJob.getUuid(); QuartzLog log = new QuartzLog(); log.setJobName(quartzJob.getJobName()); @@ -72,7 +74,9 @@ public class ExecutionJob extends QuartzJobBean { future.get(); long times = System.currentTimeMillis() - startTime; log.setTime(times); - redisUtils.set(quartzJob.getUuid(), true); + if(StringUtils.isNotBlank(uuid)) { + redisUtils.set(uuid, true); + } // 任务状态 log.setIsSuccess(true); System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒"); @@ -84,7 +88,9 @@ public class ExecutionJob extends QuartzJobBean { quartzJobService.executionSubJob(tasks); } } catch (Exception e) { - redisUtils.set(quartzJob.getUuid(), false); + if(StringUtils.isNotBlank(uuid)) { + redisUtils.set(uuid, false); + } System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName()); System.out.println("--------------------------------------------------------------"); long times = System.currentTimeMillis() - startTime; From fbd09cf4d21c4791f9b614f695934b7dc853dbcf Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 21 Jun 2020 16:17:14 +0800 Subject: [PATCH 3/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java | 3 +-- .../java/me/zhengjie/modules/quartz/utils/ExecutionJob.java | 1 + .../zhengjie/modules/system/service/impl/RoleServiceImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java index b2f9aa35..aee6b47f 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package me.zhengjie.utils; @@ -23,6 +22,7 @@ package me.zhengjie.utils; * @apiNote: 关于缓存的Key 集合 */ public interface CacheKey { + /** * 内置 用户、岗位、应用、菜单、角色 相关key */ @@ -41,7 +41,6 @@ public interface CacheKey { /** * s数据 */ - String DATE_USER = "data::user:"; /** * 菜单 diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java index 380f5cf9..798f9c35 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java @@ -28,6 +28,7 @@ import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.service.EmailService; import me.zhengjie.utils.RedisUtils; import me.zhengjie.utils.SpringContextHolder; +import me.zhengjie.utils.StringUtils; import me.zhengjie.utils.ThrowableUtil; import org.quartz.JobExecutionContext; import org.springframework.scheduling.annotation.Async; diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java index d694334c..a15d4edc 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java @@ -234,7 +234,7 @@ public class RoleServiceImpl implements RoleService { private void cleanCache(Role resources, List users) { // 清理缓存 if (CollectionUtil.isNotEmpty(users)) { - users.stream().forEach(item -> { + users.forEach(item -> { userCacheClean.cleanUserCache(item.getUsername()); }); Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); From 6bc2a8ada15dc699fa98e794a12b888c9d4aa9ca Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 21 Jun 2020 16:33:10 +0800 Subject: [PATCH 4/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20=E5=89=8D=E7=AB=AF=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9=E6=94=B9=E4=B8=BA=20date-r?= =?UTF-8?q?ange-picker=20=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/template/generator/front/index.ftl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/eladmin-system/src/main/resources/template/generator/front/index.ftl b/eladmin-system/src/main/resources/template/generator/front/index.ftl index 080d0703..df5c73ca 100644 --- a/eladmin-system/src/main/resources/template/generator/front/index.ftl +++ b/eladmin-system/src/main/resources/template/generator/front/index.ftl @@ -17,16 +17,11 @@ <#if betweens??> <#list betweens as column> <#if column.queryType = 'BetWeen'> - @@ -125,6 +120,7 @@ import crudOperation from '@crud/CRUD.operation' import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' + const defaultForm = { <#if columns??><#list columns as column>${column.changeColumnName}: null<#if column_has_next>, } export default { name: '${className}', From 96660b949d4c548aa933f4dcfabecc489e9850de Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 21 Jun 2020 17:24:14 +0800 Subject: [PATCH 5/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=EF=BC=8C=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/me/zhengjie/utils/CacheKey.java | 9 ++- .../main/java/me/zhengjie/utils/DateUtil.java | 73 ++++++++----------- .../rest/AuthorizationController.java | 4 - .../security/security/TokenFilter.java | 4 +- .../security/security/TokenProvider.java | 13 ++-- .../security/service/UserCacheClean.java | 3 +- .../service/UserDetailsServiceImpl.java | 2 - .../modules/system/rest/RoleController.java | 3 - .../system/service/impl/RoleServiceImpl.java | 37 ++-------- .../system/service/impl/UserServiceImpl.java | 2 +- .../test/java/me/zhengjie/LoginCacheTest.java | 6 +- .../service/impl/AliPayServiceImpl.java | 6 +- .../service/impl/EmailServiceImpl.java | 4 +- .../service/impl/QiNiuServiceImpl.java | 4 +- 14 files changed, 64 insertions(+), 106 deletions(-) diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java index aee6b47f..24ad0c59 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/CacheKey.java @@ -15,11 +15,10 @@ */ package me.zhengjie.utils; - /** * @author: liaojinlong * @date: 2020/6/11 15:49 - * @apiNote: 关于缓存的Key 集合 + * @apiNote: 关于缓存的Key集合 */ public interface CacheKey { @@ -39,7 +38,7 @@ public interface CacheKey { String USER_ID = "user::id:"; String USER_NAME = "user::username:"; /** - * s数据 + * 数据 */ String DATE_USER = "data::user:"; /** @@ -50,6 +49,8 @@ public interface CacheKey { * 角色授权 */ String ROLE_AUTH = "role::auth:"; - + /** + * 角色信息 + */ String ROLE_ID = "role::id:"; } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java b/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java index 812f5639..0b0bf637 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/DateUtil.java @@ -26,14 +26,15 @@ import java.util.Date; * @apiNote: JDK 8 新日期类 格式化与字符串转换 工具类 */ public class DateUtil { - public static final DateTimeFormatter dfyMdHms = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - public static final DateTimeFormatter dfyMd = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + public static final DateTimeFormatter DFY_MD_HMS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + public static final DateTimeFormatter DFY_MD = DateTimeFormatter.ofPattern("yyyy-MM-dd"); /** * LocalDateTime 转时间戳 * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static Long getTimeStamp(LocalDateTime localDateTime) { return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond(); @@ -42,8 +43,8 @@ public class DateUtil { /** * 时间戳转LocalDateTime * - * @param timeStamp - * @return/ + * @param timeStamp / + * @return / */ public static LocalDateTime fromTimeStamp(Long timeStamp) { return LocalDateTime.ofEpochSecond(timeStamp, 0, OffsetDateTime.now().getOffset()); @@ -53,8 +54,8 @@ public class DateUtil { * LocalDateTime 转 Date * Jdk8 后 不推荐使用 {@link Date} Date * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static Date toDate(LocalDateTime localDateTime) { return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); @@ -64,8 +65,8 @@ public class DateUtil { * LocalDate 转 Date * Jdk8 后 不推荐使用 {@link Date} Date * - * @param localDate - * @return/ + * @param localDate / + * @return / */ public static Date toDate(LocalDate localDate) { return toDate(localDate.atTime(LocalTime.now(ZoneId.systemDefault()))); @@ -76,8 +77,8 @@ public class DateUtil { * Date转 LocalDateTime * Jdk8 后 不推荐使用 {@link Date} Date * - * @param date - * @return/ + * @param date / + * @return / */ public static LocalDateTime toLocalDateTime(Date date) { return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); @@ -86,9 +87,9 @@ public class DateUtil { /** * 日期 格式化 * - * @param localDateTime - * @param patten - * @return/ + * @param localDateTime / + * @param patten / + * @return / */ public static String localDateTimeFormat(LocalDateTime localDateTime, String patten) { DateTimeFormatter df = DateTimeFormatter.ofPattern(patten); @@ -98,9 +99,9 @@ public class DateUtil { /** * 日期 格式化 * - * @param localDateTime - * @param df - * @return/ + * @param localDateTime / + * @param df / + * @return / */ public static String localDateTimeFormat(LocalDateTime localDateTime, DateTimeFormatter df) { return df.format(localDateTime); @@ -109,28 +110,28 @@ public class DateUtil { /** * 日期格式化 yyyy-MM-dd HH:mm:ss * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static String localDateTimeFormatyMdHms(LocalDateTime localDateTime) { - return dfyMdHms.format(localDateTime); + return DFY_MD_HMS.format(localDateTime); } /** * 日期格式化 yyyy-MM-dd * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public String localDateTimeFormatyMd(LocalDateTime localDateTime) { - return dfyMd.format(localDateTime); + return DFY_MD.format(localDateTime); } /** * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, String pattern) { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern); @@ -140,30 +141,20 @@ public class DateUtil { /** * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static LocalDateTime parseLocalDateTimeFormat(String localDateTime, DateTimeFormatter dateTimeFormatter) { return LocalDateTime.from(dateTimeFormatter.parse(localDateTime)); } - /** - * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd - * - * @param localDateTime - * @return/ - */ - public static LocalDateTime parseLocalDateTimeFormatyMd(String localDateTime) { - return LocalDateTime.from(dfyMd.parse(localDateTime)); - } - /** * 字符串转 LocalDateTime ,字符串格式 yyyy-MM-dd HH:mm:ss * - * @param localDateTime - * @return/ + * @param localDateTime / + * @return / */ public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) { - return LocalDateTime.from(dfyMdHms.parse(localDateTime)); + return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime)); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java index 77c84783..afed088a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthorizationController.java @@ -16,7 +16,6 @@ package me.zhengjie.modules.security.rest; import cn.hutool.core.util.IdUtil; -import com.wf.captcha.ArithmeticCaptcha; import com.wf.captcha.base.Captcha; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -38,7 +37,6 @@ import me.zhengjie.utils.RsaUtils; import me.zhengjie.utils.RedisUtils; import me.zhengjie.utils.SecurityUtils; import me.zhengjie.utils.StringUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -47,7 +45,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; - import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; @@ -91,7 +88,6 @@ public class AuthorizationController { } UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(authUser.getUsername(), password); - Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); // 生成令牌 diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java index 7b278bc1..c5cde05a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenFilter.java @@ -93,8 +93,8 @@ public class TokenFilter extends GenericFilterBean { /** * 初步检测Token * - * @param request - * @return + * @param request / + * @return / */ private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader(properties.getHeader()); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java index df294967..3918568d 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java @@ -52,7 +52,6 @@ public class TokenProvider implements InitializingBean { private final SecurityProperties properties; private final RedisUtils redisUtils; public static final String AUTHORITIES_KEY = "auth"; - private Key key; private JwtParser jwtParser; private JwtBuilder jwtBuilder; @@ -64,7 +63,7 @@ public class TokenProvider implements InitializingBean { @Override public void afterPropertiesSet() { byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret()); - this.key = Keys.hmacShaKeyFor(keyBytes); + Key key = Keys.hmacShaKeyFor(keyBytes); jwtParser = Jwts.parserBuilder() .setSigningKey(key) .build(); @@ -76,11 +75,11 @@ public class TokenProvider implements InitializingBean { * 创建Token 设置永不过期, * Token 的时间有效性转到Redis 维护 * - * @param authentication - * @return + * @param authentication / + * @return / */ public String createToken(Authentication authentication) { - /** + /* * 获取权限列表 */ String authorities = authentication.getAuthorities().stream() @@ -98,8 +97,8 @@ public class TokenProvider implements InitializingBean { /** * 依据Token 获取鉴权信息 * - * @param token - * @return + * @param token / + * @return / */ Authentication getAuthentication(String token) { Claims claims = getClaims(token); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java index fbd7093b..3f9fe5b1 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserCacheClean.java @@ -27,12 +27,11 @@ import org.springframework.stereotype.Component; @Component public class UserCacheClean { - /** * 清理特定用户缓存信息
* 用户信息变更时 * - * @param userName + * @param userName / */ public void cleanUserCache(String userName) { if (StringUtils.isNotEmpty(userName)) { diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java index 857bf021..6ea954d6 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/UserDetailsServiceImpl.java @@ -27,7 +27,6 @@ import me.zhengjie.modules.system.service.dto.UserDto; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; - import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -42,7 +41,6 @@ public class UserDetailsServiceImpl implements UserDetailsService { private final RoleService roleService; private final DataService dataService; private final LoginProperties loginProperties; - public void setEnableCache(boolean enableCache) { this.loginProperties.setCacheEnable(enableCache); } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java index de49a55c..f723e3d2 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/rest/RoleController.java @@ -27,10 +27,7 @@ import me.zhengjie.modules.system.service.dto.RoleDto; import me.zhengjie.modules.system.service.dto.RoleQueryCriteria; import me.zhengjie.modules.system.service.dto.RoleSmallDto; import me.zhengjie.utils.SecurityUtils; -import me.zhengjie.utils.ThrowableUtil; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java index a15d4edc..8005388b 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/RoleServiceImpl.java @@ -117,7 +117,7 @@ public class RoleServiceImpl implements RoleService { role.setLevel(resources.getLevel()); roleRepository.save(role); // 更新相关缓存 - delCaches(role.getId()); + delCaches(role.getId(), null); } @Override @@ -126,11 +126,10 @@ public class RoleServiceImpl implements RoleService { List users = userRepository.findByRoleId(role.getId()); // 更新菜单 role.setMenus(resources.getMenus()); - cleanCache(resources, users); + delCaches(resources.getId(), users); roleRepository.save(role); } - @Override @Transactional(rollbackFor = Exception.class) public void untiedMenu(Long menuId) { @@ -143,7 +142,7 @@ public class RoleServiceImpl implements RoleService { public void delete(Set ids) { for (Long id : ids) { // 更新相关缓存 - delCaches(id); + delCaches(id, null); } roleRepository.deleteAllByIdIn(ids); } @@ -208,40 +207,18 @@ public class RoleServiceImpl implements RoleService { /** * 清理缓存 - * * @param id / */ - public void delCaches(Long id) { - List users = userRepository.findByRoleId(id); + public void delCaches(Long id, List users) { + users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users; if (CollectionUtil.isNotEmpty(users)) { - users.stream().forEach(item -> { - userCacheClean.cleanUserCache(item.getUsername()); - }); + users.forEach(item -> userCacheClean.cleanUserCache(item.getUsername())); Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); redisUtils.delByKeys(CacheKey.DATE_USER, userIds); redisUtils.delByKeys(CacheKey.MENU_USER, userIds); redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); + redisUtils.del(CacheKey.ROLE_ID + id); } } - - /** - * 清理缓存 - * - * @param resources - * @param users - */ - private void cleanCache(Role resources, List users) { - // 清理缓存 - if (CollectionUtil.isNotEmpty(users)) { - users.forEach(item -> { - userCacheClean.cleanUserCache(item.getUsername()); - }); - Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); - redisUtils.delByKeys(CacheKey.MENU_USER, userIds); - redisUtils.delByKeys(CacheKey.ROLE_AUTH, userIds); - redisUtils.del(CacheKey.ROLE_ID + resources.getId()); - } - } - } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java index 7f788e8c..eca89aac 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java @@ -235,7 +235,7 @@ public class UserServiceImpl implements UserService { /** * 清理 登陆时 用户缓存信息 * - * @param username + * @param username / */ private void flushCache(String username) { userCacheClean.cleanUserCache(username); diff --git a/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java b/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java index 008f61a8..4d7f55c8 100644 --- a/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java +++ b/eladmin-system/src/test/java/me/zhengjie/LoginCacheTest.java @@ -5,19 +5,19 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; - import javax.annotation.Resource; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class LoginCacheTest { + @Resource(name = "userDetailsService") private UserDetailsServiceImpl userDetailsService; - private int size = 10000; @Test public void testCache() { long start1 = System.currentTimeMillis(); + int size = 10000; for (int i = 0; i < size; i++) { userDetailsService.loadUserByUsername("admin"); } @@ -29,6 +29,6 @@ public class LoginCacheTest { userDetailsService.loadUserByUsername("admin"); } long end2 = System.currentTimeMillis(); - System.out.printf("使用缓存:" + (end1 - start1) + "毫秒\n 不使用缓存:" + (end2 - start2) + "毫秒"); + System.out.print("使用缓存:" + (end1 - start1) + "毫秒\n 不使用缓存:" + (end2 - start2) + "毫秒"); } } diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java b/eladmin-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java index 5271c4fa..0625ba42 100644 --- a/eladmin-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java +++ b/eladmin-tools/src/main/java/me/zhengjie/service/impl/AliPayServiceImpl.java @@ -38,20 +38,20 @@ import java.util.Optional; */ @Service @RequiredArgsConstructor -@CacheConfig(cacheNames = "alipay") +@CacheConfig(cacheNames = "aliPay") public class AliPayServiceImpl implements AliPayService { private final AliPayRepository alipayRepository; @Override - @Cacheable(key = "'id:1'") + @Cacheable(key = "'config'") public AlipayConfig find() { Optional alipayConfig = alipayRepository.findById(1L); return alipayConfig.orElseGet(AlipayConfig::new); } @Override - @CachePut(key = "'id:1'") + @CachePut(key = "'config'") @Transactional(rollbackFor = Exception.class) public AlipayConfig config(AlipayConfig alipayConfig) { alipayConfig.setId(1L); diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java b/eladmin-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java index 44cf9df3..3386500a 100644 --- a/eladmin-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java +++ b/eladmin-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java @@ -43,7 +43,7 @@ public class EmailServiceImpl implements EmailService { private final EmailRepository emailRepository; @Override - @CachePut(key = "'id:1'") + @CachePut(key = "'config'") @Transactional(rollbackFor = Exception.class) public EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception { emailConfig.setId(1L); @@ -55,7 +55,7 @@ public class EmailServiceImpl implements EmailService { } @Override - @Cacheable(key = "'id:1'") + @Cacheable(key = "'config'") public EmailConfig find() { Optional emailConfig = emailRepository.findById(1L); return emailConfig.orElseGet(EmailConfig::new); diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java b/eladmin-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java index 0db2d7af..942f437e 100644 --- a/eladmin-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java +++ b/eladmin-tools/src/main/java/me/zhengjie/service/impl/QiNiuServiceImpl.java @@ -65,14 +65,14 @@ public class QiNiuServiceImpl implements QiNiuService { private Long maxSize; @Override - @Cacheable(key = "'id:1'") + @Cacheable(key = "'config'") public QiniuConfig find() { Optional qiniuConfig = qiNiuConfigRepository.findById(1L); return qiniuConfig.orElseGet(QiniuConfig::new); } @Override - @CachePut(key = "'id:1'") + @CachePut(key = "'config'") @Transactional(rollbackFor = Exception.class) public QiniuConfig config(QiniuConfig qiniuConfig) { qiniuConfig.setId(1L); From a24d4f774e03da89869e6533e4cce6549a98137a Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 21 Jun 2020 17:33:56 +0800 Subject: [PATCH 6/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20update=20eladmin.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/eladmin.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/eladmin.sql b/sql/eladmin.sql index 5a95b68f..bccc611f 100644 --- a/sql/eladmin.sql +++ b/sql/eladmin.sql @@ -381,7 +381,7 @@ INSERT INTO `sys_menu` VALUES (15, 10, 0, 1, '富文本', 'Editor', 'components/ INSERT INTO `sys_menu` VALUES (16, 36, 2, 1, '图床管理', 'Pictures', 'tools/picture/index', 33, 'image', 'pictures', b'0', b'0', b'0', 'pictures:list', NULL, NULL, '2018-12-28 09:36:53', NULL); INSERT INTO `sys_menu` VALUES (18, 36, 3, 1, '存储管理', 'Storage', 'tools/storage/index', 34, 'qiniu', 'storage', b'0', b'0', b'0', 'storage:list', NULL, NULL, '2018-12-31 11:12:15', NULL); INSERT INTO `sys_menu` VALUES (19, 36, 0, 1, '支付宝工具', 'AliPay', 'tools/aliPay/index', 37, 'alipay', 'aliPay', b'0', b'0', b'0', NULL, NULL, NULL, '2018-12-31 14:52:38', NULL); -INSERT INTO `sys_menu` VALUES (21, NULL, 2, 0, '多级菜单', NULL, '', 900, 'menu', 'nested', b'0', b'0', b'1', NULL, NULL, NULL, '2019-01-04 16:22:03', NULL); +INSERT INTO `sys_menu` VALUES (21, NULL, 2, 0, '多级菜单', NULL, '', 900, 'menu', 'nested', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:22:03', NULL); INSERT INTO `sys_menu` VALUES (22, 21, 2, 1, '二级菜单1', NULL, 'nested/menu1/index', 999, 'menu', 'menu1', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:23:29', NULL); INSERT INTO `sys_menu` VALUES (23, 21, 0, 1, '二级菜单2', NULL, 'nested/menu2/index', 999, 'menu', 'menu2', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:23:57', NULL); INSERT INTO `sys_menu` VALUES (24, 22, 0, 1, '三级菜单1', NULL, 'nested/menu1/menu1-1', 999, 'menu', 'menu1-1', b'0', b'0', b'0', NULL, NULL, NULL, '2019-01-04 16:24:48', NULL); @@ -584,6 +584,8 @@ INSERT INTO `sys_roles_menus` VALUES (19, 1); INSERT INTO `sys_roles_menus` VALUES (21, 1); INSERT INTO `sys_roles_menus` VALUES (22, 1); INSERT INTO `sys_roles_menus` VALUES (23, 1); +INSERT INTO `sys_roles_menus` VALUES (24, 1); +INSERT INTO `sys_roles_menus` VALUES (27, 1); INSERT INTO `sys_roles_menus` VALUES (28, 1); INSERT INTO `sys_roles_menus` VALUES (30, 1); INSERT INTO `sys_roles_menus` VALUES (32, 1); From 73eb350172ac99e589a23d0ae8cc60560b3630f3 Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 21 Jun 2020 17:49:08 +0800 Subject: [PATCH 7/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20@Query=20=E5=8A=A0=E5=85=A5=20INNER=20=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close https://github.com/elunez/eladmin/issues/415 --- .../src/main/java/me/zhengjie/annotation/Query.java | 4 ++-- .../src/main/java/me/zhengjie/utils/QueryHelp.java | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java b/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java index c5bbcca6..6f693ecf 100644 --- a/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java +++ b/eladmin-common/src/main/java/me/zhengjie/annotation/Query.java @@ -80,8 +80,8 @@ public @interface Query { * 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询 */ enum Join { - /** jie 2019-6-4 13:18:30 左右连接 */ - LEFT, RIGHT + /** jie 2019-6-4 13:18:30 */ + LEFT, RIGHT, INNER } } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java b/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java index cc998084..321b766d 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/QueryHelp.java @@ -100,6 +100,13 @@ public class QueryHelp { join = root.join(name, JoinType.RIGHT); } break; + case INNER: + if(ObjectUtil.isNotNull(join) && ObjectUtil.isNotNull(val)){ + join = join.join(name, JoinType.INNER); + } else { + join = root.join(name, JoinType.INNER); + } + break; default: break; } } From cee42e3a67458a8b2002ff9bd3e47e57ad158d3c Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Mon, 22 Jun 2020 21:17:17 +0800 Subject: [PATCH 8/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20EncryptUtils=20=E4=BC=98=E5=8C=96=E5=9C=A8linux=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=AD=98=E5=9C=A8=E8=A7=A3=E5=AF=86=E4=B9=B1=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close https://github.com/elunez/eladmin/issues/419 --- .../src/main/java/me/zhengjie/utils/EncryptUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/EncryptUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/EncryptUtils.java index 01185a8d..4f334aac 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/EncryptUtils.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/EncryptUtils.java @@ -61,7 +61,7 @@ public class EncryptUtils { * 对称解密 */ public static String desDecrypt(String source) throws Exception { - byte[] src = hex2byte(source.getBytes()); + byte[] src = hex2byte(source.getBytes(StandardCharsets.UTF_8)); DESKeySpec desKeySpec = getDesKeySpec(source); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); From 3379f4a93d00d4e38bf9e40c86f31407712e7fe6 Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Wed, 24 Jun 2020 09:37:52 +0800 Subject: [PATCH 9/9] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96](v2.5?= =?UTF-8?q?):=20update=20code=5F=20=E7=9B=B8=E5=85=B3=E8=A1=A8=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E8=B0=83=E6=95=B4.sql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close https://github.com/elunez/eladmin/issues/422 --- eladmin-system/src/main/resources/config/application-dev.yml | 2 +- sql/code_ 相关表字段调整.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index d9a67418..c68f99f5 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -88,8 +88,8 @@ generator: #是否开启 swagger-ui swagger: enabled: true -# IP 本地解析 +# IP 本地解析 ip: local-parsing: true diff --git a/sql/code_ 相关表字段调整.sql b/sql/code_ 相关表字段调整.sql index 75ddf6ab..dd27cab7 100644 --- a/sql/code_ 相关表字段调整.sql +++ b/sql/code_ 相关表字段调整.sql @@ -3,5 +3,5 @@ alter table code_gen_config CHANGE id config_id BIGINT(20) AUTO_INCREMENT COMMEN -- code_gen_config end -- -- code_column_config 表改动 start -- -alter table code_column_config CHANGE id config_idcolumn_id BIGINT(20) AUTO_INCREMENT COMMENT 'ID'; +alter table code_column_config CHANGE id column_id BIGINT(20) AUTO_INCREMENT COMMENT 'ID'; -- code_column_config end -- \ No newline at end of file