Commit 3e3bcc963da25b5dd1eb5cec09321a0adb48773c

Authored by YunaiV
2 parents e2edd7a4 5b6723fc

Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into master-jdk17

yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoTracerAutoConfiguration.java
... ... @@ -21,7 +21,8 @@ import org.springframework.context.annotation.Bean;
21 21 @AutoConfiguration
22 22 @ConditionalOnClass(name = {
23 23 "org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer",
24   - "io.opentracing.Tracer"
  24 + "io.opentracing.Tracer",
  25 + "jakarta.servlet.Filter"
25 26 })
26 27 @EnableConfigurationProperties(TracerProperties.class)
27 28 @ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true)
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
... ... @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.SortingField;
9 9 import cn.iocoder.yudao.framework.mybatis.core.enums.DbTypeEnum;
10 10 import com.baomidou.mybatisplus.annotation.DbType;
11 11 import com.baomidou.mybatisplus.core.conditions.Wrapper;
  12 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
12 13 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
13 14 import com.baomidou.mybatisplus.core.metadata.OrderItem;
14 15 import com.baomidou.mybatisplus.core.toolkit.StringPool;
... ... @@ -47,16 +48,36 @@ public class MyBatisUtils {
47 48 return page;
48 49 }
49 50  
  51 + @SuppressWarnings("PatternVariableCanBeUsed")
