From 5f8ce75df47cba3b6717ef1b265f80a152ee996d Mon Sep 17 00:00:00 2001 From: Ikko Ashimine Date: Mon, 12 Dec 2022 05:29:43 +0000 Subject: [PATCH 01/67] fix typo in uni-swiper-dot.vue defualt -> default Signed-off-by: Ikko Ashimine --- .../uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-ui-admin-uniapp/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue b/yudao-ui-admin-uniapp/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue index 46eb8c1fa..e5befae18 100644 --- a/yudao-ui-admin-uniapp/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue +++ b/yudao-ui-admin-uniapp/uni_modules/uni-swiper-dot/components/uni-swiper-dot/uni-swiper-dot.vue @@ -35,7 +35,7 @@ * @tutorial https://ext.dcloud.net.cn/plugin?id=284 * @property {Number} current 当前指示点索引,必须是通过 `swiper` 的 `change` 事件获取到的 `e.detail.current` * @property {String} mode = [default|round|nav|indexes] 指示点的类型 - * @value defualt 默认指示点 + * @value default 默认指示点 * @value round 圆形指示点 * @value nav 条形指示点 * @value indexes 索引指示点 From 0f31ce7ecf0b872f8cf8cc83df66886fa8488140 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Thu, 15 Dec 2022 14:36:17 +0800 Subject: [PATCH 02/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mq/config/YudaoMQAutoConfiguration.java | 11 +++- .../mq/scheduler/PendingMessageScheduler.java | 66 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java index c369d49d6..9c70a1246 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; +import cn.iocoder.yudao.framework.mq.scheduler.PendingMessageScheduler; import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -24,7 +25,6 @@ import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.stream.DefaultStreamMessageListenerContainerX; import org.springframework.data.redis.stream.StreamMessageListenerContainer; -import org.springframework.scheduling.annotation.Async; import java.util.List; import java.util.Properties; @@ -69,6 +69,15 @@ public class YudaoMQAutoConfiguration { return container; } + /** + * + * @return + */ + @Bean + public PendingMessageScheduler pendingMessageScheduler(){ + return new PendingMessageScheduler(); + } + /** * 创建 Redis Stream 集群消费的容器 * diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java new file mode 100644 index 000000000..38d8df3bb --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.framework.mq.scheduler; + +import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; +import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.connection.stream.Consumer; +import org.springframework.data.redis.connection.stream.MapRecord; +import org.springframework.data.redis.connection.stream.PendingMessagesSummary; +import org.springframework.data.redis.connection.stream.ReadOffset; +import org.springframework.data.redis.connection.stream.StreamOffset; +import org.springframework.data.redis.connection.stream.StreamRecords; +import org.springframework.data.redis.core.StreamOperations; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.List; +import java.util.Map; + +/** + * 这个定时器用于处理,crash 之后的消费者未消费完的消息 + */ +@Slf4j +@EnableScheduling +public class PendingMessageScheduler { + + @Autowired + private List> listeners; + @Autowired + private RedisMQTemplate redisTemplate; + @Value("${spring.application.name}") + private String groupName; + + /** + * 一分钟执行一次 + */ + @Scheduled(fixedRate = 60 * 1000) + public void processPendingMessage() { + StreamOperations ops = redisTemplate.getRedisTemplate().opsForStream(); + + for (AbstractStreamMessageListener listener : listeners) { + PendingMessagesSummary pendingMessagesSummary = ops.pending(listener.getStreamKey(), groupName); + // 每个消费者的pending消息数量 + Map pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer(); + pendingMessagesPerConsumer.entrySet().forEach(entry -> { + String consumerName = entry.getKey(); + Long pendingMessageCount = entry.getValue(); + log.info("[processPendingMessage][消费者({}) 消息数量({})]", consumerName, pendingMessageCount); + + // 从消费者的pending队列中读取消息 + List> retVal = ops.read(Consumer.from(groupName, consumerName), StreamOffset.create(listener.getStreamKey(), ReadOffset.from("0"))); + + for (MapRecord record : retVal) { + // 重新投递消息 + redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() + .ofObject(record.getValue()) // 设置内容 + .withStreamKey(listener.getStreamKey())); + + // ack 消息消费完成 + redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, record); + } + }); + } + } +} From a6c92816f0fb5801c27f6dc74cc0ac9542622b86 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Thu, 15 Dec 2022 15:33:15 +0800 Subject: [PATCH 03/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mq/scheduler/PendingMessageScheduler.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java index 38d8df3bb..1d5825a10 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.framework.mq.scheduler; import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.stream.Consumer; @@ -17,6 +19,7 @@ import org.springframework.scheduling.annotation.Scheduled; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * 这个定时器用于处理,crash 之后的消费者未消费完的消息 @@ -24,19 +27,35 @@ import java.util.Map; @Slf4j @EnableScheduling public class PendingMessageScheduler { - + private static final String LOCK_KEY = "redis:pending:msg:lock"; @Autowired private List> listeners; @Autowired private RedisMQTemplate redisTemplate; @Value("${spring.application.name}") private String groupName; + @Autowired + private RedissonClient redissonClient; /** * 一分钟执行一次 */ @Scheduled(fixedRate = 60 * 1000) public void processPendingMessage() { + final RLock lock = redissonClient.getLock(LOCK_KEY); + try { + // 尝试加锁,最多等待 30 秒,上锁以后 60 秒自动解锁 + boolean lockFlag = lock.tryLock(30, 60, TimeUnit.SECONDS); + if (lockFlag) { + execute(); + } + } catch (InterruptedException e) { + log.error("获取锁失败", e); + } + + } + + private void execute() { StreamOperations ops = redisTemplate.getRedisTemplate().opsForStream(); for (AbstractStreamMessageListener listener : listeners) { From 46f3790492492bfaee83cf33039a445de9787b6d Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 23 Dec 2022 10:28:59 +0800 Subject: [PATCH 04/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mq/config/YudaoMQAutoConfiguration.java | 21 ++++-- ...java => RedisPendingMessageResendJob.java} | 74 ++++++++++--------- 2 files changed, 52 insertions(+), 43 deletions(-) rename yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/{PendingMessageScheduler.java => RedisPendingMessageResendJob.java} (52%) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java index 9c70a1246..e306389be 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java @@ -8,9 +8,11 @@ import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; -import cn.iocoder.yudao.framework.mq.scheduler.PendingMessageScheduler; +import cn.iocoder.yudao.framework.mq.scheduler.RedisPendingMessageResendJob; import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.RedisServerCommands; @@ -25,6 +27,7 @@ import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.stream.DefaultStreamMessageListenerContainerX; import org.springframework.data.redis.stream.StreamMessageListenerContainer; +import org.springframework.scheduling.annotation.EnableScheduling; import java.util.List; import java.util.Properties; @@ -35,6 +38,7 @@ import java.util.Properties; * @author 芋道源码 */ @Slf4j +@EnableScheduling // 启用定时任务,用于 RedisPendingMessageResendJob 重发消息 @AutoConfiguration(after = YudaoRedisAutoConfiguration.class) public class YudaoMQAutoConfiguration { @@ -70,17 +74,19 @@ public class YudaoMQAutoConfiguration { } /** - * - * @return + * 创建 Redis Stream 重新消费的任务 */ @Bean - public PendingMessageScheduler pendingMessageScheduler(){ - return new PendingMessageScheduler(); + public RedisPendingMessageResendJob redisPendingMessageResendJob(List> listeners, + RedisMQTemplate redisTemplate, + @Value("${spring.application.name}") String groupName, + RedissonClient redissonClient) { + return new RedisPendingMessageResendJob(listeners, redisTemplate, groupName, redissonClient); } /** * 创建 Redis Stream 集群消费的容器 - * + *

