valueFunc) {
if (CollUtil.isEmpty(from)) {
return null;
}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java
index 2481b2acb..d0fe496ed 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRuleTest.java
@@ -4,11 +4,11 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
-import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
-import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
+import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
+import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import org.junit.jupiter.api.BeforeEach;
@@ -23,6 +23,7 @@ import static cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataP
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
@@ -73,6 +74,8 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L)
.setUserType(UserTypeEnum.ADMIN.getValue()));
securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
+ // mock 方法(permissionApi 返回 null)
+ when(permissionApi.getDeptDataPermission(eq(loginUser.getId()))).thenReturn(null);
// 调用
NullPointerException exception = assertThrows(NullPointerException.class,
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
index 3effb1952..a13b7dd3a 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
@@ -63,9 +63,7 @@
com.github.binarywang
weixin-java-pay
- 4.5.0
-
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
index adad219ed..121aeb087 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
@@ -70,6 +70,7 @@ public class PayClientFactoryImpl implements PayClientFactory {
case ALIPAY_APP: return (AbstractPayClient) new AlipayAppPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_PC: return (AbstractPayClient) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_BAR: return (AbstractPayClient) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config);
+ // 其它支付
case MOCK: return (AbstractPayClient) new MockPayClient(channelId, (MockPayClientConfig) config);
}
// 创建失败,错误日志 + 抛出异常
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
index 071737b76..1d3f4d48b 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
@@ -11,7 +11,9 @@ import java.time.LocalDateTime;
import java.util.Map;
/**
- * 模拟支付的 PayClient 实现类, 模拟支付返回结果都是成功
+ * 模拟支付的 PayClient 实现类
+ *
+ * 模拟支付返回结果都是成功,方便大家日常流畅
*
* @author jason
*/
@@ -25,31 +27,30 @@ public class MockPayClient extends AbstractPayClient {
@Override
protected void doInit() {
-
}
@Override
protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
- // 模拟支付渠道订单号为空
- return PayOrderRespDTO.successOf("", "", LocalDateTime.now(), reqDTO.getOutTradeNo(), MOCK_RESP_SUCCESS_DATA);
+ return PayOrderRespDTO.successOf("MOCK-P-" + reqDTO.getOutTradeNo(), "", LocalDateTime.now(),
+ reqDTO.getOutTradeNo(), MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayOrderRespDTO doGetOrder(String outTradeNo) {
- // 模拟支付渠道订单号为空
- return PayOrderRespDTO.successOf("", "", LocalDateTime.now(), outTradeNo, MOCK_RESP_SUCCESS_DATA);
+ return PayOrderRespDTO.successOf("MOCK-P-" + outTradeNo, "", LocalDateTime.now(),
+ outTradeNo, MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
- // 模拟支付渠道退款单号为空
- return PayRefundRespDTO.successOf("", LocalDateTime.now(), reqDTO.getOutRefundNo(), MOCK_RESP_SUCCESS_DATA);
+ return PayRefundRespDTO.successOf("MOCK-R-" + reqDTO.getOutRefundNo(), LocalDateTime.now(),
+ reqDTO.getOutRefundNo(), MOCK_RESP_SUCCESS_DATA);
}
@Override
protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) {
- // 模拟支付渠道退款单号为空
- return PayRefundRespDTO.successOf("", LocalDateTime.now(), outRefundNo, MOCK_RESP_SUCCESS_DATA);
+ return PayRefundRespDTO.successOf("MOCK-R-" + outRefundNo, LocalDateTime.now(),
+ outRefundNo, MOCK_RESP_SUCCESS_DATA);
}
@Override
@@ -61,4 +62,5 @@ public class MockPayClient extends AbstractPayClient {
protected PayOrderRespDTO doParseOrderNotify(Map params, String body) {
throw new UnsupportedOperationException("模拟支付无支付回调");
}
-}
\ No newline at end of file
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClientConfig.java
index 61f68a2c1..3e35c52dc 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClientConfig.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClientConfig.java
@@ -14,7 +14,9 @@ import javax.validation.Validator;
public class MockPayClientConfig implements PayClientConfig {
/**
- * 配置名称,如果不加任何属性, JsonUtils.parseObject2 解析会报错. 暂时加个名称
+ * 配置名称
+ *
+ * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称
*/
private String name;
@@ -22,4 +24,5 @@ public class MockPayClientConfig implements PayClientConfig {
public void validate(Validator validator) {
// 模拟支付配置无需校验
}
-}
\ No newline at end of file
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefine.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefine.java
deleted file mode 100644
index c78ae44ec..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefine.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package cn.iocoder.yudao.framework.tenant.core.redis;
-
-import cn.hutool.core.util.ArrayUtil;
-import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
-import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
-
-import java.time.Duration;
-
-/**
- * 多租户拓展的 RedisKeyDefine 实现类
- *
- * 由于 Redis 不同于 MySQL 有 column 字段,无法通过类似 WHERE tenant_id = ? 的方式过滤
- * 所以需要通过在 Redis Key 上增加后缀的方式,进行租户之间的隔离。具体的步骤是:
- * 1. 假设 Redis Key 是 user:%d,示例是 user:1;对应到多租户的 Redis Key 是 user:%d:%d,
- * 2. 在 Redis DAO 中,需要使用 {@link #formatKey(Object...)} 方法,进行 Redis Key 的格式化
- *
- * 注意,大多数情况下,并不用使用 TenantRedisKeyDefine 实现。主要的使用场景,还是 Redis Key 可能存在冲突的情况。
- * 例如说,租户 1 和 2 都有一个手机号作为 Key,则他们会存在冲突的问题
- *
- * @author 芋道源码
- */
-public class TenantRedisKeyDefine extends RedisKeyDefine {
-
- /**
- * 多租户的 KEY 模板
- */
- private static final String KEY_TEMPLATE_SUFFIX = ":%d";
-
- public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class> valueType, Duration timeout) {
- super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeout);
- }
-
- public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class> valueType, TimeoutTypeEnum timeoutType) {
- super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeoutType);
- }
-
- private static String buildKeyTemplate(String keyTemplate) {
- return keyTemplate + KEY_TEMPLATE_SUFFIX;
- }
-
- @Override
- public String formatKey(Object... args) {
- args = ArrayUtil.append(args, TenantContextHolder.getRequiredTenantId());
- return super.formatKey(args);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefineTest.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefineTest.java
deleted file mode 100644
index d456e011c..000000000
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefineTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.framework.tenant.core.redis;
-
-import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
-import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-class TenantRedisKeyDefineTest {
-
- @Test
- public void testFormatKey() {
- Long tenantId = 30L;
- TenantContextHolder.setTenantId(tenantId);
- // 准备参数
- TenantRedisKeyDefine define = new TenantRedisKeyDefine("", "user:%d:%d", RedisKeyDefine.KeyTypeEnum.HASH,
- Object.class, RedisKeyDefine.TimeoutTypeEnum.FIXED);
- Long userId = 10L;
- Integer userType = 1;
-
- // 调用
- String key = define.formatKey(userId, userType);
- // 断言
- assertEquals("user:10:1:30", key);
- }
-
-}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
index e2f19275e..b67e542cf 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
@@ -34,16 +34,12 @@
com.github.binarywang
-
wx-java-mp-spring-boot-starter
- 4.5.0
com.github.binarywang
wx-java-miniapp-spring-boot-starter
- 4.5.0
-
diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java
index 057445519..21f19efe6 100644
--- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java
@@ -1,7 +1,5 @@
package cn.iocoder.yudao.framework.captcha.config;
-import cn.hutool.core.util.ClassUtil;
-import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
import com.xingyuv.captcha.properties.AjCaptchaProperties;
import com.xingyuv.captcha.service.CaptchaCacheService;
@@ -15,12 +13,6 @@ import javax.annotation.Resource;
@AutoConfiguration
public class YudaoCaptchaConfiguration {
- static {
- // 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
- // 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
- ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName());
- }
-
@Resource
private StringRedisTemplate stringRedisTemplate;
diff --git a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java
index 3e1147c37..5fa5b5858 100644
--- a/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java
+++ b/yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java
@@ -1,12 +1,5 @@
package cn.iocoder.yudao.framework.captcha.core.enums;
-import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
-import com.xingyuv.captcha.model.vo.PointVO;
-
-import java.time.Duration;
-
-import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
-
/**
* 验证码 Redis Key 枚举类
*
@@ -14,12 +7,22 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
*/
public interface CaptchaRedisKeyConstants {
- RedisKeyDefine AJ_CAPTCHA_REQ_LIMIT = new RedisKeyDefine("验证码的请求限流",
- "AJ.CAPTCHA.REQ.LIMIT-%s-%s",
- STRING, Integer.class, Duration.ofSeconds(60)); // 例如说:验证失败 5 次,get 接口锁定
+ /**
+ * 验证码的请求限流
+ *
+ * KEY 格式:AJ.CAPTCHA.REQ.LIMIT-%s-%s
+ * VALUE 数据类型:String // 例如说:验证失败 5 次,get 接口锁定
+ * 过期时间:60 秒
+ */
+ String AJ_CAPTCHA_REQ_LIMIT = "AJ.CAPTCHA.REQ.LIMIT-%s-%s";
- RedisKeyDefine AJ_CAPTCHA_RUNNING = new RedisKeyDefine("验证码的坐标",
- "RUNNING:CAPTCHA:%s", // AbstractCaptchaService.REDIS_CAPTCHA_KEY
- STRING, PointVO.class, Duration.ofSeconds(120)); // {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
+ /**
+ * 验证码的坐标
+ *
+ * KEY 格式:RUNNING:CAPTCHA:%s // AbstractCaptchaService.REDIS_CAPTCHA_KEY
+ * VALUE 数据类型:String // PointVO.class {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
+ * 过期时间:120 秒
+ */
+ String AJ_CAPTCHA_RUNNING = "RUNNING:CAPTCHA:%s";
}
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml b/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
index 14a7eaf30..fb89d2673 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/pom.xml
@@ -64,9 +64,8 @@
com.github.yulichang
- mybatis-plus-join-boot-starter
+ mybatis-plus-join-boot-starter
-
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
index 614469e92..9eed6d0e0 100644
--- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
@@ -6,10 +6,10 @@ import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.toolkit.Db;
-import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
@@ -17,10 +17,8 @@ import java.util.List;
/**
* 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
- *
- * 为什么继承 MPJBaseMapper 接口?支持 MyBatis Plus 多表 Join 的能力。
*/
-public interface BaseMapperX extends MPJBaseMapper {
+public interface BaseMapperX extends BaseMapper {
default PageResult selectPage(PageParam pageParam, @Param("ew") Wrapper queryWrapper) {
// MyBatis Plus 查询
@@ -46,18 +44,6 @@ public interface BaseMapperX extends MPJBaseMapper {
return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2));
}
- default T selectOne(SFunction field1, Object value1, SFunction field2, Object value2,
- SFunction field3, Object value3) {
- return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2)
- .eq(field3, value3));
- }
-
- default T selectOne(SFunction field1, Object value1, SFunction field2, Object value2,
- SFunction field3, Object value3, SFunction field4, Object value4) {
- return selectOne(new LambdaQueryWrapper().eq(field1, value1).eq(field2, value2)
- .eq(field3, value3).eq(field4, value4));
- }
-
default Long selectCount() {
return selectCount(new QueryWrapper());
}
@@ -117,11 +103,6 @@ public interface BaseMapperX extends MPJBaseMapper {
update(update, new QueryWrapper<>());
}
- /**
- * 根据ID 批量更新,适合大量数据更新
- *
- * @param entities 实体们
- */
default void updateBatch(Collection entities) {
Db.updateBatchById(entities);
}
@@ -130,13 +111,8 @@ public interface BaseMapperX extends MPJBaseMapper {
Db.updateBatchById(entities, size);
}
- /**
- * 批量修改插入, 会根据实体的主键是否为空,更新还是修改。默认为 1000
- *
- * @param entities 实体们
- */
- default void saveOrUpdateBatch(Collection entities){
- Db.saveOrUpdateBatch(entities);
+ default void saveOrUpdateBatch(Collection collection) {
+ Db.saveOrUpdateBatch(collection);
}
}
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/idempotent/core/redis/IdempotentRedisDAO.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/idempotent/core/redis/IdempotentRedisDAO.java
index 05e1c6bd2..e3a79414d 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/idempotent/core/redis/IdempotentRedisDAO.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/idempotent/core/redis/IdempotentRedisDAO.java
@@ -1,13 +1,10 @@
package cn.iocoder.yudao.framework.idempotent.core.redis;
-import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
-import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
-
/**
* 幂等 Redis DAO
*
@@ -16,9 +13,14 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
@AllArgsConstructor
public class IdempotentRedisDAO {
- private static final RedisKeyDefine IDEMPOTENT = new RedisKeyDefine("幂等操作",
- "idempotent:%s", // 参数为 uuid
- STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
+ /**
+ * 幂等操作
+ *
+ * KEY 格式:idempotent:%s // 参数为 uuid
+ * VALUE 格式:String
+ * 过期时间:不固定
+ */
+ private static final String IDEMPOTENT = "idempotent:%s";
private final StringRedisTemplate redisTemplate;
@@ -28,7 +30,7 @@ public class IdempotentRedisDAO {
}
private static String formatKey(String key) {
- return String.format(IDEMPOTENT.getKeyTemplate(), key);
+ return String.format(IDEMPOTENT, key);
}
}
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/config/YudaoLock4jConfiguration.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/config/YudaoLock4jConfiguration.java
index 2986da6c8..2fc7f21ea 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/config/YudaoLock4jConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/config/YudaoLock4jConfiguration.java
@@ -1,21 +1,13 @@
package cn.iocoder.yudao.framework.lock4j.config;
-import cn.hutool.core.util.ClassUtil;
-import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy;
-import cn.iocoder.yudao.framework.lock4j.core.Lock4jRedisKeyConstants;
+import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
@AutoConfiguration(before = LockAutoConfiguration.class)
public class YudaoLock4jConfiguration {
- static {
- // 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
- // 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
- ClassUtil.loadClass(Lock4jRedisKeyConstants.class.getName());
- }
-
@Bean
public DefaultLockFailureStrategy lockFailureStrategy() {
return new DefaultLockFailureStrategy();
diff --git a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/core/Lock4jRedisKeyConstants.java b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/core/Lock4jRedisKeyConstants.java
index cc01a253b..693d05252 100644
--- a/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/core/Lock4jRedisKeyConstants.java
+++ b/yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/core/Lock4jRedisKeyConstants.java
@@ -1,10 +1,5 @@
package cn.iocoder.yudao.framework.lock4j.core;
-import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
-import org.redisson.api.RLock;
-
-import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH;
-
/**
* Lock4j Redis Key 枚举类
*
@@ -12,8 +7,13 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.H
*/
public interface Lock4jRedisKeyConstants {
- RedisKeyDefine LOCK4J = new RedisKeyDefine("分布式锁",
- "lock4j:%s", // 参数来自 DefaultLockKeyBuilder 类
- HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构
+ /**
+ * 分布式锁
+ *
+ * KEY 格式:lock4j:%s // 参数来自 DefaultLockKeyBuilder 类
+ * VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构
+ * 过期时间:不固定
+ */
+ String LOCK4J = "lock4j:%s";
}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/pom.xml b/yudao-framework/yudao-spring-boot-starter-redis/pom.xml
index 430ede255..c1a728b35 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-redis/pom.xml
@@ -37,6 +37,11 @@
netty-all
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index 0b837569e..1442e8a83 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.redis.config;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.redis.core.TimeoutRedisCacheManager;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -7,8 +9,15 @@ import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
-import org.springframework.data.redis.serializer.RedisSerializer;
+
+import java.util.Objects;
+
+import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration.buildRedisSerializer;
/**
* Cache 配置类,基于 Redis 实现
@@ -20,15 +29,19 @@ public class YudaoCacheAutoConfiguration {
/**
* RedisCacheConfiguration Bean
- *
+ *
* 参考 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration 的 createConfiguration 方法
*/
@Bean
@Primary
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
- // 设置使用 JSON 序列化方式
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
- config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
+ // 设置使用 : 单冒号,而不是双 :: 冒号,避免 Redis Desktop Manager 多余空格
+ // 详细可见 https://blog.csdn.net/chuixue24/article/details/103928965 博客
+ config = config.computePrefixWith(cacheName -> cacheName + StrUtil.COLON);
+ // 设置使用 JSON 序列化方式
+ config = config.serializeValuesWith(
+ RedisSerializationContext.SerializationPair.fromSerializer(buildRedisSerializer()));
// 设置 CacheProperties.Redis 的属性
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
@@ -47,4 +60,14 @@ public class YudaoCacheAutoConfiguration {
return config;
}
+ @Bean
+ public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate,
+ RedisCacheConfiguration redisCacheConfiguration) {
+ // 创建 RedisCacheWriter 对象
+ RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
+ RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+ // 创建 TenantRedisCacheManager 对象
+ return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
+ }
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoRedisAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoRedisAutoConfiguration.java
index 901830c69..5904a3a2b 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoRedisAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoRedisAutoConfiguration.java
@@ -1,5 +1,8 @@
package cn.iocoder.yudao.framework.redis.config;
+import cn.hutool.core.util.ReflectUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -25,9 +28,17 @@ public class YudaoRedisAutoConfiguration {
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
- template.setValueSerializer(RedisSerializer.json());
- template.setHashValueSerializer(RedisSerializer.json());
+ template.setValueSerializer(buildRedisSerializer());
+ template.setHashValueSerializer(buildRedisSerializer());
return template;
}
+ public static RedisSerializer> buildRedisSerializer() {
+ RedisSerializer