50 52 public static <T> void addOrder(Wrapper<T> wrapper, Collection<SortingField> sortingFields) {
51 53 if (CollUtil.isEmpty(sortingFields)) {
52 54 return;
53 55 }
54   - QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
55   - for (SortingField sortingField : sortingFields) {
56   - query.orderBy(true,
57   - SortingField.ORDER_ASC.equals(sortingField.getOrder()),
58   - StrUtil.toUnderlineCase(sortingField.getField()));
  56 + if (wrapper instanceof QueryWrapper<T>) {
  57 + QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
  58 + for (SortingField sortingField : sortingFields) {
  59 + query.orderBy(true,
  60 + SortingField.ORDER_ASC.equals(sortingField.getOrder()),
  61 + StrUtil.toUnderlineCase(sortingField.getField()));
  62 + }
  63 + } else if (wrapper instanceof LambdaQueryWrapper<T>) {
  64 + // LambdaQueryWrapper 不直接支持字符串字段排序,使用 last 方法拼接 ORDER BY
  65 + LambdaQueryWrapper<T> lambdaQuery = (LambdaQueryWrapper<T>) wrapper;
  66 + StringBuilder orderBy = new StringBuilder();
  67 + for (SortingField sortingField : sortingFields) {
  68 + if (StrUtil.isNotEmpty(orderBy)) {
  69 + orderBy.append(", ");
  70 + }
  71 + orderBy.append(StrUtil.toUnderlineCase(sortingField.getField()))
  72 + .append(" ")
  73 + .append(SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? "ASC" : "DESC");
  74 + }
  75 + lambdaQuery.last("ORDER BY " + orderBy);
  76 + // 另外个思路:https://blog.csdn.net/m0_59084856/article/details/138450913
  77 + } else {
  78 + throw new IllegalArgumentException("Unsupported wrapper type: " + wrapper.getClass().getName());
59 79 }
  80 +
60 81 }
61 82  
62 83 /**
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/encrypt/core/filter/ApiEncryptFilter.java
... ... @@ -128,6 +128,7 @@ public class ApiEncryptFilter extends ApiRequestFilter {
128 128 *
129 129 * @param request 请求
130 130 */
  131 + @SuppressWarnings("PatternVariableCanBeUsed")
131 132 private ApiEncrypt getApiEncrypt(HttpServletRequest request) {
132 133 try {
133 134 HandlerExecutionChain mappingHandler = requestMappingHandlerMapping.getHandler(request);
... ... @@ -135,7 +136,8 @@ public class ApiEncryptFilter extends ApiRequestFilter {
135 136 return null;
136 137 }
137 138 Object handler = mappingHandler.getHandler();
138   - if (handler instanceof HandlerMethod handlerMethod) {
  139 + if (handler instanceof HandlerMethod) {
  140 + HandlerMethod handlerMethod = (HandlerMethod) handler;
139 141 ApiEncrypt annotation = handlerMethod.getMethodAnnotation(ApiEncrypt.class);
140 142 if (annotation == null) {
141 143 annotation = handlerMethod.getBeanType().getAnnotation(ApiEncrypt.class);
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
... ... @@ -36,6 +36,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException;
36 36 import org.springframework.web.bind.annotation.ExceptionHandler;
37 37 import org.springframework.web.bind.annotation.RestControllerAdvice;
38 38 import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
  39 +import org.springframework.web.multipart.MaxUploadSizeExceededException;
39 40 import org.springframework.web.servlet.NoHandlerFoundException;
40 41 import org.springframework.web.servlet.resource.NoResourceFoundException;
41 42  
... ... @@ -93,6 +94,9 @@ public class GlobalExceptionHandler {
93 94 if (ex instanceof ValidationException) {
94 95 return validationException((ValidationException) ex);
95 96 }
  97 + if (ex instanceof MaxUploadSizeExceededException) {
  98 + return maxUploadSizeExceededExceptionHandler((MaxUploadSizeExceededException) ex);
  99 + }
96 100 if (ex instanceof NoHandlerFoundException) {
97 101 return noHandlerFoundExceptionHandler((NoHandlerFoundException) ex);
98 102 }
... ... @@ -111,9 +115,6 @@ public class GlobalExceptionHandler {
111 115 if (ex instanceof AccessDeniedException) {
112 116 return accessDeniedExceptionHandler(request, (AccessDeniedException) ex);
113 117 }
114   - if (ex instanceof UncheckedExecutionException && ex.getCause() != ex) {
115   - return allExceptionHandler(request, ex.getCause());
116   - }
117 118 return defaultExceptionHandler(request, ex);
118 119 }
119 120  
... ... @@ -214,6 +215,14 @@ public class GlobalExceptionHandler {
214 215 }
215 216  
216 217 /**
  218 + * 处理上传文件过大异常
  219 + */
  220 + @ExceptionHandler(MaxUploadSizeExceededException.class)
  221 + public CommonResult<?> maxUploadSizeExceededExceptionHandler(MaxUploadSizeExceededException ex) {
  222 + return CommonResult.error(BAD_REQUEST.getCode(), "上传文件过大,请调整后重试");
  223 + }
  224 +
  225 + /**
217 226 * 处理 SpringMVC 请求地址不存在
218 227 *
219 228 * 注意,它需要设置如下两个配置项:
... ... @@ -309,6 +318,12 @@ public class GlobalExceptionHandler {
309 318 */
310 319 @ExceptionHandler(value = Exception.class)
311 320 public CommonResult<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
  321 + // 特殊:如果是 ServiceException 的异常,则直接返回
  322 + // 例如说:https://gitee.com/zhijiantianya/yudao-cloud/issues/ICSSRM、https://gitee.com/zhijiantianya/yudao-cloud/issues/ICT6FM
  323 + if (ex.getCause() != null && ex.getCause() instanceof ServiceException) {
  324 + return serviceExceptionHandler((ServiceException) ex.getCause());
  325 + }
  326 +
312 327 // 情况一:处理表不存在的异常
313 328 CommonResult<?> tableNotExistsResult = handleTableNotExists(ex);
314 329 if (tableNotExistsResult != null) {
... ...
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java
... ... @@ -30,7 +30,7 @@ public interface CouponConvert {
30 30 CouponRespDTO convert(CouponDO bean);
31 31  
32 32 default CouponDO convert(CouponTemplateDO template, Long userId) {
33   - CouponDO couponDO = new CouponDO()
  33 + CouponDO coupon = new CouponDO()
34 34 .setTemplateId(template.getId())
35 35 .setName(template.getName())
36 36 .setTakeType(template.getTakeType())
... ... @@ -44,13 +44,13 @@ public interface CouponConvert {
44 44 .setStatus(CouponStatusEnum.UNUSED.getStatus())
45 45 .setUserId(userId);
46 46 if (CouponTemplateValidityTypeEnum.DATE.getType().equals(template.getValidityType())) {
47   - couponDO.setValidStartTime(template.getValidStartTime());
48   - couponDO.setValidEndTime(template.getValidEndTime());
  47 + coupon.setValidStartTime(template.getValidStartTime());
  48 + coupon.setValidEndTime(template.getValidEndTime());
49 49 } else if (CouponTemplateValidityTypeEnum.TERM.getType().equals(template.getValidityType())) {
50   - couponDO.setValidStartTime(LocalDateTime.now().plusDays(template.getFixedStartTerm()));
51   - couponDO.setValidEndTime(LocalDateTime.now().plusDays(template.getFixedEndTerm()));
  50 + coupon.setValidStartTime(LocalDateTime.now().plusDays(template.getFixedStartTerm()));
  51 + coupon.setValidEndTime(coupon.getValidStartTime().plusDays(template.getFixedEndTerm()));
52 52 }
53   - return couponDO;
  53 + return coupon;
54 54 }
55 55  
56 56 CouponPageReqVO convert(AppCouponPageReqVO pageReqVO, Collection<Long> userIds);
... ...
yudao-module-mall/yudao-module-trade/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeStatusSyncToWxaOrderHandler.java
... ... @@ -42,6 +42,40 @@ public class TradeStatusSyncToWxaOrderHandler implements TradeOrderHandler {
42 42 if (ObjUtil.notEqual(order.getPayChannelCode(), PayChannelEnum.WX_LITE.getCode())) {
43 43 return;
44 44 }
  45 +
  46 + // 上传订单物流信息到微信小程序
  47 + uploadWxaOrderShippingInfo(order);
  48 + }
  49 +
  50 + @Override
  51 + public void afterReceiveOrder(TradeOrderDO order) {
  52 + // 注意:只有微信小程序支付的订单,才需要同步
  53 + if (ObjUtil.notEqual(order.getPayChannelCode(), PayChannelEnum.WX_LITE.getCode())) {
  54 + return;
  55 + }
  56 + PayOrderRespDTO payOrder = payOrderApi.getOrder(order.getPayOrderId());
  57 + SocialWxaOrderNotifyConfirmReceiveReqDTO reqDTO = new SocialWxaOrderNotifyConfirmReceiveReqDTO()
  58 + .setTransactionId(payOrder.getChannelOrderNo())
  59 + .setReceivedTime(order.getReceiveTime());
  60 + try {
  61 + socialClientApi.notifyWxaOrderConfirmReceive(UserTypeEnum.MEMBER.getValue(), reqDTO);
  62 + } catch (Exception ex) {
  63 + log.error("[afterReceiveOrder][订单({}) 通知订单收货到微信小程序失败]", order, ex);
  64 + }
  65 +
  66 + // 如果是门店自提订单,上传订单物流信息到微信小程序
  67 + // 原因是,门店自提订单没有 “afterDeliveryOrder” 阶段。可见 https://t.zsxq.com/KWD3u 反馈
  68 + if (DeliveryTypeEnum.PICK_UP.getType().equals(order.getDeliveryType())) {
  69 + uploadWxaOrderShippingInfo(order);
  70 + }
  71 + }
  72 +
  73 + /**
  74 + * 上传订单物流信息到微信小程序
  75 + *
  76 + * @param order 订单
  77 + */
  78 + private void uploadWxaOrderShippingInfo(TradeOrderDO order) {
45 79 PayOrderRespDTO payOrder = payOrderApi.getOrder(order.getPayOrderId());
46 80 SocialWxaOrderUploadShippingInfoReqDTO reqDTO = new SocialWxaOrderUploadShippingInfoReqDTO()
47 81 .setTransactionId(payOrder.getChannelOrderNo())
... ... @@ -64,23 +98,6 @@ public class TradeStatusSyncToWxaOrderHandler implements TradeOrderHandler {
64 98 }
65 99 }
66 100  
67   - @Override
68   - public void afterReceiveOrder(TradeOrderDO order) {
69   - // 注意:只有微信小程序支付的订单,才需要同步
70   - if (ObjUtil.notEqual(order.getPayChannelCode(), PayChannelEnum.WX_LITE.getCode())) {
71   - return;
72   - }
73   - PayOrderRespDTO payOrder = payOrderApi.getOrder(order.getPayOrderId());
74   - SocialWxaOrderNotifyConfirmReceiveReqDTO reqDTO = new SocialWxaOrderNotifyConfirmReceiveReqDTO()
75   - .setTransactionId(payOrder.getChannelOrderNo())
76   - .setReceivedTime(order.getReceiveTime());
77   - try {
78   - socialClientApi.notifyWxaOrderConfirmReceive(UserTypeEnum.MEMBER.getValue(), reqDTO);
79   - } catch (Exception ex) {
80   - log.error("[afterReceiveOrder][订单({}) 通知订单收货到微信小程序失败]", order, ex);
81   - }
82   - }
83   -
84 101 // TODO @芋艿:【设置路径】 https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E5%85%AD%E3%80%81%E6%B6%88%E6%81%AF%E8%B7%B3%E8%BD%AC%E8%B7%AF%E5%BE%84%E8%AE%BE%E7%BD%AE%E6%8E%A5%E5%8F%A3
85 102  
86 103 }
... ...