diff --git a/README.md b/README.md
index 60310204cc..bebf005432 100644
--- a/README.md
+++ b/README.md
@@ -248,7 +248,7 @@
| 框架 | 说明 | 版本 | 学习指南 |
|---------------------------------------------------------------------------------------------|------------------|-------------|----------------------------------------------------------------|
-| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.13 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
+| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.14 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.18 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
diff --git a/pom.xml b/pom.xml
index b2180e8b75..b263326684 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,7 +39,7 @@
3.8.1
1.18.28
- 2.7.13
+ 2.7.14
1.5.5.Final
UTF-8
diff --git a/sql/postgresql/ruoyi-vue-pro.sql b/sql/postgresql/ruoyi-vue-pro.sql
index d279476bbf..3b6fecc358 100644
--- a/sql/postgresql/ruoyi-vue-pro.sql
+++ b/sql/postgresql/ruoyi-vue-pro.sql
@@ -5552,7 +5552,7 @@ CREATE TABLE "system_role"
"code" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,
"sort" int4 NOT NULL,
"data_scope" int2 NOT NULL,
- "data_scope_dept_ids" varchar(500) COLLATE "pg_catalog"."default" NOT NULL,
+ "data_scope_dept_ids" varchar(500) COLLATE "pg_catalog"."default" NOT NULL DEFAULT '',
"status" int2 NOT NULL,
"type" int2 NOT NULL,
"remark" varchar(500) COLLATE "pg_catalog"."default",
diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index 19fd0e1a12..0d43f9a11f 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -16,7 +16,7 @@
1.8.0-snapshot
- 2.7.13
+ 2.7.14
1.6.15
4.1.0
@@ -43,7 +43,7 @@
6.8.0
- 1.0.5
+ 1.0.6
1.15.4
1.18.28
1.5.5.Final
@@ -68,7 +68,7 @@
4.6.3
2.2.1
3.1.758
- 1.0.1
+ 1.0.3
1.5.8
2.12.2
4.5.0
diff --git a/yudao-example/yudao-sso-demo-by-code/pom.xml b/yudao-example/yudao-sso-demo-by-code/pom.xml
index dc0c0241ea..e67bd8e93a 100644
--- a/yudao-example/yudao-sso-demo-by-code/pom.xml
+++ b/yudao-example/yudao-sso-demo-by-code/pom.xml
@@ -21,7 +21,7 @@
8
UTF-8
- 2.7.13
+ 2.7.14
diff --git a/yudao-example/yudao-sso-demo-by-password/pom.xml b/yudao-example/yudao-sso-demo-by-password/pom.xml
index ee5d05390b..bccd1580fa 100644
--- a/yudao-example/yudao-sso-demo-by-password/pom.xml
+++ b/yudao-example/yudao-sso-demo-by-password/pom.xml
@@ -21,7 +21,7 @@
8
UTF-8
- 2.7.13
+ 2.7.14
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
index 85c0a63745..396694a75b 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
@@ -53,7 +53,7 @@ public class WxAppPayClient extends AbstractWxPayClient {
// 构建 WxPayUnifiedOrderV3Request 对象
WxPayUnifiedOrderV3Request request = buildPayUnifiedOrderRequestV3(reqDTO);
// 执行请求
- WxPayUnifiedOrderV3Result.JsapiResult response = client.createOrderV3(TradeTypeEnum.APP, request);
+ WxPayUnifiedOrderV3Result.AppResult response = client.createOrderV3(TradeTypeEnum.APP, request);
// 转换结果
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), toJsonString(response),
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
index bc53c244e5..cd4193abf2 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
@@ -4,6 +4,7 @@ import cn.hutool.core.annotation.AnnotationUtil;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
@@ -27,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -124,10 +126,12 @@ public class YudaoTenantAutoConfiguration {
@Bean
@Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
public RedisCacheManager tenantRedisCacheManager(RedisTemplate redisTemplate,
- RedisCacheConfiguration redisCacheConfiguration) {
+ RedisCacheConfiguration redisCacheConfiguration,
+ YudaoCacheProperties yudaoCacheProperties) {
// 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
- RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+ RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+ BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
// 创建 TenantRedisCacheManager 对象
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
}
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 1442e8a83d..2797e21171 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
@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -23,7 +24,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
* Cache 配置类,基于 Redis 实现
*/
@AutoConfiguration
-@EnableConfigurationProperties({CacheProperties.class})
+@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
@EnableCaching
public class YudaoCacheAutoConfiguration {
@@ -62,10 +63,12 @@ public class YudaoCacheAutoConfiguration {
@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate,
- RedisCacheConfiguration redisCacheConfiguration) {
+ RedisCacheConfiguration redisCacheConfiguration,
+ YudaoCacheProperties yudaoCacheProperties) {
// 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
- RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+ RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+ BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
// 创建 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/YudaoCacheProperties.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
new file mode 100644
index 0000000000..c51219d0fc
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.redis.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * Cache 配置项
+ *
+ * @author Wanwan
+ */
+@ConfigurationProperties("yudao.cache")
+@Data
+@Validated
+public class YudaoCacheProperties {
+
+ /**
+ * {@link #redisScanBatchSize} 默认值
+ */
+ private static final Integer REDIS_SCAN_BATCH_SIZE_DEFAULT = 30;
+
+ /**
+ * redis scan 一次返回数量
+ */
+ private Integer redisScanBatchSize = REDIS_SCAN_BATCH_SIZE_DEFAULT;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
index cfdee653df..bf34fc0818 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.framework.redis.core;
+import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
-import org.springframework.boot.convert.DurationStyle;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@@ -9,12 +9,12 @@ import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import java.time.Duration;
-import java.time.temporal.ChronoUnit;
/**
* 支持自定义过期时间的 {@link RedisCacheManager} 实现类
*
- * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间。
+ * 单位为最后一个字母(支持的单位有:d 天,h 小时,m 分钟,s 秒),默认单位为 s 秒
*
* @author 芋道源码
*/
@@ -42,10 +42,42 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
// 移除 # 后面的 : 以及后面的内容,避免影响解析
names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
// 解析时间
- Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
+ Duration duration = parseDuration(names[1]);
cacheConfig = cacheConfig.entryTtl(duration);
}
return super.createRedisCache(names[0], cacheConfig);
}
+ /**
+ * 解析过期时间 Duration
+ *
+ * @param ttlStr 过期时间字符串
+ * @return 过期时间 Duration
+ */
+ private Duration parseDuration(String ttlStr) {
+ String timeUnit = StrUtil.subSuf(ttlStr, -1);
+ switch (timeUnit) {
+ case "d":
+ return Duration.ofDays(removeDurationSuffix(ttlStr));
+ case "h":
+ return Duration.ofHours(removeDurationSuffix(ttlStr));
+ case "m":
+ return Duration.ofMinutes(removeDurationSuffix(ttlStr));
+ case "s":
+ return Duration.ofSeconds(removeDurationSuffix(ttlStr));
+ default:
+ return Duration.ofSeconds(Long.parseLong(ttlStr));
+ }
+ }
+
+ /**
+ * 移除多余的后缀,返回具体的时间
+ *
+ * @param ttlStr 过期时间字符串
+ * @return 时间
+ */
+ private Long removeDurationSuffix(String ttlStr) {
+ return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
+ }
+
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
index a108e8f770..f06fd34741 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
@@ -45,7 +45,8 @@ public class MenuServiceImpl implements MenuService {
private TenantService tenantService;
@Override
- @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#reqVO.permission")
+ @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#reqVO.permission",
+ condition = "#reqVO.permission != null")
public Long createMenu(MenuCreateReqVO reqVO) {
// 校验父菜单存在
validateParentMenu(reqVO.getParentId(), null);
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
index 226c939e4d..fd49bf9701 100755
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
@@ -34,7 +34,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
@@ -175,7 +174,7 @@ public class TenantServiceImpl implements TenantService {
public void updateTenantRoleMenu(Long tenantId, Set menuIds) {
TenantUtils.execute(tenantId, () -> {
// 获得所有角色
- List roles = roleService.getRoleListByStatus(null);
+ List roles = roleService.getRoleList();
roles.forEach(role -> Assert.isTrue(tenantId.equals(role.getTenantId()), "角色({}/{}) 租户不匹配",
role.getId(), role.getTenantId(), tenantId)); // 兜底校验
// 重新分配每个角色的权限
diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml
index 04118f184b..e6296ceab5 100644
--- a/yudao-server/pom.xml
+++ b/yudao-server/pom.xml
@@ -111,7 +111,7 @@
org.springframework.boot
spring-boot-maven-plugin
- 2.7.13
+ 2.7.14
true
diff --git a/yudao-ui-admin/src/assets/styles/ruoyi.scss b/yudao-ui-admin/src/assets/styles/ruoyi.scss
index c95bb0a551..2ea1f0ad49 100644
--- a/yudao-ui-admin/src/assets/styles/ruoyi.scss
+++ b/yudao-ui-admin/src/assets/styles/ruoyi.scss
@@ -95,7 +95,7 @@
font-size: 13px;
}
}
- .el-table__body-wrapper {
+ .el-table__body-wrapper,.el-table__fixed-body-wrapper {
.el-button [class*="el-icon-"] + span {
margin-left: 1px;
}
diff --git a/yudao-ui-admin/src/views/infra/fileConfig/index.vue b/yudao-ui-admin/src/views/infra/fileConfig/index.vue
index 01e671fab8..dcc45c67ae 100755
--- a/yudao-ui-admin/src/views/infra/fileConfig/index.vue
+++ b/yudao-ui-admin/src/views/infra/fileConfig/index.vue
@@ -102,7 +102,7 @@
主动模式
- 主动模式
+ 被动模式
diff --git a/yudao-ui-admin/src/views/pay/cashier/index.vue b/yudao-ui-admin/src/views/pay/cashier/index.vue
index 465f41f3ca..85d702760a 100644
--- a/yudao-ui-admin/src/views/pay/cashier/index.vue
+++ b/yudao-ui-admin/src/views/pay/cashier/index.vue
@@ -238,7 +238,7 @@ export default {
if (data.status === PayOrderStatusEnum.SUCCESS.status) {
this.clearQueryInterval();
this.$message.success('支付成功!');
- this.goReturnUrl();
+ this.goReturnUrl('success');
return
}
@@ -321,13 +321,13 @@ export default {
if (response.data.status === PayOrderStatusEnum.SUCCESS.status) {
this.clearQueryInterval();
this.$message.success('支付成功!');
- this.goReturnUrl();
+ this.goReturnUrl('success');
}
// 已取消
if (response.data.status === PayOrderStatusEnum.CLOSED.status) {
this.clearQueryInterval();
this.$message.error('支付已关闭!');
- this.goReturnUrl();
+ this.goReturnUrl('close');
}
})
}, 1000 * 2)
diff --git a/yudao-ui-admin/src/views/pay/order/index.vue b/yudao-ui-admin/src/views/pay/order/index.vue
index 967ec97c47..146fb0feb2 100755
--- a/yudao-ui-admin/src/views/pay/order/index.vue
+++ b/yudao-ui-admin/src/views/pay/order/index.vue
@@ -302,25 +302,7 @@ export default {
font-weight: bold;
}
-.tag-purple {
- color: #722ed1;
- background: #f9f0ff;
- border-color: #d3adf7;
-}
-
-.tag-cyan {
- color: #13c2c2;
- background: #e6fffb;
- border-color: #87e8de;
-}
-
-.tag-pink {
- color: #eb2f96;
- background: #fff0f6;
- border-color: #ffadd2;
-}
-
-.order-font{
+.order-font {
font-size: 12px;
padding: 2px 0;
}