mirror of https://github.com/elunez/eladmin
Merge branch 'master' of https://gitee.com/elunez/eladmin
commit
cf1e17c7cf
|
@ -80,8 +80,8 @@ public @interface Query {
|
||||||
* 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
|
* 适用于简单连接查询,复杂的请自定义该注解,或者使用sql查询
|
||||||
*/
|
*/
|
||||||
enum Join {
|
enum Join {
|
||||||
/** jie 2019-6-4 13:18:30 左右连接 */
|
/** jie 2019-6-4 13:18:30 */
|
||||||
LEFT, RIGHT
|
LEFT, RIGHT, INNER
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:";
|
||||||
|
/**
|
||||||
|
* 数据
|
||||||
|
*/
|
||||||
|
String DATE_USER = "data::user:";
|
||||||
|
/**
|
||||||
|
* 菜单
|
||||||
|
*/
|
||||||
|
String MENU_USER = "menu::user:";
|
||||||
|
/**
|
||||||
|
* 角色授权
|
||||||
|
*/
|
||||||
|
String ROLE_AUTH = "role::auth:";
|
||||||
|
/**
|
||||||
|
* 角色信息
|
||||||
|
*/
|
||||||
|
String ROLE_ID = "role::id:";
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* 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 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 /
|
||||||
|
*/
|
||||||
|
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 DFY_MD_HMS.format(localDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式化 yyyy-MM-dd
|
||||||
|
*
|
||||||
|
* @param localDateTime /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public String localDateTimeFormatyMd(LocalDateTime localDateTime) {
|
||||||
|
return DFY_MD.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 HH:mm:ss
|
||||||
|
*
|
||||||
|
* @param localDateTime /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static LocalDateTime parseLocalDateTimeFormatyMdHms(String localDateTime) {
|
||||||
|
return LocalDateTime.from(DFY_MD_HMS.parse(localDateTime));
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ public class EncryptUtils {
|
||||||
* 对称解密
|
* 对称解密
|
||||||
*/
|
*/
|
||||||
public static String desDecrypt(String source) throws Exception {
|
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);
|
DESKeySpec desKeySpec = getDesKeySpec(source);
|
||||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||||
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
|
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
|
||||||
|
|
|
@ -100,6 +100,13 @@ public class QueryHelp {
|
||||||
join = root.join(name, JoinType.RIGHT);
|
join = root.join(name, JoinType.RIGHT);
|
||||||
}
|
}
|
||||||
break;
|
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;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,19 +174,19 @@ public class RedisUtils {
|
||||||
if (keys != null && keys.length > 0) {
|
if (keys != null && keys.length > 0) {
|
||||||
if (keys.length == 1) {
|
if (keys.length == 1) {
|
||||||
boolean result = redisTemplate.delete(keys[0]);
|
boolean result = redisTemplate.delete(keys[0]);
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
System.out.println(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result));
|
log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString());
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
} else {
|
} else {
|
||||||
Set<Object> keySet = new HashSet<>();
|
Set<Object> keySet = new HashSet<>();
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
keySet.addAll(redisTemplate.keys(key));
|
keySet.addAll(redisTemplate.keys(key));
|
||||||
}
|
}
|
||||||
long count = redisTemplate.delete(keySet);
|
long count = redisTemplate.delete(keySet);
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
System.out.println("成功删除缓存:" + keySet.toString());
|
log.debug("成功删除缓存:" + keySet.toString());
|
||||||
System.out.println("缓存删除数量:" + count + "个");
|
log.debug("缓存删除数量:" + count + "个");
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,9 +697,9 @@ public class RedisUtils {
|
||||||
}
|
}
|
||||||
long count = redisTemplate.delete(keys);
|
long count = redisTemplate.delete(keys);
|
||||||
// 此处提示可自行删除
|
// 此处提示可自行删除
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
System.out.println("成功删除缓存:" + keys.toString());
|
log.debug("成功删除缓存:" + keys.toString());
|
||||||
System.out.println("缓存删除数量:" + count + "个");
|
log.debug("缓存删除数量:" + count + "个");
|
||||||
System.out.println("--------------------------------------------");
|
log.debug("--------------------------------------------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.lionsoul.ip2region.DbSearcher;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetAddress;
|
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 final Logger log = LoggerFactory.getLogger(StringUtils.class);
|
||||||
private static boolean ipLocal = false;
|
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 char SEPARATOR = '_';
|
||||||
private static final String UNKNOWN = "unknown";
|
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 path = "ip2region/ip2region.db";
|
||||||
String name = "ip2region.db";
|
String name = "ip2region.db";
|
||||||
DbConfig config;
|
|
||||||
try {
|
try {
|
||||||
config = new DbConfig();
|
config = new DbConfig();
|
||||||
File file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name);
|
file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name);
|
||||||
searcher = new DbSearcher(config, file.getPath());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), 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) {
|
public static String getLocalCityInfo(String ip) {
|
||||||
try {
|
try {
|
||||||
DataBlock dataBlock;
|
DataBlock dataBlock = new DbSearcher(config, file.getPath())
|
||||||
dataBlock = searcher.binarySearch(ip);
|
.binarySearch(ip);
|
||||||
String address = dataBlock.getRegion().replace("0|", "");
|
String region = dataBlock.getRegion();
|
||||||
|
String address = region.replace("0|", "");
|
||||||
char symbol = '|';
|
char symbol = '|';
|
||||||
if (address.charAt(address.length() - 1) == symbol) {
|
if (address.charAt(address.length() - 1) == symbol) {
|
||||||
address = address.substring(0, address.length() - 1);
|
address = address.substring(0, address.length() - 1);
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package me.zhengjie.annotation;
|
package me.zhengjie.annotation;
|
||||||
|
|
||||||
|
import me.zhengjie.annotation.type.LogActionType;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@ -28,4 +30,13 @@ import java.lang.annotation.Target;
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Log {
|
public @interface Log {
|
||||||
String value() default "";
|
String value() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean enable() default true;
|
||||||
|
|
||||||
|
LogActionType type() default LogActionType.SELECT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,9 +19,12 @@ import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.modules.quartz.domain.QuartzJob;
|
import me.zhengjie.modules.quartz.domain.QuartzJob;
|
||||||
import me.zhengjie.modules.quartz.repository.QuartzJobRepository;
|
import me.zhengjie.modules.quartz.repository.QuartzJobRepository;
|
||||||
import me.zhengjie.modules.quartz.utils.QuartzManage;
|
import me.zhengjie.modules.quartz.utils.QuartzManage;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,19 +34,20 @@ import java.util.List;
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class JobRunner implements ApplicationRunner {
|
public class JobRunner implements ApplicationRunner {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
|
||||||
private final QuartzJobRepository quartzJobRepository;
|
private final QuartzJobRepository quartzJobRepository;
|
||||||
private final QuartzManage quartzManage;
|
private final QuartzManage quartzManage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目启动时重新激活启用的定时任务
|
* 项目启动时重新激活启用的定时任务
|
||||||
|
*
|
||||||
* @param applicationArguments /
|
* @param applicationArguments /
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(ApplicationArguments applicationArguments){
|
public void run(ApplicationArguments applicationArguments) {
|
||||||
System.out.println("--------------------注入定时任务---------------------");
|
log.info("--------------------注入定时任务---------------------");
|
||||||
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
|
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse();
|
||||||
quartzJobs.forEach(quartzManage::addJob);
|
quartzJobs.forEach(quartzManage::addJob);
|
||||||
System.out.println("--------------------定时任务注入完成---------------------");
|
log.info("--------------------定时任务注入完成---------------------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import me.zhengjie.modules.quartz.service.QuartzJobService;
|
||||||
import me.zhengjie.service.EmailService;
|
import me.zhengjie.service.EmailService;
|
||||||
import me.zhengjie.utils.RedisUtils;
|
import me.zhengjie.utils.RedisUtils;
|
||||||
import me.zhengjie.utils.SpringContextHolder;
|
import me.zhengjie.utils.SpringContextHolder;
|
||||||
|
import me.zhengjie.utils.StringUtils;
|
||||||
import me.zhengjie.utils.ThrowableUtil;
|
import me.zhengjie.utils.ThrowableUtil;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
@ -55,6 +56,8 @@ public class ExecutionJob extends QuartzJobBean {
|
||||||
QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);
|
QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);
|
||||||
RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
|
RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
|
||||||
|
|
||||||
|
String uuid = quartzJob.getUuid();
|
||||||
|
|
||||||
QuartzLog log = new QuartzLog();
|
QuartzLog log = new QuartzLog();
|
||||||
log.setJobName(quartzJob.getJobName());
|
log.setJobName(quartzJob.getJobName());
|
||||||
log.setBeanName(quartzJob.getBeanName());
|
log.setBeanName(quartzJob.getBeanName());
|
||||||
|
@ -72,7 +75,9 @@ public class ExecutionJob extends QuartzJobBean {
|
||||||
future.get();
|
future.get();
|
||||||
long times = System.currentTimeMillis() - startTime;
|
long times = System.currentTimeMillis() - startTime;
|
||||||
log.setTime(times);
|
log.setTime(times);
|
||||||
redisUtils.set(quartzJob.getUuid(), true);
|
if(StringUtils.isNotBlank(uuid)) {
|
||||||
|
redisUtils.set(uuid, true);
|
||||||
|
}
|
||||||
// 任务状态
|
// 任务状态
|
||||||
log.setIsSuccess(true);
|
log.setIsSuccess(true);
|
||||||
System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒");
|
System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒");
|
||||||
|
@ -84,7 +89,9 @@ public class ExecutionJob extends QuartzJobBean {
|
||||||
quartzJobService.executionSubJob(tasks);
|
quartzJobService.executionSubJob(tasks);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
redisUtils.set(quartzJob.getUuid(), false);
|
if(StringUtils.isNotBlank(uuid)) {
|
||||||
|
redisUtils.set(uuid, false);
|
||||||
|
}
|
||||||
System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName());
|
System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName());
|
||||||
System.out.println("--------------------------------------------------------------");
|
System.out.println("--------------------------------------------------------------");
|
||||||
long times = System.currentTimeMillis() - startTime;
|
long times = System.currentTimeMillis() - startTime;
|
||||||
|
|
|
@ -17,7 +17,10 @@ package me.zhengjie.modules.security.config;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.annotation.AnonymousAccess;
|
import me.zhengjie.annotation.AnonymousAccess;
|
||||||
|
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||||
import me.zhengjie.modules.security.security.*;
|
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 me.zhengjie.utils.enums.RequestMethodEnum;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
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.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +57,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
private final JwtAuthenticationEntryPoint authenticationErrorHandler;
|
private final JwtAuthenticationEntryPoint authenticationErrorHandler;
|
||||||
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
|
private final SecurityProperties properties;
|
||||||
|
private final OnlineUserService onlineUserService;
|
||||||
|
private final UserCacheClean userCacheClean;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
GrantedAuthorityDefaults grantedAuthorityDefaults() {
|
||||||
|
@ -144,7 +151,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
if (null != anonymousAccess) {
|
if (null != anonymousAccess) {
|
||||||
List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
|
List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
|
||||||
RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
|
RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
|
||||||
switch (Objects.requireNonNull(request)){
|
switch (Objects.requireNonNull(request)) {
|
||||||
case GET:
|
case GET:
|
||||||
get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
break;
|
break;
|
||||||
|
@ -176,6 +183,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private TokenConfigurer securityConfigurerAdapter() {
|
private TokenConfigurer securityConfigurerAdapter() {
|
||||||
return new TokenConfigurer(tokenProvider);
|
return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheClean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,12 @@ package me.zhengjie.modules.security.config.bean;
|
||||||
import com.wf.captcha.*;
|
import com.wf.captcha.*;
|
||||||
import com.wf.captcha.base.Captcha;
|
import com.wf.captcha.base.Captcha;
|
||||||
import me.zhengjie.exception.BadConfigurationException;
|
import me.zhengjie.exception.BadConfigurationException;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置文件读取
|
* 配置文件读取
|
||||||
|
*
|
||||||
* @author liaojinlong
|
* @author liaojinlong
|
||||||
* @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6
|
* @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +36,10 @@ public class LoginProperties {
|
||||||
private boolean singleLogin = false;
|
private boolean singleLogin = false;
|
||||||
|
|
||||||
private LoginCode loginCode;
|
private LoginCode loginCode;
|
||||||
|
/**
|
||||||
|
* 用户登录信息缓存
|
||||||
|
*/
|
||||||
|
private boolean cacheEnable;
|
||||||
|
|
||||||
public boolean isSingleLogin() {
|
public boolean isSingleLogin() {
|
||||||
return singleLogin;
|
return singleLogin;
|
||||||
|
@ -51,6 +57,14 @@ public class LoginProperties {
|
||||||
this.loginCode = loginCode;
|
this.loginCode = loginCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCacheEnable() {
|
||||||
|
return cacheEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCacheEnable(boolean cacheEnable) {
|
||||||
|
this.cacheEnable = cacheEnable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取验证码生产类
|
* 获取验证码生产类
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package me.zhengjie.modules.security.rest;
|
package me.zhengjie.modules.security.rest;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import com.wf.captcha.ArithmeticCaptcha;
|
|
||||||
import com.wf.captcha.base.Captcha;
|
import com.wf.captcha.base.Captcha;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
@ -38,7 +37,6 @@ import me.zhengjie.utils.RsaUtils;
|
||||||
import me.zhengjie.utils.RedisUtils;
|
import me.zhengjie.utils.RedisUtils;
|
||||||
import me.zhengjie.utils.SecurityUtils;
|
import me.zhengjie.utils.SecurityUtils;
|
||||||
import me.zhengjie.utils.StringUtils;
|
import me.zhengjie.utils.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
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.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -91,7 +88,6 @@ public class AuthorizationController {
|
||||||
}
|
}
|
||||||
UsernamePasswordAuthenticationToken authenticationToken =
|
UsernamePasswordAuthenticationToken authenticationToken =
|
||||||
new UsernamePasswordAuthenticationToken(authUser.getUsername(), password);
|
new UsernamePasswordAuthenticationToken(authUser.getUsername(), password);
|
||||||
|
|
||||||
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
|
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
// 生成令牌
|
// 生成令牌
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
package me.zhengjie.modules.security.security;
|
package me.zhengjie.modules.security.security;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
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.SecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||||
|
@ -28,10 +31,13 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
|
||||||
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||||
|
|
||||||
private final TokenProvider tokenProvider;
|
private final TokenProvider tokenProvider;
|
||||||
|
private final SecurityProperties properties;
|
||||||
|
private final OnlineUserService onlineUserService;
|
||||||
|
private final UserCacheClean userCacheClean;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(HttpSecurity http) {
|
public void configure(HttpSecurity http) {
|
||||||
TokenFilter customFilter = new TokenFilter(tokenProvider);
|
TokenFilter customFilter = new TokenFilter(tokenProvider, properties, onlineUserService, userCacheClean);
|
||||||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,31 +17,49 @@ package me.zhengjie.modules.security.security;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import io.jsonwebtoken.ExpiredJwtException;
|
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.config.bean.SecurityProperties;
|
||||||
|
import me.zhengjie.modules.security.service.UserCacheClean;
|
||||||
import me.zhengjie.modules.security.service.dto.OnlineUserDto;
|
import me.zhengjie.modules.security.service.dto.OnlineUserDto;
|
||||||
import me.zhengjie.modules.security.service.OnlineUserService;
|
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.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author /
|
* @author /
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class TokenFilter extends GenericFilterBean {
|
public class TokenFilter extends GenericFilterBean {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TokenFilter.class);
|
||||||
|
|
||||||
|
|
||||||
private final TokenProvider tokenProvider;
|
private final TokenProvider tokenProvider;
|
||||||
|
private final SecurityProperties properties;
|
||||||
|
private final OnlineUserService onlineUserService;
|
||||||
|
private final UserCacheClean userCacheClean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
@Override
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||||
|
@ -49,14 +67,18 @@ public class TokenFilter extends GenericFilterBean {
|
||||||
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
||||||
String token = resolveToken(httpServletRequest);
|
String token = resolveToken(httpServletRequest);
|
||||||
// 对于 Token 为空的不需要去查 Redis
|
// 对于 Token 为空的不需要去查 Redis
|
||||||
if(StrUtil.isNotBlank(token)){
|
if (StrUtil.isNotBlank(token)) {
|
||||||
OnlineUserDto onlineUserDto = null;
|
OnlineUserDto onlineUserDto = null;
|
||||||
SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);
|
boolean cleanUserCache = false;
|
||||||
try {
|
try {
|
||||||
OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);
|
|
||||||
onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token);
|
onlineUserDto = onlineUserService.getOne(properties.getOnlineKey() + token);
|
||||||
} catch (ExpiredJwtException e) {
|
} catch (ExpiredJwtException e) {
|
||||||
log.error(e.getMessage());
|
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)) {
|
if (onlineUserDto != null && StringUtils.hasText(token)) {
|
||||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||||
|
@ -68,12 +90,19 @@ public class TokenFilter extends GenericFilterBean {
|
||||||
filterChain.doFilter(servletRequest, servletResponse);
|
filterChain.doFilter(servletRequest, servletResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初步检测Token
|
||||||
|
*
|
||||||
|
* @param request /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
private String resolveToken(HttpServletRequest request) {
|
private String resolveToken(HttpServletRequest request) {
|
||||||
SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);
|
|
||||||
String bearerToken = request.getHeader(properties.getHeader());
|
String bearerToken = request.getHeader(properties.getHeader());
|
||||||
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) {
|
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())) {
|
||||||
// 去掉令牌前缀
|
// 去掉令牌前缀
|
||||||
return bearerToken.replace(properties.getTokenStartWith(),"");
|
return bearerToken.replace(properties.getTokenStartWith(), "");
|
||||||
|
} else {
|
||||||
|
log.debug("非法Token:{}", bearerToken);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import cn.hutool.core.util.ObjectUtil;
|
||||||
import io.jsonwebtoken.*;
|
import io.jsonwebtoken.*;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
import io.jsonwebtoken.io.Decoders;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||||
import me.zhengjie.utils.RedisUtils;
|
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.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -47,40 +47,61 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class TokenProvider implements InitializingBean {
|
public class TokenProvider implements InitializingBean {
|
||||||
|
|
||||||
private final SecurityProperties properties;
|
private final SecurityProperties properties;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
private static final String AUTHORITIES_KEY = "auth";
|
public static final String AUTHORITIES_KEY = "auth";
|
||||||
private Key key;
|
private JwtParser jwtParser;
|
||||||
|
private JwtBuilder jwtBuilder;
|
||||||
|
|
||||||
|
public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) {
|
||||||
|
this.properties = properties;
|
||||||
|
this.redisUtils = redisUtils;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
|
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
|
||||||
this.key = Keys.hmacShaKeyFor(keyBytes);
|
Key key = Keys.hmacShaKeyFor(keyBytes);
|
||||||
|
jwtParser = Jwts.parserBuilder()
|
||||||
|
.setSigningKey(key)
|
||||||
|
.build();
|
||||||
|
jwtBuilder = Jwts.builder()
|
||||||
|
.signWith(key, SignatureAlgorithm.HS512);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建Token 设置永不过期,
|
||||||
|
* Token 的时间有效性转到Redis 维护
|
||||||
|
*
|
||||||
|
* @param authentication /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
public String createToken(Authentication authentication) {
|
public String createToken(Authentication authentication) {
|
||||||
|
/*
|
||||||
|
* 获取权限列表
|
||||||
|
*/
|
||||||
String authorities = authentication.getAuthorities().stream()
|
String authorities = authentication.getAuthorities().stream()
|
||||||
.map(GrantedAuthority::getAuthority)
|
.map(GrantedAuthority::getAuthority)
|
||||||
.collect(Collectors.joining(","));
|
.collect(Collectors.joining(","));
|
||||||
|
|
||||||
return Jwts.builder()
|
return jwtBuilder
|
||||||
.setSubject(authentication.getName())
|
|
||||||
.claim(AUTHORITIES_KEY, authorities)
|
|
||||||
.signWith(key, SignatureAlgorithm.HS512)
|
|
||||||
// 加入ID确保生成的 Token 都不一致
|
// 加入ID确保生成的 Token 都不一致
|
||||||
.setId(IdUtil.simpleUUID())
|
.setId(IdUtil.simpleUUID())
|
||||||
|
.claim(AUTHORITIES_KEY, authorities)
|
||||||
|
.setSubject(authentication.getName())
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 依据Token 获取鉴权信息
|
||||||
|
*
|
||||||
|
* @param token /
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
Authentication getAuthentication(String token) {
|
Authentication getAuthentication(String token) {
|
||||||
Claims claims = Jwts.parserBuilder()
|
Claims claims = getClaims(token);
|
||||||
.setSigningKey(key)
|
|
||||||
.build()
|
|
||||||
.parseClaimsJws(token)
|
|
||||||
.getBody();
|
|
||||||
|
|
||||||
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
|
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
|
||||||
Object authoritiesStr = claims.get(AUTHORITIES_KEY);
|
Object authoritiesStr = claims.get(AUTHORITIES_KEY);
|
||||||
|
@ -89,29 +110,33 @@ public class TokenProvider implements InitializingBean {
|
||||||
Arrays.stream(authoritiesStr.toString().split(","))
|
Arrays.stream(authoritiesStr.toString().split(","))
|
||||||
.map(SimpleGrantedAuthority::new)
|
.map(SimpleGrantedAuthority::new)
|
||||||
.collect(Collectors.toList()) : Collections.emptyList();
|
.collect(Collectors.toList()) : Collections.emptyList();
|
||||||
|
User principal = new User(claims.getSubject(), "******", authorities);
|
||||||
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
|
* @param token 需要检查的token
|
||||||
*/
|
*/
|
||||||
public void checkRenewal(String token){
|
public void checkRenewal(String token) {
|
||||||
// 判断是否续期token,计算token的过期时间
|
// 判断是否续期token,计算token的过期时间
|
||||||
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
|
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
|
||||||
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
|
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
|
||||||
// 判断当前时间与过期时间的时间差
|
// 判断当前时间与过期时间的时间差
|
||||||
long differ = expireDate.getTime() - System.currentTimeMillis();
|
long differ = expireDate.getTime() - System.currentTimeMillis();
|
||||||
// 如果在续期检查的范围内,则续期
|
// 如果在续期检查的范围内,则续期
|
||||||
if(differ <= properties.getDetect()){
|
if (differ <= properties.getDetect()) {
|
||||||
long renew = time + properties.getRenew();
|
long renew = time + properties.getRenew();
|
||||||
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
|
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken(HttpServletRequest request){
|
public String getToken(HttpServletRequest request) {
|
||||||
final String requestHeader = request.getHeader(properties.getHeader());
|
final String requestHeader = request.getHeader(properties.getHeader());
|
||||||
if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
|
if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
|
||||||
return requestHeader.substring(7);
|
return requestHeader.substring(7);
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理特定用户缓存信息<br>
|
||||||
|
* 用户信息变更时
|
||||||
|
*
|
||||||
|
* @param userName /
|
||||||
|
*/
|
||||||
|
public void cleanUserCache(String userName) {
|
||||||
|
if (StringUtils.isNotEmpty(userName)) {
|
||||||
|
UserDetailsServiceImpl.userDtoCache.remove(userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理所有用户的缓存信息<br>
|
||||||
|
* ,如发生角色授权信息变化,可以简便的全部失效缓存
|
||||||
|
*/
|
||||||
|
public void cleanAll() {
|
||||||
|
UserDetailsServiceImpl.userDtoCache.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ package me.zhengjie.modules.security.service;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.exception.BadRequestException;
|
import me.zhengjie.exception.BadRequestException;
|
||||||
import me.zhengjie.exception.EntityNotFoundException;
|
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.security.service.dto.JwtUserDto;
|
||||||
import me.zhengjie.modules.system.service.DataService;
|
import me.zhengjie.modules.system.service.DataService;
|
||||||
import me.zhengjie.modules.system.service.RoleService;
|
import me.zhengjie.modules.system.service.RoleService;
|
||||||
|
@ -26,6 +27,8 @@ import me.zhengjie.modules.system.service.dto.UserDto;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Zheng Jie
|
* @author Zheng Jie
|
||||||
|
@ -34,13 +37,30 @@ import org.springframework.stereotype.Service;
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service("userDetailsService")
|
@Service("userDetailsService")
|
||||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final RoleService roleService;
|
private final RoleService roleService;
|
||||||
private final DataService dataService;
|
private final DataService dataService;
|
||||||
|
private final LoginProperties loginProperties;
|
||||||
|
public void setEnableCache(boolean enableCache) {
|
||||||
|
this.loginProperties.setCacheEnable(enableCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息缓存
|
||||||
|
*
|
||||||
|
* @see {@link UserCacheClean}
|
||||||
|
*/
|
||||||
|
static Map<String, JwtUserDto> userDtoCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JwtUserDto loadUserByUsername(String username) {
|
public JwtUserDto loadUserByUsername(String username) {
|
||||||
|
boolean searchDb = true;
|
||||||
|
JwtUserDto jwtUserDto = null;
|
||||||
|
if (loginProperties.isCacheEnable() && userDtoCache.containsKey(username)) {
|
||||||
|
jwtUserDto = userDtoCache.get(username);
|
||||||
|
searchDb = false;
|
||||||
|
}
|
||||||
|
if (searchDb) {
|
||||||
UserDto user;
|
UserDto user;
|
||||||
try {
|
try {
|
||||||
user = userService.findByName(username);
|
user = userService.findByName(username);
|
||||||
|
@ -54,11 +74,14 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
if (!user.getEnabled()) {
|
if (!user.getEnabled()) {
|
||||||
throw new BadRequestException("账号未激活");
|
throw new BadRequestException("账号未激活");
|
||||||
}
|
}
|
||||||
return new JwtUserDto(
|
jwtUserDto = new JwtUserDto(
|
||||||
user,
|
user,
|
||||||
dataService.getDeptIds(user),
|
dataService.getDeptIds(user),
|
||||||
roleService.mapToGrantedAuthorities(user)
|
roleService.mapToGrantedAuthorities(user)
|
||||||
);
|
);
|
||||||
|
userDtoCache.put(username, jwtUserDto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return jwtUserDto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.RoleQueryCriteria;
|
||||||
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
|
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
|
||||||
import me.zhengjie.utils.SecurityUtils;
|
import me.zhengjie.utils.SecurityUtils;
|
||||||
import me.zhengjie.utils.ThrowableUtil;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
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.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package me.zhengjie.modules.system.service.impl;
|
package me.zhengjie.modules.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.exception.BadRequestException;
|
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.Menu;
|
||||||
import me.zhengjie.modules.system.domain.Role;
|
import me.zhengjie.modules.system.domain.Role;
|
||||||
import me.zhengjie.exception.EntityExistException;
|
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.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -59,6 +62,7 @@ public class RoleServiceImpl implements RoleService {
|
||||||
private final RoleSmallMapper roleSmallMapper;
|
private final RoleSmallMapper roleSmallMapper;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
private final UserCacheClean userCacheClean;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RoleDto> queryAll() {
|
public List<RoleDto> queryAll() {
|
||||||
|
@ -68,12 +72,12 @@ public class RoleServiceImpl implements RoleService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RoleDto> queryAll(RoleQueryCriteria criteria) {
|
public List<RoleDto> 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
|
@Override
|
||||||
public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) {
|
public Object queryAll(RoleQueryCriteria criteria, Pageable pageable) {
|
||||||
Page<Role> page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
Page<Role> page = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
|
||||||
return PageUtil.toPage(page.map(roleMapper::toDto));
|
return PageUtil.toPage(page.map(roleMapper::toDto));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,15 +86,15 @@ public class RoleServiceImpl implements RoleService {
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public RoleDto findById(long id) {
|
public RoleDto findById(long id) {
|
||||||
Role role = roleRepository.findById(id).orElseGet(Role::new);
|
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);
|
return roleMapper.toDto(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void create(Role resources) {
|
public void create(Role resources) {
|
||||||
if(roleRepository.findByName(resources.getName()) != null){
|
if (roleRepository.findByName(resources.getName()) != null) {
|
||||||
throw new EntityExistException(Role.class,"username",resources.getName());
|
throw new EntityExistException(Role.class, "username", resources.getName());
|
||||||
}
|
}
|
||||||
roleRepository.save(resources);
|
roleRepository.save(resources);
|
||||||
}
|
}
|
||||||
|
@ -99,12 +103,12 @@ public class RoleServiceImpl implements RoleService {
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void update(Role resources) {
|
public void update(Role resources) {
|
||||||
Role role = roleRepository.findById(resources.getId()).orElseGet(Role::new);
|
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());
|
Role role1 = roleRepository.findByName(resources.getName());
|
||||||
|
|
||||||
if(role1 != null && !role1.getId().equals(role.getId())){
|
if (role1 != null && !role1.getId().equals(role.getId())) {
|
||||||
throw new EntityExistException(Role.class,"username",resources.getName());
|
throw new EntityExistException(Role.class, "username", resources.getName());
|
||||||
}
|
}
|
||||||
role.setName(resources.getName());
|
role.setName(resources.getName());
|
||||||
role.setDescription(resources.getDescription());
|
role.setDescription(resources.getDescription());
|
||||||
|
@ -113,20 +117,16 @@ public class RoleServiceImpl implements RoleService {
|
||||||
role.setLevel(resources.getLevel());
|
role.setLevel(resources.getLevel());
|
||||||
roleRepository.save(role);
|
roleRepository.save(role);
|
||||||
// 更新相关缓存
|
// 更新相关缓存
|
||||||
delCaches(role.getId());
|
delCaches(role.getId(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateMenu(Role resources, RoleDto roleDTO) {
|
public void updateMenu(Role resources, RoleDto roleDTO) {
|
||||||
Role role = roleMapper.toEntity(roleDTO);
|
Role role = roleMapper.toEntity(roleDTO);
|
||||||
List<User> users = userRepository.findByRoleId(role.getId());
|
List<User> users = userRepository.findByRoleId(role.getId());
|
||||||
Set<Long> userIds = users.stream().map(User::getId).collect(Collectors.toSet());
|
|
||||||
// 更新菜单
|
// 更新菜单
|
||||||
role.setMenus(resources.getMenus());
|
role.setMenus(resources.getMenus());
|
||||||
// 清理缓存
|
delCaches(resources.getId(), users);
|
||||||
redisUtils.delByKeys("menu::user:",userIds);
|
|
||||||
redisUtils.delByKeys("role::auth:",userIds);
|
|
||||||
redisUtils.del("role::id:" + resources.getId());
|
|
||||||
roleRepository.save(role);
|
roleRepository.save(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ public class RoleServiceImpl implements RoleService {
|
||||||
public void delete(Set<Long> ids) {
|
public void delete(Set<Long> ids) {
|
||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
// 更新相关缓存
|
// 更新相关缓存
|
||||||
delCaches(id);
|
delCaches(id, null);
|
||||||
}
|
}
|
||||||
roleRepository.deleteAllByIdIn(ids);
|
roleRepository.deleteAllByIdIn(ids);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ public class RoleServiceImpl implements RoleService {
|
||||||
public List<GrantedAuthority> mapToGrantedAuthorities(UserDto user) {
|
public List<GrantedAuthority> mapToGrantedAuthorities(UserDto user) {
|
||||||
Set<String> permissions = new HashSet<>();
|
Set<String> permissions = new HashSet<>();
|
||||||
// 如果是管理员直接返回
|
// 如果是管理员直接返回
|
||||||
if(user.getIsAdmin()){
|
if (user.getIsAdmin()) {
|
||||||
permissions.add("admin");
|
permissions.add("admin");
|
||||||
return permissions.stream().map(SimpleGrantedAuthority::new)
|
return permissions.stream().map(SimpleGrantedAuthority::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
@ -183,7 +183,7 @@ public class RoleServiceImpl implements RoleService {
|
||||||
public void download(List<RoleDto> roles, HttpServletResponse response) throws IOException {
|
public void download(List<RoleDto> roles, HttpServletResponse response) throws IOException {
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
for (RoleDto role : roles) {
|
for (RoleDto role : roles) {
|
||||||
Map<String,Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("角色名称", role.getName());
|
map.put("角色名称", role.getName());
|
||||||
map.put("角色级别", role.getLevel());
|
map.put("角色级别", role.getLevel());
|
||||||
map.put("描述", role.getDescription());
|
map.put("描述", role.getDescription());
|
||||||
|
@ -193,21 +193,9 @@ public class RoleServiceImpl implements RoleService {
|
||||||
FileUtil.downloadExcel(list, response);
|
FileUtil.downloadExcel(list, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理缓存
|
|
||||||
* @param id /
|
|
||||||
*/
|
|
||||||
public void delCaches(Long id){
|
|
||||||
List<User> users = userRepository.findByRoleId(id);
|
|
||||||
Set<Long> 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
|
@Override
|
||||||
public void verification(Set<Long> ids) {
|
public void verification(Set<Long> ids) {
|
||||||
if(userRepository.countByRoles(ids) > 0){
|
if (userRepository.countByRoles(ids) > 0) {
|
||||||
throw new BadRequestException("所选角色存在用户关联,请解除关联再试!");
|
throw new BadRequestException("所选角色存在用户关联,请解除关联再试!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,4 +204,21 @@ public class RoleServiceImpl implements RoleService {
|
||||||
public List<Role> findInMenuId(List<Long> menuIds) {
|
public List<Role> findInMenuId(List<Long> menuIds) {
|
||||||
return roleRepository.findInMenuId(menuIds);
|
return roleRepository.findInMenuId(menuIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理缓存
|
||||||
|
* @param id /
|
||||||
|
*/
|
||||||
|
public void delCaches(Long id, List<User> users) {
|
||||||
|
users = CollectionUtil.isEmpty(users) ? userRepository.findByRoleId(id) : users;
|
||||||
|
if (CollectionUtil.isNotEmpty(users)) {
|
||||||
|
users.forEach(item -> userCacheClean.cleanUserCache(item.getUsername()));
|
||||||
|
Set<Long> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package me.zhengjie.modules.system.service.impl;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.config.FileProperties;
|
import me.zhengjie.config.FileProperties;
|
||||||
|
import me.zhengjie.modules.security.service.UserCacheClean;
|
||||||
import me.zhengjie.modules.system.domain.User;
|
import me.zhengjie.modules.system.domain.User;
|
||||||
import me.zhengjie.exception.EntityExistException;
|
import me.zhengjie.exception.EntityExistException;
|
||||||
import me.zhengjie.exception.EntityNotFoundException;
|
import me.zhengjie.exception.EntityNotFoundException;
|
||||||
|
@ -35,7 +36,9 @@ import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -54,16 +57,17 @@ public class UserServiceImpl implements UserService {
|
||||||
private final UserMapper userMapper;
|
private final UserMapper userMapper;
|
||||||
private final FileProperties properties;
|
private final FileProperties properties;
|
||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
|
private final UserCacheClean userCacheClean;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object queryAll(UserQueryCriteria criteria, Pageable pageable) {
|
public Object queryAll(UserQueryCriteria criteria, Pageable pageable) {
|
||||||
Page<User> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
Page<User> page = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
|
||||||
return PageUtil.toPage(page.map(userMapper::toDto));
|
return PageUtil.toPage(page.map(userMapper::toDto));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserDto> queryAll(UserQueryCriteria criteria) {
|
public List<UserDto> queryAll(UserQueryCriteria criteria) {
|
||||||
List<User> users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
|
List<User> users = userRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
|
||||||
return userMapper.toDto(users);
|
return userMapper.toDto(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,18 +76,18 @@ public class UserServiceImpl implements UserService {
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public UserDto findById(long id) {
|
public UserDto findById(long id) {
|
||||||
User user = userRepository.findById(id).orElseGet(User::new);
|
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);
|
return userMapper.toDto(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void create(User resources) {
|
public void create(User resources) {
|
||||||
if(userRepository.findByUsername(resources.getUsername())!=null){
|
if (userRepository.findByUsername(resources.getUsername()) != null) {
|
||||||
throw new EntityExistException(User.class,"username",resources.getUsername());
|
throw new EntityExistException(User.class, "username", resources.getUsername());
|
||||||
}
|
}
|
||||||
if(userRepository.findByEmail(resources.getEmail())!=null){
|
if (userRepository.findByEmail(resources.getEmail()) != null) {
|
||||||
throw new EntityExistException(User.class,"email",resources.getEmail());
|
throw new EntityExistException(User.class, "email", resources.getEmail());
|
||||||
}
|
}
|
||||||
userRepository.save(resources);
|
userRepository.save(resources);
|
||||||
}
|
}
|
||||||
|
@ -92,22 +96,22 @@ public class UserServiceImpl implements UserService {
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void update(User resources) {
|
public void update(User resources) {
|
||||||
User user = userRepository.findById(resources.getId()).orElseGet(User::new);
|
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 user1 = userRepository.findByUsername(resources.getUsername());
|
||||||
User user2 = userRepository.findByEmail(resources.getEmail());
|
User user2 = userRepository.findByEmail(resources.getEmail());
|
||||||
|
|
||||||
if(user1 !=null&&!user.getId().equals(user1.getId())){
|
if (user1 != null && !user.getId().equals(user1.getId())) {
|
||||||
throw new EntityExistException(User.class,"username",resources.getUsername());
|
throw new EntityExistException(User.class, "username", resources.getUsername());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user2!=null&&!user.getId().equals(user2.getId())){
|
if (user2 != null && !user.getId().equals(user2.getId())) {
|
||||||
throw new EntityExistException(User.class,"email",resources.getEmail());
|
throw new EntityExistException(User.class, "email", resources.getEmail());
|
||||||
}
|
}
|
||||||
// 如果用户的角色改变
|
// 如果用户的角色改变
|
||||||
if (!resources.getRoles().equals(user.getRoles())) {
|
if (!resources.getRoles().equals(user.getRoles())) {
|
||||||
redisUtils.del("data::user:" + resources.getId());
|
redisUtils.del(CacheKey.DATE_USER + resources.getId());
|
||||||
redisUtils.del("menu::user:" + resources.getId());
|
redisUtils.del(CacheKey.MENU_USER + resources.getId());
|
||||||
redisUtils.del("role::auth:" + resources.getId());
|
redisUtils.del(CacheKey.ROLE_AUTH + resources.getId());
|
||||||
}
|
}
|
||||||
// 如果用户名称修改
|
// 如果用户名称修改
|
||||||
if(!resources.getUsername().equals(user.getUsername())){
|
if(!resources.getUsername().equals(user.getUsername())){
|
||||||
|
@ -164,8 +168,9 @@ public class UserServiceImpl implements UserService {
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updatePass(String username, String pass) {
|
public void updatePass(String username, String pass) {
|
||||||
userRepository.updatePass(username,pass,new Date());
|
userRepository.updatePass(username, pass, new Date());
|
||||||
redisUtils.del("user::username:" + username);
|
redisUtils.del("user::username:" + username);
|
||||||
|
flushCache(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,18 +182,23 @@ public class UserServiceImpl implements UserService {
|
||||||
user.setAvatarPath(Objects.requireNonNull(file).getPath());
|
user.setAvatarPath(Objects.requireNonNull(file).getPath());
|
||||||
user.setAvatarName(file.getName());
|
user.setAvatarName(file.getName());
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
if(StringUtils.isNotBlank(oldPath)){
|
if (StringUtils.isNotBlank(oldPath)) {
|
||||||
FileUtil.del(oldPath);
|
FileUtil.del(oldPath);
|
||||||
}
|
}
|
||||||
redisUtils.del("user::username:" + user.getUsername());
|
@NotBlank String username = user.getUsername();
|
||||||
return new HashMap<String,String>(1){{put("avatar",file.getName());}};
|
redisUtils.del(CacheKey.USER_NAME + username);
|
||||||
|
flushCache(username);
|
||||||
|
return new HashMap<String, String>(1) {{
|
||||||
|
put("avatar", file.getName());
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateEmail(String username, String email) {
|
public void updateEmail(String username, String email) {
|
||||||
userRepository.updateEmail(username,email);
|
userRepository.updateEmail(username, email);
|
||||||
redisUtils.del("user::username:" + username);
|
redisUtils.del(CacheKey.USER_NAME + username);
|
||||||
|
flushCache(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -196,7 +206,7 @@ public class UserServiceImpl implements UserService {
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
for (UserDto userDTO : queryAll) {
|
for (UserDto userDTO : queryAll) {
|
||||||
List<String> roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList());
|
List<String> roles = userDTO.getRoles().stream().map(RoleSmallDto::getName).collect(Collectors.toList());
|
||||||
Map<String,Object> map = new LinkedHashMap<>();
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
map.put("用户名", userDTO.getUsername());
|
map.put("用户名", userDTO.getUsername());
|
||||||
map.put("角色", roles);
|
map.put("角色", roles);
|
||||||
map.put("部门", userDTO.getDept().getName());
|
map.put("部门", userDTO.getDept().getName());
|
||||||
|
@ -213,10 +223,21 @@ public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清理缓存
|
* 清理缓存
|
||||||
|
*
|
||||||
* @param id /
|
* @param id /
|
||||||
*/
|
*/
|
||||||
public void delCaches(Long id, String username){
|
public void delCaches(Long id, String username) {
|
||||||
redisUtils.del("user::id:" + id);
|
redisUtils.del(CacheKey.USER_ID + id);
|
||||||
redisUtils.del("user::username:" + username);
|
redisUtils.del(CacheKey.USER_NAME + username);
|
||||||
|
flushCache(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理 登陆时 用户缓存信息
|
||||||
|
*
|
||||||
|
* @param username /
|
||||||
|
*/
|
||||||
|
private void flushCache(String username) {
|
||||||
|
userCacheClean.cleanUserCache(username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ spring:
|
||||||
|
|
||||||
# 登录相关配置
|
# 登录相关配置
|
||||||
login:
|
login:
|
||||||
|
# 登录缓存
|
||||||
|
cache-enable: true
|
||||||
# 是否限制单用户登录
|
# 是否限制单用户登录
|
||||||
single: false
|
single: false
|
||||||
# 验证码
|
# 验证码
|
||||||
|
@ -86,8 +88,8 @@ generator:
|
||||||
#是否开启 swagger-ui
|
#是否开启 swagger-ui
|
||||||
swagger:
|
swagger:
|
||||||
enabled: true
|
enabled: true
|
||||||
# IP 本地解析
|
|
||||||
|
|
||||||
|
# IP 本地解析
|
||||||
ip:
|
ip:
|
||||||
local-parsing: true
|
local-parsing: true
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ spring:
|
||||||
|
|
||||||
# 登录相关配置
|
# 登录相关配置
|
||||||
login:
|
login:
|
||||||
|
# 登录缓存
|
||||||
|
cache-enable: true
|
||||||
# 是否限制单用户登录
|
# 是否限制单用户登录
|
||||||
single: false
|
single: false
|
||||||
# 验证码
|
# 验证码
|
||||||
|
@ -83,7 +85,7 @@ jwt:
|
||||||
|
|
||||||
# IP 本地解析
|
# IP 本地解析
|
||||||
ip:
|
ip:
|
||||||
local-parsing: true
|
local-parsing: false
|
||||||
|
|
||||||
#是否允许生成代码,生产环境设置为false
|
#是否允许生成代码,生产环境设置为false
|
||||||
generator:
|
generator:
|
||||||
|
|
|
@ -17,16 +17,11 @@
|
||||||
<#if betweens??>
|
<#if betweens??>
|
||||||
<#list betweens as column>
|
<#list betweens as column>
|
||||||
<#if column.queryType = 'BetWeen'>
|
<#if column.queryType = 'BetWeen'>
|
||||||
<el-date-picker
|
<date-range-picker
|
||||||
v-model="query.${column.changeColumnName}"
|
v-model="query.${column.changeColumnName}"
|
||||||
:default-time="['00:00:00','23:59:59']"
|
|
||||||
type="daterange"
|
|
||||||
range-separator=":"
|
|
||||||
size="small"
|
|
||||||
class="date-item"
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
start-placeholder="${column.changeColumnName}Start"
|
start-placeholder="${column.changeColumnName}Start"
|
||||||
end-placeholder="${column.changeColumnName}End"
|
end-placeholder="${column.changeColumnName}Start"
|
||||||
|
class="date-item"
|
||||||
/>
|
/>
|
||||||
</#if>
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
|
@ -125,6 +120,7 @@ import crudOperation from '@crud/CRUD.operation'
|
||||||
import udOperation from '@crud/UD.operation'
|
import udOperation from '@crud/UD.operation'
|
||||||
import pagination from '@crud/Pagination'
|
import pagination from '@crud/Pagination'
|
||||||
|
|
||||||
|
|
||||||
const defaultForm = { <#if columns??><#list columns as column>${column.changeColumnName}: null<#if column_has_next>, </#if></#list></#if> }
|
const defaultForm = { <#if columns??><#list columns as column>${column.changeColumnName}: null<#if column_has_next>, </#if></#list></#if> }
|
||||||
export default {
|
export default {
|
||||||
name: '${className}',
|
name: '${className}',
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCache() {
|
||||||
|
long start1 = System.currentTimeMillis();
|
||||||
|
int size = 10000;
|
||||||
|
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.print("使用缓存:" + (end1 - start1) + "毫秒\n 不使用缓存:" + (end2 - start2) + "毫秒");
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,20 +38,20 @@ import java.util.Optional;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@CacheConfig(cacheNames = "alipay")
|
@CacheConfig(cacheNames = "aliPay")
|
||||||
public class AliPayServiceImpl implements AliPayService {
|
public class AliPayServiceImpl implements AliPayService {
|
||||||
|
|
||||||
private final AliPayRepository alipayRepository;
|
private final AliPayRepository alipayRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(key = "'id:1'")
|
@Cacheable(key = "'config'")
|
||||||
public AlipayConfig find() {
|
public AlipayConfig find() {
|
||||||
Optional<AlipayConfig> alipayConfig = alipayRepository.findById(1L);
|
Optional<AlipayConfig> alipayConfig = alipayRepository.findById(1L);
|
||||||
return alipayConfig.orElseGet(AlipayConfig::new);
|
return alipayConfig.orElseGet(AlipayConfig::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CachePut(key = "'id:1'")
|
@CachePut(key = "'config'")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public AlipayConfig config(AlipayConfig alipayConfig) {
|
public AlipayConfig config(AlipayConfig alipayConfig) {
|
||||||
alipayConfig.setId(1L);
|
alipayConfig.setId(1L);
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class EmailServiceImpl implements EmailService {
|
||||||
private final EmailRepository emailRepository;
|
private final EmailRepository emailRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CachePut(key = "'id:1'")
|
@CachePut(key = "'config'")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception {
|
public EmailConfig config(EmailConfig emailConfig, EmailConfig old) throws Exception {
|
||||||
emailConfig.setId(1L);
|
emailConfig.setId(1L);
|
||||||
|
@ -55,7 +55,7 @@ public class EmailServiceImpl implements EmailService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(key = "'id:1'")
|
@Cacheable(key = "'config'")
|
||||||
public EmailConfig find() {
|
public EmailConfig find() {
|
||||||
Optional<EmailConfig> emailConfig = emailRepository.findById(1L);
|
Optional<EmailConfig> emailConfig = emailRepository.findById(1L);
|
||||||
return emailConfig.orElseGet(EmailConfig::new);
|
return emailConfig.orElseGet(EmailConfig::new);
|
||||||
|
|
|
@ -65,14 +65,14 @@ public class QiNiuServiceImpl implements QiNiuService {
|
||||||
private Long maxSize;
|
private Long maxSize;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(key = "'id:1'")
|
@Cacheable(key = "'config'")
|
||||||
public QiniuConfig find() {
|
public QiniuConfig find() {
|
||||||
Optional<QiniuConfig> qiniuConfig = qiNiuConfigRepository.findById(1L);
|
Optional<QiniuConfig> qiniuConfig = qiNiuConfigRepository.findById(1L);
|
||||||
return qiniuConfig.orElseGet(QiniuConfig::new);
|
return qiniuConfig.orElseGet(QiniuConfig::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CachePut(key = "'id:1'")
|
@CachePut(key = "'config'")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public QiniuConfig config(QiniuConfig qiniuConfig) {
|
public QiniuConfig config(QiniuConfig qiniuConfig) {
|
||||||
qiniuConfig.setId(1L);
|
qiniuConfig.setId(1L);
|
||||||
|
|
|
@ -3,5 +3,5 @@ alter table code_gen_config CHANGE id config_id BIGINT(20) AUTO_INCREMENT COMMEN
|
||||||
-- code_gen_config end --
|
-- code_gen_config end --
|
||||||
|
|
||||||
-- code_column_config 表改动 start --
|
-- 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 --
|
-- code_column_config end --
|
|
@ -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 (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 (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 (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 (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 (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);
|
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 (21, 1);
|
||||||
INSERT INTO `sys_roles_menus` VALUES (22, 1);
|
INSERT INTO `sys_roles_menus` VALUES (22, 1);
|
||||||
INSERT INTO `sys_roles_menus` VALUES (23, 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 (28, 1);
|
||||||
INSERT INTO `sys_roles_menus` VALUES (30, 1);
|
INSERT INTO `sys_roles_menus` VALUES (30, 1);
|
||||||
INSERT INTO `sys_roles_menus` VALUES (32, 1);
|
INSERT INTO `sys_roles_menus` VALUES (32, 1);
|
||||||
|
|
Loading…
Reference in New Issue