* Redis Stream 的 xreadgroup 命令:https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html */ @Bean(initMethod = "start", destroyMethod = "stop") @@ -108,7 +114,8 @@ public class YudaoMQAutoConfiguration { // 创建 listener 对应的消费者分组 try { redisTemplate.opsForStream().createGroup(listener.getStreamKey(), listener.getGroup()); - } catch (Exception ignore) {} + } catch (Exception ignore) { + } // 设置 listener 对应的 redisTemplate listener.setRedisMQTemplate(redisMQTemplate); // 创建 Consumer 对象 diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java similarity index 52% rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java index 1d5825a10..2f64ab498 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/PendingMessageScheduler.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java @@ -1,12 +1,11 @@ package cn.iocoder.yudao.framework.mq.scheduler; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.stream.Consumer; import org.springframework.data.redis.connection.stream.MapRecord; import org.springframework.data.redis.connection.stream.PendingMessagesSummary; @@ -14,51 +13,53 @@ import org.springframework.data.redis.connection.stream.ReadOffset; import org.springframework.data.redis.connection.stream.StreamOffset; import org.springframework.data.redis.connection.stream.StreamRecords; import org.springframework.data.redis.core.StreamOperations; -import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; /** - * 这个定时器用于处理,crash 之后的消费者未消费完的消息 + * 这个任务用于处理,crash 之后的消费者未消费完的消息 */ @Slf4j -@EnableScheduling -public class PendingMessageScheduler { +public class RedisPendingMessageResendJob { private static final String LOCK_KEY = "redis:pending:msg:lock"; - @Autowired - private List> listeners; - @Autowired - private RedisMQTemplate redisTemplate; - @Value("${spring.application.name}") - private String groupName; - @Autowired - private RedissonClient redissonClient; + + private final List> listeners; + private final RedisMQTemplate redisTemplate; + private final String groupName; + private final RedissonClient redissonClient; + + public RedisPendingMessageResendJob(List> listeners, RedisMQTemplate redisTemplate, String groupName, RedissonClient redissonClient) { + this.listeners = listeners; + this.redisTemplate = redisTemplate; + this.groupName = groupName; + this.redissonClient = redissonClient; + } /** - * 一分钟执行一次 + * 一分钟执行一次,这里选择每分钟的35秒执行,是为了避免整点任务过多的问题 */ - @Scheduled(fixedRate = 60 * 1000) - public void processPendingMessage() { - final RLock lock = redissonClient.getLock(LOCK_KEY); - try { - // 尝试加锁,最多等待 30 秒,上锁以后 60 秒自动解锁 - boolean lockFlag = lock.tryLock(30, 60, TimeUnit.SECONDS); - if (lockFlag) { + @Scheduled(cron = "35 * * * * ?") + public void messageResend() { + RLock lock = redissonClient.getLock(LOCK_KEY); + log.info("[messageResend][尝试获取锁]"); + // 尝试加锁 + if (lock.tryLock()) { + try { execute(); + } catch (Exception ex) { + log.error("[messageResend][执行异常]", ex); + } finally { + lock.unlock(); } - } catch (InterruptedException e) { - log.error("获取锁失败", e); } - } private void execute() { StreamOperations ops = redisTemplate.getRedisTemplate().opsForStream(); - for (AbstractStreamMessageListener listener : listeners) { + listeners.forEach(listener -> { PendingMessagesSummary pendingMessagesSummary = ops.pending(listener.getStreamKey(), groupName); // 每个消费者的pending消息数量 Map pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer(); @@ -69,17 +70,18 @@ public class PendingMessageScheduler { // 从消费者的pending队列中读取消息 List> retVal = ops.read(Consumer.from(groupName, consumerName), StreamOffset.create(listener.getStreamKey(), ReadOffset.from("0"))); + if (CollUtil.isNotEmpty(retVal)) { + for (MapRecord record : retVal) { + // 重新投递消息 + redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() + .ofObject(record.getValue()) // 设置内容 + .withStreamKey(listener.getStreamKey())); - for (MapRecord record : retVal) { - // 重新投递消息 - redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() - .ofObject(record.getValue()) // 设置内容 - .withStreamKey(listener.getStreamKey())); - - // ack 消息消费完成 - redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, record); + // ack 消息消费完成 + redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, record); + } } }); - } + }); } } From e9645d7054db531e02910c7ea89f35b09aea2fe4 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 23 Dec 2022 10:31:41 +0800 Subject: [PATCH 05/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mq/scheduler/RedisPendingMessageResendJob.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java index 2f64ab498..59d9a0489 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java @@ -61,17 +61,17 @@ public class RedisPendingMessageResendJob { listeners.forEach(listener -> { PendingMessagesSummary pendingMessagesSummary = ops.pending(listener.getStreamKey(), groupName); - // 每个消费者的pending消息数量 + // 每个消费者的 pending 队列消息数量 Map pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer(); pendingMessagesPerConsumer.entrySet().forEach(entry -> { String consumerName = entry.getKey(); Long pendingMessageCount = entry.getValue(); log.info("[processPendingMessage][消费者({}) 消息数量({})]", consumerName, pendingMessageCount); - // 从消费者的pending队列中读取消息 - List> retVal = ops.read(Consumer.from(groupName, consumerName), StreamOffset.create(listener.getStreamKey(), ReadOffset.from("0"))); - if (CollUtil.isNotEmpty(retVal)) { - for (MapRecord record : retVal) { + // 从消费者的 pending 队列中读取消息 + List> records = ops.read(Consumer.from(groupName, consumerName), StreamOffset.create(listener.getStreamKey(), ReadOffset.from("0"))); + if (CollUtil.isNotEmpty(records)) { + for (MapRecord record : records) { // 重新投递消息 redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() .ofObject(record.getValue()) // 设置内容 From 2d7d3f151177f407b9828e295a12c7686afaf34b Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 23 Dec 2022 10:32:18 +0800 Subject: [PATCH 06/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/mq/scheduler/RedisPendingMessageResendJob.java | 1 - 1 file changed, 1 deletion(-) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java index 59d9a0489..2a96805db 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java @@ -43,7 +43,6 @@ public class RedisPendingMessageResendJob { @Scheduled(cron = "35 * * * * ?") public void messageResend() { RLock lock = redissonClient.getLock(LOCK_KEY); - log.info("[messageResend][尝试获取锁]"); // 尝试加锁 if (lock.tryLock()) { try { From 0e6b4e463f4e49edea6642c15af7ba87099f2ebc Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 23 Dec 2022 10:33:38 +0800 Subject: [PATCH 07/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/framework/mq/config/YudaoMQAutoConfiguration.java | 2 +- .../mq/{scheduler => job}/RedisPendingMessageResendJob.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/{scheduler => job}/RedisPendingMessageResendJob.java (98%) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java index e306389be..042a4f736 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; -import cn.iocoder.yudao.framework.mq.scheduler.RedisPendingMessageResendJob; +import cn.iocoder.yudao.framework.mq.job.RedisPendingMessageResendJob; import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RedissonClient; diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java similarity index 98% rename from yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java rename to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java index 2a96805db..ff01e3e3a 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/scheduler/RedisPendingMessageResendJob.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.framework.mq.scheduler; +package cn.iocoder.yudao.framework.mq.job; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; From 84b0f339445aaa6f339c4b0b4f273e48e98d3439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B7=BB=E7=BF=BC?= <2100022743@stu.pku.edu.cn> Date: Sun, 25 Dec 2022 13:16:38 +0000 Subject: [PATCH 08/67] =?UTF-8?q?update=20yudao-module-system-biz/system/c?= =?UTF-8?q?ontroller/admin/user/UserController.java.=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=B8=AD=E7=9A=84=E9=94=99=E5=88=AB=E5=AD=97?= =?UTF-8?q?=E2=80=9C=20=20//=20=E8=8E=B7=E7=94=A8=E6=88=B7=E9=97=A8?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E5=8F=AA=E8=A6=81=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=9A=84=E2=80=9D=E6=94=B9=E4=B8=BA=E2=80=9C?= =?UTF-8?q?=20=20//=20=E8=8E=B7=E5=8F=96=E7=94=A8=E6=88=B7=E5=88=97?= =?UTF-8?q?=E8=A1=A8=EF=BC=8C=E5=8F=AA=E8=A6=81=E5=BC=80=E5=90=AF=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=9A=84=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王添翼 <2100022743@stu.pku.edu.cn> --- .../module/system/controller/admin/user/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 993b66dea..a2369ae24 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -112,7 +112,7 @@ public class UserController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取用户精简信息列表", notes = "只包含被开启的用户,主要用于前端的下拉选项") public CommonResult> getSimpleUsers() { - // 获用户门列表,只要开启状态的 + // 获用户列表,只要开启状态的 List list = userService.getUsersByStatus(CommonStatusEnum.ENABLE.getStatus()); // 排序后,返回给前端 return success(UserConvert.INSTANCE.convertList04(list)); From 604266d33c6b29a829282294b02d076e8fbe1b17 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Tue, 27 Dec 2022 22:52:19 +0800 Subject: [PATCH 09/67] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20redis=20mq=20?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mq/job/RedisPendingMessageResendJob.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java index ff01e3e3a..f4ba050c0 100644 --- a/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java +++ b/yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.mq.job; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; @@ -22,7 +23,9 @@ import java.util.Map; * 这个任务用于处理,crash 之后的消费者未消费完的消息 */ @Slf4j +@AllArgsConstructor public class RedisPendingMessageResendJob { + private static final String LOCK_KEY = "redis:pending:msg:lock"; private final List> listeners; @@ -30,13 +33,6 @@ public class RedisPendingMessageResendJob { private final String groupName; private final RedissonClient redissonClient; - public RedisPendingMessageResendJob(List> listeners, RedisMQTemplate redisTemplate, String groupName, RedissonClient redissonClient) { - this.listeners = listeners; - this.redisTemplate = redisTemplate; - this.groupName = groupName; - this.redissonClient = redissonClient; - } - /** * 一分钟执行一次,这里选择每分钟的35秒执行,是为了避免整点任务过多的问题 */ @@ -57,28 +53,26 @@ public class RedisPendingMessageResendJob { private void execute() { StreamOperations ops = redisTemplate.getRedisTemplate().opsForStream(); - listeners.forEach(listener -> { PendingMessagesSummary pendingMessagesSummary = ops.pending(listener.getStreamKey(), groupName); // 每个消费者的 pending 队列消息数量 Map pendingMessagesPerConsumer = pendingMessagesSummary.getPendingMessagesPerConsumer(); - pendingMessagesPerConsumer.entrySet().forEach(entry -> { - String consumerName = entry.getKey(); - Long pendingMessageCount = entry.getValue(); + pendingMessagesPerConsumer.forEach((consumerName, pendingMessageCount) -> { log.info("[processPendingMessage][消费者({}) 消息数量({})]", consumerName, pendingMessageCount); // 从消费者的 pending 队列中读取消息 List> records = ops.read(Consumer.from(groupName, consumerName), StreamOffset.create(listener.getStreamKey(), ReadOffset.from("0"))); - if (CollUtil.isNotEmpty(records)) { - for (MapRecord record : records) { - // 重新投递消息 - redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() - .ofObject(record.getValue()) // 设置内容 - .withStreamKey(listener.getStreamKey())); + if (CollUtil.isEmpty(records)) { + return; + } + for (MapRecord record : records) { + // 重新投递消息 + redisTemplate.getRedisTemplate().opsForStream().add(StreamRecords.newRecord() + .ofObject(record.getValue()) // 设置内容 + .withStreamKey(listener.getStreamKey())); - // ack 消息消费完成 - redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, record); - } + // ack 消息消费完成 + redisTemplate.getRedisTemplate().opsForStream().acknowledge(groupName, record); } }); }); From 2c0215938411cd7c016fed68633ea74f640e3589 Mon Sep 17 00:00:00 2001 From: plimlips <156839224@qq.com> Date: Wed, 28 Dec 2022 15:49:03 +0000 Subject: [PATCH 10/67] =?UTF-8?q?update=20yudao-ui-admin/src/components/Fi?= =?UTF-8?q?leUpload/index.vue.=20=E5=90=8E=E5=8F=B0=E4=B8=80=E7=9B=B4?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=200=20=E4=BD=9C=E4=B8=BA=E6=88=90=E5=8A=9F?= =?UTF-8?q?=EF=BC=8C=E6=89=80=E4=BB=A5=E5=89=8D=E7=AB=AF=E4=B9=9F=E4=B8=8D?= =?UTF-8?q?=E5=BA=94=E8=AF=A5=E4=BD=BF=E7=94=A8200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: plimlips <156839224@qq.com> --- yudao-ui-admin/src/components/FileUpload/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-ui-admin/src/components/FileUpload/index.vue b/yudao-ui-admin/src/components/FileUpload/index.vue index 214a3be6d..d9c4f4db8 100644 --- a/yudao-ui-admin/src/components/FileUpload/index.vue +++ b/yudao-ui-admin/src/components/FileUpload/index.vue @@ -150,7 +150,7 @@ export default { }, // 上传成功回调 handleUploadSuccess(res, file) { - if (res.code === 200) { + if (res.code === 0) { // edit by 芋道源码 this.uploadList.push({ name: res.data, url: res.data }); this.uploadedSuccessfully(); From ac3c7511323140dc5cd12544c5a1b927a2c27476 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 29 Dec 2022 18:56:55 +0800 Subject: [PATCH 11/67] =?UTF-8?q?329=20=E4=BF=AE=E6=94=B9`=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E6=A8=A1=E5=9D=97>=E6=94=AF=E4=BB=98=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=EF=BC=88yyyy-MM-ddTHH:mm:ssXXX=EF=BC=89`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/core/client/impl/wx/WXPubPayClient.java | 16 ++++++++++------ .../client/impl/aliyun/AliyunSmsCodeMapping.java | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java index 88e7ac75f..a04114a85 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.wx; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; @@ -26,8 +26,8 @@ import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; import lombok.extern.slf4j.Slf4j; +import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.Date; import java.util.Objects; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; @@ -100,8 +100,8 @@ public class WXPubPayClient extends AbstractPayClient { WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() .outTradeNo(reqDTO.getMerchantOrderId()) .body(reqDTO.getBody()) - .totalFee(reqDTO.getAmount().intValue()) // 单位分 - .timeExpire(DateUtil.format(Date.from(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()).toInstant()), "yyyy-MM-dd'T'HH:mm:ssXXX")) + .totalFee(reqDTO.getAmount()) // 单位分 + .timeExpire(formatDate(reqDTO.getExpireTime())) .spbillCreateIp(reqDTO.getUserIp()) .openid(getOpenid(reqDTO)) .notifyUrl(reqDTO.getNotifyUrl()) @@ -115,8 +115,8 @@ public class WXPubPayClient extends AbstractPayClient { WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); request.setOutTradeNo(reqDTO.getMerchantOrderId()); request.setDescription(reqDTO.getBody()); - request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount().intValue())); // 单位分 - request.setTimeExpire(DateUtil.format(Date.from(reqDTO.getExpireTime().atZone(ZoneId.systemDefault()).toInstant()), "yyyy-MM-dd'T'HH:mm:ssXXX")); + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(reqDTO.getAmount())); // 单位分 + request.setTimeExpire(formatDate(reqDTO.getExpireTime())); request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(getOpenid(reqDTO))); request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); request.setNotifyUrl(reqDTO.getNotifyUrl()); @@ -196,4 +196,8 @@ public class WXPubPayClient extends AbstractPayClient { throw new UnsupportedOperationException(); } + private static String formatDate(LocalDateTime time) { + return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyy-MM-dd'T'HH:mm:ssXXX"); + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsCodeMapping.java b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsCodeMapping.java index 549bf8b0b..fd188d9b2 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsCodeMapping.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-sms/src/main/java/cn/iocoder/yudao/framework/sms/core/client/impl/aliyun/AliyunSmsCodeMapping.java @@ -35,8 +35,8 @@ public class AliyunSmsCodeMapping implements SmsCodeMapping { case "isv.OUT_OF_SERVICE": return SmsFrameworkErrorCodeConstants.SMS_ACCOUNT_MONEY_NOT_ENOUGH; case "isv.MOBILE_NUMBER_ILLEGAL": return SmsFrameworkErrorCodeConstants.SMS_MOBILE_INVALID; case "isv.TEMPLATE_MISSING_PARAMETERS": return SmsFrameworkErrorCodeConstants.SMS_TEMPLATE_PARAM_ERROR; + default: return SmsFrameworkErrorCodeConstants.SMS_UNKNOWN; } - return SmsFrameworkErrorCodeConstants.SMS_UNKNOWN; } } From 1aee4ad00f9f9d304423960e7fe53148c6b98a78 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 29 Dec 2022 20:18:59 +0800 Subject: [PATCH 12/67] =?UTF-8?q?=E3=80=90=E4=BF=AE=E5=A4=8D=E3=80=91DeptS?= =?UTF-8?q?ervice=20=E7=9A=84=20getDeptsByParentIdFromCache=20=E5=9C=A8?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=83=A8=E9=97=A8=E5=88=97=E8=A1=A8=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=9C=AA=E5=A4=84=E7=90=86=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/system/dal/dataobject/dept/DeptDO.java | 4 ++-- .../yudao/module/system/service/dept/DeptServiceImpl.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java index 647eb1eeb..31f90cfc4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.dept; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -19,7 +19,7 @@ import lombok.EqualsAndHashCode; @KeySequence("system_dept_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) -public class DeptDO extends BaseDO { +public class DeptDO extends TenantBaseDO { /** * 部门ID diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java index dbdedd2f8..049a6415a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; @@ -198,12 +199,19 @@ public class DeptServiceImpl implements DeptService { if (recursiveCount == 0) { return; } + // 获得子部门 Collection depts = parentDeptMap.get(parentId); if (CollUtil.isEmpty(depts)) { return; } + // 针对多租户,过滤掉非当前租户的部门 + Long tenantId = TenantContextHolder.getTenantId(); + if (tenantId != null) { + depts = CollUtil.filterNew(depts, dept -> tenantId.equals(dept.getTenantId())); + } result.addAll(depts); + // 继续递归 depts.forEach(dept -> getDeptsByParentIdFromCache(result, dept.getId(), recursiveCount - 1, parentDeptMap)); From a83b8e8fbc23ae37348e1c551a98ea9a54896bbc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 30 Dec 2022 00:27:14 +0800 Subject: [PATCH 13/67] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +---- pom.xml | 4 ++-- yudao-dependencies/pom.xml | 7 +++++++ .../core/rule/dept/DeptDataPermissionRuleTest.java | 2 +- yudao-framework/yudao-spring-boot-starter-biz-ip/pom.xml | 1 - .../iocoder/yudao/framework/ip/core/utils/AreaUtils.java | 4 +++- .../src/test/resources/application-unit-test.yaml | 2 +- .../yudao/module/infra/service/file/FileServiceTest.java | 2 +- .../src/test/resources/application-unit-test.yaml | 2 +- yudao-module-mall/pom.xml | 5 +---- .../src/test/resources/application-unit-test.yaml | 2 +- .../src/test/resources/application-unit-test.yaml | 2 +- .../src/test/resources/application-unit-test.yaml | 2 +- .../src/test/resources/application-unit-test.yaml | 2 +- .../src/test/resources/application-unit-test.yaml | 2 +- .../yudao/module/system/service/dept/DeptServiceTest.java | 8 ++++++++ .../module/system/service/dict/DictDataServiceTest.java | 4 ++-- .../src/test/resources/application-unit-test.yaml | 2 +- yudao-ui-admin/src/views/mall/trade/order/detail.vue | 7 ++++--- yudao-ui-admin/src/views/mall/trade/order/index.vue | 3 ++- 20 files changed, 40 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 80b60d900..f85c3a1d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -**严肃声明:现在、未来都不会有商业版本,所有功能全部开源!** - -**拒绝虚假开源,售卖商业版,程序员不骗程序员!!** +**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!** **「我喜欢写代码,乐此不疲」** **「我喜欢做开源,以此为乐」** @@ -181,7 +179,6 @@ ps:核心功能已经实现,正在对接微信小程序中... | `yudao-module-system` | 系统功能的 Module 模块 | | `yudao-module-member` | 会员中心的 Module 模块 | | `yudao-module-infra` | 基础设施的 Module 模块 | -| `yudao-module-tool` | 研发工具的 Module 模块 | | `yudao-module-bpm` | 工作流程的 Module 模块 | | `yudao-module-pay` | 支付系统的 Module 模块 | diff --git a/pom.xml b/pom.xml index 8f8f62990..3b1d56ef2 100644 --- a/pom.xml +++ b/pom.xml @@ -14,12 +14,12 @@ yudao-server yudao-module-member - yudao-module-bpm yudao-module-system yudao-module-infra yudao-module-pay - + yudao-module-visualization + yudao-example diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 78d3bcf34..277f9d347 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -56,6 +56,7 @@ 2.6.0 1.3.0 4.1.85.Final + 2.6.6 3.0.0 4.10.0 @@ -515,6 +516,12 @@ ${netty-all.version} + + org.lionsoul + ip2region + ${ip2region.version} + + com.squareup.okio 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 a50e2382f..2481b2acb 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 @@ -227,7 +227,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest { // 调用 Expression expression = rule.getExpression(tableName, tableAlias); // 断言 - assertEquals("u.dept_id IN (10, 20) OR u.id = 1", expression.toString()); + assertEquals("(u.dept_id IN (10, 20) OR u.id = 1)", expression.toString()); assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-ip/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-ip/pom.xml index f30ce1255..4ee1dc5b8 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-ip/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-biz-ip/pom.xml @@ -34,7 +34,6 @@ org.lionsoul ip2region - ${ip2region.version} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java index c77f8be30..d3fe59a6c 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java @@ -28,7 +28,9 @@ public class AreaUtils { @SuppressWarnings("InstantiationOfUtilityClass") private final static AreaUtils INSTANCE = new AreaUtils(); - + /** + * Area 内存缓存,提升访问速度 + */ private static Map areas; private AreaUtils() { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml b/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml index 25bfe0a62..1bbe0f530 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java index 2d4285bee..90bde8f4e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java @@ -79,7 +79,7 @@ public class FileServiceTest extends BaseDbUnitTest { FileClient client = mock(FileClient.class); when(fileConfigService.getMasterFileClient()).thenReturn(client); String url = randomString(); - when(client.upload(same(content), same(path), same("image/jpeg"))).thenReturn(url); + when(client.upload(same(content), same(path), eq("image/jpeg"))).thenReturn(url); when(client.getId()).thenReturn(10L); String name = "单测文件名"; // 调用 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml index 3a2079cdc..31e5ae5c9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml index 4c362d526..37484f00c 100644 --- a/yudao-module-mall/pom.xml +++ b/yudao-module-mall/pom.xml @@ -15,18 +15,15 @@ ${project.artifactId} - 商城大模块,由 product 商品、promotion 营销、trade 交易 coupon等组成 + 商城大模块,由 product 商品、promotion 营销、trade 交易等组成 - - yudao-module-promotion-api yudao-module-promotion-biz yudao-module-product-api yudao-module-product-biz yudao-module-trade-api yudao-module-trade-biz - diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml index 3a2079cdc..31e5ae5c9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml index 60914d97f..a384353aa 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml index 113a0fee5..19dd0e97b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml b/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml index 60914d97f..a384353aa 100644 --- a/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-member/yudao-module-member-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml index 60914d97f..a384353aa 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java index 6a140fc6c..e17187ad6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.service.dept; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptUpdateReqVO; @@ -12,6 +13,7 @@ import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import com.google.common.collect.Multimap; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -47,6 +49,12 @@ public class DeptServiceTest extends BaseDbUnitTest { @MockBean private DeptProducer deptProducer; + @BeforeEach + public void setUp() { + // 清理租户上下文 + TenantContextHolder.clear(); + } + @Test @SuppressWarnings("unchecked") void testInitLocalCache() { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java index bf38bace1..02fba6c21 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java @@ -57,7 +57,7 @@ public class DictDataServiceTest extends BaseDbUnitTest { // 准备参数 DictDataPageReqVO reqVO = new DictDataPageReqVO(); reqVO.setLabel("芋"); - reqVO.setDictType("yu"); + reqVO.setDictType("yunai"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 @@ -86,7 +86,7 @@ public class DictDataServiceTest extends BaseDbUnitTest { // 准备参数 DictDataExportReqVO reqVO = new DictDataExportReqVO(); reqVO.setLabel("芋"); - reqVO.setDictType("yu"); + reqVO.setDictType("yunai"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml b/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml index 63ea5546d..460d4a250 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/application-unit-test.yaml @@ -9,7 +9,7 @@ spring: # 数据源配置项 datasource: name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 driver-class-name: org.h2.Driver username: sa password: diff --git a/yudao-ui-admin/src/views/mall/trade/order/detail.vue b/yudao-ui-admin/src/views/mall/trade/order/detail.vue index 013f2c31e..fe3e29604 100644 --- a/yudao-ui-admin/src/views/mall/trade/order/detail.vue +++ b/yudao-ui-admin/src/views/mall/trade/order/detail.vue @@ -58,7 +58,8 @@ @@ -79,7 +80,7 @@ - + ¥{{ (order.originalPrice / 100.0).toFixed(2) }} ¥{{ (order.deliveryPrice / 100.0).toFixed(2) }} ¥{{ (order.adjustPrice / 100.0).toFixed(2) }} @@ -92,7 +93,7 @@ ¥{{ (order.pointPrice / 100.0).toFixed(2) }} - + ¥{{ (order.payPrice / 100.0).toFixed(2) }} diff --git a/yudao-ui-admin/src/views/mall/trade/order/index.vue b/yudao-ui-admin/src/views/mall/trade/order/index.vue index ae9d59b30..619e27609 100644 --- a/yudao-ui-admin/src/views/mall/trade/order/index.vue +++ b/yudao-ui-admin/src/views/mall/trade/order/index.vue @@ -99,7 +99,8 @@ {{row.spuName}} - {{property.propertyName}}:{{property.valueName}} + + {{property.propertyName}}:{{property.valueName}} From 9a468600867a1e28847313c7509c395a7a7cd2f9 Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 30 Dec 2022 15:04:28 +0800 Subject: [PATCH 14/67] =?UTF-8?q?fix:=20=E9=87=8D=E5=A4=8D=20file=20?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/infra/dal/mysql/file/FileContentDAOImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java index c4dcfe8a0..e38acf2cf 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java @@ -1,11 +1,13 @@ package cn.iocoder.yudao.module.infra.dal.mysql.file; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.file.core.client.db.DBFileContentFrameworkDAO; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.stereotype.Repository; import javax.annotation.Resource; +import java.util.List; @Repository public class FileContentDAOImpl implements DBFileContentFrameworkDAO { @@ -27,9 +29,9 @@ public class FileContentDAOImpl implements DBFileContentFrameworkDAO { @Override public byte[] selectContent(Long configId, String path) { - FileContentDO fileContentDO = fileContentMapper.selectOne( + List fileContentDOs = fileContentMapper.selectList( buildQuery(configId, path).select(FileContentDO::getContent)); - return fileContentDO != null ? fileContentDO.getContent() : null; + return CollUtil.isNotEmpty(fileContentDOs) ? CollUtil.getFirst(fileContentDOs).getContent() : null; } private LambdaQueryWrapper buildQuery(Long configId, String path) { From 639c7820f92e0368e94f63a762f9ef5fc96e44ec Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Fri, 30 Dec 2022 16:07:53 +0800 Subject: [PATCH 15/67] =?UTF-8?q?fix:=20=E9=87=8D=E5=A4=8D=20file=20?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java index e38acf2cf..5213edc7a 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java @@ -30,7 +30,7 @@ public class FileContentDAOImpl implements DBFileContentFrameworkDAO { @Override public byte[] selectContent(Long configId, String path) { List fileContentDOs = fileContentMapper.selectList( - buildQuery(configId, path).select(FileContentDO::getContent)); + buildQuery(configId, path).select(FileContentDO::getContent).orderByDesc(FileContentDO::getId)); return CollUtil.isNotEmpty(fileContentDOs) ? CollUtil.getFirst(fileContentDOs).getContent() : null; } From b7380019baec326038d48fb256cbb6d52d78717d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 30 Dec 2022 22:09:53 +0800 Subject: [PATCH 16/67] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=A1=B9=E7=9B=AE=20RE?= =?UTF-8?q?ADME=20=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 110 +++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index f85c3a1d9..62cba4b1e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ * 管理后台的 Vue3 版本采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) ,Vue2 版本采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) * 管理后台的移动端采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5! -* 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson +* 后端采用 Spring Boot 多模块架构、MySQL + MyBatis Plus、Redis + Redisson * 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等 * 权限认证使用 Spring Security & Token & Redis,支持多终端、多种用户的认证系统,支持 SSO 单点登录 * 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能 @@ -36,12 +36,12 @@ * 集成阿里云、腾讯云等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务 * 集成报表设计器,支持数据报表、图形报表、打印设计等 -| 项目名 | 说明 | 传送门 | -|--------------------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) | -| `yudao-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/yudao-cloud)**     [Github](https://github.com/YunaiV/yudao-cloud) | -| `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) | - | `ruoyi-vue-pro-mini` | 精简版 移除工作流 支付等模块| **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/mini)** | +| 项目名 | 说明 | 传送门 | +|----------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------| +| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) | +| `yudao-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/yudao-cloud)**     [Github](https://github.com/YunaiV/yudao-cloud) | +| `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) | + | `ruoyi-vue-pro-mini` | 精简版:移除工作流、支付等模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/mini)** | ## 😎 开源协议 @@ -94,8 +94,9 @@ | ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 | | 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 | | | 通知公告 | 系统通知公告信息发布维护 | -| 🚀 | 敏感词 | 配置系统敏感词,支持标签分组 | +| 🚀 | 敏感词 | 配置系统敏感词,支持标签分组 | | 🚀 | 应用管理 | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 | +| 🚀 | 地区管理 | 展示省份、城市、区镇等城市信息,支持 IP 对应城市 | ### 工作流程 @@ -130,7 +131,7 @@ ps:核心功能已经实现,正在对接微信小程序中... | | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 | | 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 | | ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 | -| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 | +| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 | | 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 | | | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 | | | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 | @@ -167,46 +168,47 @@ ps:核心功能已经实现,正在对接微信小程序中... ## 🐨 技术栈 -| 项目 | 说明 | -|-------------------------|-----------------------| -| `yudao-dependencies` | Maven 依赖版本管理 | -| `yudao-framework` | Java 框架拓展 | -| `yudao-server` | 管理后台 + 用户 APP 的服务端 | -| `yudao-ui-admin` | 管理后台的 Vue2 前端项目 | -| `yudao-ui-admin-vue3` | 管理后台的 Vue3 前端项目 | -| `yudao-ui-admin-uniapp` | 管理后台的 uni-app 多端项目 | -| `yudao-ui-app` | 用户 APP 的 UI 界面 | -| `yudao-module-system` | 系统功能的 Module 模块 | -| `yudao-module-member` | 会员中心的 Module 模块 | -| `yudao-module-infra` | 基础设施的 Module 模块 | -| `yudao-module-bpm` | 工作流程的 Module 模块 | -| `yudao-module-pay` | 支付系统的 Module 模块 | +| 项目 | 说明 | +|------------------------------|--------------------| +| `yudao-dependencies` | Maven 依赖版本管理 | +| `yudao-framework` | Java 框架拓展 | +| `yudao-server` | 管理后台 + 用户 APP 的服务端 | +| `yudao-ui-admin` | 管理后台的 Vue2 前端项目 | +| `yudao-ui-admin-vue3` | 管理后台的 Vue3 前端项目 | +| `yudao-ui-admin-uniapp` | 管理后台的 uni-app 多端项目 | +| `yudao-ui-app` | 用户 APP 的 UI 界面 | +| `yudao-module-system` | 系统功能的 Module 模块 | +| `yudao-module-member` | 会员中心的 Module 模块 | +| `yudao-module-infra` | 基础设施的 Module 模块 | +| `yudao-module-bpm` | 工作流程的 Module 模块 | +| `yudao-module-pay` | 支付系统的 Module 模块 | +| `yudao-module-visualization` | 大屏报表 Module 模块 | ### 后端 -| 框架 | 说明 | 版本 | 学习指南 | -|---------------------------------------------------------------------------------------------|-----------------------|-------------|----------------------------------------------------------------| -| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.6 | [文档](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.15 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | -| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | -| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.6.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | -| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | | -| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.18.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) | -| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.24 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | -| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | -| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | -| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.7.2 | [文档](https://doc.iocoder.cn/bpm/) | -| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | -| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | -| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | +| 框架 | 说明 | 版本 | 学习指南 | +|---------------------------------------------------------------------------------------------|------------------|-------------|----------------------------------------------------------------| +| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.6 | [文档](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.15 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | +| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | +| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.6.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | +| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | | +| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.18.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) | +| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.24 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) | +| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | +| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | +| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.7.2 | [文档](https://doc.iocoder.cn/bpm/) | +| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | +| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | +| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | | [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) | -| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.9 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) | -| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | | -| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) | -| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.24 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) | -| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - | -| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.8.0 | - | +| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.9 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) | +| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | | +| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) | +| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.24 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) | +| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - | +| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.8.0 | - | ### [管理后台 Vue2 前端](./yudao-ui-admin) @@ -217,22 +219,22 @@ ps:核心功能已经实现,正在对接微信小程序中... ### [管理后台 Vue3 前端](./yudao-ui-admin-vue3) -| 框架 | 说明 | 版本 | +| 框架 | 说明 | 版本 | |----------------------------------------------------------------------|:------------:|:------:| -| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.45 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.3 | +| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.45 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.3 | | [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.27 | | [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 | | [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 | -| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | -| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.7 | +| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | +| [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.7 | ### [管理后台 uni-app 跨端](./yudao-ui-admin-uniapp) -| 框架 | 说明 | 版本 | -|----------------------------------------------------------------------|------------------|--------| -| [uni-app](hhttps://github.com/dcloudio/uni-app) | 跨平台框架 | 2.0.0 | -| [uni-ui](https://github.com/dcloudio/uni-ui) | 基于 uni-app 的 UI 框架 | 1.4.20 | +| 框架 | 说明 | 版本 | +|-------------------------------------------------|--------------------|--------| +| [uni-app](hhttps://github.com/dcloudio/uni-app) | 跨平台框架 | 2.0.0 | +| [uni-ui](https://github.com/dcloudio/uni-ui) | 基于 uni-app 的 UI 框架 | 1.4.20 | ## 🐷 演示图 From 7912a54ebd0d8057b948384a6dbec4d4bc122196 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 31 Dec 2022 17:31:06 +0800 Subject: [PATCH 17/67] =?UTF-8?q?=E3=80=90=E4=BF=AE=E5=A4=8D=E3=80=91?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0/=E4=BF=AE=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=9A=84=E5=94=AF=E4=B8=80=E6=89=8B=E6=9C=BA=E3=80=81?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E7=AD=89=E5=AD=97=E6=AE=B5=E7=9A=84=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E4=B8=8D=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/service/user/AdminUserServiceImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index c57935267..1bb180011 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; @@ -72,6 +73,10 @@ public class AdminUserServiceImpl implements AdminUserService { @Resource private FileApi fileApi; + @Resource + @Lazy // 循环依赖(自己依赖自己),避免报错 + private AdminUserServiceImpl self; + @Override @Transactional(rollbackFor = Exception.class) public Long createUser(UserCreateReqVO reqVO) { @@ -83,7 +88,7 @@ public class AdminUserServiceImpl implements AdminUserService { } }); // 校验正确性 - checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), + self.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), reqVO.getDeptId(), reqVO.getPostIds()); // 插入用户 AdminUserDO user = UserConvert.INSTANCE.convert(reqVO); @@ -102,7 +107,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Transactional(rollbackFor = Exception.class) public void updateUser(UserUpdateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), + self.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), reqVO.getDeptId(), reqVO.getPostIds()); // 更新用户 AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO); @@ -299,7 +304,8 @@ public class AdminUserServiceImpl implements AdminUserService { return deptIds; } - private void checkCreateOrUpdate(Long id, String username, String mobile, String email, + @DataPermission(enable = false) // 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确 + public void checkCreateOrUpdate(Long id, String username, String mobile, String email, Long deptId, Set postIds) { // 校验用户存在 checkUserExists(id); From 6f8384af70009779a1a241e95d1a44211b3df0c3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 31 Dec 2022 19:30:07 +0800 Subject: [PATCH 18/67] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E3=80=8A=E6=95=8F?= =?UTF-8?q?=E6=84=9F=E8=AF=8D=E3=80=8B=E3=80=8A=E5=9C=B0=E5=8C=BA=20&=20IP?= =?UTF-8?q?=E3=80=8B=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-ui-admin/src/views/system/area/index.vue | 2 +- yudao-ui-admin/src/views/system/sensitiveWord/index.vue | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yudao-ui-admin/src/views/system/area/index.vue b/yudao-ui-admin/src/views/system/area/index.vue index 6f9b77ce7..dc93d4237 100644 --- a/yudao-ui-admin/src/views/system/area/index.vue +++ b/yudao-ui-admin/src/views/system/area/index.vue @@ -1,6 +1,6 @@