diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index 9b0ed59e82..13f38e8d80 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -64,6 +64,7 @@
2.9.2
2.7.0
3.0.6
+ 4.1.113.Final
3.5.0
4.11.0
@@ -78,6 +79,13 @@
+
+ io.netty
+ netty-bom
+ ${netty.version}
+ pom
+ import
+
org.springframework.boot
spring-boot-dependencies
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java
index ce9eb16314..de409a4a3a 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.tenant.core.job;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
@@ -44,7 +45,8 @@ public class TenantJobAspect {
// TODO 芋艿:先通过 parallel 实现并行;1)多个租户,是一条执行日志;2)异常的情况
TenantUtils.execute(tenantId, () -> {
try {
- joinPoint.proceed();
+ Object result = joinPoint.proceed();
+ results.put(tenantId, StrUtil.toStringOrNull(result));
} catch (Throwable e) {
log.error("[execute][租户({}) 执行 Job 发生异常", tenantId, e);
results.put(tenantId, ExceptionUtil.getRootCauseMessage(e));
diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java
index 0f08b7cf5e..3aded88738 100644
--- a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate;
import cn.iocoder.yudao.framework.websocket.core.handler.JsonWebSocketMessageHandler;
import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener;
import cn.iocoder.yudao.framework.websocket.core.security.LoginUserHandshakeInterceptor;
+import cn.iocoder.yudao.framework.websocket.core.security.WebSocketAuthorizeRequestsCustomizer;
import cn.iocoder.yudao.framework.websocket.core.sender.kafka.KafkaWebSocketMessageConsumer;
import cn.iocoder.yudao.framework.websocket.core.sender.kafka.KafkaWebSocketMessageSender;
import cn.iocoder.yudao.framework.websocket.core.sender.local.LocalWebSocketMessageSender;
@@ -76,10 +77,15 @@ public class YudaoWebSocketAutoConfiguration {
return new WebSocketSessionManagerImpl();
}
+ @Bean
+ public WebSocketAuthorizeRequestsCustomizer webSocketAuthorizeRequestsCustomizer(WebSocketProperties webSocketProperties) {
+ return new WebSocketAuthorizeRequestsCustomizer(webSocketProperties);
+ }
+
// ==================== Sender 相关 ====================
@Configuration
- @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "local", matchIfMissing = true)
+ @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "local")
public class LocalWebSocketMessageSenderConfiguration {
@Bean
@@ -90,7 +96,7 @@ public class YudaoWebSocketAutoConfiguration {
}
@Configuration
- @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "redis", matchIfMissing = true)
+ @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "redis")
public class RedisWebSocketMessageSenderConfiguration {
@Bean
@@ -108,7 +114,7 @@ public class YudaoWebSocketAutoConfiguration {
}
@Configuration
- @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "rocketmq", matchIfMissing = true)
+ @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "rocketmq")
public class RocketMQWebSocketMessageSenderConfiguration {
@Bean
@@ -127,7 +133,7 @@ public class YudaoWebSocketAutoConfiguration {
}
@Configuration
- @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "rabbitmq", matchIfMissing = true)
+ @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "rabbitmq")
public class RabbitMQWebSocketMessageSenderConfiguration {
@Bean
@@ -156,7 +162,7 @@ public class YudaoWebSocketAutoConfiguration {
}
@Configuration
- @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "kafka", matchIfMissing = true)
+ @ConditionalOnProperty(prefix = "yudao.websocket", name = "sender-type", havingValue = "kafka")
public class KafkaWebSocketMessageSenderConfiguration {
@Bean
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java
index 64ebb1aac8..ec392e496d 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java
@@ -48,8 +48,13 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
// 第二步,获取任务的所有处理人
- Set assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
- execution.setVariable(super.collectionVariable, assigneeUserIds);
+ // 由于每次审批(会签、或签等情况)后都会执行一次,所以 variable 已经有结果,不重复计算
+ @SuppressWarnings("unchecked")
+ Set assigneeUserIds = (Set) execution.getVariable(super.collectionVariable, Set.class);
+ if (assigneeUserIds == null) {
+ assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
+ execution.setVariable(super.collectionVariable, assigneeUserIds);
+ }
return assigneeUserIds.size();
}
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java
index a214e26255..16a54481d7 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmSequentialMultiInstanceBehavior.java
@@ -1,14 +1,13 @@
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
-import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
+import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import lombok.Setter;
import org.flowable.bpmn.model.Activity;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
-import java.util.LinkedHashSet;
import java.util.Set;
/**
@@ -42,8 +41,13 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
// 第二步,获取任务的所有处理人
- Set assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!!
- execution.setVariable(super.collectionVariable, assigneeUserIds);
+ // 由于每次审批(会签、或签等情况)后都会执行一次,所以 variable 已经有结果,不重复计算
+ @SuppressWarnings("unchecked")
+ Set assigneeUserIds = (Set) execution.getVariable(super.collectionVariable, Set.class);
+ if (assigneeUserIds == null) {
+ assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
+ execution.setVariable(super.collectionVariable, assigneeUserIds);
+ }
return assigneeUserIds.size();
}
diff --git a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
index e9f39a81fe..4cce820b77 100644
--- a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
+++ b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants.java
@@ -22,7 +22,7 @@ public interface ErrorCodeConstants {
ErrorCode JOB_CHANGE_STATUS_EQUALS = new ErrorCode(1_001_001_003, "定时任务已经处于该状态,无需修改");
ErrorCode JOB_UPDATE_ONLY_NORMAL_STATUS = new ErrorCode(1_001_001_004, "只有开启状态的任务,才可以修改");
ErrorCode JOB_CRON_EXPRESSION_VALID = new ErrorCode(1_001_001_005, "CRON 表达式不正确");
- ErrorCode JOB_HANDLER_BEAN_NOT_EXISTS = new ErrorCode(1_001_001_006, "定时任务的处理器 Bean 不存在");
+ ErrorCode JOB_HANDLER_BEAN_NOT_EXISTS = new ErrorCode(1_001_001_006, "定时任务的处理器 Bean 不存在,注意 Bean 默认首字母小写");
ErrorCode JOB_HANDLER_BEAN_TYPE_ERROR = new ErrorCode(1_001_001_007, "定时任务的处理器 Bean 类型不正确,未实现 JobHandler 接口");
// ========== API 错误日志 1-001-002-000 ==========
diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java
index abdb613482..0687d13e90 100644
--- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java
+++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -91,13 +92,15 @@ public class JobServiceImpl implements JobService {
}
private void validateJobHandlerExists(String handlerName) {
- Object handler = SpringUtil.getBean(handlerName);
- if (handler == null) {
+ try {
+ Object handler = SpringUtil.getBean(handlerName);
+ assert handler != null;
+ if (!(handler instanceof JobHandler)) {
+ throw exception(JOB_HANDLER_BEAN_TYPE_ERROR);
+ }
+ } catch (NoSuchBeanDefinitionException e) {
throw exception(JOB_HANDLER_BEAN_NOT_EXISTS);
}
- if (!(handler instanceof JobHandler)) {
- throw exception(JOB_HANDLER_BEAN_TYPE_ERROR);
- }
}
@Override
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
index 67353726aa..7f4b0e034d 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
@@ -23,10 +23,10 @@ import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClien
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
+import jakarta.annotation.Resource;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
-import javax.annotation.Resource;
import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -215,7 +215,7 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
* @return 物流轨迹
*/
@Cacheable(cacheNames = RedisKeyConstants.EXPRESS_TRACK, key = "#code + '-' + #logisticsNo + '-' + #receiverMobile",
- condition = "#result != null && #result.length() > 0")
+ unless = "#result == null")
public List getExpressTrackList(String code, String logisticsNo, String receiverMobile) {
return expressClientFactory.getDefaultExpressClient().getExpressTrackList(new ExpressTrackQueryReqDTO()
.setExpressCode(code).setLogisticsNo(logisticsNo).setPhone(receiverMobile));
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
index 1f7619e49d..9ca167cc3f 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -55,13 +55,13 @@ import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper;
+import jakarta.annotation.Resource;
+import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import javax.annotation.Resource;
-import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@@ -375,8 +375,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// 3. 记录订单日志
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus(),
- MapUtil.builder().put("expressName", express != null ? express.getName() : "无")
- .put("logisticsNo", express != null ? deliveryReqVO.getLogisticsNo() : "无").build());
+ MapUtil.builder().put("deliveryName", express != null ? express.getName() : "")
+ .put("logisticsNo", express != null ? deliveryReqVO.getLogisticsNo() : "").build());
// 4.1 发送站内信
tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO()
diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
index f8adb42d53..103d4b34ba 100755
--- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
+++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
@@ -431,9 +431,7 @@ public class PayOrderServiceImpl implements PayOrderService {
return;
}
- // TODO 芋艿:应该 new 出来更新
- order.setPrice(payPrice);
- orderMapper.updateById(order);
+ orderMapper.updateById(new PayOrderDO().setId(order.getId()).setPrice(payPrice));
}
@Override
diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
index c50cb19d42..73e88c0b08 100644
--- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
+++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
@@ -180,7 +180,6 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
.setReason("想退钱").setPrice(walletRecharge.getPayPrice()));
// 4. 更新充值记录退款单号
- // TODO @jaosn:一般新建这种 update 对象,建议是,第一个 set id 属性,容易知道以它为更新
walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId)
.setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId()));
}
diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
index d6f9281bc3..1a6bd35575 100644
--- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
+++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
@@ -121,6 +121,7 @@ public class PayWalletServiceImpl implements PayWalletService {
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public PayWalletTransactionDO reduceWalletBalance(Long walletId, Long bizId,
PayWalletBizTypeEnum bizType, Integer price) {
// 1. 获取钱包
@@ -158,6 +159,7 @@ public class PayWalletServiceImpl implements PayWalletService {
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public PayWalletTransactionDO addWalletBalance(Long walletId, String bizId,
PayWalletBizTypeEnum bizType, Integer price) {
// 1.1 获取钱包
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java
index 6907fa54bd..8d1927e5de 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java
@@ -280,7 +280,8 @@ public class SocialClientServiceImpl implements SocialClientService {
}
@Override
- @Cacheable(cacheNames = RedisKeyConstants.WXA_SUBSCRIBE_TEMPLATE, key = "#userType", condition = "#result != null")
+ @Cacheable(cacheNames = RedisKeyConstants.WXA_SUBSCRIBE_TEMPLATE, key = "#userType",
+ unless = "#result == null")
public List getSubscribeTemplateList(Integer userType) {
WxMaService service = getWxMaService(userType);
try {