diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java
index 836463fe..c12aef29 100644
--- a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java
+++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/RedisConstants.java
@@ -19,10 +19,50 @@ public final class RedisConstants {
public static final String PREFIX_MENU_CODE = "kv#{}:menu:code:";
/** 参数编号 */
- public static final String PREFIX_OPTIONS_CODE = "kv#{}:options:code";
+ public static final String PREFIX_OPTIONS_CODE = "hash#{}:options";
/** 用户搜索记录 */
public static final String PREFIX_HIS_USERNAME = "zset#{}:his:username:";
+
+
+ /** 用户ID */
+ public static final String PREFIX_USER_ID = "kv#{}:user_id:";
+
+ /** 用户ID 和 角色 */
+ public static final String PREFIX_USER_ID_AND_ROLES = "kv#{}:user_id:roles:";
+
+ /** 用户ID 和 默认角色 */
+ public static final String PREFIX_USER_ID_DEF_ROLE = "kv#{}:user_id:def_role_id:";
+
+ /** 用户ID 和 组织 */
+ public static final String PREFIX_USER_ID_ORGS = "kv#{}:user_id:orgs:";
+
+ /** 用户ID 和 默认组织 */
+ public static final String PREFIX_USER_ID_DEF_ORG = "kv#{}:user_id:def_org:";
+
+ /** 用户ID 和 权限 */
+ public static final String PREFIX_USER_ID_PERMISSIONS = "kv#{}:user_id:permissions:";
+
+ /** 用户ID 和 菜单 */
+ public static final String PREFIX_USER_ID_MENUS = "kv#{}:user_id:menus:";
+
+ /** 用户名 */
+ public static final String PREFIX_USERNAME = "kv#{}:username:";
+
+
+
+ /** 票据 */
+ public static final String PREFIX_TICKET = "set#{}:ticket:";
+
+ /** 账号失败次数 */
+ public static final String PREFIX_ACCOUNT_SLIP_COUNT = "kv#{}:account:slip:count:";
+
+ /** 账号失败锁定KEY */
+ public static final String PREFIX_ACCOUNT_SLIP_LOCK = "kv#{}:account:slip:lock:";
+
+
+
+
private RedisConstants(){}
}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java
deleted file mode 100644
index 4f8d709a..00000000
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/conf/RedisMessageListenerConfig.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
- *
- * 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 org.opsli.core.autoconfigure.conf;
-
-import lombok.extern.slf4j.Slf4j;
-import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.data.redis.listener.PatternTopic;
-import org.springframework.data.redis.listener.RedisMessageListenerContainer;
-import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
-
-
-/**
- * 消息订阅 配置
- *
- * @author Parker
- * @date 2020-09-15
- **/
-@Slf4j
-@Configuration
-@ConditionalOnProperty(name = "spring.redis.pushsub.enable", havingValue = "true")
-public class RedisMessageListenerConfig {
-
-
- /**
- * redis消息监听器容器
- * 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
- * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
- */
- @Bean
- public RedisMessageListenerContainer container(LettuceConnectionFactory lettuceConnectionFactory) {
- RedisPushSubReceiver receiver = new RedisPushSubReceiver();
- RedisMessageListenerContainer container = new RedisMessageListenerContainer();
- container.setConnectionFactory(lettuceConnectionFactory);
-
- //订阅了的通道
- container.addMessageListener(listenerAdapter(new RedisPushSubReceiver()), new PatternTopic(receiver.getListenerChannel()));
-
- return container;
- }
-
-
- /**
- * 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法
- * 想要处理消息 需要重写 消息接受方法
- *
- */
- @Bean
- public MessageListenerAdapter listenerAdapter(RedisPushSubReceiver baseReceiver) {
- //这个地方 是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
- //也有好几个重载方法,这边默认调用处理器的方法 叫handleMessage 可以自己到源码里面看
- //receiveMessage就是对应消费者那边的消费方法吗,而Receiver是自己弄的一个消费者类
- return new MessageListenerAdapter(baseReceiver, "receiveMessage");
- }
-
-}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java
index e9b28b08..38ea5651 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/autoconfigure/properties/CacheProperties.java
@@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
@EqualsAndHashCode(callSuper = false)
public class CacheProperties {
- public static final String PROP_PREFIX = "spring.cache-conf";
+ public static final String PROP_PREFIX = "spring.cache";
/** 缓存前缀 */
private String prefix;
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
index d78fbcfe..3f3f547e 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
@@ -37,30 +37,24 @@ import org.opsli.api.base.warpper.ApiWrapper;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.annotation.hotdata.EnableHotData;
-import org.opsli.common.constants.CacheConstants;
import org.opsli.common.constants.TreeConstants;
import org.opsli.common.enums.ExcelOperate;
import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException;
-import org.opsli.common.msg.CommonMsg;
import org.opsli.common.utils.OutputStreamUtil;
import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.autoconfigure.properties.GlobalProperties;
import org.opsli.core.base.entity.BaseEntity;
import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.base.service.interfaces.CrudServiceInterface;
-import org.opsli.core.cache.CacheUtil;
import org.opsli.core.msg.CoreMsg;
import org.opsli.core.msg.TokenMsg;
import org.opsli.core.security.shiro.realm.JwtRealm;
-import org.opsli.core.utils.DistributedLockUtil;
import org.opsli.core.utils.ExcelUtil;
import org.opsli.core.utils.UserUtil;
import org.opsli.plugins.excel.exception.ExcelPluginException;
import org.opsli.plugins.excel.listener.BatchExcelListener;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@@ -98,90 +92,6 @@ public abstract class BaseRestController 泛型
- */
- public static V getTimed(final Class vClass, final String key){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(vClass, key, false, false);
- }
-
- /**
- * 获得 普通 缓存
- * @param vClass 泛型Class
- * @param key 键
- * @param isSaveLocal 是否保存到本地
- * @return 泛型
- */
- public static V getTimed(final Class vClass, final String key,
- final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(vClass, key, false, isSaveLocal);
- }
-
- /**
- * 获得 普通 缓存
- * @param key 键
- * @return Object
- */
- public static Object getEden(final String key){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(key, true, false);
- }
-
- /**
- * 获得 普通 缓存
- * @param key 键
- * @param isSaveLocal 是否保存到本地
- * @return Object
- */
- public static Object getEden(final String key, final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(key, true, isSaveLocal);
- }
-
- /**
- * 获得 普通 缓存
- * @param vClass 泛型Class
- * @param key 键
- * @return 泛型
- */
- public static V getEden(final String key, final Class vClass){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(vClass, key, true, false);
- }
-
- /**
- * 获得 普通 缓存
- * @param vClass 泛型Class
- * @param key 键
- * @param isSaveLocal 是否保存到本地
- * @return 泛型
- */
- public static V getEden(final String key, final boolean isSaveLocal,
- final Class vClass){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 转换数据泛型
- return CacheUtil.get(vClass, key, true, isSaveLocal);
- }
-
- /**
- * 获得 普通 缓存
- * @param vClass 泛型Class
- * @param key 键
- * @param isEden 是否永久层数据
- * @param isSaveLocal 是否保存到本地
- * @return 泛型
- */
- private static V get(final Class vClass, final String key, final boolean isEden,
- final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 获得缓存数据
- Object cacheObj = CacheUtil.get(key, isEden, isSaveLocal);
- // 转换数据泛型
- return Convert.convert(vClass, cacheObj);
- }
-
- /**
- * 获得 普通 缓存
- * @param key 键
- * @param isEden 是否永久层数据
- * @param isSaveLocal 是否保存到本地
- * @return Object
- */
- private static Object get(final String key, final boolean isEden, final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 缓存 Key
- String cacheKey = CacheUtil.handleUsualKey(key, isEden);
-
- // 获得缓存Json
- JSONObject cacheJson;
-
- // 判读是否需要 先从本地缓存获取
- if(isSaveLocal){
- // 获得缓存Json
- cacheJson = ehCachePlugin.get(CacheConstants.EHCACHE_SPACE,
- cacheKey, JSONObject.class);
- if(cacheJson != null){
- return cacheJson.get(JSON_KEY);
- }
- }
-
- // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存
- cacheJson = (JSONObject) redisPlugin.get(cacheKey);
- if(cacheJson != null){
- // 判读是否需要 存入本地EhCache
- if(isSaveLocal){
- //存入EhCache
- ehCachePlugin.put(CacheConstants.EHCACHE_SPACE,
- cacheKey, cacheJson);
- }
- }
-
- return cacheJson != null ? cacheJson.get(JSON_KEY) : null;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return null;
- }
-
-
-
- /**
- * 获得 Hash 缓存
- * @param vClass 泛型Class
- * @param key 键
- * @param field 字段名
- * @return 泛型
- */
- public static V getHash(final Class vClass, final String key, final String field){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 获得缓存数据
- Object cacheObj = CacheUtil.getHash(key, field, false);
- // 转换数据泛型
- return Convert.convert(vClass, cacheObj);
- }
-
- /**
- * 获得 Hash 缓存
- * @param key 键
- * @param field 字段名
- * @param isSaveLocal 是否保存到本地
- * @param vClass 泛型Class
- * @return 泛型
- */
- public static V getHash(final Class vClass, final String key,
- final String field, final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 获得缓存数据
- Object cacheObj = CacheUtil.getHash(key, field, isSaveLocal);
- // 转换数据泛型
- return Convert.convert(vClass, cacheObj);
- }
-
- /**
- * 获得 Hash 缓存
- * @param key 键
- * @param field 字段名
- * @return Object
- */
- public static Object getHash(final String key, final String field){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- return CacheUtil.getHash(key, field, false);
- }
-
- /**
- * 获得 Hash 缓存
- * @param key 键
- * @param field 字段名
- * @param isSaveLocal 是否保存到本地
- * @return Object
- */
- public static Object getHash(final String key, final String field,
- final boolean isSaveLocal){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 缓存 Key
- String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key);
-
- // 获得缓存Json
- JSONObject cacheJson;
-
- // 判读是否需要 先从本地缓存获取
- if(isSaveLocal){
- // 获得缓存Json
- cacheJson = ehCachePlugin.get(CacheConstants.EHCACHE_SPACE,
- cacheKey +":"+ field, JSONObject.class);
- if(cacheJson != null){
- return cacheJson.get(JSON_KEY);
- }
- }
-
- // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存
- cacheJson = (JSONObject) redisPlugin.hGet(cacheKey, field);
- if(cacheJson != null){
- // 判读是否需要 存入本地EhCache
- if(isSaveLocal){
- //存入EhCache
- ehCachePlugin.put(CacheConstants.EHCACHE_SPACE,
- cacheKey + ":" + field, cacheJson);
- }
- }
-
- return cacheJson != null ? cacheJson.get(JSON_KEY) : null;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return null;
- }
-
-
- /**
- * 获得 Hash 缓存
- * @param key 键
- * @return Object
- */
- public static Map getHashAll(final String key){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 缓存 Key
- String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key);
-
- Map retMap = Maps.newHashMap();
-
- // 如果本地缓存找不到该缓存 则去远端缓存拉去缓存
- Map allCache = redisPlugin.hGetAll(cacheKey);
- if(CollUtil.isEmpty(allCache)){
- return retMap;
- }
-
- for (Map.Entry entry : allCache.entrySet()) {
- // 赋值
- JSONObject jsonObject = (JSONObject) entry.getValue();
- if (jsonObject == null) {
- continue;
- }
- Object data = jsonObject.get(CacheUtil.JSON_KEY);
- if (data == null) {
- continue;
- }
-
- retMap.put(Convert.toStr(entry.getKey()), data);
- }
-
- return retMap;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return null;
- }
-
- // ========================= PUT =========================
-
-
- /**
- * 存普通缓存
- * @param key 键
- * @param value 值
- * @return boolean
- */
- public static boolean put(final String key, final Object value) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- return CacheUtil.put(key, value, false);
- }
-
- /**
- * 存永久缓存
- * @param key 键
- * @param value 值
- * @param isEden 是否永久存储
- * @return boolean
- */
- public static boolean put(final String key, final Object value, final boolean isEden) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 自动处理 key
-
- // 则统一转换为 JSONObject
- JSONObject cacheJson = new JSONObject();
- cacheJson.put(JSON_KEY, value);
-
- // 缓存 Key
- String cacheKey = CacheUtil.handleUsualKey(key, isEden);
-
- // 判断是否为永久存储
- if(isEden) {
- // 存入Redis
- return redisPlugin.put(cacheKey, cacheJson);
- }else{
- // 随机缓存失效时间 防止缓存雪崩
- // 范围在当前时效的 1.2 - 2倍
-
- // 生成随机失效时间
- int timeout = RandomUtil.randomInt(
- Convert.toInt(TTL_HOT_DATA_TIME * 1.2),
- Convert.toInt(TTL_HOT_DATA_TIME * 2)
- );
-
- // 存入Redis
- return redisPlugin.put(cacheKey, cacheJson, timeout);
- }
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
-
-
- /**
- * 存 永久 Hash 缓存
- * @param key 键
- * @param field 字段名
- * @param value 值
- * @return boolean
- */
- public static boolean putHash(final String key, final String field, final Object value) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 处理 key
- String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key);
-
- // 则统一转换为 JSONObject
- JSONObject cacheJson = new JSONObject();
- cacheJson.put(JSON_KEY, value);
-
- // 存入Redis
- return redisPlugin.hPut(cacheKey, field, cacheJson);
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
-
- // ========================= DEL =========================
-
-
- /**
- * 删缓存
- * @param key 键
- * @return boolean
- */
- public static boolean del(final String key) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 计数器
- int count = 0;
-
- Object timed = CacheUtil.getTimed(key);
- Object eden = CacheUtil.getEden(key);
-
- // 删除key 集合
- List cacheKeys = Lists.newArrayList();
- if(timed != null){
- count+=2;
- // 处理 key - 时控数据
- cacheKeys.add(
- CacheUtil.handleKey(CacheType.TIMED, key)
- );
- }
- if(eden != null){
- count+=2;
- // 处理 key - 永久数据
- cacheKeys.add(
- CacheUtil.handleKey(CacheType.EDEN, key));
- }
-
- // 循环删除缓存数据
- for (String cacheKey : cacheKeys) {
-
- // 删除 EhCache
- boolean ehcacheRet = ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE, cacheKey);
- if(ehcacheRet){
- count--;
- }
-
- // 删除 Redis
- boolean redisRet = redisPlugin.del(cacheKey);
- if(redisRet){
- count--;
- }
- }
-
- return count == 0;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
- /**
- * 删 Hash 缓存
- * @param key 键
- * @param field 字段名
- * @return boolean
- */
- public static boolean delHash(final String key, final String field) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- try {
- // 计数器
- int count = 2;
-
- // 自动处理 key
- String cacheKey = CacheUtil.handleKey(CacheType.EDEN_HASH, key);
-
- // 删除 EhCache
- boolean ehcacheRet = ehCachePlugin.delete(CacheConstants.EHCACHE_SPACE,cacheKey +":"+ field);
- if(ehcacheRet){
- count--;
- }
-
- // 删除 Redis
- Long hDeleteLong = redisPlugin.hDelete(cacheKey, field);
- if(hDeleteLong != null && hDeleteLong > 0){
- count--;
- }
-
- return count == 0;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
- // ====================================================================
-
- /**
- * 放一个空属性 有效时间为 5分钟
- * 用于 防止穿透判断 弥补布隆过滤器
- *
- * @param key 键
- * @return boolean
- */
- public static boolean putNilFlag(String key) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
- // 处理缓存 key
- String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key);
-
- try {
- // 存入Redis
- Long increment = redisPlugin.increment(cacheKey);
- // 设置失效时间
- redisPlugin.expire(cacheKey, TTL_NIL_DATA_TIME);
- return increment != null;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
- /**
- * 删除空属性
- * 用于 防止穿透判断 弥补布隆过滤器
- *
- * @param key 键
- * @return boolean
- */
- public static boolean delNilFlag(String key) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 处理缓存 key
- String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key);
- try {
- // 删除Redis
- return redisPlugin.del(cacheKey);
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
-
- /**
- * 获得一个空属性 有效时间为 5分钟
- * 用于 防止穿透判断 弥补布隆过滤器
- *
- * @param key 键
- * @return boolean
- */
- public static boolean hasNilFlag(String key) {
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
- // 处理缓存 key
- String cacheKey = CacheUtil.handleKey(NIL_FLAG_PREFIX + ":" + key);
-
- try {
- Object nilObj = redisPlugin.get(cacheKey);
- if(nilObj == null){
- return false;
- }
-
- Long nilNum = Convert.toLong(nilObj, 0L);
- return NIL_FLAG_THRESHOLD < nilNum;
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return false;
- }
-
-
- // ====================================================================
-
- /**
- * 处理 key 默认为临时
- * @param key 缓存Key
- * @return String
- */
- public static String handleKey(String key){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- return CacheUtil.handleKey(CacheType.TIMED, key);
- }
-
- /**
- * 处理 key
- * @param cacheType 缓存类型
- * @param key 缓存Key
- * @return String
- */
- public static String handleKey(CacheType cacheType, String key){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- return PREFIX_NAME + cacheType.getName() + ":" +
- key;
- }
/**
* 格式化Key
@@ -754,74 +61,12 @@ public class CacheUtil {
}
- /**
- * 内部处理 普通 key
- * @param key 缓存Key
- * @param isEden 是否永久
- * @return String
- */
- private static String handleUsualKey(String key, boolean isEden){
- if(isEden){
- return CacheUtil.handleKey(CacheType.EDEN, key);
- }
- return CacheUtil.handleKey(CacheType.TIMED, key);
- }
-
- /**
- * 读配置文件
- */
- private static void readPropertyXML() throws IOException {
- // 有坑 读 xml
- ClassPathResource resource = new ClassPathResource("config/ehcache-opsli.xml");
- Document document = XmlUtil.readXML(resource.getInputStream());
- NodeList nodeList = document.getElementsByTagName("cache");
- if(nodeList != null){
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node item = nodeList.item(i);
- NamedNodeMap attributes = item.getAttributes();
- if(attributes == null){
- continue;
- }
- Node alias = attributes.getNamedItem("alias");
- if("hotData".equals(alias.getNodeValue())){
- NodeList childNodes = item.getChildNodes();
- if(childNodes != null){
- for (int j = 0; j < childNodes.getLength(); j++) {
- if("expiry".equals(childNodes.item(j).getNodeName())){
- NodeList expiryNodes = childNodes.item(j).getChildNodes();
- if(expiryNodes != null){
- for (int k = 0; k < expiryNodes.getLength(); k++) {
- if("ttl".equals(expiryNodes.item(k).getNodeName())){
- Node ttlNode = expiryNodes.item(k);
- Node ttlValue = ttlNode.getFirstChild();
- // 默认 60000秒 6小时
- TTL_HOT_DATA_TIME = Convert.toInt(ttlValue.getNodeValue(), 21600);
- break;
- }
- }
- }
- break;
- }
- }
- }
- break;
- }
- }
- }
- }
-
/**
* 初始化
*/
@Autowired
- public void init(CacheProperties cacheProperties,
- RedisPlugin redisPlugin,
- EhCachePlugin ehCachePlugin){
-
- CacheUtil.PREFIX_NAME = Convert.toStr(cacheProperties.getPrefix(), "opsli") + ":";
- CacheUtil.redisPlugin = redisPlugin;
- CacheUtil.ehCachePlugin = ehCachePlugin;
-
+ public void init(CacheProperties cacheProperties){
+ CacheUtil.PREFIX_NAME = Convert.toStr(cacheProperties.getPrefix(), "opsli");
IS_INIT = true;
}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java
index e9111bf6..a7f9616e 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/cache/SecurityCache.java
@@ -1,8 +1,24 @@
+/**
+ * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+ *
+ * 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 org.opsli.core.cache;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.Striped;
@@ -144,10 +160,12 @@ public final class SecurityCache {
throw new RuntimeException("入参[redisTemplate,key,val]必填");
}
+ String cacheKey = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV);
+
// 判断是否为永久存储
if(isEden) {
redisTemplate.opsForValue()
- .set("kv#" + key, val);
+ .set(cacheKey, val);
}else{
// 随机缓存失效时间 防止缓存雪崩
// 范围在当前时效的 1.2 - 2倍
@@ -159,7 +177,12 @@ public final class SecurityCache {
);
redisTemplate.opsForValue()
- .set(CACHE_PREFIX_KV + key, val, timeout, TimeUnit.SECONDS);
+ .set(
+ cacheKey,
+ val,
+ timeout,
+ TimeUnit.SECONDS
+ );
}
// 清除本地记录
@@ -356,8 +379,10 @@ public final class SecurityCache {
throw new RuntimeException("入参[redisTemplate,key,cacheMap]必填");
}
+ String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH);
+
redisTemplate.opsForHash()
- .putAll(CACHE_PREFIX_HASH + key, cacheMap);
+ .putAll(cacheKeyByHash, cacheMap);
// 清除本地记录
LFU_NULL_CACHE.invalidate(key);
@@ -378,8 +403,10 @@ public final class SecurityCache {
throw new RuntimeException("入参[redisTemplate,key,field,val]必填");
}
+ String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH);
+
redisTemplate.opsForHash()
- .put(CACHE_PREFIX_HASH + key, field, val);
+ .put(cacheKeyByHash, field, val);
final String tempKey = key + "_" + field;
// 清除本地记录
@@ -431,8 +458,13 @@ public final class SecurityCache {
// 清除本地记录
LFU_NULL_CACHE.invalidate(key);
+
+ String cacheKeyByKv = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV);
+ String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH);
+
// 清除缓存
- redisTemplate.delete(key);
+ redisTemplate.delete(cacheKeyByKv);
+ redisTemplate.delete(cacheKeyByHash);
return true;
}
@@ -455,8 +487,10 @@ public final class SecurityCache {
return null;
}
+ String cacheKey = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_KV);
+
// 从 缓存回调查询数据
- cache = redisTemplate.opsForValue().get(CACHE_PREFIX_KV + key);
+ cache = redisTemplate.opsForValue().get(cacheKey);
}catch (Exception e){
log.error(e.getMessage(), e);
}
@@ -481,8 +515,10 @@ public final class SecurityCache {
return null;
}
+ String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH);
+
// 从 缓存回调查询数据
- cache = redisTemplate.opsForHash().get(CACHE_PREFIX_HASH + key, field);
+ cache = redisTemplate.opsForHash().get(cacheKeyByHash, field);
}catch (Exception e){
log.error(e.getMessage(), e);
}
@@ -508,8 +544,10 @@ public final class SecurityCache {
return null;
}
+ String cacheKeyByHash = StrUtil.addPrefixIfNot(key, CACHE_PREFIX_HASH);
+
// 从 缓存回调查询数据
- Map entries = redisTemplate.opsForHash().entries(CACHE_PREFIX_HASH + key);
+ Map entries = redisTemplate.opsForHash().entries(cacheKeyByHash);
// 如果补偿器不为空 则进行补偿判断
if(null != callbackSourceCount){
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java
deleted file mode 100644
index d5bbf7f4..00000000
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/filters/aspect/CacheDataAop.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
- *
- * 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 org.opsli.core.filters.aspect;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import com.google.common.collect.Lists;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.opsli.api.base.warpper.ApiWrapper;
-import org.opsli.common.annotation.hotdata.EnableHotData;
-import org.opsli.common.annotation.hotdata.HotDataDel;
-import org.opsli.common.annotation.hotdata.HotDataPut;
-import org.opsli.common.constants.CacheConstants;
-import org.opsli.core.cache.CacheUtil;
-import org.opsli.core.cache.pushsub.entity.CacheDataEntity;
-import org.opsli.core.cache.pushsub.enums.CacheHandleType;
-import org.opsli.core.cache.pushsub.msgs.CacheDataMsgFactory;
-import org.opsli.plugins.redis.RedisPlugin;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.List;
-
-import static org.opsli.common.constants.OrderConstants.HOT_DATA_ORDER;
-
-/**
- * 热点数据 拦截处理
- *
- * @author parker
- * @date 2020-09-16
- */
-@Slf4j
-@Order(HOT_DATA_ORDER)
-@Aspect
-@Component
-public class CacheDataAop {
-
- @Autowired
- private RedisPlugin redisPlugin;
-
- @Pointcut("@annotation(org.opsli.common.annotation.hotdata.HotDataPut)")
- public void hotDataPut() {
- }
-
- @Pointcut("@annotation(org.opsli.common.annotation.hotdata.HotDataDel)")
- public void hotDataDel() {
- }
-
- /**
- * 切如 更新数据
- * @param point point
- * @return Object
- * @throws Throwable 异常
- */
- @Around("hotDataPut()")
- public Object hotDataPutProcess(ProceedingJoinPoint point) throws Throwable {
- Object[] args = point.getArgs();
- Object returnValue = point.proceed(args);
- // 判断 方法上是否使用 EnableHotData注解 如果没有表示开启热数据 则直接跳过
- Annotation annotation = point.getTarget().getClass().getAnnotation(EnableHotData.class);
- if(annotation == null){
- return returnValue;
- }
-
- List cacheDataEntityList = this.putHandlerData(point, returnValue);
- // 非法判断
- if(CollUtil.isEmpty(cacheDataEntityList)){
- return returnValue;
- }
-
- for (CacheDataEntity cacheDataEntity : cacheDataEntityList) {
- // 更新缓存数据
- // 热点数据
- boolean putRet = CacheUtil.put(CacheConstants.HOT_DATA_PREFIX +":"+ cacheDataEntity.getKey(),
- returnValue);
- if(putRet){
- // 广播缓存数据 - 通知其他服务器同步数据
- redisPlugin.sendMessage(
- CacheDataMsgFactory.createMsg(
- cacheDataEntity, returnValue, CacheHandleType.UPDATE)
- );
- }
- }
-
- return returnValue;
- }
-
-
- /**
- * 切如 删除数据 和 逻辑删除上
- * @param point point
- * @return Object
- * @throws Throwable 异常
- */
- @Around("hotDataDel()")
- public Object hotDataDelProcess(ProceedingJoinPoint point) throws Throwable {
- Object[] args= point.getArgs();
- Object returnValue = point.proceed(args);
- // 判断 方法上是否使用 EnableHotData注解 如果没有表示开启热数据 则直接跳过
- Annotation annotation = point.getTarget().getClass().getAnnotation(EnableHotData.class);
- if(annotation == null){
- return returnValue;
- }
-
- // 删除状态判断
- try {
- Boolean ret = (Boolean) returnValue;
- if(ret == null || !ret){
- return returnValue;
- }
- }catch (Exception e){
- log.error(e.getMessage(),e);
- return returnValue;
- }
-
- List cacheDataEntityList = this.delHandlerData(point, args);
- // 非法判断
- if(CollUtil.isEmpty(cacheDataEntityList)){
- return returnValue;
- }
-
- for (CacheDataEntity cacheDataEntity : cacheDataEntityList) {
- // 更新缓存数据 - 删除缓存
- boolean delRet = CacheUtil.del(CacheConstants.HOT_DATA_PREFIX +":"+ cacheDataEntity.getKey());
- if(delRet){
- // 广播缓存数据 - 通知其他服务器同步数据
- redisPlugin.sendMessage(
- CacheDataMsgFactory.createMsg(
- cacheDataEntity, null, CacheHandleType.DELETE)
- );
- }
- }
-
- return returnValue;
- }
-
-
- // ===========================================================================
-
-
- /***
- * PUT 处理数据
- * @param point point
- */
- private List putHandlerData(ProceedingJoinPoint point, Object returnValue){
- // 这里 只对 继承了 ApiWrapper 的类做处理
- if(!(returnValue instanceof ApiWrapper)){
- return null;
- }
-
- // 消息集合 后续可能会考虑 多消息存储
- List cacheDataEntities = Lists.newArrayListWithCapacity(1);
-
- // 报错不处理
- try {
- // 获得方法
- Method objMethod = this.getMethod(point);
- if(objMethod == null) {
- return null;
- }
-
- // 获取注解参数
- HotDataPut aCache = objMethod.getAnnotation(HotDataPut.class);
- if(aCache != null){
- // 这里 只对 继承了 BaseEntity 的类做处理
- ApiWrapper apiWrapper = (ApiWrapper) returnValue;
-
- CacheDataEntity ret = new CacheDataEntity(apiWrapper.getId());
- // 存放数据
- this.putCacheData(cacheDataEntities, ret);
-
- return cacheDataEntities;
- }
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return null;
- }
-
-
- /***
- * DEL 处理数据
- * @param point point
- */
- private List delHandlerData(ProceedingJoinPoint point, Object[] args){
- if(args == null || args.length == 0){
- return null;
- }
-
- // 消息集合
- List cacheDataEntities = Lists.newArrayListWithCapacity(args.length);
-
- // 报错不处理
- try {
- // 获得方法
- Method objMethod = this.getMethod(point);
- if(objMethod == null) {
- return null;
- }
-
- // 获取注解参数
- HotDataDel aCache= objMethod.getAnnotation(HotDataDel.class);
- if(aCache != null){
-
- List keyList = null;
-
- // 处理数据
- for (Object arg : args) {
- if (arg instanceof ApiWrapper) {
- // key 存储ID
- ApiWrapper apiWrapper = Convert.convert(ApiWrapper.class, arg);
- keyList = Convert.toList(String.class, apiWrapper.getId());
- } else if (arg instanceof Collection) {
- try {
- keyList = Lists.newArrayList();
- List baseEntityList = Convert.toList(ApiWrapper.class, arg);
- for (ApiWrapper baseEntity : baseEntityList) {
- keyList.add(baseEntity.getId());
- }
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- }else {
- keyList = Convert.toList(String.class, arg);
- }
- }
-
- if(keyList != null && CollUtil.isNotEmpty(keyList)){
- for (String key : keyList) {
- CacheDataEntity ret = new CacheDataEntity(key);
- // 存放数据
- this.putCacheData(cacheDataEntities, ret);
- }
- }
-
- return cacheDataEntities;
- }
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }
- return null;
- }
-
-
- // =====================
-
- /**
- * 获得方法
- * @param point point
- * @return Method 方法
- */
- private Method getMethod(ProceedingJoinPoint point){
- Method m = null;
- try {
- String methodName= point.getSignature().getName();
- Class> classTarget= point.getTarget().getClass();
- Class>[] par=((MethodSignature) point.getSignature()).getParameterTypes();
- m = classTarget.getMethod(methodName, par);
- }catch (Exception ignored){}
- return m;
- }
-
- /**
- * 存放数据
- * @param cacheDataList 缓存数据集合
- * @param cacheData 缓存数据
- */
- private void putCacheData(List cacheDataList, CacheDataEntity cacheData){
- // 非法判断
- if(cacheDataList == null){
- return;
- }
- cacheDataList.add(cacheData);
- }
-
-
-}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java
index 23ea767f..c06a581e 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/CaptchaUtil.java
@@ -98,8 +98,11 @@ public class CaptchaUtil {
// 生成验证码
Captcha captcha = captchaStrategy.createCaptcha();
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(PREFIX + uuid);
+
// 保存至缓存
- boolean ret = redisPlugin.put(CacheUtil.getPrefixName() + PREFIX + uuid, captcha.text(), TIME_OUT);
+ boolean ret = redisPlugin.put(cacheKey, captcha.text(), TIME_OUT);
if(ret){
// 输出
captcha.out(out);
@@ -127,8 +130,11 @@ public class CaptchaUtil {
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_CODE_NULL);
}
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(PREFIX + uuid);
+
// 验证码
- String codeTemp = (String) redisPlugin.get(CacheUtil.getPrefixName() + PREFIX + uuid);
+ String codeTemp = (String) redisPlugin.get(cacheKey);
if (StringUtils.isEmpty(codeTemp)) {
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_NULL);
}
@@ -156,8 +162,11 @@ public class CaptchaUtil {
return false;
}
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(PREFIX + uuid);
+
//删除验证码
- return redisPlugin.del(CacheUtil.getPrefixName() + PREFIX + uuid);
+ return redisPlugin.del(cacheKey);
}
// ======================
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java
index 2fcd5999..4ad19619 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/DistributedLockUtil.java
@@ -60,7 +60,9 @@ public class DistributedLockUtil {
boolean isLock = true;
// 分布式上锁
if(REDISSON_LOCK != null){
- isLock = REDISSON_LOCK.tryLock(CacheUtil.getPrefixName() + lockName, LEASE_TIME);
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(lockName);
+ isLock = REDISSON_LOCK.tryLock(cacheKey, LEASE_TIME);
}
return isLock;
}
@@ -76,7 +78,9 @@ public class DistributedLockUtil {
// 释放锁
if(REDISSON_LOCK != null){
- REDISSON_LOCK.unlockByThread(CacheUtil.getPrefixName() + lockName);
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(lockName);
+ REDISSON_LOCK.unlockByThread(cacheKey);
}
}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java
index 2f710acb..b6bc8f91 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/MenuUtil.java
@@ -45,9 +45,6 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
@Lazy(false)
public class MenuUtil {
- /** 前缀 */
- public static final String PREFIX_CODE = "menu:code:";
-
/** 菜单 Api */
private static MenuApi menuApi;
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java
index fca7063a..c6a6e865 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserTokenUtil.java
@@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
import org.opsli.api.wrapper.system.user.UserModel;
+import org.opsli.common.constants.RedisConstants;
import org.opsli.common.constants.SignConstants;
import org.opsli.common.constants.TokenConstants;
import org.opsli.common.constants.TokenTypeConstants;
@@ -64,12 +65,6 @@ public class UserTokenUtil {
/** token 缓存名 */
public static final String TOKEN_NAME = TokenConstants.ACCESS_TOKEN;
- /** 缓存前缀 */
- private static final String TICKET_PREFIX = "ticket:";
- /** 账号失败次数 */
- public static final String ACCOUNT_SLIP_COUNT_PREFIX = "account:slip:count:";
- /** 账号失败锁定KEY */
- public static final String ACCOUNT_SLIP_LOCK_PREFIX = "account:slip:lock:";
/** 限制登录数量 -1 为无限大 */
public static final int ACCOUNT_LIMIT_INFINITE = -1;
/** 登录配置信息 */
@@ -100,8 +95,8 @@ public class UserTokenUtil {
// 如果当前登录开启 数量限制
if(LOGIN_PROPERTIES.getLimitCount() > ACCOUNT_LIMIT_INFINITE){
// 当前用户已存在 Token数量
- Long ticketLen = redisPlugin.sSize(CacheUtil.getPrefixName() +
- TICKET_PREFIX + user.getUsername());
+ Long ticketLen = redisPlugin.sSize(
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()));
if(ticketLen !=null && ticketLen >= LOGIN_PROPERTIES.getLimitCount()){
// 如果是拒绝后者 则直接抛出异常
if(LoginLimitRefuse.AFTER == LOGIN_PROPERTIES.getLimitRefuse()){
@@ -110,7 +105,9 @@ public class UserTokenUtil {
}
// 如果是拒绝前者 则弹出前者
else {
- redisPlugin.sPop(CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername());
+ redisPlugin.sPop(
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername())
+ );
}
}
}
@@ -135,11 +132,13 @@ public class UserTokenUtil {
// 在redis存一份 token 是为了防止 人为造假
// 保存用户token
Long saveLong = redisPlugin.sPut(
- CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(), signToken);
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()),
+ signToken
+ );
if(saveLong != null && saveLong > 0){
// 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命
redisPlugin.expire(
- CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(),
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()),
JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS);
TokenRet tokenRet = new TokenRet();
@@ -249,11 +248,13 @@ public class UserTokenUtil {
if(user != null){
// 删除Token信息
redisPlugin.sRemove(
- CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername(), token);
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername()),
+ token);
// 如果缓存中 无该用户任何Token信息 则删除用户缓存
Long size = redisPlugin.sSize(
- CacheUtil.getPrefixName() + TICKET_PREFIX + user.getUsername());
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + user.getUsername())
+ );
if(size == null || size == 0L) {
// 删除相关信息
UserUtil.refreshUser(user);
@@ -296,7 +297,8 @@ public class UserTokenUtil {
String username = getUserNameByToken(token);
boolean hashKey = redisPlugin.sHashKey(
- CacheUtil.getPrefixName() + TICKET_PREFIX + username, token);
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username),
+ token);
if(!hashKey){
return false;
}
@@ -305,7 +307,7 @@ public class UserTokenUtil {
if(BooleanUtil.isTrue(LOGIN_PROPERTIES.getReviveMode())){
// 设置该用户全部token失效时间, 如果这时又有新设备登录 则续命
redisPlugin.expire(
- CacheUtil.getPrefixName() + TICKET_PREFIX + username,
+ CacheUtil.formatKey(RedisConstants.PREFIX_TICKET + username),
JwtUtil.EXPIRE_MILLISECOND, TimeUnit.MILLISECONDS);
}
@@ -329,7 +331,7 @@ public class UserTokenUtil {
// 判断账号是否临时锁定
Long loseTimeMillis = (Long) redisPlugin.get(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username);
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username));
if(loseTimeMillis != null){
Date currDate = DateUtil.date();
DateTime loseDate = DateUtil.date(loseTimeMillis);
@@ -364,18 +366,19 @@ public class UserTokenUtil {
// 如果失败次数 超过阈值 则锁定账号
Long slipNum = redisPlugin.increment(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username);
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username));
if (slipNum != null){
// 设置失效时间为 5分钟
redisPlugin.expire(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username, LOGIN_PROPERTIES.getSlipLockSpeed());
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username),
+ LOGIN_PROPERTIES.getSlipLockSpeed());
// 如果确认 都失败 则存入临时缓存
if(slipNum >= LOGIN_PROPERTIES.getSlipCount()){
long currentTimeMillis = System.currentTimeMillis();
// 存入Redis
redisPlugin.put(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username,
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username),
currentTimeMillis, LOGIN_PROPERTIES.getSlipLockSpeed());
}
}
@@ -396,7 +399,7 @@ public class UserTokenUtil {
long count = 0L;
Object obj = redisPlugin.get(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username);
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username));
if(obj != null){
try {
count = Convert.convert(Long.class, obj);
@@ -418,10 +421,10 @@ public class UserTokenUtil {
// 删除失败次数记录
redisPlugin.del(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_COUNT_PREFIX + username);
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_COUNT + username));
// 删除失败次数记录
redisPlugin.del(
- CacheUtil.getPrefixName() + ACCOUNT_SLIP_LOCK_PREFIX + username);
+ CacheUtil.formatKey(RedisConstants.PREFIX_ACCOUNT_SLIP_LOCK + username));
}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java
index 471123cb..ca9aa1fa 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/utils/UserUtil.java
@@ -29,16 +29,18 @@ import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.role.RoleModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
-import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
+import org.opsli.common.constants.RedisConstants;
import org.opsli.common.exception.TokenException;
import org.opsli.core.api.TokenThreadLocal;
import org.opsli.core.autoconfigure.properties.GlobalProperties;
import org.opsli.core.cache.CacheUtil;
+import org.opsli.core.cache.SecurityCache;
import org.opsli.core.msg.CoreMsg;
import org.opsli.core.msg.TokenMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -57,16 +59,6 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
@Lazy(false)
public class UserUtil {
- /** 前缀 */
- public static final String PREFIX_ID = "userId:";
- public static final String PREFIX_ID_ROLES = "userId:roles:";
- public static final String PREFIX_ID_DEF_ROLE = "userId:def_role:";
- public static final String PREFIX_ID_ORGS = "userId:orgs:";
- public static final String PREFIX_ID_DEF_ORG = "userId:def_org:";
- public static final String PREFIX_ID_PERMISSIONS = "userId:permissions:";
- public static final String PREFIX_ID_MENUS = "userId:menus:";
- public static final String PREFIX_USERNAME = "username:";
-
/** 修改租户权限 */
private static final String PERMS_TENANT = "system_user_tenant";
@@ -85,6 +77,8 @@ public class UserUtil {
/** 增加初始状态开关 防止异常使用 */
private static boolean IS_INIT;
+ private static RedisTemplate redisTemplate;
+
/**
* 获得当前系统登陆用户
* @return UserModel
@@ -169,67 +163,24 @@ public class UserUtil {
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 缓存Key
- String cacheKey = PREFIX_ID + userId;
-
- // 先从缓存里拿
- UserModel userModel = CacheUtil.getTimed(UserModel.class, cacheKey);
- if (userModel != null){
- // 如果不是递归触发 可进入一次
- if(!isRecursion){
- // 如果是 切换租户权限 则进行新一轮判断
- // 注意不要陷入递归死循环 只保障循环一次
- if (StringUtils.isNotBlank(userModel.getSwitchTenantUserId())){
- userModel = getUser(userModel.getSwitchTenantUserId(), true);
- }
- }
- return userModel;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return null;
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return null;
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- userModel = CacheUtil.getTimed(UserModel.class, cacheKey);
- if (userModel != null){
- return userModel;
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + userId);
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
UserModel userModelTemp = new UserModel();
userModelTemp.setId(userId);
// 设置为系统内部调用 否则 会拿到 空值
userModelTemp.setIzApi(true);
+
+ // 查询数据库
ResultVo resultVo = userApi.get(userModelTemp);
- if(resultVo.isSuccess()){
- userModel = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, userModel);
+ if(!resultVo.isSuccess()){
+ return null;
}
+ return resultVo.getData();
+ }, true);
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
-
- if(userModel == null){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
- return null;
- }
+ UserModel userModel = Convert.convert(UserModel.class, cache);
// 如果不是递归触发 可进入一次
if(!isRecursion){
@@ -255,56 +206,18 @@ public class UserUtil {
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 缓存Key
- String cacheKey = PREFIX_USERNAME + userName;
-
- // 先从缓存里拿
- UserModel userModel = CacheUtil.getTimed(UserModel.class, cacheKey);
- if (userModel != null){
- return userModel;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return null;
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return null;
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- userModel = CacheUtil.getTimed(UserModel.class, cacheKey);
- if (userModel != null) {
- return userModel;
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + userName);
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
ResultVo resultVo = userApi.getUserByUsername(userName);
- if (resultVo.isSuccess()) {
- userModel = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, userModel);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
+ return resultVo.getData();
+ }, true);
- if(userModel == null){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
- return null;
- }
-
- return userModel;
+ return Convert.convert(UserModel.class, cache);
}
/**
@@ -325,59 +238,22 @@ public class UserUtil {
}
// 缓存Key
- String cacheKey = PREFIX_ID_ROLES + userId;
-
- List roles;
-
- // 先从缓存里拿
- Object obj = CacheUtil.getTimed(cacheKey);
- roles = Convert.toList(String.class, obj);
- if(CollUtil.isNotEmpty(roles)){
- return roles;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return ListUtil.empty();
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return ListUtil.empty();
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- obj = CacheUtil.getTimed(cacheKey);
- roles = Convert.toList(String.class, obj);
- if(CollUtil.isNotEmpty(roles)){
- return roles;
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_AND_ROLES + userId);
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo> resultVo = userRoleRefApi.getRolesByUserId(userId);
- if(resultVo.isSuccess()){
- roles = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, roles);
+ ResultVo> resultVo = userRoleRefApi.getRolesByUserId(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
+ return resultVo.getData();
+ }, true);
- if(CollUtil.isEmpty(roles)){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
+ List roles = Convert.toList(String.class, cache);
+ if(null == roles){
return ListUtil.empty();
}
-
return roles;
}
@@ -399,60 +275,24 @@ public class UserUtil {
userId = currUser.getSwitchTenantUserId();
}
- // 缓存Key
- String cacheKey = PREFIX_ID_PERMISSIONS + userId;
-
- List permissions;
-
- // 先从缓存里拿
- Object obj = CacheUtil.getTimed(cacheKey);
- permissions = Convert.toList(String.class, obj);
- if(CollUtil.isNotEmpty(permissions)){
- return permissions;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return ListUtil.empty();
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return ListUtil.empty();
- }
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- obj = CacheUtil.getTimed(cacheKey);
- permissions = Convert.toList(String.class, obj);
- if(CollUtil.isNotEmpty(permissions)){
- return permissions;
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_PERMISSIONS + userId);
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo> resultVo = userRoleRefApi.getAllPerms(userId);
- if(resultVo.isSuccess()){
- permissions = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, permissions);
+ ResultVo> resultVo = userRoleRefApi.getAllPerms(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
+ return resultVo.getData();
+ }, true);
- if(CollUtil.isEmpty(permissions)){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
+ List permissions = Convert.toList(String.class, cache);
+ if(null == permissions){
return ListUtil.empty();
}
-
return permissions;
}
@@ -473,61 +313,24 @@ public class UserUtil {
userId = currUser.getSwitchTenantUserId();
}
- // 缓存Key
- String cacheKey = PREFIX_ID_ORGS + userId;
-
- List orgList;
-
- // 先从缓存里拿
- Object obj = CacheUtil.getTimed(cacheKey);
- orgList = Convert.toList(UserOrgRefModel.class, obj);
- if(CollUtil.isNotEmpty(orgList)){
- return orgList;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return ListUtil.empty();
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_ORGS + userId);
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return ListUtil.empty();
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- obj = CacheUtil.getTimed(cacheKey);
- orgList = Convert.toList(UserOrgRefModel.class, obj);
- if(CollUtil.isNotEmpty(orgList)){
- return orgList;
- }
-
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo> resultVo = userOrgRefApi.findListByUserId(userId);
- if(resultVo.isSuccess()){
- orgList = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, orgList);
+ ResultVo> resultVo = userOrgRefApi.findListByUserId(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
+ return resultVo.getData();
+ }, true);
- if(CollUtil.isEmpty(orgList)){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
+ List orgList = Convert.toList(UserOrgRefModel.class, cache);
+ if(null == orgList){
return ListUtil.empty();
}
-
return orgList;
}
@@ -561,61 +364,24 @@ public class UserUtil {
userId = currUser.getSwitchTenantUserId();
}
- // 缓存Key
- String cacheKey = PREFIX_ID_MENUS + userId;
-
- List menus;
-
- // 先从缓存里拿
- Object obj = CacheUtil.getTimed(cacheKey);
- menus = Convert.toList(MenuModel.class, obj);
- if(CollUtil.isNotEmpty(menus)){
- return menus;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return ListUtil.empty();
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return ListUtil.empty();
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- obj = CacheUtil.getTimed(cacheKey);
- menus = Convert.toList(MenuModel.class, obj);
- if(CollUtil.isNotEmpty(menus)){
- return menus;
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_MENUS + userId);
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo> resultVo = userRoleRefApi.getMenuListByUserId(userId);
- if(resultVo.isSuccess()){
- menus = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, menus);
+ ResultVo> resultVo = userRoleRefApi.getMenuListByUserId(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
+ return resultVo.getData();
+ }, true);
- if(CollUtil.isEmpty(menus)){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
+ List menus = Convert.toList(MenuModel.class, cache);
+ if(null == menus){
return ListUtil.empty();
}
-
return menus;
}
@@ -637,57 +403,21 @@ public class UserUtil {
userId = currUser.getSwitchTenantUserId();
}
- // 缓存Key
- String cacheKey = PREFIX_ID_DEF_ROLE + userId;
-
- // 先从缓存里拿
- RoleModel roleModel = CacheUtil.getTimed(RoleModel.class, cacheKey);
- if (roleModel != null){
- return roleModel;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return null;
- }
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return null;
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- roleModel = CacheUtil.getTimed(RoleModel.class, cacheKey);
- if (roleModel != null){
- return roleModel;
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ROLE + userId);
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo resultVo = userRoleRefApi.getDefRoleByUserId(userId);
- if(resultVo.isSuccess()){
- roleModel = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, roleModel);
+ ResultVo resultVo = userRoleRefApi.getDefRoleByUserId(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
-
- if(roleModel == null){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
- return null;
- }
+ return resultVo.getData();
+ }, true);
- return roleModel;
+ return Convert.convert(RoleModel.class, cache);
}
@@ -710,56 +440,19 @@ public class UserUtil {
}
// 缓存Key
- String cacheKey = PREFIX_ID_DEF_ORG + userId;
-
- // 先从缓存里拿
- UserOrgRefModel orgModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey);
- if (orgModel != null){
- return orgModel;
- }
-
- // 拿不到 --------
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return null;
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return null;
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- orgModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey);
- if (orgModel != null){
- return orgModel;
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ORG + userId);
+ final String finalUserId = userId;
+ Object cache = SecurityCache.get(redisTemplate, cacheKey, (k) -> {
// 查询数据库
- ResultVo resultVo = userOrgRefApi.getDefOrgByUserId(userId);
- if(resultVo.isSuccess()){
- orgModel = resultVo.getData();
- // 存入缓存
- CacheUtil.put(cacheKey, orgModel);
+ ResultVo resultVo = userOrgRefApi.getDefOrgByUserId(finalUserId);
+ if(!resultVo.isSuccess()){
+ return null;
}
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
-
- if(orgModel == null){
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
- return null;
- }
+ return resultVo.getData();
+ }, true);
- return orgModel;
+ return Convert.convert(UserOrgRefModel.class, cache);
}
@@ -781,33 +474,11 @@ public class UserUtil {
}
// 缓存Key
- String cacheKey = PREFIX_ID + user.getId();
- try {
- // 存入缓存
- CacheUtil.put(cacheKey, user);
- }catch (Exception e){
- log.error(e.getMessage(), e);
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return false;
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + user.getId());
+ // 存入缓存
+ SecurityCache.put(redisTemplate, cacheKey, user);
- // 存入缓存
- flag = CacheUtil.put(cacheKey, user);
- }catch (Exception e){
- flag = false;
- log.error(e.getMessage(), e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
-
- return flag;
+ return true;
}
/**
@@ -824,49 +495,22 @@ public class UserUtil {
return true;
}
- UserModel userModelById = CacheUtil.getTimed(
- UserModel.class, PREFIX_ID + user.getId());
- UserModel userModelByUsername = CacheUtil.getTimed(
- UserModel.class, PREFIX_USERNAME + user.getUsername());
-
- boolean hasNilFlagById = CacheUtil.hasNilFlag(PREFIX_ID + user.getId());
- boolean hasNilFlagByName = CacheUtil.hasNilFlag(PREFIX_USERNAME + user.getUsername());
+ String cacheKeyByUserId = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID + user.getId());
+ String cacheKeyByUsername = CacheUtil.formatKey(RedisConstants.PREFIX_USERNAME + user.getUsername());
// 计数器
- int count = 0;
-
- if (hasNilFlagById){
- count++;
+ int count = 2;
+ {
// 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID + user.getId());
+ boolean tmp = SecurityCache.remove(redisTemplate, cacheKeyByUserId);
if(tmp){
count--;
}
}
- if (hasNilFlagByName){
- count++;
+ {
// 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_USERNAME + user.getUsername());
- if(tmp){
- count--;
- }
- }
-
- // 只要有一个不为空 则执行刷新
- if (userModelById != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID + user.getId());
- if(tmp){
- count--;
- }
- }
-
- if (userModelByUsername != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_USERNAME + user.getUsername());
+ boolean tmp = SecurityCache.remove(redisTemplate, cacheKeyByUsername);
if(tmp){
count--;
}
@@ -886,32 +530,9 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
- Object obj = CacheUtil.getTimed(PREFIX_ID_ROLES + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_ROLES + userId);
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_AND_ROLES + userId);
- // 计数器
- int count = 0;
-
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_ROLES + userId);
- if(tmp){
- count--;
- }
- }
-
- if(obj != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_ROLES + userId);
- if(tmp){
- count--;
- }
- }
-
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
/**
@@ -928,32 +549,9 @@ public class UserUtil {
return true;
}
- // 计数器
- int count = 0;
-
- RoleModel roleModel = CacheUtil.getTimed(RoleModel.class, PREFIX_ID_DEF_ROLE + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_DEF_ROLE + userId);
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ROLE + userId);
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_DEF_ROLE + userId);
- if(tmp){
- count--;
- }
- }
-
- if(roleModel != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_DEF_ROLE + userId);
- if(tmp){
- count--;
- }
- }
-
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
@@ -968,34 +566,9 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_PERMISSIONS + userId);
- Object obj = CacheUtil.getTimed(PREFIX_ID_PERMISSIONS + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_PERMISSIONS + userId);
-
- // 计数器
- int count = 0;
-
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_PERMISSIONS + userId);
- if(tmp){
- count--;
- }
- }
-
- if(obj != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_PERMISSIONS + userId);
- if(tmp){
- count--;
- }
- }
-
-
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
/**
@@ -1012,31 +585,9 @@ public class UserUtil {
return true;
}
- // 计数器
- int count = 0;
-
- UserOrgRefWebModel orgRefModel = CacheUtil.getTimed(UserOrgRefWebModel.class, PREFIX_ID_ORGS + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_ORGS + userId);
-
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_ORGS + userId);
- if(tmp){
- count--;
- }
- }
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_ORGS + userId);
- if(orgRefModel != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_ORGS + userId);
- if(tmp){
- count--;
- }
- }
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
/**
@@ -1053,32 +604,9 @@ public class UserUtil {
return true;
}
- // 计数器
- int count = 0;
-
- UserOrgRefModel orgModel = CacheUtil.getTimed(UserOrgRefModel.class, PREFIX_ID_DEF_ORG + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_DEF_ORG + userId);
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_DEF_ORG + userId);
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_DEF_ORG + userId);
- if(tmp){
- count--;
- }
- }
-
- if(orgModel != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_DEF_ORG + userId);
- if(tmp){
- count--;
- }
- }
-
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
@@ -1092,33 +620,9 @@ public class UserUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
+ String cacheKey = CacheUtil.formatKey(RedisConstants.PREFIX_USER_ID_MENUS + userId);
- Object obj = CacheUtil.getTimed(PREFIX_ID_MENUS + userId);
- boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_ID_MENUS + userId);
-
- // 计数器
- int count = 0;
-
- // 只要不为空 则执行刷新
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(PREFIX_ID_MENUS + userId);
- if(tmp){
- count--;
- }
- }
-
- if(obj != null){
- count++;
- // 先删除
- boolean tmp = CacheUtil.del(PREFIX_ID_MENUS + userId);
- if(tmp){
- count--;
- }
- }
-
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
/**
@@ -1201,7 +705,8 @@ public class UserUtil {
public void init(GlobalProperties globalProperties,
UserApi userApi,
UserRoleRefApi userRoleRefApi,
- UserOrgRefApi userOrgRefApi){
+ UserOrgRefApi userOrgRefApi,
+ RedisTemplate redisTemplate) {
if(globalProperties != null && globalProperties.getAuth() != null
&& globalProperties.getAuth().getToken() != null
){
@@ -1210,11 +715,9 @@ public class UserUtil {
}
UserUtil.userApi = userApi;
-
UserUtil.userRoleRefApi = userRoleRefApi;
-
UserUtil.userOrgRefApi = userOrgRefApi;
-
+ UserUtil.redisTemplate = redisTemplate;
IS_INIT = true;
}
diff --git a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java
index 826b1796..7868f839 100644
--- a/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java
+++ b/opsli-modulars/opsli-modulars-generator/src/main/java/org/opsli/plugins/generator/utils/GenTemplateUtil.java
@@ -20,16 +20,18 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.convert.Convert;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.opsli.core.cache.CacheUtil;
+import org.opsli.core.cache.SecurityCache;
import org.opsli.core.msg.CoreMsg;
-import org.opsli.core.utils.DistributedLockUtil;
import org.opsli.core.utils.ThrowExceptionUtil;
import org.opsli.modulars.generator.template.service.IGenTemplateDetailService;
import org.opsli.modulars.generator.template.wrapper.GenTemplateDetailModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -53,11 +55,13 @@ public class GenTemplateUtil {
private static boolean IS_INIT;
/** 缓存前缀 NAME */
- private static final String CACHE_PREFIX_NAME = "gen:template:";
+ private static final String CACHE_PREFIX_NAME = "hash#{}:gen:template:";
/** 代码模板明细 Service */
private static IGenTemplateDetailService genTemplateDetailService;
+ private static RedisTemplate redisTemplate;
+
/**
* 根据模板ID 模板明细列表
* @param parentId 模板ID
@@ -69,77 +73,21 @@ public class GenTemplateUtil {
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
// 缓存Key
- String cacheKey = CACHE_PREFIX_NAME + parentId;
-
- // 处理集合数据
- List wrapperModels = handleDictList(
- CacheUtil.getHashAll(cacheKey), parentId);
- if(CollUtil.isNotEmpty(wrapperModels)){
- return sortWrappers(wrapperModels);
- }
-
- // 防止缓存穿透判断
- boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
- if(hasNilFlag){
- return sortWrappers(wrapperModels);
- }
-
- try {
- // 分布式加锁
- if(!DistributedLockUtil.lock(cacheKey)){
- // 无法申领分布式锁
- log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
- return sortWrappers(wrapperModels);
- }
-
- // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
- // 处理集合数据
- wrapperModels = handleDictList(
- CacheUtil.getHashAll(cacheKey), parentId);
- if(CollUtil.isNotEmpty(wrapperModels)){
- return sortWrappers(wrapperModels);
- }
-
+ String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + parentId);
- List listByParent = genTemplateDetailService.findListByParent(parentId);
+ Map templateCache = SecurityCache.hGetAll(redisTemplate, cacheKey, (k) -> {
// 处理数据库查询数据
- if(CollUtil.isNotEmpty(listByParent)){
- wrapperModels = listByParent;
- // 计数器
- int count = wrapperModels.size();
- for (GenTemplateDetailModel model : wrapperModels) {
- // 保存至缓存
- boolean ret = GenTemplateUtil.put(model);
- if(ret){
- count--;
- }
- }
-
- // 回滚 清空缓存
- if(count != 0){
- for (GenTemplateDetailModel model : wrapperModels) {
- GenTemplateUtil.del(model);
- }
- }
-
- return sortWrappers(wrapperModels);
+ List listByParent = genTemplateDetailService.findListByParent(parentId);
+ Map templateMap = Maps.newHashMapWithExpectedSize(listByParent.size());
+ for (GenTemplateDetailModel genTemplateDetailModel : listByParent) {
+ templateMap.put(genTemplateDetailModel.getId(), genTemplateDetailModel);
}
+ return templateMap;
+ });
- }catch (Exception e){
- log.error(e.getMessage(),e);
- }finally {
- // 释放锁
- DistributedLockUtil.unlock(cacheKey);
- }
-
- // 如果值还是 为空 则赋默认值
- if(CollUtil.isEmpty(wrapperModels)){
- // 加入缓存防穿透
- // 设置空变量 用于防止穿透判断
- CacheUtil.putNilFlag(cacheKey);
- }
- // 排序
+ // 处理集合数据
+ List wrapperModels = handleDictList(templateCache);
return sortWrappers(wrapperModels);
}
@@ -150,8 +98,8 @@ public class GenTemplateUtil {
*/
private static List sortWrappers(List wrapperModels) {
// 非法判读
- if(wrapperModels == null){
- return null;
+ if(CollUtil.isEmpty(wrapperModels)){
+ return ListUtil.empty();
}
return ListUtil.sort(wrapperModels,
@@ -162,22 +110,6 @@ public class GenTemplateUtil {
// ===============
- /**
- * 删除 字典
- * @param model 字典模型
- */
- private static boolean put(GenTemplateDetailModel model){
- // 判断 工具类是否初始化完成
- ThrowExceptionUtil.isThrowException(!IS_INIT,
- CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
-
- // 清除缓存
- GenTemplateUtil.del(model);
-
- return CacheUtil.putHash(CACHE_PREFIX_NAME + model.getParentId(),
- model.getId(), model);
- }
-
/**
* 删除 字典
* @param model 字典模型
@@ -192,36 +124,10 @@ public class GenTemplateUtil {
return true;
}
- boolean hasNilFlag = CacheUtil.hasNilFlag(CACHE_PREFIX_NAME +
- model.getParentId() + ":" + model.getId());
-
- GenTemplateDetailModel templateDetailModel = CacheUtil.getHash(GenTemplateDetailModel.class,
- CACHE_PREFIX_NAME + model.getParentId(),
- model.getId());
-
- // 计数器
- int count = 0;
- if (hasNilFlag){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delNilFlag(CACHE_PREFIX_NAME +
- model.getParentId() + ":" + model.getId());
- if(tmp){
- count--;
- }
- }
-
- if (templateDetailModel != null){
- count++;
- // 清除空拦截
- boolean tmp = CacheUtil.delHash(CACHE_PREFIX_NAME +
- model.getParentId(), model.getId());
- if(tmp){
- count--;
- }
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + model.getParentId());
- return count == 0;
+ return SecurityCache.hDel(redisTemplate, cacheKey, model.getId());
}
/**
@@ -234,29 +140,18 @@ public class GenTemplateUtil {
ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
- List wrapperList = GenTemplateUtil.getTemplateDetailList(parentId);
- if(CollUtil.isEmpty(wrapperList)){
- return true;
- }
+ // 缓存Key
+ String cacheKey = CacheUtil.formatKey(CACHE_PREFIX_NAME + parentId);
- // 计数器
- int count = wrapperList.size();
- for (GenTemplateDetailModel wrapperModel : wrapperList) {
- boolean tmp = GenTemplateUtil.del(wrapperModel);
- if(tmp){
- count--;
- }
- }
- return count == 0;
+ return SecurityCache.remove(redisTemplate, cacheKey);
}
/***
* 处理返回模板明细集合
* @param tempMap Map
- * @param id 模板ID
* @return List
*/
- public static List handleDictList(Map tempMap, String id){
+ public static List handleDictList(Map tempMap){
List wrapperModels = Lists.newArrayList();
if(CollUtil.isNotEmpty(tempMap)){
for (Map.Entry entry : tempMap.entrySet()) {
@@ -278,8 +173,10 @@ public class GenTemplateUtil {
* 初始化
*/
@Autowired
- public void init(IGenTemplateDetailService genTemplateDetailService) {
+ public void init(IGenTemplateDetailService genTemplateDetailService,
+ RedisTemplate redisTemplate) {
GenTemplateUtil.genTemplateDetailService = genTemplateDetailService;
+ GenTemplateUtil.redisTemplate = redisTemplate;
IS_INIT = true;
}
diff --git a/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index e02ef412..6e73d4f4 100644
--- a/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/opsli-plugins/opsli-plugins-redis/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -1,10 +1,4 @@
{
"properties": [
- {
- "name": "spring.redis.pushsub.enable",
- "type": "java.lang.Boolean",
- "defaultValue": false,
- "description": "开启消息订阅."
- }
]
}
diff --git a/opsli-starter/src/main/resources/application.yaml b/opsli-starter/src/main/resources/application.yaml
index 21990b94..97cfbc9d 100644
--- a/opsli-starter/src/main/resources/application.yaml
+++ b/opsli-starter/src/main/resources/application.yaml
@@ -54,21 +54,11 @@ spring:
# allow-bean-definition-overriding: true
# 缓存配置项
- cache-conf:
+ cache:
# 前缀
prefix: opsli
- # 一级缓存 ---- EhCache 配置
- cache:
- # 是否启用本地缓存 (默认不启用, 如果业务对于缓存依赖较高可启用本地缓存作为一级缓存)
- enable: false
- # 加载配置文件
- jcache:
- config: classpath:config/ehcache-opsli.xml
# 二级缓存 ---- Redis 配置
redis:
- # 开启消息订阅
- pushsub:
- enable: true
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
diff --git a/opsli-starter/src/main/resources/config/ehcache-opsli.xml b/opsli-starter/src/main/resources/config/ehcache-opsli.xml
deleted file mode 100644
index f2888992..00000000
--- a/opsli-starter/src/main/resources/config/ehcache-opsli.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- java.lang.String
- java.lang.Object
-
- 2000
-
-
-
-
-
-
-
-
-
- 21600
-
-
-
-
\ No newline at end of file