From 052e4689ee083ee2fdbbce3daa615bfaf9904249 Mon Sep 17 00:00:00 2001 From: "zhijiantianya@gmail.com" Date: Wed, 12 Jul 2023 12:52:48 +0800 Subject: [PATCH] =?UTF-8?q?by=20gateway:=20=E6=94=AF=E4=BB=98=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/test/core/util/RandomUtils.java | 4 + .../module/pay/enums/ErrorCodeConstants.java | 3 +- .../admin/app/PayAppController.java | 39 ++------- .../controller/admin/app/vo/PayAppBaseVO.java | 14 ++-- .../admin/app/vo/PayAppPageItemRespVO.java | 4 +- .../admin/app/vo/PayAppPageReqVO.java | 13 +-- .../controller/admin/app/vo/PayAppRespVO.java | 2 +- .../admin/app/vo/PayAppUpdateReqVO.java | 2 +- .../admin/app/vo/PayAppUpdateStatusReqVO.java | 6 +- .../module/pay/convert/app/PayAppConvert.java | 15 +++- .../pay/dal/mysql/app/PayAppMapper.java | 14 ++-- .../pay/dal/mysql/order/PayOrderMapper.java | 13 +-- .../pay/dal/mysql/refund/PayRefundMapper.java | 9 +- .../module/pay/service/app/PayAppService.java | 17 ++-- .../pay/service/app/PayAppServiceImpl.java | 84 +++++++------------ .../pay/service/order/PayOrderService.java | 8 ++ .../service/order/PayOrderServiceImpl.java | 5 ++ .../pay/service/refund/PayRefundService.java | 8 ++ .../service/refund/PayRefundServiceImpl.java | 5 ++ .../pay/service/app/PayAppServiceTest.java | 39 +++++---- .../src/test/resources/sql/clean.sql | 1 - .../src/test/resources/sql/create_tables.sql | 21 +---- 22 files changed, 142 insertions(+), 184 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java b/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java index 7f114e5b1..779803059 100644 --- a/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java @@ -102,6 +102,10 @@ public class RandomUtils { return randomString() + "@qq.com"; } + public static String randomURL() { + return "https://www.iocoder.cn/" + randomString(); + } + @SafeVarargs public static T randomPojo(Class clazz, Consumer... consumers) { T pojo = PODAM_FACTORY.manufacturePojo(clazz); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 3d73f181e..0353afff5 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -12,7 +12,8 @@ public interface ErrorCodeConstants { // ========== APP 模块 1007000000 ========== ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在"); ErrorCode PAY_APP_IS_DISABLE = new ErrorCode(1007000002, "App 已经被禁用"); - ErrorCode PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE = new ErrorCode(1007000003, "支付应用存在交易中的订单,无法删除"); + ErrorCode PAY_APP_EXIST_ORDER_CANT_DELETE = new ErrorCode(1007000003, "支付应用存在支付订单,无法删除"); + ErrorCode PAY_APP_EXIST_REFUND_CANT_DELETE = new ErrorCode(1007000004, "支付应用存在退款订单,无法删除"); // ========== CHANNEL 模块 1007001000 ========== ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java index dda11bc96..562b2e4d4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/PayAppController.java @@ -24,6 +24,7 @@ import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; @Slf4j @Tag(name = "管理后台 - 支付应用信息") @@ -78,15 +79,6 @@ public class PayAppController { return success(PayAppConvert.INSTANCE.convert(app)); } - @GetMapping("/list") - @Operation(summary = "获得支付应用信息列表") - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") - @PreAuthorize("@ss.hasPermission('pay:app:query')") - public CommonResult> getAppList(@RequestParam("ids") Collection ids) { - List list = appService.getAppList(ids); - return success(PayAppConvert.INSTANCE.convertList(list)); - } - @GetMapping("/page") @Operation(summary = "获得支付应用信息分页") @PreAuthorize("@ss.hasPermission('pay:app:query')") @@ -94,34 +86,15 @@ public class PayAppController { // 得到应用分页列表 PageResult pageResult = appService.getAppPage(pageVO); if (CollUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); + return success(PageResult.empty()); } // 得到所有的应用编号,查出所有的渠道 - Collection payAppIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getId); - List channels = channelService.getChannelListByAppIds(payAppIds); - // TODO @aquan:可以基于 appId 简历一个 multiMap。这样下面,直接 get 到之后,CollUtil buildSet 即可 - Iterator iterator = channels.iterator(); + Collection appIds = convertList(pageResult.getList(), PayAppDO::getId); + List channels = channelService.getChannelListByAppIds(appIds); - // 利用反射将渠道数据复制到返回的数据结构中去 - List appList = new ArrayList<>(pageResult.getList().size()); - pageResult.getList().forEach(app -> { - // 写入应用信息的数据 - PayAppPageItemRespVO respVO = PayAppConvert.INSTANCE.pageConvert(app); - // 写入支付渠道信息的数据 - Set channelCodes = new HashSet<>(PayChannelEnum.values().length); - while (iterator.hasNext()) { - PayChannelDO channelDO = iterator.next(); - if (channelDO.getAppId().equals(app.getId())) { - channelCodes.add(channelDO.getCode()); - iterator.remove(); - } - } - respVO.setChannelCodes(channelCodes); - appList.add(respVO); - }); - - return success(new PageResult<>(appList, pageResult.getTotal())); + // 拼接后返回 + return success(PayAppConvert.INSTANCE.convertPage(pageResult, channels)); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java index c6a4570b3..d2ff4f321 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppBaseVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.app.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; +import org.hibernate.validator.constraints.URL; + import javax.validation.constraints.*; /** @@ -10,23 +12,25 @@ import javax.validation.constraints.*; @Data public class PayAppBaseVO { - @Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "小豆") @NotNull(message = "应用名不能为空") private String name; - @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(description = "备注") + @Schema(description = "备注", example = "我是一个测试应用") private String remark; - @Schema(description = "支付结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "支付结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/pay-callback") @NotNull(message = "支付结果的回调地址不能为空") + @URL(message = "支付结果的回调地址必须为 URL 格式") private String payNotifyUrl; - @Schema(description = "退款结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "退款结果的回调地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://127.0.0.1:48080/refund-callback") @NotNull(message = "退款结果的回调地址不能为空") + @URL(message = "退款结果的回调地址必须为 URL 格式") private String refundNotifyUrl; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageItemRespVO.java index 0610d63fb..76b62003c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageItemRespVO.java @@ -14,13 +14,13 @@ import java.util.Set; @ToString(callSuper = true) public class PayAppPageItemRespVO extends PayAppBaseVO { - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - @Schema(description = "渠道编码集合", requiredMode = Schema.RequiredMode.REQUIRED, example = "[alipay_pc, alipay_wap]") + @Schema(description = "已配置的支付渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "[alipay_pc, alipay_wap]") private Set channelCodes; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageReqVO.java index 5a4cd1ce8..94ade7ce6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppPageReqVO.java @@ -17,21 +17,12 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class PayAppPageReqVO extends PageParam { - @Schema(description = "应用名") + @Schema(description = "应用名", example = "小豆") private String name; - @Schema(description = "开启状态") + @Schema(description = "开启状态", example = "0") private Integer status; - @Schema(description = "备注") - private String remark; - - @Schema(description = "支付结果的回调地址") - private String payNotifyUrl; - - @Schema(description = "退款结果的回调地址") - private String refundNotifyUrl; - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @Schema(description = "创建时间") private LocalDateTime[] createTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppRespVO.java index 87dadcbc7..9471a2f01 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppRespVO.java @@ -10,7 +10,7 @@ import java.time.LocalDateTime; @ToString(callSuper = true) public class PayAppRespVO extends PayAppBaseVO { - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateReqVO.java index 2cc363b6e..5edf2290a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateReqVO.java @@ -9,7 +9,7 @@ import javax.validation.constraints.*; @ToString(callSuper = true) public class PayAppUpdateReqVO extends PayAppBaseVO { - @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "应用编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateStatusReqVO.java index 64b7ea444..9b8dad6e1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateStatusReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/app/vo/PayAppUpdateStatusReqVO.java @@ -9,11 +9,11 @@ import javax.validation.constraints.NotNull; @Data public class PayAppUpdateStatusReqVO { - @Schema(description = "商户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "商户编号不能为空") + @Schema(description = "应用编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "应用编号不能为空") private Long id; - @Schema(description = "状态,见 SysCommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @Schema(description = "状态,见 SysCommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java index ef0be7e3d..4853d07f7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java @@ -1,15 +1,20 @@ package cn.iocoder.yudao.module.pay.convert.app; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppPageItemRespVO; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppRespVO; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppUpdateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; /** * 支付应用信息 Convert @@ -31,6 +36,14 @@ public interface PayAppConvert { List convertList(List list); - PageResult convertPage(PageResult page); + PageResult convertPage(PageResult page); + + default PageResult convertPage(PageResult pageResult, List channels) { + PageResult voPageResult = convertPage(pageResult); + // 处理 channel 关系 + Map> appIdChannelMap = CollectionUtils.convertMultiMap2(channels, PayChannelDO::getAppId, PayChannelDO::getCode); + voPageResult.getList().forEach(app -> app.setChannelCodes(appIdChannelMap.get(app.getId()))); + return voPageResult; + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/app/PayAppMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/app/PayAppMapper.java index 6ac163a9e..c31dba551 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/app/PayAppMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/app/PayAppMapper.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.app; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; @@ -11,14 +12,11 @@ import org.apache.ibatis.annotations.Mapper; public interface PayAppMapper extends BaseMapperX { default PageResult selectPage(PayAppPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .likeIfPresent("name", reqVO.getName()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("remark", reqVO.getRemark()) - .eqIfPresent("pay_notify_url", reqVO.getPayNotifyUrl()) - .eqIfPresent("refund_notify_url", reqVO.getRefundNotifyUrl()) - .betweenIfPresent("create_time", reqVO.getCreateTime()) - .orderByDesc("id")); + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(PayAppDO::getName, reqVO.getName()) + .eqIfPresent(PayAppDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(PayAppDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(PayAppDO::getId)); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java index 5d90f41f9..49c7d2fbf 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java @@ -50,17 +50,8 @@ public interface PayOrderMapper extends BaseMapperX { .in(PayOrderDO::getId, idList)); } - /** - * 查询符合的订单数量 - * - * @param appId 应用编号 - * @param status 订单状态 - * @return 条数 - */ - default Long selectCount(Long appId, Integer status) { - return selectCount(new LambdaQueryWrapper() - .eq(PayOrderDO::getAppId, appId) - .in(PayOrderDO::getStatus, status)); + default Long selectCountByAppId(Long appId) { + return selectCount(PayOrderDO::getAppId, appId); } default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java index 7614c8f8e..35a6bd5a7 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -38,11 +37,8 @@ public interface PayRefundMapper extends BaseMapperX { .orderByDesc("id")); } - default Long selectCount(Long appId, Integer status) { - - return selectCount(new LambdaQueryWrapper() - .eq(PayRefundDO::getAppId, appId) - .eq(PayRefundDO::getStatus, status)); + default Long selectCountByApp(Long appId) { + return selectCount(PayRefundDO::getAppId, appId); } default PayRefundDO selectByReqNo(String reqNo) { @@ -52,4 +48,5 @@ public interface PayRefundMapper extends BaseMapperX { default PayRefundDO selectByTradeNoAndMerchantRefundNo(String tradeNo, String merchantRefundNo){ return selectOne("trade_no", tradeNo, "merchant_refund_no", merchantRefundNo); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java index 14dce0a18..7105b78a8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppService.java @@ -35,6 +35,14 @@ public interface PayAppService { */ void updateApp(@Valid PayAppUpdateReqVO updateReqVO); + /** + * 修改应用信息状态 + * + * @param id 应用编号 + * @param status 状态 + */ + void updateAppStatus(Long id, Integer status); + /** * 删除支付应用信息 * @@ -66,14 +74,6 @@ public interface PayAppService { */ PageResult getAppPage(PayAppPageReqVO pageReqVO); - /** - * 修改应用信息状态 - * - * @param id 应用编号 - * @param status 状态{@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} - */ - void updateAppStatus(Long id, Integer status); - /** * 获得指定编号的商户 Map * @@ -85,7 +85,6 @@ public interface PayAppService { return CollectionUtils.convertMap(list, PayAppDO::getId); } - /** * 支付应用的合法性 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java index 5f70fb5fe..c644edbfd 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceImpl.java @@ -9,12 +9,13 @@ import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppUpdateReqVO; import cn.iocoder.yudao.module.pay.convert.app.PayAppConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.mysql.app.PayAppMapper; -import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; -import com.google.common.annotations.VisibleForTesting; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -23,11 +24,10 @@ import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE; -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_NOT_FOUND; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; /** - * 支付应用信息 Service 实现类 + * 支付应用 Service 实现类 * * @author aquan */ @@ -37,11 +37,13 @@ public class PayAppServiceImpl implements PayAppService { @Resource private PayAppMapper appMapper; - // TODO 芋艿:不能调用对方的 mapper + @Resource - private PayOrderMapper orderMapper; + @Lazy // 延迟加载,避免循环依赖报错 + private PayOrderService orderService; @Resource - private PayRefundMapper refundMapper; + @Lazy // 延迟加载,避免循环依赖报错 + private PayRefundService refundService; @Override public Long createApp(PayAppCreateReqVO createReqVO) { @@ -55,17 +57,34 @@ public class PayAppServiceImpl implements PayAppService { @Override public void updateApp(PayAppUpdateReqVO updateReqVO) { // 校验存在 - this.validateAppExists(updateReqVO.getId()); + validateAppExists(updateReqVO.getId()); // 更新 PayAppDO updateObj = PayAppConvert.INSTANCE.convert(updateReqVO); appMapper.updateById(updateObj); } + @Override + public void updateAppStatus(Long id, Integer status) { + // 校验商户存在 + validateAppExists(id); + // 更新状态 + PayAppDO app = new PayAppDO(); + app.setId(id); + app.setStatus(status); + appMapper.updateById(app); + } + @Override public void deleteApp(Long id) { // 校验存在 - this.validateAppExists(id); - this.validateOrderTransactionExist(id); + validateAppExists(id); + // 校验关联数据是否存在 + if (orderService.getOrderCountByAppId(id) > 0) { + throw exception(PAY_APP_EXIST_ORDER_CANT_DELETE); + } + if (refundService.getRefundCountByAppId(id) > 0) { + throw exception(PAY_APP_EXIST_REFUND_CANT_DELETE); + } // 删除 appMapper.deleteById(id); @@ -92,49 +111,6 @@ public class PayAppServiceImpl implements PayAppService { return appMapper.selectPage(pageReqVO); } - @Override - public void updateAppStatus(Long id, Integer status) { - // 校验商户存在 - this.checkAppExists(id); - // 更新状态 - PayAppDO app = new PayAppDO(); - app.setId(id); - app.setStatus(status); - appMapper.updateById(app); - } - - /** - * 检查商户是否存在 - * - * @param id 商户编号 - */ - @VisibleForTesting - public void checkAppExists(Long id) { - if (id == null) { - return; - } - PayAppDO payApp = appMapper.selectById(id); - if (payApp == null) { - throw exception(PAY_APP_NOT_FOUND); - } - } - - /** - * 验证是否存在交易中或者退款中等处理中状态的订单 - * - * @param appId 应用 ID - */ - private void validateOrderTransactionExist(Long appId) { - // 查看交易订单 - if (orderMapper.selectCount(appId, PayOrderStatusEnum.WAITING.getStatus()) > 0) { - throw exception(PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE); - } - // 查看退款订单 - if (refundMapper.selectCount(appId, PayRefundStatusEnum.CREATE.getStatus()) > 0) { - throw exception(PAY_APP_EXIST_TRANSACTION_ORDER_CANT_DELETE); - } - } - @Override public PayAppDO validPayApp(Long id) { PayAppDO app = appMapper.selectById(id); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java index d6ba9b7ad..890bacd62 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java @@ -32,6 +32,14 @@ public interface PayOrderService { */ PayOrderDO getOrder(Long id); + /** + * 获得指定应用的订单数量 + * + * @param appId 应用编号 + * @return 订单数量 + */ + Long getOrderCountByAppId(Long appId); + /** * 获得支付订单 * 分页 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 aa84882de..d27c52212 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 @@ -82,6 +82,11 @@ public class PayOrderServiceImpl implements PayOrderService { return orderMapper.selectById(id); } + @Override + public Long getOrderCountByAppId(Long appId) { + return orderMapper.selectCountByAppId(appId); + } + @Override public PageResult getOrderPage(PayOrderPageReqVO pageReqVO) { return orderMapper.selectPage(pageReqVO); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java index 9f1c9bfd9..14f525582 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -25,6 +25,14 @@ public interface PayRefundService { */ PayRefundDO getRefund(Long id); + /** + * 获得指定应用的退款数量 + * + * @param appId 应用编号 + * @return 退款数量 + */ + Long getRefundCountByAppId(Long appId); + /** * 获得退款订单分页 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index d505f1b13..a5f815bdd 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -80,6 +80,11 @@ public class PayRefundServiceImpl implements PayRefundService { return refundMapper.selectById(id); } + @Override + public Long getRefundCountByAppId(Long appId) { + return refundMapper.selectCountByApp(appId); + } + @Override public PageResult getRefundPage(PayRefundPageReqVO pageReqVO) { return refundMapper.selectPage(pageReqVO); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java index 3fad0745b..df785d128 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/app/PayAppServiceTest.java @@ -3,27 +3,37 @@ package cn.iocoder.yudao.module.pay.service.app; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppCreateReqVO; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppPageReqVO; import cn.iocoder.yudao.module.pay.controller.admin.app.vo.PayAppUpdateReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; import cn.iocoder.yudao.module.pay.dal.mysql.app.PayAppMapper; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; import java.time.LocalDateTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_APP_NOT_FOUND; import static org.junit.jupiter.api.Assertions.*; +/** + * {@link PayAppServiceImpl} 的单元测试 + * + * @author aquan + */ @Import(PayAppServiceImpl.class) public class PayAppServiceTest extends BaseDbUnitTest { @@ -33,17 +43,23 @@ public class PayAppServiceTest extends BaseDbUnitTest { @Resource private PayAppMapper appMapper; + @MockBean + private PayOrderService orderService; + @MockBean + private PayRefundService refundService; + @Test public void testCreateApp_success() { // 准备参数 PayAppCreateReqVO reqVO = randomPojo(PayAppCreateReqVO.class, o -> - o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())) + .setPayNotifyUrl(randomURL()) + .setRefundNotifyUrl(randomURL())); // 调用 Long appId = appService.createApp(reqVO); // 断言 assertNotNull(appId); - // 校验记录的属性是否正确 PayAppDO app = appMapper.selectById(appId); assertPojoEquals(reqVO, app); } @@ -57,6 +73,7 @@ public class PayAppServiceTest extends BaseDbUnitTest { // 准备参数 PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> { o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setPayNotifyUrl(randomURL()).setRefundNotifyUrl(randomURL()); o.setId(dbApp.getId()); // 设置更新的 ID }); @@ -106,9 +123,6 @@ public class PayAppServiceTest extends BaseDbUnitTest { PayAppDO dbApp = randomPojo(PayAppDO.class, o -> { // 等会查询到 o.setName("灿灿姐的杂货铺"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("敏敏姐的小卖铺"); - o.setPayNotifyUrl("https://www.hc.com"); - o.setRefundNotifyUrl("https://www.xm.com"); o.setCreateTime(buildTime(2021,11,20)); }); @@ -117,22 +131,13 @@ public class PayAppServiceTest extends BaseDbUnitTest { appMapper.insert(cloneIgnoreId(dbApp, o -> o.setName("敏敏姐的杂货铺"))); // 测试 status 不匹配 appMapper.insert(cloneIgnoreId(dbApp, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - // 测试 remark 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRemark("灿灿姐的小卖部"))); - // 测试 payNotifyUrl 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setPayNotifyUrl("xm.com"))); - // 测试 refundNotifyUrl 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setRefundNotifyUrl("hc.com"))); // 测试 createTime 不匹配 appMapper.insert(cloneIgnoreId(dbApp, o -> o.setCreateTime(buildTime(2021,12,21)))); // 准备参数 PayAppPageReqVO reqVO = new PayAppPageReqVO(); reqVO.setName("灿灿姐的杂货铺"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("敏敏姐的小卖铺"); - reqVO.setPayNotifyUrl("https://www.hc.com"); - reqVO.setRefundNotifyUrl("https://www.xm.com"); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021,11,19),buildTime(2021,11,21)})); + reqVO.setCreateTime(buildBetweenTime(2021, 11, 19, 2021, 11, 21)); // 调用 PageResult pageResult = appService.getAppPage(reqVO); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/clean.sql b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/clean.sql index 7430b6bfe..2a4610d02 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/clean.sql @@ -1,4 +1,3 @@ -DELETE FROM pay_merchant; DELETE FROM pay_app; DELETE FROM pay_channel; DELETE FROM pay_order; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql index 09cfa2887..fea1365a5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-pay/yudao-module-pay-biz/src/test/resources/sql/create_tables.sql @@ -1,18 +1,3 @@ -CREATE TABLE IF NOT EXISTS "pay_merchant" ( - "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "no" varchar(32) NOT NULL, - "name" varchar(64) NOT NULL, - "short_name" varchar(64) NOT NULL, - "status" tinyint NOT NULL, - "remark" varchar(255) DEFAULT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit(1) NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '支付商户信息'; - CREATE TABLE IF NOT EXISTS "pay_app" ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, "name" varchar(64) NOT NULL, @@ -20,14 +5,13 @@ CREATE TABLE IF NOT EXISTS "pay_app" ( "remark" varchar(255) DEFAULT NULL, `pay_notify_url` varchar(1024) NOT NULL, `refund_notify_url` varchar(1024) NOT NULL, - `merchant_id` bigint(20) NOT NULL, "creator" varchar(64) DEFAULT '', "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, "updater" varchar(64) DEFAULT '', "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "deleted" bit(1) NOT NULL DEFAULT FALSE, PRIMARY KEY ("id") -) COMMENT = '支付应用信息'; +) COMMENT = '支付应用'; CREATE TABLE IF NOT EXISTS "pay_channel" ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, @@ -35,7 +19,6 @@ CREATE TABLE IF NOT EXISTS "pay_channel" ( "status" tinyint(4) NOT NULL, "remark" varchar(255) DEFAULT NULL, "fee_rate" double NOT NULL DEFAULT 0, - "merchant_id" bigint(20) NOT NULL, "app_id" bigint(20) NOT NULL, "config" varchar(10240) NOT NULL, "creator" varchar(64) NULL DEFAULT '', @@ -49,7 +32,6 @@ CREATE TABLE IF NOT EXISTS "pay_channel" ( CREATE TABLE IF NOT EXISTS `pay_order` ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, - `merchant_id` bigint(20) NOT NULL, `app_id` bigint(20) NOT NULL, `channel_id` bigint(20) DEFAULT NULL, `channel_code` varchar(32) DEFAULT NULL, @@ -82,7 +64,6 @@ CREATE TABLE IF NOT EXISTS `pay_order` ( CREATE TABLE IF NOT EXISTS `pay_refund` ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, - `merchant_id` bigint(20) NOT NULL, `app_id` bigint(20) NOT NULL, `channel_id` bigint(20) NOT NULL, `channel_code` varchar(32) NOT NULL,