Commit 15cca8f3de3f1b34b6c53d13698cfc757656f506
1 parent
348d0737
mall + pay:
1. 支付订单的状态同步 Job 2. 支付订单的过期关闭 Job
Showing
7 changed files
with
247 additions
and
7 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/order/PayOrderStatusRespEnum.java
| ... | ... | @@ -34,6 +34,16 @@ public enum PayOrderStatusRespEnum { |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | /** |
| 37 | + * 判断是否已退款 | |
| 38 | + * | |
| 39 | + * @param status 状态 | |
| 40 | + * @return 是否支付成功 | |
| 41 | + */ | |
| 42 | + public static boolean isRefund(Integer status) { | |
| 43 | + return Objects.equals(status, REFUND.getStatus()); | |
| 44 | + } | |
| 45 | + | |
| 46 | + /** | |
| 37 | 47 | * 判断是否支付关闭 |
| 38 | 48 | * |
| 39 | 49 | * @param status 状态 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java
| ... | ... | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 5 | 5 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 6 | 6 | import org.apache.ibatis.annotations.Mapper; |
| 7 | 7 | |
| 8 | +import java.time.LocalDateTime; | |
| 8 | 9 | import java.util.List; |
| 9 | 10 | |
| 10 | 11 | @Mapper |
| ... | ... | @@ -23,4 +24,10 @@ public interface PayOrderExtensionMapper extends BaseMapperX<PayOrderExtensionDO |
| 23 | 24 | return selectList(PayOrderExtensionDO::getOrderId, orderId); |
| 24 | 25 | } |
| 25 | 26 | |
| 27 | + default List<PayOrderExtensionDO> selectListByStatusAndCreateTimeGe(Integer status, LocalDateTime minCreateTime) { | |
| 28 | + return selectList(new LambdaQueryWrapper<PayOrderExtensionDO>() | |
| 29 | + .eq(PayOrderExtensionDO::getStatus, status) | |
| 30 | + .ge(PayOrderExtensionDO::getCreateTime, minCreateTime)); | |
| 31 | + } | |
| 32 | + | |
| 26 | 33 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java
| ... | ... | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 9 | 9 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 10 | 10 | import org.apache.ibatis.annotations.Mapper; |
| 11 | 11 | |
| 12 | +import java.time.LocalDateTime; | |
| 12 | 13 | import java.util.List; |
| 13 | 14 | |
| 14 | 15 | @Mapper |
| ... | ... | @@ -52,4 +53,10 @@ public interface PayOrderMapper extends BaseMapperX<PayOrderDO> { |
| 52 | 53 | .eq(PayOrderDO::getId, id).eq(PayOrderDO::getStatus, status)); |
| 53 | 54 | } |
| 54 | 55 | |
| 56 | + default List<PayOrderDO> selectListByStatusAndExpireTimeLt(Integer status, LocalDateTime expireTime) { | |
| 57 | + return selectList(new LambdaQueryWrapper<PayOrderDO>() | |
| 58 | + .eq(PayOrderDO::getStatus, status) | |
| 59 | + .lt(PayOrderDO::getExpireTime, expireTime)); | |
| 60 | + } | |
| 61 | + | |
| 55 | 62 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderExpireJob.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.job.order; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | |
| 5 | +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; | |
| 6 | +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 支付订单的过期 Job | |
| 13 | + * | |
| 14 | + * 支付超过过期时间时,支付渠道是不会通知进行过期,所以需要定时进行过期关闭。 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@Component | |
| 19 | +@TenantJob | |
| 20 | +public class PayOrderExpireJob implements JobHandler { | |
| 21 | + | |
| 22 | + @Resource | |
| 23 | + private PayOrderService orderService; | |
| 24 | + | |
| 25 | + @Override | |
| 26 | + public String execute(String param) { | |
| 27 | + int count = orderService.expireOrder(); | |
| 28 | + return StrUtil.format("支付过期 {} 个", count); | |
| 29 | + } | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.job.order; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | |
| 5 | +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; | |
| 6 | +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | +import java.time.Duration; | |
| 11 | +import java.time.LocalDateTime; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 支付订单的同步 Job | |
| 15 | + * | |
| 16 | + * 由于支付订单的状态,是由支付渠道异步通知进行同步,考虑到异步通知可能会失败(小概率),所以需要定时进行同步。 | |
| 17 | + * | |
| 18 | + * @author 芋道源码 | |
| 19 | + */ | |
| 20 | +@Component | |
| 21 | +@TenantJob | |
| 22 | +public class PayOrderSyncJob implements JobHandler { | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 同步创建时间在 N 分钟之前的订单 | |
| 26 | + * | |
| 27 | + * 为什么同步 10 分钟之前的订单? | |
| 28 | + * 因为一个订单发起支付,到支付成功,大多数在 10 分钟内,需要保证轮询到。 | |
| 29 | + * 如果设置为 30、60 或者更大时间范围,会导致轮询的订单太多,影响性能。当然,你也可以根据自己的业务情况来处理。 | |
| 30 | + */ | |
| 31 | + private static final Duration CREATE_TIME_DURATION_BEFORE = Duration.ofMinutes(10); | |
| 32 | + | |
| 33 | + @Resource | |
| 34 | + private PayOrderService orderService; | |
| 35 | + | |
| 36 | + @Override | |
| 37 | + public String execute(String param) { | |
| 38 | + LocalDateTime minCreateTime = LocalDateTime.now().minus(CREATE_TIME_DURATION_BEFORE); | |
| 39 | + int count = orderService.syncOrder(minCreateTime); | |
| 40 | + return StrUtil.format("同步订单 {} 个", count); | |
| 41 | + } | |
| 42 | + | |
| 43 | +} | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
| ... | ... | @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 12 | 12 | |
| 13 | 13 | import javax.validation.Valid; |
| 14 | 14 | import javax.validation.constraints.NotEmpty; |
| 15 | +import java.time.LocalDateTime; | |
| 15 | 16 | import java.util.List; |
| 16 | 17 | |
| 17 | 18 | /** |
| ... | ... | @@ -105,4 +106,19 @@ public interface PayOrderService { |
| 105 | 106 | */ |
| 106 | 107 | PayOrderExtensionDO getOrderExtension(Long id); |
| 107 | 108 | |
| 109 | + /** | |
| 110 | + * 同步订单的支付状态 | |
| 111 | + * | |
| 112 | + * @param minCreateTime 最小创建时间 | |
| 113 | + * @return 同步到已支付的订单数量 | |
| 114 | + */ | |
| 115 | + int syncOrder(LocalDateTime minCreateTime); | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * 将已过期的订单,状态修改为已关闭 | |
| 119 | + * | |
| 120 | + * @return 过期的订单数量 | |
| 121 | + */ | |
| 122 | + int expireOrder(); | |
| 123 | + | |
| 108 | 124 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.service.order; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.util.ObjectUtil; |
| 4 | 5 | import cn.hutool.core.util.StrUtil; |
| 5 | 6 | import cn.hutool.extra.spring.SpringUtil; |
| ... | ... | @@ -39,6 +40,8 @@ import org.springframework.transaction.annotation.Transactional; |
| 39 | 40 | import org.springframework.validation.annotation.Validated; |
| 40 | 41 | |
| 41 | 42 | import javax.annotation.Resource; |
| 43 | +import java.time.Duration; | |
| 44 | +import java.time.LocalDateTime; | |
| 42 | 45 | import java.util.List; |
| 43 | 46 | import java.util.Objects; |
| 44 | 47 | |
| ... | ... | @@ -152,6 +155,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 152 | 155 | .setReturnUrl(reqVO.getReturnUrl()) |
| 153 | 156 | // 订单相关字段 |
| 154 | 157 | .setPrice(order.getPrice()).setExpireTime(order.getExpireTime()); |
| 158 | + unifiedOrderReqDTO.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofSeconds(70))); // TODO 芋艿:稍后删除掉 | |
| 155 | 159 | PayOrderRespDTO unifiedOrderResp = client.unifiedOrder(unifiedOrderReqDTO); |
| 156 | 160 | |
| 157 | 161 | // 4. 如果调用直接支付成功,则直接更新支付单状态为成功。例如说:付款码支付,免密支付时,就直接验证支付成功 |
| ... | ... | @@ -297,7 +301,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 297 | 301 | throw exception(ORDER_EXTENSION_NOT_FOUND); |
| 298 | 302 | } |
| 299 | 303 | if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) { // 如果已经是成功,直接返回,不用重复更新 |
| 300 | - log.info("[updateOrderExtensionSuccess][支付拓展单({}) 已经是已支付,无需更新]", orderExtension.getId()); | |
| 304 | + log.info("[updateOrderExtensionSuccess][orderExtension({}) 已经是已支付,无需更新]", orderExtension.getId()); | |
| 301 | 305 | return orderExtension; |
| 302 | 306 | } |
| 303 | 307 | if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态,必须是待支付 |
| ... | ... | @@ -310,7 +314,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 310 | 314 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 311 | 315 | throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); |
| 312 | 316 | } |
| 313 | - log.info("[updateOrderExtensionSuccess][支付拓展单({}) 更新为已支付]", orderExtension.getId()); | |
| 317 | + log.info("[updateOrderExtensionSuccess][orderExtension({}) 更新为已支付]", orderExtension.getId()); | |
| 314 | 318 | return orderExtension; |
| 315 | 319 | } |
| 316 | 320 | |
| ... | ... | @@ -331,7 +335,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 331 | 335 | } |
| 332 | 336 | if (PayOrderStatusEnum.isSuccess(order.getStatus()) // 如果已经是成功,直接返回,不用重复更新 |
| 333 | 337 | && Objects.equals(order.getExtensionId(), orderExtension.getId())) { |
| 334 | - log.info("[updateOrderExtensionSuccess][支付订单({}) 已经是已支付,无需更新]", order.getId()); | |
| 338 | + log.info("[updateOrderExtensionSuccess][order({}) 已经是已支付,无需更新]", order.getId()); | |
| 335 | 339 | return true; |
| 336 | 340 | } |
| 337 | 341 | if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 |
| ... | ... | @@ -349,7 +353,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 349 | 353 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 350 | 354 | throw exception(ORDER_STATUS_IS_NOT_WAITING); |
| 351 | 355 | } |
| 352 | - log.info("[updateOrderExtensionSuccess][支付订单({}) 更新为已支付]", order.getId()); | |
| 356 | + log.info("[updateOrderExtensionSuccess][order({}) 更新为已支付]", order.getId()); | |
| 353 | 357 | return false; |
| 354 | 358 | } |
| 355 | 359 | |
| ... | ... | @@ -364,12 +368,12 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 364 | 368 | throw exception(ORDER_EXTENSION_NOT_FOUND); |
| 365 | 369 | } |
| 366 | 370 | if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) { // 如果已经是关闭,直接返回,不用重复更新 |
| 367 | - log.info("[updateOrderExtensionClosed][支付拓展单({}) 已经是支付关闭,无需更新]", orderExtension.getId()); | |
| 371 | + log.info("[updateOrderExtensionClosed][orderExtension({}) 已经是支付关闭,无需更新]", orderExtension.getId()); | |
| 368 | 372 | return; |
| 369 | 373 | } |
| 370 | 374 | // 一般出现先是支付成功,然后支付关闭,都是全部退款导致关闭的场景。这个情况,我们不更新支付拓展单,只通过退款流程,更新支付单 |
| 371 | 375 | if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) { |
| 372 | - log.info("[updateOrderExtensionClosed][支付拓展单({}) 是已支付,无需更新为支付关闭]", orderExtension.getId()); | |
| 376 | + log.info("[updateOrderExtensionClosed][orderExtension({}) 是已支付,无需更新为支付关闭]", orderExtension.getId()); | |
| 373 | 377 | return; |
| 374 | 378 | } |
| 375 | 379 | if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态,必须是待支付 |
| ... | ... | @@ -383,7 +387,7 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 383 | 387 | if (updateCounts == 0) { // 校验状态,必须是待支付 |
| 384 | 388 | throw exception(ORDER_EXTENSION_STATUS_IS_NOT_WAITING); |
| 385 | 389 | } |
| 386 | - log.info("[updateOrderExtensionClosed][支付拓展单({}) 更新为支付关闭]", orderExtension.getId()); | |
| 390 | + log.info("[updateOrderExtensionClosed][orderExtension({}) 更新为支付关闭]", orderExtension.getId()); | |
| 387 | 391 | } |
| 388 | 392 | |
| 389 | 393 | @Override |
| ... | ... | @@ -414,6 +418,128 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 414 | 418 | return orderExtensionMapper.selectById(id); |
| 415 | 419 | } |
| 416 | 420 | |
| 421 | + @Override | |
| 422 | + public int syncOrder(LocalDateTime minCreateTime) { | |
| 423 | + // 1. 查询指定创建时间内的待支付订单 | |
| 424 | + List<PayOrderExtensionDO> orderExtensions = orderExtensionMapper.selectListByStatusAndCreateTimeGe( | |
| 425 | + PayOrderStatusEnum.WAITING.getStatus(), minCreateTime); | |
| 426 | + if (CollUtil.isEmpty(orderExtensions)) { | |
| 427 | + return 0; | |
| 428 | + } | |
| 429 | + // 2. 遍历执行 | |
| 430 | + int count = 0; | |
| 431 | + for (PayOrderExtensionDO orderExtension : orderExtensions) { | |
| 432 | + count += syncOrder(orderExtension) ? 1 : 0; | |
| 433 | + } | |
| 434 | + return count; | |
| 435 | + } | |
| 436 | + | |
| 437 | + /** | |
| 438 | + * 同步单个支付拓展单 | |
| 439 | + * | |
| 440 | + * @param orderExtension 支付拓展单 | |
| 441 | + * @return 是否已支付 | |
| 442 | + */ | |
| 443 | + private boolean syncOrder(PayOrderExtensionDO orderExtension) { | |
| 444 | + try { | |
| 445 | + // 1.1 查询支付订单信息 | |
| 446 | + PayClient payClient = payClientFactory.getPayClient(orderExtension.getChannelId()); | |
| 447 | + if (payClient == null) { | |
| 448 | + log.error("[syncOrder][渠道编号({}) 找不到对应的支付客户端]", orderExtension.getChannelId()); | |
| 449 | + return false; | |
| 450 | + } | |
| 451 | + PayOrderRespDTO respDTO = payClient.getOrder(orderExtension.getNo()); | |
| 452 | + // 1.2 回调支付结果 | |
| 453 | + notifyOrder(orderExtension.getChannelId(), respDTO); | |
| 454 | + | |
| 455 | + // 2. 如果是已支付,则返回 1 | |
| 456 | + return PayOrderStatusRespEnum.isSuccess(respDTO.getStatus()); | |
| 457 | + } catch (Throwable e) { | |
| 458 | + log.error("[syncOrder][orderExtension({}) 同步支付状态异常]", orderExtension.getId(), e); | |
| 459 | + return false; | |
| 460 | + } | |
| 461 | + } | |
| 462 | + | |
| 463 | + @Override | |
| 464 | + public int expireOrder() { | |
| 465 | + // 1. 查询过期的待支付订单 | |
| 466 | + List<PayOrderDO> orders = orderMapper.selectListByStatusAndExpireTimeLt( | |
| 467 | + PayOrderStatusEnum.WAITING.getStatus(), LocalDateTime.now()); | |
| 468 | + if (CollUtil.isEmpty(orders)) { | |
| 469 | + return 0; | |
| 470 | + } | |
| 471 | + | |
| 472 | + // 2. 遍历执行 | |
| 473 | + int count = 0; | |
| 474 | + for (PayOrderDO order : orders) { | |
| 475 | + count += expireOrder(order) ? 1 : 0; | |
| 476 | + } | |
| 477 | + return count; | |
| 478 | + } | |
| 479 | + | |
| 480 | + /** | |
| 481 | + * 同步单个支付单 | |
| 482 | + * | |
| 483 | + * @param order 支付单 | |
| 484 | + * @return 是否已过期 | |
| 485 | + */ | |
| 486 | + private boolean expireOrder(PayOrderDO order) { | |
| 487 | + try { | |
| 488 | + // 1. 需要先处理关联的支付拓展单,避免错误的过期已支付 or 已退款的订单 | |
| 489 | + List<PayOrderExtensionDO> orderExtensions = orderExtensionMapper.selectListByOrderId(order.getId()); | |
| 490 | + for (PayOrderExtensionDO orderExtension : orderExtensions) { | |
| 491 | + if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) { | |
| 492 | + continue; | |
| 493 | + } | |
| 494 | + // 情况一:校验数据库中的 orderExtension 是不是已支付 | |
| 495 | + if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) { | |
| 496 | + log.error("[expireOrder][order({}) 的 extension({}) 已支付,可能是数据不一致]", | |
| 497 | + order.getId(), orderExtension.getId()); | |
| 498 | + return false; | |
| 499 | + } | |
| 500 | + // 情况二:调用三方接口,查询支付单状态,是不是已支付/已退款 | |
| 501 | + PayClient payClient = payClientFactory.getPayClient(orderExtension.getChannelId()); | |
| 502 | + if (payClient == null) { | |
| 503 | + log.error("[expireOrder][渠道编号({}) 找不到对应的支付客户端]", orderExtension.getChannelId()); | |
| 504 | + return false; | |
| 505 | + } | |
| 506 | + PayOrderRespDTO respDTO = payClient.getOrder(orderExtension.getNo()); | |
| 507 | + if (PayOrderStatusRespEnum.isRefund(respDTO.getStatus())) { | |
| 508 | + // 补充说明:按道理,应该是 WAITING => SUCCESS => REFUND 状态,如果直接 WAITING => REFUND 状态,说明中间丢了过程 | |
| 509 | + // 此时,需要人工介入,手工补齐数据,保持 WAITING => SUCCESS => REFUND 的过程 | |
| 510 | + log.error("[expireOrder][extension({}) 的 PayOrderRespDTO({}) 已退款,可能是回调延迟]", | |
| 511 | + orderExtension.getId(), toJsonString(respDTO)); | |
| 512 | + return false; | |
| 513 | + } | |
| 514 | + if (PayOrderStatusRespEnum.isSuccess(respDTO.getStatus())) { | |
| 515 | + notifyOrder(orderExtension.getChannelId(), respDTO); | |
| 516 | + return false; | |
| 517 | + } | |
| 518 | + // 兜底逻辑:将支付拓展单更新为已关闭 | |
| 519 | + PayOrderExtensionDO updateObj = new PayOrderExtensionDO().setStatus(PayOrderStatusEnum.CLOSED.getStatus()) | |
| 520 | + .setChannelNotifyData(toJsonString(respDTO)); | |
| 521 | + if (orderExtensionMapper.updateByIdAndStatus(orderExtension.getId(), PayOrderStatusEnum.WAITING.getStatus(), | |
| 522 | + updateObj) == 0) { | |
| 523 | + log.error("[expireOrder][extension({}) 更新为支付关闭失败]", orderExtension.getId()); | |
| 524 | + return false; | |
| 525 | + } | |
| 526 | + log.info("[expireOrder][extension({}) 更新为支付关闭成功]", orderExtension.getId()); | |
| 527 | + } | |
| 528 | + | |
| 529 | + // 2. 都没有上述情况,可以安心更新为已关闭 | |
| 530 | + PayOrderDO updateObj = new PayOrderDO().setStatus(PayOrderStatusEnum.CLOSED.getStatus()); | |
| 531 | + if (orderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateObj) == 0) { | |
| 532 | + log.error("[expireOrder][order({}) 更新为支付关闭失败]", order.getId()); | |
| 533 | + return false; | |
| 534 | + } | |
| 535 | + log.info("[expireOrder][order({}) 更新为支付关闭失败]", order.getId()); | |
| 536 | + return true; | |
| 537 | + } catch (Throwable e) { | |
| 538 | + log.error("[expireOrder][order({}) 过期订单异常]", order.getId(), e); | |
| 539 | + return false; | |
| 540 | + } | |
| 541 | + } | |
| 542 | + | |
| 417 | 543 | /** |
| 418 | 544 | * 获得自身的代理对象,解决 AOP 生效问题 |
| 419 | 545 | * | ... | ... |