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; }